Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Redis\Connections;
4
 
5
use Closure;
6
use Illuminate\Contracts\Redis\Connection as ConnectionContract;
7
use Illuminate\Support\Arr;
8
use Redis;
9
use RedisException;
10
 
11
/**
12
 * @mixin \Redis
13
 */
14
class PhpRedisConnection extends Connection implements ConnectionContract
15
{
16
    use PacksPhpRedisValues;
17
 
18
    /**
19
     * The connection creation callback.
20
     *
21
     * @var callable
22
     */
23
    protected $connector;
24
 
25
    /**
26
     * The connection configuration array.
27
     *
28
     * @var array
29
     */
30
    protected $config;
31
 
32
    /**
33
     * Create a new PhpRedis connection.
34
     *
35
     * @param  \Redis  $client
36
     * @param  callable|null  $connector
37
     * @param  array  $config
38
     * @return void
39
     */
40
    public function __construct($client, callable $connector = null, array $config = [])
41
    {
42
        $this->client = $client;
43
        $this->config = $config;
44
        $this->connector = $connector;
45
    }
46
 
47
    /**
48
     * Returns the value of the given key.
49
     *
50
     * @param  string  $key
51
     * @return string|null
52
     */
53
    public function get($key)
54
    {
55
        $result = $this->command('get', [$key]);
56
 
57
        return $result !== false ? $result : null;
58
    }
59
 
60
    /**
61
     * Get the values of all the given keys.
62
     *
63
     * @param  array  $keys
64
     * @return array
65
     */
66
    public function mget(array $keys)
67
    {
68
        return array_map(function ($value) {
69
            return $value !== false ? $value : null;
70
        }, $this->command('mget', [$keys]));
71
    }
72
 
73
    /**
74
     * Set the string value in the argument as the value of the key.
75
     *
76
     * @param  string  $key
77
     * @param  mixed  $value
78
     * @param  string|null  $expireResolution
79
     * @param  int|null  $expireTTL
80
     * @param  string|null  $flag
81
     * @return bool
82
     */
83
    public function set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
84
    {
85
        return $this->command('set', [
86
            $key,
87
            $value,
88
            $expireResolution ? [$flag, $expireResolution => $expireTTL] : null,
89
        ]);
90
    }
91
 
92
    /**
93
     * Set the given key if it doesn't exist.
94
     *
95
     * @param  string  $key
96
     * @param  string  $value
97
     * @return int
98
     */
99
    public function setnx($key, $value)
100
    {
101
        return (int) $this->command('setnx', [$key, $value]);
102
    }
103
 
104
    /**
105
     * Get the value of the given hash fields.
106
     *
107
     * @param  string  $key
399 lars 108
     * @param  mixed  ...$dictionary
148 lars 109
     * @return array
110
     */
111
    public function hmget($key, ...$dictionary)
112
    {
113
        if (count($dictionary) === 1) {
114
            $dictionary = $dictionary[0];
115
        }
116
 
117
        return array_values($this->command('hmget', [$key, $dictionary]));
118
    }
119
 
120
    /**
121
     * Set the given hash fields to their respective values.
122
     *
123
     * @param  string  $key
399 lars 124
     * @param  mixed  ...$dictionary
148 lars 125
     * @return int
126
     */
127
    public function hmset($key, ...$dictionary)
128
    {
129
        if (count($dictionary) === 1) {
130
            $dictionary = $dictionary[0];
131
        } else {
132
            $input = collect($dictionary);
133
 
134
            $dictionary = $input->nth(2)->combine($input->nth(2, 1))->toArray();
135
        }
136
 
137
        return $this->command('hmset', [$key, $dictionary]);
138
    }
139
 
140
    /**
141
     * Set the given hash field if it doesn't exist.
142
     *
143
     * @param  string  $hash
144
     * @param  string  $key
145
     * @param  string  $value
146
     * @return int
147
     */
148
    public function hsetnx($hash, $key, $value)
149
    {
150
        return (int) $this->command('hsetnx', [$hash, $key, $value]);
151
    }
152
 
153
    /**
154
     * Removes the first count occurrences of the value element from the list.
155
     *
156
     * @param  string  $key
157
     * @param  int  $count
158
     * @param  mixed  $value
159
     * @return int|false
160
     */
161
    public function lrem($key, $count, $value)
162
    {
163
        return $this->command('lrem', [$key, $value, $count]);
164
    }
165
 
166
    /**
167
     * Removes and returns the first element of the list stored at key.
168
     *
399 lars 169
     * @param  mixed  ...$arguments
148 lars 170
     * @return array|null
171
     */
172
    public function blpop(...$arguments)
173
    {
174
        $result = $this->command('blpop', $arguments);
175
 
176
        return empty($result) ? null : $result;
177
    }
178
 
179
    /**
180
     * Removes and returns the last element of the list stored at key.
181
     *
399 lars 182
     * @param  mixed  ...$arguments
148 lars 183
     * @return array|null
184
     */
185
    public function brpop(...$arguments)
186
    {
187
        $result = $this->command('brpop', $arguments);
188
 
189
        return empty($result) ? null : $result;
190
    }
191
 
192
    /**
193
     * Removes and returns a random element from the set value at key.
194
     *
195
     * @param  string  $key
196
     * @param  int|null  $count
197
     * @return mixed|false
198
     */
199
    public function spop($key, $count = 1)
200
    {
201
        return $this->command('spop', func_get_args());
202
    }
203
 
204
    /**
205
     * Add one or more members to a sorted set or update its score if it already exists.
206
     *
207
     * @param  string  $key
399 lars 208
     * @param  mixed  ...$dictionary
148 lars 209
     * @return int
210
     */
211
    public function zadd($key, ...$dictionary)
212
    {
213
        if (is_array(end($dictionary))) {
214
            foreach (array_pop($dictionary) as $member => $score) {
215
                $dictionary[] = $score;
216
                $dictionary[] = $member;
217
            }
218
        }
219
 
220
        $options = [];
221
 
222
        foreach (array_slice($dictionary, 0, 3) as $i => $value) {
223
            if (in_array($value, ['nx', 'xx', 'ch', 'incr', 'gt', 'lt', 'NX', 'XX', 'CH', 'INCR', 'GT', 'LT'], true)) {
224
                $options[] = $value;
225
 
226
                unset($dictionary[$i]);
227
            }
228
        }
229
 
230
        return $this->command('zadd', array_merge([$key], [$options], array_values($dictionary)));
231
    }
232
 
233
    /**
234
     * Return elements with score between $min and $max.
235
     *
236
     * @param  string  $key
237
     * @param  mixed  $min
238
     * @param  mixed  $max
239
     * @param  array  $options
240
     * @return array
241
     */
242
    public function zrangebyscore($key, $min, $max, $options = [])
243
    {
244
        if (isset($options['limit']) && Arr::isAssoc($options['limit'])) {
245
            $options['limit'] = [
246
                $options['limit']['offset'],
247
                $options['limit']['count'],
248
            ];
249
        }
250
 
251
        return $this->command('zRangeByScore', [$key, $min, $max, $options]);
252
    }
253
 
254
    /**
255
     * Return elements with score between $min and $max.
256
     *
257
     * @param  string  $key
258
     * @param  mixed  $min
259
     * @param  mixed  $max
260
     * @param  array  $options
261
     * @return array
262
     */
263
    public function zrevrangebyscore($key, $min, $max, $options = [])
264
    {
265
        if (isset($options['limit']) && Arr::isAssoc($options['limit'])) {
266
            $options['limit'] = [
267
                $options['limit']['offset'],
268
                $options['limit']['count'],
269
            ];
270
        }
271
 
272
        return $this->command('zRevRangeByScore', [$key, $min, $max, $options]);
273
    }
274
 
275
    /**
276
     * Find the intersection between sets and store in a new set.
277
     *
278
     * @param  string  $output
279
     * @param  array  $keys
280
     * @param  array  $options
281
     * @return int
282
     */
283
    public function zinterstore($output, $keys, $options = [])
284
    {
285
        return $this->command('zinterstore', [$output, $keys,
286
            $options['weights'] ?? null,
287
            $options['aggregate'] ?? 'sum',
288
        ]);
289
    }
290
 
291
    /**
292
     * Find the union between sets and store in a new set.
293
     *
294
     * @param  string  $output
295
     * @param  array  $keys
296
     * @param  array  $options
297
     * @return int
298
     */
299
    public function zunionstore($output, $keys, $options = [])
300
    {
301
        return $this->command('zunionstore', [$output, $keys,
302
            $options['weights'] ?? null,
303
            $options['aggregate'] ?? 'sum',
304
        ]);
305
    }
306
 
307
    /**
308
     * Scans all keys based on options.
309
     *
310
     * @param  mixed  $cursor
311
     * @param  array  $options
312
     * @return mixed
313
     */
314
    public function scan($cursor, $options = [])
315
    {
316
        $result = $this->client->scan($cursor,
317
            $options['match'] ?? '*',
318
            $options['count'] ?? 10
319
        );
320
 
321
        if ($result === false) {
322
            $result = [];
323
        }
324
 
325
        return $cursor === 0 && empty($result) ? false : [$cursor, $result];
326
    }
327
 
328
    /**
329
     * Scans the given set for all values based on options.
330
     *
331
     * @param  string  $key
332
     * @param  mixed  $cursor
333
     * @param  array  $options
334
     * @return mixed
335
     */
336
    public function zscan($key, $cursor, $options = [])
337
    {
338
        $result = $this->client->zscan($key, $cursor,
339
            $options['match'] ?? '*',
340
            $options['count'] ?? 10
341
        );
342
 
343
        if ($result === false) {
344
            $result = [];
345
        }
346
 
347
        return $cursor === 0 && empty($result) ? false : [$cursor, $result];
348
    }
349
 
350
    /**
351
     * Scans the given hash for all values based on options.
352
     *
353
     * @param  string  $key
354
     * @param  mixed  $cursor
355
     * @param  array  $options
356
     * @return mixed
357
     */
358
    public function hscan($key, $cursor, $options = [])
359
    {
360
        $result = $this->client->hscan($key, $cursor,
361
            $options['match'] ?? '*',
362
            $options['count'] ?? 10
363
        );
364
 
365
        if ($result === false) {
366
            $result = [];
367
        }
368
 
369
        return $cursor === 0 && empty($result) ? false : [$cursor, $result];
370
    }
371
 
372
    /**
373
     * Scans the given set for all values based on options.
374
     *
375
     * @param  string  $key
376
     * @param  mixed  $cursor
377
     * @param  array  $options
378
     * @return mixed
379
     */
380
    public function sscan($key, $cursor, $options = [])
381
    {
382
        $result = $this->client->sscan($key, $cursor,
383
            $options['match'] ?? '*',
384
            $options['count'] ?? 10
385
        );
386
 
387
        if ($result === false) {
388
            $result = [];
389
        }
390
 
391
        return $cursor === 0 && empty($result) ? false : [$cursor, $result];
392
    }
393
 
394
    /**
395
     * Execute commands in a pipeline.
396
     *
397
     * @param  callable|null  $callback
398
     * @return \Redis|array
399
     */
400
    public function pipeline(callable $callback = null)
401
    {
402
        $pipeline = $this->client()->pipeline();
403
 
404
        return is_null($callback)
405
            ? $pipeline
406
            : tap($pipeline, $callback)->exec();
407
    }
408
 
409
    /**
410
     * Execute commands in a transaction.
411
     *
412
     * @param  callable|null  $callback
413
     * @return \Redis|array
414
     */
415
    public function transaction(callable $callback = null)
416
    {
417
        $transaction = $this->client()->multi();
418
 
419
        return is_null($callback)
420
            ? $transaction
421
            : tap($transaction, $callback)->exec();
422
    }
423
 
424
    /**
425
     * Evaluate a LUA script serverside, from the SHA1 hash of the script instead of the script itself.
426
     *
427
     * @param  string  $script
428
     * @param  int  $numkeys
399 lars 429
     * @param  mixed  ...$arguments
148 lars 430
     * @return mixed
431
     */
432
    public function evalsha($script, $numkeys, ...$arguments)
433
    {
434
        return $this->command('evalsha', [
435
            $this->script('load', $script), $arguments, $numkeys,
436
        ]);
437
    }
438
 
439
    /**
440
     * Evaluate a script and return its result.
441
     *
442
     * @param  string  $script
443
     * @param  int  $numberOfKeys
399 lars 444
     * @param  dynamic  ...$arguments
148 lars 445
     * @return mixed
446
     */
447
    public function eval($script, $numberOfKeys, ...$arguments)
448
    {
449
        return $this->command('eval', [$script, $arguments, $numberOfKeys]);
450
    }
451
 
452
    /**
453
     * Subscribe to a set of given channels for messages.
454
     *
455
     * @param  array|string  $channels
456
     * @param  \Closure  $callback
457
     * @return void
458
     */
459
    public function subscribe($channels, Closure $callback)
460
    {
461
        $this->client->subscribe((array) $channels, function ($redis, $channel, $message) use ($callback) {
462
            $callback($message, $channel);
463
        });
464
    }
465
 
466
    /**
467
     * Subscribe to a set of given channels with wildcards.
468
     *
469
     * @param  array|string  $channels
470
     * @param  \Closure  $callback
471
     * @return void
472
     */
473
    public function psubscribe($channels, Closure $callback)
474
    {
475
        $this->client->psubscribe((array) $channels, function ($redis, $pattern, $channel, $message) use ($callback) {
476
            $callback($message, $channel);
477
        });
478
    }
479
 
480
    /**
481
     * Subscribe to a set of given channels for messages.
482
     *
483
     * @param  array|string  $channels
484
     * @param  \Closure  $callback
485
     * @param  string  $method
486
     * @return void
487
     */
488
    public function createSubscription($channels, Closure $callback, $method = 'subscribe')
489
    {
490
        //
491
    }
492
 
493
    /**
494
     * Flush the selected Redis database.
495
     *
496
     * @return mixed
497
     */
498
    public function flushdb()
499
    {
500
        $arguments = func_get_args();
501
 
502
        if (strtoupper((string) ($arguments[0] ?? null)) === 'ASYNC') {
503
            return $this->command('flushdb', [true]);
504
        }
505
 
506
        return $this->command('flushdb');
507
    }
508
 
509
    /**
510
     * Execute a raw command.
511
     *
512
     * @param  array  $parameters
513
     * @return mixed
514
     */
515
    public function executeRaw(array $parameters)
516
    {
517
        return $this->command('rawCommand', $parameters);
518
    }
519
 
520
    /**
521
     * Run a command against the Redis database.
522
     *
523
     * @param  string  $method
524
     * @param  array  $parameters
525
     * @return mixed
526
     *
527
     * @throws \RedisException
528
     */
529
    public function command($method, array $parameters = [])
530
    {
531
        try {
532
            return parent::command($method, $parameters);
533
        } catch (RedisException $e) {
534
            foreach (['went away', 'socket', 'read error on connection'] as $errorMessage) {
535
                if (str_contains($e->getMessage(), $errorMessage)) {
536
                    $this->client = $this->connector ? call_user_func($this->connector) : $this->client;
537
 
538
                    break;
539
                }
540
            }
541
 
542
            throw $e;
543
        }
544
    }
545
 
546
    /**
547
     * Disconnects from the Redis instance.
548
     *
549
     * @return void
550
     */
551
    public function disconnect()
552
    {
553
        $this->client->close();
554
    }
555
 
556
    /**
557
     * Pass other method calls down to the underlying client.
558
     *
559
     * @param  string  $method
560
     * @param  array  $parameters
561
     * @return mixed
562
     */
563
    public function __call($method, $parameters)
564
    {
565
        return parent::__call(strtolower($method), $parameters);
566
    }
567
}