Redis Object Cache - Version 1.2.2

Version Description

  • Added redis_object_cache_set action
    • Added redis_object_cache_get action and filter
    • Prevented duplicated admin status messages
    • Load bundled Predis library only if necessary
    • Load bundled Predis library using WP_CONTENT_DIR constant
    • Updated stats() method output to be uniform with WordPress
Download this release

Release Info

Developer tillkruess
Plugin Icon 128x128 Redis Object Cache
Version 1.2.2
Comparing to
See all releases

Code changes from version 1.2 to 1.2.2

includes/admin-page.php CHANGED
@@ -3,7 +3,7 @@
3
 
4
  <div class="wrap">
5
 
6
- <h2><?php _e( 'Redis Object Cache', 'redis-cache' ); ?></h2>
7
 
8
  <?php settings_errors(); ?>
9
 
3
 
4
  <div class="wrap">
5
 
6
+ <h1><?php _e( 'Redis Object Cache', 'redis-cache' ); ?></h1>
7
 
8
  <?php settings_errors(); ?>
9
 
includes/object-cache.php CHANGED
@@ -2,8 +2,8 @@
2
  /*
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
- Description: A Redis backend for the WordPress Object Cache based on the Predis client library for PHP.
6
- Version: 1.1.1
7
  Author: Till Krüss
8
  Author URI: http://till.kruss.me/
9
  License: GPLv3
@@ -246,7 +246,7 @@ class WP_Object_Cache {
246
  /**
247
  * Holds the Redis client.
248
  *
249
- * @var Predis\Client
250
  */
251
  private $redis;
252
 
@@ -368,15 +368,13 @@ class WP_Object_Cache {
368
  $this->redis_client = sprintf( 'HHVM %s Extension', HHVM_VERSION );
369
  $this->redis = new Redis();
370
 
371
- // adjust host and port, if the scheme is `unix`
372
  if ( strcasecmp( 'unix', $redis[ 'scheme' ] ) === 0 ) {
373
  $redis[ 'host' ] = 'unix://' . $redis[ 'path' ];
374
  $redis[ 'port' ] = 0;
375
  }
376
 
377
- if ( ! $this->redis->connect( $redis[ 'host' ], $redis[ 'port' ] ) ) {
378
- throw new Exception;
379
- }
380
 
381
  if ( isset( $redis[ 'password' ] ) ) {
382
  $this->redis->auth( $redis[ 'password' ] );
@@ -386,8 +384,6 @@ class WP_Object_Cache {
386
  $this->redis->select( $redis[ 'database' ] );
387
  }
388
 
389
- $this->redis_connected = true;
390
-
391
  } elseif ( strcasecmp( 'pecl', $redis_client ) === 0 ) {
392
 
393
  $this->redis_client = 'PCEL Extension';
@@ -407,34 +403,33 @@ class WP_Object_Cache {
407
  $this->redis->select( $redis[ 'database' ] );
408
  }
409
 
410
- $this->redis_connected = true;
411
-
412
  } else {
413
 
414
  $this->redis_client = 'Predis';
415
 
416
- // require PHP 5.4 or greater
417
  if ( version_compare( PHP_VERSION, '5.4.0', '<' ) ) {
418
  throw new Exception;
419
  }
420
 
421
- // check if bundled Predis library exists
422
- if ( ! realpath( dirname( __FILE__ ) . '/plugins/redis-cache/includes/predis.php' ) ) {
423
- throw new Exception;
 
424
  }
425
 
426
- require_once dirname( __FILE__ ) . '/plugins/redis-cache/includes/predis.php';
427
-
428
- Predis\Autoloader::register();
429
-
430
  $this->redis = new Predis\Client( $redis );
431
  $this->redis->connect();
432
 
433
- $this->redis_connected = true;
434
  $this->redis_client .= ' v' . Predis\Client::VERSION;
435
 
436
  }
437
 
 
 
 
 
 
438
  } catch ( Exception $exception ) {
439
 
440
  // When Redis is unavailable, fall back to the internal back by forcing all groups to be "no redis" groups
@@ -528,9 +523,9 @@ class WP_Object_Cache {
528
  $expiration = $this->validate_expiration( $expiration );
529
 
530
  if ( $expiration ) {
531
- $result = $this->parse_predis_response( $this->redis->setex( $derived_key, $expiration, maybe_serialize( $value ) ) );
532
  } else {
533
- $result = $this->parse_predis_response( $this->redis->set( $derived_key, maybe_serialize( $value ) ) );
534
  }
535
  }
536
 
@@ -563,7 +558,7 @@ class WP_Object_Cache {
563
  }
564
 
565
  if ( $this->redis_status() && ! in_array( $group, $this->no_redis_groups ) ) {
566
- $result = $this->parse_predis_response( $this->redis->del( $derived_key ) );
567
  }
568
 
569
  return $result;
@@ -584,7 +579,7 @@ class WP_Object_Cache {
584
  $this->cache = array();
585
 
586
  if ( $this->redis_status() ) {
587
- $result = $this->parse_predis_response( $this->redis->flushdb() );
588
  }
589
 
590
  return $result;
@@ -616,12 +611,16 @@ class WP_Object_Cache {
616
  return false;
617
  } else {
618
  $this->cache_hits++;
619
- $value = maybe_unserialize( $result );
620
  }
621
 
622
  $this->add_to_internal_cache( $derived_key, $value );
623
 
624
- return is_object( $value ) ? clone $value : $value;
 
 
 
 
625
  }
626
 
627
  /**
@@ -705,9 +704,9 @@ class WP_Object_Cache {
705
  if ( ! in_array( $group, $this->no_redis_groups ) && $this->redis_status() ) {
706
  $expiration = $this->validate_expiration($expiration);
707
  if ( $expiration ) {
708
- $result = $this->parse_predis_response( $this->redis->setex( $derived_key, $expiration, maybe_serialize( $value ) ) );
709
  } else {
710
- $result = $this->parse_predis_response( $this->redis->set( $derived_key, maybe_serialize( $value ) ) );
711
  }
712
  }
713
 
@@ -716,6 +715,8 @@ class WP_Object_Cache {
716
  $this->add_to_internal_cache( $derived_key, $value );
717
  }
718
 
 
 
719
  return $result;
720
  }
721
 
@@ -741,7 +742,7 @@ class WP_Object_Cache {
741
  }
742
 
743
  // Save to Redis
744
- $result = $this->parse_predis_response( $this->redis->incrBy( $derived_key, $offset ) );
745
 
746
  $this->add_to_internal_cache( $derived_key, (int) $this->redis->get( $derived_key ) );
747
 
@@ -770,7 +771,7 @@ class WP_Object_Cache {
770
  }
771
 
772
  // Save to Redis
773
- $result = $this->parse_predis_response( $this->redis->decrBy( $derived_key, $offset ) );
774
 
775
  $this->add_to_internal_cache( $derived_key, (int) $this->redis->get( $derived_key ) );
776
 
@@ -790,12 +791,9 @@ class WP_Object_Cache {
790
  <strong>Cache Misses:</strong> <?php echo $this->cache_misses; ?>
791
  </p>
792
 
793
- <p><strong>Caches Retrieved:</strong></p>
794
-
795
  <ul>
796
- <li><em>prefix:group:key - size in kilobytes</em></li>
797
  <?php foreach ( $this->cache as $group => $cache ) : ?>
798
- <li><?php printf( '%s - %s kb', strip_tags( $group ), number_format( strlen( serialize( $cache ) ) / 1024, 2 ) ); ?></li>
799
  <?php endforeach; ?>
800
  </ul><?php
801
 
@@ -844,12 +842,12 @@ class WP_Object_Cache {
844
  }
845
 
846
  /**
847
- * Convert the response fro Predis into something meaningful
848
  *
849
  * @param mixed $response
850
  * @return mixed
851
  */
852
- protected function parse_predis_response( $response ) {
853
  if ( is_bool( $response ) ) {
854
  return $response;
855
  }
@@ -947,4 +945,97 @@ class WP_Object_Cache {
947
  return $expiration;
948
  }
949
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
950
  }
2
  /*
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
+ Description: A persistent object cache backend powered by Redis. Supports HHVM's Redis extension, the PCEL Redis Extension and the Predis library for PHP.
6
+ Version: 1.2.2
7
  Author: Till Krüss
8
  Author URI: http://till.kruss.me/
9
  License: GPLv3
246
  /**
247
  * Holds the Redis client.
248
  *
249
+ * @var mixed
250
  */
251
  private $redis;
252
 
368
  $this->redis_client = sprintf( 'HHVM %s Extension', HHVM_VERSION );
369
  $this->redis = new Redis();
370
 
371
+ // Adjust host and port, if the scheme is `unix`
372
  if ( strcasecmp( 'unix', $redis[ 'scheme' ] ) === 0 ) {
373
  $redis[ 'host' ] = 'unix://' . $redis[ 'path' ];
374
  $redis[ 'port' ] = 0;
375
  }
376
 
377
+ $this->redis->connect( $redis[ 'host' ], $redis[ 'port' ] );
 
 
378
 
379
  if ( isset( $redis[ 'password' ] ) ) {
380
  $this->redis->auth( $redis[ 'password' ] );
384
  $this->redis->select( $redis[ 'database' ] );
385
  }
386
 
 
 
387
  } elseif ( strcasecmp( 'pecl', $redis_client ) === 0 ) {
388
 
389
  $this->redis_client = 'PCEL Extension';
403
  $this->redis->select( $redis[ 'database' ] );
404
  }
405
 
 
 
406
  } else {
407
 
408
  $this->redis_client = 'Predis';
409
 
410
+ // Require PHP 5.4 or greater
411
  if ( version_compare( PHP_VERSION, '5.4.0', '<' ) ) {
412
  throw new Exception;
413
  }
414
 
415
+ // Load bundled Predis library
416
+ if ( ! class_exists( 'Predis\Client' ) ) {
417
+ require_once WP_CONTENT_DIR . '/plugins/redis-cache/includes/predis.php';
418
+ Predis\Autoloader::register();
419
  }
420
 
 
 
 
 
421
  $this->redis = new Predis\Client( $redis );
422
  $this->redis->connect();
423
 
 
424
  $this->redis_client .= ' v' . Predis\Client::VERSION;
425
 
426
  }
427
 
428
+ // Throws exception if Redis is unavailable
429
+ $this->redis->ping();
430
+
431
+ $this->redis_connected = true;
432
+
433
  } catch ( Exception $exception ) {
434
 
435
  // When Redis is unavailable, fall back to the internal back by forcing all groups to be "no redis" groups
523
  $expiration = $this->validate_expiration( $expiration );
524
 
525
  if ( $expiration ) {
526
+ $result = $this->parse_redis_response( $this->redis->setex( $derived_key, $expiration, $this->maybe_serialize( $value ) ) );
527
  } else {
528
+ $result = $this->parse_redis_response( $this->redis->set( $derived_key, $this->maybe_serialize( $value ) ) );
529
  }
530
  }
531
 
558
  }
559
 
560
  if ( $this->redis_status() && ! in_array( $group, $this->no_redis_groups ) ) {
561
+ $result = $this->parse_redis_response( $this->redis->del( $derived_key ) );
562
  }
563
 
564
  return $result;
579
  $this->cache = array();
580
 
581
  if ( $this->redis_status() ) {
582
+ $result = $this->parse_redis_response( $this->redis->flushdb() );
583
  }
584
 
585
  return $result;
611
  return false;
612
  } else {
613
  $this->cache_hits++;
614
+ $value = $this->maybe_unserialize( $result );
615
  }
616
 
617
  $this->add_to_internal_cache( $derived_key, $value );
618
 
619
+ $value = is_object( $value ) ? clone $value : $value;
620
+
621
+ do_action( 'redis_object_cache_get', $key, $value, $group );
622
+
623
+ return apply_filters( 'redis_object_cache_get', $value, $key, $group );
624
  }
625
 
626
  /**
704
  if ( ! in_array( $group, $this->no_redis_groups ) && $this->redis_status() ) {
705
  $expiration = $this->validate_expiration($expiration);
706
  if ( $expiration ) {
707
+ $result = $this->parse_redis_response( $this->redis->setex( $derived_key, $expiration, $this->maybe_serialize( $value ) ) );
708
  } else {
709
+ $result = $this->parse_redis_response( $this->redis->set( $derived_key, $this->maybe_serialize( $value ) ) );
710
  }
711
  }
712
 
715
  $this->add_to_internal_cache( $derived_key, $value );
716
  }
717
 
718
+ do_action( 'redis_object_cache_set', $key, $value, $group, $expiration );
719
+
720
  return $result;
721
  }
722
 
742
  }
743
 
744
  // Save to Redis
745
+ $result = $this->parse_redis_response( $this->redis->incrBy( $derived_key, $offset ) );
746
 
747
  $this->add_to_internal_cache( $derived_key, (int) $this->redis->get( $derived_key ) );
748
 
771
  }
772
 
773
  // Save to Redis
774
+ $result = $this->parse_redis_response( $this->redis->decrBy( $derived_key, $offset ) );
775
 
776
  $this->add_to_internal_cache( $derived_key, (int) $this->redis->get( $derived_key ) );
777
 
791
  <strong>Cache Misses:</strong> <?php echo $this->cache_misses; ?>
792
  </p>
793
 
 
 
794
  <ul>
 
795
  <?php foreach ( $this->cache as $group => $cache ) : ?>
796
+ <li><?php printf( '%s - %sk', strip_tags( $group ), number_format( strlen( serialize( $cache ) ) / 1024, 2 ) ); ?></li>
797
  <?php endforeach; ?>
798
  </ul><?php
799
 
842
  }
843
 
844
  /**
845
+ * Convert Redis responses into something meaningful
846
  *
847
  * @param mixed $response
848
  * @return mixed
849
  */
850
+ protected function parse_redis_response( $response ) {
851
  if ( is_bool( $response ) ) {
852
  return $response;
853
  }
945
  return $expiration;
946
  }
947
 
948
+ /**
949
+ * Unserialize value only if it was serialized.
950
+ *
951
+ * @param string $original Maybe unserialized original, if is needed.
952
+ * @return mixed Unserialized data can be any type.
953
+ */
954
+ protected function maybe_unserialize( $original ) {
955
+ if ( $this->is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
956
+ return @unserialize( $original );
957
+ return $original;
958
+ }
959
+
960
+ /**
961
+ * Serialize data, if needed.
962
+ * @param string|array|object $data Data that might be serialized.
963
+ * @return mixed A scalar data
964
+ */
965
+ protected function maybe_serialize( $data ) {
966
+ if ( is_array( $data ) || is_object( $data ) )
967
+ return serialize( $data );
968
+
969
+ if ( $this->is_serialized( $data, false ) )
970
+ return serialize( $data );
971
+
972
+ return $data;
973
+ }
974
+
975
+ /**
976
+ * Check value to find if it was serialized.
977
+ *
978
+ * If $data is not an string, then returned value will always be false.
979
+ * Serialized data is always a string.
980
+ *
981
+ * @param string $data Value to check to see if was serialized.
982
+ * @param bool $strict Optional. Whether to be strict about the end of the string. Default true.
983
+ * @return bool False if not serialized and true if it was.
984
+ */
985
+ protected function is_serialized( $data, $strict = true ) {
986
+
987
+ // if it isn't a string, it isn't serialized.
988
+ if ( ! is_string( $data ) ) {
989
+ return false;
990
+ }
991
+ $data = trim( $data );
992
+ if ( 'N;' == $data ) {
993
+ return true;
994
+ }
995
+ if ( strlen( $data ) < 4 ) {
996
+ return false;
997
+ }
998
+ if ( ':' !== $data[1] ) {
999
+ return false;
1000
+ }
1001
+ if ( $strict ) {
1002
+ $lastc = substr( $data, -1 );
1003
+ if ( ';' !== $lastc && '}' !== $lastc ) {
1004
+ return false;
1005
+ }
1006
+ } else {
1007
+ $semicolon = strpos( $data, ';' );
1008
+ $brace = strpos( $data, '}' );
1009
+ // Either ; or } must exist.
1010
+ if ( false === $semicolon && false === $brace )
1011
+ return false;
1012
+ // But neither must be in the first X characters.
1013
+ if ( false !== $semicolon && $semicolon < 3 )
1014
+ return false;
1015
+ if ( false !== $brace && $brace < 4 )
1016
+ return false;
1017
+ }
1018
+ $token = $data[0];
1019
+ switch ( $token ) {
1020
+ case 's' :
1021
+ if ( $strict ) {
1022
+ if ( '"' !== substr( $data, -2, 1 ) ) {
1023
+ return false;
1024
+ }
1025
+ } elseif ( false === strpos( $data, '"' ) ) {
1026
+ return false;
1027
+ }
1028
+ // or else fall through
1029
+ case 'a' :
1030
+ case 'O' :
1031
+ return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
1032
+ case 'b' :
1033
+ case 'i' :
1034
+ case 'd' :
1035
+ $end = $strict ? '$' : '';
1036
+ return (bool) preg_match( "/^{$token}:[0-9.E-]+;$end/", $data );
1037
+ }
1038
+ return false;
1039
+ }
1040
+
1041
  }
includes/predis.php CHANGED
@@ -11,8 +11,6 @@
11
 
12
  namespace Predis\Command;
13
 
14
- use InvalidArgumentException;
15
-
16
  /**
17
  * Defines an abstraction representing a Redis command.
18
  *
@@ -201,6 +199,7 @@ abstract class Command implements CommandInterface
201
 
202
  /**
203
  * @link http://redis.io/commands/zrange
 
204
  * @author Daniele Alessandri <suppakilla@gmail.com>
205
  */
206
  class ZSetRange extends Command
@@ -280,7 +279,7 @@ class ZSetRange extends Command
280
  if ($this->withScores()) {
281
  $result = array();
282
 
283
- for ($i = 0; $i < count($data); $i++) {
284
  $result[$data[$i]] = $data[++$i];
285
  }
286
 
@@ -293,6 +292,7 @@ class ZSetRange extends Command
293
 
294
  /**
295
  * @link http://redis.io/commands/sinterstore
 
296
  * @author Daniele Alessandri <suppakilla@gmail.com>
297
  */
298
  class SetIntersectionStore extends Command
@@ -319,95 +319,116 @@ class SetIntersectionStore extends Command
319
  }
320
 
321
  /**
322
- * @link http://redis.io/commands/sinter
 
323
  * @author Daniele Alessandri <suppakilla@gmail.com>
324
  */
325
- class SetIntersection extends Command
326
  {
327
  /**
328
  * {@inheritdoc}
329
  */
330
  public function getId()
331
  {
332
- return 'SINTER';
333
  }
334
 
335
  /**
336
- * {@inheritdoc}
 
 
337
  */
338
- protected function filterArguments(array $arguments)
339
  {
340
- return self::normalizeArguments($arguments);
341
  }
342
  }
343
 
344
  /**
345
- * @link http://redis.io/commands/eval
 
346
  * @author Daniele Alessandri <suppakilla@gmail.com>
347
  */
348
- class ServerEval extends Command
349
  {
350
  /**
351
  * {@inheritdoc}
352
  */
353
  public function getId()
354
  {
355
- return 'EVAL';
356
  }
357
 
358
  /**
359
- * Calculates the SHA1 hash of the body of the script.
360
- *
361
- * @return string SHA1 hash.
362
  */
363
- public function getScriptHash()
364
  {
365
- return sha1($this->getArgument(0));
366
  }
367
  }
368
 
369
  /**
370
- * @link http://redis.io/commands/rename
 
371
  * @author Daniele Alessandri <suppakilla@gmail.com>
372
  */
373
- class KeyRename extends Command
374
  {
375
  /**
376
  * {@inheritdoc}
377
  */
378
  public function getId()
379
  {
380
- return 'RENAME';
 
 
 
 
 
 
 
 
381
  }
382
  }
383
 
384
  /**
385
- * @link http://redis.io/commands/setex
 
386
  * @author Daniele Alessandri <suppakilla@gmail.com>
387
  */
388
- class StringSetExpire extends Command
389
  {
390
  /**
391
  * {@inheritdoc}
392
  */
393
  public function getId()
394
  {
395
- return 'SETEX';
 
 
 
 
 
 
 
 
396
  }
397
  }
398
 
399
  /**
400
- * @link http://redis.io/commands/mset
 
401
  * @author Daniele Alessandri <suppakilla@gmail.com>
402
  */
403
- class StringSetMultiple extends Command
404
  {
405
  /**
406
  * {@inheritdoc}
407
  */
408
  public function getId()
409
  {
410
- return 'MSET';
411
  }
412
 
413
  /**
@@ -415,24 +436,34 @@ class StringSetMultiple extends Command
415
  */
416
  protected function filterArguments(array $arguments)
417
  {
418
- if (count($arguments) === 1 && is_array($arguments[0])) {
419
- $flattenedKVs = array();
420
- $args = $arguments[0];
421
-
422
- foreach ($args as $k => $v) {
423
- $flattenedKVs[] = $k;
424
- $flattenedKVs[] = $v;
425
- }
426
-
427
- return $flattenedKVs;
428
  }
429
 
430
  return $arguments;
431
  }
432
  }
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  /**
435
  * @link http://redis.io/commands/expireat
 
436
  * @author Daniele Alessandri <suppakilla@gmail.com>
437
  */
438
  class KeyExpireAt extends Command
@@ -455,35 +486,24 @@ class KeyExpireAt extends Command
455
  }
456
 
457
  /**
458
- * @link http://redis.io/commands/blpop
 
459
  * @author Daniele Alessandri <suppakilla@gmail.com>
460
  */
461
- class ListPopFirstBlocking extends Command
462
  {
463
  /**
464
  * {@inheritdoc}
465
  */
466
  public function getId()
467
  {
468
- return 'BLPOP';
469
- }
470
-
471
- /**
472
- * {@inheritdoc}
473
- */
474
- protected function filterArguments(array $arguments)
475
- {
476
- if (count($arguments) === 2 && is_array($arguments[0])) {
477
- list($arguments, $timeout) = $arguments;
478
- array_push($arguments, $timeout);
479
- }
480
-
481
- return $arguments;
482
  }
483
  }
484
 
485
  /**
486
  * @link http://redis.io/commands/unsubscribe
 
487
  * @author Daniele Alessandri <suppakilla@gmail.com>
488
  */
489
  class PubSubUnsubscribe extends Command
@@ -506,130 +526,133 @@ class PubSubUnsubscribe extends Command
506
  }
507
 
508
  /**
509
- * @link http://redis.io/commands/info
 
510
  * @author Daniele Alessandri <suppakilla@gmail.com>
511
  */
512
- class ServerInfo extends Command
513
  {
514
  /**
515
  * {@inheritdoc}
516
  */
517
  public function getId()
518
  {
519
- return 'INFO';
520
  }
521
 
522
  /**
523
  * {@inheritdoc}
524
  */
525
- public function parseResponse($data)
526
  {
527
- $info = array();
528
- $infoLines = preg_split('/\r?\n/', $data);
529
 
530
- foreach ($infoLines as $row) {
531
- if (strpos($row, ':') === false) {
532
- continue;
533
- }
534
 
535
- list($k, $v) = $this->parseRow($row);
536
- $info[$k] = $v;
 
 
 
537
  }
538
 
539
- return $info;
540
  }
541
 
542
  /**
543
- * Parses a single row of the response and returns the key-value pair.
544
  *
545
- * @param string $row Single row of the response.
546
  *
547
  * @return array
548
  */
549
- protected function parseRow($row)
550
  {
551
- list($k, $v) = explode(':', $row, 2);
 
552
 
553
- if (preg_match('/^db\d+$/', $k)) {
554
- $v = $this->parseDatabaseStats($v);
 
 
 
 
555
  }
556
 
557
- return array($k, $v);
 
 
 
 
 
558
  }
 
559
 
 
 
 
 
 
 
 
560
  /**
561
- * Extracts the statistics of each logical DB from the string buffer.
562
- *
563
- * @param string $str Response buffer.
564
- *
565
- * @return array
566
  */
567
- protected function parseDatabaseStats($str)
568
  {
569
- $db = array();
570
-
571
- foreach (explode(',', $str) as $dbvar) {
572
- list($dbvk, $dbvv) = explode('=', $dbvar);
573
- $db[trim($dbvk)] = $dbvv;
574
- }
575
-
576
- return $db;
577
  }
578
 
579
  /**
580
- * Parses the response and extracts the allocation statistics.
581
- *
582
- * @param string $str Response buffer.
583
- *
584
- * @return array
585
  */
586
- protected function parseAllocationStats($str)
587
  {
588
- $stats = array();
589
-
590
- foreach (explode(',', $str) as $kv) {
591
- @list($size, $objects, $extra) = explode('=', $kv);
592
 
593
- // hack to prevent incorrect values when parsing the >=256 key
594
- if (isset($extra)) {
595
- $size = ">=$objects";
596
- $objects = $extra;
597
- }
598
 
599
- $stats[$size] = $objects;
 
 
600
  }
601
 
602
- return $stats;
 
 
 
 
 
 
 
 
603
  }
604
  }
605
 
606
  /**
607
- * @link http://redis.io/commands/evalsha
 
608
  * @author Daniele Alessandri <suppakilla@gmail.com>
609
  */
610
- class ServerEvalSHA extends ServerEval
611
  {
612
  /**
613
  * {@inheritdoc}
614
  */
615
  public function getId()
616
  {
617
- return 'EVALSHA';
618
- }
619
-
620
- /**
621
- * Returns the SHA1 hash of the body of the script.
622
- *
623
- * @return string SHA1 hash.
624
- */
625
- public function getScriptHash()
626
- {
627
- return $this->getArgument(0);
628
  }
629
  }
630
 
631
  /**
632
  * @link http://redis.io/commands/expire
 
633
  * @author Daniele Alessandri <suppakilla@gmail.com>
634
  */
635
  class KeyExpire extends Command
@@ -652,133 +675,107 @@ class KeyExpire extends Command
652
  }
653
 
654
  /**
655
- * @link http://redis.io/commands/subscribe
 
656
  * @author Daniele Alessandri <suppakilla@gmail.com>
657
  */
658
- class PubSubSubscribe extends Command
659
  {
660
  /**
661
  * {@inheritdoc}
662
  */
663
  public function getId()
664
  {
665
- return 'SUBSCRIBE';
666
  }
667
 
668
  /**
669
  * {@inheritdoc}
670
  */
671
- protected function filterArguments(array $arguments)
672
  {
673
- return self::normalizeArguments($arguments);
674
- }
675
- }
676
 
677
- /**
678
- * @link http://redis.io/commands/rpush
679
- * @author Daniele Alessandri <suppakilla@gmail.com>
680
- */
681
- class ListPushTail extends Command
682
- {
683
- /**
684
- * {@inheritdoc}
685
- */
686
- public function getId()
687
- {
688
- return 'RPUSH';
689
- }
690
 
691
- /**
692
- * {@inheritdoc}
693
- */
694
- protected function filterArguments(array $arguments)
695
- {
696
- return self::normalizeVariadic($arguments);
697
- }
698
- }
699
 
700
- /**
701
- * @link http://redis.io/commands/ttl
702
- * @author Daniele Alessandri <suppakilla@gmail.com>
703
- */
704
- class KeyTimeToLive extends Command
705
- {
706
- /**
707
- * {@inheritdoc}
708
- */
709
- public function getId()
710
- {
711
- return 'TTL';
712
  }
713
- }
714
 
715
- /**
716
- * @link http://redis.io/commands/zunionstore
717
- * @author Daniele Alessandri <suppakilla@gmail.com>
718
- */
719
- class ZSetUnionStore extends Command
720
- {
721
  /**
722
- * {@inheritdoc}
 
 
 
 
723
  */
724
- public function getId()
725
  {
726
- return 'ZUNIONSTORE';
 
 
 
 
 
 
727
  }
728
 
729
  /**
730
- * {@inheritdoc}
 
 
 
 
731
  */
732
- protected function filterArguments(array $arguments)
733
  {
734
- $options = array();
735
- $argc = count($arguments);
736
-
737
- if ($argc > 2 && is_array($arguments[$argc - 1])) {
738
- $options = $this->prepareOptions(array_pop($arguments));
739
- }
740
 
741
- if (is_array($arguments[1])) {
742
- $arguments = array_merge(
743
- array($arguments[0], count($arguments[1])),
744
- $arguments[1]
745
- );
746
  }
747
 
748
- return array_merge($arguments, $options);
749
  }
750
 
751
  /**
752
- * Returns a list of options and modifiers compatible with Redis.
753
  *
754
- * @param array $options List of options.
755
  *
756
  * @return array
757
  */
758
- private function prepareOptions($options)
759
  {
760
- $opts = array_change_key_case($options, CASE_UPPER);
761
- $finalizedOpts = array();
762
 
763
- if (isset($opts['WEIGHTS']) && is_array($opts['WEIGHTS'])) {
764
- $finalizedOpts[] = 'WEIGHTS';
765
 
766
- foreach ($opts['WEIGHTS'] as $weight) {
767
- $finalizedOpts[] = $weight;
 
 
768
  }
769
- }
770
 
771
- if (isset($opts['AGGREGATE'])) {
772
- $finalizedOpts[] = 'AGGREGATE';
773
- $finalizedOpts[] = $opts['AGGREGATE'];
774
  }
775
 
776
- return $finalizedOpts;
777
  }
778
  }
779
 
780
  /**
781
  * @link http://redis.io/commands/zrangebyscore
 
782
  * @author Daniele Alessandri <suppakilla@gmail.com>
783
  */
784
  class ZSetRangeByScore extends ZSetRange
@@ -817,7 +814,7 @@ class ZSetRangeByScore extends ZSetRange
817
  {
818
  $arguments = $this->getArguments();
819
 
820
- for ($i = 3; $i < count($arguments); $i++) {
821
  switch (strtoupper($arguments[$i])) {
822
  case 'WITHSCORES':
823
  return true;
@@ -833,138 +830,144 @@ class ZSetRangeByScore extends ZSetRange
833
  }
834
 
835
  /**
836
- * @link http://redis.io/commands/zremrangebyrank
 
837
  * @author Daniele Alessandri <suppakilla@gmail.com>
838
  */
839
- class ZSetRemoveRangeByRank extends Command
840
  {
841
  /**
842
  * {@inheritdoc}
843
  */
844
  public function getId()
845
  {
846
- return 'ZREMRANGEBYRANK';
847
  }
848
- }
849
 
850
- /**
851
- * @link http://redis.io/commands/spop
852
- * @author Daniele Alessandri <suppakilla@gmail.com>
853
- */
854
- class SetPop extends Command
855
- {
856
  /**
857
  * {@inheritdoc}
858
  */
859
- public function getId()
860
  {
861
- return 'SPOP';
 
 
 
 
 
 
 
 
 
 
 
 
862
  }
863
  }
864
 
865
  /**
866
- * @link http://redis.io/commands/smove
 
867
  * @author Daniele Alessandri <suppakilla@gmail.com>
868
  */
869
- class SetMove extends Command
870
  {
871
  /**
872
  * {@inheritdoc}
873
  */
874
  public function getId()
875
  {
876
- return 'SMOVE';
877
  }
878
 
879
  /**
880
- * {@inheritdoc}
 
 
881
  */
882
- public function parseResponse($data)
883
  {
884
- return (bool) $data;
885
  }
886
  }
887
 
888
  /**
889
- * @link http://redis.io/commands/sismember
 
890
  * @author Daniele Alessandri <suppakilla@gmail.com>
891
  */
892
- class SetIsMember extends Command
893
  {
894
  /**
895
  * {@inheritdoc}
896
  */
897
  public function getId()
898
  {
899
- return 'SISMEMBER';
900
- }
901
-
902
- /**
903
- * {@inheritdoc}
904
- */
905
- public function parseResponse($data)
906
- {
907
- return (bool) $data;
908
  }
909
  }
910
 
911
  /**
912
- * @link http://redis.io/commands/smembers
 
913
  * @author Daniele Alessandri <suppakilla@gmail.com>
914
  */
915
- class SetMembers extends Command
916
  {
917
  /**
918
  * {@inheritdoc}
919
  */
920
  public function getId()
921
  {
922
- return 'SMEMBERS';
923
  }
924
  }
925
 
926
  /**
927
- * @link http://redis.io/commands/zremrangebyscore
 
928
  * @author Daniele Alessandri <suppakilla@gmail.com>
929
  */
930
- class ZSetRemoveRangeByScore extends Command
931
  {
932
  /**
933
  * {@inheritdoc}
934
  */
935
  public function getId()
936
  {
937
- return 'ZREMRANGEBYSCORE';
938
  }
939
  }
940
 
941
  /**
942
- * @link http://redis.io/commands/srandmember
 
943
  * @author Daniele Alessandri <suppakilla@gmail.com>
944
  */
945
- class SetRandomMember extends Command
946
  {
947
  /**
948
  * {@inheritdoc}
949
  */
950
  public function getId()
951
  {
952
- return 'SRANDMEMBER';
953
  }
954
  }
955
 
956
  /**
957
- * @link http://redis.io/commands/sscan
 
958
  * @author Daniele Alessandri <suppakilla@gmail.com>
959
  */
960
- class SetScan extends Command
961
  {
962
  /**
963
  * {@inheritdoc}
964
  */
965
  public function getId()
966
  {
967
- return 'SSCAN';
968
  }
969
 
970
  /**
@@ -973,394 +976,411 @@ class SetScan extends Command
973
  protected function filterArguments(array $arguments)
974
  {
975
  if (count($arguments) === 3 && is_array($arguments[2])) {
976
- $options = $this->prepareOptions(array_pop($arguments));
977
- $arguments = array_merge($arguments, $options);
 
978
  }
979
 
980
  return $arguments;
981
  }
982
-
983
- /**
984
- * Returns a list of options and modifiers compatible with Redis.
985
- *
986
- * @param array $options List of options.
987
- *
988
- * @return array
989
- */
990
- protected function prepareOptions($options)
991
- {
992
- $options = array_change_key_case($options, CASE_UPPER);
993
- $normalized = array();
994
-
995
- if (!empty($options['MATCH'])) {
996
- $normalized[] = 'MATCH';
997
- $normalized[] = $options['MATCH'];
998
- }
999
-
1000
- if (!empty($options['COUNT'])) {
1001
- $normalized[] = 'COUNT';
1002
- $normalized[] = $options['COUNT'];
1003
- }
1004
-
1005
- return $normalized;
1006
- }
1007
  }
1008
 
1009
  /**
1010
- * @link http://redis.io/commands/zremrangebylex
 
1011
  * @author Daniele Alessandri <suppakilla@gmail.com>
1012
  */
1013
- class ZSetRemoveRangeByLex extends Command
1014
  {
1015
  /**
1016
  * {@inheritdoc}
1017
  */
1018
  public function getId()
1019
  {
1020
- return 'ZREMRANGEBYLEX';
1021
  }
1022
  }
1023
 
1024
  /**
1025
- * @link http://redis.io/commands/bitop
 
1026
  * @author Daniele Alessandri <suppakilla@gmail.com>
1027
  */
1028
- class StringBitOp extends Command
1029
  {
1030
  /**
1031
  * {@inheritdoc}
1032
  */
1033
  public function getId()
1034
  {
1035
- return 'BITOP';
1036
  }
 
1037
 
 
 
 
 
 
 
 
1038
  /**
1039
  * {@inheritdoc}
1040
  */
1041
- protected function filterArguments(array $arguments)
1042
  {
1043
- if (count($arguments) === 3 && is_array($arguments[2])) {
1044
- list($operation, $destination, ) = $arguments;
1045
- $arguments = $arguments[2];
1046
- array_unshift($arguments, $operation, $destination);
1047
- }
1048
-
1049
- return $arguments;
1050
  }
1051
  }
1052
 
1053
  /**
1054
- * @link http://redis.io/commands/bitcount
 
1055
  * @author Daniele Alessandri <suppakilla@gmail.com>
1056
  */
1057
- class StringBitCount extends Command
1058
  {
1059
  /**
1060
  * {@inheritdoc}
1061
  */
1062
  public function getId()
1063
  {
1064
- return 'BITCOUNT';
 
 
 
 
 
 
 
 
1065
  }
1066
  }
1067
 
1068
  /**
1069
- * @link http://redis.io/commands/append
 
1070
  * @author Daniele Alessandri <suppakilla@gmail.com>
1071
  */
1072
- class StringAppend extends Command
1073
  {
1074
  /**
1075
  * {@inheritdoc}
1076
  */
1077
  public function getId()
1078
  {
1079
- return 'APPEND';
1080
  }
1081
  }
1082
 
1083
  /**
1084
- * @link http://redis.io/commands/sunion
 
1085
  * @author Daniele Alessandri <suppakilla@gmail.com>
1086
  */
1087
- class SetUnion extends SetIntersection
1088
  {
1089
  /**
1090
  * {@inheritdoc}
1091
  */
1092
  public function getId()
1093
  {
1094
- return 'SUNION';
1095
  }
1096
  }
1097
 
1098
  /**
1099
- * @link http://redis.io/commands/sunionstore
 
1100
  * @author Daniele Alessandri <suppakilla@gmail.com>
1101
  */
1102
- class SetUnionStore extends SetIntersectionStore
1103
  {
1104
  /**
1105
  * {@inheritdoc}
1106
  */
1107
  public function getId()
1108
  {
1109
- return 'SUNIONSTORE';
1110
  }
1111
  }
1112
 
1113
  /**
1114
- * @link http://redis.io/commands/srem
 
1115
  * @author Daniele Alessandri <suppakilla@gmail.com>
1116
  */
1117
- class SetRemove extends Command
1118
  {
1119
  /**
1120
  * {@inheritdoc}
1121
  */
1122
  public function getId()
1123
  {
1124
- return 'SREM';
1125
  }
 
1126
 
 
 
 
 
 
 
 
1127
  /**
1128
  * {@inheritdoc}
1129
  */
1130
- protected function filterArguments(array $arguments)
1131
  {
1132
- return self::normalizeVariadic($arguments);
1133
  }
1134
  }
1135
 
1136
  /**
1137
- * @link http://redis.io/commands/zrevrange
 
1138
  * @author Daniele Alessandri <suppakilla@gmail.com>
1139
  */
1140
- class ZSetReverseRange extends ZSetRange
1141
  {
1142
  /**
1143
  * {@inheritdoc}
1144
  */
1145
  public function getId()
1146
  {
1147
- return 'ZREVRANGE';
1148
  }
1149
  }
1150
 
1151
  /**
1152
- * @link http://redis.io/commands/slowlog
 
1153
  * @author Daniele Alessandri <suppakilla@gmail.com>
1154
  */
1155
- class ServerSlowlog extends Command
1156
  {
1157
  /**
1158
  * {@inheritdoc}
1159
  */
1160
  public function getId()
1161
  {
1162
- return 'SLOWLOG';
1163
  }
 
1164
 
 
 
 
 
 
 
 
1165
  /**
1166
  * {@inheritdoc}
1167
  */
1168
- public function parseResponse($data)
1169
  {
1170
- if (is_array($data)) {
1171
- $log = array();
1172
-
1173
- foreach ($data as $index => $entry) {
1174
- $log[$index] = array(
1175
- 'id' => $entry[0],
1176
- 'timestamp' => $entry[1],
1177
- 'duration' => $entry[2],
1178
- 'command' => $entry[3],
1179
- );
1180
- }
1181
-
1182
- return $log;
1183
- }
1184
-
1185
- return $data;
1186
  }
1187
  }
1188
 
1189
  /**
1190
- * @link http://redis.io/commands/zscore
 
1191
  * @author Daniele Alessandri <suppakilla@gmail.com>
1192
  */
1193
- class ZSetScore extends Command
1194
  {
1195
  /**
1196
  * {@inheritdoc}
1197
  */
1198
  public function getId()
1199
  {
1200
- return 'ZSCORE';
1201
  }
1202
  }
1203
 
1204
  /**
1205
- * @link http://redis.io/commands/slaveof
 
1206
  * @author Daniele Alessandri <suppakilla@gmail.com>
1207
  */
1208
- class ServerSlaveOf extends Command
1209
  {
1210
  /**
1211
  * {@inheritdoc}
1212
  */
1213
  public function getId()
1214
  {
1215
- return 'SLAVEOF';
1216
  }
 
1217
 
 
 
 
 
 
 
 
1218
  /**
1219
  * {@inheritdoc}
1220
  */
1221
- protected function filterArguments(array $arguments)
1222
  {
1223
- if (count($arguments) === 0 || $arguments[0] === 'NO ONE') {
1224
- return array('NO', 'ONE');
1225
- }
1226
-
1227
- return $arguments;
1228
  }
1229
  }
1230
 
1231
  /**
1232
- * @link http://redis.io/commands/shutdown
 
1233
  * @author Daniele Alessandri <suppakilla@gmail.com>
1234
  */
1235
- class ServerShutdown extends Command
1236
  {
1237
  /**
1238
  * {@inheritdoc}
1239
  */
1240
  public function getId()
1241
  {
1242
- return 'SHUTDOWN';
1243
  }
1244
  }
1245
 
1246
  /**
1247
- * @link http://redis.io/commands/script
 
1248
  * @author Daniele Alessandri <suppakilla@gmail.com>
1249
  */
1250
- class ServerScript extends Command
1251
  {
1252
  /**
1253
  * {@inheritdoc}
1254
  */
1255
  public function getId()
1256
  {
1257
- return 'SCRIPT';
1258
  }
1259
  }
1260
 
1261
  /**
1262
- * @link http://redis.io/topics/sentinel
 
1263
  * @author Daniele Alessandri <suppakilla@gmail.com>
1264
  */
1265
- class ServerSentinel extends Command
1266
  {
1267
  /**
1268
  * {@inheritdoc}
1269
  */
1270
  public function getId()
1271
  {
1272
- return 'SENTINEL';
1273
  }
1274
 
1275
  /**
1276
  * {@inheritdoc}
1277
  */
1278
- public function parseResponse($data)
1279
  {
1280
- switch (strtolower($this->getArgument(0))) {
1281
- case 'masters':
1282
- case 'slaves':
1283
- return self::processMastersOrSlaves($data);
1284
 
1285
- default:
1286
- return $data;
1287
- }
 
 
 
 
 
 
 
 
 
 
1288
  }
1289
 
1290
  /**
1291
- * Returns a processed response to SENTINEL MASTERS or SENTINEL SLAVES.
1292
- *
1293
- * @param array $servers List of Redis servers.
1294
- *
1295
- * @return array
1296
  */
1297
- protected static function processMastersOrSlaves(array $servers)
1298
  {
1299
- foreach ($servers as $idx => $node) {
1300
- $processed = array();
1301
- $count = count($node);
1302
 
1303
- for ($i = 0; $i < $count; $i++) {
1304
- $processed[$node[$i]] = $node[++$i];
 
 
 
 
 
1305
  }
1306
 
1307
- $servers[$idx] = $processed;
1308
  }
1309
 
1310
- return $servers;
1311
  }
1312
  }
1313
 
1314
  /**
1315
- * @link http://redis.io/commands/zscan
 
1316
  * @author Daniele Alessandri <suppakilla@gmail.com>
1317
  */
1318
- class ZSetScan extends Command
1319
  {
1320
  /**
1321
  * {@inheritdoc}
1322
  */
1323
  public function getId()
1324
  {
1325
- return 'ZSCAN';
1326
  }
 
1327
 
 
 
 
 
 
 
 
1328
  /**
1329
  * {@inheritdoc}
1330
  */
1331
- protected function filterArguments(array $arguments)
1332
  {
1333
- if (count($arguments) === 3 && is_array($arguments[2])) {
1334
- $options = $this->prepareOptions(array_pop($arguments));
1335
- $arguments = array_merge($arguments, $options);
1336
- }
1337
-
1338
- return $arguments;
1339
  }
1340
 
1341
  /**
1342
- * Returns a list of options and modifiers compatible with Redis.
1343
- *
1344
- * @param array $options List of options.
1345
- *
1346
- * @return array
1347
  */
1348
- protected function prepareOptions($options)
1349
  {
1350
- $options = array_change_key_case($options, CASE_UPPER);
1351
- $normalized = array();
1352
-
1353
- if (!empty($options['MATCH'])) {
1354
- $normalized[] = 'MATCH';
1355
- $normalized[] = $options['MATCH'];
1356
- }
1357
 
1358
- if (!empty($options['COUNT'])) {
1359
- $normalized[] = 'COUNT';
1360
- $normalized[] = $options['COUNT'];
1361
- }
1362
-
1363
- return $normalized;
 
 
 
 
 
 
 
1364
  }
1365
 
1366
  /**
@@ -1368,357 +1388,397 @@ class ZSetScan extends Command
1368
  */
1369
  public function parseResponse($data)
1370
  {
1371
- if (is_array($data)) {
1372
- $members = $data[1];
1373
- $result = array();
1374
-
1375
- for ($i = 0; $i < count($members); $i++) {
1376
- $result[$members[$i]] = (float) $members[++$i];
1377
- }
1378
-
1379
- $data[1] = $result;
1380
- }
1381
-
1382
- return $data;
1383
  }
1384
  }
1385
 
1386
  /**
1387
- * @link http://redis.io/commands/zrevrank
 
1388
  * @author Daniele Alessandri <suppakilla@gmail.com>
1389
  */
1390
- class ZSetReverseRank extends Command
1391
  {
1392
  /**
1393
  * {@inheritdoc}
1394
  */
1395
  public function getId()
1396
  {
1397
- return 'ZREVRANK';
1398
  }
1399
- }
1400
 
1401
- /**
1402
- * @link http://redis.io/commands/sdiffstore
1403
- * @author Daniele Alessandri <suppakilla@gmail.com>
1404
- */
1405
- class SetDifferenceStore extends SetIntersectionStore
1406
- {
1407
  /**
1408
  * {@inheritdoc}
1409
  */
1410
- public function getId()
1411
  {
1412
- return 'SDIFFSTORE';
1413
  }
1414
  }
1415
 
1416
  /**
1417
- * @link http://redis.io/commands/zrevrangebyscore
 
1418
  * @author Daniele Alessandri <suppakilla@gmail.com>
1419
  */
1420
- class ZSetReverseRangeByScore extends ZSetRangeByScore
1421
  {
1422
  /**
1423
  * {@inheritdoc}
1424
  */
1425
  public function getId()
1426
  {
1427
- return 'ZREVRANGEBYSCORE';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1428
  }
1429
  }
1430
 
1431
  /**
1432
- * @link http://redis.io/commands/sdiff
 
1433
  * @author Daniele Alessandri <suppakilla@gmail.com>
1434
  */
1435
- class SetDifference extends SetIntersection
1436
  {
1437
  /**
1438
  * {@inheritdoc}
1439
  */
1440
  public function getId()
1441
  {
1442
- return 'SDIFF';
1443
  }
1444
  }
1445
 
1446
  /**
1447
- * @link http://redis.io/commands/scard
 
1448
  * @author Daniele Alessandri <suppakilla@gmail.com>
1449
  */
1450
- class SetCardinality extends Command
1451
  {
1452
  /**
1453
  * {@inheritdoc}
1454
  */
1455
  public function getId()
1456
  {
1457
- return 'SCARD';
1458
  }
1459
  }
1460
 
1461
  /**
1462
- * @link http://redis.io/commands/time
 
1463
  * @author Daniele Alessandri <suppakilla@gmail.com>
1464
  */
1465
- class ServerTime extends Command
1466
  {
1467
  /**
1468
  * {@inheritdoc}
1469
  */
1470
  public function getId()
1471
  {
1472
- return 'TIME';
1473
  }
1474
  }
1475
 
1476
  /**
1477
- * @link http://redis.io/commands/sadd
 
1478
  * @author Daniele Alessandri <suppakilla@gmail.com>
1479
  */
1480
- class SetAdd extends Command
1481
  {
1482
  /**
1483
  * {@inheritdoc}
1484
  */
1485
  public function getId()
1486
  {
1487
- return 'SADD';
1488
  }
1489
 
1490
  /**
1491
  * {@inheritdoc}
1492
  */
1493
- protected function filterArguments(array $arguments)
1494
  {
1495
- return self::normalizeVariadic($arguments);
1496
  }
1497
  }
1498
 
1499
  /**
1500
- * @link http://redis.io/commands/bitpos
 
1501
  * @author Daniele Alessandri <suppakilla@gmail.com>
1502
  */
1503
- class StringBitPos extends Command
1504
  {
1505
  /**
1506
  * {@inheritdoc}
1507
  */
1508
  public function getId()
1509
  {
1510
- return 'BITPOS';
1511
  }
1512
  }
1513
 
1514
  /**
1515
- * @link http://redis.io/commands/decrby
 
1516
  * @author Daniele Alessandri <suppakilla@gmail.com>
1517
  */
1518
- class StringDecrementBy extends Command
1519
  {
1520
  /**
1521
  * {@inheritdoc}
1522
  */
1523
  public function getId()
1524
  {
1525
- return 'DECRBY';
1526
  }
1527
- }
1528
 
1529
- /**
1530
- * @link http://redis.io/commands/substr
1531
- * @author Daniele Alessandri <suppakilla@gmail.com>
1532
- */
1533
- class StringSubstr extends Command
1534
- {
1535
  /**
1536
  * {@inheritdoc}
1537
  */
1538
- public function getId()
1539
  {
1540
- return 'SUBSTR';
1541
  }
1542
  }
1543
 
1544
  /**
1545
- * @link http://redis.io/commands/zlexcount
 
1546
  * @author Daniele Alessandri <suppakilla@gmail.com>
1547
  */
1548
- class ZSetLexCount extends Command
1549
  {
1550
  /**
1551
  * {@inheritdoc}
1552
  */
1553
  public function getId()
1554
  {
1555
- return 'ZLEXCOUNT';
1556
  }
1557
- }
1558
 
1559
- /**
1560
- * @link http://redis.io/commands/zinterstore
1561
- * @author Daniele Alessandri <suppakilla@gmail.com>
1562
- */
1563
- class ZSetIntersectionStore extends ZSetUnionStore
1564
- {
1565
  /**
1566
  * {@inheritdoc}
1567
  */
1568
- public function getId()
1569
  {
1570
- return 'ZINTERSTORE';
1571
  }
1572
  }
1573
 
1574
  /**
1575
- * @link http://redis.io/commands/strlen
 
1576
  * @author Daniele Alessandri <suppakilla@gmail.com>
1577
  */
1578
- class StringStrlen extends Command
1579
  {
1580
  /**
1581
  * {@inheritdoc}
1582
  */
1583
  public function getId()
1584
  {
1585
- return 'STRLEN';
1586
  }
1587
  }
1588
 
1589
  /**
1590
- * @link http://redis.io/commands/setrange
 
1591
  * @author Daniele Alessandri <suppakilla@gmail.com>
1592
  */
1593
- class StringSetRange extends Command
1594
  {
1595
  /**
1596
  * {@inheritdoc}
1597
  */
1598
  public function getId()
1599
  {
1600
- return 'SETRANGE';
1601
  }
1602
  }
1603
 
1604
  /**
1605
- * @link http://redis.io/commands/msetnx
 
1606
  * @author Daniele Alessandri <suppakilla@gmail.com>
1607
  */
1608
- class StringSetMultiplePreserve extends StringSetMultiple
1609
  {
1610
  /**
1611
  * {@inheritdoc}
1612
  */
1613
  public function getId()
1614
  {
1615
- return 'MSETNX';
1616
  }
 
1617
 
 
 
 
 
 
 
 
1618
  /**
1619
  * {@inheritdoc}
1620
  */
1621
- public function parseResponse($data)
1622
  {
1623
- return (bool) $data;
1624
  }
1625
  }
1626
 
1627
  /**
1628
- * @link http://redis.io/commands/setnx
 
1629
  * @author Daniele Alessandri <suppakilla@gmail.com>
1630
  */
1631
- class StringSetPreserve extends Command
1632
  {
1633
  /**
1634
  * {@inheritdoc}
1635
  */
1636
  public function getId()
1637
  {
1638
- return 'SETNX';
1639
  }
 
1640
 
 
 
 
 
 
 
 
1641
  /**
1642
  * {@inheritdoc}
1643
  */
1644
- public function parseResponse($data)
1645
  {
1646
- return (bool) $data;
1647
  }
1648
  }
1649
 
1650
  /**
1651
- * @link http://redis.io/commands/discard
 
1652
  * @author Daniele Alessandri <suppakilla@gmail.com>
1653
  */
1654
- class TransactionDiscard extends Command
1655
  {
1656
  /**
1657
  * {@inheritdoc}
1658
  */
1659
  public function getId()
1660
  {
1661
- return 'DISCARD';
1662
  }
1663
  }
1664
 
1665
  /**
1666
- * @link http://redis.io/commands/exec
 
1667
  * @author Daniele Alessandri <suppakilla@gmail.com>
1668
  */
1669
- class TransactionExec extends Command
1670
  {
1671
  /**
1672
  * {@inheritdoc}
1673
  */
1674
  public function getId()
1675
  {
1676
- return 'EXEC';
1677
  }
1678
  }
1679
 
1680
  /**
1681
- * @link http://redis.io/commands/zcard
 
1682
  * @author Daniele Alessandri <suppakilla@gmail.com>
1683
  */
1684
- class ZSetCardinality extends Command
1685
  {
1686
  /**
1687
  * {@inheritdoc}
1688
  */
1689
  public function getId()
1690
  {
1691
- return 'ZCARD';
1692
  }
1693
  }
1694
 
1695
  /**
1696
- * @link http://redis.io/commands/zcount
 
1697
  * @author Daniele Alessandri <suppakilla@gmail.com>
1698
  */
1699
- class ZSetCount extends Command
1700
  {
1701
  /**
1702
  * {@inheritdoc}
1703
  */
1704
  public function getId()
1705
  {
1706
- return 'ZCOUNT';
1707
  }
1708
  }
1709
 
1710
  /**
1711
- * @link http://redis.io/commands/zadd
 
1712
  * @author Daniele Alessandri <suppakilla@gmail.com>
1713
  */
1714
- class ZSetAdd extends Command
1715
  {
1716
  /**
1717
  * {@inheritdoc}
1718
  */
1719
  public function getId()
1720
  {
1721
- return 'ZADD';
1722
  }
1723
 
1724
  /**
@@ -1726,403 +1786,430 @@ class ZSetAdd extends Command
1726
  */
1727
  protected function filterArguments(array $arguments)
1728
  {
1729
- if (count($arguments) === 2 && is_array($arguments[1])) {
1730
- $flattened = array($arguments[0]);
1731
-
1732
- foreach ($arguments[1] as $member => $score) {
1733
- $flattened[] = $score;
1734
- $flattened[] = $member;
1735
- }
1736
-
1737
- return $flattened;
1738
  }
1739
 
1740
  return $arguments;
1741
  }
1742
- }
1743
 
1744
- /**
1745
- * @link http://redis.io/commands/watch
1746
- * @author Daniele Alessandri <suppakilla@gmail.com>
1747
- */
1748
- class TransactionWatch extends Command
1749
- {
1750
  /**
1751
- * {@inheritdoc}
 
 
 
 
1752
  */
1753
- public function getId()
1754
  {
1755
- return 'WATCH';
 
 
 
 
 
 
 
 
 
 
 
 
 
1756
  }
1757
 
1758
  /**
1759
  * {@inheritdoc}
1760
  */
1761
- protected function filterArguments(array $arguments)
1762
  {
1763
- if (isset($arguments[0]) && is_array($arguments[0])) {
1764
- return $arguments[0];
 
 
 
 
 
 
 
1765
  }
1766
 
1767
- return $arguments;
1768
  }
1769
  }
1770
 
1771
  /**
1772
- * @link http://redis.io/commands/multi
 
1773
  * @author Daniele Alessandri <suppakilla@gmail.com>
1774
  */
1775
- class TransactionMulti extends Command
1776
  {
1777
  /**
1778
  * {@inheritdoc}
1779
  */
1780
  public function getId()
1781
  {
1782
- return 'MULTI';
1783
  }
1784
  }
1785
 
1786
- /**
1787
- * @link http://redis.io/commands/unwatch
1788
- * @author Daniele Alessandri <suppakilla@gmail.com>
1789
- */
1790
- class TransactionUnwatch extends Command
1791
  {
1792
  /**
1793
  * {@inheritdoc}
1794
  */
1795
  public function getId()
1796
  {
1797
- return 'UNWATCH';
1798
  }
1799
  }
1800
 
1801
  /**
1802
- * @link http://redis.io/commands/zrangebylex
 
1803
  * @author Daniele Alessandri <suppakilla@gmail.com>
1804
  */
1805
- class ZSetRangeByLex extends ZSetRange
1806
  {
1807
  /**
1808
  * {@inheritdoc}
1809
  */
1810
  public function getId()
1811
  {
1812
- return 'ZRANGEBYLEX';
1813
  }
 
1814
 
 
 
 
 
 
 
 
1815
  /**
1816
  * {@inheritdoc}
1817
  */
1818
- protected function prepareOptions($options)
1819
  {
1820
- $opts = array_change_key_case($options, CASE_UPPER);
1821
- $finalizedOpts = array();
1822
-
1823
- if (isset($opts['LIMIT']) && is_array($opts['LIMIT'])) {
1824
- $limit = array_change_key_case($opts['LIMIT'], CASE_UPPER);
1825
-
1826
- $finalizedOpts[] = 'LIMIT';
1827
- $finalizedOpts[] = isset($limit['OFFSET']) ? $limit['OFFSET'] : $limit[0];
1828
- $finalizedOpts[] = isset($limit['COUNT']) ? $limit['COUNT'] : $limit[1];
1829
- }
1830
-
1831
- return $finalizedOpts;
1832
  }
 
1833
 
 
 
 
 
 
 
 
1834
  /**
1835
  * {@inheritdoc}
1836
  */
1837
- protected function withScores()
1838
  {
1839
- return false;
1840
  }
1841
  }
1842
 
1843
  /**
1844
- * @link http://redis.io/commands/zrank
 
1845
  * @author Daniele Alessandri <suppakilla@gmail.com>
1846
  */
1847
- class ZSetRank extends Command
1848
  {
1849
  /**
1850
  * {@inheritdoc}
1851
  */
1852
  public function getId()
1853
  {
1854
- return 'ZRANK';
1855
  }
1856
  }
1857
 
1858
  /**
1859
- * @link http://redis.io/commands/mget
 
1860
  * @author Daniele Alessandri <suppakilla@gmail.com>
1861
  */
1862
- class StringGetMultiple extends Command
1863
  {
1864
  /**
1865
  * {@inheritdoc}
1866
  */
1867
  public function getId()
1868
  {
1869
- return 'MGET';
1870
  }
 
1871
 
 
 
 
 
 
 
 
1872
  /**
1873
  * {@inheritdoc}
1874
  */
1875
- protected function filterArguments(array $arguments)
1876
  {
1877
- return self::normalizeArguments($arguments);
1878
  }
1879
  }
1880
 
1881
  /**
1882
- * @link http://redis.io/commands/getrange
 
1883
  * @author Daniele Alessandri <suppakilla@gmail.com>
1884
  */
1885
- class StringGetRange extends Command
1886
  {
1887
  /**
1888
  * {@inheritdoc}
1889
  */
1890
  public function getId()
1891
  {
1892
- return 'GETRANGE';
1893
  }
1894
  }
1895
 
1896
  /**
1897
- * @link http://redis.io/commands/zrem
 
1898
  * @author Daniele Alessandri <suppakilla@gmail.com>
1899
  */
1900
- class ZSetRemove extends Command
1901
  {
1902
  /**
1903
  * {@inheritdoc}
1904
  */
1905
  public function getId()
1906
  {
1907
- return 'ZREM';
1908
  }
1909
 
1910
  /**
1911
  * {@inheritdoc}
1912
  */
1913
- protected function filterArguments(array $arguments)
1914
  {
1915
- return self::normalizeVariadic($arguments);
1916
  }
1917
  }
1918
 
1919
  /**
1920
- * @link http://redis.io/commands/getbit
 
1921
  * @author Daniele Alessandri <suppakilla@gmail.com>
1922
  */
1923
- class StringGetBit extends Command
1924
  {
1925
  /**
1926
  * {@inheritdoc}
1927
  */
1928
  public function getId()
1929
  {
1930
- return 'GETBIT';
1931
  }
1932
  }
1933
 
1934
  /**
1935
- * @link http://redis.io/commands/zincrby
 
1936
  * @author Daniele Alessandri <suppakilla@gmail.com>
1937
  */
1938
- class ZSetIncrementBy extends Command
1939
  {
1940
  /**
1941
  * {@inheritdoc}
1942
  */
1943
  public function getId()
1944
  {
1945
- return 'ZINCRBY';
1946
  }
1947
- }
1948
 
1949
- /**
1950
- * @link http://redis.io/commands/get
1951
- * @author Daniele Alessandri <suppakilla@gmail.com>
1952
- */
1953
- class StringGet extends Command
1954
- {
1955
  /**
1956
  * {@inheritdoc}
1957
  */
1958
- public function getId()
1959
  {
1960
- return 'GET';
1961
  }
1962
  }
1963
 
1964
  /**
1965
- * @link http://redis.io/commands/getset
 
1966
  * @author Daniele Alessandri <suppakilla@gmail.com>
1967
  */
1968
- class StringGetSet extends Command
1969
  {
1970
  /**
1971
  * {@inheritdoc}
1972
  */
1973
  public function getId()
1974
  {
1975
- return 'GETSET';
1976
  }
1977
  }
1978
 
1979
  /**
1980
- * @link http://redis.io/commands/incr
 
1981
  * @author Daniele Alessandri <suppakilla@gmail.com>
1982
  */
1983
- class StringIncrement extends Command
1984
  {
1985
  /**
1986
  * {@inheritdoc}
1987
  */
1988
  public function getId()
1989
  {
1990
- return 'INCR';
1991
  }
1992
  }
1993
 
1994
  /**
1995
- * @link http://redis.io/commands/set
 
1996
  * @author Daniele Alessandri <suppakilla@gmail.com>
1997
  */
1998
- class StringSet extends Command
1999
  {
2000
  /**
2001
  * {@inheritdoc}
2002
  */
2003
  public function getId()
2004
  {
2005
- return 'SET';
2006
  }
2007
  }
2008
 
2009
  /**
2010
- * @link http://redis.io/commands/setbit
 
2011
  * @author Daniele Alessandri <suppakilla@gmail.com>
2012
  */
2013
- class StringSetBit extends Command
2014
  {
2015
  /**
2016
  * {@inheritdoc}
2017
  */
2018
  public function getId()
2019
  {
2020
- return 'SETBIT';
2021
  }
2022
  }
2023
 
2024
  /**
2025
- * @link http://redis.io/commands/psetex
 
2026
  * @author Daniele Alessandri <suppakilla@gmail.com>
2027
  */
2028
- class StringPreciseSetExpire extends StringSetExpire
2029
  {
2030
  /**
2031
  * {@inheritdoc}
2032
  */
2033
  public function getId()
2034
  {
2035
- return 'PSETEX';
2036
  }
2037
  }
2038
 
2039
  /**
2040
- * @link http://redis.io/commands/incrbyfloat
 
2041
  * @author Daniele Alessandri <suppakilla@gmail.com>
2042
  */
2043
- class StringIncrementByFloat extends Command
2044
  {
2045
  /**
2046
  * {@inheritdoc}
2047
  */
2048
  public function getId()
2049
  {
2050
- return 'INCRBYFLOAT';
2051
  }
2052
- }
2053
 
2054
- /**
2055
- * @link http://redis.io/commands/incrby
2056
- * @author Daniele Alessandri <suppakilla@gmail.com>
2057
- */
2058
- class StringIncrementBy extends Command
2059
- {
2060
  /**
2061
  * {@inheritdoc}
2062
  */
2063
- public function getId()
2064
  {
2065
- return 'INCRBY';
 
 
 
 
 
 
 
2066
  }
2067
  }
2068
 
2069
  /**
2070
- * @link http://redis.io/commands/save
 
2071
  * @author Daniele Alessandri <suppakilla@gmail.com>
2072
  */
2073
- class ServerSave extends Command
2074
  {
2075
  /**
2076
  * {@inheritdoc}
2077
  */
2078
  public function getId()
2079
  {
2080
- return 'SAVE';
2081
  }
2082
  }
2083
 
2084
  /**
2085
- * @link http://redis.io/commands/decr
 
2086
  * @author Daniele Alessandri <suppakilla@gmail.com>
2087
  */
2088
- class StringDecrement extends Command
2089
  {
2090
  /**
2091
  * {@inheritdoc}
2092
  */
2093
  public function getId()
2094
  {
2095
- return 'DECR';
2096
  }
2097
- }
2098
 
2099
- /**
2100
- * @link http://redis.io/commands/flushall
2101
- * @author Daniele Alessandri <suppakilla@gmail.com>
2102
- */
2103
- class ServerFlushAll extends Command
2104
- {
2105
  /**
2106
  * {@inheritdoc}
2107
  */
2108
- public function getId()
2109
  {
2110
- return 'FLUSHALL';
2111
- }
 
 
 
 
2112
  }
2113
 
2114
  /**
2115
- * @link http://redis.io/commands/del
 
2116
  * @author Daniele Alessandri <suppakilla@gmail.com>
2117
  */
2118
- class KeyDelete extends Command
2119
  {
2120
  /**
2121
  * {@inheritdoc}
2122
  */
2123
  public function getId()
2124
  {
2125
- return 'DEL';
2126
  }
2127
 
2128
  /**
@@ -2130,37 +2217,43 @@ class KeyDelete extends Command
2130
  */
2131
  protected function filterArguments(array $arguments)
2132
  {
2133
- return self::normalizeArguments($arguments);
 
 
 
 
2134
  }
2135
  }
2136
 
2137
  /**
2138
- * @link http://redis.io/commands/dump
 
2139
  * @author Daniele Alessandri <suppakilla@gmail.com>
2140
  */
2141
- class KeyDump extends Command
2142
  {
2143
  /**
2144
  * {@inheritdoc}
2145
  */
2146
  public function getId()
2147
  {
2148
- return 'DUMP';
2149
  }
2150
  }
2151
 
2152
  /**
2153
- * @link http://redis.io/commands/exists
 
2154
  * @author Daniele Alessandri <suppakilla@gmail.com>
2155
  */
2156
- class KeyExists extends Command
2157
  {
2158
  /**
2159
  * {@inheritdoc}
2160
  */
2161
  public function getId()
2162
  {
2163
- return 'EXISTS';
2164
  }
2165
 
2166
  /**
@@ -2173,40 +2266,50 @@ class KeyExists extends Command
2173
  }
2174
 
2175
  /**
2176
- * @link http://redis.io/commands/pfmerge
 
2177
  * @author Daniele Alessandri <suppakilla@gmail.com>
2178
  */
2179
- class HyperLogLogMerge extends Command
2180
  {
2181
  /**
2182
  * {@inheritdoc}
2183
  */
2184
  public function getId()
2185
  {
2186
- return 'PFMERGE';
2187
  }
 
2188
 
 
 
 
 
 
 
 
2189
  /**
2190
  * {@inheritdoc}
2191
  */
2192
- protected function filterArguments(array $arguments)
2193
  {
2194
- return self::normalizeArguments($arguments);
2195
  }
2196
  }
2197
 
2198
  /**
2199
- * @link http://redis.io/commands/pfcount
 
2200
  * @author Daniele Alessandri <suppakilla@gmail.com>
2201
  */
2202
- class HyperLogLogCount extends Command
2203
  {
2204
  /**
2205
  * {@inheritdoc}
2206
  */
2207
  public function getId()
2208
  {
2209
- return 'PFCOUNT';
2210
  }
2211
 
2212
  /**
@@ -2214,45 +2317,124 @@ class HyperLogLogCount extends Command
2214
  */
2215
  protected function filterArguments(array $arguments)
2216
  {
2217
- return self::normalizeArguments($arguments);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2218
  }
2219
  }
2220
 
2221
  /**
2222
- * @link http://redis.io/commands/hvals
 
2223
  * @author Daniele Alessandri <suppakilla@gmail.com>
2224
  */
2225
- class HashValues extends Command
2226
  {
2227
  /**
2228
  * {@inheritdoc}
2229
  */
2230
  public function getId()
2231
  {
2232
- return 'HVALS';
2233
  }
2234
- }
2235
 
2236
- /**
2237
- * @link http://redis.io/commands/pfadd
2238
- * @author Daniele Alessandri <suppakilla@gmail.com>
2239
- */
2240
- class HyperLogLogAdd extends Command
2241
- {
2242
  /**
2243
  * {@inheritdoc}
2244
  */
2245
- public function getId()
2246
  {
2247
- return 'PFADD';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2248
  }
 
2249
 
 
 
 
 
 
 
 
2250
  /**
2251
  * {@inheritdoc}
2252
  */
2253
- protected function filterArguments(array $arguments)
2254
  {
2255
- return self::normalizeVariadic($arguments);
2256
  }
2257
 
2258
  /**
@@ -2265,184 +2447,200 @@ class HyperLogLogAdd extends Command
2265
  }
2266
 
2267
  /**
2268
- * @link http://redis.io/commands/keys
 
2269
  * @author Daniele Alessandri <suppakilla@gmail.com>
2270
  */
2271
- class KeyKeys extends Command
2272
  {
2273
  /**
2274
  * {@inheritdoc}
2275
  */
2276
  public function getId()
2277
  {
2278
- return 'KEYS';
2279
  }
2280
  }
2281
 
2282
  /**
2283
- * @link http://redis.io/commands/move
 
2284
  * @author Daniele Alessandri <suppakilla@gmail.com>
2285
  */
2286
- class KeyMove extends Command
2287
  {
2288
  /**
2289
  * {@inheritdoc}
2290
  */
2291
  public function getId()
2292
  {
2293
- return 'MOVE';
2294
- }
2295
-
2296
- /**
2297
- * {@inheritdoc}
2298
- */
2299
- public function parseResponse($data)
2300
- {
2301
- return (bool) $data;
2302
  }
2303
  }
2304
 
2305
  /**
2306
- * @link http://redis.io/commands/randomkey
 
2307
  * @author Daniele Alessandri <suppakilla@gmail.com>
2308
  */
2309
- class KeyRandom extends Command
2310
  {
2311
  /**
2312
  * {@inheritdoc}
2313
  */
2314
  public function getId()
2315
  {
2316
- return 'RANDOMKEY';
2317
  }
 
2318
 
 
 
 
 
 
 
 
2319
  /**
2320
  * {@inheritdoc}
2321
  */
2322
- public function parseResponse($data)
2323
  {
2324
- return $data !== '' ? $data : null;
2325
  }
2326
  }
2327
 
2328
  /**
2329
- * @link http://redis.io/commands/renamenx
 
2330
  * @author Daniele Alessandri <suppakilla@gmail.com>
2331
  */
2332
- class KeyRenamePreserve extends KeyRename
2333
  {
2334
  /**
2335
  * {@inheritdoc}
2336
  */
2337
  public function getId()
2338
  {
2339
- return 'RENAMENX';
2340
  }
 
2341
 
 
 
 
 
 
 
 
2342
  /**
2343
  * {@inheritdoc}
2344
  */
2345
- public function parseResponse($data)
2346
  {
2347
- return (bool) $data;
2348
  }
2349
  }
2350
 
2351
  /**
2352
- * @link http://redis.io/commands/restore
 
2353
  * @author Daniele Alessandri <suppakilla@gmail.com>
2354
  */
2355
- class KeyRestore extends Command
2356
  {
2357
  /**
2358
  * {@inheritdoc}
2359
  */
2360
  public function getId()
2361
  {
2362
- return 'RESTORE';
2363
  }
2364
  }
2365
 
2366
  /**
2367
- * @link http://redis.io/commands/pttl
 
2368
  * @author Daniele Alessandri <suppakilla@gmail.com>
2369
  */
2370
- class KeyPreciseTimeToLive extends KeyTimeToLive
2371
  {
2372
  /**
2373
  * {@inheritdoc}
2374
  */
2375
  public function getId()
2376
  {
2377
- return 'PTTL';
2378
  }
2379
  }
2380
 
2381
  /**
2382
- * @link http://redis.io/commands/pexpireat
 
2383
  * @author Daniele Alessandri <suppakilla@gmail.com>
2384
  */
2385
- class KeyPreciseExpireAt extends KeyExpireAt
2386
  {
2387
  /**
2388
  * {@inheritdoc}
2389
  */
2390
  public function getId()
2391
  {
2392
- return 'PEXPIREAT';
2393
  }
2394
  }
2395
 
2396
  /**
2397
- * @link http://redis.io/commands/persist
 
2398
  * @author Daniele Alessandri <suppakilla@gmail.com>
2399
  */
2400
- class KeyPersist extends Command
2401
  {
2402
  /**
2403
  * {@inheritdoc}
2404
  */
2405
  public function getId()
2406
  {
2407
- return 'PERSIST';
2408
  }
2409
 
2410
  /**
2411
  * {@inheritdoc}
2412
  */
2413
- public function parseResponse($data)
2414
  {
2415
- return (bool) $data;
2416
- }
2417
- }
 
2418
 
2419
- /**
2420
- * @link http://redis.io/commands/pexpire
2421
- * @author Daniele Alessandri <suppakilla@gmail.com>
2422
- */
2423
- class KeyPreciseExpire extends KeyExpire
2424
- {
2425
- /**
2426
- * {@inheritdoc}
2427
- */
2428
- public function getId()
2429
- {
2430
- return 'PEXPIRE';
2431
  }
2432
- }
2433
 
2434
- /**
2435
- * @link http://redis.io/commands/hsetnx
2436
- * @author Daniele Alessandri <suppakilla@gmail.com>
2437
- */
2438
- class HashSetPreserve extends Command
2439
- {
2440
  /**
2441
- * {@inheritdoc}
 
 
 
 
2442
  */
2443
- public function getId()
2444
  {
2445
- return 'HSETNX';
 
 
 
 
 
 
 
 
 
 
 
 
 
2446
  }
2447
 
2448
  /**
@@ -2450,12 +2648,24 @@ class HashSetPreserve extends Command
2450
  */
2451
  public function parseResponse($data)
2452
  {
2453
- return (bool) $data;
 
 
 
 
 
 
 
 
 
 
 
2454
  }
2455
  }
2456
 
2457
  /**
2458
  * @link http://redis.io/commands/hmset
 
2459
  * @author Daniele Alessandri <suppakilla@gmail.com>
2460
  */
2461
  class HashSetMultiple extends Command
@@ -2490,55 +2700,58 @@ class HashSetMultiple extends Command
2490
  }
2491
 
2492
  /**
2493
- * @link http://redis.io/commands/select
 
2494
  * @author Daniele Alessandri <suppakilla@gmail.com>
2495
  */
2496
- class ConnectionSelect extends Command
2497
  {
2498
  /**
2499
  * {@inheritdoc}
2500
  */
2501
  public function getId()
2502
  {
2503
- return 'SELECT';
2504
  }
2505
- }
2506
 
2507
- /**
2508
- * @link http://redis.io/commands/hdel
2509
- * @author Daniele Alessandri <suppakilla@gmail.com>
2510
- */
2511
- class HashDelete extends Command
2512
- {
2513
  /**
2514
  * {@inheritdoc}
2515
  */
2516
- public function getId()
2517
  {
2518
- return 'HDEL';
2519
  }
 
2520
 
 
 
 
 
 
 
 
2521
  /**
2522
  * {@inheritdoc}
2523
  */
2524
- protected function filterArguments(array $arguments)
2525
  {
2526
- return self::normalizeVariadic($arguments);
2527
  }
2528
  }
2529
 
2530
  /**
2531
- * @link http://redis.io/commands/hexists
 
2532
  * @author Daniele Alessandri <suppakilla@gmail.com>
2533
  */
2534
- class HashExists extends Command
2535
  {
2536
  /**
2537
  * {@inheritdoc}
2538
  */
2539
  public function getId()
2540
  {
2541
- return 'HEXISTS';
2542
  }
2543
 
2544
  /**
@@ -2551,136 +2764,114 @@ class HashExists extends Command
2551
  }
2552
 
2553
  /**
2554
- * @link http://redis.io/commands/quit
 
2555
  * @author Daniele Alessandri <suppakilla@gmail.com>
2556
  */
2557
- class ConnectionQuit extends Command
2558
  {
2559
  /**
2560
  * {@inheritdoc}
2561
  */
2562
  public function getId()
2563
  {
2564
- return 'QUIT';
2565
  }
2566
  }
2567
 
2568
  /**
2569
- * @link http://redis.io/commands/ping
 
2570
  * @author Daniele Alessandri <suppakilla@gmail.com>
2571
  */
2572
- class ConnectionPing extends Command
2573
  {
2574
  /**
2575
  * {@inheritdoc}
2576
  */
2577
  public function getId()
2578
  {
2579
- return 'PING';
2580
  }
2581
- }
2582
 
2583
- /**
2584
- * @link http://redis.io/commands/auth
2585
- * @author Daniele Alessandri <suppakilla@gmail.com>
2586
- */
2587
- class ConnectionAuth extends Command
2588
- {
2589
  /**
2590
  * {@inheritdoc}
2591
  */
2592
- public function getId()
2593
  {
2594
- return 'AUTH';
2595
  }
2596
  }
2597
 
2598
  /**
2599
- * @link http://redis.io/commands/echo
 
2600
  * @author Daniele Alessandri <suppakilla@gmail.com>
2601
  */
2602
- class ConnectionEcho extends Command
2603
  {
2604
  /**
2605
  * {@inheritdoc}
2606
  */
2607
  public function getId()
2608
  {
2609
- return 'ECHO';
2610
  }
2611
- }
2612
 
2613
- /**
2614
- * @link http://redis.io/commands/hget
2615
- * @author Daniele Alessandri <suppakilla@gmail.com>
2616
- */
2617
- class HashGet extends Command
2618
- {
2619
  /**
2620
  * {@inheritdoc}
2621
  */
2622
- public function getId()
2623
  {
2624
- return 'HGET';
2625
  }
2626
  }
2627
 
2628
  /**
2629
- * @link http://redis.io/commands/hgetall
 
2630
  * @author Daniele Alessandri <suppakilla@gmail.com>
2631
  */
2632
- class HashGetAll extends Command
2633
  {
2634
  /**
2635
  * {@inheritdoc}
2636
  */
2637
  public function getId()
2638
  {
2639
- return 'HGETALL';
2640
  }
2641
 
2642
  /**
2643
  * {@inheritdoc}
2644
  */
2645
- public function parseResponse($data)
2646
  {
2647
- $result = array();
2648
-
2649
- for ($i = 0; $i < count($data); $i++) {
2650
- $result[$data[$i]] = $data[++$i];
2651
- }
2652
-
2653
- return $result;
2654
  }
2655
- }
2656
 
2657
- /**
2658
- * @link http://redis.io/commands/hlen
2659
- * @author Daniele Alessandri <suppakilla@gmail.com>
2660
- */
2661
- class HashLength extends Command
2662
- {
2663
  /**
2664
  * {@inheritdoc}
2665
  */
2666
- public function getId()
2667
  {
2668
- return 'HLEN';
2669
  }
2670
  }
2671
 
2672
  /**
2673
- * @link http://redis.io/commands/hscan
 
2674
  * @author Daniele Alessandri <suppakilla@gmail.com>
2675
  */
2676
- class HashScan extends Command
2677
  {
2678
  /**
2679
  * {@inheritdoc}
2680
  */
2681
  public function getId()
2682
  {
2683
- return 'HSCAN';
2684
  }
2685
 
2686
  /**
@@ -2688,71 +2879,23 @@ class HashScan extends Command
2688
  */
2689
  protected function filterArguments(array $arguments)
2690
  {
2691
- if (count($arguments) === 3 && is_array($arguments[2])) {
2692
- $options = $this->prepareOptions(array_pop($arguments));
2693
- $arguments = array_merge($arguments, $options);
2694
- }
2695
-
2696
- return $arguments;
2697
- }
2698
-
2699
- /**
2700
- * Returns a list of options and modifiers compatible with Redis.
2701
- *
2702
- * @param array $options List of options.
2703
- *
2704
- * @return array
2705
- */
2706
- protected function prepareOptions($options)
2707
- {
2708
- $options = array_change_key_case($options, CASE_UPPER);
2709
- $normalized = array();
2710
-
2711
- if (!empty($options['MATCH'])) {
2712
- $normalized[] = 'MATCH';
2713
- $normalized[] = $options['MATCH'];
2714
- }
2715
-
2716
- if (!empty($options['COUNT'])) {
2717
- $normalized[] = 'COUNT';
2718
- $normalized[] = $options['COUNT'];
2719
- }
2720
-
2721
- return $normalized;
2722
- }
2723
-
2724
- /**
2725
- * {@inheritdoc}
2726
- */
2727
- public function parseResponse($data)
2728
- {
2729
- if (is_array($data)) {
2730
- $fields = $data[1];
2731
- $result = array();
2732
-
2733
- for ($i = 0; $i < count($fields); $i++) {
2734
- $result[$fields[$i]] = $fields[++$i];
2735
- }
2736
-
2737
- $data[1] = $result;
2738
- }
2739
-
2740
- return $data;
2741
  }
2742
  }
2743
 
2744
  /**
2745
- * @link http://redis.io/commands/hset
 
2746
  * @author Daniele Alessandri <suppakilla@gmail.com>
2747
  */
2748
- class HashSet extends Command
2749
  {
2750
  /**
2751
  * {@inheritdoc}
2752
  */
2753
  public function getId()
2754
  {
2755
- return 'HSET';
2756
  }
2757
 
2758
  /**
@@ -2765,138 +2908,106 @@ class HashSet extends Command
2765
  }
2766
 
2767
  /**
2768
- * @link http://redis.io/commands/hkeys
 
2769
  * @author Daniele Alessandri <suppakilla@gmail.com>
2770
  */
2771
- class HashKeys extends Command
2772
  {
2773
  /**
2774
  * {@inheritdoc}
2775
  */
2776
  public function getId()
2777
  {
2778
- return 'HKEYS';
2779
  }
2780
  }
2781
 
2782
  /**
2783
- * @link http://redis.io/commands/hincrbyfloat
 
2784
  * @author Daniele Alessandri <suppakilla@gmail.com>
2785
  */
2786
- class HashIncrementByFloat extends Command
2787
  {
2788
  /**
2789
  * {@inheritdoc}
2790
  */
2791
  public function getId()
2792
  {
2793
- return 'HINCRBYFLOAT';
2794
  }
2795
  }
2796
 
2797
  /**
2798
- * @link http://redis.io/commands/hmget
 
2799
  * @author Daniele Alessandri <suppakilla@gmail.com>
2800
  */
2801
- class HashGetMultiple extends Command
2802
  {
2803
  /**
2804
  * {@inheritdoc}
2805
  */
2806
  public function getId()
2807
  {
2808
- return 'HMGET';
2809
  }
2810
-
2811
- /**
2812
- * {@inheritdoc}
2813
- */
2814
- protected function filterArguments(array $arguments)
2815
- {
2816
- return self::normalizeVariadic($arguments);
2817
- }
2818
- }
2819
 
2820
  /**
2821
- * @link http://redis.io/commands/hincrby
 
2822
  * @author Daniele Alessandri <suppakilla@gmail.com>
2823
  */
2824
- class HashIncrementBy extends Command
2825
  {
2826
  /**
2827
  * {@inheritdoc}
2828
  */
2829
  public function getId()
2830
  {
2831
- return 'HINCRBY';
2832
  }
2833
  }
2834
 
2835
  /**
2836
- * @link http://redis.io/commands/scan
 
2837
  * @author Daniele Alessandri <suppakilla@gmail.com>
2838
  */
2839
- class KeyScan extends Command
2840
  {
2841
  /**
2842
  * {@inheritdoc}
2843
  */
2844
  public function getId()
2845
  {
2846
- return 'SCAN';
2847
  }
2848
 
2849
  /**
2850
  * {@inheritdoc}
2851
  */
2852
- protected function filterArguments(array $arguments)
2853
- {
2854
- if (count($arguments) === 2 && is_array($arguments[1])) {
2855
- $options = $this->prepareOptions(array_pop($arguments));
2856
- $arguments = array_merge($arguments, $options);
2857
- }
2858
-
2859
- return $arguments;
2860
- }
2861
-
2862
- /**
2863
- * Returns a list of options and modifiers compatible with Redis.
2864
- *
2865
- * @param array $options List of options.
2866
- *
2867
- * @return array
2868
- */
2869
- protected function prepareOptions($options)
2870
  {
2871
- $options = array_change_key_case($options, CASE_UPPER);
2872
- $normalized = array();
2873
-
2874
- if (!empty($options['MATCH'])) {
2875
- $normalized[] = 'MATCH';
2876
- $normalized[] = $options['MATCH'];
2877
- }
2878
-
2879
- if (!empty($options['COUNT'])) {
2880
- $normalized[] = 'COUNT';
2881
- $normalized[] = $options['COUNT'];
2882
- }
2883
-
2884
- return $normalized;
2885
  }
2886
  }
2887
 
2888
  /**
2889
- * @link http://redis.io/commands/sort
 
2890
  * @author Daniele Alessandri <suppakilla@gmail.com>
2891
  */
2892
- class KeySort extends Command
2893
  {
2894
  /**
2895
  * {@inheritdoc}
2896
  */
2897
  public function getId()
2898
  {
2899
- return 'SORT';
2900
  }
2901
 
2902
  /**
@@ -2904,253 +3015,234 @@ class KeySort extends Command
2904
  */
2905
  protected function filterArguments(array $arguments)
2906
  {
2907
- if (count($arguments) === 1) {
2908
- return $arguments;
2909
- }
2910
-
2911
- $query = array($arguments[0]);
2912
- $sortParams = array_change_key_case($arguments[1], CASE_UPPER);
2913
 
2914
- if (isset($sortParams['BY'])) {
2915
- $query[] = 'BY';
2916
- $query[] = $sortParams['BY'];
2917
- }
2918
-
2919
- if (isset($sortParams['GET'])) {
2920
- $getargs = $sortParams['GET'];
2921
 
2922
- if (is_array($getargs)) {
2923
- foreach ($getargs as $getarg) {
2924
- $query[] = 'GET';
2925
- $query[] = $getarg;
2926
  }
2927
- } else {
2928
- $query[] = 'GET';
2929
- $query[] = $getargs;
2930
  }
2931
  }
2932
 
2933
- if (isset($sortParams['LIMIT']) &&
2934
- is_array($sortParams['LIMIT']) &&
2935
- count($sortParams['LIMIT']) == 2) {
2936
-
2937
- $query[] = 'LIMIT';
2938
- $query[] = $sortParams['LIMIT'][0];
2939
- $query[] = $sortParams['LIMIT'][1];
2940
- }
2941
-
2942
- if (isset($sortParams['SORT'])) {
2943
- $query[] = strtoupper($sortParams['SORT']);
2944
- }
2945
-
2946
- if (isset($sortParams['ALPHA']) && $sortParams['ALPHA'] == true) {
2947
- $query[] = 'ALPHA';
2948
- }
2949
-
2950
- if (isset($sortParams['STORE'])) {
2951
- $query[] = 'STORE';
2952
- $query[] = $sortParams['STORE'];
2953
- }
2954
-
2955
- return $query;
2956
  }
2957
  }
2958
 
2959
  /**
2960
- * Class for generic "anonymous" Redis commands.
2961
- *
2962
- * This command class does not filter input arguments or parse responses, but
2963
- * can be used to leverage the standard Predis API to execute any command simply
2964
- * by providing the needed arguments following the command signature as defined
2965
- * by Redis in its documentation.
2966
  *
2967
  * @author Daniele Alessandri <suppakilla@gmail.com>
2968
  */
2969
- class RawCommand implements CommandInterface
2970
  {
2971
- private $slot;
2972
- private $commandID;
2973
- private $arguments;
2974
-
2975
  /**
2976
- * @param array $arguments Command ID and its arguments.
2977
- *
2978
- * @throws \InvalidArgumentException
2979
  */
2980
- public function __construct(array $arguments)
2981
  {
2982
- if (!$arguments) {
2983
- throw new InvalidArgumentException(
2984
- 'The arguments array must contain at least the command ID.'
2985
- );
2986
- }
2987
-
2988
- $this->commandID = strtoupper(array_shift($arguments));
2989
- $this->arguments = $arguments;
2990
  }
2991
 
2992
  /**
2993
- * Creates a new raw command using a variadic method.
2994
- *
2995
- * @param string $commandID Redis command ID.
2996
- * @param string ... Arguments list for the command.
2997
- *
2998
- * @return CommandInterface
2999
  */
3000
- public static function create($commandID /* [ $arg, ... */)
3001
  {
3002
- $arguments = func_get_args();
3003
- $command = new self($arguments);
3004
-
3005
- return $command;
3006
  }
 
3007
 
 
 
 
 
 
 
 
3008
  /**
3009
  * {@inheritdoc}
3010
  */
3011
  public function getId()
3012
  {
3013
- return $this->commandID;
3014
  }
 
3015
 
 
 
 
 
 
 
 
3016
  /**
3017
  * {@inheritdoc}
3018
  */
3019
- public function setArguments(array $arguments)
3020
  {
3021
- $this->arguments = $arguments;
3022
- unset($this->slot);
3023
  }
 
3024
 
 
 
 
 
 
 
 
3025
  /**
3026
  * {@inheritdoc}
3027
  */
3028
- public function setRawArguments(array $arguments)
3029
  {
3030
- $this->setArguments($arguments);
3031
  }
3032
 
3033
  /**
3034
  * {@inheritdoc}
3035
  */
3036
- public function getArguments()
3037
  {
3038
- return $this->arguments;
3039
  }
 
3040
 
 
 
 
 
 
 
 
3041
  /**
3042
  * {@inheritdoc}
3043
  */
3044
- public function getArgument($index)
3045
  {
3046
- if (isset($this->arguments[$index])) {
3047
- return $this->arguments[$index];
3048
- }
3049
  }
 
3050
 
 
 
 
 
 
 
 
3051
  /**
3052
  * {@inheritdoc}
3053
  */
3054
- public function setSlot($slot)
3055
  {
3056
- $this->slot = $slot;
3057
  }
 
3058
 
 
 
 
 
 
 
 
3059
  /**
3060
  * {@inheritdoc}
3061
  */
3062
- public function getSlot()
3063
  {
3064
- if (isset($this->slot)) {
3065
- return $this->slot;
3066
- }
3067
  }
 
3068
 
 
 
 
 
 
 
 
3069
  /**
3070
  * {@inheritdoc}
3071
  */
3072
- public function parseResponse($data)
3073
  {
3074
- return $data;
3075
  }
3076
  }
3077
 
3078
  /**
3079
- * Base class used to implement an higher level abstraction for commands based
3080
- * on Lua scripting with EVAL and EVALSHA.
3081
  *
3082
- * @link http://redis.io/commands/eval
3083
  * @author Daniele Alessandri <suppakilla@gmail.com>
3084
  */
3085
- abstract class ScriptCommand extends ServerEvalSHA
3086
  {
3087
  /**
3088
- * Gets the body of a Lua script.
3089
- *
3090
- * @return string
3091
- */
3092
- abstract public function getScript();
3093
-
3094
- /**
3095
- * Specifies the number of arguments that should be considered as keys.
3096
- *
3097
- * The default behaviour for the base class is to return 0 to indicate that
3098
- * all the elements of the arguments array should be considered as keys, but
3099
- * subclasses can enforce a static number of keys.
3100
- *
3101
- * @return int
3102
  */
3103
- protected function getKeysCount()
3104
  {
3105
- return 0;
3106
  }
 
3107
 
 
 
 
 
 
 
 
 
 
 
3108
  /**
3109
- * Returns the elements from the arguments that are identified as keys.
3110
- *
3111
- * @return array
3112
  */
3113
- public function getKeys()
3114
  {
3115
- return array_slice($this->getArguments(), 2, $this->getKeysCount());
3116
  }
3117
 
3118
  /**
3119
  * {@inheritdoc}
3120
  */
3121
- protected function filterArguments(array $arguments)
3122
  {
3123
- if (($numkeys = $this->getKeysCount()) && $numkeys < 0) {
3124
- $numkeys = count($arguments) + $numkeys;
3125
- }
3126
 
3127
- return array_merge(array(sha1($this->getScript()), (int) $numkeys), $arguments);
3128
- }
 
3129
 
3130
- /**
3131
- * @return array
3132
- */
3133
- public function getEvalArguments()
3134
- {
3135
- $arguments = $this->getArguments();
3136
- $arguments[0] = $this->getScript();
3137
 
3138
- return $arguments;
3139
  }
3140
  }
3141
 
3142
  /**
3143
- * @link http://redis.io/commands/bgrewriteaof
 
3144
  * @author Daniele Alessandri <suppakilla@gmail.com>
3145
  */
3146
- class ServerBackgroundRewriteAOF extends Command
3147
  {
3148
  /**
3149
  * {@inheritdoc}
3150
  */
3151
  public function getId()
3152
  {
3153
- return 'BGREWRITEAOF';
3154
  }
3155
 
3156
  /**
@@ -3158,123 +3250,191 @@ class ServerBackgroundRewriteAOF extends Command
3158
  */
3159
  public function parseResponse($data)
3160
  {
3161
- return $data == 'Background append only file rewriting started';
 
 
 
 
 
 
3162
  }
3163
  }
3164
 
3165
  /**
3166
- * @link http://redis.io/commands/punsubscribe
 
3167
  * @author Daniele Alessandri <suppakilla@gmail.com>
3168
  */
3169
- class PubSubUnsubscribeByPattern extends PubSubUnsubscribe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3170
  {
3171
  /**
3172
  * {@inheritdoc}
3173
  */
3174
  public function getId()
3175
  {
3176
- return 'PUNSUBSCRIBE';
3177
  }
3178
  }
3179
 
3180
  /**
3181
- * @link http://redis.io/commands/psubscribe
 
3182
  * @author Daniele Alessandri <suppakilla@gmail.com>
3183
  */
3184
- class PubSubSubscribeByPattern extends PubSubSubscribe
3185
  {
3186
  /**
3187
  * {@inheritdoc}
3188
  */
3189
  public function getId()
3190
  {
3191
- return 'PSUBSCRIBE';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3192
  }
3193
  }
3194
 
3195
  /**
3196
- * @link http://redis.io/commands/publish
 
3197
  * @author Daniele Alessandri <suppakilla@gmail.com>
3198
  */
3199
- class PubSubPublish extends Command
3200
  {
3201
  /**
3202
  * {@inheritdoc}
3203
  */
3204
  public function getId()
3205
  {
3206
- return 'PUBLISH';
3207
  }
3208
  }
3209
 
3210
  /**
3211
- * @link http://redis.io/commands/pubsub
 
3212
  * @author Daniele Alessandri <suppakilla@gmail.com>
3213
  */
3214
- class PubSubPubsub extends Command
3215
  {
3216
  /**
3217
  * {@inheritdoc}
3218
  */
3219
  public function getId()
3220
  {
3221
- return 'PUBSUB';
3222
- }
3223
-
3224
- /**
3225
- * {@inheritdoc}
3226
- */
3227
- public function parseResponse($data)
3228
- {
3229
- switch (strtolower($this->getArgument(0))) {
3230
- case 'numsub':
3231
- return self::processNumsub($data);
3232
-
3233
- default:
3234
- return $data;
3235
- }
3236
- }
3237
-
3238
- /**
3239
- * Returns the processed response to PUBSUB NUMSUB.
3240
- *
3241
- * @param array $channels List of channels
3242
- *
3243
- * @return array
3244
- */
3245
- protected static function processNumsub(array $channels)
3246
- {
3247
- $processed = array();
3248
- $count = count($channels);
3249
-
3250
- for ($i = 0; $i < $count; $i++) {
3251
- $processed[$channels[$i]] = $channels[++$i];
3252
- }
3253
-
3254
- return $processed;
3255
  }
3256
  }
3257
 
3258
  /**
3259
- * @link http://redis.io/commands/bgsave
 
3260
  * @author Daniele Alessandri <suppakilla@gmail.com>
3261
  */
3262
- class ServerBackgroundSave extends Command
3263
  {
3264
  /**
3265
  * {@inheritdoc}
3266
  */
3267
  public function getId()
3268
  {
3269
- return 'BGSAVE';
3270
  }
 
3271
 
 
 
 
 
 
 
 
3272
  /**
3273
  * {@inheritdoc}
3274
  */
3275
- public function parseResponse($data)
3276
  {
3277
- return $data === 'Background saving started' ? true : $data;
3278
  }
3279
  }
3280
 
@@ -3283,6 +3443,7 @@ class ServerBackgroundSave extends Command
3283
  * @link http://redis.io/commands/client-kill
3284
  * @link http://redis.io/commands/client-getname
3285
  * @link http://redis.io/commands/client-setname
 
3286
  * @author Daniele Alessandri <suppakilla@gmail.com>
3287
  */
3288
  class ServerClient extends Command
@@ -3340,426 +3501,474 @@ class ServerClient extends Command
3340
  }
3341
 
3342
  /**
3343
- * @link http://redis.io/commands/info
 
3344
  * @author Daniele Alessandri <suppakilla@gmail.com>
3345
  */
3346
- class ServerInfoV26x extends ServerInfo
3347
  {
3348
  /**
3349
  * {@inheritdoc}
3350
  */
3351
- public function parseResponse($data)
3352
  {
3353
- if ($data === '') {
3354
- return array();
3355
- }
3356
-
3357
- $info = array();
3358
-
3359
- $current = null;
3360
- $infoLines = preg_split('/\r?\n/', $data);
3361
 
3362
- if (isset($infoLines[0]) && $infoLines[0][0] !== '#') {
3363
- return parent::parseResponse($data);
3364
- }
 
 
 
 
 
3365
 
3366
- foreach ($infoLines as $row) {
3367
- if ($row === '') {
3368
- continue;
3369
- }
 
 
 
 
 
 
 
 
 
 
 
3370
 
3371
- if (preg_match('/^# (\w+)$/', $row, $matches)) {
3372
- $info[$matches[1]] = array();
3373
- $current = &$info[$matches[1]];
3374
- continue;
3375
- }
 
 
 
 
 
 
 
 
 
3376
 
3377
- list($k, $v) = $this->parseRow($row);
3378
- $current[$k] = $v;
3379
- }
 
 
 
 
 
 
 
 
 
 
 
 
3380
 
3381
- return $info;
 
 
 
 
 
 
 
 
 
 
 
 
3382
  }
3383
  }
3384
 
3385
  /**
3386
- * @link http://redis.io/commands/lastsave
 
3387
  * @author Daniele Alessandri <suppakilla@gmail.com>
3388
  */
3389
- class ServerLastSave extends Command
3390
  {
3391
  /**
3392
  * {@inheritdoc}
3393
  */
3394
  public function getId()
3395
  {
3396
- return 'LASTSAVE';
3397
  }
3398
  }
3399
 
3400
  /**
3401
- * @link http://redis.io/commands/monitor
 
3402
  * @author Daniele Alessandri <suppakilla@gmail.com>
3403
  */
3404
- class ServerMonitor extends Command
3405
  {
3406
  /**
3407
  * {@inheritdoc}
3408
  */
3409
  public function getId()
3410
  {
3411
- return 'MONITOR';
3412
  }
3413
  }
3414
 
3415
  /**
3416
- * @link http://redis.io/commands/flushdb
 
3417
  * @author Daniele Alessandri <suppakilla@gmail.com>
3418
  */
3419
- class ServerFlushDatabase extends Command
3420
  {
3421
  /**
3422
  * {@inheritdoc}
3423
  */
3424
  public function getId()
3425
  {
3426
- return 'FLUSHDB';
3427
  }
3428
  }
3429
 
3430
  /**
3431
- * @link http://redis.io/commands/dbsize
 
3432
  * @author Daniele Alessandri <suppakilla@gmail.com>
3433
  */
3434
- class ServerDatabaseSize extends Command
3435
  {
3436
  /**
3437
  * {@inheritdoc}
3438
  */
3439
  public function getId()
3440
  {
3441
- return 'DBSIZE';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3442
  }
3443
  }
3444
 
3445
  /**
3446
- * @link http://redis.io/commands/command
 
3447
  * @author Daniele Alessandri <suppakilla@gmail.com>
3448
  */
3449
- class ServerCommand extends Command
3450
  {
3451
  /**
3452
  * {@inheritdoc}
3453
  */
3454
  public function getId()
3455
  {
3456
- return 'COMMAND';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3457
  }
3458
- }
3459
 
3460
- /**
3461
- * @link http://redis.io/commands/config-set
3462
- * @link http://redis.io/commands/config-get
3463
- * @link http://redis.io/commands/config-resetstat
3464
- * @link http://redis.io/commands/config-rewrite
3465
- * @author Daniele Alessandri <suppakilla@gmail.com>
3466
- */
3467
- class ServerConfig extends Command
3468
- {
3469
  /**
3470
- * {@inheritdoc}
 
 
3471
  */
3472
- public function getId()
3473
  {
3474
- return 'CONFIG';
3475
  }
3476
 
3477
  /**
3478
  * {@inheritdoc}
3479
  */
3480
- public function parseResponse($data)
3481
  {
3482
- if (is_array($data)) {
3483
- $result = array();
3484
-
3485
- for ($i = 0; $i < count($data); $i++) {
3486
- $result[$data[$i]] = $data[++$i];
3487
- }
3488
-
3489
- return $result;
3490
  }
3491
 
3492
- return $data;
3493
  }
3494
- }
3495
-
3496
- /**
3497
- * Defines a command whose keys can be prefixed.
3498
- *
3499
- * @author Daniele Alessandri <suppakilla@gmail.com>
3500
- */
3501
- interface PrefixableCommandInterface extends CommandInterface
3502
- {
3503
- /**
3504
- * Prefixes all the keys found in the arguments of the command.
3505
- *
3506
- * @param string $prefix String used to prefix the keys.
3507
- */
3508
- public function prefixKeys($prefix);
3509
- }
3510
 
3511
- /**
3512
- * @link http://redis.io/commands/ltrim
3513
- * @author Daniele Alessandri <suppakilla@gmail.com>
3514
- */
3515
- class ListTrim extends Command
3516
- {
3517
  /**
3518
- * {@inheritdoc}
3519
  */
3520
- public function getId()
3521
  {
3522
- return 'LTRIM';
 
 
 
3523
  }
3524
  }
3525
 
3526
  /**
3527
- * @link http://redis.io/commands/lpop
 
3528
  * @author Daniele Alessandri <suppakilla@gmail.com>
3529
  */
3530
- class ListPopFirst extends Command
3531
  {
3532
  /**
3533
  * {@inheritdoc}
3534
  */
3535
  public function getId()
3536
  {
3537
- return 'LPOP';
3538
  }
3539
- }
3540
 
3541
- /**
3542
- * @link http://redis.io/commands/rpop
3543
- * @author Daniele Alessandri <suppakilla@gmail.com>
3544
- */
3545
- class ListPopLast extends Command
3546
- {
3547
  /**
3548
  * {@inheritdoc}
3549
  */
3550
- public function getId()
3551
  {
3552
- return 'RPOP';
3553
  }
3554
  }
3555
 
3556
  /**
3557
- * @link http://redis.io/commands/brpop
 
 
 
 
 
 
3558
  * @author Daniele Alessandri <suppakilla@gmail.com>
3559
  */
3560
- class ListPopLastBlocking extends ListPopFirstBlocking
3561
  {
 
 
 
 
3562
  /**
3563
- * {@inheritdoc}
 
 
3564
  */
3565
- public function getId()
3566
  {
3567
- return 'BRPOP';
 
 
 
 
 
 
 
3568
  }
3569
- }
3570
 
3571
- /**
3572
- * @link http://redis.io/commands/llen
3573
- * @author Daniele Alessandri <suppakilla@gmail.com>
3574
- */
3575
- class ListLength extends Command
3576
- {
3577
  /**
3578
- * {@inheritdoc}
 
 
 
 
 
3579
  */
3580
- public function getId()
3581
  {
3582
- return 'LLEN';
 
 
 
3583
  }
3584
- }
3585
 
3586
- /**
3587
- * @link http://redis.io/commands/linsert
3588
- * @author Daniele Alessandri <suppakilla@gmail.com>
3589
- */
3590
- class ListInsert extends Command
3591
- {
3592
  /**
3593
  * {@inheritdoc}
3594
  */
3595
  public function getId()
3596
  {
3597
- return 'LINSERT';
3598
  }
3599
- }
3600
 
3601
- /**
3602
- * @link http://redis.io/commands/type
3603
- * @author Daniele Alessandri <suppakilla@gmail.com>
3604
- */
3605
- class KeyType extends Command
3606
- {
3607
  /**
3608
  * {@inheritdoc}
3609
  */
3610
- public function getId()
3611
  {
3612
- return 'TYPE';
 
3613
  }
3614
- }
3615
 
3616
- /**
3617
- * @link http://redis.io/commands/lindex
3618
- * @author Daniele Alessandri <suppakilla@gmail.com>
3619
- */
3620
- class ListIndex extends Command
3621
- {
3622
  /**
3623
  * {@inheritdoc}
3624
  */
3625
- public function getId()
3626
  {
3627
- return 'LINDEX';
3628
  }
3629
- }
3630
 
3631
- /**
3632
- * @link http://redis.io/commands/rpoplpush
3633
- * @author Daniele Alessandri <suppakilla@gmail.com>
3634
- */
3635
- class ListPopLastPushHead extends Command
3636
- {
3637
  /**
3638
  * {@inheritdoc}
3639
  */
3640
- public function getId()
3641
  {
3642
- return 'RPOPLPUSH';
3643
  }
3644
- }
3645
 
3646
- /**
3647
- * @link http://redis.io/commands/brpoplpush
3648
- * @author Daniele Alessandri <suppakilla@gmail.com>
3649
- */
3650
- class ListPopLastPushHeadBlocking extends Command
3651
- {
3652
  /**
3653
  * {@inheritdoc}
3654
  */
3655
- public function getId()
3656
  {
3657
- return 'BRPOPLPUSH';
 
 
3658
  }
3659
- }
3660
 
3661
- /**
3662
- * @link http://redis.io/commands/lrem
3663
- * @author Daniele Alessandri <suppakilla@gmail.com>
3664
- */
3665
- class ListRemove extends Command
3666
- {
3667
  /**
3668
  * {@inheritdoc}
3669
  */
3670
- public function getId()
3671
  {
3672
- return 'LREM';
3673
  }
3674
- }
3675
 
3676
- /**
3677
- * @link http://redis.io/commands/lset
3678
- * @author Daniele Alessandri <suppakilla@gmail.com>
3679
- */
3680
- class ListSet extends Command
3681
- {
3682
  /**
3683
  * {@inheritdoc}
3684
  */
3685
- public function getId()
3686
  {
3687
- return 'LSET';
 
 
3688
  }
3689
- }
3690
 
3691
- /**
3692
- * @link http://redis.io/commands/lrange
3693
- * @author Daniele Alessandri <suppakilla@gmail.com>
3694
- */
3695
- class ListRange extends Command
3696
- {
3697
  /**
3698
  * {@inheritdoc}
3699
  */
3700
- public function getId()
3701
  {
3702
- return 'LRANGE';
3703
  }
3704
  }
3705
 
3706
  /**
3707
- * @link http://redis.io/commands/rpushx
 
3708
  * @author Daniele Alessandri <suppakilla@gmail.com>
3709
  */
3710
- class ListPushTailX extends Command
3711
  {
3712
  /**
3713
  * {@inheritdoc}
3714
  */
3715
  public function getId()
3716
  {
3717
- return 'RPUSHX';
3718
  }
3719
  }
3720
 
3721
  /**
3722
- * @link http://redis.io/commands/lpush
 
3723
  * @author Daniele Alessandri <suppakilla@gmail.com>
3724
  */
3725
- class ListPushHead extends ListPushTail
3726
  {
3727
  /**
3728
  * {@inheritdoc}
3729
  */
3730
  public function getId()
3731
  {
3732
- return 'LPUSH';
3733
  }
3734
  }
3735
 
3736
  /**
3737
- * @link http://redis.io/commands/lpushx
 
3738
  * @author Daniele Alessandri <suppakilla@gmail.com>
3739
  */
3740
- class ListPushHeadX extends Command
3741
  {
3742
  /**
3743
  * {@inheritdoc}
3744
  */
3745
  public function getId()
3746
  {
3747
- return 'LPUSHX';
3748
  }
3749
  }
3750
 
3751
  /**
3752
- * @link http://redis.io/commands/object
 
3753
  * @author Daniele Alessandri <suppakilla@gmail.com>
3754
  */
3755
- class ServerObject extends Command
3756
  {
3757
  /**
3758
  * {@inheritdoc}
3759
  */
3760
  public function getId()
3761
  {
3762
- return 'OBJECT';
3763
  }
3764
  }
3765
 
@@ -3767,14 +3976,11 @@ class ServerObject extends Command
3767
 
3768
  namespace Predis\Connection;
3769
 
3770
- use InvalidArgumentException;
3771
- use Predis\CommunicationException;
3772
  use Predis\Command\CommandInterface;
 
3773
  use Predis\Protocol\ProtocolException;
3774
  use Predis\Protocol\ProtocolProcessorInterface;
3775
  use Predis\Protocol\Text\ProtocolProcessor as TextProtocolProcessor;
3776
- use UnexpectedValueException;
3777
- use ReflectionClass;
3778
  use Predis\Command\RawCommand;
3779
  use Predis\NotSupportedException;
3780
  use Predis\Response\Error as ErrorResponse;
@@ -3955,20 +4161,20 @@ abstract class AbstractConnection implements NodeConnectionInterface
3955
  *
3956
  * @param ParametersInterface $parameters Initialization parameters for the connection.
3957
  *
3958
- * @return ParametersInterface
3959
- *
3960
  * @throws \InvalidArgumentException
 
 
3961
  */
3962
  protected function assertParameters(ParametersInterface $parameters)
3963
  {
3964
- $scheme = $parameters->scheme;
3965
-
3966
- if ($scheme !== 'tcp' && $scheme !== 'unix') {
3967
- throw new InvalidArgumentException("Invalid scheme: '$scheme'.");
3968
- }
3969
 
3970
- if ($scheme === 'unix' && !isset($parameters->path)) {
3971
- throw new InvalidArgumentException('Missing UNIX domain socket path.');
3972
  }
3973
 
3974
  return $parameters;
@@ -4037,6 +4243,29 @@ abstract class AbstractConnection implements NodeConnectionInterface
4037
  return $this->read();
4038
  }
4039
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4040
  /**
4041
  * Helper method to handle connection errors.
4042
  *
@@ -4046,9 +4275,7 @@ abstract class AbstractConnection implements NodeConnectionInterface
4046
  protected function onConnectionError($message, $code = null)
4047
  {
4048
  CommunicationException::handle(
4049
- new ConnectionException(
4050
- $this, "$message [{$this->parameters->scheme}://{$this->getIdentifier()}]", $code
4051
- )
4052
  );
4053
  }
4054
 
@@ -4060,9 +4287,7 @@ abstract class AbstractConnection implements NodeConnectionInterface
4060
  protected function onProtocolError($message)
4061
  {
4062
  CommunicationException::handle(
4063
- new ProtocolException(
4064
- $this, "$message [{$this->parameters->scheme}://{$this->getIdentifier()}]"
4065
- )
4066
  );
4067
  }
4068
 
@@ -4125,9 +4350,9 @@ abstract class AbstractConnection implements NodeConnectionInterface
4125
 
4126
  /**
4127
  * Standard connection to Redis servers implemented on top of PHP's streams.
4128
- * The connection parameters supported by this class are:
4129
  *
4130
- * - scheme: it can be either 'tcp' or 'unix'.
4131
  * - host: hostname or IP address of the server.
4132
  * - port: TCP port of the server.
4133
  * - path: path of a UNIX domain socket when scheme is 'unix'.
@@ -4160,10 +4385,17 @@ class StreamConnection extends AbstractConnection
4160
  */
4161
  protected function createResource()
4162
  {
4163
- $initializer = "{$this->parameters->scheme}StreamInitializer";
4164
- $resource = $this->$initializer($this->parameters);
 
 
4165
 
4166
- return $resource;
 
 
 
 
 
4167
  }
4168
 
4169
  /**
@@ -4175,7 +4407,12 @@ class StreamConnection extends AbstractConnection
4175
  */
4176
  protected function tcpStreamInitializer(ParametersInterface $parameters)
4177
  {
4178
- $uri = "tcp://{$parameters->host}:{$parameters->port}";
 
 
 
 
 
4179
  $flags = STREAM_CLIENT_CONNECT;
4180
 
4181
  if (isset($parameters->async_connect) && (bool) $parameters->async_connect) {
@@ -4196,7 +4433,7 @@ class StreamConnection extends AbstractConnection
4196
  if (isset($parameters->read_write_timeout)) {
4197
  $rwtimeout = (float) $parameters->read_write_timeout;
4198
  $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
4199
- $timeoutSeconds = floor($rwtimeout);
4200
  $timeoutUSeconds = ($rwtimeout - $timeoutSeconds) * 1000000;
4201
  stream_set_timeout($resource, $timeoutSeconds, $timeoutUSeconds);
4202
  }
@@ -4218,6 +4455,10 @@ class StreamConnection extends AbstractConnection
4218
  */
4219
  protected function unixStreamInitializer(ParametersInterface $parameters)
4220
  {
 
 
 
 
4221
  $uri = "unix://{$parameters->path}";
4222
  $flags = STREAM_CLIENT_CONNECT;
4223
 
@@ -4234,7 +4475,7 @@ class StreamConnection extends AbstractConnection
4234
  if (isset($parameters->read_write_timeout)) {
4235
  $rwtimeout = (float) $parameters->read_write_timeout;
4236
  $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
4237
- $timeoutSeconds = floor($rwtimeout);
4238
  $timeoutUSeconds = ($rwtimeout - $timeoutSeconds) * 1000000;
4239
  stream_set_timeout($resource, $timeoutSeconds, $timeoutUSeconds);
4240
  }
@@ -4313,7 +4554,7 @@ class StreamConnection extends AbstractConnection
4313
  $size = (int) $payload;
4314
 
4315
  if ($size === -1) {
4316
- return null;
4317
  }
4318
 
4319
  $bulkData = '';
@@ -4336,12 +4577,12 @@ class StreamConnection extends AbstractConnection
4336
  $count = (int) $payload;
4337
 
4338
  if ($count === -1) {
4339
- return null;
4340
  }
4341
 
4342
  $multibulk = array();
4343
 
4344
- for ($i = 0; $i < $count; $i++) {
4345
  $multibulk[$i] = $this->read();
4346
  }
4347
 
@@ -4373,7 +4614,7 @@ class StreamConnection extends AbstractConnection
4373
 
4374
  $buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
4375
 
4376
- for ($i = 0, $reqlen--; $i < $reqlen; $i++) {
4377
  $argument = $arguments[$i];
4378
  $arglen = strlen($argument);
4379
  $buffer .= "\${$arglen}\r\n{$argument}\r\n";
@@ -4526,7 +4767,7 @@ interface CompositeConnectionInterface extends NodeConnectionInterface
4526
  *
4527
  * The connection parameters supported by this class are:
4528
  *
4529
- * - scheme: it can be either 'tcp' or 'unix'.
4530
  * - host: hostname or IP address of the server.
4531
  * - port: TCP port of the server.
4532
  * - path: path of a UNIX domain socket when scheme is 'unix'.
@@ -4537,6 +4778,7 @@ interface CompositeConnectionInterface extends NodeConnectionInterface
4537
  * - persistent: the connection is left intact after a GC collection.
4538
  *
4539
  * @link https://github.com/nrk/phpiredis
 
4540
  * @author Daniele Alessandri <suppakilla@gmail.com>
4541
  */
4542
  class PhpiredisStreamConnection extends StreamConnection
@@ -4582,7 +4824,7 @@ class PhpiredisStreamConnection extends StreamConnection
4582
  */
4583
  protected function tcpStreamInitializer(ParametersInterface $parameters)
4584
  {
4585
- $uri = "tcp://{$parameters->host}:{$parameters->port}";
4586
  $flags = STREAM_CLIENT_CONNECT;
4587
  $socket = null;
4588
 
@@ -4606,7 +4848,7 @@ class PhpiredisStreamConnection extends StreamConnection
4606
  $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
4607
 
4608
  $timeout = array(
4609
- 'sec' => $timeoutSeconds = floor($rwtimeout),
4610
  'usec' => ($rwtimeout - $timeoutSeconds) * 1000000,
4611
  );
4612
 
@@ -4743,6 +4985,7 @@ class PhpiredisStreamConnection extends StreamConnection
4743
  * @link http://webd.is
4744
  * @link http://github.com/nicolasff/webdis
4745
  * @link http://github.com/seppo0010/phpiredis
 
4746
  * @author Daniele Alessandri <suppakilla@gmail.com>
4747
  */
4748
  class WebdisConnection implements NodeConnectionInterface
@@ -4761,7 +5004,7 @@ class WebdisConnection implements NodeConnectionInterface
4761
  $this->assertExtensions();
4762
 
4763
  if ($parameters->scheme !== 'http') {
4764
- throw new InvalidArgumentException("Invalid scheme: '{$parameters->scheme}'.");
4765
  }
4766
 
4767
  $this->parameters = $parameters;
@@ -4820,10 +5063,14 @@ class WebdisConnection implements NodeConnectionInterface
4820
  {
4821
  $parameters = $this->getParameters();
4822
 
 
 
 
 
4823
  $options = array(
4824
  CURLOPT_FAILONERROR => true,
4825
  CURLOPT_CONNECTTIMEOUT_MS => $parameters->timeout * 1000,
4826
- CURLOPT_URL => "{$parameters->scheme}://{$parameters->host}:{$parameters->port}",
4827
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
4828
  CURLOPT_POST => true,
4829
  CURLOPT_WRITEFUNCTION => array($this, 'feedReader'),
@@ -4921,9 +5168,9 @@ class WebdisConnection implements NodeConnectionInterface
4921
  *
4922
  * @param CommandInterface $command Command instance.
4923
  *
4924
- * @return string
4925
- *
4926
  * @throws NotSupportedException
 
 
4927
  */
4928
  protected function getCommandId(CommandInterface $command)
4929
  {
@@ -5066,7 +5313,7 @@ class WebdisConnection implements NodeConnectionInterface
5066
  *
5067
  * The connection parameters supported by this class are:
5068
  *
5069
- * - scheme: it can be either 'tcp' or 'unix'.
5070
  * - host: hostname or IP address of the server.
5071
  * - port: TCP port of the server.
5072
  * - path: path of a UNIX domain socket when scheme is 'unix'.
@@ -5074,6 +5321,7 @@ class WebdisConnection implements NodeConnectionInterface
5074
  * - read_write_timeout: timeout of read / write operations.
5075
  *
5076
  * @link http://github.com/nrk/phpiredis
 
5077
  * @author Daniele Alessandri <suppakilla@gmail.com>
5078
  */
5079
  class PhpiredisSocketConnection extends AbstractConnection
@@ -5126,13 +5374,15 @@ class PhpiredisSocketConnection extends AbstractConnection
5126
  */
5127
  protected function assertParameters(ParametersInterface $parameters)
5128
  {
 
 
5129
  if (isset($parameters->persistent)) {
5130
  throw new NotSupportedException(
5131
- "Persistent connections are not supported by this connection backend."
5132
  );
5133
  }
5134
 
5135
- return parent::assertParameters($parameters);
5136
  }
5137
 
5138
  /**
@@ -5197,22 +5447,54 @@ class PhpiredisSocketConnection extends AbstractConnection
5197
  $this->onConnectionError(trim($errstr), $errno);
5198
  }
5199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5200
  /**
5201
  * {@inheritdoc}
5202
  */
5203
  protected function createResource()
5204
  {
5205
- $isUnix = $this->parameters->scheme === 'unix';
5206
- $domain = $isUnix ? AF_UNIX : AF_INET;
5207
- $protocol = $isUnix ? 0 : SOL_TCP;
 
 
 
 
 
 
 
 
 
 
 
5208
 
5209
- $socket = @call_user_func('socket_create', $domain, SOCK_STREAM, $protocol);
5210
 
5211
  if (!is_resource($socket)) {
5212
  $this->emitSocketError();
5213
  }
5214
 
5215
- $this->setSocketOptions($socket, $this->parameters);
 
5216
 
5217
  return $socket;
5218
  }
@@ -5225,16 +5507,14 @@ class PhpiredisSocketConnection extends AbstractConnection
5225
  */
5226
  private function setSocketOptions($socket, ParametersInterface $parameters)
5227
  {
5228
- if ($parameters->scheme !== 'tcp') {
5229
- return;
5230
- }
5231
-
5232
- if (!socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1)) {
5233
- $this->emitSocketError();
5234
- }
5235
 
5236
- if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
5237
- $this->emitSocketError();
 
5238
  }
5239
 
5240
  if (isset($parameters->read_write_timeout)) {
@@ -5257,50 +5537,20 @@ class PhpiredisSocketConnection extends AbstractConnection
5257
  }
5258
  }
5259
 
5260
- /**
5261
- * Gets the address from the connection parameters.
5262
- *
5263
- * @param ParametersInterface $parameters Parameters used to initialize the connection.
5264
- *
5265
- * @return string
5266
- */
5267
- protected static function getAddress(ParametersInterface $parameters)
5268
- {
5269
- if ($parameters->scheme === 'unix') {
5270
- return $parameters->path;
5271
- }
5272
-
5273
- $host = $parameters->host;
5274
-
5275
- if (ip2long($host) === false) {
5276
- if (false === $addresses = gethostbynamel($host)) {
5277
- return false;
5278
- }
5279
-
5280
- return $addresses[array_rand($addresses)];
5281
- }
5282
-
5283
- return $host;
5284
- }
5285
-
5286
  /**
5287
  * Opens the actual connection to the server with a timeout.
5288
  *
 
 
5289
  * @param ParametersInterface $parameters Parameters used to initialize the connection.
5290
  *
5291
  * @return string
5292
  */
5293
- private function connectWithTimeout(ParametersInterface $parameters)
5294
  {
5295
- if (false === $host = self::getAddress($parameters)) {
5296
- $this->onConnectionError("Cannot resolve the address of '$parameters->host'.");
5297
- }
5298
-
5299
- $socket = $this->getResource();
5300
-
5301
  socket_set_nonblock($socket);
5302
 
5303
- if (@socket_connect($socket, $host, (int) $parameters->port) === false) {
5304
  $error = socket_last_error();
5305
 
5306
  if ($error != SOCKET_EINPROGRESS && $error != SOCKET_EALREADY) {
@@ -5322,9 +5572,11 @@ class PhpiredisSocketConnection extends AbstractConnection
5322
  if ($selected === 2) {
5323
  $this->onConnectionError('Connection refused.', SOCKET_ECONNREFUSED);
5324
  }
 
5325
  if ($selected === 0) {
5326
  $this->onConnectionError('Connection timed out.', SOCKET_ETIMEDOUT);
5327
  }
 
5328
  if ($selected === false) {
5329
  $this->emitSocketError();
5330
  }
@@ -5335,13 +5587,9 @@ class PhpiredisSocketConnection extends AbstractConnection
5335
  */
5336
  public function connect()
5337
  {
5338
- if (parent::connect()) {
5339
- $this->connectWithTimeout($this->parameters);
5340
-
5341
- if ($this->initCommands) {
5342
- foreach ($this->initCommands as $command) {
5343
- $this->executeCommand($command);
5344
- }
5345
  }
5346
  }
5347
  }
@@ -5388,7 +5636,7 @@ class PhpiredisSocketConnection extends AbstractConnection
5388
  $reader = $this->reader;
5389
 
5390
  while (PHPIREDIS_READER_STATE_INCOMPLETE === $state = phpiredis_reader_get_state($reader)) {
5391
- if (@socket_recv($socket, $buffer, 4096, 0) === false || $buffer === '') {
5392
  $this->emitSocketError();
5393
  }
5394
 
@@ -5469,7 +5717,7 @@ class CompositeStreamConnection extends StreamConnection implements CompositeCon
5469
  public function readBuffer($length)
5470
  {
5471
  if ($length <= 0) {
5472
- throw new InvalidArgumentException('Length parameter must be greater than 0.');
5473
  }
5474
 
5475
  $value = '';
@@ -5599,11 +5847,20 @@ class Parameters implements ParametersInterface
5599
  /**
5600
  * Parses an URI string returning an array of connection parameters.
5601
  *
5602
- * @param string $uri URI string.
 
 
 
 
5603
  *
5604
- * @return array
 
 
 
5605
  *
5606
  * @throws \InvalidArgumentException
 
 
5607
  */
5608
  public static function parse($uri)
5609
  {
@@ -5612,8 +5869,16 @@ class Parameters implements ParametersInterface
5612
  $uri = str_ireplace('unix:///', 'unix://localhost/', $uri);
5613
  }
5614
 
5615
- if (!($parsed = parse_url($uri)) || !isset($parsed['host'])) {
5616
- throw new InvalidArgumentException("Invalid parameters URI: $uri");
 
 
 
 
 
 
 
 
5617
  }
5618
 
5619
  if (isset($parsed['query'])) {
@@ -5623,6 +5888,23 @@ class Parameters implements ParametersInterface
5623
  $parsed = array_merge($parsed, $queryarray);
5624
  }
5625
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5626
  return $parsed;
5627
  }
5628
 
@@ -5681,8 +5963,9 @@ class Parameters implements ParametersInterface
5681
  class Factory implements FactoryInterface
5682
  {
5683
  protected $schemes = array(
5684
- 'tcp' => 'Predis\Connection\StreamConnection',
5685
  'unix' => 'Predis\Connection\StreamConnection',
 
5686
  'http' => 'Predis\Connection\WebdisConnection',
5687
  );
5688
 
@@ -5693,9 +5976,9 @@ class Factory implements FactoryInterface
5693
  *
5694
  * @param mixed $initializer FQN of a connection class or a callable for lazy initialization.
5695
  *
5696
- * @return mixed
5697
- *
5698
  * @throws \InvalidArgumentException
 
 
5699
  */
5700
  protected function checkInitializer($initializer)
5701
  {
@@ -5703,10 +5986,10 @@ class Factory implements FactoryInterface
5703
  return $initializer;
5704
  }
5705
 
5706
- $class = new ReflectionClass($initializer);
5707
 
5708
  if (!$class->isSubclassOf('Predis\Connection\NodeConnectionInterface')) {
5709
- throw new InvalidArgumentException(
5710
  'A connection initializer must be a valid connection class or a callable object.'
5711
  );
5712
  }
@@ -5742,7 +6025,7 @@ class Factory implements FactoryInterface
5742
  $scheme = $parameters->scheme;
5743
 
5744
  if (!isset($this->schemes[$scheme])) {
5745
- throw new InvalidArgumentException("Unknown connection scheme: '$scheme'.");
5746
  }
5747
 
5748
  $initializer = $this->schemes[$scheme];
@@ -5755,8 +6038,8 @@ class Factory implements FactoryInterface
5755
  }
5756
 
5757
  if (!$connection instanceof NodeConnectionInterface) {
5758
- throw new UnexpectedValueException(
5759
- "Objects returned by connection initializers must implement ".
5760
  "'Predis\Connection\NodeConnectionInterface'."
5761
  );
5762
  }
@@ -5813,8 +6096,6 @@ class Factory implements FactoryInterface
5813
 
5814
  namespace Predis\Profile;
5815
 
5816
- use InvalidArgumentException;
5817
- use ReflectionClass;
5818
  use Predis\ClientException;
5819
  use Predis\Command\CommandInterface;
5820
  use Predis\Command\Processor\ProcessorInterface;
@@ -5959,10 +6240,10 @@ abstract class RedisProfile implements ProfileInterface
5959
  */
5960
  public function defineCommand($commandID, $class)
5961
  {
5962
- $reflection = new ReflectionClass($class);
5963
 
5964
  if (!$reflection->isSubclassOf('Predis\Command\CommandInterface')) {
5965
- throw new InvalidArgumentException("The class '$class' is not a valid command class.");
5966
  }
5967
 
5968
  $this->commands[strtoupper($commandID)] = $class;
@@ -6019,231 +6300,233 @@ class RedisVersion300 extends RedisProfile
6019
  /* ---------------- Redis 1.2 ---------------- */
6020
 
6021
  /* commands operating on the key space */
6022
- 'EXISTS' => 'Predis\Command\KeyExists',
6023
- 'DEL' => 'Predis\Command\KeyDelete',
6024
- 'TYPE' => 'Predis\Command\KeyType',
6025
- 'KEYS' => 'Predis\Command\KeyKeys',
6026
- 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6027
- 'RENAME' => 'Predis\Command\KeyRename',
6028
- 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6029
- 'EXPIRE' => 'Predis\Command\KeyExpire',
6030
- 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6031
- 'TTL' => 'Predis\Command\KeyTimeToLive',
6032
- 'MOVE' => 'Predis\Command\KeyMove',
6033
- 'SORT' => 'Predis\Command\KeySort',
6034
- 'DUMP' => 'Predis\Command\KeyDump',
6035
- 'RESTORE' => 'Predis\Command\KeyRestore',
6036
 
6037
  /* commands operating on string values */
6038
- 'SET' => 'Predis\Command\StringSet',
6039
- 'SETNX' => 'Predis\Command\StringSetPreserve',
6040
- 'MSET' => 'Predis\Command\StringSetMultiple',
6041
- 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6042
- 'GET' => 'Predis\Command\StringGet',
6043
- 'MGET' => 'Predis\Command\StringGetMultiple',
6044
- 'GETSET' => 'Predis\Command\StringGetSet',
6045
- 'INCR' => 'Predis\Command\StringIncrement',
6046
- 'INCRBY' => 'Predis\Command\StringIncrementBy',
6047
- 'DECR' => 'Predis\Command\StringDecrement',
6048
- 'DECRBY' => 'Predis\Command\StringDecrementBy',
6049
 
6050
  /* commands operating on lists */
6051
- 'RPUSH' => 'Predis\Command\ListPushTail',
6052
- 'LPUSH' => 'Predis\Command\ListPushHead',
6053
- 'LLEN' => 'Predis\Command\ListLength',
6054
- 'LRANGE' => 'Predis\Command\ListRange',
6055
- 'LTRIM' => 'Predis\Command\ListTrim',
6056
- 'LINDEX' => 'Predis\Command\ListIndex',
6057
- 'LSET' => 'Predis\Command\ListSet',
6058
- 'LREM' => 'Predis\Command\ListRemove',
6059
- 'LPOP' => 'Predis\Command\ListPopFirst',
6060
- 'RPOP' => 'Predis\Command\ListPopLast',
6061
- 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6062
 
6063
  /* commands operating on sets */
6064
- 'SADD' => 'Predis\Command\SetAdd',
6065
- 'SREM' => 'Predis\Command\SetRemove',
6066
- 'SPOP' => 'Predis\Command\SetPop',
6067
- 'SMOVE' => 'Predis\Command\SetMove',
6068
- 'SCARD' => 'Predis\Command\SetCardinality',
6069
- 'SISMEMBER' => 'Predis\Command\SetIsMember',
6070
- 'SINTER' => 'Predis\Command\SetIntersection',
6071
- 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6072
- 'SUNION' => 'Predis\Command\SetUnion',
6073
- 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6074
- 'SDIFF' => 'Predis\Command\SetDifference',
6075
- 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
6076
- 'SMEMBERS' => 'Predis\Command\SetMembers',
6077
- 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
6078
 
6079
  /* commands operating on sorted sets */
6080
- 'ZADD' => 'Predis\Command\ZSetAdd',
6081
- 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
6082
- 'ZREM' => 'Predis\Command\ZSetRemove',
6083
- 'ZRANGE' => 'Predis\Command\ZSetRange',
6084
- 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
6085
- 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
6086
- 'ZCARD' => 'Predis\Command\ZSetCardinality',
6087
- 'ZSCORE' => 'Predis\Command\ZSetScore',
6088
- 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
6089
 
6090
  /* connection related commands */
6091
- 'PING' => 'Predis\Command\ConnectionPing',
6092
- 'AUTH' => 'Predis\Command\ConnectionAuth',
6093
- 'SELECT' => 'Predis\Command\ConnectionSelect',
6094
- 'ECHO' => 'Predis\Command\ConnectionEcho',
6095
- 'QUIT' => 'Predis\Command\ConnectionQuit',
6096
 
6097
  /* remote server control commands */
6098
- 'INFO' => 'Predis\Command\ServerInfoV26x',
6099
- 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
6100
- 'MONITOR' => 'Predis\Command\ServerMonitor',
6101
- 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
6102
- 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
6103
- 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
6104
- 'SAVE' => 'Predis\Command\ServerSave',
6105
- 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
6106
- 'LASTSAVE' => 'Predis\Command\ServerLastSave',
6107
- 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
6108
- 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
6109
 
6110
  /* ---------------- Redis 2.0 ---------------- */
6111
 
6112
  /* commands operating on string values */
6113
- 'SETEX' => 'Predis\Command\StringSetExpire',
6114
- 'APPEND' => 'Predis\Command\StringAppend',
6115
- 'SUBSTR' => 'Predis\Command\StringSubstr',
6116
 
6117
  /* commands operating on lists */
6118
- 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
6119
- 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
6120
 
6121
  /* commands operating on sorted sets */
6122
- 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
6123
- 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
6124
- 'ZCOUNT' => 'Predis\Command\ZSetCount',
6125
- 'ZRANK' => 'Predis\Command\ZSetRank',
6126
- 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
6127
- 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
6128
 
6129
  /* commands operating on hashes */
6130
- 'HSET' => 'Predis\Command\HashSet',
6131
- 'HSETNX' => 'Predis\Command\HashSetPreserve',
6132
- 'HMSET' => 'Predis\Command\HashSetMultiple',
6133
- 'HINCRBY' => 'Predis\Command\HashIncrementBy',
6134
- 'HGET' => 'Predis\Command\HashGet',
6135
- 'HMGET' => 'Predis\Command\HashGetMultiple',
6136
- 'HDEL' => 'Predis\Command\HashDelete',
6137
- 'HEXISTS' => 'Predis\Command\HashExists',
6138
- 'HLEN' => 'Predis\Command\HashLength',
6139
- 'HKEYS' => 'Predis\Command\HashKeys',
6140
- 'HVALS' => 'Predis\Command\HashValues',
6141
- 'HGETALL' => 'Predis\Command\HashGetAll',
6142
 
6143
  /* transactions */
6144
- 'MULTI' => 'Predis\Command\TransactionMulti',
6145
- 'EXEC' => 'Predis\Command\TransactionExec',
6146
- 'DISCARD' => 'Predis\Command\TransactionDiscard',
6147
 
6148
  /* publish - subscribe */
6149
- 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
6150
- 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
6151
- 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
6152
- 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
6153
- 'PUBLISH' => 'Predis\Command\PubSubPublish',
6154
 
6155
  /* remote server control commands */
6156
- 'CONFIG' => 'Predis\Command\ServerConfig',
6157
 
6158
  /* ---------------- Redis 2.2 ---------------- */
6159
 
6160
  /* commands operating on the key space */
6161
- 'PERSIST' => 'Predis\Command\KeyPersist',
6162
 
6163
  /* commands operating on string values */
6164
- 'STRLEN' => 'Predis\Command\StringStrlen',
6165
- 'SETRANGE' => 'Predis\Command\StringSetRange',
6166
- 'GETRANGE' => 'Predis\Command\StringGetRange',
6167
- 'SETBIT' => 'Predis\Command\StringSetBit',
6168
- 'GETBIT' => 'Predis\Command\StringGetBit',
6169
 
6170
  /* commands operating on lists */
6171
- 'RPUSHX' => 'Predis\Command\ListPushTailX',
6172
- 'LPUSHX' => 'Predis\Command\ListPushHeadX',
6173
- 'LINSERT' => 'Predis\Command\ListInsert',
6174
- 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
6175
 
6176
  /* commands operating on sorted sets */
6177
- 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
6178
 
6179
  /* transactions */
6180
- 'WATCH' => 'Predis\Command\TransactionWatch',
6181
- 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
6182
 
6183
  /* remote server control commands */
6184
- 'OBJECT' => 'Predis\Command\ServerObject',
6185
- 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
6186
 
6187
  /* ---------------- Redis 2.4 ---------------- */
6188
 
6189
  /* remote server control commands */
6190
- 'CLIENT' => 'Predis\Command\ServerClient',
6191
 
6192
  /* ---------------- Redis 2.6 ---------------- */
6193
 
6194
  /* commands operating on the key space */
6195
- 'PTTL' => 'Predis\Command\KeyPreciseTimeToLive',
6196
- 'PEXPIRE' => 'Predis\Command\KeyPreciseExpire',
6197
- 'PEXPIREAT' => 'Predis\Command\KeyPreciseExpireAt',
 
6198
 
6199
  /* commands operating on string values */
6200
- 'PSETEX' => 'Predis\Command\StringPreciseSetExpire',
6201
- 'INCRBYFLOAT' => 'Predis\Command\StringIncrementByFloat',
6202
- 'BITOP' => 'Predis\Command\StringBitOp',
6203
- 'BITCOUNT' => 'Predis\Command\StringBitCount',
6204
 
6205
  /* commands operating on hashes */
6206
- 'HINCRBYFLOAT' => 'Predis\Command\HashIncrementByFloat',
6207
 
6208
  /* scripting */
6209
- 'EVAL' => 'Predis\Command\ServerEval',
6210
- 'EVALSHA' => 'Predis\Command\ServerEvalSHA',
6211
- 'SCRIPT' => 'Predis\Command\ServerScript',
6212
 
6213
  /* remote server control commands */
6214
- 'TIME' => 'Predis\Command\ServerTime',
6215
- 'SENTINEL' => 'Predis\Command\ServerSentinel',
6216
 
6217
  /* ---------------- Redis 2.8 ---------------- */
6218
 
6219
  /* commands operating on the key space */
6220
- 'SCAN' => 'Predis\Command\KeyScan',
6221
 
6222
  /* commands operating on string values */
6223
- 'BITPOS' => 'Predis\Command\StringBitPos',
6224
 
6225
  /* commands operating on sets */
6226
- 'SSCAN' => 'Predis\Command\SetScan',
6227
 
6228
  /* commands operating on sorted sets */
6229
- 'ZSCAN' => 'Predis\Command\ZSetScan',
6230
- 'ZLEXCOUNT' => 'Predis\Command\ZSetLexCount',
6231
- 'ZRANGEBYLEX' => 'Predis\Command\ZSetRangeByLex',
6232
- 'ZREMRANGEBYLEX' => 'Predis\Command\ZSetRemoveRangeByLex',
 
6233
 
6234
  /* commands operating on hashes */
6235
- 'HSCAN' => 'Predis\Command\HashScan',
6236
 
6237
  /* publish - subscribe */
6238
- 'PUBSUB' => 'Predis\Command\PubSubPubsub',
6239
 
6240
  /* commands operating on HyperLogLog */
6241
- 'PFADD' => 'Predis\Command\HyperLogLogAdd',
6242
- 'PFCOUNT' => 'Predis\Command\HyperLogLogCount',
6243
- 'PFMERGE' => 'Predis\Command\HyperLogLogMerge',
6244
 
6245
  /* remote server control commands */
6246
- 'COMMAND' => 'Predis\Command\ServerCommand',
6247
 
6248
  /* ---------------- Redis 3.0 ---------------- */
6249
 
@@ -6275,200 +6558,201 @@ class RedisVersion260 extends RedisProfile
6275
  /* ---------------- Redis 1.2 ---------------- */
6276
 
6277
  /* commands operating on the key space */
6278
- 'EXISTS' => 'Predis\Command\KeyExists',
6279
- 'DEL' => 'Predis\Command\KeyDelete',
6280
- 'TYPE' => 'Predis\Command\KeyType',
6281
- 'KEYS' => 'Predis\Command\KeyKeys',
6282
- 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6283
- 'RENAME' => 'Predis\Command\KeyRename',
6284
- 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6285
- 'EXPIRE' => 'Predis\Command\KeyExpire',
6286
- 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6287
- 'TTL' => 'Predis\Command\KeyTimeToLive',
6288
- 'MOVE' => 'Predis\Command\KeyMove',
6289
- 'SORT' => 'Predis\Command\KeySort',
6290
- 'DUMP' => 'Predis\Command\KeyDump',
6291
- 'RESTORE' => 'Predis\Command\KeyRestore',
6292
 
6293
  /* commands operating on string values */
6294
- 'SET' => 'Predis\Command\StringSet',
6295
- 'SETNX' => 'Predis\Command\StringSetPreserve',
6296
- 'MSET' => 'Predis\Command\StringSetMultiple',
6297
- 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6298
- 'GET' => 'Predis\Command\StringGet',
6299
- 'MGET' => 'Predis\Command\StringGetMultiple',
6300
- 'GETSET' => 'Predis\Command\StringGetSet',
6301
- 'INCR' => 'Predis\Command\StringIncrement',
6302
- 'INCRBY' => 'Predis\Command\StringIncrementBy',
6303
- 'DECR' => 'Predis\Command\StringDecrement',
6304
- 'DECRBY' => 'Predis\Command\StringDecrementBy',
6305
 
6306
  /* commands operating on lists */
6307
- 'RPUSH' => 'Predis\Command\ListPushTail',
6308
- 'LPUSH' => 'Predis\Command\ListPushHead',
6309
- 'LLEN' => 'Predis\Command\ListLength',
6310
- 'LRANGE' => 'Predis\Command\ListRange',
6311
- 'LTRIM' => 'Predis\Command\ListTrim',
6312
- 'LINDEX' => 'Predis\Command\ListIndex',
6313
- 'LSET' => 'Predis\Command\ListSet',
6314
- 'LREM' => 'Predis\Command\ListRemove',
6315
- 'LPOP' => 'Predis\Command\ListPopFirst',
6316
- 'RPOP' => 'Predis\Command\ListPopLast',
6317
- 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6318
 
6319
  /* commands operating on sets */
6320
- 'SADD' => 'Predis\Command\SetAdd',
6321
- 'SREM' => 'Predis\Command\SetRemove',
6322
- 'SPOP' => 'Predis\Command\SetPop',
6323
- 'SMOVE' => 'Predis\Command\SetMove',
6324
- 'SCARD' => 'Predis\Command\SetCardinality',
6325
- 'SISMEMBER' => 'Predis\Command\SetIsMember',
6326
- 'SINTER' => 'Predis\Command\SetIntersection',
6327
- 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6328
- 'SUNION' => 'Predis\Command\SetUnion',
6329
- 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6330
- 'SDIFF' => 'Predis\Command\SetDifference',
6331
- 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
6332
- 'SMEMBERS' => 'Predis\Command\SetMembers',
6333
- 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
6334
 
6335
  /* commands operating on sorted sets */
6336
- 'ZADD' => 'Predis\Command\ZSetAdd',
6337
- 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
6338
- 'ZREM' => 'Predis\Command\ZSetRemove',
6339
- 'ZRANGE' => 'Predis\Command\ZSetRange',
6340
- 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
6341
- 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
6342
- 'ZCARD' => 'Predis\Command\ZSetCardinality',
6343
- 'ZSCORE' => 'Predis\Command\ZSetScore',
6344
- 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
6345
 
6346
  /* connection related commands */
6347
- 'PING' => 'Predis\Command\ConnectionPing',
6348
- 'AUTH' => 'Predis\Command\ConnectionAuth',
6349
- 'SELECT' => 'Predis\Command\ConnectionSelect',
6350
- 'ECHO' => 'Predis\Command\ConnectionEcho',
6351
- 'QUIT' => 'Predis\Command\ConnectionQuit',
6352
 
6353
  /* remote server control commands */
6354
- 'INFO' => 'Predis\Command\ServerInfoV26x',
6355
- 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
6356
- 'MONITOR' => 'Predis\Command\ServerMonitor',
6357
- 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
6358
- 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
6359
- 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
6360
- 'SAVE' => 'Predis\Command\ServerSave',
6361
- 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
6362
- 'LASTSAVE' => 'Predis\Command\ServerLastSave',
6363
- 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
6364
- 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
6365
 
6366
  /* ---------------- Redis 2.0 ---------------- */
6367
 
6368
  /* commands operating on string values */
6369
- 'SETEX' => 'Predis\Command\StringSetExpire',
6370
- 'APPEND' => 'Predis\Command\StringAppend',
6371
- 'SUBSTR' => 'Predis\Command\StringSubstr',
6372
 
6373
  /* commands operating on lists */
6374
- 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
6375
- 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
6376
 
6377
  /* commands operating on sorted sets */
6378
- 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
6379
- 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
6380
- 'ZCOUNT' => 'Predis\Command\ZSetCount',
6381
- 'ZRANK' => 'Predis\Command\ZSetRank',
6382
- 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
6383
- 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
6384
 
6385
  /* commands operating on hashes */
6386
- 'HSET' => 'Predis\Command\HashSet',
6387
- 'HSETNX' => 'Predis\Command\HashSetPreserve',
6388
- 'HMSET' => 'Predis\Command\HashSetMultiple',
6389
- 'HINCRBY' => 'Predis\Command\HashIncrementBy',
6390
- 'HGET' => 'Predis\Command\HashGet',
6391
- 'HMGET' => 'Predis\Command\HashGetMultiple',
6392
- 'HDEL' => 'Predis\Command\HashDelete',
6393
- 'HEXISTS' => 'Predis\Command\HashExists',
6394
- 'HLEN' => 'Predis\Command\HashLength',
6395
- 'HKEYS' => 'Predis\Command\HashKeys',
6396
- 'HVALS' => 'Predis\Command\HashValues',
6397
- 'HGETALL' => 'Predis\Command\HashGetAll',
6398
 
6399
  /* transactions */
6400
- 'MULTI' => 'Predis\Command\TransactionMulti',
6401
- 'EXEC' => 'Predis\Command\TransactionExec',
6402
- 'DISCARD' => 'Predis\Command\TransactionDiscard',
6403
 
6404
  /* publish - subscribe */
6405
- 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
6406
- 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
6407
- 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
6408
- 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
6409
- 'PUBLISH' => 'Predis\Command\PubSubPublish',
6410
 
6411
  /* remote server control commands */
6412
- 'CONFIG' => 'Predis\Command\ServerConfig',
6413
 
6414
  /* ---------------- Redis 2.2 ---------------- */
6415
 
6416
  /* commands operating on the key space */
6417
- 'PERSIST' => 'Predis\Command\KeyPersist',
6418
 
6419
  /* commands operating on string values */
6420
- 'STRLEN' => 'Predis\Command\StringStrlen',
6421
- 'SETRANGE' => 'Predis\Command\StringSetRange',
6422
- 'GETRANGE' => 'Predis\Command\StringGetRange',
6423
- 'SETBIT' => 'Predis\Command\StringSetBit',
6424
- 'GETBIT' => 'Predis\Command\StringGetBit',
6425
 
6426
  /* commands operating on lists */
6427
- 'RPUSHX' => 'Predis\Command\ListPushTailX',
6428
- 'LPUSHX' => 'Predis\Command\ListPushHeadX',
6429
- 'LINSERT' => 'Predis\Command\ListInsert',
6430
- 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
6431
 
6432
  /* commands operating on sorted sets */
6433
- 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
6434
 
6435
  /* transactions */
6436
- 'WATCH' => 'Predis\Command\TransactionWatch',
6437
- 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
6438
 
6439
  /* remote server control commands */
6440
- 'OBJECT' => 'Predis\Command\ServerObject',
6441
- 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
6442
 
6443
  /* ---------------- Redis 2.4 ---------------- */
6444
 
6445
  /* remote server control commands */
6446
- 'CLIENT' => 'Predis\Command\ServerClient',
6447
 
6448
  /* ---------------- Redis 2.6 ---------------- */
6449
 
6450
  /* commands operating on the key space */
6451
- 'PTTL' => 'Predis\Command\KeyPreciseTimeToLive',
6452
- 'PEXPIRE' => 'Predis\Command\KeyPreciseExpire',
6453
- 'PEXPIREAT' => 'Predis\Command\KeyPreciseExpireAt',
 
6454
 
6455
  /* commands operating on string values */
6456
- 'PSETEX' => 'Predis\Command\StringPreciseSetExpire',
6457
- 'INCRBYFLOAT' => 'Predis\Command\StringIncrementByFloat',
6458
- 'BITOP' => 'Predis\Command\StringBitOp',
6459
- 'BITCOUNT' => 'Predis\Command\StringBitCount',
6460
 
6461
  /* commands operating on hashes */
6462
- 'HINCRBYFLOAT' => 'Predis\Command\HashIncrementByFloat',
6463
 
6464
  /* scripting */
6465
- 'EVAL' => 'Predis\Command\ServerEval',
6466
- 'EVALSHA' => 'Predis\Command\ServerEvalSHA',
6467
- 'SCRIPT' => 'Predis\Command\ServerScript',
6468
 
6469
  /* remote server control commands */
6470
- 'TIME' => 'Predis\Command\ServerTime',
6471
- 'SENTINEL' => 'Predis\Command\ServerSentinel',
6472
  );
6473
  }
6474
  }
@@ -6497,231 +6781,233 @@ class RedisVersion280 extends RedisProfile
6497
  /* ---------------- Redis 1.2 ---------------- */
6498
 
6499
  /* commands operating on the key space */
6500
- 'EXISTS' => 'Predis\Command\KeyExists',
6501
- 'DEL' => 'Predis\Command\KeyDelete',
6502
- 'TYPE' => 'Predis\Command\KeyType',
6503
- 'KEYS' => 'Predis\Command\KeyKeys',
6504
- 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6505
- 'RENAME' => 'Predis\Command\KeyRename',
6506
- 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6507
- 'EXPIRE' => 'Predis\Command\KeyExpire',
6508
- 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6509
- 'TTL' => 'Predis\Command\KeyTimeToLive',
6510
- 'MOVE' => 'Predis\Command\KeyMove',
6511
- 'SORT' => 'Predis\Command\KeySort',
6512
- 'DUMP' => 'Predis\Command\KeyDump',
6513
- 'RESTORE' => 'Predis\Command\KeyRestore',
6514
 
6515
  /* commands operating on string values */
6516
- 'SET' => 'Predis\Command\StringSet',
6517
- 'SETNX' => 'Predis\Command\StringSetPreserve',
6518
- 'MSET' => 'Predis\Command\StringSetMultiple',
6519
- 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6520
- 'GET' => 'Predis\Command\StringGet',
6521
- 'MGET' => 'Predis\Command\StringGetMultiple',
6522
- 'GETSET' => 'Predis\Command\StringGetSet',
6523
- 'INCR' => 'Predis\Command\StringIncrement',
6524
- 'INCRBY' => 'Predis\Command\StringIncrementBy',
6525
- 'DECR' => 'Predis\Command\StringDecrement',
6526
- 'DECRBY' => 'Predis\Command\StringDecrementBy',
6527
 
6528
  /* commands operating on lists */
6529
- 'RPUSH' => 'Predis\Command\ListPushTail',
6530
- 'LPUSH' => 'Predis\Command\ListPushHead',
6531
- 'LLEN' => 'Predis\Command\ListLength',
6532
- 'LRANGE' => 'Predis\Command\ListRange',
6533
- 'LTRIM' => 'Predis\Command\ListTrim',
6534
- 'LINDEX' => 'Predis\Command\ListIndex',
6535
- 'LSET' => 'Predis\Command\ListSet',
6536
- 'LREM' => 'Predis\Command\ListRemove',
6537
- 'LPOP' => 'Predis\Command\ListPopFirst',
6538
- 'RPOP' => 'Predis\Command\ListPopLast',
6539
- 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6540
 
6541
  /* commands operating on sets */
6542
- 'SADD' => 'Predis\Command\SetAdd',
6543
- 'SREM' => 'Predis\Command\SetRemove',
6544
- 'SPOP' => 'Predis\Command\SetPop',
6545
- 'SMOVE' => 'Predis\Command\SetMove',
6546
- 'SCARD' => 'Predis\Command\SetCardinality',
6547
- 'SISMEMBER' => 'Predis\Command\SetIsMember',
6548
- 'SINTER' => 'Predis\Command\SetIntersection',
6549
- 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6550
- 'SUNION' => 'Predis\Command\SetUnion',
6551
- 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6552
- 'SDIFF' => 'Predis\Command\SetDifference',
6553
- 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
6554
- 'SMEMBERS' => 'Predis\Command\SetMembers',
6555
- 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
6556
 
6557
  /* commands operating on sorted sets */
6558
- 'ZADD' => 'Predis\Command\ZSetAdd',
6559
- 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
6560
- 'ZREM' => 'Predis\Command\ZSetRemove',
6561
- 'ZRANGE' => 'Predis\Command\ZSetRange',
6562
- 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
6563
- 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
6564
- 'ZCARD' => 'Predis\Command\ZSetCardinality',
6565
- 'ZSCORE' => 'Predis\Command\ZSetScore',
6566
- 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
6567
 
6568
  /* connection related commands */
6569
- 'PING' => 'Predis\Command\ConnectionPing',
6570
- 'AUTH' => 'Predis\Command\ConnectionAuth',
6571
- 'SELECT' => 'Predis\Command\ConnectionSelect',
6572
- 'ECHO' => 'Predis\Command\ConnectionEcho',
6573
- 'QUIT' => 'Predis\Command\ConnectionQuit',
6574
 
6575
  /* remote server control commands */
6576
- 'INFO' => 'Predis\Command\ServerInfoV26x',
6577
- 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
6578
- 'MONITOR' => 'Predis\Command\ServerMonitor',
6579
- 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
6580
- 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
6581
- 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
6582
- 'SAVE' => 'Predis\Command\ServerSave',
6583
- 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
6584
- 'LASTSAVE' => 'Predis\Command\ServerLastSave',
6585
- 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
6586
- 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
6587
 
6588
  /* ---------------- Redis 2.0 ---------------- */
6589
 
6590
  /* commands operating on string values */
6591
- 'SETEX' => 'Predis\Command\StringSetExpire',
6592
- 'APPEND' => 'Predis\Command\StringAppend',
6593
- 'SUBSTR' => 'Predis\Command\StringSubstr',
6594
 
6595
  /* commands operating on lists */
6596
- 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
6597
- 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
6598
 
6599
  /* commands operating on sorted sets */
6600
- 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
6601
- 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
6602
- 'ZCOUNT' => 'Predis\Command\ZSetCount',
6603
- 'ZRANK' => 'Predis\Command\ZSetRank',
6604
- 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
6605
- 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
6606
 
6607
  /* commands operating on hashes */
6608
- 'HSET' => 'Predis\Command\HashSet',
6609
- 'HSETNX' => 'Predis\Command\HashSetPreserve',
6610
- 'HMSET' => 'Predis\Command\HashSetMultiple',
6611
- 'HINCRBY' => 'Predis\Command\HashIncrementBy',
6612
- 'HGET' => 'Predis\Command\HashGet',
6613
- 'HMGET' => 'Predis\Command\HashGetMultiple',
6614
- 'HDEL' => 'Predis\Command\HashDelete',
6615
- 'HEXISTS' => 'Predis\Command\HashExists',
6616
- 'HLEN' => 'Predis\Command\HashLength',
6617
- 'HKEYS' => 'Predis\Command\HashKeys',
6618
- 'HVALS' => 'Predis\Command\HashValues',
6619
- 'HGETALL' => 'Predis\Command\HashGetAll',
6620
 
6621
  /* transactions */
6622
- 'MULTI' => 'Predis\Command\TransactionMulti',
6623
- 'EXEC' => 'Predis\Command\TransactionExec',
6624
- 'DISCARD' => 'Predis\Command\TransactionDiscard',
6625
 
6626
  /* publish - subscribe */
6627
- 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
6628
- 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
6629
- 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
6630
- 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
6631
- 'PUBLISH' => 'Predis\Command\PubSubPublish',
6632
 
6633
  /* remote server control commands */
6634
- 'CONFIG' => 'Predis\Command\ServerConfig',
6635
 
6636
  /* ---------------- Redis 2.2 ---------------- */
6637
 
6638
  /* commands operating on the key space */
6639
- 'PERSIST' => 'Predis\Command\KeyPersist',
6640
 
6641
  /* commands operating on string values */
6642
- 'STRLEN' => 'Predis\Command\StringStrlen',
6643
- 'SETRANGE' => 'Predis\Command\StringSetRange',
6644
- 'GETRANGE' => 'Predis\Command\StringGetRange',
6645
- 'SETBIT' => 'Predis\Command\StringSetBit',
6646
- 'GETBIT' => 'Predis\Command\StringGetBit',
6647
 
6648
  /* commands operating on lists */
6649
- 'RPUSHX' => 'Predis\Command\ListPushTailX',
6650
- 'LPUSHX' => 'Predis\Command\ListPushHeadX',
6651
- 'LINSERT' => 'Predis\Command\ListInsert',
6652
- 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
6653
 
6654
  /* commands operating on sorted sets */
6655
- 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
6656
 
6657
  /* transactions */
6658
- 'WATCH' => 'Predis\Command\TransactionWatch',
6659
- 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
6660
 
6661
  /* remote server control commands */
6662
- 'OBJECT' => 'Predis\Command\ServerObject',
6663
- 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
6664
 
6665
  /* ---------------- Redis 2.4 ---------------- */
6666
 
6667
  /* remote server control commands */
6668
- 'CLIENT' => 'Predis\Command\ServerClient',
6669
 
6670
  /* ---------------- Redis 2.6 ---------------- */
6671
 
6672
  /* commands operating on the key space */
6673
- 'PTTL' => 'Predis\Command\KeyPreciseTimeToLive',
6674
- 'PEXPIRE' => 'Predis\Command\KeyPreciseExpire',
6675
- 'PEXPIREAT' => 'Predis\Command\KeyPreciseExpireAt',
 
6676
 
6677
  /* commands operating on string values */
6678
- 'PSETEX' => 'Predis\Command\StringPreciseSetExpire',
6679
- 'INCRBYFLOAT' => 'Predis\Command\StringIncrementByFloat',
6680
- 'BITOP' => 'Predis\Command\StringBitOp',
6681
- 'BITCOUNT' => 'Predis\Command\StringBitCount',
6682
 
6683
  /* commands operating on hashes */
6684
- 'HINCRBYFLOAT' => 'Predis\Command\HashIncrementByFloat',
6685
 
6686
  /* scripting */
6687
- 'EVAL' => 'Predis\Command\ServerEval',
6688
- 'EVALSHA' => 'Predis\Command\ServerEvalSHA',
6689
- 'SCRIPT' => 'Predis\Command\ServerScript',
6690
 
6691
  /* remote server control commands */
6692
- 'TIME' => 'Predis\Command\ServerTime',
6693
- 'SENTINEL' => 'Predis\Command\ServerSentinel',
6694
 
6695
  /* ---------------- Redis 2.8 ---------------- */
6696
 
6697
  /* commands operating on the key space */
6698
- 'SCAN' => 'Predis\Command\KeyScan',
6699
 
6700
  /* commands operating on string values */
6701
- 'BITPOS' => 'Predis\Command\StringBitPos',
6702
 
6703
  /* commands operating on sets */
6704
- 'SSCAN' => 'Predis\Command\SetScan',
6705
 
6706
  /* commands operating on sorted sets */
6707
- 'ZSCAN' => 'Predis\Command\ZSetScan',
6708
- 'ZLEXCOUNT' => 'Predis\Command\ZSetLexCount',
6709
- 'ZRANGEBYLEX' => 'Predis\Command\ZSetRangeByLex',
6710
- 'ZREMRANGEBYLEX' => 'Predis\Command\ZSetRemoveRangeByLex',
 
6711
 
6712
  /* commands operating on hashes */
6713
- 'HSCAN' => 'Predis\Command\HashScan',
6714
 
6715
  /* publish - subscribe */
6716
- 'PUBSUB' => 'Predis\Command\PubSubPubsub',
6717
 
6718
  /* commands operating on HyperLogLog */
6719
- 'PFADD' => 'Predis\Command\HyperLogLogAdd',
6720
- 'PFCOUNT' => 'Predis\Command\HyperLogLogCount',
6721
- 'PFMERGE' => 'Predis\Command\HyperLogLogMerge',
6722
 
6723
  /* remote server control commands */
6724
- 'COMMAND' => 'Predis\Command\ServerCommand',
6725
  );
6726
  }
6727
  }
@@ -6750,173 +7036,173 @@ class RedisVersion240 extends RedisProfile
6750
  /* ---------------- Redis 1.2 ---------------- */
6751
 
6752
  /* commands operating on the key space */
6753
- 'EXISTS' => 'Predis\Command\KeyExists',
6754
- 'DEL' => 'Predis\Command\KeyDelete',
6755
- 'TYPE' => 'Predis\Command\KeyType',
6756
- 'KEYS' => 'Predis\Command\KeyKeys',
6757
- 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6758
- 'RENAME' => 'Predis\Command\KeyRename',
6759
- 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6760
- 'EXPIRE' => 'Predis\Command\KeyExpire',
6761
- 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6762
- 'TTL' => 'Predis\Command\KeyTimeToLive',
6763
- 'MOVE' => 'Predis\Command\KeyMove',
6764
- 'SORT' => 'Predis\Command\KeySort',
6765
 
6766
  /* commands operating on string values */
6767
- 'SET' => 'Predis\Command\StringSet',
6768
- 'SETNX' => 'Predis\Command\StringSetPreserve',
6769
- 'MSET' => 'Predis\Command\StringSetMultiple',
6770
- 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6771
- 'GET' => 'Predis\Command\StringGet',
6772
- 'MGET' => 'Predis\Command\StringGetMultiple',
6773
- 'GETSET' => 'Predis\Command\StringGetSet',
6774
- 'INCR' => 'Predis\Command\StringIncrement',
6775
- 'INCRBY' => 'Predis\Command\StringIncrementBy',
6776
- 'DECR' => 'Predis\Command\StringDecrement',
6777
- 'DECRBY' => 'Predis\Command\StringDecrementBy',
6778
 
6779
  /* commands operating on lists */
6780
- 'RPUSH' => 'Predis\Command\ListPushTail',
6781
- 'LPUSH' => 'Predis\Command\ListPushHead',
6782
- 'LLEN' => 'Predis\Command\ListLength',
6783
- 'LRANGE' => 'Predis\Command\ListRange',
6784
- 'LTRIM' => 'Predis\Command\ListTrim',
6785
- 'LINDEX' => 'Predis\Command\ListIndex',
6786
- 'LSET' => 'Predis\Command\ListSet',
6787
- 'LREM' => 'Predis\Command\ListRemove',
6788
- 'LPOP' => 'Predis\Command\ListPopFirst',
6789
- 'RPOP' => 'Predis\Command\ListPopLast',
6790
- 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6791
 
6792
  /* commands operating on sets */
6793
- 'SADD' => 'Predis\Command\SetAdd',
6794
- 'SREM' => 'Predis\Command\SetRemove',
6795
- 'SPOP' => 'Predis\Command\SetPop',
6796
- 'SMOVE' => 'Predis\Command\SetMove',
6797
- 'SCARD' => 'Predis\Command\SetCardinality',
6798
- 'SISMEMBER' => 'Predis\Command\SetIsMember',
6799
- 'SINTER' => 'Predis\Command\SetIntersection',
6800
- 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6801
- 'SUNION' => 'Predis\Command\SetUnion',
6802
- 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6803
- 'SDIFF' => 'Predis\Command\SetDifference',
6804
- 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
6805
- 'SMEMBERS' => 'Predis\Command\SetMembers',
6806
- 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
6807
 
6808
  /* commands operating on sorted sets */
6809
- 'ZADD' => 'Predis\Command\ZSetAdd',
6810
- 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
6811
- 'ZREM' => 'Predis\Command\ZSetRemove',
6812
- 'ZRANGE' => 'Predis\Command\ZSetRange',
6813
- 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
6814
- 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
6815
- 'ZCARD' => 'Predis\Command\ZSetCardinality',
6816
- 'ZSCORE' => 'Predis\Command\ZSetScore',
6817
- 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
6818
 
6819
  /* connection related commands */
6820
- 'PING' => 'Predis\Command\ConnectionPing',
6821
- 'AUTH' => 'Predis\Command\ConnectionAuth',
6822
- 'SELECT' => 'Predis\Command\ConnectionSelect',
6823
- 'ECHO' => 'Predis\Command\ConnectionEcho',
6824
- 'QUIT' => 'Predis\Command\ConnectionQuit',
6825
 
6826
  /* remote server control commands */
6827
- 'INFO' => 'Predis\Command\ServerInfo',
6828
- 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
6829
- 'MONITOR' => 'Predis\Command\ServerMonitor',
6830
- 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
6831
- 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
6832
- 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
6833
- 'SAVE' => 'Predis\Command\ServerSave',
6834
- 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
6835
- 'LASTSAVE' => 'Predis\Command\ServerLastSave',
6836
- 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
6837
- 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
6838
 
6839
  /* ---------------- Redis 2.0 ---------------- */
6840
 
6841
  /* commands operating on string values */
6842
- 'SETEX' => 'Predis\Command\StringSetExpire',
6843
- 'APPEND' => 'Predis\Command\StringAppend',
6844
- 'SUBSTR' => 'Predis\Command\StringSubstr',
6845
 
6846
  /* commands operating on lists */
6847
- 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
6848
- 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
6849
 
6850
  /* commands operating on sorted sets */
6851
- 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
6852
- 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
6853
- 'ZCOUNT' => 'Predis\Command\ZSetCount',
6854
- 'ZRANK' => 'Predis\Command\ZSetRank',
6855
- 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
6856
- 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
6857
 
6858
  /* commands operating on hashes */
6859
- 'HSET' => 'Predis\Command\HashSet',
6860
- 'HSETNX' => 'Predis\Command\HashSetPreserve',
6861
- 'HMSET' => 'Predis\Command\HashSetMultiple',
6862
- 'HINCRBY' => 'Predis\Command\HashIncrementBy',
6863
- 'HGET' => 'Predis\Command\HashGet',
6864
- 'HMGET' => 'Predis\Command\HashGetMultiple',
6865
- 'HDEL' => 'Predis\Command\HashDelete',
6866
- 'HEXISTS' => 'Predis\Command\HashExists',
6867
- 'HLEN' => 'Predis\Command\HashLength',
6868
- 'HKEYS' => 'Predis\Command\HashKeys',
6869
- 'HVALS' => 'Predis\Command\HashValues',
6870
- 'HGETALL' => 'Predis\Command\HashGetAll',
6871
 
6872
  /* transactions */
6873
- 'MULTI' => 'Predis\Command\TransactionMulti',
6874
- 'EXEC' => 'Predis\Command\TransactionExec',
6875
- 'DISCARD' => 'Predis\Command\TransactionDiscard',
6876
 
6877
  /* publish - subscribe */
6878
- 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
6879
- 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
6880
- 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
6881
- 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
6882
- 'PUBLISH' => 'Predis\Command\PubSubPublish',
6883
 
6884
  /* remote server control commands */
6885
- 'CONFIG' => 'Predis\Command\ServerConfig',
6886
 
6887
  /* ---------------- Redis 2.2 ---------------- */
6888
 
6889
  /* commands operating on the key space */
6890
- 'PERSIST' => 'Predis\Command\KeyPersist',
6891
 
6892
  /* commands operating on string values */
6893
- 'STRLEN' => 'Predis\Command\StringStrlen',
6894
- 'SETRANGE' => 'Predis\Command\StringSetRange',
6895
- 'GETRANGE' => 'Predis\Command\StringGetRange',
6896
- 'SETBIT' => 'Predis\Command\StringSetBit',
6897
- 'GETBIT' => 'Predis\Command\StringGetBit',
6898
 
6899
  /* commands operating on lists */
6900
- 'RPUSHX' => 'Predis\Command\ListPushTailX',
6901
- 'LPUSHX' => 'Predis\Command\ListPushHeadX',
6902
- 'LINSERT' => 'Predis\Command\ListInsert',
6903
- 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
6904
 
6905
  /* commands operating on sorted sets */
6906
- 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
6907
 
6908
  /* transactions */
6909
- 'WATCH' => 'Predis\Command\TransactionWatch',
6910
- 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
6911
 
6912
  /* remote server control commands */
6913
- 'OBJECT' => 'Predis\Command\ServerObject',
6914
- 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
6915
 
6916
  /* ---------------- Redis 2.4 ---------------- */
6917
 
6918
  /* remote server control commands */
6919
- 'CLIENT' => 'Predis\Command\ServerClient',
6920
  );
6921
  }
6922
  }
@@ -6945,139 +7231,139 @@ class RedisVersion200 extends RedisProfile
6945
  /* ---------------- Redis 1.2 ---------------- */
6946
 
6947
  /* commands operating on the key space */
6948
- 'EXISTS' => 'Predis\Command\KeyExists',
6949
- 'DEL' => 'Predis\Command\KeyDelete',
6950
- 'TYPE' => 'Predis\Command\KeyType',
6951
- 'KEYS' => 'Predis\Command\KeyKeys',
6952
- 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6953
- 'RENAME' => 'Predis\Command\KeyRename',
6954
- 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6955
- 'EXPIRE' => 'Predis\Command\KeyExpire',
6956
- 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6957
- 'TTL' => 'Predis\Command\KeyTimeToLive',
6958
- 'MOVE' => 'Predis\Command\KeyMove',
6959
- 'SORT' => 'Predis\Command\KeySort',
6960
 
6961
  /* commands operating on string values */
6962
- 'SET' => 'Predis\Command\StringSet',
6963
- 'SETNX' => 'Predis\Command\StringSetPreserve',
6964
- 'MSET' => 'Predis\Command\StringSetMultiple',
6965
- 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6966
- 'GET' => 'Predis\Command\StringGet',
6967
- 'MGET' => 'Predis\Command\StringGetMultiple',
6968
- 'GETSET' => 'Predis\Command\StringGetSet',
6969
- 'INCR' => 'Predis\Command\StringIncrement',
6970
- 'INCRBY' => 'Predis\Command\StringIncrementBy',
6971
- 'DECR' => 'Predis\Command\StringDecrement',
6972
- 'DECRBY' => 'Predis\Command\StringDecrementBy',
6973
 
6974
  /* commands operating on lists */
6975
- 'RPUSH' => 'Predis\Command\ListPushTail',
6976
- 'LPUSH' => 'Predis\Command\ListPushHead',
6977
- 'LLEN' => 'Predis\Command\ListLength',
6978
- 'LRANGE' => 'Predis\Command\ListRange',
6979
- 'LTRIM' => 'Predis\Command\ListTrim',
6980
- 'LINDEX' => 'Predis\Command\ListIndex',
6981
- 'LSET' => 'Predis\Command\ListSet',
6982
- 'LREM' => 'Predis\Command\ListRemove',
6983
- 'LPOP' => 'Predis\Command\ListPopFirst',
6984
- 'RPOP' => 'Predis\Command\ListPopLast',
6985
- 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6986
 
6987
  /* commands operating on sets */
6988
- 'SADD' => 'Predis\Command\SetAdd',
6989
- 'SREM' => 'Predis\Command\SetRemove',
6990
- 'SPOP' => 'Predis\Command\SetPop',
6991
- 'SMOVE' => 'Predis\Command\SetMove',
6992
- 'SCARD' => 'Predis\Command\SetCardinality',
6993
- 'SISMEMBER' => 'Predis\Command\SetIsMember',
6994
- 'SINTER' => 'Predis\Command\SetIntersection',
6995
- 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6996
- 'SUNION' => 'Predis\Command\SetUnion',
6997
- 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6998
- 'SDIFF' => 'Predis\Command\SetDifference',
6999
- 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
7000
- 'SMEMBERS' => 'Predis\Command\SetMembers',
7001
- 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
7002
 
7003
  /* commands operating on sorted sets */
7004
- 'ZADD' => 'Predis\Command\ZSetAdd',
7005
- 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
7006
- 'ZREM' => 'Predis\Command\ZSetRemove',
7007
- 'ZRANGE' => 'Predis\Command\ZSetRange',
7008
- 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
7009
- 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
7010
- 'ZCARD' => 'Predis\Command\ZSetCardinality',
7011
- 'ZSCORE' => 'Predis\Command\ZSetScore',
7012
- 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
7013
 
7014
  /* connection related commands */
7015
- 'PING' => 'Predis\Command\ConnectionPing',
7016
- 'AUTH' => 'Predis\Command\ConnectionAuth',
7017
- 'SELECT' => 'Predis\Command\ConnectionSelect',
7018
- 'ECHO' => 'Predis\Command\ConnectionEcho',
7019
- 'QUIT' => 'Predis\Command\ConnectionQuit',
7020
 
7021
  /* remote server control commands */
7022
- 'INFO' => 'Predis\Command\ServerInfo',
7023
- 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
7024
- 'MONITOR' => 'Predis\Command\ServerMonitor',
7025
- 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
7026
- 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
7027
- 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
7028
- 'SAVE' => 'Predis\Command\ServerSave',
7029
- 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
7030
- 'LASTSAVE' => 'Predis\Command\ServerLastSave',
7031
- 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
7032
- 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
7033
 
7034
  /* ---------------- Redis 2.0 ---------------- */
7035
 
7036
  /* commands operating on string values */
7037
- 'SETEX' => 'Predis\Command\StringSetExpire',
7038
- 'APPEND' => 'Predis\Command\StringAppend',
7039
- 'SUBSTR' => 'Predis\Command\StringSubstr',
7040
 
7041
  /* commands operating on lists */
7042
- 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
7043
- 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
7044
 
7045
  /* commands operating on sorted sets */
7046
- 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
7047
- 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
7048
- 'ZCOUNT' => 'Predis\Command\ZSetCount',
7049
- 'ZRANK' => 'Predis\Command\ZSetRank',
7050
- 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
7051
- 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
7052
 
7053
  /* commands operating on hashes */
7054
- 'HSET' => 'Predis\Command\HashSet',
7055
- 'HSETNX' => 'Predis\Command\HashSetPreserve',
7056
- 'HMSET' => 'Predis\Command\HashSetMultiple',
7057
- 'HINCRBY' => 'Predis\Command\HashIncrementBy',
7058
- 'HGET' => 'Predis\Command\HashGet',
7059
- 'HMGET' => 'Predis\Command\HashGetMultiple',
7060
- 'HDEL' => 'Predis\Command\HashDelete',
7061
- 'HEXISTS' => 'Predis\Command\HashExists',
7062
- 'HLEN' => 'Predis\Command\HashLength',
7063
- 'HKEYS' => 'Predis\Command\HashKeys',
7064
- 'HVALS' => 'Predis\Command\HashValues',
7065
- 'HGETALL' => 'Predis\Command\HashGetAll',
7066
 
7067
  /* transactions */
7068
- 'MULTI' => 'Predis\Command\TransactionMulti',
7069
- 'EXEC' => 'Predis\Command\TransactionExec',
7070
- 'DISCARD' => 'Predis\Command\TransactionDiscard',
7071
 
7072
  /* publish - subscribe */
7073
- 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
7074
- 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
7075
- 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
7076
- 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
7077
- 'PUBLISH' => 'Predis\Command\PubSubPublish',
7078
 
7079
  /* remote server control commands */
7080
- 'CONFIG' => 'Predis\Command\ServerConfig',
7081
  );
7082
  }
7083
  }
@@ -7094,7 +7380,7 @@ class RedisUnstable extends RedisVersion300
7094
  */
7095
  public function getVersion()
7096
  {
7097
- return '3.0';
7098
  }
7099
 
7100
  /**
@@ -7102,7 +7388,12 @@ class RedisUnstable extends RedisVersion300
7102
  */
7103
  public function getSupportedCommands()
7104
  {
7105
- return array_merge(parent::getSupportedCommands(), array());
 
 
 
 
 
7106
  }
7107
  }
7108
 
@@ -7114,14 +7405,14 @@ class RedisUnstable extends RedisVersion300
7114
  final class Factory
7115
  {
7116
  private static $profiles = array(
7117
- '2.0' => 'Predis\Profile\RedisVersion200',
7118
- '2.2' => 'Predis\Profile\RedisVersion220',
7119
- '2.4' => 'Predis\Profile\RedisVersion240',
7120
- '2.6' => 'Predis\Profile\RedisVersion260',
7121
- '2.8' => 'Predis\Profile\RedisVersion280',
7122
- '3.0' => 'Predis\Profile\RedisVersion300',
 
7123
  'default' => 'Predis\Profile\RedisVersion300',
7124
- 'dev' => 'Predis\Profile\RedisUnstable',
7125
  );
7126
 
7127
  /**
@@ -7162,10 +7453,10 @@ final class Factory
7162
  */
7163
  public static function define($alias, $class)
7164
  {
7165
- $reflection = new ReflectionClass($class);
7166
 
7167
  if (!$reflection->isSubclassOf('Predis\Profile\ProfileInterface')) {
7168
- throw new InvalidArgumentException("The class '$class' is not a valid profile class.");
7169
  }
7170
 
7171
  self::$profiles[$alias] = $class;
@@ -7176,9 +7467,9 @@ final class Factory
7176
  *
7177
  * @param string $version Profile version or alias.
7178
  *
7179
- * @return ProfileInterface
7180
- *
7181
  * @throws ClientException
 
 
7182
  */
7183
  public static function get($version)
7184
  {
@@ -7216,168 +7507,168 @@ class RedisVersion220 extends RedisProfile
7216
  /* ---------------- Redis 1.2 ---------------- */
7217
 
7218
  /* commands operating on the key space */
7219
- 'EXISTS' => 'Predis\Command\KeyExists',
7220
- 'DEL' => 'Predis\Command\KeyDelete',
7221
- 'TYPE' => 'Predis\Command\KeyType',
7222
- 'KEYS' => 'Predis\Command\KeyKeys',
7223
- 'RANDOMKEY' => 'Predis\Command\KeyRandom',
7224
- 'RENAME' => 'Predis\Command\KeyRename',
7225
- 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
7226
- 'EXPIRE' => 'Predis\Command\KeyExpire',
7227
- 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
7228
- 'TTL' => 'Predis\Command\KeyTimeToLive',
7229
- 'MOVE' => 'Predis\Command\KeyMove',
7230
- 'SORT' => 'Predis\Command\KeySort',
7231
 
7232
  /* commands operating on string values */
7233
- 'SET' => 'Predis\Command\StringSet',
7234
- 'SETNX' => 'Predis\Command\StringSetPreserve',
7235
- 'MSET' => 'Predis\Command\StringSetMultiple',
7236
- 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
7237
- 'GET' => 'Predis\Command\StringGet',
7238
- 'MGET' => 'Predis\Command\StringGetMultiple',
7239
- 'GETSET' => 'Predis\Command\StringGetSet',
7240
- 'INCR' => 'Predis\Command\StringIncrement',
7241
- 'INCRBY' => 'Predis\Command\StringIncrementBy',
7242
- 'DECR' => 'Predis\Command\StringDecrement',
7243
- 'DECRBY' => 'Predis\Command\StringDecrementBy',
7244
 
7245
  /* commands operating on lists */
7246
- 'RPUSH' => 'Predis\Command\ListPushTail',
7247
- 'LPUSH' => 'Predis\Command\ListPushHead',
7248
- 'LLEN' => 'Predis\Command\ListLength',
7249
- 'LRANGE' => 'Predis\Command\ListRange',
7250
- 'LTRIM' => 'Predis\Command\ListTrim',
7251
- 'LINDEX' => 'Predis\Command\ListIndex',
7252
- 'LSET' => 'Predis\Command\ListSet',
7253
- 'LREM' => 'Predis\Command\ListRemove',
7254
- 'LPOP' => 'Predis\Command\ListPopFirst',
7255
- 'RPOP' => 'Predis\Command\ListPopLast',
7256
- 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
7257
 
7258
  /* commands operating on sets */
7259
- 'SADD' => 'Predis\Command\SetAdd',
7260
- 'SREM' => 'Predis\Command\SetRemove',
7261
- 'SPOP' => 'Predis\Command\SetPop',
7262
- 'SMOVE' => 'Predis\Command\SetMove',
7263
- 'SCARD' => 'Predis\Command\SetCardinality',
7264
- 'SISMEMBER' => 'Predis\Command\SetIsMember',
7265
- 'SINTER' => 'Predis\Command\SetIntersection',
7266
- 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
7267
- 'SUNION' => 'Predis\Command\SetUnion',
7268
- 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
7269
- 'SDIFF' => 'Predis\Command\SetDifference',
7270
- 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
7271
- 'SMEMBERS' => 'Predis\Command\SetMembers',
7272
- 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
7273
 
7274
  /* commands operating on sorted sets */
7275
- 'ZADD' => 'Predis\Command\ZSetAdd',
7276
- 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
7277
- 'ZREM' => 'Predis\Command\ZSetRemove',
7278
- 'ZRANGE' => 'Predis\Command\ZSetRange',
7279
- 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
7280
- 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
7281
- 'ZCARD' => 'Predis\Command\ZSetCardinality',
7282
- 'ZSCORE' => 'Predis\Command\ZSetScore',
7283
- 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
7284
 
7285
  /* connection related commands */
7286
- 'PING' => 'Predis\Command\ConnectionPing',
7287
- 'AUTH' => 'Predis\Command\ConnectionAuth',
7288
- 'SELECT' => 'Predis\Command\ConnectionSelect',
7289
- 'ECHO' => 'Predis\Command\ConnectionEcho',
7290
- 'QUIT' => 'Predis\Command\ConnectionQuit',
7291
 
7292
  /* remote server control commands */
7293
- 'INFO' => 'Predis\Command\ServerInfo',
7294
- 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
7295
- 'MONITOR' => 'Predis\Command\ServerMonitor',
7296
- 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
7297
- 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
7298
- 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
7299
- 'SAVE' => 'Predis\Command\ServerSave',
7300
- 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
7301
- 'LASTSAVE' => 'Predis\Command\ServerLastSave',
7302
- 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
7303
- 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
7304
 
7305
  /* ---------------- Redis 2.0 ---------------- */
7306
 
7307
  /* commands operating on string values */
7308
- 'SETEX' => 'Predis\Command\StringSetExpire',
7309
- 'APPEND' => 'Predis\Command\StringAppend',
7310
- 'SUBSTR' => 'Predis\Command\StringSubstr',
7311
 
7312
  /* commands operating on lists */
7313
- 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
7314
- 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
7315
 
7316
  /* commands operating on sorted sets */
7317
- 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
7318
- 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
7319
- 'ZCOUNT' => 'Predis\Command\ZSetCount',
7320
- 'ZRANK' => 'Predis\Command\ZSetRank',
7321
- 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
7322
- 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
7323
 
7324
  /* commands operating on hashes */
7325
- 'HSET' => 'Predis\Command\HashSet',
7326
- 'HSETNX' => 'Predis\Command\HashSetPreserve',
7327
- 'HMSET' => 'Predis\Command\HashSetMultiple',
7328
- 'HINCRBY' => 'Predis\Command\HashIncrementBy',
7329
- 'HGET' => 'Predis\Command\HashGet',
7330
- 'HMGET' => 'Predis\Command\HashGetMultiple',
7331
- 'HDEL' => 'Predis\Command\HashDelete',
7332
- 'HEXISTS' => 'Predis\Command\HashExists',
7333
- 'HLEN' => 'Predis\Command\HashLength',
7334
- 'HKEYS' => 'Predis\Command\HashKeys',
7335
- 'HVALS' => 'Predis\Command\HashValues',
7336
- 'HGETALL' => 'Predis\Command\HashGetAll',
7337
 
7338
  /* transactions */
7339
- 'MULTI' => 'Predis\Command\TransactionMulti',
7340
- 'EXEC' => 'Predis\Command\TransactionExec',
7341
- 'DISCARD' => 'Predis\Command\TransactionDiscard',
7342
 
7343
  /* publish - subscribe */
7344
- 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
7345
- 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
7346
- 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
7347
- 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
7348
- 'PUBLISH' => 'Predis\Command\PubSubPublish',
7349
 
7350
  /* remote server control commands */
7351
- 'CONFIG' => 'Predis\Command\ServerConfig',
7352
 
7353
  /* ---------------- Redis 2.2 ---------------- */
7354
 
7355
  /* commands operating on the key space */
7356
- 'PERSIST' => 'Predis\Command\KeyPersist',
7357
 
7358
  /* commands operating on string values */
7359
- 'STRLEN' => 'Predis\Command\StringStrlen',
7360
- 'SETRANGE' => 'Predis\Command\StringSetRange',
7361
- 'GETRANGE' => 'Predis\Command\StringGetRange',
7362
- 'SETBIT' => 'Predis\Command\StringSetBit',
7363
- 'GETBIT' => 'Predis\Command\StringGetBit',
7364
 
7365
  /* commands operating on lists */
7366
- 'RPUSHX' => 'Predis\Command\ListPushTailX',
7367
- 'LPUSHX' => 'Predis\Command\ListPushHeadX',
7368
- 'LINSERT' => 'Predis\Command\ListInsert',
7369
- 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
7370
 
7371
  /* commands operating on sorted sets */
7372
- 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
7373
 
7374
  /* transactions */
7375
- 'WATCH' => 'Predis\Command\TransactionWatch',
7376
- 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
7377
 
7378
  /* remote server control commands */
7379
- 'OBJECT' => 'Predis\Command\ServerObject',
7380
- 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
7381
  );
7382
  }
7383
  }
@@ -7386,15 +7677,13 @@ class RedisVersion220 extends RedisProfile
7386
 
7387
  namespace Predis;
7388
 
7389
- use InvalidArgumentException;
7390
- use UnexpectedValueException;
7391
  use Predis\Command\CommandInterface;
7392
  use Predis\Command\RawCommand;
7393
  use Predis\Command\ScriptCommand;
7394
  use Predis\Configuration\Options;
7395
  use Predis\Configuration\OptionsInterface;
7396
- use Predis\Connection\ConnectionInterface;
7397
  use Predis\Connection\AggregateConnectionInterface;
 
7398
  use Predis\Connection\ParametersInterface;
7399
  use Predis\Monitor\Consumer as MonitorConsumer;
7400
  use Predis\Pipeline\Pipeline;
@@ -7404,7 +7693,6 @@ use Predis\Response\ResponseInterface;
7404
  use Predis\Response\ServerException;
7405
  use Predis\Transaction\MultiExec as MultiExecTransaction;
7406
  use Predis\Profile\ProfileInterface;
7407
- use Exception;
7408
  use Predis\Connection\NodeConnectionInterface;
7409
 
7410
  /**
@@ -7412,7 +7700,7 @@ use Predis\Connection\NodeConnectionInterface;
7412
  *
7413
  * @author Daniele Alessandri <suppakilla@gmail.com>
7414
  */
7415
- abstract class PredisException extends Exception
7416
  {
7417
  }
7418
 
@@ -7562,7 +7850,6 @@ abstract class PredisException extends Exception
7562
  */
7563
  interface ClientContextInterface
7564
  {
7565
-
7566
  /**
7567
  * Sends the specified command instance to Redis.
7568
  *
@@ -7605,13 +7892,13 @@ abstract class CommunicationException extends PredisException
7605
  * @param NodeConnectionInterface $connection Connection that generated the exception.
7606
  * @param string $message Error message.
7607
  * @param int $code Error code.
7608
- * @param Exception $innerException Inner exception for wrapping the original error.
7609
  */
7610
  public function __construct(
7611
  NodeConnectionInterface $connection,
7612
  $message = null,
7613
  $code = null,
7614
- Exception $innerException = null
7615
  ) {
7616
  parent::__construct($message, $code, $innerException);
7617
  $this->connection = $connection;
@@ -7903,7 +8190,7 @@ class ClientException extends PredisException
7903
  */
7904
  class Client implements ClientInterface
7905
  {
7906
- const VERSION = '1.0.1';
7907
 
7908
  protected $connection;
7909
  protected $options;
@@ -7927,9 +8214,9 @@ class Client implements ClientInterface
7927
  *
7928
  * @param mixed $options Client options.
7929
  *
7930
- * @return OptionsInterface
7931
- *
7932
  * @throws \InvalidArgumentException
 
 
7933
  */
7934
  protected function createOptions($options)
7935
  {
@@ -7941,7 +8228,7 @@ class Client implements ClientInterface
7941
  return $options;
7942
  }
7943
 
7944
- throw new InvalidArgumentException("Invalid type for client options.");
7945
  }
7946
 
7947
  /**
@@ -7959,9 +8246,9 @@ class Client implements ClientInterface
7959
  *
7960
  * @param mixed $parameters Connection parameters or connection instance.
7961
  *
7962
- * @return ConnectionInterface
7963
- *
7964
  * @throws \InvalidArgumentException
 
 
7965
  */
7966
  protected function createConnection($parameters)
7967
  {
@@ -8003,7 +8290,7 @@ class Client implements ClientInterface
8003
  return $connection;
8004
  }
8005
 
8006
- throw new InvalidArgumentException('Invalid type for connection parameters.');
8007
  }
8008
 
8009
  /**
@@ -8020,7 +8307,7 @@ class Client implements ClientInterface
8020
  $connection = call_user_func_array($callable, func_get_args());
8021
 
8022
  if (!$connection instanceof ConnectionInterface) {
8023
- throw new UnexpectedValueException(
8024
  'The callable connection initializer returned an invalid type.'
8025
  );
8026
  }
@@ -8052,14 +8339,14 @@ class Client implements ClientInterface
8052
  *
8053
  * @param string $connectionID Identifier of a connection.
8054
  *
8055
- * @return Client
8056
- *
8057
  * @throws \InvalidArgumentException
 
 
8058
  */
8059
  public function getClientFor($connectionID)
8060
  {
8061
  if (!$connection = $this->getConnectionById($connectionID)) {
8062
- throw new InvalidArgumentException("Invalid connection ID: $connectionID.");
8063
  }
8064
 
8065
  return new static($connection, $this->options);
@@ -8116,9 +8403,9 @@ class Client implements ClientInterface
8116
  *
8117
  * @param string $connectionID Index or alias of the single connection.
8118
  *
8119
- * @return Connection\NodeConnectionInterface
8120
- *
8121
  * @throws NotSupportedException
 
 
8122
  */
8123
  public function getConnectionById($connectionID)
8124
  {
@@ -8205,9 +8492,9 @@ class Client implements ClientInterface
8205
  * @param CommandInterface $command Redis command that generated the error.
8206
  * @param ErrorResponseInterface $response Instance of the error response.
8207
  *
8208
- * @return mixed
8209
- *
8210
  * @throws ServerException
 
 
8211
  */
8212
  protected function onErrorResponse(CommandInterface $command, ErrorResponseInterface $response)
8213
  {
@@ -8403,7 +8690,7 @@ class Autoloader
8403
  public function __construct($baseDirectory = __DIR__)
8404
  {
8405
  $this->directory = $baseDirectory;
8406
- $this->prefix = __NAMESPACE__ . '\\';
8407
  $this->prefixLength = strlen($this->prefix);
8408
  }
8409
 
@@ -8414,7 +8701,7 @@ class Autoloader
8414
  */
8415
  public static function register($prepend = false)
8416
  {
8417
- spl_autoload_register(array(new self, 'autoload'), true, $prepend);
8418
  }
8419
 
8420
  /**
@@ -8429,7 +8716,7 @@ class Autoloader
8429
  $filepath = $this->directory.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts).'.php';
8430
 
8431
  if (is_file($filepath)) {
8432
- require($filepath);
8433
  }
8434
  }
8435
  }
@@ -8439,7 +8726,6 @@ class Autoloader
8439
 
8440
  namespace Predis\Configuration;
8441
 
8442
- use InvalidArgumentException;
8443
  use Predis\Connection\Aggregate\ClusterInterface;
8444
  use Predis\Connection\Aggregate\PredisCluster;
8445
  use Predis\Connection\Aggregate\RedisCluster;
@@ -8597,7 +8883,7 @@ class ProfileOption implements OptionInterface
8597
  $value = Predis_Factory::get($value);
8598
  $this->setProcessors($options, $value);
8599
  } elseif (!$value instanceof ProfileInterface) {
8600
- throw new InvalidArgumentException('Invalid value for the profile option.');
8601
  }
8602
 
8603
  return $value;
@@ -8647,7 +8933,7 @@ class ReplicationOption implements OptionInterface
8647
  return $asbool ? $this->getDefault($options) : null;
8648
  }
8649
 
8650
- throw new InvalidArgumentException(
8651
  "An instance of type 'Predis\Connection\Aggregate\ReplicationInterface' was expected."
8652
  );
8653
  }
@@ -8693,11 +8979,11 @@ class Options implements OptionsInterface
8693
  protected function getHandlers()
8694
  {
8695
  return array(
8696
- 'cluster' => 'Predis\Configuration\ClusterOption',
8697
  'connections' => 'Predis\Configuration\ConnectionFactoryOption',
8698
- 'exceptions' => 'Predis\Configuration\ExceptionsOption',
8699
- 'prefix' => 'Predis\Configuration\PrefixOption',
8700
- 'profile' => 'Predis\Configuration\ProfileOption',
8701
  'replication' => 'Predis\Configuration\ReplicationOption',
8702
  );
8703
  }
@@ -8750,7 +9036,7 @@ class Options implements OptionsInterface
8750
  $value = $this->input[$option];
8751
  unset($this->input[$option]);
8752
 
8753
- if (method_exists($value, '__invoke')) {
8754
  $value = $value($this, $option);
8755
  }
8756
 
@@ -8767,7 +9053,7 @@ class Options implements OptionsInterface
8767
  return $this->options[$option] = $this->getDefault($option);
8768
  }
8769
 
8770
- return null;
8771
  }
8772
  }
8773
 
@@ -8795,7 +9081,7 @@ class ConnectionFactoryOption implements OptionInterface
8795
 
8796
  return $factory;
8797
  } else {
8798
- throw new InvalidArgumentException(
8799
  'Invalid value provided for the connections option.'
8800
  );
8801
  }
@@ -8878,7 +9164,7 @@ class ClusterOption implements OptionInterface
8878
  }
8879
 
8880
  if (!$value instanceof ClusterInterface) {
8881
- throw new InvalidArgumentException(
8882
  "An instance of type 'Predis\Connection\Aggregate\ClusterInterface' was expected."
8883
  );
8884
  }
@@ -8919,14 +9205,14 @@ interface ResponseInterface
8919
  interface ErrorInterface extends ResponseInterface
8920
  {
8921
  /**
8922
- * Returns the error message
8923
  *
8924
  * @return string
8925
  */
8926
  public function getMessage();
8927
 
8928
  /**
8929
- * Returns the error type (e.g. ERR, ASK, MOVED)
8930
  *
8931
  * @return string
8932
  */
@@ -9031,7 +9317,7 @@ class Error implements ErrorInterface
9031
  */
9032
  public function getErrorType()
9033
  {
9034
- list($errorType, ) = explode(' ', $this->getMessage(), 2);
9035
 
9036
  return $errorType;
9037
  }
@@ -9061,7 +9347,7 @@ class ServerException extends PredisException implements ErrorInterface
9061
  */
9062
  public function getErrorType()
9063
  {
9064
- list($errorType, ) = explode(' ', $this->getMessage(), 2);
9065
 
9066
  return $errorType;
9067
  }
@@ -9113,6 +9399,7 @@ interface ResponseHandlerInterface
9113
  * the payload as a string.
9114
  *
9115
  * @link http://redis.io/topics/protocol
 
9116
  * @author Daniele Alessandri <suppakilla@gmail.com>
9117
  */
9118
  class StatusResponse implements ResponseHandlerInterface
@@ -9134,6 +9421,7 @@ class StatusResponse implements ResponseHandlerInterface
9134
  * built-in into Predis, such as transactions or pipelines. Use them with care!
9135
  *
9136
  * @link http://redis.io/topics/protocol
 
9137
  * @author Daniele Alessandri <suppakilla@gmail.com>
9138
  */
9139
  class StreamableMultiBulkResponse implements ResponseHandlerInterface
@@ -9160,6 +9448,7 @@ class StreamableMultiBulkResponse implements ResponseHandlerInterface
9160
  * It returns multibulk responses as PHP arrays.
9161
  *
9162
  * @link http://redis.io/topics/protocol
 
9163
  * @author Daniele Alessandri <suppakilla@gmail.com>
9164
  */
9165
  class MultiBulkResponse implements ResponseHandlerInterface
@@ -9178,7 +9467,7 @@ class MultiBulkResponse implements ResponseHandlerInterface
9178
  }
9179
 
9180
  if ($length === -1) {
9181
- return null;
9182
  }
9183
 
9184
  $list = array();
@@ -9187,7 +9476,7 @@ class MultiBulkResponse implements ResponseHandlerInterface
9187
  $handlersCache = array();
9188
  $reader = $connection->getProtocol()->getResponseReader();
9189
 
9190
- for ($i = 0; $i < $length; $i++) {
9191
  $header = $connection->readLine();
9192
  $prefix = $header[0];
9193
 
@@ -9211,6 +9500,7 @@ class MultiBulkResponse implements ResponseHandlerInterface
9211
  * It translates the payload to a complex response object for Predis.
9212
  *
9213
  * @link http://redis.io/topics/protocol
 
9214
  * @author Daniele Alessandri <suppakilla@gmail.com>
9215
  */
9216
  class ErrorResponse implements ResponseHandlerInterface
@@ -9229,6 +9519,7 @@ class ErrorResponse implements ResponseHandlerInterface
9229
  * It translates the payload an integer or NULL.
9230
  *
9231
  * @link http://redis.io/topics/protocol
 
9232
  * @author Daniele Alessandri <suppakilla@gmail.com>
9233
  */
9234
  class IntegerResponse implements ResponseHandlerInterface
@@ -9248,7 +9539,7 @@ class IntegerResponse implements ResponseHandlerInterface
9248
  ));
9249
  }
9250
 
9251
- return null;
9252
  }
9253
  }
9254
 
@@ -9257,6 +9548,7 @@ class IntegerResponse implements ResponseHandlerInterface
9257
  * It translates the payload to a string or a NULL.
9258
  *
9259
  * @link http://redis.io/topics/protocol
 
9260
  * @author Daniele Alessandri <suppakilla@gmail.com>
9261
  */
9262
  class BulkResponse implements ResponseHandlerInterface
@@ -9279,7 +9571,7 @@ class BulkResponse implements ResponseHandlerInterface
9279
  }
9280
 
9281
  if ($length == -1) {
9282
- return null;
9283
  }
9284
 
9285
  CommunicationException::handle(new ProtocolException(
@@ -9294,10 +9586,8 @@ class BulkResponse implements ResponseHandlerInterface
9294
 
9295
  namespace Predis\Collection\Iterator;
9296
 
9297
- use Iterator;
9298
  use Predis\ClientInterface;
9299
  use Predis\NotSupportedException;
9300
- use InvalidArgumentException;
9301
 
9302
  /**
9303
  * Provides the base implementation for a fully-rewindable PHP iterator that can
@@ -9312,7 +9602,7 @@ use InvalidArgumentException;
9312
  *
9313
  * @author Daniele Alessandri <suppakilla@gmail.com>
9314
  */
9315
- abstract class CursorBasedIterator implements Iterator
9316
  {
9317
  protected $client;
9318
  protected $match;
@@ -9417,7 +9707,7 @@ abstract class CursorBasedIterator implements Iterator
9417
  */
9418
  protected function extractNext()
9419
  {
9420
- $this->position++;
9421
  $this->current = array_shift($this->elements);
9422
  }
9423
 
@@ -9480,6 +9770,7 @@ abstract class CursorBasedIterator implements Iterator
9480
  * ZSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9481
  *
9482
  * @author Daniele Alessandri <suppakilla@gmail.com>
 
9483
  * @link http://redis.io/commands/scan
9484
  */
9485
  class SortedSetKey extends CursorBasedIterator
@@ -9525,6 +9816,7 @@ class SortedSetKey extends CursorBasedIterator
9525
  * command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9526
  *
9527
  * @author Daniele Alessandri <suppakilla@gmail.com>
 
9528
  * @link http://redis.io/commands/scan
9529
  */
9530
  class SetKey extends CursorBasedIterator
@@ -9557,6 +9849,7 @@ class SetKey extends CursorBasedIterator
9557
  * SCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9558
  *
9559
  * @author Daniele Alessandri <suppakilla@gmail.com>
 
9560
  * @link http://redis.io/commands/scan
9561
  */
9562
  class Keyspace extends CursorBasedIterator
@@ -9585,6 +9878,7 @@ class Keyspace extends CursorBasedIterator
9585
  * HSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9586
  *
9587
  * @author Daniele Alessandri <suppakilla@gmail.com>
 
9588
  * @link http://redis.io/commands/scan
9589
  */
9590
  class HashKey extends CursorBasedIterator
@@ -9632,9 +9926,10 @@ class HashKey extends CursorBasedIterator
9632
  * times (trimmed, deleted, overwritten) during the iteration process.
9633
  *
9634
  * @author Daniele Alessandri <suppakilla@gmail.com>
 
9635
  * @link http://redis.io/commands/lrange
9636
  */
9637
- class ListKey implements Iterator
9638
  {
9639
  protected $client;
9640
  protected $count;
@@ -9658,7 +9953,7 @@ class ListKey implements Iterator
9658
  $this->requiredCommand($client, 'LRANGE');
9659
 
9660
  if ((false === $count = filter_var($count, FILTER_VALIDATE_INT)) || $count < 0) {
9661
- throw new InvalidArgumentException('The $count argument must be a positive integer.');
9662
  }
9663
 
9664
  $this->client = $client;
@@ -9727,7 +10022,7 @@ class ListKey implements Iterator
9727
  */
9728
  protected function extractNext()
9729
  {
9730
- $this->position++;
9731
  $this->current = array_shift($this->elements);
9732
  }
9733
 
@@ -9785,14 +10080,13 @@ class ListKey implements Iterator
9785
 
9786
  namespace Predis\Cluster;
9787
 
9788
- use InvalidArgumentException;
9789
  use Predis\Command\CommandInterface;
9790
  use Predis\Command\ScriptCommand;
9791
  use Predis\Cluster\Distributor\DistributorInterface;
9792
  use Predis\Cluster\Distributor\HashRing;
9793
- use Predis\NotSupportedException;
9794
- use Predis\Cluster\Hash\HashGeneratorInterface;
9795
  use Predis\Cluster\Hash\CRC16;
 
 
9796
 
9797
  /**
9798
  * Interface for classes defining the strategy used to calculate an hash out of
@@ -9861,125 +10155,127 @@ abstract class ClusterStrategy implements StrategyInterface
9861
 
9862
  return array(
9863
  /* commands operating on the key space */
9864
- 'EXISTS' => $getKeyFromFirstArgument,
9865
- 'DEL' => $getKeyFromAllArguments,
9866
- 'TYPE' => $getKeyFromFirstArgument,
9867
- 'EXPIRE' => $getKeyFromFirstArgument,
9868
- 'EXPIREAT' => $getKeyFromFirstArgument,
9869
- 'PERSIST' => $getKeyFromFirstArgument,
9870
- 'PEXPIRE' => $getKeyFromFirstArgument,
9871
- 'PEXPIREAT' => $getKeyFromFirstArgument,
9872
- 'TTL' => $getKeyFromFirstArgument,
9873
- 'PTTL' => $getKeyFromFirstArgument,
9874
- 'SORT' => $getKeyFromFirstArgument, // TODO
9875
- 'DUMP' => $getKeyFromFirstArgument,
9876
- 'RESTORE' => $getKeyFromFirstArgument,
9877
 
9878
  /* commands operating on string values */
9879
- 'APPEND' => $getKeyFromFirstArgument,
9880
- 'DECR' => $getKeyFromFirstArgument,
9881
- 'DECRBY' => $getKeyFromFirstArgument,
9882
- 'GET' => $getKeyFromFirstArgument,
9883
- 'GETBIT' => $getKeyFromFirstArgument,
9884
- 'MGET' => $getKeyFromAllArguments,
9885
- 'SET' => $getKeyFromFirstArgument,
9886
- 'GETRANGE' => $getKeyFromFirstArgument,
9887
- 'GETSET' => $getKeyFromFirstArgument,
9888
- 'INCR' => $getKeyFromFirstArgument,
9889
- 'INCRBY' => $getKeyFromFirstArgument,
9890
- 'INCRBYFLOAT' => $getKeyFromFirstArgument,
9891
- 'SETBIT' => $getKeyFromFirstArgument,
9892
- 'SETEX' => $getKeyFromFirstArgument,
9893
- 'MSET' => array($this, 'getKeyFromInterleavedArguments'),
9894
- 'MSETNX' => array($this, 'getKeyFromInterleavedArguments'),
9895
- 'SETNX' => $getKeyFromFirstArgument,
9896
- 'SETRANGE' => $getKeyFromFirstArgument,
9897
- 'STRLEN' => $getKeyFromFirstArgument,
9898
- 'SUBSTR' => $getKeyFromFirstArgument,
9899
- 'BITOP' => array($this, 'getKeyFromBitOp'),
9900
- 'BITCOUNT' => $getKeyFromFirstArgument,
9901
 
9902
  /* commands operating on lists */
9903
- 'LINSERT' => $getKeyFromFirstArgument,
9904
- 'LINDEX' => $getKeyFromFirstArgument,
9905
- 'LLEN' => $getKeyFromFirstArgument,
9906
- 'LPOP' => $getKeyFromFirstArgument,
9907
- 'RPOP' => $getKeyFromFirstArgument,
9908
- 'RPOPLPUSH' => $getKeyFromAllArguments,
9909
- 'BLPOP' => array($this, 'getKeyFromBlockingListCommands'),
9910
- 'BRPOP' => array($this, 'getKeyFromBlockingListCommands'),
9911
- 'BRPOPLPUSH' => array($this, 'getKeyFromBlockingListCommands'),
9912
- 'LPUSH' => $getKeyFromFirstArgument,
9913
- 'LPUSHX' => $getKeyFromFirstArgument,
9914
- 'RPUSH' => $getKeyFromFirstArgument,
9915
- 'RPUSHX' => $getKeyFromFirstArgument,
9916
- 'LRANGE' => $getKeyFromFirstArgument,
9917
- 'LREM' => $getKeyFromFirstArgument,
9918
- 'LSET' => $getKeyFromFirstArgument,
9919
- 'LTRIM' => $getKeyFromFirstArgument,
9920
 
9921
  /* commands operating on sets */
9922
- 'SADD' => $getKeyFromFirstArgument,
9923
- 'SCARD' => $getKeyFromFirstArgument,
9924
- 'SDIFF' => $getKeyFromAllArguments,
9925
- 'SDIFFSTORE' => $getKeyFromAllArguments,
9926
- 'SINTER' => $getKeyFromAllArguments,
9927
- 'SINTERSTORE' => $getKeyFromAllArguments,
9928
- 'SUNION' => $getKeyFromAllArguments,
9929
- 'SUNIONSTORE' => $getKeyFromAllArguments,
9930
- 'SISMEMBER' => $getKeyFromFirstArgument,
9931
- 'SMEMBERS' => $getKeyFromFirstArgument,
9932
- 'SSCAN' => $getKeyFromFirstArgument,
9933
- 'SPOP' => $getKeyFromFirstArgument,
9934
- 'SRANDMEMBER' => $getKeyFromFirstArgument,
9935
- 'SREM' => $getKeyFromFirstArgument,
9936
 
9937
  /* commands operating on sorted sets */
9938
- 'ZADD' => $getKeyFromFirstArgument,
9939
- 'ZCARD' => $getKeyFromFirstArgument,
9940
- 'ZCOUNT' => $getKeyFromFirstArgument,
9941
- 'ZINCRBY' => $getKeyFromFirstArgument,
9942
- 'ZINTERSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
9943
- 'ZRANGE' => $getKeyFromFirstArgument,
9944
- 'ZRANGEBYSCORE' => $getKeyFromFirstArgument,
9945
- 'ZRANK' => $getKeyFromFirstArgument,
9946
- 'ZREM' => $getKeyFromFirstArgument,
9947
- 'ZREMRANGEBYRANK' => $getKeyFromFirstArgument,
9948
- 'ZREMRANGEBYSCORE' => $getKeyFromFirstArgument,
9949
- 'ZREVRANGE' => $getKeyFromFirstArgument,
9950
- 'ZREVRANGEBYSCORE' => $getKeyFromFirstArgument,
9951
- 'ZREVRANK' => $getKeyFromFirstArgument,
9952
- 'ZSCORE' => $getKeyFromFirstArgument,
9953
- 'ZUNIONSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
9954
- 'ZSCAN' => $getKeyFromFirstArgument,
9955
- 'ZLEXCOUNT' => $getKeyFromFirstArgument,
9956
- 'ZRANGEBYLEX' => $getKeyFromFirstArgument,
9957
- 'ZREMRANGEBYLEX' => $getKeyFromFirstArgument,
 
9958
 
9959
  /* commands operating on hashes */
9960
- 'HDEL' => $getKeyFromFirstArgument,
9961
- 'HEXISTS' => $getKeyFromFirstArgument,
9962
- 'HGET' => $getKeyFromFirstArgument,
9963
- 'HGETALL' => $getKeyFromFirstArgument,
9964
- 'HMGET' => $getKeyFromFirstArgument,
9965
- 'HMSET' => $getKeyFromFirstArgument,
9966
- 'HINCRBY' => $getKeyFromFirstArgument,
9967
- 'HINCRBYFLOAT' => $getKeyFromFirstArgument,
9968
- 'HKEYS' => $getKeyFromFirstArgument,
9969
- 'HLEN' => $getKeyFromFirstArgument,
9970
- 'HSET' => $getKeyFromFirstArgument,
9971
- 'HSETNX' => $getKeyFromFirstArgument,
9972
- 'HVALS' => $getKeyFromFirstArgument,
9973
- 'HSCAN' => $getKeyFromFirstArgument,
 
9974
 
9975
  /* commands operating on HyperLogLog */
9976
- 'PFADD' => $getKeyFromFirstArgument,
9977
- 'PFCOUNT' => $getKeyFromAllArguments,
9978
- 'PFMERGE' => $getKeyFromAllArguments,
9979
 
9980
  /* scripting */
9981
- 'EVAL' => array($this, 'getKeyFromScriptingCommands'),
9982
- 'EVALSHA' => array($this, 'getKeyFromScriptingCommands'),
9983
  );
9984
  }
9985
 
@@ -10018,8 +10314,8 @@ abstract class ClusterStrategy implements StrategyInterface
10018
  }
10019
 
10020
  if (!is_callable($callback)) {
10021
- throw new InvalidArgumentException(
10022
- "The argument must be a callable object or NULL."
10023
  );
10024
  }
10025
 
@@ -10180,7 +10476,7 @@ abstract class ClusterStrategy implements StrategyInterface
10180
 
10181
  $currentSlot = $this->getSlotByKey($keys[0]);
10182
 
10183
- for ($i = 1; $i < $count; $i++) {
10184
  $nextSlot = $this->getSlotByKey($keys[$i]);
10185
 
10186
  if ($currentSlot !== $nextSlot) {
@@ -10255,7 +10551,7 @@ class PredisStrategy extends ClusterStrategy
10255
 
10256
  $currentKey = $this->extractKeyTag($keys[0]);
10257
 
10258
- for ($i = 1; $i < $count; $i++) {
10259
  $nextKey = $this->extractKeyTag($keys[$i]);
10260
 
10261
  if ($currentKey !== $nextKey) {
@@ -10302,7 +10598,7 @@ class RedisStrategy extends ClusterStrategy
10302
  */
10303
  public function getSlotByKey($key)
10304
  {
10305
- $key = $this->extractKeyTag($key);
10306
  $slot = $this->hashGenerator->hash($key) & 0x3FFF;
10307
 
10308
  return $slot;
@@ -10403,18 +10699,12 @@ class ProtocolException extends CommunicationException
10403
  namespace Predis\Connection\Aggregate;
10404
 
10405
  use Predis\Connection\AggregateConnectionInterface;
10406
- use InvalidArgumentException;
10407
- use RuntimeException;
10408
  use Predis\Command\CommandInterface;
10409
  use Predis\Connection\NodeConnectionInterface;
10410
  use Predis\Replication\ReplicationStrategy;
10411
- use ArrayIterator;
10412
- use Countable;
10413
- use IteratorAggregate;
10414
- use Predis\NotSupportedException;
10415
  use Predis\Cluster\PredisStrategy;
10416
  use Predis\Cluster\StrategyInterface;
10417
- use OutOfBoundsException;
10418
  use Predis\Cluster\RedisStrategy as RedisClusterStrategy;
10419
  use Predis\Command\RawCommand;
10420
  use Predis\Connection\FactoryInterface;
@@ -10489,7 +10779,7 @@ interface ReplicationInterface extends AggregateConnectionInterface
10489
  *
10490
  * @author Daniele Alessandri <suppakilla@gmail.com>
10491
  */
10492
- class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10493
  {
10494
  private $useClusterSlots = true;
10495
  private $defaultParameters = array();
@@ -10679,7 +10969,7 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10679
  $last < 0x0000 || $last > 0x3FFF ||
10680
  $last < $first
10681
  ) {
10682
- throw new OutOfBoundsException(
10683
  "Invalid slot range for $connection: [$first-$last]."
10684
  );
10685
  }
@@ -10723,11 +11013,11 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10723
  */
10724
  protected function createConnection($connectionID)
10725
  {
10726
- $host = explode(':', $connectionID, 2);
10727
 
10728
  $parameters = array_merge($this->defaultParameters, array(
10729
- 'host' => $host[0],
10730
- 'port' => $host[1],
10731
  ));
10732
 
10733
  $connection = $this->connections->create($parameters);
@@ -10760,14 +11050,14 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10760
  *
10761
  * @param int $slot Slot index.
10762
  *
10763
- * @return NodeConnectionInterface
10764
- *
10765
  * @throws \OutOfBoundsException
 
 
10766
  */
10767
  public function getConnectionBySlot($slot)
10768
  {
10769
  if ($slot < 0x0000 || $slot > 0x3FFF) {
10770
- throw new OutOfBoundsException("Invalid slot [$slot].");
10771
  }
10772
 
10773
  if (isset($this->slots[$slot])) {
@@ -10874,8 +11164,9 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10874
  * Handles -ASK responses by executing again the command against the node
10875
  * indicated by the Redis response.
10876
  *
10877
- * @param CommandInterface $command Command that generated the -ASK response.
10878
- * @param string $details Parameters of the -ASK response.
 
10879
  * @return mixed
10880
  */
10881
  protected function onAskResponse(CommandInterface $command, $details)
@@ -10936,7 +11227,7 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10936
  */
10937
  public function getIterator()
10938
  {
10939
- return new ArrayIterator(array_values($this->pool));
10940
  }
10941
 
10942
  /**
@@ -11003,9 +11294,10 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
11003
  * implementing client-side sharding based on pluggable distribution strategies.
11004
  *
11005
  * @author Daniele Alessandri <suppakilla@gmail.com>
 
11006
  * @todo Add the ability to remove connections from pool.
11007
  */
11008
- class PredisCluster implements ClusterInterface, IteratorAggregate, Countable
11009
  {
11010
  private $pool;
11011
  private $strategy;
@@ -11168,7 +11460,7 @@ class PredisCluster implements ClusterInterface, IteratorAggregate, Countable
11168
  */
11169
  public function getIterator()
11170
  {
11171
- return new ArrayIterator($this->pool);
11172
  }
11173
 
11174
  /**
@@ -11242,7 +11534,7 @@ class MasterSlaveReplication implements ReplicationInterface
11242
  protected function check()
11243
  {
11244
  if (!isset($this->master) || !$this->slaves) {
11245
- throw new RuntimeException('Replication needs one master and at least one slave.');
11246
  }
11247
  }
11248
 
@@ -11330,7 +11622,7 @@ class MasterSlaveReplication implements ReplicationInterface
11330
  return $this->slaves[$connectionId];
11331
  }
11332
 
11333
- return null;
11334
  }
11335
 
11336
  /**
@@ -11344,7 +11636,7 @@ class MasterSlaveReplication implements ReplicationInterface
11344
  $connection = $this->getConnectionById($connection);
11345
  }
11346
  if ($connection !== $this->master && !in_array($connection, $this->slaves, true)) {
11347
- throw new InvalidArgumentException('Invalid connection or connection not found.');
11348
  }
11349
 
11350
  $this->current = $connection;
@@ -11466,7 +11758,6 @@ class MasterSlaveReplication implements ReplicationInterface
11466
 
11467
  namespace Predis\Pipeline;
11468
 
11469
- use SplQueue;
11470
  use Predis\ClientException;
11471
  use Predis\ClientInterface;
11472
  use Predis\Connection\ConnectionInterface;
@@ -11474,11 +11765,9 @@ use Predis\Connection\NodeConnectionInterface;
11474
  use Predis\Response\ErrorInterface as ErrorResponseInterface;
11475
  use Predis\Response\ResponseInterface;
11476
  use Predis\Response\ServerException;
11477
- use Predis\NotSupportedException;
11478
  use Predis\CommunicationException;
11479
  use Predis\Connection\Aggregate\ClusterInterface;
11480
- use Exception;
11481
- use InvalidArgumentException;
11482
  use Predis\ClientContextInterface;
11483
  use Predis\Command\CommandInterface;
11484
  use Predis\Connection\Aggregate\ReplicationInterface;
@@ -11505,7 +11794,7 @@ class Pipeline implements ClientContextInterface
11505
  public function __construct(ClientInterface $client)
11506
  {
11507
  $this->client = $client;
11508
- $this->pipeline = new SplQueue();
11509
  }
11510
 
11511
  /**
@@ -11585,11 +11874,11 @@ class Pipeline implements ClientContextInterface
11585
  * from the current connection.
11586
  *
11587
  * @param ConnectionInterface $connection Current connection instance.
11588
- * @param SplQueue $commands Queued commands.
11589
  *
11590
  * @return array
11591
  */
11592
- protected function executePipeline(ConnectionInterface $connection, SplQueue $commands)
11593
  {
11594
  foreach ($commands as $command) {
11595
  $connection->writeRequest($command);
@@ -11627,7 +11916,7 @@ class Pipeline implements ClientContextInterface
11627
  $responses = $this->executePipeline($this->getConnection(), $this->pipeline);
11628
  $this->responses = array_merge($this->responses, $responses);
11629
  } else {
11630
- $this->pipeline = new SplQueue();
11631
  }
11632
 
11633
  return $this;
@@ -11654,15 +11943,15 @@ class Pipeline implements ClientContextInterface
11654
  *
11655
  * @param mixed $callable Optional callback for execution.
11656
  *
11657
- * @return array
 
11658
  *
11659
- * @throws Exception
11660
- * @throws InvalidArgumentException
11661
  */
11662
  public function execute($callable = null)
11663
  {
11664
  if ($callable && !is_callable($callable)) {
11665
- throw new InvalidArgumentException('The argument must be a callable object.');
11666
  }
11667
 
11668
  $exception = null;
@@ -11674,7 +11963,7 @@ class Pipeline implements ClientContextInterface
11674
  }
11675
 
11676
  $this->flushPipeline();
11677
- } catch (Exception $exception) {
11678
  // NOOP
11679
  }
11680
 
@@ -11718,7 +12007,7 @@ class FireAndForget extends Pipeline
11718
  /**
11719
  * {@inheritdoc}
11720
  */
11721
- protected function executePipeline(ConnectionInterface $connection, SplQueue $commands)
11722
  {
11723
  while (!$commands->isEmpty()) {
11724
  $connection->writeRequest($commands->dequeue());
@@ -11735,6 +12024,7 @@ class FireAndForget extends Pipeline
11735
  * returns the exception instances as the rest of the response elements.
11736
  *
11737
  * @todo Awful naming!
 
11738
  * @author Daniele Alessandri <suppakilla@gmail.com>
11739
  */
11740
  class ConnectionErrorProof extends Pipeline
@@ -11750,7 +12040,7 @@ class ConnectionErrorProof extends Pipeline
11750
  /**
11751
  * {@inheritdoc}
11752
  */
11753
- protected function executePipeline(ConnectionInterface $connection, SplQueue $commands)
11754
  {
11755
  if ($connection instanceof NodeConnectionInterface) {
11756
  return $this->executeSingleNode($connection, $commands);
@@ -11766,9 +12056,9 @@ class ConnectionErrorProof extends Pipeline
11766
  /**
11767
  * {@inheritdoc}
11768
  */
11769
- protected function executeSingleNode(NodeConnectionInterface $connection, SplQueue $commands)
11770
  {
11771
- $responses = array();
11772
  $sizeOfPipe = count($commands);
11773
 
11774
  foreach ($commands as $command) {
@@ -11779,7 +12069,7 @@ class ConnectionErrorProof extends Pipeline
11779
  }
11780
  }
11781
 
11782
- for ($i = 0; $i < $sizeOfPipe; $i++) {
11783
  $command = $commands->dequeue();
11784
 
11785
  try {
@@ -11798,7 +12088,7 @@ class ConnectionErrorProof extends Pipeline
11798
  /**
11799
  * {@inheritdoc}
11800
  */
11801
- protected function executeCluster(ClusterInterface $connection, SplQueue $commands)
11802
  {
11803
  $responses = array();
11804
  $sizeOfPipe = count($commands);
@@ -11818,7 +12108,7 @@ class ConnectionErrorProof extends Pipeline
11818
  }
11819
  }
11820
 
11821
- for ($i = 0; $i < $sizeOfPipe; $i++) {
11822
  $command = $commands->dequeue();
11823
 
11824
  $cmdConnection = $connection->getConnection($command);
@@ -11881,7 +12171,7 @@ class Atomic extends Pipeline
11881
  /**
11882
  * {@inheritdoc}
11883
  */
11884
- protected function executePipeline(ConnectionInterface $connection, SplQueue $commands)
11885
  {
11886
  $profile = $this->getClient()->getProfile();
11887
  $connection->executeCommand($profile->createCommand('multi'));
@@ -11921,8 +12211,8 @@ class Atomic extends Pipeline
11921
  $sizeOfPipe = count($commands);
11922
  $exceptions = $this->throwServerExceptions();
11923
 
11924
- for ($i = 0; $i < $sizeOfPipe; $i++) {
11925
- $command = $commands->dequeue();
11926
  $response = $executed[$i];
11927
 
11928
  if (!$response instanceof ResponseInterface) {
@@ -11945,7 +12235,6 @@ class Atomic extends Pipeline
11945
  namespace Predis\Cluster\Distributor;
11946
 
11947
  use Predis\Cluster\Hash\HashGeneratorInterface;
11948
- use Exception;
11949
 
11950
  /**
11951
  * A distributor implements the logic to automatically distribute keys among
@@ -12026,7 +12315,7 @@ interface DistributorInterface
12026
  class HashRing implements DistributorInterface, HashGeneratorInterface
12027
  {
12028
  const DEFAULT_REPLICAS = 128;
12029
- const DEFAULT_WEIGHT = 100;
12030
 
12031
  private $ring;
12032
  private $ringKeys;
@@ -12057,7 +12346,7 @@ class HashRing implements DistributorInterface, HashGeneratorInterface
12057
  // last wins, thus the order in which nodes are added is significant.
12058
  $this->nodes[] = array(
12059
  'object' => $node,
12060
- 'weight' => (int) $weight ?: $this::DEFAULT_WEIGHT
12061
  );
12062
 
12063
  $this->reset();
@@ -12162,7 +12451,7 @@ class HashRing implements DistributorInterface, HashGeneratorInterface
12162
  $nodeHash = $this->getNodeHash($nodeObject);
12163
  $replicas = (int) round($weightRatio * $totalNodes * $replicas);
12164
 
12165
- for ($i = 0; $i < $replicas; $i++) {
12166
  $key = crc32("$nodeHash:$i");
12167
  $ring[$key] = $nodeObject;
12168
  }
@@ -12300,7 +12589,7 @@ class KetamaRing extends HashRing
12300
  $nodeHash = $this->getNodeHash($nodeObject);
12301
  $replicas = (int) floor($weightRatio * $totalNodes * ($replicas / 4));
12302
 
12303
- for ($i = 0; $i < $replicas; $i++) {
12304
  $unpackedDigest = unpack('V4', md5("$nodeHash-$i", true));
12305
 
12306
  foreach ($unpackedDigest as $key) {
@@ -12335,7 +12624,7 @@ class KetamaRing extends HashRing
12335
  *
12336
  * @author Daniele Alessandri <suppakilla@gmail.com>
12337
  */
12338
- class EmptyRingException extends Exception
12339
  {
12340
  }
12341
 
@@ -12344,12 +12633,7 @@ class EmptyRingException extends Exception
12344
  namespace Predis\Response\Iterator;
12345
 
12346
  use Predis\Connection\NodeConnectionInterface;
12347
- use Iterator;
12348
- use Countable;
12349
  use Predis\Response\ResponseInterface;
12350
- use OuterIterator;
12351
- use InvalidArgumentException;
12352
- use UnexpectedValueException;
12353
 
12354
  /**
12355
  * Iterator that abstracts the access to multibulk responses allowing them to be
@@ -12363,7 +12647,7 @@ use UnexpectedValueException;
12363
  *
12364
  * @author Daniele Alessandri <suppakilla@gmail.com>
12365
  */
12366
- abstract class MultiBulkIterator implements Iterator, Countable, ResponseInterface
12367
  {
12368
  protected $current;
12369
  protected $position;
@@ -12459,7 +12743,7 @@ class MultiBulk extends MultiBulkIterator
12459
  $this->connection = $connection;
12460
  $this->size = $size;
12461
  $this->position = 0;
12462
- $this->current = $size > 0 ? $this->getValue() : null;
12463
  }
12464
 
12465
  /**
@@ -12513,7 +12797,7 @@ class MultiBulk extends MultiBulkIterator
12513
  *
12514
  * @author Daniele Alessandri <suppakilla@gmail.com>
12515
  */
12516
- class MultiBulkTuple extends MultiBulk implements OuterIterator
12517
  {
12518
  private $iterator;
12519
 
@@ -12527,7 +12811,7 @@ class MultiBulkTuple extends MultiBulk implements OuterIterator
12527
  $this->size = count($iterator) / 2;
12528
  $this->iterator = $iterator;
12529
  $this->position = $iterator->getPosition();
12530
- $this->current = $this->size > 0 ? $this->getValue() : null;
12531
  }
12532
 
12533
  /**
@@ -12541,13 +12825,13 @@ class MultiBulkTuple extends MultiBulk implements OuterIterator
12541
  protected function checkPreconditions(MultiBulk $iterator)
12542
  {
12543
  if ($iterator->getPosition() !== 0) {
12544
- throw new InvalidArgumentException(
12545
  'Cannot initialize a tuple iterator using an already initiated iterator.'
12546
  );
12547
  }
12548
 
12549
  if (($size = count($iterator)) % 2 !== 0) {
12550
- throw new UnexpectedValueException("Invalid response size for a tuple iterator.");
12551
  }
12552
  }
12553
 
@@ -12656,7 +12940,7 @@ class CRC16 implements HashGeneratorInterface
12656
  $CCITT_16 = self::$CCITT_16;
12657
  $strlen = strlen($value);
12658
 
12659
- for ($i = 0; $i < $strlen; $i++) {
12660
  $crc = (($crc << 8) ^ $CCITT_16[($crc >> 8) ^ ord($value[$i])]) & 0xFFFF;
12661
  }
12662
 
@@ -12668,11 +12952,8 @@ class CRC16 implements HashGeneratorInterface
12668
 
12669
  namespace Predis\Command\Processor;
12670
 
12671
- use InvalidArgumentException;
12672
  use Predis\Command\CommandInterface;
12673
  use Predis\Command\PrefixableCommandInterface;
12674
- use ArrayAccess;
12675
- use ArrayIterator;
12676
 
12677
  /**
12678
  * A command processor processes Redis commands before they are sent to Redis.
@@ -12694,7 +12975,7 @@ interface ProcessorInterface
12694
  *
12695
  * @author Daniele Alessandri <suppakilla@gmail.com>
12696
  */
12697
- class ProcessorChain implements ArrayAccess, ProcessorInterface
12698
  {
12699
  private $processors = array();
12700
 
@@ -12731,7 +13012,7 @@ class ProcessorChain implements ArrayAccess, ProcessorInterface
12731
  */
12732
  public function process(CommandInterface $command)
12733
  {
12734
- for ($i = 0; $i < $count = count($this->processors); $i++) {
12735
  $this->processors[$i]->process($command);
12736
  }
12737
  }
@@ -12747,11 +13028,11 @@ class ProcessorChain implements ArrayAccess, ProcessorInterface
12747
  /**
12748
  * Returns an iterator over the list of command processor in the chain.
12749
  *
12750
- * @return ArrayIterator
12751
  */
12752
  public function getIterator()
12753
  {
12754
- return new ArrayIterator($this->processors);
12755
  }
12756
 
12757
  /**
@@ -12786,8 +13067,8 @@ class ProcessorChain implements ArrayAccess, ProcessorInterface
12786
  public function offsetSet($index, $processor)
12787
  {
12788
  if (!$processor instanceof ProcessorInterface) {
12789
- throw new InvalidArgumentException(
12790
- "A processor chain accepts only instances of ".
12791
  "'Predis\Command\Processor\ProcessorInterface'."
12792
  );
12793
  }
@@ -12824,127 +13105,132 @@ class KeyPrefixProcessor implements ProcessorInterface
12824
  $this->prefix = $prefix;
12825
  $this->commands = array(
12826
  /* ---------------- Redis 1.2 ---------------- */
12827
- 'EXISTS' => 'self::first',
12828
- 'DEL' => 'self::all',
12829
- 'TYPE' => 'self::first',
12830
- 'KEYS' => 'self::first',
12831
- 'RENAME' => 'self::all',
12832
- 'RENAMENX' => 'self::all',
12833
- 'EXPIRE' => 'self::first',
12834
- 'EXPIREAT' => 'self::first',
12835
- 'TTL' => 'self::first',
12836
- 'MOVE' => 'self::first',
12837
- 'SORT' => 'self::sort',
12838
- 'DUMP' => 'self::first',
12839
- 'RESTORE' => 'self::first',
12840
- 'SET' => 'self::first',
12841
- 'SETNX' => 'self::first',
12842
- 'MSET' => 'self::interleaved',
12843
- 'MSETNX' => 'self::interleaved',
12844
- 'GET' => 'self::first',
12845
- 'MGET' => 'self::all',
12846
- 'GETSET' => 'self::first',
12847
- 'INCR' => 'self::first',
12848
- 'INCRBY' => 'self::first',
12849
- 'DECR' => 'self::first',
12850
- 'DECRBY' => 'self::first',
12851
- 'RPUSH' => 'self::first',
12852
- 'LPUSH' => 'self::first',
12853
- 'LLEN' => 'self::first',
12854
- 'LRANGE' => 'self::first',
12855
- 'LTRIM' => 'self::first',
12856
- 'LINDEX' => 'self::first',
12857
- 'LSET' => 'self::first',
12858
- 'LREM' => 'self::first',
12859
- 'LPOP' => 'self::first',
12860
- 'RPOP' => 'self::first',
12861
- 'RPOPLPUSH' => 'self::all',
12862
- 'SADD' => 'self::first',
12863
- 'SREM' => 'self::first',
12864
- 'SPOP' => 'self::first',
12865
- 'SMOVE' => 'self::skipLast',
12866
- 'SCARD' => 'self::first',
12867
- 'SISMEMBER' => 'self::first',
12868
- 'SINTER' => 'self::all',
12869
- 'SINTERSTORE' => 'self::all',
12870
- 'SUNION' => 'self::all',
12871
- 'SUNIONSTORE' => 'self::all',
12872
- 'SDIFF' => 'self::all',
12873
- 'SDIFFSTORE' => 'self::all',
12874
- 'SMEMBERS' => 'self::first',
12875
- 'SRANDMEMBER' => 'self::first',
12876
- 'ZADD' => 'self::first',
12877
- 'ZINCRBY' => 'self::first',
12878
- 'ZREM' => 'self::first',
12879
- 'ZRANGE' => 'self::first',
12880
- 'ZREVRANGE' => 'self::first',
12881
- 'ZRANGEBYSCORE' => 'self::first',
12882
- 'ZCARD' => 'self::first',
12883
- 'ZSCORE' => 'self::first',
12884
- 'ZREMRANGEBYSCORE' => 'self::first',
12885
  /* ---------------- Redis 2.0 ---------------- */
12886
- 'SETEX' => 'self::first',
12887
- 'APPEND' => 'self::first',
12888
- 'SUBSTR' => 'self::first',
12889
- 'BLPOP' => 'self::skipLast',
12890
- 'BRPOP' => 'self::skipLast',
12891
- 'ZUNIONSTORE' => 'self::zsetStore',
12892
- 'ZINTERSTORE' => 'self::zsetStore',
12893
- 'ZCOUNT' => 'self::first',
12894
- 'ZRANK' => 'self::first',
12895
- 'ZREVRANK' => 'self::first',
12896
- 'ZREMRANGEBYRANK' => 'self::first',
12897
- 'HSET' => 'self::first',
12898
- 'HSETNX' => 'self::first',
12899
- 'HMSET' => 'self::first',
12900
- 'HINCRBY' => 'self::first',
12901
- 'HGET' => 'self::first',
12902
- 'HMGET' => 'self::first',
12903
- 'HDEL' => 'self::first',
12904
- 'HEXISTS' => 'self::first',
12905
- 'HLEN' => 'self::first',
12906
- 'HKEYS' => 'self::first',
12907
- 'HVALS' => 'self::first',
12908
- 'HGETALL' => 'self::first',
12909
- 'SUBSCRIBE' => 'self::all',
12910
- 'UNSUBSCRIBE' => 'self::all',
12911
- 'PSUBSCRIBE' => 'self::all',
12912
- 'PUNSUBSCRIBE' => 'self::all',
12913
- 'PUBLISH' => 'self::first',
12914
  /* ---------------- Redis 2.2 ---------------- */
12915
- 'PERSIST' => 'self::first',
12916
- 'STRLEN' => 'self::first',
12917
- 'SETRANGE' => 'self::first',
12918
- 'GETRANGE' => 'self::first',
12919
- 'SETBIT' => 'self::first',
12920
- 'GETBIT' => 'self::first',
12921
- 'RPUSHX' => 'self::first',
12922
- 'LPUSHX' => 'self::first',
12923
- 'LINSERT' => 'self::first',
12924
- 'BRPOPLPUSH' => 'self::skipLast',
12925
- 'ZREVRANGEBYSCORE' => 'self::first',
12926
- 'WATCH' => 'self::all',
12927
  /* ---------------- Redis 2.6 ---------------- */
12928
- 'PTTL' => 'self::first',
12929
- 'PEXPIRE' => 'self::first',
12930
- 'PEXPIREAT' => 'self::first',
12931
- 'PSETEX' => 'self::first',
12932
- 'INCRBYFLOAT' => 'self::first',
12933
- 'BITOP' => 'self::skipFirst',
12934
- 'BITCOUNT' => 'self::first',
12935
- 'HINCRBYFLOAT' => 'self::first',
12936
- 'EVAL' => 'self::evalKeys',
12937
- 'EVALSHA' => 'self::evalKeys',
 
12938
  /* ---------------- Redis 2.8 ---------------- */
12939
- 'SSCAN' => 'self::first',
12940
- 'ZSCAN' => 'self::first',
12941
- 'HSCAN' => 'self::first',
12942
- 'PFADD' => 'self::first',
12943
- 'PFCOUNT' => 'self::all',
12944
- 'PFMERGE' => 'self::all',
12945
- 'ZLEXCOUNT' => 'self::first',
12946
- 'ZRANGEBYLEX' => 'self::first',
12947
- 'ZREMRANGEBYLEX' => 'self::first',
 
 
 
 
12948
  );
12949
  }
12950
 
@@ -13007,8 +13293,8 @@ class KeyPrefixProcessor implements ProcessorInterface
13007
  }
13008
 
13009
  if (!is_callable($callback)) {
13010
- throw new InvalidArgumentException(
13011
- "Callback must be a valid callable object or NULL"
13012
  );
13013
  }
13014
 
@@ -13084,7 +13370,7 @@ class KeyPrefixProcessor implements ProcessorInterface
13084
  if ($arguments = $command->getArguments()) {
13085
  $length = count($arguments);
13086
 
13087
- for ($i = 1; $i < $length; $i++) {
13088
  $arguments[$i] = "$prefix{$arguments[$i]}";
13089
  }
13090
 
@@ -13103,7 +13389,7 @@ class KeyPrefixProcessor implements ProcessorInterface
13103
  if ($arguments = $command->getArguments()) {
13104
  $length = count($arguments);
13105
 
13106
- for ($i = 0; $i < $length - 1; $i++) {
13107
  $arguments[$i] = "$prefix{$arguments[$i]}";
13108
  }
13109
 
@@ -13123,7 +13409,7 @@ class KeyPrefixProcessor implements ProcessorInterface
13123
  $arguments[0] = "$prefix{$arguments[0]}";
13124
 
13125
  if (($count = count($arguments)) > 1) {
13126
- for ($i = 1; $i < $count; $i++) {
13127
  switch ($arguments[$i]) {
13128
  case 'BY':
13129
  case 'STORE':
@@ -13157,7 +13443,7 @@ class KeyPrefixProcessor implements ProcessorInterface
13157
  public static function evalKeys(CommandInterface $command, $prefix)
13158
  {
13159
  if ($arguments = $command->getArguments()) {
13160
- for ($i = 2; $i < $arguments[1] + 2; $i++) {
13161
  $arguments[$i] = "$prefix{$arguments[$i]}";
13162
  }
13163
 
@@ -13177,13 +13463,27 @@ class KeyPrefixProcessor implements ProcessorInterface
13177
  $arguments[0] = "$prefix{$arguments[0]}";
13178
  $length = ((int) $arguments[1]) + 2;
13179
 
13180
- for ($i = 2; $i < $length; $i++) {
13181
  $arguments[$i] = "$prefix{$arguments[$i]}";
13182
  }
13183
 
13184
  $command->setRawArguments($arguments);
13185
  }
13186
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13187
  }
13188
 
13189
  /* --------------------------------------------------------------------------- */
@@ -13197,14 +13497,15 @@ use Predis\Protocol\RequestSerializerInterface;
13197
  use Predis\Protocol\ResponseReaderInterface;
13198
  use Predis\CommunicationException;
13199
  use Predis\Protocol\ProtocolException;
13200
- use Predis\Response\Status as StatusResponse;
13201
  use Predis\Response\Error as ErrorResponse;
13202
  use Predis\Response\Iterator\MultiBulk as MultiBulkIterator;
 
13203
 
13204
  /**
13205
  * Response reader for the standard Redis wire protocol.
13206
  *
13207
  * @link http://redis.io/topics/protocol
 
13208
  * @author Daniele Alessandri <suppakilla@gmail.com>
13209
  */
13210
  class ResponseReader implements ResponseReaderInterface
@@ -13259,7 +13560,7 @@ class ResponseReader implements ResponseReaderInterface
13259
  return $this->handlers[$prefix];
13260
  }
13261
 
13262
- return null;
13263
  }
13264
 
13265
  /**
@@ -13303,6 +13604,7 @@ class ResponseReader implements ResponseReaderInterface
13303
  * Request serializer for the standard Redis wire protocol.
13304
  *
13305
  * @link http://redis.io/topics/protocol
 
13306
  * @author Daniele Alessandri <suppakilla@gmail.com>
13307
  */
13308
  class RequestSerializer implements RequestSerializerInterface
@@ -13320,7 +13622,7 @@ class RequestSerializer implements RequestSerializerInterface
13320
 
13321
  $buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
13322
 
13323
- for ($i = 0, $reqlen--; $i < $reqlen; $i++) {
13324
  $argument = $arguments[$i];
13325
  $arglen = strlen($argument);
13326
  $buffer .= "\${$arglen}\r\n{$argument}\r\n";
@@ -13334,6 +13636,7 @@ class RequestSerializer implements RequestSerializerInterface
13334
  * Protocol processor for the standard Redis wire protocol.
13335
  *
13336
  * @link http://redis.io/topics/protocol
 
13337
  * @author Daniele Alessandri <suppakilla@gmail.com>
13338
  */
13339
  class ProtocolProcessor implements ProtocolProcessorInterface
@@ -13375,7 +13678,7 @@ class ProtocolProcessor implements ProtocolProcessorInterface
13375
  case '$':
13376
  $size = (int) $payload;
13377
  if ($size === -1) {
13378
- return null;
13379
  }
13380
 
13381
  return substr($connection->readBuffer($size + 2), 0, -2);
@@ -13384,7 +13687,7 @@ class ProtocolProcessor implements ProtocolProcessorInterface
13384
  $count = (int) $payload;
13385
 
13386
  if ($count === -1) {
13387
- return null;
13388
  }
13389
  if ($this->mbiterable) {
13390
  return new MultiBulkIterator($connection, $count);
@@ -13392,7 +13695,7 @@ class ProtocolProcessor implements ProtocolProcessorInterface
13392
 
13393
  $multibulk = array();
13394
 
13395
- for ($i = 0; $i < $count; $i++) {
13396
  $multibulk[$i] = $this->read($connection);
13397
  }
13398
 
@@ -13435,6 +13738,7 @@ class ProtocolProcessor implements ProtocolProcessorInterface
13435
  * pluggable handlers to serialize requests and deserialize responses.
13436
  *
13437
  * @link http://redis.io/topics/protocol
 
13438
  * @author Daniele Alessandri <suppakilla@gmail.com>
13439
  */
13440
  class CompositeProtocolProcessor implements ProtocolProcessorInterface
@@ -13522,20 +13826,18 @@ class CompositeProtocolProcessor implements ProtocolProcessorInterface
13522
 
13523
  namespace Predis\PubSub;
13524
 
13525
- use Iterator;
13526
  use Predis\ClientException;
13527
  use Predis\ClientInterface;
13528
  use Predis\Command\Command;
13529
- use Predis\NotSupportedException;
13530
  use Predis\Connection\AggregateConnectionInterface;
13531
- use InvalidArgumentException;
13532
 
13533
  /**
13534
  * Base implementation of a PUB/SUB consumer abstraction based on PHP iterators.
13535
  *
13536
  * @author Daniele Alessandri <suppakilla@gmail.com>
13537
  */
13538
- abstract class AbstractConsumer implements Iterator
13539
  {
13540
  const SUBSCRIBE = 'subscribe';
13541
  const UNSUBSCRIBE = 'unsubscribe';
@@ -13545,9 +13847,9 @@ abstract class AbstractConsumer implements Iterator
13545
  const PMESSAGE = 'pmessage';
13546
  const PONG = 'pong';
13547
 
13548
- const STATUS_VALID = 1; // 0b0001
13549
- const STATUS_SUBSCRIBED = 2; // 0b0010
13550
- const STATUS_PSUBSCRIBED = 4; // 0b0100
13551
 
13552
  private $position = null;
13553
  private $statusFlags = self::STATUS_VALID;
@@ -13700,7 +14002,7 @@ abstract class AbstractConsumer implements Iterator
13700
  public function next()
13701
  {
13702
  if ($this->valid()) {
13703
- $this->position++;
13704
  }
13705
 
13706
  return $this->position;
@@ -13725,7 +14027,7 @@ abstract class AbstractConsumer implements Iterator
13725
  */
13726
  protected function invalidate()
13727
  {
13728
- $this->statusFlags = 0; // 0b0000;
13729
  }
13730
 
13731
  /**
@@ -13770,7 +14072,7 @@ class DispatcherLoop
13770
  protected function assertCallback($callable)
13771
  {
13772
  if (!is_callable($callable)) {
13773
- throw new InvalidArgumentException('The given argument must be a callable object.');
13774
  }
13775
  }
13776
 
@@ -13821,7 +14123,7 @@ class DispatcherLoop
13821
  */
13822
  public function attachCallback($channel, $callback)
13823
  {
13824
- $callbackName = $this->getPrefixKeys() . $channel;
13825
 
13826
  $this->assertCallback($callback);
13827
  $this->callbacks[$callbackName] = $callback;
@@ -13835,7 +14137,7 @@ class DispatcherLoop
13835
  */
13836
  public function detachCallback($channel)
13837
  {
13838
- $callbackName = $this->getPrefixKeys() . $channel;
13839
 
13840
  if (isset($this->callbacks[$callbackName])) {
13841
  unset($this->callbacks[$callbackName]);
@@ -13879,7 +14181,7 @@ class DispatcherLoop
13879
  }
13880
 
13881
  /**
13882
- * Return the prefix used for keys
13883
  *
13884
  * @return string
13885
  */
@@ -14008,14 +14310,14 @@ class Consumer extends AbstractConsumer
14008
 
14009
  case self::MESSAGE:
14010
  return (object) array(
14011
- 'kind' => $response[0],
14012
  'channel' => $response[1],
14013
  'payload' => $response[2],
14014
  );
14015
 
14016
  case self::PMESSAGE:
14017
  return (object) array(
14018
- 'kind' => $response[0],
14019
  'pattern' => $response[1],
14020
  'channel' => $response[2],
14021
  'payload' => $response[3],
@@ -14023,7 +14325,7 @@ class Consumer extends AbstractConsumer
14023
 
14024
  case self::PONG:
14025
  return (object) array(
14026
- 'kind' => $response[0],
14027
  'payload' => $response[1],
14028
  );
14029
 
@@ -14040,20 +14342,17 @@ class Consumer extends AbstractConsumer
14040
  namespace Predis\Transaction;
14041
 
14042
  use Predis\PredisException;
14043
- use Exception;
14044
- use InvalidArgumentException;
14045
- use SplQueue;
14046
  use Predis\ClientContextInterface;
14047
  use Predis\ClientException;
14048
  use Predis\ClientInterface;
 
14049
  use Predis\CommunicationException;
 
14050
  use Predis\NotSupportedException;
 
14051
  use Predis\Response\ErrorInterface as ErrorResponseInterface;
14052
  use Predis\Response\ServerException;
14053
  use Predis\Response\Status as StatusResponse;
14054
- use Predis\Command\CommandInterface;
14055
- use Predis\Connection\AggregateConnectionInterface;
14056
- use Predis\Protocol\ProtocolException;
14057
 
14058
  /**
14059
  * Utility class used to track the state of a MULTI / EXEC transaction.
@@ -14223,9 +14522,9 @@ class MultiExec implements ClientContextInterface
14223
  protected $client;
14224
  protected $commands;
14225
  protected $exceptions = true;
14226
- protected $attempts = 0;
14227
- protected $watchKeys = array();
14228
- protected $modeCAS = false;
14229
 
14230
  /**
14231
  * @param ClientInterface $client Client instance used by the transaction.
@@ -14298,7 +14597,7 @@ class MultiExec implements ClientContextInterface
14298
  protected function reset()
14299
  {
14300
  $this->state->reset();
14301
- $this->commands = new SplQueue();
14302
  }
14303
 
14304
  /**
@@ -14354,9 +14653,9 @@ class MultiExec implements ClientContextInterface
14354
  * @param string $commandID Command ID.
14355
  * @param array $arguments Arguments for the command.
14356
  *
14357
- * @return mixed
14358
- *
14359
  * @throws ServerException
 
 
14360
  */
14361
  protected function call($commandID, array $arguments = array())
14362
  {
@@ -14376,10 +14675,10 @@ class MultiExec implements ClientContextInterface
14376
  *
14377
  * @param CommandInterface $command Command instance.
14378
  *
14379
- * @return $this|mixed
14380
- *
14381
  * @throws AbortedMultiExecException
14382
  * @throws CommunicationException
 
 
14383
  */
14384
  public function executeCommand(CommandInterface $command)
14385
  {
@@ -14407,10 +14706,10 @@ class MultiExec implements ClientContextInterface
14407
  *
14408
  * @param string|array $keys One or more keys.
14409
  *
14410
- * @return mixed
14411
- *
14412
  * @throws NotSupportedException
14413
  * @throws ClientException
 
 
14414
  */
14415
  public function watch($keys)
14416
  {
@@ -14448,9 +14747,9 @@ class MultiExec implements ClientContextInterface
14448
  /**
14449
  * Executes UNWATCH.
14450
  *
14451
- * @return MultiExec
14452
- *
14453
  * @throws NotSupportedException
 
 
14454
  */
14455
  public function unwatch()
14456
  {
@@ -14499,7 +14798,7 @@ class MultiExec implements ClientContextInterface
14499
  *
14500
  * @param mixed $callable Callback for execution.
14501
  *
14502
- * @throws InvalidArgumentException
14503
  * @throws ClientException
14504
  */
14505
  private function checkBeforeExecution($callable)
@@ -14512,7 +14811,7 @@ class MultiExec implements ClientContextInterface
14512
 
14513
  if ($callable) {
14514
  if (!is_callable($callable)) {
14515
- throw new InvalidArgumentException('The argument must be a callable object.');
14516
  }
14517
 
14518
  if (!$this->commands->isEmpty()) {
@@ -14536,11 +14835,11 @@ class MultiExec implements ClientContextInterface
14536
  *
14537
  * @param mixed $callable Optional callback for execution.
14538
  *
14539
- * @return array
14540
- *
14541
  * @throws CommunicationException
14542
  * @throws AbortedMultiExecException
14543
  * @throws ServerException
 
 
14544
  */
14545
  public function execute($callable = null)
14546
  {
@@ -14559,7 +14858,7 @@ class MultiExec implements ClientContextInterface
14559
  $this->discard();
14560
  }
14561
 
14562
- return null;
14563
  }
14564
 
14565
  $execResponse = $this->call('EXEC');
@@ -14587,7 +14886,7 @@ class MultiExec implements ClientContextInterface
14587
  $this->onProtocolError('EXEC returned an unexpected number of response items.');
14588
  }
14589
 
14590
- for ($i = 0; $i < $size; $i++) {
14591
  $cmdResponse = $execResponse[$i];
14592
 
14593
  if ($cmdResponse instanceof ErrorResponseInterface && $this->exceptions) {
@@ -14619,7 +14918,7 @@ class MultiExec implements ClientContextInterface
14619
  // NOOP
14620
  } catch (ServerException $exception) {
14621
  // NOOP
14622
- } catch (Exception $exception) {
14623
  $this->discard();
14624
  }
14625
 
@@ -14681,7 +14980,6 @@ class AbortedMultiExecException extends PredisException
14681
 
14682
  namespace Predis\Session;
14683
 
14684
- use SessionHandlerInterface;
14685
  use Predis\ClientInterface;
14686
 
14687
  /**
@@ -14694,7 +14992,7 @@ use Predis\ClientInterface;
14694
  *
14695
  * @author Daniele Alessandri <suppakilla@gmail.com>
14696
  */
14697
- class Handler implements SessionHandlerInterface
14698
  {
14699
  protected $client;
14700
  protected $ttl;
@@ -14719,7 +15017,7 @@ class Handler implements SessionHandlerInterface
14719
  */
14720
  public function register()
14721
  {
14722
- if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
14723
  session_set_save_handler($this, true);
14724
  } else {
14725
  session_set_save_handler(
@@ -14816,17 +15114,16 @@ class Handler implements SessionHandlerInterface
14816
 
14817
  namespace Predis\Monitor;
14818
 
14819
- use Iterator;
14820
  use Predis\ClientInterface;
14821
- use Predis\NotSupportedException;
14822
  use Predis\Connection\AggregateConnectionInterface;
 
14823
 
14824
  /**
14825
  * Redis MONITOR consumer.
14826
  *
14827
  * @author Daniele Alessandri <suppakilla@gmail.com>
14828
  */
14829
- class Consumer implements Iterator
14830
  {
14831
  private $client;
14832
  private $valid;
@@ -14925,7 +15222,7 @@ class Consumer implements Iterator
14925
  */
14926
  public function next()
14927
  {
14928
- $this->position++;
14929
  }
14930
 
14931
  /**
@@ -14970,9 +15267,9 @@ class Consumer implements Iterator
14970
 
14971
  return (object) array(
14972
  'timestamp' => (float) $timestamp,
14973
- 'database' => $database,
14974
- 'client' => $client,
14975
- 'command' => substr($command, 1, -1),
14976
  'arguments' => $arguments,
14977
  );
14978
  }
@@ -14982,8 +15279,8 @@ class Consumer implements Iterator
14982
 
14983
  namespace Predis\Replication;
14984
 
14985
- use Predis\NotSupportedException;
14986
  use Predis\Command\CommandInterface;
 
14987
 
14988
  /**
14989
  * Defines a strategy for master/slave replication.
@@ -15012,9 +15309,9 @@ class ReplicationStrategy
15012
  *
15013
  * @param CommandInterface $command Command instance.
15014
  *
15015
- * @return bool
15016
- *
15017
  * @throws NotSupportedException
 
 
15018
  */
15019
  public function isReadOperation(CommandInterface $command)
15020
  {
@@ -15125,17 +15422,17 @@ class ReplicationStrategy
15125
  protected function getDisallowedOperations()
15126
  {
15127
  return array(
15128
- 'SHUTDOWN' => true,
15129
- 'INFO' => true,
15130
- 'DBSIZE' => true,
15131
- 'LASTSAVE' => true,
15132
- 'CONFIG' => true,
15133
- 'MONITOR' => true,
15134
- 'SLAVEOF' => true,
15135
- 'SAVE' => true,
15136
- 'BGSAVE' => true,
15137
- 'BGREWRITEAOF' => true,
15138
- 'SLOWLOG' => true,
15139
  );
15140
  }
15141
 
@@ -15147,59 +15444,62 @@ class ReplicationStrategy
15147
  protected function getReadOnlyOperations()
15148
  {
15149
  return array(
15150
- 'EXISTS' => true,
15151
- 'TYPE' => true,
15152
- 'KEYS' => true,
15153
- 'SCAN' => true,
15154
- 'RANDOMKEY' => true,
15155
- 'TTL' => true,
15156
- 'GET' => true,
15157
- 'MGET' => true,
15158
- 'SUBSTR' => true,
15159
- 'STRLEN' => true,
15160
- 'GETRANGE' => true,
15161
- 'GETBIT' => true,
15162
- 'LLEN' => true,
15163
- 'LRANGE' => true,
15164
- 'LINDEX' => true,
15165
- 'SCARD' => true,
15166
- 'SISMEMBER' => true,
15167
- 'SINTER' => true,
15168
- 'SUNION' => true,
15169
- 'SDIFF' => true,
15170
- 'SMEMBERS' => true,
15171
- 'SSCAN' => true,
15172
- 'SRANDMEMBER' => true,
15173
- 'ZRANGE' => true,
15174
- 'ZREVRANGE' => true,
15175
- 'ZRANGEBYSCORE' => true,
15176
- 'ZREVRANGEBYSCORE' => true,
15177
- 'ZCARD' => true,
15178
- 'ZSCORE' => true,
15179
- 'ZCOUNT' => true,
15180
- 'ZRANK' => true,
15181
- 'ZREVRANK' => true,
15182
- 'ZSCAN' => true,
15183
- 'ZLEXCOUNT' => true,
15184
- 'ZRANGEBYLEX' => true,
15185
- 'HGET' => true,
15186
- 'HMGET' => true,
15187
- 'HEXISTS' => true,
15188
- 'HLEN' => true,
15189
- 'HKEYS' => true,
15190
- 'HVALS' => true,
15191
- 'HGETALL' => true,
15192
- 'HSCAN' => true,
15193
- 'PING' => true,
15194
- 'AUTH' => true,
15195
- 'SELECT' => true,
15196
- 'ECHO' => true,
15197
- 'QUIT' => true,
15198
- 'OBJECT' => true,
15199
- 'BITCOUNT' => true,
15200
- 'TIME' => true,
15201
- 'PFCOUNT' => true,
15202
- 'SORT' => array($this, 'isSortReadOnly'),
 
 
 
15203
  );
15204
  }
15205
  }
11
 
12
  namespace Predis\Command;
13
 
 
 
14
  /**
15
  * Defines an abstraction representing a Redis command.
16
  *
199
 
200
  /**
201
  * @link http://redis.io/commands/zrange
202
+ *
203
  * @author Daniele Alessandri <suppakilla@gmail.com>
204
  */
205
  class ZSetRange extends Command
279
  if ($this->withScores()) {
280
  $result = array();
281
 
282
+ for ($i = 0; $i < count($data); ++$i) {
283
  $result[$data[$i]] = $data[++$i];
284
  }
285
 
292
 
293
  /**
294
  * @link http://redis.io/commands/sinterstore
295
+ *
296
  * @author Daniele Alessandri <suppakilla@gmail.com>
297
  */
298
  class SetIntersectionStore extends Command
319
  }
320
 
321
  /**
322
+ * @link http://redis.io/commands/eval
323
+ *
324
  * @author Daniele Alessandri <suppakilla@gmail.com>
325
  */
326
+ class ServerEval extends Command
327
  {
328
  /**
329
  * {@inheritdoc}
330
  */
331
  public function getId()
332
  {
333
+ return 'EVAL';
334
  }
335
 
336
  /**
337
+ * Calculates the SHA1 hash of the body of the script.
338
+ *
339
+ * @return string SHA1 hash.
340
  */
341
+ public function getScriptHash()
342
  {
343
+ return sha1($this->getArgument(0));
344
  }
345
  }
346
 
347
  /**
348
+ * @link http://redis.io/commands/sinter
349
+ *
350
  * @author Daniele Alessandri <suppakilla@gmail.com>
351
  */
352
+ class SetIntersection extends Command
353
  {
354
  /**
355
  * {@inheritdoc}
356
  */
357
  public function getId()
358
  {
359
+ return 'SINTER';
360
  }
361
 
362
  /**
363
+ * {@inheritdoc}
 
 
364
  */
365
+ protected function filterArguments(array $arguments)
366
  {
367
+ return self::normalizeArguments($arguments);
368
  }
369
  }
370
 
371
  /**
372
+ * @link http://redis.io/commands/rpush
373
+ *
374
  * @author Daniele Alessandri <suppakilla@gmail.com>
375
  */
376
+ class ListPushTail extends Command
377
  {
378
  /**
379
  * {@inheritdoc}
380
  */
381
  public function getId()
382
  {
383
+ return 'RPUSH';
384
+ }
385
+
386
+ /**
387
+ * {@inheritdoc}
388
+ */
389
+ protected function filterArguments(array $arguments)
390
+ {
391
+ return self::normalizeVariadic($arguments);
392
  }
393
  }
394
 
395
  /**
396
+ * @link http://redis.io/commands/subscribe
397
+ *
398
  * @author Daniele Alessandri <suppakilla@gmail.com>
399
  */
400
+ class PubSubSubscribe extends Command
401
  {
402
  /**
403
  * {@inheritdoc}
404
  */
405
  public function getId()
406
  {
407
+ return 'SUBSCRIBE';
408
+ }
409
+
410
+ /**
411
+ * {@inheritdoc}
412
+ */
413
+ protected function filterArguments(array $arguments)
414
+ {
415
+ return self::normalizeArguments($arguments);
416
  }
417
  }
418
 
419
  /**
420
+ * @link http://redis.io/commands/blpop
421
+ *
422
  * @author Daniele Alessandri <suppakilla@gmail.com>
423
  */
424
+ class ListPopFirstBlocking extends Command
425
  {
426
  /**
427
  * {@inheritdoc}
428
  */
429
  public function getId()
430
  {
431
+ return 'BLPOP';
432
  }
433
 
434
  /**
436
  */
437
  protected function filterArguments(array $arguments)
438
  {
439
+ if (count($arguments) === 2 && is_array($arguments[0])) {
440
+ list($arguments, $timeout) = $arguments;
441
+ array_push($arguments, $timeout);
 
 
 
 
 
 
 
442
  }
443
 
444
  return $arguments;
445
  }
446
  }
447
 
448
+ /**
449
+ * @link http://redis.io/commands/ttl
450
+ *
451
+ * @author Daniele Alessandri <suppakilla@gmail.com>
452
+ */
453
+ class KeyTimeToLive extends Command
454
+ {
455
+ /**
456
+ * {@inheritdoc}
457
+ */
458
+ public function getId()
459
+ {
460
+ return 'TTL';
461
+ }
462
+ }
463
+
464
  /**
465
  * @link http://redis.io/commands/expireat
466
+ *
467
  * @author Daniele Alessandri <suppakilla@gmail.com>
468
  */
469
  class KeyExpireAt extends Command
486
  }
487
 
488
  /**
489
+ * @link http://redis.io/commands/rename
490
+ *
491
  * @author Daniele Alessandri <suppakilla@gmail.com>
492
  */
493
+ class KeyRename extends Command
494
  {
495
  /**
496
  * {@inheritdoc}
497
  */
498
  public function getId()
499
  {
500
+ return 'RENAME';
 
 
 
 
 
 
 
 
 
 
 
 
 
501
  }
502
  }
503
 
504
  /**
505
  * @link http://redis.io/commands/unsubscribe
506
+ *
507
  * @author Daniele Alessandri <suppakilla@gmail.com>
508
  */
509
  class PubSubUnsubscribe extends Command
526
  }
527
 
528
  /**
529
+ * @link http://redis.io/commands/zunionstore
530
+ *
531
  * @author Daniele Alessandri <suppakilla@gmail.com>
532
  */
533
+ class ZSetUnionStore extends Command
534
  {
535
  /**
536
  * {@inheritdoc}
537
  */
538
  public function getId()
539
  {
540
+ return 'ZUNIONSTORE';
541
  }
542
 
543
  /**
544
  * {@inheritdoc}
545
  */
546
+ protected function filterArguments(array $arguments)
547
  {
548
+ $options = array();
549
+ $argc = count($arguments);
550
 
551
+ if ($argc > 2 && is_array($arguments[$argc - 1])) {
552
+ $options = $this->prepareOptions(array_pop($arguments));
553
+ }
 
554
 
555
+ if (is_array($arguments[1])) {
556
+ $arguments = array_merge(
557
+ array($arguments[0], count($arguments[1])),
558
+ $arguments[1]
559
+ );
560
  }
561
 
562
+ return array_merge($arguments, $options);
563
  }
564
 
565
  /**
566
+ * Returns a list of options and modifiers compatible with Redis.
567
  *
568
+ * @param array $options List of options.
569
  *
570
  * @return array
571
  */
572
+ private function prepareOptions($options)
573
  {
574
+ $opts = array_change_key_case($options, CASE_UPPER);
575
+ $finalizedOpts = array();
576
 
577
+ if (isset($opts['WEIGHTS']) && is_array($opts['WEIGHTS'])) {
578
+ $finalizedOpts[] = 'WEIGHTS';
579
+
580
+ foreach ($opts['WEIGHTS'] as $weight) {
581
+ $finalizedOpts[] = $weight;
582
+ }
583
  }
584
 
585
+ if (isset($opts['AGGREGATE'])) {
586
+ $finalizedOpts[] = 'AGGREGATE';
587
+ $finalizedOpts[] = $opts['AGGREGATE'];
588
+ }
589
+
590
+ return $finalizedOpts;
591
  }
592
+ }
593
 
594
+ /**
595
+ * @link http://redis.io/commands/zrangebylex
596
+ *
597
+ * @author Daniele Alessandri <suppakilla@gmail.com>
598
+ */
599
+ class ZSetRangeByLex extends ZSetRange
600
+ {
601
  /**
602
+ * {@inheritdoc}
 
 
 
 
603
  */
604
+ public function getId()
605
  {
606
+ return 'ZRANGEBYLEX';
 
 
 
 
 
 
 
607
  }
608
 
609
  /**
610
+ * {@inheritdoc}
 
 
 
 
611
  */
612
+ protected function prepareOptions($options)
613
  {
614
+ $opts = array_change_key_case($options, CASE_UPPER);
615
+ $finalizedOpts = array();
 
 
616
 
617
+ if (isset($opts['LIMIT']) && is_array($opts['LIMIT'])) {
618
+ $limit = array_change_key_case($opts['LIMIT'], CASE_UPPER);
 
 
 
619
 
620
+ $finalizedOpts[] = 'LIMIT';
621
+ $finalizedOpts[] = isset($limit['OFFSET']) ? $limit['OFFSET'] : $limit[0];
622
+ $finalizedOpts[] = isset($limit['COUNT']) ? $limit['COUNT'] : $limit[1];
623
  }
624
 
625
+ return $finalizedOpts;
626
+ }
627
+
628
+ /**
629
+ * {@inheritdoc}
630
+ */
631
+ protected function withScores()
632
+ {
633
+ return false;
634
  }
635
  }
636
 
637
  /**
638
+ * @link http://redis.io/commands/setex
639
+ *
640
  * @author Daniele Alessandri <suppakilla@gmail.com>
641
  */
642
+ class StringSetExpire extends Command
643
  {
644
  /**
645
  * {@inheritdoc}
646
  */
647
  public function getId()
648
  {
649
+ return 'SETEX';
 
 
 
 
 
 
 
 
 
 
650
  }
651
  }
652
 
653
  /**
654
  * @link http://redis.io/commands/expire
655
+ *
656
  * @author Daniele Alessandri <suppakilla@gmail.com>
657
  */
658
  class KeyExpire extends Command
675
  }
676
 
677
  /**
678
+ * @link http://redis.io/commands/info
679
+ *
680
  * @author Daniele Alessandri <suppakilla@gmail.com>
681
  */
682
+ class ServerInfo extends Command
683
  {
684
  /**
685
  * {@inheritdoc}
686
  */
687
  public function getId()
688
  {
689
+ return 'INFO';
690
  }
691
 
692
  /**
693
  * {@inheritdoc}
694
  */
695
+ public function parseResponse($data)
696
  {
697
+ $info = array();
698
+ $infoLines = preg_split('/\r?\n/', $data);
 
699
 
700
+ foreach ($infoLines as $row) {
701
+ if (strpos($row, ':') === false) {
702
+ continue;
703
+ }
 
 
 
 
 
 
 
 
 
704
 
705
+ list($k, $v) = $this->parseRow($row);
706
+ $info[$k] = $v;
707
+ }
 
 
 
 
 
708
 
709
+ return $info;
 
 
 
 
 
 
 
 
 
 
 
710
  }
 
711
 
 
 
 
 
 
 
712
  /**
713
+ * Parses a single row of the response and returns the key-value pair.
714
+ *
715
+ * @param string $row Single row of the response.
716
+ *
717
+ * @return array
718
  */
719
+ protected function parseRow($row)
720
  {
721
+ list($k, $v) = explode(':', $row, 2);
722
+
723
+ if (preg_match('/^db\d+$/', $k)) {
724
+ $v = $this->parseDatabaseStats($v);
725
+ }
726
+
727
+ return array($k, $v);
728
  }
729
 
730
  /**
731
+ * Extracts the statistics of each logical DB from the string buffer.
732
+ *
733
+ * @param string $str Response buffer.
734
+ *
735
+ * @return array
736
  */
737
+ protected function parseDatabaseStats($str)
738
  {
739
+ $db = array();
 
 
 
 
 
740
 
741
+ foreach (explode(',', $str) as $dbvar) {
742
+ list($dbvk, $dbvv) = explode('=', $dbvar);
743
+ $db[trim($dbvk)] = $dbvv;
 
 
744
  }
745
 
746
+ return $db;
747
  }
748
 
749
  /**
750
+ * Parses the response and extracts the allocation statistics.
751
  *
752
+ * @param string $str Response buffer.
753
  *
754
  * @return array
755
  */
756
+ protected function parseAllocationStats($str)
757
  {
758
+ $stats = array();
 
759
 
760
+ foreach (explode(',', $str) as $kv) {
761
+ @list($size, $objects, $extra) = explode('=', $kv);
762
 
763
+ // hack to prevent incorrect values when parsing the >=256 key
764
+ if (isset($extra)) {
765
+ $size = ">=$objects";
766
+ $objects = $extra;
767
  }
 
768
 
769
+ $stats[$size] = $objects;
 
 
770
  }
771
 
772
+ return $stats;
773
  }
774
  }
775
 
776
  /**
777
  * @link http://redis.io/commands/zrangebyscore
778
+ *
779
  * @author Daniele Alessandri <suppakilla@gmail.com>
780
  */
781
  class ZSetRangeByScore extends ZSetRange
814
  {
815
  $arguments = $this->getArguments();
816
 
817
+ for ($i = 3; $i < count($arguments); ++$i) {
818
  switch (strtoupper($arguments[$i])) {
819
  case 'WITHSCORES':
820
  return true;
830
  }
831
 
832
  /**
833
+ * @link http://redis.io/commands/mset
834
+ *
835
  * @author Daniele Alessandri <suppakilla@gmail.com>
836
  */
837
+ class StringSetMultiple extends Command
838
  {
839
  /**
840
  * {@inheritdoc}
841
  */
842
  public function getId()
843
  {
844
+ return 'MSET';
845
  }
 
846
 
 
 
 
 
 
 
847
  /**
848
  * {@inheritdoc}
849
  */
850
+ protected function filterArguments(array $arguments)
851
  {
852
+ if (count($arguments) === 1 && is_array($arguments[0])) {
853
+ $flattenedKVs = array();
854
+ $args = $arguments[0];
855
+
856
+ foreach ($args as $k => $v) {
857
+ $flattenedKVs[] = $k;
858
+ $flattenedKVs[] = $v;
859
+ }
860
+
861
+ return $flattenedKVs;
862
+ }
863
+
864
+ return $arguments;
865
  }
866
  }
867
 
868
  /**
869
+ * @link http://redis.io/commands/evalsha
870
+ *
871
  * @author Daniele Alessandri <suppakilla@gmail.com>
872
  */
873
+ class ServerEvalSHA extends ServerEval
874
  {
875
  /**
876
  * {@inheritdoc}
877
  */
878
  public function getId()
879
  {
880
+ return 'EVALSHA';
881
  }
882
 
883
  /**
884
+ * Returns the SHA1 hash of the body of the script.
885
+ *
886
+ * @return string SHA1 hash.
887
  */
888
+ public function getScriptHash()
889
  {
890
+ return $this->getArgument(0);
891
  }
892
  }
893
 
894
  /**
895
+ * @link http://redis.io/commands/decr
896
+ *
897
  * @author Daniele Alessandri <suppakilla@gmail.com>
898
  */
899
+ class StringDecrement extends Command
900
  {
901
  /**
902
  * {@inheritdoc}
903
  */
904
  public function getId()
905
  {
906
+ return 'DECR';
 
 
 
 
 
 
 
 
907
  }
908
  }
909
 
910
  /**
911
+ * @link http://redis.io/commands/decrby
912
+ *
913
  * @author Daniele Alessandri <suppakilla@gmail.com>
914
  */
915
+ class StringDecrementBy extends Command
916
  {
917
  /**
918
  * {@inheritdoc}
919
  */
920
  public function getId()
921
  {
922
+ return 'DECRBY';
923
  }
924
  }
925
 
926
  /**
927
+ * @link http://redis.io/commands/get
928
+ *
929
  * @author Daniele Alessandri <suppakilla@gmail.com>
930
  */
931
+ class StringGet extends Command
932
  {
933
  /**
934
  * {@inheritdoc}
935
  */
936
  public function getId()
937
  {
938
+ return 'GET';
939
  }
940
  }
941
 
942
  /**
943
+ * @link http://redis.io/commands/bitpos
944
+ *
945
  * @author Daniele Alessandri <suppakilla@gmail.com>
946
  */
947
+ class StringBitPos extends Command
948
  {
949
  /**
950
  * {@inheritdoc}
951
  */
952
  public function getId()
953
  {
954
+ return 'BITPOS';
955
  }
956
  }
957
 
958
  /**
959
+ * @link http://redis.io/commands/bitop
960
+ *
961
  * @author Daniele Alessandri <suppakilla@gmail.com>
962
  */
963
+ class StringBitOp extends Command
964
  {
965
  /**
966
  * {@inheritdoc}
967
  */
968
  public function getId()
969
  {
970
+ return 'BITOP';
971
  }
972
 
973
  /**
976
  protected function filterArguments(array $arguments)
977
  {
978
  if (count($arguments) === 3 && is_array($arguments[2])) {
979
+ list($operation, $destination) = $arguments;
980
+ $arguments = $arguments[2];
981
+ array_unshift($arguments, $operation, $destination);
982
  }
983
 
984
  return $arguments;
985
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
986
  }
987
 
988
  /**
989
+ * @link http://redis.io/commands/append
990
+ *
991
  * @author Daniele Alessandri <suppakilla@gmail.com>
992
  */
993
+ class StringAppend extends Command
994
  {
995
  /**
996
  * {@inheritdoc}
997
  */
998
  public function getId()
999
  {
1000
+ return 'APPEND';
1001
  }
1002
  }
1003
 
1004
  /**
1005
+ * @link http://redis.io/commands/bitcount
1006
+ *
1007
  * @author Daniele Alessandri <suppakilla@gmail.com>
1008
  */
1009
+ class StringBitCount extends Command
1010
  {
1011
  /**
1012
  * {@inheritdoc}
1013
  */
1014
  public function getId()
1015
  {
1016
+ return 'BITCOUNT';
1017
  }
1018
+ }
1019
 
1020
+ /**
1021
+ * @link http://redis.io/commands/getbit
1022
+ *
1023
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1024
+ */
1025
+ class StringGetBit extends Command
1026
+ {
1027
  /**
1028
  * {@inheritdoc}
1029
  */
1030
+ public function getId()
1031
  {
1032
+ return 'GETBIT';
 
 
 
 
 
 
1033
  }
1034
  }
1035
 
1036
  /**
1037
+ * @link http://redis.io/commands/mget
1038
+ *
1039
  * @author Daniele Alessandri <suppakilla@gmail.com>
1040
  */
1041
+ class StringGetMultiple extends Command
1042
  {
1043
  /**
1044
  * {@inheritdoc}
1045
  */
1046
  public function getId()
1047
  {
1048
+ return 'MGET';
1049
+ }
1050
+
1051
+ /**
1052
+ * {@inheritdoc}
1053
+ */
1054
+ protected function filterArguments(array $arguments)
1055
+ {
1056
+ return self::normalizeArguments($arguments);
1057
  }
1058
  }
1059
 
1060
  /**
1061
+ * @link http://redis.io/commands/incrbyfloat
1062
+ *
1063
  * @author Daniele Alessandri <suppakilla@gmail.com>
1064
  */
1065
+ class StringIncrementByFloat extends Command
1066
  {
1067
  /**
1068
  * {@inheritdoc}
1069
  */
1070
  public function getId()
1071
  {
1072
+ return 'INCRBYFLOAT';
1073
  }
1074
  }
1075
 
1076
  /**
1077
+ * @link http://redis.io/commands/psetex
1078
+ *
1079
  * @author Daniele Alessandri <suppakilla@gmail.com>
1080
  */
1081
+ class StringPreciseSetExpire extends StringSetExpire
1082
  {
1083
  /**
1084
  * {@inheritdoc}
1085
  */
1086
  public function getId()
1087
  {
1088
+ return 'PSETEX';
1089
  }
1090
  }
1091
 
1092
  /**
1093
+ * @link http://redis.io/commands/set
1094
+ *
1095
  * @author Daniele Alessandri <suppakilla@gmail.com>
1096
  */
1097
+ class StringSet extends Command
1098
  {
1099
  /**
1100
  * {@inheritdoc}
1101
  */
1102
  public function getId()
1103
  {
1104
+ return 'SET';
1105
  }
1106
  }
1107
 
1108
  /**
1109
+ * @link http://redis.io/commands/incrby
1110
+ *
1111
  * @author Daniele Alessandri <suppakilla@gmail.com>
1112
  */
1113
+ class StringIncrementBy extends Command
1114
  {
1115
  /**
1116
  * {@inheritdoc}
1117
  */
1118
  public function getId()
1119
  {
1120
+ return 'INCRBY';
1121
  }
1122
+ }
1123
 
1124
+ /**
1125
+ * @link http://redis.io/commands/incr
1126
+ *
1127
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1128
+ */
1129
+ class StringIncrement extends Command
1130
+ {
1131
  /**
1132
  * {@inheritdoc}
1133
  */
1134
+ public function getId()
1135
  {
1136
+ return 'INCR';
1137
  }
1138
  }
1139
 
1140
  /**
1141
+ * @link http://redis.io/commands/getrange
1142
+ *
1143
  * @author Daniele Alessandri <suppakilla@gmail.com>
1144
  */
1145
+ class StringGetRange extends Command
1146
  {
1147
  /**
1148
  * {@inheritdoc}
1149
  */
1150
  public function getId()
1151
  {
1152
+ return 'GETRANGE';
1153
  }
1154
  }
1155
 
1156
  /**
1157
+ * @link http://redis.io/commands/getset
1158
+ *
1159
  * @author Daniele Alessandri <suppakilla@gmail.com>
1160
  */
1161
+ class StringGetSet extends Command
1162
  {
1163
  /**
1164
  * {@inheritdoc}
1165
  */
1166
  public function getId()
1167
  {
1168
+ return 'GETSET';
1169
  }
1170
+ }
1171
 
1172
+ /**
1173
+ * @link http://redis.io/commands/sunionstore
1174
+ *
1175
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1176
+ */
1177
+ class SetUnionStore extends SetIntersectionStore
1178
+ {
1179
  /**
1180
  * {@inheritdoc}
1181
  */
1182
+ public function getId()
1183
  {
1184
+ return 'SUNIONSTORE';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1185
  }
1186
  }
1187
 
1188
  /**
1189
+ * @link http://redis.io/commands/sunion
1190
+ *
1191
  * @author Daniele Alessandri <suppakilla@gmail.com>
1192
  */
1193
+ class SetUnion extends SetIntersection
1194
  {
1195
  /**
1196
  * {@inheritdoc}
1197
  */
1198
  public function getId()
1199
  {
1200
+ return 'SUNION';
1201
  }
1202
  }
1203
 
1204
  /**
1205
+ * @link http://redis.io/commands/sdiff
1206
+ *
1207
  * @author Daniele Alessandri <suppakilla@gmail.com>
1208
  */
1209
+ class SetDifference extends SetIntersection
1210
  {
1211
  /**
1212
  * {@inheritdoc}
1213
  */
1214
  public function getId()
1215
  {
1216
+ return 'SDIFF';
1217
  }
1218
+ }
1219
 
1220
+ /**
1221
+ * @link http://redis.io/commands/sdiffstore
1222
+ *
1223
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1224
+ */
1225
+ class SetDifferenceStore extends SetIntersectionStore
1226
+ {
1227
  /**
1228
  * {@inheritdoc}
1229
  */
1230
+ public function getId()
1231
  {
1232
+ return 'SDIFFSTORE';
 
 
 
 
1233
  }
1234
  }
1235
 
1236
  /**
1237
+ * @link http://redis.io/commands/hget
1238
+ *
1239
  * @author Daniele Alessandri <suppakilla@gmail.com>
1240
  */
1241
+ class HashGet extends Command
1242
  {
1243
  /**
1244
  * {@inheritdoc}
1245
  */
1246
  public function getId()
1247
  {
1248
+ return 'HGET';
1249
  }
1250
  }
1251
 
1252
  /**
1253
+ * @link http://redis.io/commands/scard
1254
+ *
1255
  * @author Daniele Alessandri <suppakilla@gmail.com>
1256
  */
1257
+ class SetCardinality extends Command
1258
  {
1259
  /**
1260
  * {@inheritdoc}
1261
  */
1262
  public function getId()
1263
  {
1264
+ return 'SCARD';
1265
  }
1266
  }
1267
 
1268
  /**
1269
+ * @link http://redis.io/commands/sadd
1270
+ *
1271
  * @author Daniele Alessandri <suppakilla@gmail.com>
1272
  */
1273
+ class SetAdd extends Command
1274
  {
1275
  /**
1276
  * {@inheritdoc}
1277
  */
1278
  public function getId()
1279
  {
1280
+ return 'SADD';
1281
  }
1282
 
1283
  /**
1284
  * {@inheritdoc}
1285
  */
1286
+ protected function filterArguments(array $arguments)
1287
  {
1288
+ return self::normalizeVariadic($arguments);
1289
+ }
1290
+ }
 
1291
 
1292
+ /**
1293
+ * @link http://redis.io/commands/slowlog
1294
+ *
1295
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1296
+ */
1297
+ class ServerSlowlog extends Command
1298
+ {
1299
+ /**
1300
+ * {@inheritdoc}
1301
+ */
1302
+ public function getId()
1303
+ {
1304
+ return 'SLOWLOG';
1305
  }
1306
 
1307
  /**
1308
+ * {@inheritdoc}
 
 
 
 
1309
  */
1310
+ public function parseResponse($data)
1311
  {
1312
+ if (is_array($data)) {
1313
+ $log = array();
 
1314
 
1315
+ foreach ($data as $index => $entry) {
1316
+ $log[$index] = array(
1317
+ 'id' => $entry[0],
1318
+ 'timestamp' => $entry[1],
1319
+ 'duration' => $entry[2],
1320
+ 'command' => $entry[3],
1321
+ );
1322
  }
1323
 
1324
+ return $log;
1325
  }
1326
 
1327
+ return $data;
1328
  }
1329
  }
1330
 
1331
  /**
1332
+ * @link http://redis.io/commands/time
1333
+ *
1334
  * @author Daniele Alessandri <suppakilla@gmail.com>
1335
  */
1336
+ class ServerTime extends Command
1337
  {
1338
  /**
1339
  * {@inheritdoc}
1340
  */
1341
  public function getId()
1342
  {
1343
+ return 'TIME';
1344
  }
1345
+ }
1346
 
1347
+ /**
1348
+ * @link http://redis.io/commands/hexists
1349
+ *
1350
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1351
+ */
1352
+ class HashExists extends Command
1353
+ {
1354
  /**
1355
  * {@inheritdoc}
1356
  */
1357
+ public function getId()
1358
  {
1359
+ return 'HEXISTS';
 
 
 
 
 
1360
  }
1361
 
1362
  /**
1363
+ * {@inheritdoc}
 
 
 
 
1364
  */
1365
+ public function parseResponse($data)
1366
  {
1367
+ return (bool) $data;
1368
+ }
1369
+ }
 
 
 
 
1370
 
1371
+ /**
1372
+ * @link http://redis.io/commands/sismember
1373
+ *
1374
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1375
+ */
1376
+ class SetIsMember extends Command
1377
+ {
1378
+ /**
1379
+ * {@inheritdoc}
1380
+ */
1381
+ public function getId()
1382
+ {
1383
+ return 'SISMEMBER';
1384
  }
1385
 
1386
  /**
1388
  */
1389
  public function parseResponse($data)
1390
  {
1391
+ return (bool) $data;
 
 
 
 
 
 
 
 
 
 
 
1392
  }
1393
  }
1394
 
1395
  /**
1396
+ * @link http://redis.io/commands/srem
1397
+ *
1398
  * @author Daniele Alessandri <suppakilla@gmail.com>
1399
  */
1400
+ class SetRemove extends Command
1401
  {
1402
  /**
1403
  * {@inheritdoc}
1404
  */
1405
  public function getId()
1406
  {
1407
+ return 'SREM';
1408
  }
 
1409
 
 
 
 
 
 
 
1410
  /**
1411
  * {@inheritdoc}
1412
  */
1413
+ protected function filterArguments(array $arguments)
1414
  {
1415
+ return self::normalizeVariadic($arguments);
1416
  }
1417
  }
1418
 
1419
  /**
1420
+ * @link http://redis.io/commands/sscan
1421
+ *
1422
  * @author Daniele Alessandri <suppakilla@gmail.com>
1423
  */
1424
+ class SetScan extends Command
1425
  {
1426
  /**
1427
  * {@inheritdoc}
1428
  */
1429
  public function getId()
1430
  {
1431
+ return 'SSCAN';
1432
+ }
1433
+
1434
+ /**
1435
+ * {@inheritdoc}
1436
+ */
1437
+ protected function filterArguments(array $arguments)
1438
+ {
1439
+ if (count($arguments) === 3 && is_array($arguments[2])) {
1440
+ $options = $this->prepareOptions(array_pop($arguments));
1441
+ $arguments = array_merge($arguments, $options);
1442
+ }
1443
+
1444
+ return $arguments;
1445
+ }
1446
+
1447
+ /**
1448
+ * Returns a list of options and modifiers compatible with Redis.
1449
+ *
1450
+ * @param array $options List of options.
1451
+ *
1452
+ * @return array
1453
+ */
1454
+ protected function prepareOptions($options)
1455
+ {
1456
+ $options = array_change_key_case($options, CASE_UPPER);
1457
+ $normalized = array();
1458
+
1459
+ if (!empty($options['MATCH'])) {
1460
+ $normalized[] = 'MATCH';
1461
+ $normalized[] = $options['MATCH'];
1462
+ }
1463
+
1464
+ if (!empty($options['COUNT'])) {
1465
+ $normalized[] = 'COUNT';
1466
+ $normalized[] = $options['COUNT'];
1467
+ }
1468
+
1469
+ return $normalized;
1470
  }
1471
  }
1472
 
1473
  /**
1474
+ * @link http://redis.io/commands/srandmember
1475
+ *
1476
  * @author Daniele Alessandri <suppakilla@gmail.com>
1477
  */
1478
+ class SetRandomMember extends Command
1479
  {
1480
  /**
1481
  * {@inheritdoc}
1482
  */
1483
  public function getId()
1484
  {
1485
+ return 'SRANDMEMBER';
1486
  }
1487
  }
1488
 
1489
  /**
1490
+ * @link http://redis.io/commands/spop
1491
+ *
1492
  * @author Daniele Alessandri <suppakilla@gmail.com>
1493
  */
1494
+ class SetPop extends Command
1495
  {
1496
  /**
1497
  * {@inheritdoc}
1498
  */
1499
  public function getId()
1500
  {
1501
+ return 'SPOP';
1502
  }
1503
  }
1504
 
1505
  /**
1506
+ * @link http://redis.io/commands/smembers
1507
+ *
1508
  * @author Daniele Alessandri <suppakilla@gmail.com>
1509
  */
1510
+ class SetMembers extends Command
1511
  {
1512
  /**
1513
  * {@inheritdoc}
1514
  */
1515
  public function getId()
1516
  {
1517
+ return 'SMEMBERS';
1518
  }
1519
  }
1520
 
1521
  /**
1522
+ * @link http://redis.io/commands/smove
1523
+ *
1524
  * @author Daniele Alessandri <suppakilla@gmail.com>
1525
  */
1526
+ class SetMove extends Command
1527
  {
1528
  /**
1529
  * {@inheritdoc}
1530
  */
1531
  public function getId()
1532
  {
1533
+ return 'SMOVE';
1534
  }
1535
 
1536
  /**
1537
  * {@inheritdoc}
1538
  */
1539
+ public function parseResponse($data)
1540
  {
1541
+ return (bool) $data;
1542
  }
1543
  }
1544
 
1545
  /**
1546
+ * @link http://redis.io/commands/setbit
1547
+ *
1548
  * @author Daniele Alessandri <suppakilla@gmail.com>
1549
  */
1550
+ class StringSetBit extends Command
1551
  {
1552
  /**
1553
  * {@inheritdoc}
1554
  */
1555
  public function getId()
1556
  {
1557
+ return 'SETBIT';
1558
  }
1559
  }
1560
 
1561
  /**
1562
+ * @link http://redis.io/commands/hdel
1563
+ *
1564
  * @author Daniele Alessandri <suppakilla@gmail.com>
1565
  */
1566
+ class HashDelete extends Command
1567
  {
1568
  /**
1569
  * {@inheritdoc}
1570
  */
1571
  public function getId()
1572
  {
1573
+ return 'HDEL';
1574
  }
 
1575
 
 
 
 
 
 
 
1576
  /**
1577
  * {@inheritdoc}
1578
  */
1579
+ protected function filterArguments(array $arguments)
1580
  {
1581
+ return self::normalizeVariadic($arguments);
1582
  }
1583
  }
1584
 
1585
  /**
1586
+ * @link http://redis.io/commands/zrem
1587
+ *
1588
  * @author Daniele Alessandri <suppakilla@gmail.com>
1589
  */
1590
+ class ZSetRemove extends Command
1591
  {
1592
  /**
1593
  * {@inheritdoc}
1594
  */
1595
  public function getId()
1596
  {
1597
+ return 'ZREM';
1598
  }
 
1599
 
 
 
 
 
 
 
1600
  /**
1601
  * {@inheritdoc}
1602
  */
1603
+ protected function filterArguments(array $arguments)
1604
  {
1605
+ return self::normalizeVariadic($arguments);
1606
  }
1607
  }
1608
 
1609
  /**
1610
+ * @link http://redis.io/commands/zremrangebylex
1611
+ *
1612
  * @author Daniele Alessandri <suppakilla@gmail.com>
1613
  */
1614
+ class ZSetRemoveRangeByLex extends Command
1615
  {
1616
  /**
1617
  * {@inheritdoc}
1618
  */
1619
  public function getId()
1620
  {
1621
+ return 'ZREMRANGEBYLEX';
1622
  }
1623
  }
1624
 
1625
  /**
1626
+ * @link http://redis.io/commands/zremrangebyrank
1627
+ *
1628
  * @author Daniele Alessandri <suppakilla@gmail.com>
1629
  */
1630
+ class ZSetRemoveRangeByRank extends Command
1631
  {
1632
  /**
1633
  * {@inheritdoc}
1634
  */
1635
  public function getId()
1636
  {
1637
+ return 'ZREMRANGEBYRANK';
1638
  }
1639
  }
1640
 
1641
  /**
1642
+ * @link http://redis.io/commands/zrank
1643
+ *
1644
  * @author Daniele Alessandri <suppakilla@gmail.com>
1645
  */
1646
+ class ZSetRank extends Command
1647
  {
1648
  /**
1649
  * {@inheritdoc}
1650
  */
1651
  public function getId()
1652
  {
1653
+ return 'ZRANK';
1654
  }
1655
+ }
1656
 
1657
+ /**
1658
+ * @link http://redis.io/commands/echo
1659
+ *
1660
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1661
+ */
1662
+ class ConnectionEcho extends Command
1663
+ {
1664
  /**
1665
  * {@inheritdoc}
1666
  */
1667
+ public function getId()
1668
  {
1669
+ return 'ECHO';
1670
  }
1671
  }
1672
 
1673
  /**
1674
+ * @link http://redis.io/commands/quit
1675
+ *
1676
  * @author Daniele Alessandri <suppakilla@gmail.com>
1677
  */
1678
+ class ConnectionQuit extends Command
1679
  {
1680
  /**
1681
  * {@inheritdoc}
1682
  */
1683
  public function getId()
1684
  {
1685
+ return 'QUIT';
1686
  }
1687
+ }
1688
 
1689
+ /**
1690
+ * @link http://redis.io/commands/ping
1691
+ *
1692
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1693
+ */
1694
+ class ConnectionPing extends Command
1695
+ {
1696
  /**
1697
  * {@inheritdoc}
1698
  */
1699
+ public function getId()
1700
  {
1701
+ return 'PING';
1702
  }
1703
  }
1704
 
1705
  /**
1706
+ * @link http://redis.io/commands/zremrangebyscore
1707
+ *
1708
  * @author Daniele Alessandri <suppakilla@gmail.com>
1709
  */
1710
+ class ZSetRemoveRangeByScore extends Command
1711
  {
1712
  /**
1713
  * {@inheritdoc}
1714
  */
1715
  public function getId()
1716
  {
1717
+ return 'ZREMRANGEBYSCORE';
1718
  }
1719
  }
1720
 
1721
  /**
1722
+ * @link http://redis.io/commands/zrevrange
1723
+ *
1724
  * @author Daniele Alessandri <suppakilla@gmail.com>
1725
  */
1726
+ class ZSetReverseRange extends ZSetRange
1727
  {
1728
  /**
1729
  * {@inheritdoc}
1730
  */
1731
  public function getId()
1732
  {
1733
+ return 'ZREVRANGE';
1734
  }
1735
  }
1736
 
1737
  /**
1738
+ * @link http://redis.io/commands/zscore
1739
+ *
1740
  * @author Daniele Alessandri <suppakilla@gmail.com>
1741
  */
1742
+ class ZSetScore extends Command
1743
  {
1744
  /**
1745
  * {@inheritdoc}
1746
  */
1747
  public function getId()
1748
  {
1749
+ return 'ZSCORE';
1750
  }
1751
  }
1752
 
1753
  /**
1754
+ * @link http://redis.io/commands/auth
1755
+ *
1756
  * @author Daniele Alessandri <suppakilla@gmail.com>
1757
  */
1758
+ class ConnectionAuth extends Command
1759
  {
1760
  /**
1761
  * {@inheritdoc}
1762
  */
1763
  public function getId()
1764
  {
1765
+ return 'AUTH';
1766
  }
1767
  }
1768
 
1769
  /**
1770
+ * @link http://redis.io/commands/zscan
1771
+ *
1772
  * @author Daniele Alessandri <suppakilla@gmail.com>
1773
  */
1774
+ class ZSetScan extends Command
1775
  {
1776
  /**
1777
  * {@inheritdoc}
1778
  */
1779
  public function getId()
1780
  {
1781
+ return 'ZSCAN';
1782
  }
1783
 
1784
  /**
1786
  */
1787
  protected function filterArguments(array $arguments)
1788
  {
1789
+ if (count($arguments) === 3 && is_array($arguments[2])) {
1790
+ $options = $this->prepareOptions(array_pop($arguments));
1791
+ $arguments = array_merge($arguments, $options);
 
 
 
 
 
 
1792
  }
1793
 
1794
  return $arguments;
1795
  }
 
1796
 
 
 
 
 
 
 
1797
  /**
1798
+ * Returns a list of options and modifiers compatible with Redis.
1799
+ *
1800
+ * @param array $options List of options.
1801
+ *
1802
+ * @return array
1803
  */
1804
+ protected function prepareOptions($options)
1805
  {
1806
+ $options = array_change_key_case($options, CASE_UPPER);
1807
+ $normalized = array();
1808
+
1809
+ if (!empty($options['MATCH'])) {
1810
+ $normalized[] = 'MATCH';
1811
+ $normalized[] = $options['MATCH'];
1812
+ }
1813
+
1814
+ if (!empty($options['COUNT'])) {
1815
+ $normalized[] = 'COUNT';
1816
+ $normalized[] = $options['COUNT'];
1817
+ }
1818
+
1819
+ return $normalized;
1820
  }
1821
 
1822
  /**
1823
  * {@inheritdoc}
1824
  */
1825
+ public function parseResponse($data)
1826
  {
1827
+ if (is_array($data)) {
1828
+ $members = $data[1];
1829
+ $result = array();
1830
+
1831
+ for ($i = 0; $i < count($members); ++$i) {
1832
+ $result[$members[$i]] = (float) $members[++$i];
1833
+ }
1834
+
1835
+ $data[1] = $result;
1836
  }
1837
 
1838
+ return $data;
1839
  }
1840
  }
1841
 
1842
  /**
1843
+ * @link http://redis.io/commands/zrevrank
1844
+ *
1845
  * @author Daniele Alessandri <suppakilla@gmail.com>
1846
  */
1847
+ class ZSetReverseRank extends Command
1848
  {
1849
  /**
1850
  * {@inheritdoc}
1851
  */
1852
  public function getId()
1853
  {
1854
+ return 'ZREVRANK';
1855
  }
1856
  }
1857
 
1858
+ class ZSetReverseRangeByLex extends ZSetRangeByLex
 
 
 
 
1859
  {
1860
  /**
1861
  * {@inheritdoc}
1862
  */
1863
  public function getId()
1864
  {
1865
+ return 'ZREVRANGEBYLEX';
1866
  }
1867
  }
1868
 
1869
  /**
1870
+ * @link http://redis.io/commands/zrevrangebyscore
1871
+ *
1872
  * @author Daniele Alessandri <suppakilla@gmail.com>
1873
  */
1874
+ class ZSetReverseRangeByScore extends ZSetRangeByScore
1875
  {
1876
  /**
1877
  * {@inheritdoc}
1878
  */
1879
  public function getId()
1880
  {
1881
+ return 'ZREVRANGEBYSCORE';
1882
  }
1883
+ }
1884
 
1885
+ /**
1886
+ * @link http://redis.io/commands/zlexcount
1887
+ *
1888
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1889
+ */
1890
+ class ZSetLexCount extends Command
1891
+ {
1892
  /**
1893
  * {@inheritdoc}
1894
  */
1895
+ public function getId()
1896
  {
1897
+ return 'ZLEXCOUNT';
 
 
 
 
 
 
 
 
 
 
 
1898
  }
1899
+ }
1900
 
1901
+ /**
1902
+ * @link http://redis.io/commands/zinterstore
1903
+ *
1904
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1905
+ */
1906
+ class ZSetIntersectionStore extends ZSetUnionStore
1907
+ {
1908
  /**
1909
  * {@inheritdoc}
1910
  */
1911
+ public function getId()
1912
  {
1913
+ return 'ZINTERSTORE';
1914
  }
1915
  }
1916
 
1917
  /**
1918
+ * @link http://redis.io/commands/strlen
1919
+ *
1920
  * @author Daniele Alessandri <suppakilla@gmail.com>
1921
  */
1922
+ class StringStrlen extends Command
1923
  {
1924
  /**
1925
  * {@inheritdoc}
1926
  */
1927
  public function getId()
1928
  {
1929
+ return 'STRLEN';
1930
  }
1931
  }
1932
 
1933
  /**
1934
+ * @link http://redis.io/commands/substr
1935
+ *
1936
  * @author Daniele Alessandri <suppakilla@gmail.com>
1937
  */
1938
+ class StringSubstr extends Command
1939
  {
1940
  /**
1941
  * {@inheritdoc}
1942
  */
1943
  public function getId()
1944
  {
1945
+ return 'SUBSTR';
1946
  }
1947
+ }
1948
 
1949
+ /**
1950
+ * @link http://redis.io/commands/discard
1951
+ *
1952
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1953
+ */
1954
+ class TransactionDiscard extends Command
1955
+ {
1956
  /**
1957
  * {@inheritdoc}
1958
  */
1959
+ public function getId()
1960
  {
1961
+ return 'DISCARD';
1962
  }
1963
  }
1964
 
1965
  /**
1966
+ * @link http://redis.io/commands/setrange
1967
+ *
1968
  * @author Daniele Alessandri <suppakilla@gmail.com>
1969
  */
1970
+ class StringSetRange extends Command
1971
  {
1972
  /**
1973
  * {@inheritdoc}
1974
  */
1975
  public function getId()
1976
  {
1977
+ return 'SETRANGE';
1978
  }
1979
  }
1980
 
1981
  /**
1982
+ * @link http://redis.io/commands/setnx
1983
+ *
1984
  * @author Daniele Alessandri <suppakilla@gmail.com>
1985
  */
1986
+ class StringSetPreserve extends Command
1987
  {
1988
  /**
1989
  * {@inheritdoc}
1990
  */
1991
  public function getId()
1992
  {
1993
+ return 'SETNX';
1994
  }
1995
 
1996
  /**
1997
  * {@inheritdoc}
1998
  */
1999
+ public function parseResponse($data)
2000
  {
2001
+ return (bool) $data;
2002
  }
2003
  }
2004
 
2005
  /**
2006
+ * @link http://redis.io/commands/select
2007
+ *
2008
  * @author Daniele Alessandri <suppakilla@gmail.com>
2009
  */
2010
+ class ConnectionSelect extends Command
2011
  {
2012
  /**
2013
  * {@inheritdoc}
2014
  */
2015
  public function getId()
2016
  {
2017
+ return 'SELECT';
2018
  }
2019
  }
2020
 
2021
  /**
2022
+ * @link http://redis.io/commands/msetnx
2023
+ *
2024
  * @author Daniele Alessandri <suppakilla@gmail.com>
2025
  */
2026
+ class StringSetMultiplePreserve extends StringSetMultiple
2027
  {
2028
  /**
2029
  * {@inheritdoc}
2030
  */
2031
  public function getId()
2032
  {
2033
+ return 'MSETNX';
2034
  }
 
2035
 
 
 
 
 
 
 
2036
  /**
2037
  * {@inheritdoc}
2038
  */
2039
+ public function parseResponse($data)
2040
  {
2041
+ return (bool) $data;
2042
  }
2043
  }
2044
 
2045
  /**
2046
+ * @link http://redis.io/commands/exec
2047
+ *
2048
  * @author Daniele Alessandri <suppakilla@gmail.com>
2049
  */
2050
+ class TransactionExec extends Command
2051
  {
2052
  /**
2053
  * {@inheritdoc}
2054
  */
2055
  public function getId()
2056
  {
2057
+ return 'EXEC';
2058
  }
2059
  }
2060
 
2061
  /**
2062
+ * @link http://redis.io/commands/multi
2063
+ *
2064
  * @author Daniele Alessandri <suppakilla@gmail.com>
2065
  */
2066
+ class TransactionMulti extends Command
2067
  {
2068
  /**
2069
  * {@inheritdoc}
2070
  */
2071
  public function getId()
2072
  {
2073
+ return 'MULTI';
2074
  }
2075
  }
2076
 
2077
  /**
2078
+ * @link http://redis.io/commands/zcount
2079
+ *
2080
  * @author Daniele Alessandri <suppakilla@gmail.com>
2081
  */
2082
+ class ZSetCount extends Command
2083
  {
2084
  /**
2085
  * {@inheritdoc}
2086
  */
2087
  public function getId()
2088
  {
2089
+ return 'ZCOUNT';
2090
  }
2091
  }
2092
 
2093
  /**
2094
+ * @link http://redis.io/commands/zincrby
2095
+ *
2096
  * @author Daniele Alessandri <suppakilla@gmail.com>
2097
  */
2098
+ class ZSetIncrementBy extends Command
2099
  {
2100
  /**
2101
  * {@inheritdoc}
2102
  */
2103
  public function getId()
2104
  {
2105
+ return 'ZINCRBY';
2106
  }
2107
  }
2108
 
2109
  /**
2110
+ * @link http://redis.io/commands/zcard
2111
+ *
2112
  * @author Daniele Alessandri <suppakilla@gmail.com>
2113
  */
2114
+ class ZSetCardinality extends Command
2115
  {
2116
  /**
2117
  * {@inheritdoc}
2118
  */
2119
  public function getId()
2120
  {
2121
+ return 'ZCARD';
2122
  }
2123
  }
2124
 
2125
  /**
2126
+ * @link http://redis.io/commands/zadd
2127
+ *
2128
  * @author Daniele Alessandri <suppakilla@gmail.com>
2129
  */
2130
+ class ZSetAdd extends Command
2131
  {
2132
  /**
2133
  * {@inheritdoc}
2134
  */
2135
  public function getId()
2136
  {
2137
+ return 'ZADD';
2138
  }
 
2139
 
 
 
 
 
 
 
2140
  /**
2141
  * {@inheritdoc}
2142
  */
2143
+ protected function filterArguments(array $arguments)
2144
  {
2145
+ if (is_array(end($arguments))) {
2146
+ foreach (array_pop($arguments) as $member => $score) {
2147
+ $arguments[] = $score;
2148
+ $arguments[] = $member;
2149
+ }
2150
+ }
2151
+
2152
+ return $arguments;
2153
  }
2154
  }
2155
 
2156
  /**
2157
+ * @link http://redis.io/commands/unwatch
2158
+ *
2159
  * @author Daniele Alessandri <suppakilla@gmail.com>
2160
  */
2161
+ class TransactionUnwatch extends Command
2162
  {
2163
  /**
2164
  * {@inheritdoc}
2165
  */
2166
  public function getId()
2167
  {
2168
+ return 'UNWATCH';
2169
  }
2170
  }
2171
 
2172
  /**
2173
+ * @link http://redis.io/commands/watch
2174
+ *
2175
  * @author Daniele Alessandri <suppakilla@gmail.com>
2176
  */
2177
+ class TransactionWatch extends Command
2178
  {
2179
  /**
2180
  * {@inheritdoc}
2181
  */
2182
  public function getId()
2183
  {
2184
+ return 'WATCH';
2185
  }
 
2186
 
 
 
 
 
 
 
2187
  /**
2188
  * {@inheritdoc}
2189
  */
2190
+ protected function filterArguments(array $arguments)
2191
  {
2192
+ if (isset($arguments[0]) && is_array($arguments[0])) {
2193
+ return $arguments[0];
2194
+ }
2195
+
2196
+ return $arguments;
2197
+ }
2198
  }
2199
 
2200
  /**
2201
+ * @link http://redis.io/commands/slaveof
2202
+ *
2203
  * @author Daniele Alessandri <suppakilla@gmail.com>
2204
  */
2205
+ class ServerSlaveOf extends Command
2206
  {
2207
  /**
2208
  * {@inheritdoc}
2209
  */
2210
  public function getId()
2211
  {
2212
+ return 'SLAVEOF';
2213
  }
2214
 
2215
  /**
2217
  */
2218
  protected function filterArguments(array $arguments)
2219
  {
2220
+ if (count($arguments) === 0 || $arguments[0] === 'NO ONE') {
2221
+ return array('NO', 'ONE');
2222
+ }
2223
+
2224
+ return $arguments;
2225
  }
2226
  }
2227
 
2228
  /**
2229
+ * @link http://redis.io/commands/shutdown
2230
+ *
2231
  * @author Daniele Alessandri <suppakilla@gmail.com>
2232
  */
2233
+ class ServerShutdown extends Command
2234
  {
2235
  /**
2236
  * {@inheritdoc}
2237
  */
2238
  public function getId()
2239
  {
2240
+ return 'SHUTDOWN';
2241
  }
2242
  }
2243
 
2244
  /**
2245
+ * @link http://redis.io/commands/hset
2246
+ *
2247
  * @author Daniele Alessandri <suppakilla@gmail.com>
2248
  */
2249
+ class HashSet extends Command
2250
  {
2251
  /**
2252
  * {@inheritdoc}
2253
  */
2254
  public function getId()
2255
  {
2256
+ return 'HSET';
2257
  }
2258
 
2259
  /**
2266
  }
2267
 
2268
  /**
2269
+ * @link http://redis.io/commands/type
2270
+ *
2271
  * @author Daniele Alessandri <suppakilla@gmail.com>
2272
  */
2273
+ class KeyType extends Command
2274
  {
2275
  /**
2276
  * {@inheritdoc}
2277
  */
2278
  public function getId()
2279
  {
2280
+ return 'TYPE';
2281
  }
2282
+ }
2283
 
2284
+ /**
2285
+ * @link http://redis.io/commands/lindex
2286
+ *
2287
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2288
+ */
2289
+ class ListIndex extends Command
2290
+ {
2291
  /**
2292
  * {@inheritdoc}
2293
  */
2294
+ public function getId()
2295
  {
2296
+ return 'LINDEX';
2297
  }
2298
  }
2299
 
2300
  /**
2301
+ * @link http://redis.io/commands/sort
2302
+ *
2303
  * @author Daniele Alessandri <suppakilla@gmail.com>
2304
  */
2305
+ class KeySort extends Command
2306
  {
2307
  /**
2308
  * {@inheritdoc}
2309
  */
2310
  public function getId()
2311
  {
2312
+ return 'SORT';
2313
  }
2314
 
2315
  /**
2317
  */
2318
  protected function filterArguments(array $arguments)
2319
  {
2320
+ if (count($arguments) === 1) {
2321
+ return $arguments;
2322
+ }
2323
+
2324
+ $query = array($arguments[0]);
2325
+ $sortParams = array_change_key_case($arguments[1], CASE_UPPER);
2326
+
2327
+ if (isset($sortParams['BY'])) {
2328
+ $query[] = 'BY';
2329
+ $query[] = $sortParams['BY'];
2330
+ }
2331
+
2332
+ if (isset($sortParams['GET'])) {
2333
+ $getargs = $sortParams['GET'];
2334
+
2335
+ if (is_array($getargs)) {
2336
+ foreach ($getargs as $getarg) {
2337
+ $query[] = 'GET';
2338
+ $query[] = $getarg;
2339
+ }
2340
+ } else {
2341
+ $query[] = 'GET';
2342
+ $query[] = $getargs;
2343
+ }
2344
+ }
2345
+
2346
+ if (isset($sortParams['LIMIT']) &&
2347
+ is_array($sortParams['LIMIT']) &&
2348
+ count($sortParams['LIMIT']) == 2) {
2349
+ $query[] = 'LIMIT';
2350
+ $query[] = $sortParams['LIMIT'][0];
2351
+ $query[] = $sortParams['LIMIT'][1];
2352
+ }
2353
+
2354
+ if (isset($sortParams['SORT'])) {
2355
+ $query[] = strtoupper($sortParams['SORT']);
2356
+ }
2357
+
2358
+ if (isset($sortParams['ALPHA']) && $sortParams['ALPHA'] == true) {
2359
+ $query[] = 'ALPHA';
2360
+ }
2361
+
2362
+ if (isset($sortParams['STORE'])) {
2363
+ $query[] = 'STORE';
2364
+ $query[] = $sortParams['STORE'];
2365
+ }
2366
+
2367
+ return $query;
2368
  }
2369
  }
2370
 
2371
  /**
2372
+ * @link http://redis.io/commands/scan
2373
+ *
2374
  * @author Daniele Alessandri <suppakilla@gmail.com>
2375
  */
2376
+ class KeyScan extends Command
2377
  {
2378
  /**
2379
  * {@inheritdoc}
2380
  */
2381
  public function getId()
2382
  {
2383
+ return 'SCAN';
2384
  }
 
2385
 
 
 
 
 
 
 
2386
  /**
2387
  * {@inheritdoc}
2388
  */
2389
+ protected function filterArguments(array $arguments)
2390
  {
2391
+ if (count($arguments) === 2 && is_array($arguments[1])) {
2392
+ $options = $this->prepareOptions(array_pop($arguments));
2393
+ $arguments = array_merge($arguments, $options);
2394
+ }
2395
+
2396
+ return $arguments;
2397
+ }
2398
+
2399
+ /**
2400
+ * Returns a list of options and modifiers compatible with Redis.
2401
+ *
2402
+ * @param array $options List of options.
2403
+ *
2404
+ * @return array
2405
+ */
2406
+ protected function prepareOptions($options)
2407
+ {
2408
+ $options = array_change_key_case($options, CASE_UPPER);
2409
+ $normalized = array();
2410
+
2411
+ if (!empty($options['MATCH'])) {
2412
+ $normalized[] = 'MATCH';
2413
+ $normalized[] = $options['MATCH'];
2414
+ }
2415
+
2416
+ if (!empty($options['COUNT'])) {
2417
+ $normalized[] = 'COUNT';
2418
+ $normalized[] = $options['COUNT'];
2419
+ }
2420
+
2421
+ return $normalized;
2422
  }
2423
+ }
2424
 
2425
+ /**
2426
+ * @link http://redis.io/commands/renamenx
2427
+ *
2428
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2429
+ */
2430
+ class KeyRenamePreserve extends KeyRename
2431
+ {
2432
  /**
2433
  * {@inheritdoc}
2434
  */
2435
+ public function getId()
2436
  {
2437
+ return 'RENAMENX';
2438
  }
2439
 
2440
  /**
2447
  }
2448
 
2449
  /**
2450
+ * @link http://redis.io/commands/restore
2451
+ *
2452
  * @author Daniele Alessandri <suppakilla@gmail.com>
2453
  */
2454
+ class KeyRestore extends Command
2455
  {
2456
  /**
2457
  * {@inheritdoc}
2458
  */
2459
  public function getId()
2460
  {
2461
+ return 'RESTORE';
2462
  }
2463
  }
2464
 
2465
  /**
2466
+ * @link http://redis.io/commands/linsert
2467
+ *
2468
  * @author Daniele Alessandri <suppakilla@gmail.com>
2469
  */
2470
+ class ListInsert extends Command
2471
  {
2472
  /**
2473
  * {@inheritdoc}
2474
  */
2475
  public function getId()
2476
  {
2477
+ return 'LINSERT';
 
 
 
 
 
 
 
 
2478
  }
2479
  }
2480
 
2481
  /**
2482
+ * @link http://redis.io/commands/llen
2483
+ *
2484
  * @author Daniele Alessandri <suppakilla@gmail.com>
2485
  */
2486
+ class ListLength extends Command
2487
  {
2488
  /**
2489
  * {@inheritdoc}
2490
  */
2491
  public function getId()
2492
  {
2493
+ return 'LLEN';
2494
  }
2495
+ }
2496
 
2497
+ /**
2498
+ * @link http://redis.io/commands/rpoplpush
2499
+ *
2500
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2501
+ */
2502
+ class ListPopLastPushHead extends Command
2503
+ {
2504
  /**
2505
  * {@inheritdoc}
2506
  */
2507
+ public function getId()
2508
  {
2509
+ return 'RPOPLPUSH';
2510
  }
2511
  }
2512
 
2513
  /**
2514
+ * @link http://redis.io/commands/brpoplpush
2515
+ *
2516
  * @author Daniele Alessandri <suppakilla@gmail.com>
2517
  */
2518
+ class ListPopLastPushHeadBlocking extends Command
2519
  {
2520
  /**
2521
  * {@inheritdoc}
2522
  */
2523
  public function getId()
2524
  {
2525
+ return 'BRPOPLPUSH';
2526
  }
2527
+ }
2528
 
2529
+ /**
2530
+ * @link http://redis.io/commands/lpush
2531
+ *
2532
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2533
+ */
2534
+ class ListPushHead extends ListPushTail
2535
+ {
2536
  /**
2537
  * {@inheritdoc}
2538
  */
2539
+ public function getId()
2540
  {
2541
+ return 'LPUSH';
2542
  }
2543
  }
2544
 
2545
  /**
2546
+ * @link http://redis.io/commands/brpop
2547
+ *
2548
  * @author Daniele Alessandri <suppakilla@gmail.com>
2549
  */
2550
+ class ListPopLastBlocking extends ListPopFirstBlocking
2551
  {
2552
  /**
2553
  * {@inheritdoc}
2554
  */
2555
  public function getId()
2556
  {
2557
+ return 'BRPOP';
2558
  }
2559
  }
2560
 
2561
  /**
2562
+ * @link http://redis.io/commands/rpop
2563
+ *
2564
  * @author Daniele Alessandri <suppakilla@gmail.com>
2565
  */
2566
+ class ListPopLast extends Command
2567
  {
2568
  /**
2569
  * {@inheritdoc}
2570
  */
2571
  public function getId()
2572
  {
2573
+ return 'RPOP';
2574
  }
2575
  }
2576
 
2577
  /**
2578
+ * @link http://redis.io/commands/lpop
2579
+ *
2580
  * @author Daniele Alessandri <suppakilla@gmail.com>
2581
  */
2582
+ class ListPopFirst extends Command
2583
  {
2584
  /**
2585
  * {@inheritdoc}
2586
  */
2587
  public function getId()
2588
  {
2589
+ return 'LPOP';
2590
  }
2591
  }
2592
 
2593
  /**
2594
+ * @link http://redis.io/commands/hscan
2595
+ *
2596
  * @author Daniele Alessandri <suppakilla@gmail.com>
2597
  */
2598
+ class HashScan extends Command
2599
  {
2600
  /**
2601
  * {@inheritdoc}
2602
  */
2603
  public function getId()
2604
  {
2605
+ return 'HSCAN';
2606
  }
2607
 
2608
  /**
2609
  * {@inheritdoc}
2610
  */
2611
+ protected function filterArguments(array $arguments)
2612
  {
2613
+ if (count($arguments) === 3 && is_array($arguments[2])) {
2614
+ $options = $this->prepareOptions(array_pop($arguments));
2615
+ $arguments = array_merge($arguments, $options);
2616
+ }
2617
 
2618
+ return $arguments;
 
 
 
 
 
 
 
 
 
 
 
2619
  }
 
2620
 
 
 
 
 
 
 
2621
  /**
2622
+ * Returns a list of options and modifiers compatible with Redis.
2623
+ *
2624
+ * @param array $options List of options.
2625
+ *
2626
+ * @return array
2627
  */
2628
+ protected function prepareOptions($options)
2629
  {
2630
+ $options = array_change_key_case($options, CASE_UPPER);
2631
+ $normalized = array();
2632
+
2633
+ if (!empty($options['MATCH'])) {
2634
+ $normalized[] = 'MATCH';
2635
+ $normalized[] = $options['MATCH'];
2636
+ }
2637
+
2638
+ if (!empty($options['COUNT'])) {
2639
+ $normalized[] = 'COUNT';
2640
+ $normalized[] = $options['COUNT'];
2641
+ }
2642
+
2643
+ return $normalized;
2644
  }
2645
 
2646
  /**
2648
  */
2649
  public function parseResponse($data)
2650
  {
2651
+ if (is_array($data)) {
2652
+ $fields = $data[1];
2653
+ $result = array();
2654
+
2655
+ for ($i = 0; $i < count($fields); ++$i) {
2656
+ $result[$fields[$i]] = $fields[++$i];
2657
+ }
2658
+
2659
+ $data[1] = $result;
2660
+ }
2661
+
2662
+ return $data;
2663
  }
2664
  }
2665
 
2666
  /**
2667
  * @link http://redis.io/commands/hmset
2668
+ *
2669
  * @author Daniele Alessandri <suppakilla@gmail.com>
2670
  */
2671
  class HashSetMultiple extends Command
2700
  }
2701
 
2702
  /**
2703
+ * @link http://redis.io/commands/randomkey
2704
+ *
2705
  * @author Daniele Alessandri <suppakilla@gmail.com>
2706
  */
2707
+ class KeyRandom extends Command
2708
  {
2709
  /**
2710
  * {@inheritdoc}
2711
  */
2712
  public function getId()
2713
  {
2714
+ return 'RANDOMKEY';
2715
  }
 
2716
 
 
 
 
 
 
 
2717
  /**
2718
  * {@inheritdoc}
2719
  */
2720
+ public function parseResponse($data)
2721
  {
2722
+ return $data !== '' ? $data : null;
2723
  }
2724
+ }
2725
 
2726
+ /**
2727
+ * @link http://redis.io/commands/dump
2728
+ *
2729
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2730
+ */
2731
+ class KeyDump extends Command
2732
+ {
2733
  /**
2734
  * {@inheritdoc}
2735
  */
2736
+ public function getId()
2737
  {
2738
+ return 'DUMP';
2739
  }
2740
  }
2741
 
2742
  /**
2743
+ * @link http://redis.io/commands/exists
2744
+ *
2745
  * @author Daniele Alessandri <suppakilla@gmail.com>
2746
  */
2747
+ class KeyExists extends Command
2748
  {
2749
  /**
2750
  * {@inheritdoc}
2751
  */
2752
  public function getId()
2753
  {
2754
+ return 'EXISTS';
2755
  }
2756
 
2757
  /**
2764
  }
2765
 
2766
  /**
2767
+ * @link http://redis.io/commands/hstrlen
2768
+ *
2769
  * @author Daniele Alessandri <suppakilla@gmail.com>
2770
  */
2771
+ class HashStringLength extends Command
2772
  {
2773
  /**
2774
  * {@inheritdoc}
2775
  */
2776
  public function getId()
2777
  {
2778
+ return 'HSTRLEN';
2779
  }
2780
  }
2781
 
2782
  /**
2783
+ * @link http://redis.io/commands/del
2784
+ *
2785
  * @author Daniele Alessandri <suppakilla@gmail.com>
2786
  */
2787
+ class KeyDelete extends Command
2788
  {
2789
  /**
2790
  * {@inheritdoc}
2791
  */
2792
  public function getId()
2793
  {
2794
+ return 'DEL';
2795
  }
 
2796
 
 
 
 
 
 
 
2797
  /**
2798
  * {@inheritdoc}
2799
  */
2800
+ protected function filterArguments(array $arguments)
2801
  {
2802
+ return self::normalizeArguments($arguments);
2803
  }
2804
  }
2805
 
2806
  /**
2807
+ * @link http://redis.io/commands/pfmerge
2808
+ *
2809
  * @author Daniele Alessandri <suppakilla@gmail.com>
2810
  */
2811
+ class HyperLogLogMerge extends Command
2812
  {
2813
  /**
2814
  * {@inheritdoc}
2815
  */
2816
  public function getId()
2817
  {
2818
+ return 'PFMERGE';
2819
  }
 
2820
 
 
 
 
 
 
 
2821
  /**
2822
  * {@inheritdoc}
2823
  */
2824
+ protected function filterArguments(array $arguments)
2825
  {
2826
+ return self::normalizeArguments($arguments);
2827
  }
2828
  }
2829
 
2830
  /**
2831
+ * @link http://redis.io/commands/pfadd
2832
+ *
2833
  * @author Daniele Alessandri <suppakilla@gmail.com>
2834
  */
2835
+ class HyperLogLogAdd extends Command
2836
  {
2837
  /**
2838
  * {@inheritdoc}
2839
  */
2840
  public function getId()
2841
  {
2842
+ return 'PFADD';
2843
  }
2844
 
2845
  /**
2846
  * {@inheritdoc}
2847
  */
2848
+ protected function filterArguments(array $arguments)
2849
  {
2850
+ return self::normalizeVariadic($arguments);
 
 
 
 
 
 
2851
  }
 
2852
 
 
 
 
 
 
 
2853
  /**
2854
  * {@inheritdoc}
2855
  */
2856
+ public function parseResponse($data)
2857
  {
2858
+ return (bool) $data;
2859
  }
2860
  }
2861
 
2862
  /**
2863
+ * @link http://redis.io/commands/pfcount
2864
+ *
2865
  * @author Daniele Alessandri <suppakilla@gmail.com>
2866
  */
2867
+ class HyperLogLogCount extends Command
2868
  {
2869
  /**
2870
  * {@inheritdoc}
2871
  */
2872
  public function getId()
2873
  {
2874
+ return 'PFCOUNT';
2875
  }
2876
 
2877
  /**
2879
  */
2880
  protected function filterArguments(array $arguments)
2881
  {
2882
+ return self::normalizeArguments($arguments);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2883
  }
2884
  }
2885
 
2886
  /**
2887
+ * @link http://redis.io/commands/hsetnx
2888
+ *
2889
  * @author Daniele Alessandri <suppakilla@gmail.com>
2890
  */
2891
+ class HashSetPreserve extends Command
2892
  {
2893
  /**
2894
  * {@inheritdoc}
2895
  */
2896
  public function getId()
2897
  {
2898
+ return 'HSETNX';
2899
  }
2900
 
2901
  /**
2908
  }
2909
 
2910
  /**
2911
+ * @link http://redis.io/commands/keys
2912
+ *
2913
  * @author Daniele Alessandri <suppakilla@gmail.com>
2914
  */
2915
+ class KeyKeys extends Command
2916
  {
2917
  /**
2918
  * {@inheritdoc}
2919
  */
2920
  public function getId()
2921
  {
2922
+ return 'KEYS';
2923
  }
2924
  }
2925
 
2926
  /**
2927
+ * @link http://redis.io/commands/pexpireat
2928
+ *
2929
  * @author Daniele Alessandri <suppakilla@gmail.com>
2930
  */
2931
+ class KeyPreciseExpireAt extends KeyExpireAt
2932
  {
2933
  /**
2934
  * {@inheritdoc}
2935
  */
2936
  public function getId()
2937
  {
2938
+ return 'PEXPIREAT';
2939
  }
2940
  }
2941
 
2942
  /**
2943
+ * @link http://redis.io/commands/pttl
2944
+ *
2945
  * @author Daniele Alessandri <suppakilla@gmail.com>
2946
  */
2947
+ class KeyPreciseTimeToLive extends KeyTimeToLive
2948
  {
2949
  /**
2950
  * {@inheritdoc}
2951
  */
2952
  public function getId()
2953
  {
2954
+ return 'PTTL';
2955
  }
2956
+ }
 
 
 
 
 
 
 
 
2957
 
2958
  /**
2959
+ * @link http://redis.io/commands/pexpire
2960
+ *
2961
  * @author Daniele Alessandri <suppakilla@gmail.com>
2962
  */
2963
+ class KeyPreciseExpire extends KeyExpire
2964
  {
2965
  /**
2966
  * {@inheritdoc}
2967
  */
2968
  public function getId()
2969
  {
2970
+ return 'PEXPIRE';
2971
  }
2972
  }
2973
 
2974
  /**
2975
+ * @link http://redis.io/commands/persist
2976
+ *
2977
  * @author Daniele Alessandri <suppakilla@gmail.com>
2978
  */
2979
+ class KeyPersist extends Command
2980
  {
2981
  /**
2982
  * {@inheritdoc}
2983
  */
2984
  public function getId()
2985
  {
2986
+ return 'PERSIST';
2987
  }
2988
 
2989
  /**
2990
  * {@inheritdoc}
2991
  */
2992
+ public function parseResponse($data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2993
  {
2994
+ return (bool) $data;
 
 
 
 
 
 
 
 
 
 
 
 
 
2995
  }
2996
  }
2997
 
2998
  /**
2999
+ * @link http://redis.io/commands/migrate
3000
+ *
3001
  * @author Daniele Alessandri <suppakilla@gmail.com>
3002
  */
3003
+ class KeyMigrate extends Command
3004
  {
3005
  /**
3006
  * {@inheritdoc}
3007
  */
3008
  public function getId()
3009
  {
3010
+ return 'MIGRATE';
3011
  }
3012
 
3013
  /**
3015
  */
3016
  protected function filterArguments(array $arguments)
3017
  {
3018
+ if (is_array(end($arguments))) {
3019
+ foreach (array_pop($arguments) as $modifier => $value) {
3020
+ $modifier = strtoupper($modifier);
 
 
 
3021
 
3022
+ if ($modifier === 'COPY' && $value == true) {
3023
+ $arguments[] = $modifier;
3024
+ }
 
 
 
 
3025
 
3026
+ if ($modifier === 'REPLACE' && $value == true) {
3027
+ $arguments[] = $modifier;
 
 
3028
  }
 
 
 
3029
  }
3030
  }
3031
 
3032
+ return $arguments;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3033
  }
3034
  }
3035
 
3036
  /**
3037
+ * @link http://redis.io/commands/move
 
 
 
 
 
3038
  *
3039
  * @author Daniele Alessandri <suppakilla@gmail.com>
3040
  */
3041
+ class KeyMove extends Command
3042
  {
 
 
 
 
3043
  /**
3044
+ * {@inheritdoc}
 
 
3045
  */
3046
+ public function getId()
3047
  {
3048
+ return 'MOVE';
 
 
 
 
 
 
 
3049
  }
3050
 
3051
  /**
3052
+ * {@inheritdoc}
 
 
 
 
 
3053
  */
3054
+ public function parseResponse($data)
3055
  {
3056
+ return (bool) $data;
 
 
 
3057
  }
3058
+ }
3059
 
3060
+ /**
3061
+ * @link http://redis.io/commands/lpushx
3062
+ *
3063
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3064
+ */
3065
+ class ListPushHeadX extends Command
3066
+ {
3067
  /**
3068
  * {@inheritdoc}
3069
  */
3070
  public function getId()
3071
  {
3072
+ return 'LPUSHX';
3073
  }
3074
+ }
3075
 
3076
+ /**
3077
+ * @link http://redis.io/commands/hlen
3078
+ *
3079
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3080
+ */
3081
+ class HashLength extends Command
3082
+ {
3083
  /**
3084
  * {@inheritdoc}
3085
  */
3086
+ public function getId()
3087
  {
3088
+ return 'HLEN';
 
3089
  }
3090
+ }
3091
 
3092
+ /**
3093
+ * @link http://redis.io/commands/hmget
3094
+ *
3095
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3096
+ */
3097
+ class HashGetMultiple extends Command
3098
+ {
3099
  /**
3100
  * {@inheritdoc}
3101
  */
3102
+ public function getId()
3103
  {
3104
+ return 'HMGET';
3105
  }
3106
 
3107
  /**
3108
  * {@inheritdoc}
3109
  */
3110
+ protected function filterArguments(array $arguments)
3111
  {
3112
+ return self::normalizeVariadic($arguments);
3113
  }
3114
+ }
3115
 
3116
+ /**
3117
+ * @link http://redis.io/commands/flushall
3118
+ *
3119
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3120
+ */
3121
+ class ServerFlushAll extends Command
3122
+ {
3123
  /**
3124
  * {@inheritdoc}
3125
  */
3126
+ public function getId()
3127
  {
3128
+ return 'FLUSHALL';
 
 
3129
  }
3130
+ }
3131
 
3132
+ /**
3133
+ * @link http://redis.io/commands/flushdb
3134
+ *
3135
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3136
+ */
3137
+ class ServerFlushDatabase extends Command
3138
+ {
3139
  /**
3140
  * {@inheritdoc}
3141
  */
3142
+ public function getId()
3143
  {
3144
+ return 'FLUSHDB';
3145
  }
3146
+ }
3147
 
3148
+ /**
3149
+ * @link http://redis.io/commands/hincrby
3150
+ *
3151
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3152
+ */
3153
+ class HashIncrementBy extends Command
3154
+ {
3155
  /**
3156
  * {@inheritdoc}
3157
  */
3158
+ public function getId()
3159
  {
3160
+ return 'HINCRBY';
 
 
3161
  }
3162
+ }
3163
 
3164
+ /**
3165
+ * @link http://redis.io/commands/dbsize
3166
+ *
3167
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3168
+ */
3169
+ class ServerDatabaseSize extends Command
3170
+ {
3171
  /**
3172
  * {@inheritdoc}
3173
  */
3174
+ public function getId()
3175
  {
3176
+ return 'DBSIZE';
3177
  }
3178
  }
3179
 
3180
  /**
3181
+ * @link http://redis.io/commands/command
 
3182
  *
 
3183
  * @author Daniele Alessandri <suppakilla@gmail.com>
3184
  */
3185
+ class ServerCommand extends Command
3186
  {
3187
  /**
3188
+ * {@inheritdoc}
 
 
 
 
 
 
 
 
 
 
 
 
 
3189
  */
3190
+ public function getId()
3191
  {
3192
+ return 'COMMAND';
3193
  }
3194
+ }
3195
 
3196
+ /**
3197
+ * @link http://redis.io/commands/config-set
3198
+ * @link http://redis.io/commands/config-get
3199
+ * @link http://redis.io/commands/config-resetstat
3200
+ * @link http://redis.io/commands/config-rewrite
3201
+ *
3202
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3203
+ */
3204
+ class ServerConfig extends Command
3205
+ {
3206
  /**
3207
+ * {@inheritdoc}
 
 
3208
  */
3209
+ public function getId()
3210
  {
3211
+ return 'CONFIG';
3212
  }
3213
 
3214
  /**
3215
  * {@inheritdoc}
3216
  */
3217
+ public function parseResponse($data)
3218
  {
3219
+ if (is_array($data)) {
3220
+ $result = array();
 
3221
 
3222
+ for ($i = 0; $i < count($data); ++$i) {
3223
+ $result[$data[$i]] = $data[++$i];
3224
+ }
3225
 
3226
+ return $result;
3227
+ }
 
 
 
 
 
3228
 
3229
+ return $data;
3230
  }
3231
  }
3232
 
3233
  /**
3234
+ * @link http://redis.io/commands/hgetall
3235
+ *
3236
  * @author Daniele Alessandri <suppakilla@gmail.com>
3237
  */
3238
+ class HashGetAll extends Command
3239
  {
3240
  /**
3241
  * {@inheritdoc}
3242
  */
3243
  public function getId()
3244
  {
3245
+ return 'HGETALL';
3246
  }
3247
 
3248
  /**
3250
  */
3251
  public function parseResponse($data)
3252
  {
3253
+ $result = array();
3254
+
3255
+ for ($i = 0; $i < count($data); ++$i) {
3256
+ $result[$data[$i]] = $data[++$i];
3257
+ }
3258
+
3259
+ return $result;
3260
  }
3261
  }
3262
 
3263
  /**
3264
+ * @link http://redis.io/commands/info
3265
+ *
3266
  * @author Daniele Alessandri <suppakilla@gmail.com>
3267
  */
3268
+ class ServerInfoV26x extends ServerInfo
3269
+ {
3270
+ /**
3271
+ * {@inheritdoc}
3272
+ */
3273
+ public function parseResponse($data)
3274
+ {
3275
+ if ($data === '') {
3276
+ return array();
3277
+ }
3278
+
3279
+ $info = array();
3280
+
3281
+ $current = null;
3282
+ $infoLines = preg_split('/\r?\n/', $data);
3283
+
3284
+ if (isset($infoLines[0]) && $infoLines[0][0] !== '#') {
3285
+ return parent::parseResponse($data);
3286
+ }
3287
+
3288
+ foreach ($infoLines as $row) {
3289
+ if ($row === '') {
3290
+ continue;
3291
+ }
3292
+
3293
+ if (preg_match('/^# (\w+)$/', $row, $matches)) {
3294
+ $info[$matches[1]] = array();
3295
+ $current = &$info[$matches[1]];
3296
+ continue;
3297
+ }
3298
+
3299
+ list($k, $v) = $this->parseRow($row);
3300
+ $current[$k] = $v;
3301
+ }
3302
+
3303
+ return $info;
3304
+ }
3305
+ }
3306
+
3307
+ /**
3308
+ * @link http://redis.io/commands/script
3309
+ *
3310
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3311
+ */
3312
+ class ServerScript extends Command
3313
  {
3314
  /**
3315
  * {@inheritdoc}
3316
  */
3317
  public function getId()
3318
  {
3319
+ return 'SCRIPT';
3320
  }
3321
  }
3322
 
3323
  /**
3324
+ * @link http://redis.io/topics/sentinel
3325
+ *
3326
  * @author Daniele Alessandri <suppakilla@gmail.com>
3327
  */
3328
+ class ServerSentinel extends Command
3329
  {
3330
  /**
3331
  * {@inheritdoc}
3332
  */
3333
  public function getId()
3334
  {
3335
+ return 'SENTINEL';
3336
+ }
3337
+
3338
+ /**
3339
+ * {@inheritdoc}
3340
+ */
3341
+ public function parseResponse($data)
3342
+ {
3343
+ switch (strtolower($this->getArgument(0))) {
3344
+ case 'masters':
3345
+ case 'slaves':
3346
+ return self::processMastersOrSlaves($data);
3347
+
3348
+ default:
3349
+ return $data;
3350
+ }
3351
+ }
3352
+
3353
+ /**
3354
+ * Returns a processed response to SENTINEL MASTERS or SENTINEL SLAVES.
3355
+ *
3356
+ * @param array $servers List of Redis servers.
3357
+ *
3358
+ * @return array
3359
+ */
3360
+ protected static function processMastersOrSlaves(array $servers)
3361
+ {
3362
+ foreach ($servers as $idx => $node) {
3363
+ $processed = array();
3364
+ $count = count($node);
3365
+
3366
+ for ($i = 0; $i < $count; ++$i) {
3367
+ $processed[$node[$i]] = $node[++$i];
3368
+ }
3369
+
3370
+ $servers[$idx] = $processed;
3371
+ }
3372
+
3373
+ return $servers;
3374
  }
3375
  }
3376
 
3377
  /**
3378
+ * @link http://redis.io/commands/save
3379
+ *
3380
  * @author Daniele Alessandri <suppakilla@gmail.com>
3381
  */
3382
+ class ServerSave extends Command
3383
  {
3384
  /**
3385
  * {@inheritdoc}
3386
  */
3387
  public function getId()
3388
  {
3389
+ return 'SAVE';
3390
  }
3391
  }
3392
 
3393
  /**
3394
+ * @link http://redis.io/commands/object
3395
+ *
3396
  * @author Daniele Alessandri <suppakilla@gmail.com>
3397
  */
3398
+ class ServerObject extends Command
3399
  {
3400
  /**
3401
  * {@inheritdoc}
3402
  */
3403
  public function getId()
3404
  {
3405
+ return 'OBJECT';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3406
  }
3407
  }
3408
 
3409
  /**
3410
+ * @link http://redis.io/commands/lastsave
3411
+ *
3412
  * @author Daniele Alessandri <suppakilla@gmail.com>
3413
  */
3414
+ class ServerLastSave extends Command
3415
  {
3416
  /**
3417
  * {@inheritdoc}
3418
  */
3419
  public function getId()
3420
  {
3421
+ return 'LASTSAVE';
3422
  }
3423
+ }
3424
 
3425
+ /**
3426
+ * @link http://redis.io/commands/monitor
3427
+ *
3428
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3429
+ */
3430
+ class ServerMonitor extends Command
3431
+ {
3432
  /**
3433
  * {@inheritdoc}
3434
  */
3435
+ public function getId()
3436
  {
3437
+ return 'MONITOR';
3438
  }
3439
  }
3440
 
3443
  * @link http://redis.io/commands/client-kill
3444
  * @link http://redis.io/commands/client-getname
3445
  * @link http://redis.io/commands/client-setname
3446
+ *
3447
  * @author Daniele Alessandri <suppakilla@gmail.com>
3448
  */
3449
  class ServerClient extends Command
3501
  }
3502
 
3503
  /**
3504
+ * @link http://redis.io/commands/bgsave
3505
+ *
3506
  * @author Daniele Alessandri <suppakilla@gmail.com>
3507
  */
3508
+ class ServerBackgroundSave extends Command
3509
  {
3510
  /**
3511
  * {@inheritdoc}
3512
  */
3513
+ public function getId()
3514
  {
3515
+ return 'BGSAVE';
3516
+ }
 
 
 
 
 
 
3517
 
3518
+ /**
3519
+ * {@inheritdoc}
3520
+ */
3521
+ public function parseResponse($data)
3522
+ {
3523
+ return $data === 'Background saving started' ? true : $data;
3524
+ }
3525
+ }
3526
 
3527
+ /**
3528
+ * @link http://redis.io/commands/ltrim
3529
+ *
3530
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3531
+ */
3532
+ class ListTrim extends Command
3533
+ {
3534
+ /**
3535
+ * {@inheritdoc}
3536
+ */
3537
+ public function getId()
3538
+ {
3539
+ return 'LTRIM';
3540
+ }
3541
+ }
3542
 
3543
+ /**
3544
+ * Defines a command whose keys can be prefixed.
3545
+ *
3546
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3547
+ */
3548
+ interface PrefixableCommandInterface extends CommandInterface
3549
+ {
3550
+ /**
3551
+ * Prefixes all the keys found in the arguments of the command.
3552
+ *
3553
+ * @param string $prefix String used to prefix the keys.
3554
+ */
3555
+ public function prefixKeys($prefix);
3556
+ }
3557
 
3558
+ /**
3559
+ * @link http://redis.io/commands/publish
3560
+ *
3561
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3562
+ */
3563
+ class PubSubPublish extends Command
3564
+ {
3565
+ /**
3566
+ * {@inheritdoc}
3567
+ */
3568
+ public function getId()
3569
+ {
3570
+ return 'PUBLISH';
3571
+ }
3572
+ }
3573
 
3574
+ /**
3575
+ * @link http://redis.io/commands/lset
3576
+ *
3577
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3578
+ */
3579
+ class ListSet extends Command
3580
+ {
3581
+ /**
3582
+ * {@inheritdoc}
3583
+ */
3584
+ public function getId()
3585
+ {
3586
+ return 'LSET';
3587
  }
3588
  }
3589
 
3590
  /**
3591
+ * @link http://redis.io/commands/lrem
3592
+ *
3593
  * @author Daniele Alessandri <suppakilla@gmail.com>
3594
  */
3595
+ class ListRemove extends Command
3596
  {
3597
  /**
3598
  * {@inheritdoc}
3599
  */
3600
  public function getId()
3601
  {
3602
+ return 'LREM';
3603
  }
3604
  }
3605
 
3606
  /**
3607
+ * @link http://redis.io/commands/rpushx
3608
+ *
3609
  * @author Daniele Alessandri <suppakilla@gmail.com>
3610
  */
3611
+ class ListPushTailX extends Command
3612
  {
3613
  /**
3614
  * {@inheritdoc}
3615
  */
3616
  public function getId()
3617
  {
3618
+ return 'RPUSHX';
3619
  }
3620
  }
3621
 
3622
  /**
3623
+ * @link http://redis.io/commands/lrange
3624
+ *
3625
  * @author Daniele Alessandri <suppakilla@gmail.com>
3626
  */
3627
+ class ListRange extends Command
3628
  {
3629
  /**
3630
  * {@inheritdoc}
3631
  */
3632
  public function getId()
3633
  {
3634
+ return 'LRANGE';
3635
  }
3636
  }
3637
 
3638
  /**
3639
+ * @link http://redis.io/commands/pubsub
3640
+ *
3641
  * @author Daniele Alessandri <suppakilla@gmail.com>
3642
  */
3643
+ class PubSubPubsub extends Command
3644
  {
3645
  /**
3646
  * {@inheritdoc}
3647
  */
3648
  public function getId()
3649
  {
3650
+ return 'PUBSUB';
3651
+ }
3652
+
3653
+ /**
3654
+ * {@inheritdoc}
3655
+ */
3656
+ public function parseResponse($data)
3657
+ {
3658
+ switch (strtolower($this->getArgument(0))) {
3659
+ case 'numsub':
3660
+ return self::processNumsub($data);
3661
+
3662
+ default:
3663
+ return $data;
3664
+ }
3665
+ }
3666
+
3667
+ /**
3668
+ * Returns the processed response to PUBSUB NUMSUB.
3669
+ *
3670
+ * @param array $channels List of channels
3671
+ *
3672
+ * @return array
3673
+ */
3674
+ protected static function processNumsub(array $channels)
3675
+ {
3676
+ $processed = array();
3677
+ $count = count($channels);
3678
+
3679
+ for ($i = 0; $i < $count; ++$i) {
3680
+ $processed[$channels[$i]] = $channels[++$i];
3681
+ }
3682
+
3683
+ return $processed;
3684
  }
3685
  }
3686
 
3687
  /**
3688
+ * @link http://redis.io/commands/hkeys
3689
+ *
3690
  * @author Daniele Alessandri <suppakilla@gmail.com>
3691
  */
3692
+ class HashKeys extends Command
3693
  {
3694
  /**
3695
  * {@inheritdoc}
3696
  */
3697
  public function getId()
3698
  {
3699
+ return 'HKEYS';
3700
+ }
3701
+ }
3702
+
3703
+ /**
3704
+ * Base class used to implement an higher level abstraction for commands based
3705
+ * on Lua scripting with EVAL and EVALSHA.
3706
+ *
3707
+ * @link http://redis.io/commands/eval
3708
+ *
3709
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3710
+ */
3711
+ abstract class ScriptCommand extends ServerEvalSHA
3712
+ {
3713
+ /**
3714
+ * Gets the body of a Lua script.
3715
+ *
3716
+ * @return string
3717
+ */
3718
+ abstract public function getScript();
3719
+
3720
+ /**
3721
+ * Specifies the number of arguments that should be considered as keys.
3722
+ *
3723
+ * The default behaviour for the base class is to return 0 to indicate that
3724
+ * all the elements of the arguments array should be considered as keys, but
3725
+ * subclasses can enforce a static number of keys.
3726
+ *
3727
+ * @return int
3728
+ */
3729
+ protected function getKeysCount()
3730
+ {
3731
+ return 0;
3732
  }
 
3733
 
 
 
 
 
 
 
 
 
 
3734
  /**
3735
+ * Returns the elements from the arguments that are identified as keys.
3736
+ *
3737
+ * @return array
3738
  */
3739
+ public function getKeys()
3740
  {
3741
+ return array_slice($this->getArguments(), 2, $this->getKeysCount());
3742
  }
3743
 
3744
  /**
3745
  * {@inheritdoc}
3746
  */
3747
+ protected function filterArguments(array $arguments)
3748
  {
3749
+ if (($numkeys = $this->getKeysCount()) && $numkeys < 0) {
3750
+ $numkeys = count($arguments) + $numkeys;
 
 
 
 
 
 
3751
  }
3752
 
3753
+ return array_merge(array(sha1($this->getScript()), (int) $numkeys), $arguments);
3754
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3755
 
 
 
 
 
 
 
3756
  /**
3757
+ * @return array
3758
  */
3759
+ public function getEvalArguments()
3760
  {
3761
+ $arguments = $this->getArguments();
3762
+ $arguments[0] = $this->getScript();
3763
+
3764
+ return $arguments;
3765
  }
3766
  }
3767
 
3768
  /**
3769
+ * @link http://redis.io/commands/bgrewriteaof
3770
+ *
3771
  * @author Daniele Alessandri <suppakilla@gmail.com>
3772
  */
3773
+ class ServerBackgroundRewriteAOF extends Command
3774
  {
3775
  /**
3776
  * {@inheritdoc}
3777
  */
3778
  public function getId()
3779
  {
3780
+ return 'BGREWRITEAOF';
3781
  }
 
3782
 
 
 
 
 
 
 
3783
  /**
3784
  * {@inheritdoc}
3785
  */
3786
+ public function parseResponse($data)
3787
  {
3788
+ return $data == 'Background append only file rewriting started';
3789
  }
3790
  }
3791
 
3792
  /**
3793
+ * Class for generic "anonymous" Redis commands.
3794
+ *
3795
+ * This command class does not filter input arguments or parse responses, but
3796
+ * can be used to leverage the standard Predis API to execute any command simply
3797
+ * by providing the needed arguments following the command signature as defined
3798
+ * by Redis in its documentation.
3799
+ *
3800
  * @author Daniele Alessandri <suppakilla@gmail.com>
3801
  */
3802
+ class RawCommand implements CommandInterface
3803
  {
3804
+ private $slot;
3805
+ private $commandID;
3806
+ private $arguments;
3807
+
3808
  /**
3809
+ * @param array $arguments Command ID and its arguments.
3810
+ *
3811
+ * @throws \InvalidArgumentException
3812
  */
3813
+ public function __construct(array $arguments)
3814
  {
3815
+ if (!$arguments) {
3816
+ throw new \InvalidArgumentException(
3817
+ 'The arguments array must contain at least the command ID.'
3818
+ );
3819
+ }
3820
+
3821
+ $this->commandID = strtoupper(array_shift($arguments));
3822
+ $this->arguments = $arguments;
3823
  }
 
3824
 
 
 
 
 
 
 
3825
  /**
3826
+ * Creates a new raw command using a variadic method.
3827
+ *
3828
+ * @param string $commandID Redis command ID.
3829
+ * @param string ... Arguments list for the command.
3830
+ *
3831
+ * @return CommandInterface
3832
  */
3833
+ public static function create($commandID /* [ $arg, ... */)
3834
  {
3835
+ $arguments = func_get_args();
3836
+ $command = new self($arguments);
3837
+
3838
+ return $command;
3839
  }
 
3840
 
 
 
 
 
 
 
3841
  /**
3842
  * {@inheritdoc}
3843
  */
3844
  public function getId()
3845
  {
3846
+ return $this->commandID;
3847
  }
 
3848
 
 
 
 
 
 
 
3849
  /**
3850
  * {@inheritdoc}
3851
  */
3852
+ public function setArguments(array $arguments)
3853
  {
3854
+ $this->arguments = $arguments;
3855
+ unset($this->slot);
3856
  }
 
3857
 
 
 
 
 
 
 
3858
  /**
3859
  * {@inheritdoc}
3860
  */
3861
+ public function setRawArguments(array $arguments)
3862
  {
3863
+ $this->setArguments($arguments);
3864
  }
 
3865
 
 
 
 
 
 
 
3866
  /**
3867
  * {@inheritdoc}
3868
  */
3869
+ public function getArguments()
3870
  {
3871
+ return $this->arguments;
3872
  }
 
3873
 
 
 
 
 
 
 
3874
  /**
3875
  * {@inheritdoc}
3876
  */
3877
+ public function getArgument($index)
3878
  {
3879
+ if (isset($this->arguments[$index])) {
3880
+ return $this->arguments[$index];
3881
+ }
3882
  }
 
3883
 
 
 
 
 
 
 
3884
  /**
3885
  * {@inheritdoc}
3886
  */
3887
+ public function setSlot($slot)
3888
  {
3889
+ $this->slot = $slot;
3890
  }
 
3891
 
 
 
 
 
 
 
3892
  /**
3893
  * {@inheritdoc}
3894
  */
3895
+ public function getSlot()
3896
  {
3897
+ if (isset($this->slot)) {
3898
+ return $this->slot;
3899
+ }
3900
  }
 
3901
 
 
 
 
 
 
 
3902
  /**
3903
  * {@inheritdoc}
3904
  */
3905
+ public function parseResponse($data)
3906
  {
3907
+ return $data;
3908
  }
3909
  }
3910
 
3911
  /**
3912
+ * @link http://redis.io/commands/punsubscribe
3913
+ *
3914
  * @author Daniele Alessandri <suppakilla@gmail.com>
3915
  */
3916
+ class PubSubUnsubscribeByPattern extends PubSubUnsubscribe
3917
  {
3918
  /**
3919
  * {@inheritdoc}
3920
  */
3921
  public function getId()
3922
  {
3923
+ return 'PUNSUBSCRIBE';
3924
  }
3925
  }
3926
 
3927
  /**
3928
+ * @link http://redis.io/commands/psubscribe
3929
+ *
3930
  * @author Daniele Alessandri <suppakilla@gmail.com>
3931
  */
3932
+ class PubSubSubscribeByPattern extends PubSubSubscribe
3933
  {
3934
  /**
3935
  * {@inheritdoc}
3936
  */
3937
  public function getId()
3938
  {
3939
+ return 'PSUBSCRIBE';
3940
  }
3941
  }
3942
 
3943
  /**
3944
+ * @link http://redis.io/commands/hincrbyfloat
3945
+ *
3946
  * @author Daniele Alessandri <suppakilla@gmail.com>
3947
  */
3948
+ class HashIncrementByFloat extends Command
3949
  {
3950
  /**
3951
  * {@inheritdoc}
3952
  */
3953
  public function getId()
3954
  {
3955
+ return 'HINCRBYFLOAT';
3956
  }
3957
  }
3958
 
3959
  /**
3960
+ * @link http://redis.io/commands/hvals
3961
+ *
3962
  * @author Daniele Alessandri <suppakilla@gmail.com>
3963
  */
3964
+ class HashValues extends Command
3965
  {
3966
  /**
3967
  * {@inheritdoc}
3968
  */
3969
  public function getId()
3970
  {
3971
+ return 'HVALS';
3972
  }
3973
  }
3974
 
3976
 
3977
  namespace Predis\Connection;
3978
 
 
 
3979
  use Predis\Command\CommandInterface;
3980
+ use Predis\CommunicationException;
3981
  use Predis\Protocol\ProtocolException;
3982
  use Predis\Protocol\ProtocolProcessorInterface;
3983
  use Predis\Protocol\Text\ProtocolProcessor as TextProtocolProcessor;
 
 
3984
  use Predis\Command\RawCommand;
3985
  use Predis\NotSupportedException;
3986
  use Predis\Response\Error as ErrorResponse;
4161
  *
4162
  * @param ParametersInterface $parameters Initialization parameters for the connection.
4163
  *
 
 
4164
  * @throws \InvalidArgumentException
4165
+ *
4166
+ * @return ParametersInterface
4167
  */
4168
  protected function assertParameters(ParametersInterface $parameters)
4169
  {
4170
+ switch ($parameters->scheme) {
4171
+ case 'tcp':
4172
+ case 'redis':
4173
+ case 'unix':
4174
+ break;
4175
 
4176
+ default:
4177
+ throw new \InvalidArgumentException("Invalid scheme: '$parameters->scheme'.");
4178
  }
4179
 
4180
  return $parameters;
4243
  return $this->read();
4244
  }
4245
 
4246
+ /**
4247
+ * Helper method that returns an exception message augmented with useful
4248
+ * details from the connection parameters.
4249
+ *
4250
+ * @param string $message Error message.
4251
+ *
4252
+ * @return string
4253
+ */
4254
+ private function createExceptionMessage($message)
4255
+ {
4256
+ $parameters = $this->parameters;
4257
+
4258
+ if ($parameters->scheme === 'unix') {
4259
+ return "$message [$parameters->scheme:$parameters->path]";
4260
+ }
4261
+
4262
+ if (filter_var($parameters->host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
4263
+ return "$message [$parameters->scheme://[$parameters->host]:$parameters->port]";
4264
+ }
4265
+
4266
+ return "$message [$parameters->scheme://$parameters->host:$parameters->port]";
4267
+ }
4268
+
4269
  /**
4270
  * Helper method to handle connection errors.
4271
  *
4275
  protected function onConnectionError($message, $code = null)
4276
  {
4277
  CommunicationException::handle(
4278
+ new ConnectionException($this, static::createExceptionMessage($message), $code)
 
 
4279
  );
4280
  }
4281
 
4287
  protected function onProtocolError($message)
4288
  {
4289
  CommunicationException::handle(
4290
+ new ProtocolException($this, static::createExceptionMessage($message))
 
 
4291
  );
4292
  }
4293
 
4350
 
4351
  /**
4352
  * Standard connection to Redis servers implemented on top of PHP's streams.
4353
+ * The connection parameters supported by this class are:.
4354
  *
4355
+ * - scheme: it can be either 'redis', 'tcp' or 'unix'.
4356
  * - host: hostname or IP address of the server.
4357
  * - port: TCP port of the server.
4358
  * - path: path of a UNIX domain socket when scheme is 'unix'.
4385
  */
4386
  protected function createResource()
4387
  {
4388
+ switch ($this->parameters->scheme) {
4389
+ case 'tcp':
4390
+ case 'redis':
4391
+ return $this->tcpStreamInitializer($this->parameters);
4392
 
4393
+ case 'unix':
4394
+ return $this->unixStreamInitializer($this->parameters);
4395
+
4396
+ default:
4397
+ throw new \InvalidArgumentException("Invalid scheme: '{$this->parameters->scheme}'.");
4398
+ }
4399
  }
4400
 
4401
  /**
4407
  */
4408
  protected function tcpStreamInitializer(ParametersInterface $parameters)
4409
  {
4410
+ if (!filter_var($parameters->host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
4411
+ $uri = "tcp://$parameters->host:$parameters->port";
4412
+ } else {
4413
+ $uri = "tcp://[$parameters->host]:$parameters->port";
4414
+ }
4415
+
4416
  $flags = STREAM_CLIENT_CONNECT;
4417
 
4418
  if (isset($parameters->async_connect) && (bool) $parameters->async_connect) {
4433
  if (isset($parameters->read_write_timeout)) {
4434
  $rwtimeout = (float) $parameters->read_write_timeout;
4435
  $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
4436
+ $timeoutSeconds = floor($rwtimeout);
4437
  $timeoutUSeconds = ($rwtimeout - $timeoutSeconds) * 1000000;
4438
  stream_set_timeout($resource, $timeoutSeconds, $timeoutUSeconds);
4439
  }
4455
  */
4456
  protected function unixStreamInitializer(ParametersInterface $parameters)
4457
  {
4458
+ if (!isset($parameters->path)) {
4459
+ throw new InvalidArgumentException('Missing UNIX domain socket path.');
4460
+ }
4461
+
4462
  $uri = "unix://{$parameters->path}";
4463
  $flags = STREAM_CLIENT_CONNECT;
4464
 
4475
  if (isset($parameters->read_write_timeout)) {
4476
  $rwtimeout = (float) $parameters->read_write_timeout;
4477
  $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
4478
+ $timeoutSeconds = floor($rwtimeout);
4479
  $timeoutUSeconds = ($rwtimeout - $timeoutSeconds) * 1000000;
4480
  stream_set_timeout($resource, $timeoutSeconds, $timeoutUSeconds);
4481
  }
4554
  $size = (int) $payload;
4555
 
4556
  if ($size === -1) {
4557
+ return;
4558
  }
4559
 
4560
  $bulkData = '';
4577
  $count = (int) $payload;
4578
 
4579
  if ($count === -1) {
4580
+ return;
4581
  }
4582
 
4583
  $multibulk = array();
4584
 
4585
+ for ($i = 0; $i < $count; ++$i) {
4586
  $multibulk[$i] = $this->read();
4587
  }
4588
 
4614
 
4615
  $buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
4616
 
4617
+ for ($i = 0, $reqlen--; $i < $reqlen; ++$i) {
4618
  $argument = $arguments[$i];
4619
  $arglen = strlen($argument);
4620
  $buffer .= "\${$arglen}\r\n{$argument}\r\n";
4767
  *
4768
  * The connection parameters supported by this class are:
4769
  *
4770
+ * - scheme: it can be either 'redis', 'tcp' or 'unix'.
4771
  * - host: hostname or IP address of the server.
4772
  * - port: TCP port of the server.
4773
  * - path: path of a UNIX domain socket when scheme is 'unix'.
4778
  * - persistent: the connection is left intact after a GC collection.
4779
  *
4780
  * @link https://github.com/nrk/phpiredis
4781
+ *
4782
  * @author Daniele Alessandri <suppakilla@gmail.com>
4783
  */
4784
  class PhpiredisStreamConnection extends StreamConnection
4824
  */
4825
  protected function tcpStreamInitializer(ParametersInterface $parameters)
4826
  {
4827
+ $uri = "tcp://[{$parameters->host}]:{$parameters->port}";
4828
  $flags = STREAM_CLIENT_CONNECT;
4829
  $socket = null;
4830
 
4848
  $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
4849
 
4850
  $timeout = array(
4851
+ 'sec' => $timeoutSeconds = floor($rwtimeout),
4852
  'usec' => ($rwtimeout - $timeoutSeconds) * 1000000,
4853
  );
4854
 
4985
  * @link http://webd.is
4986
  * @link http://github.com/nicolasff/webdis
4987
  * @link http://github.com/seppo0010/phpiredis
4988
+ *
4989
  * @author Daniele Alessandri <suppakilla@gmail.com>
4990
  */
4991
  class WebdisConnection implements NodeConnectionInterface
5004
  $this->assertExtensions();
5005
 
5006
  if ($parameters->scheme !== 'http') {
5007
+ throw new \InvalidArgumentException("Invalid scheme: '{$parameters->scheme}'.");
5008
  }
5009
 
5010
  $this->parameters = $parameters;
5063
  {
5064
  $parameters = $this->getParameters();
5065
 
5066
+ if (filter_var($host = $parameters->host, FILTER_VALIDATE_IP)) {
5067
+ $host = "[$host]";
5068
+ }
5069
+
5070
  $options = array(
5071
  CURLOPT_FAILONERROR => true,
5072
  CURLOPT_CONNECTTIMEOUT_MS => $parameters->timeout * 1000,
5073
+ CURLOPT_URL => "$parameters->scheme://$host:$parameters->port",
5074
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
5075
  CURLOPT_POST => true,
5076
  CURLOPT_WRITEFUNCTION => array($this, 'feedReader'),
5168
  *
5169
  * @param CommandInterface $command Command instance.
5170
  *
 
 
5171
  * @throws NotSupportedException
5172
+ *
5173
+ * @return string
5174
  */
5175
  protected function getCommandId(CommandInterface $command)
5176
  {
5313
  *
5314
  * The connection parameters supported by this class are:
5315
  *
5316
+ * - scheme: it can be either 'redis', 'tcp' or 'unix'.
5317
  * - host: hostname or IP address of the server.
5318
  * - port: TCP port of the server.
5319
  * - path: path of a UNIX domain socket when scheme is 'unix'.
5321
  * - read_write_timeout: timeout of read / write operations.
5322
  *
5323
  * @link http://github.com/nrk/phpiredis
5324
+ *
5325
  * @author Daniele Alessandri <suppakilla@gmail.com>
5326
  */
5327
  class PhpiredisSocketConnection extends AbstractConnection
5374
  */
5375
  protected function assertParameters(ParametersInterface $parameters)
5376
  {
5377
+ parent::assertParameters($parameters);
5378
+
5379
  if (isset($parameters->persistent)) {
5380
  throw new NotSupportedException(
5381
+ 'Persistent connections are not supported by this connection backend.'
5382
  );
5383
  }
5384
 
5385
+ return $parameters;
5386
  }
5387
 
5388
  /**
5447
  $this->onConnectionError(trim($errstr), $errno);
5448
  }
5449
 
5450
+ /**
5451
+ * Gets the address of an host from connection parameters.
5452
+ *
5453
+ * @param ParametersInterface $parameters Parameters used to initialize the connection.
5454
+ *
5455
+ * @return string
5456
+ */
5457
+ protected static function getAddress(ParametersInterface $parameters)
5458
+ {
5459
+ if (filter_var($host = $parameters->host, FILTER_VALIDATE_IP)) {
5460
+ return $host;
5461
+ }
5462
+
5463
+ if ($host === $address = gethostbyname($host)) {
5464
+ return false;
5465
+ }
5466
+
5467
+ return $address;
5468
+ }
5469
+
5470
  /**
5471
  * {@inheritdoc}
5472
  */
5473
  protected function createResource()
5474
  {
5475
+ $parameters = $this->parameters;
5476
+
5477
+ if ($parameters->scheme === 'unix') {
5478
+ $address = $parameters->path;
5479
+ $domain = AF_UNIX;
5480
+ $protocol = 0;
5481
+ } else {
5482
+ if (false === $address = self::getAddress($parameters)) {
5483
+ $this->onConnectionError("Cannot resolve the address of '$parameters->host'.");
5484
+ }
5485
+
5486
+ $domain = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? AF_INET6 : AF_INET;
5487
+ $protocol = SOL_TCP;
5488
+ }
5489
 
5490
+ $socket = @socket_create($domain, SOCK_STREAM, $protocol);
5491
 
5492
  if (!is_resource($socket)) {
5493
  $this->emitSocketError();
5494
  }
5495
 
5496
+ $this->setSocketOptions($socket, $parameters);
5497
+ $this->connectWithTimeout($socket, $address, $parameters);
5498
 
5499
  return $socket;
5500
  }
5507
  */
5508
  private function setSocketOptions($socket, ParametersInterface $parameters)
5509
  {
5510
+ if ($parameters->scheme !== 'unix') {
5511
+ if (!socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1)) {
5512
+ $this->emitSocketError();
5513
+ }
 
 
 
5514
 
5515
+ if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
5516
+ $this->emitSocketError();
5517
+ }
5518
  }
5519
 
5520
  if (isset($parameters->read_write_timeout)) {
5537
  }
5538
  }
5539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5540
  /**
5541
  * Opens the actual connection to the server with a timeout.
5542
  *
5543
+ * @param resource $socket Socket resource.
5544
+ * @param string $address IP address (DNS-resolved from hostname)
5545
  * @param ParametersInterface $parameters Parameters used to initialize the connection.
5546
  *
5547
  * @return string
5548
  */
5549
+ private function connectWithTimeout($socket, $address, ParametersInterface $parameters)
5550
  {
 
 
 
 
 
 
5551
  socket_set_nonblock($socket);
5552
 
5553
+ if (@socket_connect($socket, $address, (int) $parameters->port) === false) {
5554
  $error = socket_last_error();
5555
 
5556
  if ($error != SOCKET_EINPROGRESS && $error != SOCKET_EALREADY) {
5572
  if ($selected === 2) {
5573
  $this->onConnectionError('Connection refused.', SOCKET_ECONNREFUSED);
5574
  }
5575
+
5576
  if ($selected === 0) {
5577
  $this->onConnectionError('Connection timed out.', SOCKET_ETIMEDOUT);
5578
  }
5579
+
5580
  if ($selected === false) {
5581
  $this->emitSocketError();
5582
  }
5587
  */
5588
  public function connect()
5589
  {
5590
+ if (parent::connect() && $this->initCommands) {
5591
+ foreach ($this->initCommands as $command) {
5592
+ $this->executeCommand($command);
 
 
 
 
5593
  }
5594
  }
5595
  }
5636
  $reader = $this->reader;
5637
 
5638
  while (PHPIREDIS_READER_STATE_INCOMPLETE === $state = phpiredis_reader_get_state($reader)) {
5639
+ if (@socket_recv($socket, $buffer, 4096, 0) === false || $buffer === '' || $buffer === null) {
5640
  $this->emitSocketError();
5641
  }
5642
 
5717
  public function readBuffer($length)
5718
  {
5719
  if ($length <= 0) {
5720
+ throw new \InvalidArgumentException('Length parameter must be greater than 0.');
5721
  }
5722
 
5723
  $value = '';
5847
  /**
5848
  * Parses an URI string returning an array of connection parameters.
5849
  *
5850
+ * When using the "redis" and "rediss" schemes the URI is parsed according
5851
+ * to the rules defined by the provisional registration documents approved
5852
+ * by IANA. If the URI has a password in its "user-information" part or a
5853
+ * database number in the "path" part these values override the values of
5854
+ * "password" and "database" if they are present in the "query" part.
5855
  *
5856
+ * @link http://www.iana.org/assignments/uri-schemes/prov/redis
5857
+ * @link http://www.iana.org/assignments/uri-schemes/prov/redis
5858
+ *
5859
+ * @param string $uri URI string.
5860
  *
5861
  * @throws \InvalidArgumentException
5862
+ *
5863
+ * @return array
5864
  */
5865
  public static function parse($uri)
5866
  {
5869
  $uri = str_ireplace('unix:///', 'unix://localhost/', $uri);
5870
  }
5871
 
5872
+ if (!$parsed = parse_url($uri)) {
5873
+ throw new \InvalidArgumentException("Invalid parameters URI: $uri");
5874
+ }
5875
+
5876
+ if (
5877
+ isset($parsed['host'])
5878
+ && false !== strpos($parsed['host'], '[')
5879
+ && false !== strpos($parsed['host'], ']')
5880
+ ) {
5881
+ $parsed['host'] = substr($parsed['host'], 1, -1);
5882
  }
5883
 
5884
  if (isset($parsed['query'])) {
5888
  $parsed = array_merge($parsed, $queryarray);
5889
  }
5890
 
5891
+ if (stripos($uri, 'redis') === 0) {
5892
+ if (isset($parsed['pass'])) {
5893
+ $parsed['password'] = $parsed['pass'];
5894
+ unset($parsed['pass']);
5895
+ }
5896
+
5897
+ if (isset($parsed['path']) && preg_match('/^\/(\d+)(\/.*)?/', $parsed['path'], $path)) {
5898
+ $parsed['database'] = $path[1];
5899
+
5900
+ if (isset($path[2])) {
5901
+ $parsed['path'] = $path[2];
5902
+ } else {
5903
+ unset($parsed['path']);
5904
+ }
5905
+ }
5906
+ }
5907
+
5908
  return $parsed;
5909
  }
5910
 
5963
  class Factory implements FactoryInterface
5964
  {
5965
  protected $schemes = array(
5966
+ 'tcp' => 'Predis\Connection\StreamConnection',
5967
  'unix' => 'Predis\Connection\StreamConnection',
5968
+ 'redis' => 'Predis\Connection\StreamConnection',
5969
  'http' => 'Predis\Connection\WebdisConnection',
5970
  );
5971
 
5976
  *
5977
  * @param mixed $initializer FQN of a connection class or a callable for lazy initialization.
5978
  *
 
 
5979
  * @throws \InvalidArgumentException
5980
+ *
5981
+ * @return mixed
5982
  */
5983
  protected function checkInitializer($initializer)
5984
  {
5986
  return $initializer;
5987
  }
5988
 
5989
+ $class = new \ReflectionClass($initializer);
5990
 
5991
  if (!$class->isSubclassOf('Predis\Connection\NodeConnectionInterface')) {
5992
+ throw new \InvalidArgumentException(
5993
  'A connection initializer must be a valid connection class or a callable object.'
5994
  );
5995
  }
6025
  $scheme = $parameters->scheme;
6026
 
6027
  if (!isset($this->schemes[$scheme])) {
6028
+ throw new \InvalidArgumentException("Unknown connection scheme: '$scheme'.");
6029
  }
6030
 
6031
  $initializer = $this->schemes[$scheme];
6038
  }
6039
 
6040
  if (!$connection instanceof NodeConnectionInterface) {
6041
+ throw new \UnexpectedValueException(
6042
+ 'Objects returned by connection initializers must implement '.
6043
  "'Predis\Connection\NodeConnectionInterface'."
6044
  );
6045
  }
6096
 
6097
  namespace Predis\Profile;
6098
 
 
 
6099
  use Predis\ClientException;
6100
  use Predis\Command\CommandInterface;
6101
  use Predis\Command\Processor\ProcessorInterface;
6240
  */
6241
  public function defineCommand($commandID, $class)
6242
  {
6243
+ $reflection = new \ReflectionClass($class);
6244
 
6245
  if (!$reflection->isSubclassOf('Predis\Command\CommandInterface')) {
6246
+ throw new \InvalidArgumentException("The class '$class' is not a valid command class.");
6247
  }
6248
 
6249
  $this->commands[strtoupper($commandID)] = $class;
6300
  /* ---------------- Redis 1.2 ---------------- */
6301
 
6302
  /* commands operating on the key space */
6303
+ 'EXISTS' => 'Predis\Command\KeyExists',
6304
+ 'DEL' => 'Predis\Command\KeyDelete',
6305
+ 'TYPE' => 'Predis\Command\KeyType',
6306
+ 'KEYS' => 'Predis\Command\KeyKeys',
6307
+ 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6308
+ 'RENAME' => 'Predis\Command\KeyRename',
6309
+ 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6310
+ 'EXPIRE' => 'Predis\Command\KeyExpire',
6311
+ 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6312
+ 'TTL' => 'Predis\Command\KeyTimeToLive',
6313
+ 'MOVE' => 'Predis\Command\KeyMove',
6314
+ 'SORT' => 'Predis\Command\KeySort',
6315
+ 'DUMP' => 'Predis\Command\KeyDump',
6316
+ 'RESTORE' => 'Predis\Command\KeyRestore',
6317
 
6318
  /* commands operating on string values */
6319
+ 'SET' => 'Predis\Command\StringSet',
6320
+ 'SETNX' => 'Predis\Command\StringSetPreserve',
6321
+ 'MSET' => 'Predis\Command\StringSetMultiple',
6322
+ 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6323
+ 'GET' => 'Predis\Command\StringGet',
6324
+ 'MGET' => 'Predis\Command\StringGetMultiple',
6325
+ 'GETSET' => 'Predis\Command\StringGetSet',
6326
+ 'INCR' => 'Predis\Command\StringIncrement',
6327
+ 'INCRBY' => 'Predis\Command\StringIncrementBy',
6328
+ 'DECR' => 'Predis\Command\StringDecrement',
6329
+ 'DECRBY' => 'Predis\Command\StringDecrementBy',
6330
 
6331
  /* commands operating on lists */
6332
+ 'RPUSH' => 'Predis\Command\ListPushTail',
6333
+ 'LPUSH' => 'Predis\Command\ListPushHead',
6334
+ 'LLEN' => 'Predis\Command\ListLength',
6335
+ 'LRANGE' => 'Predis\Command\ListRange',
6336
+ 'LTRIM' => 'Predis\Command\ListTrim',
6337
+ 'LINDEX' => 'Predis\Command\ListIndex',
6338
+ 'LSET' => 'Predis\Command\ListSet',
6339
+ 'LREM' => 'Predis\Command\ListRemove',
6340
+ 'LPOP' => 'Predis\Command\ListPopFirst',
6341
+ 'RPOP' => 'Predis\Command\ListPopLast',
6342
+ 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6343
 
6344
  /* commands operating on sets */
6345
+ 'SADD' => 'Predis\Command\SetAdd',
6346
+ 'SREM' => 'Predis\Command\SetRemove',
6347
+ 'SPOP' => 'Predis\Command\SetPop',
6348
+ 'SMOVE' => 'Predis\Command\SetMove',
6349
+ 'SCARD' => 'Predis\Command\SetCardinality',
6350
+ 'SISMEMBER' => 'Predis\Command\SetIsMember',
6351
+ 'SINTER' => 'Predis\Command\SetIntersection',
6352
+ 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6353
+ 'SUNION' => 'Predis\Command\SetUnion',
6354
+ 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6355
+ 'SDIFF' => 'Predis\Command\SetDifference',
6356
+ 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
6357
+ 'SMEMBERS' => 'Predis\Command\SetMembers',
6358
+ 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
6359
 
6360
  /* commands operating on sorted sets */
6361
+ 'ZADD' => 'Predis\Command\ZSetAdd',
6362
+ 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
6363
+ 'ZREM' => 'Predis\Command\ZSetRemove',
6364
+ 'ZRANGE' => 'Predis\Command\ZSetRange',
6365
+ 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
6366
+ 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
6367
+ 'ZCARD' => 'Predis\Command\ZSetCardinality',
6368
+ 'ZSCORE' => 'Predis\Command\ZSetScore',
6369
+ 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
6370
 
6371
  /* connection related commands */
6372
+ 'PING' => 'Predis\Command\ConnectionPing',
6373
+ 'AUTH' => 'Predis\Command\ConnectionAuth',
6374
+ 'SELECT' => 'Predis\Command\ConnectionSelect',
6375
+ 'ECHO' => 'Predis\Command\ConnectionEcho',
6376
+ 'QUIT' => 'Predis\Command\ConnectionQuit',
6377
 
6378
  /* remote server control commands */
6379
+ 'INFO' => 'Predis\Command\ServerInfoV26x',
6380
+ 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
6381
+ 'MONITOR' => 'Predis\Command\ServerMonitor',
6382
+ 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
6383
+ 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
6384
+ 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
6385
+ 'SAVE' => 'Predis\Command\ServerSave',
6386
+ 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
6387
+ 'LASTSAVE' => 'Predis\Command\ServerLastSave',
6388
+ 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
6389
+ 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
6390
 
6391
  /* ---------------- Redis 2.0 ---------------- */
6392
 
6393
  /* commands operating on string values */
6394
+ 'SETEX' => 'Predis\Command\StringSetExpire',
6395
+ 'APPEND' => 'Predis\Command\StringAppend',
6396
+ 'SUBSTR' => 'Predis\Command\StringSubstr',
6397
 
6398
  /* commands operating on lists */
6399
+ 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
6400
+ 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
6401
 
6402
  /* commands operating on sorted sets */
6403
+ 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
6404
+ 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
6405
+ 'ZCOUNT' => 'Predis\Command\ZSetCount',
6406
+ 'ZRANK' => 'Predis\Command\ZSetRank',
6407
+ 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
6408
+ 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
6409
 
6410
  /* commands operating on hashes */
6411
+ 'HSET' => 'Predis\Command\HashSet',
6412
+ 'HSETNX' => 'Predis\Command\HashSetPreserve',
6413
+ 'HMSET' => 'Predis\Command\HashSetMultiple',
6414
+ 'HINCRBY' => 'Predis\Command\HashIncrementBy',
6415
+ 'HGET' => 'Predis\Command\HashGet',
6416
+ 'HMGET' => 'Predis\Command\HashGetMultiple',
6417
+ 'HDEL' => 'Predis\Command\HashDelete',
6418
+ 'HEXISTS' => 'Predis\Command\HashExists',
6419
+ 'HLEN' => 'Predis\Command\HashLength',
6420
+ 'HKEYS' => 'Predis\Command\HashKeys',
6421
+ 'HVALS' => 'Predis\Command\HashValues',
6422
+ 'HGETALL' => 'Predis\Command\HashGetAll',
6423
 
6424
  /* transactions */
6425
+ 'MULTI' => 'Predis\Command\TransactionMulti',
6426
+ 'EXEC' => 'Predis\Command\TransactionExec',
6427
+ 'DISCARD' => 'Predis\Command\TransactionDiscard',
6428
 
6429
  /* publish - subscribe */
6430
+ 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
6431
+ 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
6432
+ 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
6433
+ 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
6434
+ 'PUBLISH' => 'Predis\Command\PubSubPublish',
6435
 
6436
  /* remote server control commands */
6437
+ 'CONFIG' => 'Predis\Command\ServerConfig',
6438
 
6439
  /* ---------------- Redis 2.2 ---------------- */
6440
 
6441
  /* commands operating on the key space */
6442
+ 'PERSIST' => 'Predis\Command\KeyPersist',
6443
 
6444
  /* commands operating on string values */
6445
+ 'STRLEN' => 'Predis\Command\StringStrlen',
6446
+ 'SETRANGE' => 'Predis\Command\StringSetRange',
6447
+ 'GETRANGE' => 'Predis\Command\StringGetRange',
6448
+ 'SETBIT' => 'Predis\Command\StringSetBit',
6449
+ 'GETBIT' => 'Predis\Command\StringGetBit',
6450
 
6451
  /* commands operating on lists */
6452
+ 'RPUSHX' => 'Predis\Command\ListPushTailX',
6453
+ 'LPUSHX' => 'Predis\Command\ListPushHeadX',
6454
+ 'LINSERT' => 'Predis\Command\ListInsert',
6455
+ 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
6456
 
6457
  /* commands operating on sorted sets */
6458
+ 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
6459
 
6460
  /* transactions */
6461
+ 'WATCH' => 'Predis\Command\TransactionWatch',
6462
+ 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
6463
 
6464
  /* remote server control commands */
6465
+ 'OBJECT' => 'Predis\Command\ServerObject',
6466
+ 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
6467
 
6468
  /* ---------------- Redis 2.4 ---------------- */
6469
 
6470
  /* remote server control commands */
6471
+ 'CLIENT' => 'Predis\Command\ServerClient',
6472
 
6473
  /* ---------------- Redis 2.6 ---------------- */
6474
 
6475
  /* commands operating on the key space */
6476
+ 'PTTL' => 'Predis\Command\KeyPreciseTimeToLive',
6477
+ 'PEXPIRE' => 'Predis\Command\KeyPreciseExpire',
6478
+ 'PEXPIREAT' => 'Predis\Command\KeyPreciseExpireAt',
6479
+ 'MIGRATE' => 'Predis\Command\KeyMigrate',
6480
 
6481
  /* commands operating on string values */
6482
+ 'PSETEX' => 'Predis\Command\StringPreciseSetExpire',
6483
+ 'INCRBYFLOAT' => 'Predis\Command\StringIncrementByFloat',
6484
+ 'BITOP' => 'Predis\Command\StringBitOp',
6485
+ 'BITCOUNT' => 'Predis\Command\StringBitCount',
6486
 
6487
  /* commands operating on hashes */
6488
+ 'HINCRBYFLOAT' => 'Predis\Command\HashIncrementByFloat',
6489
 
6490
  /* scripting */
6491
+ 'EVAL' => 'Predis\Command\ServerEval',
6492
+ 'EVALSHA' => 'Predis\Command\ServerEvalSHA',
6493
+ 'SCRIPT' => 'Predis\Command\ServerScript',
6494
 
6495
  /* remote server control commands */
6496
+ 'TIME' => 'Predis\Command\ServerTime',
6497
+ 'SENTINEL' => 'Predis\Command\ServerSentinel',
6498
 
6499
  /* ---------------- Redis 2.8 ---------------- */
6500
 
6501
  /* commands operating on the key space */
6502
+ 'SCAN' => 'Predis\Command\KeyScan',
6503
 
6504
  /* commands operating on string values */
6505
+ 'BITPOS' => 'Predis\Command\StringBitPos',
6506
 
6507
  /* commands operating on sets */
6508
+ 'SSCAN' => 'Predis\Command\SetScan',
6509
 
6510
  /* commands operating on sorted sets */
6511
+ 'ZSCAN' => 'Predis\Command\ZSetScan',
6512
+ 'ZLEXCOUNT' => 'Predis\Command\ZSetLexCount',
6513
+ 'ZRANGEBYLEX' => 'Predis\Command\ZSetRangeByLex',
6514
+ 'ZREMRANGEBYLEX' => 'Predis\Command\ZSetRemoveRangeByLex',
6515
+ 'ZREVRANGEBYLEX' => 'Predis\Command\ZSetReverseRangeByLex',
6516
 
6517
  /* commands operating on hashes */
6518
+ 'HSCAN' => 'Predis\Command\HashScan',
6519
 
6520
  /* publish - subscribe */
6521
+ 'PUBSUB' => 'Predis\Command\PubSubPubsub',
6522
 
6523
  /* commands operating on HyperLogLog */
6524
+ 'PFADD' => 'Predis\Command\HyperLogLogAdd',
6525
+ 'PFCOUNT' => 'Predis\Command\HyperLogLogCount',
6526
+ 'PFMERGE' => 'Predis\Command\HyperLogLogMerge',
6527
 
6528
  /* remote server control commands */
6529
+ 'COMMAND' => 'Predis\Command\ServerCommand',
6530
 
6531
  /* ---------------- Redis 3.0 ---------------- */
6532
 
6558
  /* ---------------- Redis 1.2 ---------------- */
6559
 
6560
  /* commands operating on the key space */
6561
+ 'EXISTS' => 'Predis\Command\KeyExists',
6562
+ 'DEL' => 'Predis\Command\KeyDelete',
6563
+ 'TYPE' => 'Predis\Command\KeyType',
6564
+ 'KEYS' => 'Predis\Command\KeyKeys',
6565
+ 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6566
+ 'RENAME' => 'Predis\Command\KeyRename',
6567
+ 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6568
+ 'EXPIRE' => 'Predis\Command\KeyExpire',
6569
+ 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6570
+ 'TTL' => 'Predis\Command\KeyTimeToLive',
6571
+ 'MOVE' => 'Predis\Command\KeyMove',
6572
+ 'SORT' => 'Predis\Command\KeySort',
6573
+ 'DUMP' => 'Predis\Command\KeyDump',
6574
+ 'RESTORE' => 'Predis\Command\KeyRestore',
6575
 
6576
  /* commands operating on string values */
6577
+ 'SET' => 'Predis\Command\StringSet',
6578
+ 'SETNX' => 'Predis\Command\StringSetPreserve',
6579
+ 'MSET' => 'Predis\Command\StringSetMultiple',
6580
+ 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6581
+ 'GET' => 'Predis\Command\StringGet',
6582
+ 'MGET' => 'Predis\Command\StringGetMultiple',
6583
+ 'GETSET' => 'Predis\Command\StringGetSet',
6584
+ 'INCR' => 'Predis\Command\StringIncrement',
6585
+ 'INCRBY' => 'Predis\Command\StringIncrementBy',
6586
+ 'DECR' => 'Predis\Command\StringDecrement',
6587
+ 'DECRBY' => 'Predis\Command\StringDecrementBy',
6588
 
6589
  /* commands operating on lists */
6590
+ 'RPUSH' => 'Predis\Command\ListPushTail',
6591
+ 'LPUSH' => 'Predis\Command\ListPushHead',
6592
+ 'LLEN' => 'Predis\Command\ListLength',
6593
+ 'LRANGE' => 'Predis\Command\ListRange',
6594
+ 'LTRIM' => 'Predis\Command\ListTrim',
6595
+ 'LINDEX' => 'Predis\Command\ListIndex',
6596
+ 'LSET' => 'Predis\Command\ListSet',
6597
+ 'LREM' => 'Predis\Command\ListRemove',
6598
+ 'LPOP' => 'Predis\Command\ListPopFirst',
6599
+ 'RPOP' => 'Predis\Command\ListPopLast',
6600
+ 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6601
 
6602
  /* commands operating on sets */
6603
+ 'SADD' => 'Predis\Command\SetAdd',
6604
+ 'SREM' => 'Predis\Command\SetRemove',
6605
+ 'SPOP' => 'Predis\Command\SetPop',
6606
+ 'SMOVE' => 'Predis\Command\SetMove',
6607
+ 'SCARD' => 'Predis\Command\SetCardinality',
6608
+ 'SISMEMBER' => 'Predis\Command\SetIsMember',
6609
+ 'SINTER' => 'Predis\Command\SetIntersection',
6610
+ 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6611
+ 'SUNION' => 'Predis\Command\SetUnion',
6612
+ 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6613
+ 'SDIFF' => 'Predis\Command\SetDifference',
6614
+ 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
6615
+ 'SMEMBERS' => 'Predis\Command\SetMembers',
6616
+ 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
6617
 
6618
  /* commands operating on sorted sets */
6619
+ 'ZADD' => 'Predis\Command\ZSetAdd',
6620
+ 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
6621
+ 'ZREM' => 'Predis\Command\ZSetRemove',
6622
+ 'ZRANGE' => 'Predis\Command\ZSetRange',
6623
+ 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
6624
+ 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
6625
+ 'ZCARD' => 'Predis\Command\ZSetCardinality',
6626
+ 'ZSCORE' => 'Predis\Command\ZSetScore',
6627
+ 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
6628
 
6629
  /* connection related commands */
6630
+ 'PING' => 'Predis\Command\ConnectionPing',
6631
+ 'AUTH' => 'Predis\Command\ConnectionAuth',
6632
+ 'SELECT' => 'Predis\Command\ConnectionSelect',
6633
+ 'ECHO' => 'Predis\Command\ConnectionEcho',
6634
+ 'QUIT' => 'Predis\Command\ConnectionQuit',
6635
 
6636
  /* remote server control commands */
6637
+ 'INFO' => 'Predis\Command\ServerInfoV26x',
6638
+ 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
6639
+ 'MONITOR' => 'Predis\Command\ServerMonitor',
6640
+ 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
6641
+ 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
6642
+ 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
6643
+ 'SAVE' => 'Predis\Command\ServerSave',
6644
+ 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
6645
+ 'LASTSAVE' => 'Predis\Command\ServerLastSave',
6646
+ 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
6647
+ 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
6648
 
6649
  /* ---------------- Redis 2.0 ---------------- */
6650
 
6651
  /* commands operating on string values */
6652
+ 'SETEX' => 'Predis\Command\StringSetExpire',
6653
+ 'APPEND' => 'Predis\Command\StringAppend',
6654
+ 'SUBSTR' => 'Predis\Command\StringSubstr',
6655
 
6656
  /* commands operating on lists */
6657
+ 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
6658
+ 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
6659
 
6660
  /* commands operating on sorted sets */
6661
+ 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
6662
+ 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
6663
+ 'ZCOUNT' => 'Predis\Command\ZSetCount',
6664
+ 'ZRANK' => 'Predis\Command\ZSetRank',
6665
+ 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
6666
+ 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
6667
 
6668
  /* commands operating on hashes */
6669
+ 'HSET' => 'Predis\Command\HashSet',
6670
+ 'HSETNX' => 'Predis\Command\HashSetPreserve',
6671
+ 'HMSET' => 'Predis\Command\HashSetMultiple',
6672
+ 'HINCRBY' => 'Predis\Command\HashIncrementBy',
6673
+ 'HGET' => 'Predis\Command\HashGet',
6674
+ 'HMGET' => 'Predis\Command\HashGetMultiple',
6675
+ 'HDEL' => 'Predis\Command\HashDelete',
6676
+ 'HEXISTS' => 'Predis\Command\HashExists',
6677
+ 'HLEN' => 'Predis\Command\HashLength',
6678
+ 'HKEYS' => 'Predis\Command\HashKeys',
6679
+ 'HVALS' => 'Predis\Command\HashValues',
6680
+ 'HGETALL' => 'Predis\Command\HashGetAll',
6681
 
6682
  /* transactions */
6683
+ 'MULTI' => 'Predis\Command\TransactionMulti',
6684
+ 'EXEC' => 'Predis\Command\TransactionExec',
6685
+ 'DISCARD' => 'Predis\Command\TransactionDiscard',
6686
 
6687
  /* publish - subscribe */
6688
+ 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
6689
+ 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
6690
+ 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
6691
+ 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
6692
+ 'PUBLISH' => 'Predis\Command\PubSubPublish',
6693
 
6694
  /* remote server control commands */
6695
+ 'CONFIG' => 'Predis\Command\ServerConfig',
6696
 
6697
  /* ---------------- Redis 2.2 ---------------- */
6698
 
6699
  /* commands operating on the key space */
6700
+ 'PERSIST' => 'Predis\Command\KeyPersist',
6701
 
6702
  /* commands operating on string values */
6703
+ 'STRLEN' => 'Predis\Command\StringStrlen',
6704
+ 'SETRANGE' => 'Predis\Command\StringSetRange',
6705
+ 'GETRANGE' => 'Predis\Command\StringGetRange',
6706
+ 'SETBIT' => 'Predis\Command\StringSetBit',
6707
+ 'GETBIT' => 'Predis\Command\StringGetBit',
6708
 
6709
  /* commands operating on lists */
6710
+ 'RPUSHX' => 'Predis\Command\ListPushTailX',
6711
+ 'LPUSHX' => 'Predis\Command\ListPushHeadX',
6712
+ 'LINSERT' => 'Predis\Command\ListInsert',
6713
+ 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
6714
 
6715
  /* commands operating on sorted sets */
6716
+ 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
6717
 
6718
  /* transactions */
6719
+ 'WATCH' => 'Predis\Command\TransactionWatch',
6720
+ 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
6721
 
6722
  /* remote server control commands */
6723
+ 'OBJECT' => 'Predis\Command\ServerObject',
6724
+ 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
6725
 
6726
  /* ---------------- Redis 2.4 ---------------- */
6727
 
6728
  /* remote server control commands */
6729
+ 'CLIENT' => 'Predis\Command\ServerClient',
6730
 
6731
  /* ---------------- Redis 2.6 ---------------- */
6732
 
6733
  /* commands operating on the key space */
6734
+ 'PTTL' => 'Predis\Command\KeyPreciseTimeToLive',
6735
+ 'PEXPIRE' => 'Predis\Command\KeyPreciseExpire',
6736
+ 'PEXPIREAT' => 'Predis\Command\KeyPreciseExpireAt',
6737
+ 'MIGRATE' => 'Predis\Command\KeyMigrate',
6738
 
6739
  /* commands operating on string values */
6740
+ 'PSETEX' => 'Predis\Command\StringPreciseSetExpire',
6741
+ 'INCRBYFLOAT' => 'Predis\Command\StringIncrementByFloat',
6742
+ 'BITOP' => 'Predis\Command\StringBitOp',
6743
+ 'BITCOUNT' => 'Predis\Command\StringBitCount',
6744
 
6745
  /* commands operating on hashes */
6746
+ 'HINCRBYFLOAT' => 'Predis\Command\HashIncrementByFloat',
6747
 
6748
  /* scripting */
6749
+ 'EVAL' => 'Predis\Command\ServerEval',
6750
+ 'EVALSHA' => 'Predis\Command\ServerEvalSHA',
6751
+ 'SCRIPT' => 'Predis\Command\ServerScript',
6752
 
6753
  /* remote server control commands */
6754
+ 'TIME' => 'Predis\Command\ServerTime',
6755
+ 'SENTINEL' => 'Predis\Command\ServerSentinel',
6756
  );
6757
  }
6758
  }
6781
  /* ---------------- Redis 1.2 ---------------- */
6782
 
6783
  /* commands operating on the key space */
6784
+ 'EXISTS' => 'Predis\Command\KeyExists',
6785
+ 'DEL' => 'Predis\Command\KeyDelete',
6786
+ 'TYPE' => 'Predis\Command\KeyType',
6787
+ 'KEYS' => 'Predis\Command\KeyKeys',
6788
+ 'RANDOMKEY' => 'Predis\Command\KeyRandom',
6789
+ 'RENAME' => 'Predis\Command\KeyRename',
6790
+ 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
6791
+ 'EXPIRE' => 'Predis\Command\KeyExpire',
6792
+ 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
6793
+ 'TTL' => 'Predis\Command\KeyTimeToLive',
6794
+ 'MOVE' => 'Predis\Command\KeyMove',
6795
+ 'SORT' => 'Predis\Command\KeySort',
6796
+ 'DUMP' => 'Predis\Command\KeyDump',
6797
+ 'RESTORE' => 'Predis\Command\KeyRestore',
6798
 
6799
  /* commands operating on string values */
6800
+ 'SET' => 'Predis\Command\StringSet',
6801
+ 'SETNX' => 'Predis\Command\StringSetPreserve',
6802
+ 'MSET' => 'Predis\Command\StringSetMultiple',
6803
+ 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
6804
+ 'GET' => 'Predis\Command\StringGet',
6805
+ 'MGET' => 'Predis\Command\StringGetMultiple',
6806
+ 'GETSET' => 'Predis\Command\StringGetSet',
6807
+ 'INCR' => 'Predis\Command\StringIncrement',
6808
+ 'INCRBY' => 'Predis\Command\StringIncrementBy',
6809
+ 'DECR' => 'Predis\Command\StringDecrement',
6810
+ 'DECRBY' => 'Predis\Command\StringDecrementBy',
6811
 
6812
  /* commands operating on lists */
6813
+ 'RPUSH' => 'Predis\Command\ListPushTail',
6814
+ 'LPUSH' => 'Predis\Command\ListPushHead',
6815
+ 'LLEN' => 'Predis\Command\ListLength',
6816
+ 'LRANGE' => 'Predis\Command\ListRange',
6817
+ 'LTRIM' => 'Predis\Command\ListTrim',
6818
+ 'LINDEX' => 'Predis\Command\ListIndex',
6819
+ 'LSET' => 'Predis\Command\ListSet',
6820
+ 'LREM' => 'Predis\Command\ListRemove',
6821
+ 'LPOP' => 'Predis\Command\ListPopFirst',
6822
+ 'RPOP' => 'Predis\Command\ListPopLast',
6823
+ 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
6824
 
6825
  /* commands operating on sets */
6826
+ 'SADD' => 'Predis\Command\SetAdd',
6827
+ 'SREM' => 'Predis\Command\SetRemove',
6828
+ 'SPOP' => 'Predis\Command\SetPop',
6829
+ 'SMOVE' => 'Predis\Command\SetMove',
6830
+ 'SCARD' => 'Predis\Command\SetCardinality',
6831
+ 'SISMEMBER' => 'Predis\Command\SetIsMember',
6832
+ 'SINTER' => 'Predis\Command\SetIntersection',
6833
+ 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
6834
+ 'SUNION' => 'Predis\Command\SetUnion',
6835
+ 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
6836
+ 'SDIFF' => 'Predis\Command\SetDifference',
6837
+ 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
6838
+ 'SMEMBERS' => 'Predis\Command\SetMembers',
6839
+ 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
6840
 
6841
  /* commands operating on sorted sets */
6842
+ 'ZADD' => 'Predis\Command\ZSetAdd',
6843
+ 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
6844
+ 'ZREM' => 'Predis\Command\ZSetRemove',
6845
+ 'ZRANGE' => 'Predis\Command\ZSetRange',
6846
+ 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
6847
+ 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
6848
+ 'ZCARD' => 'Predis\Command\ZSetCardinality',
6849
+ 'ZSCORE' => 'Predis\Command\ZSetScore',
6850
+ 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
6851
 
6852
  /* connection related commands */
6853
+ 'PING' => 'Predis\Command\ConnectionPing',
6854
+ 'AUTH' => 'Predis\Command\ConnectionAuth',
6855
+ 'SELECT' => 'Predis\Command\ConnectionSelect',
6856
+ 'ECHO' => 'Predis\Command\ConnectionEcho',
6857
+ 'QUIT' => 'Predis\Command\ConnectionQuit',
6858
 
6859
  /* remote server control commands */
6860
+ 'INFO' => 'Predis\Command\ServerInfoV26x',
6861
+ 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
6862
+ 'MONITOR' => 'Predis\Command\ServerMonitor',
6863
+ 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
6864
+ 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
6865
+ 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
6866
+ 'SAVE' => 'Predis\Command\ServerSave',
6867
+ 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
6868
+ 'LASTSAVE' => 'Predis\Command\ServerLastSave',
6869
+ 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
6870
+ 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
6871
 
6872
  /* ---------------- Redis 2.0 ---------------- */
6873
 
6874
  /* commands operating on string values */
6875
+ 'SETEX' => 'Predis\Command\StringSetExpire',
6876
+ 'APPEND' => 'Predis\Command\StringAppend',
6877
+ 'SUBSTR' => 'Predis\Command\StringSubstr',
6878
 
6879
  /* commands operating on lists */
6880
+ 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
6881
+ 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
6882
 
6883
  /* commands operating on sorted sets */
6884
+ 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
6885
+ 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
6886
+ 'ZCOUNT' => 'Predis\Command\ZSetCount',
6887
+ 'ZRANK' => 'Predis\Command\ZSetRank',
6888
+ 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
6889
+ 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
6890
 
6891
  /* commands operating on hashes */
6892
+ 'HSET' => 'Predis\Command\HashSet',
6893
+ 'HSETNX' => 'Predis\Command\HashSetPreserve',
6894
+ 'HMSET' => 'Predis\Command\HashSetMultiple',
6895
+ 'HINCRBY' => 'Predis\Command\HashIncrementBy',
6896
+ 'HGET' => 'Predis\Command\HashGet',
6897
+ 'HMGET' => 'Predis\Command\HashGetMultiple',
6898
+ 'HDEL' => 'Predis\Command\HashDelete',
6899
+ 'HEXISTS' => 'Predis\Command\HashExists',
6900
+ 'HLEN' => 'Predis\Command\HashLength',
6901
+ 'HKEYS' => 'Predis\Command\HashKeys',
6902
+ 'HVALS' => 'Predis\Command\HashValues',
6903
+ 'HGETALL' => 'Predis\Command\HashGetAll',
6904
 
6905
  /* transactions */
6906
+ 'MULTI' => 'Predis\Command\TransactionMulti',
6907
+ 'EXEC' => 'Predis\Command\TransactionExec',
6908
+ 'DISCARD' => 'Predis\Command\TransactionDiscard',
6909
 
6910
  /* publish - subscribe */
6911
+ 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
6912
+ 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
6913
+ 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
6914
+ 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
6915
+ 'PUBLISH' => 'Predis\Command\PubSubPublish',
6916
 
6917
  /* remote server control commands */
6918
+ 'CONFIG' => 'Predis\Command\ServerConfig',
6919
 
6920
  /* ---------------- Redis 2.2 ---------------- */
6921
 
6922
  /* commands operating on the key space */
6923
+ 'PERSIST' => 'Predis\Command\KeyPersist',
6924
 
6925
  /* commands operating on string values */
6926
+ 'STRLEN' => 'Predis\Command\StringStrlen',
6927
+ 'SETRANGE' => 'Predis\Command\StringSetRange',
6928
+ 'GETRANGE' => 'Predis\Command\StringGetRange',
6929
+ 'SETBIT' => 'Predis\Command\StringSetBit',
6930
+ 'GETBIT' => 'Predis\Command\StringGetBit',
6931
 
6932
  /* commands operating on lists */
6933
+ 'RPUSHX' => 'Predis\Command\ListPushTailX',
6934
+ 'LPUSHX' => 'Predis\Command\ListPushHeadX',
6935
+ 'LINSERT' => 'Predis\Command\ListInsert',
6936
+ 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
6937
 
6938
  /* commands operating on sorted sets */
6939
+ 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
6940
 
6941
  /* transactions */
6942
+ 'WATCH' => 'Predis\Command\TransactionWatch',
6943
+ 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
6944
 
6945
  /* remote server control commands */
6946
+ 'OBJECT' => 'Predis\Command\ServerObject',
6947
+ 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
6948
 
6949
  /* ---------------- Redis 2.4 ---------------- */
6950
 
6951
  /* remote server control commands */
6952
+ 'CLIENT' => 'Predis\Command\ServerClient',
6953
 
6954
  /* ---------------- Redis 2.6 ---------------- */
6955
 
6956
  /* commands operating on the key space */
6957
+ 'PTTL' => 'Predis\Command\KeyPreciseTimeToLive',
6958
+ 'PEXPIRE' => 'Predis\Command\KeyPreciseExpire',
6959
+ 'PEXPIREAT' => 'Predis\Command\KeyPreciseExpireAt',
6960
+ 'MIGRATE' => 'Predis\Command\KeyMigrate',
6961
 
6962
  /* commands operating on string values */
6963
+ 'PSETEX' => 'Predis\Command\StringPreciseSetExpire',
6964
+ 'INCRBYFLOAT' => 'Predis\Command\StringIncrementByFloat',
6965
+ 'BITOP' => 'Predis\Command\StringBitOp',
6966
+ 'BITCOUNT' => 'Predis\Command\StringBitCount',
6967
 
6968
  /* commands operating on hashes */
6969
+ 'HINCRBYFLOAT' => 'Predis\Command\HashIncrementByFloat',
6970
 
6971
  /* scripting */
6972
+ 'EVAL' => 'Predis\Command\ServerEval',
6973
+ 'EVALSHA' => 'Predis\Command\ServerEvalSHA',
6974
+ 'SCRIPT' => 'Predis\Command\ServerScript',
6975
 
6976
  /* remote server control commands */
6977
+ 'TIME' => 'Predis\Command\ServerTime',
6978
+ 'SENTINEL' => 'Predis\Command\ServerSentinel',
6979
 
6980
  /* ---------------- Redis 2.8 ---------------- */
6981
 
6982
  /* commands operating on the key space */
6983
+ 'SCAN' => 'Predis\Command\KeyScan',
6984
 
6985
  /* commands operating on string values */
6986
+ 'BITPOS' => 'Predis\Command\StringBitPos',
6987
 
6988
  /* commands operating on sets */
6989
+ 'SSCAN' => 'Predis\Command\SetScan',
6990
 
6991
  /* commands operating on sorted sets */
6992
+ 'ZSCAN' => 'Predis\Command\ZSetScan',
6993
+ 'ZLEXCOUNT' => 'Predis\Command\ZSetLexCount',
6994
+ 'ZRANGEBYLEX' => 'Predis\Command\ZSetRangeByLex',
6995
+ 'ZREMRANGEBYLEX' => 'Predis\Command\ZSetRemoveRangeByLex',
6996
+ 'ZREVRANGEBYLEX' => 'Predis\Command\ZSetReverseRangeByLex',
6997
 
6998
  /* commands operating on hashes */
6999
+ 'HSCAN' => 'Predis\Command\HashScan',
7000
 
7001
  /* publish - subscribe */
7002
+ 'PUBSUB' => 'Predis\Command\PubSubPubsub',
7003
 
7004
  /* commands operating on HyperLogLog */
7005
+ 'PFADD' => 'Predis\Command\HyperLogLogAdd',
7006
+ 'PFCOUNT' => 'Predis\Command\HyperLogLogCount',
7007
+ 'PFMERGE' => 'Predis\Command\HyperLogLogMerge',
7008
 
7009
  /* remote server control commands */
7010
+ 'COMMAND' => 'Predis\Command\ServerCommand',
7011
  );
7012
  }
7013
  }
7036
  /* ---------------- Redis 1.2 ---------------- */
7037
 
7038
  /* commands operating on the key space */
7039
+ 'EXISTS' => 'Predis\Command\KeyExists',
7040
+ 'DEL' => 'Predis\Command\KeyDelete',
7041
+ 'TYPE' => 'Predis\Command\KeyType',
7042
+ 'KEYS' => 'Predis\Command\KeyKeys',
7043
+ 'RANDOMKEY' => 'Predis\Command\KeyRandom',
7044
+ 'RENAME' => 'Predis\Command\KeyRename',
7045
+ 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
7046
+ 'EXPIRE' => 'Predis\Command\KeyExpire',
7047
+ 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
7048
+ 'TTL' => 'Predis\Command\KeyTimeToLive',
7049
+ 'MOVE' => 'Predis\Command\KeyMove',
7050
+ 'SORT' => 'Predis\Command\KeySort',
7051
 
7052
  /* commands operating on string values */
7053
+ 'SET' => 'Predis\Command\StringSet',
7054
+ 'SETNX' => 'Predis\Command\StringSetPreserve',
7055
+ 'MSET' => 'Predis\Command\StringSetMultiple',
7056
+ 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
7057
+ 'GET' => 'Predis\Command\StringGet',
7058
+ 'MGET' => 'Predis\Command\StringGetMultiple',
7059
+ 'GETSET' => 'Predis\Command\StringGetSet',
7060
+ 'INCR' => 'Predis\Command\StringIncrement',
7061
+ 'INCRBY' => 'Predis\Command\StringIncrementBy',
7062
+ 'DECR' => 'Predis\Command\StringDecrement',
7063
+ 'DECRBY' => 'Predis\Command\StringDecrementBy',
7064
 
7065
  /* commands operating on lists */
7066
+ 'RPUSH' => 'Predis\Command\ListPushTail',
7067
+ 'LPUSH' => 'Predis\Command\ListPushHead',
7068
+ 'LLEN' => 'Predis\Command\ListLength',
7069
+ 'LRANGE' => 'Predis\Command\ListRange',
7070
+ 'LTRIM' => 'Predis\Command\ListTrim',
7071
+ 'LINDEX' => 'Predis\Command\ListIndex',
7072
+ 'LSET' => 'Predis\Command\ListSet',
7073
+ 'LREM' => 'Predis\Command\ListRemove',
7074
+ 'LPOP' => 'Predis\Command\ListPopFirst',
7075
+ 'RPOP' => 'Predis\Command\ListPopLast',
7076
+ 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
7077
 
7078
  /* commands operating on sets */
7079
+ 'SADD' => 'Predis\Command\SetAdd',
7080
+ 'SREM' => 'Predis\Command\SetRemove',
7081
+ 'SPOP' => 'Predis\Command\SetPop',
7082
+ 'SMOVE' => 'Predis\Command\SetMove',
7083
+ 'SCARD' => 'Predis\Command\SetCardinality',
7084
+ 'SISMEMBER' => 'Predis\Command\SetIsMember',
7085
+ 'SINTER' => 'Predis\Command\SetIntersection',
7086
+ 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
7087
+ 'SUNION' => 'Predis\Command\SetUnion',
7088
+ 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
7089
+ 'SDIFF' => 'Predis\Command\SetDifference',
7090
+ 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
7091
+ 'SMEMBERS' => 'Predis\Command\SetMembers',
7092
+ 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
7093
 
7094
  /* commands operating on sorted sets */
7095
+ 'ZADD' => 'Predis\Command\ZSetAdd',
7096
+ 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
7097
+ 'ZREM' => 'Predis\Command\ZSetRemove',
7098
+ 'ZRANGE' => 'Predis\Command\ZSetRange',
7099
+ 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
7100
+ 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
7101
+ 'ZCARD' => 'Predis\Command\ZSetCardinality',
7102
+ 'ZSCORE' => 'Predis\Command\ZSetScore',
7103
+ 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
7104
 
7105
  /* connection related commands */
7106
+ 'PING' => 'Predis\Command\ConnectionPing',
7107
+ 'AUTH' => 'Predis\Command\ConnectionAuth',
7108
+ 'SELECT' => 'Predis\Command\ConnectionSelect',
7109
+ 'ECHO' => 'Predis\Command\ConnectionEcho',
7110
+ 'QUIT' => 'Predis\Command\ConnectionQuit',
7111
 
7112
  /* remote server control commands */
7113
+ 'INFO' => 'Predis\Command\ServerInfo',
7114
+ 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
7115
+ 'MONITOR' => 'Predis\Command\ServerMonitor',
7116
+ 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
7117
+ 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
7118
+ 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
7119
+ 'SAVE' => 'Predis\Command\ServerSave',
7120
+ 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
7121
+ 'LASTSAVE' => 'Predis\Command\ServerLastSave',
7122
+ 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
7123
+ 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
7124
 
7125
  /* ---------------- Redis 2.0 ---------------- */
7126
 
7127
  /* commands operating on string values */
7128
+ 'SETEX' => 'Predis\Command\StringSetExpire',
7129
+ 'APPEND' => 'Predis\Command\StringAppend',
7130
+ 'SUBSTR' => 'Predis\Command\StringSubstr',
7131
 
7132
  /* commands operating on lists */
7133
+ 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
7134
+ 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
7135
 
7136
  /* commands operating on sorted sets */
7137
+ 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
7138
+ 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
7139
+ 'ZCOUNT' => 'Predis\Command\ZSetCount',
7140
+ 'ZRANK' => 'Predis\Command\ZSetRank',
7141
+ 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
7142
+ 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
7143
 
7144
  /* commands operating on hashes */
7145
+ 'HSET' => 'Predis\Command\HashSet',
7146
+ 'HSETNX' => 'Predis\Command\HashSetPreserve',
7147
+ 'HMSET' => 'Predis\Command\HashSetMultiple',
7148
+ 'HINCRBY' => 'Predis\Command\HashIncrementBy',
7149
+ 'HGET' => 'Predis\Command\HashGet',
7150
+ 'HMGET' => 'Predis\Command\HashGetMultiple',
7151
+ 'HDEL' => 'Predis\Command\HashDelete',
7152
+ 'HEXISTS' => 'Predis\Command\HashExists',
7153
+ 'HLEN' => 'Predis\Command\HashLength',
7154
+ 'HKEYS' => 'Predis\Command\HashKeys',
7155
+ 'HVALS' => 'Predis\Command\HashValues',
7156
+ 'HGETALL' => 'Predis\Command\HashGetAll',
7157
 
7158
  /* transactions */
7159
+ 'MULTI' => 'Predis\Command\TransactionMulti',
7160
+ 'EXEC' => 'Predis\Command\TransactionExec',
7161
+ 'DISCARD' => 'Predis\Command\TransactionDiscard',
7162
 
7163
  /* publish - subscribe */
7164
+ 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
7165
+ 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
7166
+ 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
7167
+ 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
7168
+ 'PUBLISH' => 'Predis\Command\PubSubPublish',
7169
 
7170
  /* remote server control commands */
7171
+ 'CONFIG' => 'Predis\Command\ServerConfig',
7172
 
7173
  /* ---------------- Redis 2.2 ---------------- */
7174
 
7175
  /* commands operating on the key space */
7176
+ 'PERSIST' => 'Predis\Command\KeyPersist',
7177
 
7178
  /* commands operating on string values */
7179
+ 'STRLEN' => 'Predis\Command\StringStrlen',
7180
+ 'SETRANGE' => 'Predis\Command\StringSetRange',
7181
+ 'GETRANGE' => 'Predis\Command\StringGetRange',
7182
+ 'SETBIT' => 'Predis\Command\StringSetBit',
7183
+ 'GETBIT' => 'Predis\Command\StringGetBit',
7184
 
7185
  /* commands operating on lists */
7186
+ 'RPUSHX' => 'Predis\Command\ListPushTailX',
7187
+ 'LPUSHX' => 'Predis\Command\ListPushHeadX',
7188
+ 'LINSERT' => 'Predis\Command\ListInsert',
7189
+ 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
7190
 
7191
  /* commands operating on sorted sets */
7192
+ 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
7193
 
7194
  /* transactions */
7195
+ 'WATCH' => 'Predis\Command\TransactionWatch',
7196
+ 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
7197
 
7198
  /* remote server control commands */
7199
+ 'OBJECT' => 'Predis\Command\ServerObject',
7200
+ 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
7201
 
7202
  /* ---------------- Redis 2.4 ---------------- */
7203
 
7204
  /* remote server control commands */
7205
+ 'CLIENT' => 'Predis\Command\ServerClient',
7206
  );
7207
  }
7208
  }
7231
  /* ---------------- Redis 1.2 ---------------- */
7232
 
7233
  /* commands operating on the key space */
7234
+ 'EXISTS' => 'Predis\Command\KeyExists',
7235
+ 'DEL' => 'Predis\Command\KeyDelete',
7236
+ 'TYPE' => 'Predis\Command\KeyType',
7237
+ 'KEYS' => 'Predis\Command\KeyKeys',
7238
+ 'RANDOMKEY' => 'Predis\Command\KeyRandom',
7239
+ 'RENAME' => 'Predis\Command\KeyRename',
7240
+ 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
7241
+ 'EXPIRE' => 'Predis\Command\KeyExpire',
7242
+ 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
7243
+ 'TTL' => 'Predis\Command\KeyTimeToLive',
7244
+ 'MOVE' => 'Predis\Command\KeyMove',
7245
+ 'SORT' => 'Predis\Command\KeySort',
7246
 
7247
  /* commands operating on string values */
7248
+ 'SET' => 'Predis\Command\StringSet',
7249
+ 'SETNX' => 'Predis\Command\StringSetPreserve',
7250
+ 'MSET' => 'Predis\Command\StringSetMultiple',
7251
+ 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
7252
+ 'GET' => 'Predis\Command\StringGet',
7253
+ 'MGET' => 'Predis\Command\StringGetMultiple',
7254
+ 'GETSET' => 'Predis\Command\StringGetSet',
7255
+ 'INCR' => 'Predis\Command\StringIncrement',
7256
+ 'INCRBY' => 'Predis\Command\StringIncrementBy',
7257
+ 'DECR' => 'Predis\Command\StringDecrement',
7258
+ 'DECRBY' => 'Predis\Command\StringDecrementBy',
7259
 
7260
  /* commands operating on lists */
7261
+ 'RPUSH' => 'Predis\Command\ListPushTail',
7262
+ 'LPUSH' => 'Predis\Command\ListPushHead',
7263
+ 'LLEN' => 'Predis\Command\ListLength',
7264
+ 'LRANGE' => 'Predis\Command\ListRange',
7265
+ 'LTRIM' => 'Predis\Command\ListTrim',
7266
+ 'LINDEX' => 'Predis\Command\ListIndex',
7267
+ 'LSET' => 'Predis\Command\ListSet',
7268
+ 'LREM' => 'Predis\Command\ListRemove',
7269
+ 'LPOP' => 'Predis\Command\ListPopFirst',
7270
+ 'RPOP' => 'Predis\Command\ListPopLast',
7271
+ 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
7272
 
7273
  /* commands operating on sets */
7274
+ 'SADD' => 'Predis\Command\SetAdd',
7275
+ 'SREM' => 'Predis\Command\SetRemove',
7276
+ 'SPOP' => 'Predis\Command\SetPop',
7277
+ 'SMOVE' => 'Predis\Command\SetMove',
7278
+ 'SCARD' => 'Predis\Command\SetCardinality',
7279
+ 'SISMEMBER' => 'Predis\Command\SetIsMember',
7280
+ 'SINTER' => 'Predis\Command\SetIntersection',
7281
+ 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
7282
+ 'SUNION' => 'Predis\Command\SetUnion',
7283
+ 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
7284
+ 'SDIFF' => 'Predis\Command\SetDifference',
7285
+ 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
7286
+ 'SMEMBERS' => 'Predis\Command\SetMembers',
7287
+ 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
7288
 
7289
  /* commands operating on sorted sets */
7290
+ 'ZADD' => 'Predis\Command\ZSetAdd',
7291
+ 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
7292
+ 'ZREM' => 'Predis\Command\ZSetRemove',
7293
+ 'ZRANGE' => 'Predis\Command\ZSetRange',
7294
+ 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
7295
+ 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
7296
+ 'ZCARD' => 'Predis\Command\ZSetCardinality',
7297
+ 'ZSCORE' => 'Predis\Command\ZSetScore',
7298
+ 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
7299
 
7300
  /* connection related commands */
7301
+ 'PING' => 'Predis\Command\ConnectionPing',
7302
+ 'AUTH' => 'Predis\Command\ConnectionAuth',
7303
+ 'SELECT' => 'Predis\Command\ConnectionSelect',
7304
+ 'ECHO' => 'Predis\Command\ConnectionEcho',
7305
+ 'QUIT' => 'Predis\Command\ConnectionQuit',
7306
 
7307
  /* remote server control commands */
7308
+ 'INFO' => 'Predis\Command\ServerInfo',
7309
+ 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
7310
+ 'MONITOR' => 'Predis\Command\ServerMonitor',
7311
+ 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
7312
+ 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
7313
+ 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
7314
+ 'SAVE' => 'Predis\Command\ServerSave',
7315
+ 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
7316
+ 'LASTSAVE' => 'Predis\Command\ServerLastSave',
7317
+ 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
7318
+ 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
7319
 
7320
  /* ---------------- Redis 2.0 ---------------- */
7321
 
7322
  /* commands operating on string values */
7323
+ 'SETEX' => 'Predis\Command\StringSetExpire',
7324
+ 'APPEND' => 'Predis\Command\StringAppend',
7325
+ 'SUBSTR' => 'Predis\Command\StringSubstr',
7326
 
7327
  /* commands operating on lists */
7328
+ 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
7329
+ 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
7330
 
7331
  /* commands operating on sorted sets */
7332
+ 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
7333
+ 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
7334
+ 'ZCOUNT' => 'Predis\Command\ZSetCount',
7335
+ 'ZRANK' => 'Predis\Command\ZSetRank',
7336
+ 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
7337
+ 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
7338
 
7339
  /* commands operating on hashes */
7340
+ 'HSET' => 'Predis\Command\HashSet',
7341
+ 'HSETNX' => 'Predis\Command\HashSetPreserve',
7342
+ 'HMSET' => 'Predis\Command\HashSetMultiple',
7343
+ 'HINCRBY' => 'Predis\Command\HashIncrementBy',
7344
+ 'HGET' => 'Predis\Command\HashGet',
7345
+ 'HMGET' => 'Predis\Command\HashGetMultiple',
7346
+ 'HDEL' => 'Predis\Command\HashDelete',
7347
+ 'HEXISTS' => 'Predis\Command\HashExists',
7348
+ 'HLEN' => 'Predis\Command\HashLength',
7349
+ 'HKEYS' => 'Predis\Command\HashKeys',
7350
+ 'HVALS' => 'Predis\Command\HashValues',
7351
+ 'HGETALL' => 'Predis\Command\HashGetAll',
7352
 
7353
  /* transactions */
7354
+ 'MULTI' => 'Predis\Command\TransactionMulti',
7355
+ 'EXEC' => 'Predis\Command\TransactionExec',
7356
+ 'DISCARD' => 'Predis\Command\TransactionDiscard',
7357
 
7358
  /* publish - subscribe */
7359
+ 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
7360
+ 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
7361
+ 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
7362
+ 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
7363
+ 'PUBLISH' => 'Predis\Command\PubSubPublish',
7364
 
7365
  /* remote server control commands */
7366
+ 'CONFIG' => 'Predis\Command\ServerConfig',
7367
  );
7368
  }
7369
  }
7380
  */
7381
  public function getVersion()
7382
  {
7383
+ return '3.2';
7384
  }
7385
 
7386
  /**
7388
  */
7389
  public function getSupportedCommands()
7390
  {
7391
+ return array_merge(parent::getSupportedCommands(), array(
7392
+ /* ---------------- Redis 3.2 ---------------- */
7393
+
7394
+ /* commands operating on hashes */
7395
+ 'HSTRLEN' => 'Predis\Command\HashStringLength',
7396
+ ));
7397
  }
7398
  }
7399
 
7405
  final class Factory
7406
  {
7407
  private static $profiles = array(
7408
+ '2.0' => 'Predis\Profile\RedisVersion200',
7409
+ '2.2' => 'Predis\Profile\RedisVersion220',
7410
+ '2.4' => 'Predis\Profile\RedisVersion240',
7411
+ '2.6' => 'Predis\Profile\RedisVersion260',
7412
+ '2.8' => 'Predis\Profile\RedisVersion280',
7413
+ '3.0' => 'Predis\Profile\RedisVersion300',
7414
+ 'dev' => 'Predis\Profile\RedisUnstable',
7415
  'default' => 'Predis\Profile\RedisVersion300',
 
7416
  );
7417
 
7418
  /**
7453
  */
7454
  public static function define($alias, $class)
7455
  {
7456
+ $reflection = new \ReflectionClass($class);
7457
 
7458
  if (!$reflection->isSubclassOf('Predis\Profile\ProfileInterface')) {
7459
+ throw new \InvalidArgumentException("The class '$class' is not a valid profile class.");
7460
  }
7461
 
7462
  self::$profiles[$alias] = $class;
7467
  *
7468
  * @param string $version Profile version or alias.
7469
  *
 
 
7470
  * @throws ClientException
7471
+ *
7472
+ * @return ProfileInterface
7473
  */
7474
  public static function get($version)
7475
  {
7507
  /* ---------------- Redis 1.2 ---------------- */
7508
 
7509
  /* commands operating on the key space */
7510
+ 'EXISTS' => 'Predis\Command\KeyExists',
7511
+ 'DEL' => 'Predis\Command\KeyDelete',
7512
+ 'TYPE' => 'Predis\Command\KeyType',
7513
+ 'KEYS' => 'Predis\Command\KeyKeys',
7514
+ 'RANDOMKEY' => 'Predis\Command\KeyRandom',
7515
+ 'RENAME' => 'Predis\Command\KeyRename',
7516
+ 'RENAMENX' => 'Predis\Command\KeyRenamePreserve',
7517
+ 'EXPIRE' => 'Predis\Command\KeyExpire',
7518
+ 'EXPIREAT' => 'Predis\Command\KeyExpireAt',
7519
+ 'TTL' => 'Predis\Command\KeyTimeToLive',
7520
+ 'MOVE' => 'Predis\Command\KeyMove',
7521
+ 'SORT' => 'Predis\Command\KeySort',
7522
 
7523
  /* commands operating on string values */
7524
+ 'SET' => 'Predis\Command\StringSet',
7525
+ 'SETNX' => 'Predis\Command\StringSetPreserve',
7526
+ 'MSET' => 'Predis\Command\StringSetMultiple',
7527
+ 'MSETNX' => 'Predis\Command\StringSetMultiplePreserve',
7528
+ 'GET' => 'Predis\Command\StringGet',
7529
+ 'MGET' => 'Predis\Command\StringGetMultiple',
7530
+ 'GETSET' => 'Predis\Command\StringGetSet',
7531
+ 'INCR' => 'Predis\Command\StringIncrement',
7532
+ 'INCRBY' => 'Predis\Command\StringIncrementBy',
7533
+ 'DECR' => 'Predis\Command\StringDecrement',
7534
+ 'DECRBY' => 'Predis\Command\StringDecrementBy',
7535
 
7536
  /* commands operating on lists */
7537
+ 'RPUSH' => 'Predis\Command\ListPushTail',
7538
+ 'LPUSH' => 'Predis\Command\ListPushHead',
7539
+ 'LLEN' => 'Predis\Command\ListLength',
7540
+ 'LRANGE' => 'Predis\Command\ListRange',
7541
+ 'LTRIM' => 'Predis\Command\ListTrim',
7542
+ 'LINDEX' => 'Predis\Command\ListIndex',
7543
+ 'LSET' => 'Predis\Command\ListSet',
7544
+ 'LREM' => 'Predis\Command\ListRemove',
7545
+ 'LPOP' => 'Predis\Command\ListPopFirst',
7546
+ 'RPOP' => 'Predis\Command\ListPopLast',
7547
+ 'RPOPLPUSH' => 'Predis\Command\ListPopLastPushHead',
7548
 
7549
  /* commands operating on sets */
7550
+ 'SADD' => 'Predis\Command\SetAdd',
7551
+ 'SREM' => 'Predis\Command\SetRemove',
7552
+ 'SPOP' => 'Predis\Command\SetPop',
7553
+ 'SMOVE' => 'Predis\Command\SetMove',
7554
+ 'SCARD' => 'Predis\Command\SetCardinality',
7555
+ 'SISMEMBER' => 'Predis\Command\SetIsMember',
7556
+ 'SINTER' => 'Predis\Command\SetIntersection',
7557
+ 'SINTERSTORE' => 'Predis\Command\SetIntersectionStore',
7558
+ 'SUNION' => 'Predis\Command\SetUnion',
7559
+ 'SUNIONSTORE' => 'Predis\Command\SetUnionStore',
7560
+ 'SDIFF' => 'Predis\Command\SetDifference',
7561
+ 'SDIFFSTORE' => 'Predis\Command\SetDifferenceStore',
7562
+ 'SMEMBERS' => 'Predis\Command\SetMembers',
7563
+ 'SRANDMEMBER' => 'Predis\Command\SetRandomMember',
7564
 
7565
  /* commands operating on sorted sets */
7566
+ 'ZADD' => 'Predis\Command\ZSetAdd',
7567
+ 'ZINCRBY' => 'Predis\Command\ZSetIncrementBy',
7568
+ 'ZREM' => 'Predis\Command\ZSetRemove',
7569
+ 'ZRANGE' => 'Predis\Command\ZSetRange',
7570
+ 'ZREVRANGE' => 'Predis\Command\ZSetReverseRange',
7571
+ 'ZRANGEBYSCORE' => 'Predis\Command\ZSetRangeByScore',
7572
+ 'ZCARD' => 'Predis\Command\ZSetCardinality',
7573
+ 'ZSCORE' => 'Predis\Command\ZSetScore',
7574
+ 'ZREMRANGEBYSCORE' => 'Predis\Command\ZSetRemoveRangeByScore',
7575
 
7576
  /* connection related commands */
7577
+ 'PING' => 'Predis\Command\ConnectionPing',
7578
+ 'AUTH' => 'Predis\Command\ConnectionAuth',
7579
+ 'SELECT' => 'Predis\Command\ConnectionSelect',
7580
+ 'ECHO' => 'Predis\Command\ConnectionEcho',
7581
+ 'QUIT' => 'Predis\Command\ConnectionQuit',
7582
 
7583
  /* remote server control commands */
7584
+ 'INFO' => 'Predis\Command\ServerInfo',
7585
+ 'SLAVEOF' => 'Predis\Command\ServerSlaveOf',
7586
+ 'MONITOR' => 'Predis\Command\ServerMonitor',
7587
+ 'DBSIZE' => 'Predis\Command\ServerDatabaseSize',
7588
+ 'FLUSHDB' => 'Predis\Command\ServerFlushDatabase',
7589
+ 'FLUSHALL' => 'Predis\Command\ServerFlushAll',
7590
+ 'SAVE' => 'Predis\Command\ServerSave',
7591
+ 'BGSAVE' => 'Predis\Command\ServerBackgroundSave',
7592
+ 'LASTSAVE' => 'Predis\Command\ServerLastSave',
7593
+ 'SHUTDOWN' => 'Predis\Command\ServerShutdown',
7594
+ 'BGREWRITEAOF' => 'Predis\Command\ServerBackgroundRewriteAOF',
7595
 
7596
  /* ---------------- Redis 2.0 ---------------- */
7597
 
7598
  /* commands operating on string values */
7599
+ 'SETEX' => 'Predis\Command\StringSetExpire',
7600
+ 'APPEND' => 'Predis\Command\StringAppend',
7601
+ 'SUBSTR' => 'Predis\Command\StringSubstr',
7602
 
7603
  /* commands operating on lists */
7604
+ 'BLPOP' => 'Predis\Command\ListPopFirstBlocking',
7605
+ 'BRPOP' => 'Predis\Command\ListPopLastBlocking',
7606
 
7607
  /* commands operating on sorted sets */
7608
+ 'ZUNIONSTORE' => 'Predis\Command\ZSetUnionStore',
7609
+ 'ZINTERSTORE' => 'Predis\Command\ZSetIntersectionStore',
7610
+ 'ZCOUNT' => 'Predis\Command\ZSetCount',
7611
+ 'ZRANK' => 'Predis\Command\ZSetRank',
7612
+ 'ZREVRANK' => 'Predis\Command\ZSetReverseRank',
7613
+ 'ZREMRANGEBYRANK' => 'Predis\Command\ZSetRemoveRangeByRank',
7614
 
7615
  /* commands operating on hashes */
7616
+ 'HSET' => 'Predis\Command\HashSet',
7617
+ 'HSETNX' => 'Predis\Command\HashSetPreserve',
7618
+ 'HMSET' => 'Predis\Command\HashSetMultiple',
7619
+ 'HINCRBY' => 'Predis\Command\HashIncrementBy',
7620
+ 'HGET' => 'Predis\Command\HashGet',
7621
+ 'HMGET' => 'Predis\Command\HashGetMultiple',
7622
+ 'HDEL' => 'Predis\Command\HashDelete',
7623
+ 'HEXISTS' => 'Predis\Command\HashExists',
7624
+ 'HLEN' => 'Predis\Command\HashLength',
7625
+ 'HKEYS' => 'Predis\Command\HashKeys',
7626
+ 'HVALS' => 'Predis\Command\HashValues',
7627
+ 'HGETALL' => 'Predis\Command\HashGetAll',
7628
 
7629
  /* transactions */
7630
+ 'MULTI' => 'Predis\Command\TransactionMulti',
7631
+ 'EXEC' => 'Predis\Command\TransactionExec',
7632
+ 'DISCARD' => 'Predis\Command\TransactionDiscard',
7633
 
7634
  /* publish - subscribe */
7635
+ 'SUBSCRIBE' => 'Predis\Command\PubSubSubscribe',
7636
+ 'UNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribe',
7637
+ 'PSUBSCRIBE' => 'Predis\Command\PubSubSubscribeByPattern',
7638
+ 'PUNSUBSCRIBE' => 'Predis\Command\PubSubUnsubscribeByPattern',
7639
+ 'PUBLISH' => 'Predis\Command\PubSubPublish',
7640
 
7641
  /* remote server control commands */
7642
+ 'CONFIG' => 'Predis\Command\ServerConfig',
7643
 
7644
  /* ---------------- Redis 2.2 ---------------- */
7645
 
7646
  /* commands operating on the key space */
7647
+ 'PERSIST' => 'Predis\Command\KeyPersist',
7648
 
7649
  /* commands operating on string values */
7650
+ 'STRLEN' => 'Predis\Command\StringStrlen',
7651
+ 'SETRANGE' => 'Predis\Command\StringSetRange',
7652
+ 'GETRANGE' => 'Predis\Command\StringGetRange',
7653
+ 'SETBIT' => 'Predis\Command\StringSetBit',
7654
+ 'GETBIT' => 'Predis\Command\StringGetBit',
7655
 
7656
  /* commands operating on lists */
7657
+ 'RPUSHX' => 'Predis\Command\ListPushTailX',
7658
+ 'LPUSHX' => 'Predis\Command\ListPushHeadX',
7659
+ 'LINSERT' => 'Predis\Command\ListInsert',
7660
+ 'BRPOPLPUSH' => 'Predis\Command\ListPopLastPushHeadBlocking',
7661
 
7662
  /* commands operating on sorted sets */
7663
+ 'ZREVRANGEBYSCORE' => 'Predis\Command\ZSetReverseRangeByScore',
7664
 
7665
  /* transactions */
7666
+ 'WATCH' => 'Predis\Command\TransactionWatch',
7667
+ 'UNWATCH' => 'Predis\Command\TransactionUnwatch',
7668
 
7669
  /* remote server control commands */
7670
+ 'OBJECT' => 'Predis\Command\ServerObject',
7671
+ 'SLOWLOG' => 'Predis\Command\ServerSlowlog',
7672
  );
7673
  }
7674
  }
7677
 
7678
  namespace Predis;
7679
 
 
 
7680
  use Predis\Command\CommandInterface;
7681
  use Predis\Command\RawCommand;
7682
  use Predis\Command\ScriptCommand;
7683
  use Predis\Configuration\Options;
7684
  use Predis\Configuration\OptionsInterface;
 
7685
  use Predis\Connection\AggregateConnectionInterface;
7686
+ use Predis\Connection\ConnectionInterface;
7687
  use Predis\Connection\ParametersInterface;
7688
  use Predis\Monitor\Consumer as MonitorConsumer;
7689
  use Predis\Pipeline\Pipeline;
7693
  use Predis\Response\ServerException;
7694
  use Predis\Transaction\MultiExec as MultiExecTransaction;
7695
  use Predis\Profile\ProfileInterface;
 
7696
  use Predis\Connection\NodeConnectionInterface;
7697
 
7698
  /**
7700
  *
7701
  * @author Daniele Alessandri <suppakilla@gmail.com>
7702
  */
7703
+ abstract class PredisException extends \Exception
7704
  {
7705
  }
7706
 
7850
  */
7851
  interface ClientContextInterface
7852
  {
 
7853
  /**
7854
  * Sends the specified command instance to Redis.
7855
  *
7892
  * @param NodeConnectionInterface $connection Connection that generated the exception.
7893
  * @param string $message Error message.
7894
  * @param int $code Error code.
7895
+ * @param \Exception $innerException Inner exception for wrapping the original error.
7896
  */
7897
  public function __construct(
7898
  NodeConnectionInterface $connection,
7899
  $message = null,
7900
  $code = null,
7901
+ \Exception $innerException = null
7902
  ) {
7903
  parent::__construct($message, $code, $innerException);
7904
  $this->connection = $connection;
8190
  */
8191
  class Client implements ClientInterface
8192
  {
8193
+ const VERSION = '1.0.3';
8194
 
8195
  protected $connection;
8196
  protected $options;
8214
  *
8215
  * @param mixed $options Client options.
8216
  *
 
 
8217
  * @throws \InvalidArgumentException
8218
+ *
8219
+ * @return OptionsInterface
8220
  */
8221
  protected function createOptions($options)
8222
  {
8228
  return $options;
8229
  }
8230
 
8231
+ throw new \InvalidArgumentException('Invalid type for client options.');
8232
  }
8233
 
8234
  /**
8246
  *
8247
  * @param mixed $parameters Connection parameters or connection instance.
8248
  *
 
 
8249
  * @throws \InvalidArgumentException
8250
+ *
8251
+ * @return ConnectionInterface
8252
  */
8253
  protected function createConnection($parameters)
8254
  {
8290
  return $connection;
8291
  }
8292
 
8293
+ throw new \InvalidArgumentException('Invalid type for connection parameters.');
8294
  }
8295
 
8296
  /**
8307
  $connection = call_user_func_array($callable, func_get_args());
8308
 
8309
  if (!$connection instanceof ConnectionInterface) {
8310
+ throw new \UnexpectedValueException(
8311
  'The callable connection initializer returned an invalid type.'
8312
  );
8313
  }
8339
  *
8340
  * @param string $connectionID Identifier of a connection.
8341
  *
 
 
8342
  * @throws \InvalidArgumentException
8343
+ *
8344
+ * @return Client
8345
  */
8346
  public function getClientFor($connectionID)
8347
  {
8348
  if (!$connection = $this->getConnectionById($connectionID)) {
8349
+ throw new \InvalidArgumentException("Invalid connection ID: $connectionID.");
8350
  }
8351
 
8352
  return new static($connection, $this->options);
8403
  *
8404
  * @param string $connectionID Index or alias of the single connection.
8405
  *
 
 
8406
  * @throws NotSupportedException
8407
+ *
8408
+ * @return Connection\NodeConnectionInterface
8409
  */
8410
  public function getConnectionById($connectionID)
8411
  {
8492
  * @param CommandInterface $command Redis command that generated the error.
8493
  * @param ErrorResponseInterface $response Instance of the error response.
8494
  *
 
 
8495
  * @throws ServerException
8496
+ *
8497
+ * @return mixed
8498
  */
8499
  protected function onErrorResponse(CommandInterface $command, ErrorResponseInterface $response)
8500
  {
8690
  public function __construct($baseDirectory = __DIR__)
8691
  {
8692
  $this->directory = $baseDirectory;
8693
+ $this->prefix = __NAMESPACE__.'\\';
8694
  $this->prefixLength = strlen($this->prefix);
8695
  }
8696
 
8701
  */
8702
  public static function register($prepend = false)
8703
  {
8704
+ spl_autoload_register(array(new self(), 'autoload'), true, $prepend);
8705
  }
8706
 
8707
  /**
8716
  $filepath = $this->directory.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts).'.php';
8717
 
8718
  if (is_file($filepath)) {
8719
+ require $filepath;
8720
  }
8721
  }
8722
  }
8726
 
8727
  namespace Predis\Configuration;
8728
 
 
8729
  use Predis\Connection\Aggregate\ClusterInterface;
8730
  use Predis\Connection\Aggregate\PredisCluster;
8731
  use Predis\Connection\Aggregate\RedisCluster;
8883
  $value = Predis_Factory::get($value);
8884
  $this->setProcessors($options, $value);
8885
  } elseif (!$value instanceof ProfileInterface) {
8886
+ throw new \InvalidArgumentException('Invalid value for the profile option.');
8887
  }
8888
 
8889
  return $value;
8933
  return $asbool ? $this->getDefault($options) : null;
8934
  }
8935
 
8936
+ throw new \InvalidArgumentException(
8937
  "An instance of type 'Predis\Connection\Aggregate\ReplicationInterface' was expected."
8938
  );
8939
  }
8979
  protected function getHandlers()
8980
  {
8981
  return array(
8982
+ 'cluster' => 'Predis\Configuration\ClusterOption',
8983
  'connections' => 'Predis\Configuration\ConnectionFactoryOption',
8984
+ 'exceptions' => 'Predis\Configuration\ExceptionsOption',
8985
+ 'prefix' => 'Predis\Configuration\PrefixOption',
8986
+ 'profile' => 'Predis\Configuration\ProfileOption',
8987
  'replication' => 'Predis\Configuration\ReplicationOption',
8988
  );
8989
  }
9036
  $value = $this->input[$option];
9037
  unset($this->input[$option]);
9038
 
9039
+ if (is_object($value) && method_exists($value, '__invoke')) {
9040
  $value = $value($this, $option);
9041
  }
9042
 
9053
  return $this->options[$option] = $this->getDefault($option);
9054
  }
9055
 
9056
+ return;
9057
  }
9058
  }
9059
 
9081
 
9082
  return $factory;
9083
  } else {
9084
+ throw new \InvalidArgumentException(
9085
  'Invalid value provided for the connections option.'
9086
  );
9087
  }
9164
  }
9165
 
9166
  if (!$value instanceof ClusterInterface) {
9167
+ throw new \InvalidArgumentException(
9168
  "An instance of type 'Predis\Connection\Aggregate\ClusterInterface' was expected."
9169
  );
9170
  }
9205
  interface ErrorInterface extends ResponseInterface
9206
  {
9207
  /**
9208
+ * Returns the error message.
9209
  *
9210
  * @return string
9211
  */
9212
  public function getMessage();
9213
 
9214
  /**
9215
+ * Returns the error type (e.g. ERR, ASK, MOVED).
9216
  *
9217
  * @return string
9218
  */
9317
  */
9318
  public function getErrorType()
9319
  {
9320
+ list($errorType) = explode(' ', $this->getMessage(), 2);
9321
 
9322
  return $errorType;
9323
  }
9347
  */
9348
  public function getErrorType()
9349
  {
9350
+ list($errorType) = explode(' ', $this->getMessage(), 2);
9351
 
9352
  return $errorType;
9353
  }
9399
  * the payload as a string.
9400
  *
9401
  * @link http://redis.io/topics/protocol
9402
+ *
9403
  * @author Daniele Alessandri <suppakilla@gmail.com>
9404
  */
9405
  class StatusResponse implements ResponseHandlerInterface
9421
  * built-in into Predis, such as transactions or pipelines. Use them with care!
9422
  *
9423
  * @link http://redis.io/topics/protocol
9424
+ *
9425
  * @author Daniele Alessandri <suppakilla@gmail.com>
9426
  */
9427
  class StreamableMultiBulkResponse implements ResponseHandlerInterface
9448
  * It returns multibulk responses as PHP arrays.
9449
  *
9450
  * @link http://redis.io/topics/protocol
9451
+ *
9452
  * @author Daniele Alessandri <suppakilla@gmail.com>
9453
  */
9454
  class MultiBulkResponse implements ResponseHandlerInterface
9467
  }
9468
 
9469
  if ($length === -1) {
9470
+ return;
9471
  }
9472
 
9473
  $list = array();
9476
  $handlersCache = array();
9477
  $reader = $connection->getProtocol()->getResponseReader();
9478
 
9479
+ for ($i = 0; $i < $length; ++$i) {
9480
  $header = $connection->readLine();
9481
  $prefix = $header[0];
9482
 
9500
  * It translates the payload to a complex response object for Predis.
9501
  *
9502
  * @link http://redis.io/topics/protocol
9503
+ *
9504
  * @author Daniele Alessandri <suppakilla@gmail.com>
9505
  */
9506
  class ErrorResponse implements ResponseHandlerInterface
9519
  * It translates the payload an integer or NULL.
9520
  *
9521
  * @link http://redis.io/topics/protocol
9522
+ *
9523
  * @author Daniele Alessandri <suppakilla@gmail.com>
9524
  */
9525
  class IntegerResponse implements ResponseHandlerInterface
9539
  ));
9540
  }
9541
 
9542
+ return;
9543
  }
9544
  }
9545
 
9548
  * It translates the payload to a string or a NULL.
9549
  *
9550
  * @link http://redis.io/topics/protocol
9551
+ *
9552
  * @author Daniele Alessandri <suppakilla@gmail.com>
9553
  */
9554
  class BulkResponse implements ResponseHandlerInterface
9571
  }
9572
 
9573
  if ($length == -1) {
9574
+ return;
9575
  }
9576
 
9577
  CommunicationException::handle(new ProtocolException(
9586
 
9587
  namespace Predis\Collection\Iterator;
9588
 
 
9589
  use Predis\ClientInterface;
9590
  use Predis\NotSupportedException;
 
9591
 
9592
  /**
9593
  * Provides the base implementation for a fully-rewindable PHP iterator that can
9602
  *
9603
  * @author Daniele Alessandri <suppakilla@gmail.com>
9604
  */
9605
+ abstract class CursorBasedIterator implements \Iterator
9606
  {
9607
  protected $client;
9608
  protected $match;
9707
  */
9708
  protected function extractNext()
9709
  {
9710
+ ++$this->position;
9711
  $this->current = array_shift($this->elements);
9712
  }
9713
 
9770
  * ZSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9771
  *
9772
  * @author Daniele Alessandri <suppakilla@gmail.com>
9773
+ *
9774
  * @link http://redis.io/commands/scan
9775
  */
9776
  class SortedSetKey extends CursorBasedIterator
9816
  * command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9817
  *
9818
  * @author Daniele Alessandri <suppakilla@gmail.com>
9819
+ *
9820
  * @link http://redis.io/commands/scan
9821
  */
9822
  class SetKey extends CursorBasedIterator
9849
  * SCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9850
  *
9851
  * @author Daniele Alessandri <suppakilla@gmail.com>
9852
+ *
9853
  * @link http://redis.io/commands/scan
9854
  */
9855
  class Keyspace extends CursorBasedIterator
9878
  * HSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
9879
  *
9880
  * @author Daniele Alessandri <suppakilla@gmail.com>
9881
+ *
9882
  * @link http://redis.io/commands/scan
9883
  */
9884
  class HashKey extends CursorBasedIterator
9926
  * times (trimmed, deleted, overwritten) during the iteration process.
9927
  *
9928
  * @author Daniele Alessandri <suppakilla@gmail.com>
9929
+ *
9930
  * @link http://redis.io/commands/lrange
9931
  */
9932
+ class ListKey implements \Iterator
9933
  {
9934
  protected $client;
9935
  protected $count;
9953
  $this->requiredCommand($client, 'LRANGE');
9954
 
9955
  if ((false === $count = filter_var($count, FILTER_VALIDATE_INT)) || $count < 0) {
9956
+ throw new \InvalidArgumentException('The $count argument must be a positive integer.');
9957
  }
9958
 
9959
  $this->client = $client;
10022
  */
10023
  protected function extractNext()
10024
  {
10025
+ ++$this->position;
10026
  $this->current = array_shift($this->elements);
10027
  }
10028
 
10080
 
10081
  namespace Predis\Cluster;
10082
 
 
10083
  use Predis\Command\CommandInterface;
10084
  use Predis\Command\ScriptCommand;
10085
  use Predis\Cluster\Distributor\DistributorInterface;
10086
  use Predis\Cluster\Distributor\HashRing;
 
 
10087
  use Predis\Cluster\Hash\CRC16;
10088
+ use Predis\Cluster\Hash\HashGeneratorInterface;
10089
+ use Predis\NotSupportedException;
10090
 
10091
  /**
10092
  * Interface for classes defining the strategy used to calculate an hash out of
10155
 
10156
  return array(
10157
  /* commands operating on the key space */
10158
+ 'EXISTS' => $getKeyFromFirstArgument,
10159
+ 'DEL' => $getKeyFromAllArguments,
10160
+ 'TYPE' => $getKeyFromFirstArgument,
10161
+ 'EXPIRE' => $getKeyFromFirstArgument,
10162
+ 'EXPIREAT' => $getKeyFromFirstArgument,
10163
+ 'PERSIST' => $getKeyFromFirstArgument,
10164
+ 'PEXPIRE' => $getKeyFromFirstArgument,
10165
+ 'PEXPIREAT' => $getKeyFromFirstArgument,
10166
+ 'TTL' => $getKeyFromFirstArgument,
10167
+ 'PTTL' => $getKeyFromFirstArgument,
10168
+ 'SORT' => $getKeyFromFirstArgument, // TODO
10169
+ 'DUMP' => $getKeyFromFirstArgument,
10170
+ 'RESTORE' => $getKeyFromFirstArgument,
10171
 
10172
  /* commands operating on string values */
10173
+ 'APPEND' => $getKeyFromFirstArgument,
10174
+ 'DECR' => $getKeyFromFirstArgument,
10175
+ 'DECRBY' => $getKeyFromFirstArgument,
10176
+ 'GET' => $getKeyFromFirstArgument,
10177
+ 'GETBIT' => $getKeyFromFirstArgument,
10178
+ 'MGET' => $getKeyFromAllArguments,
10179
+ 'SET' => $getKeyFromFirstArgument,
10180
+ 'GETRANGE' => $getKeyFromFirstArgument,
10181
+ 'GETSET' => $getKeyFromFirstArgument,
10182
+ 'INCR' => $getKeyFromFirstArgument,
10183
+ 'INCRBY' => $getKeyFromFirstArgument,
10184
+ 'INCRBYFLOAT' => $getKeyFromFirstArgument,
10185
+ 'SETBIT' => $getKeyFromFirstArgument,
10186
+ 'SETEX' => $getKeyFromFirstArgument,
10187
+ 'MSET' => array($this, 'getKeyFromInterleavedArguments'),
10188
+ 'MSETNX' => array($this, 'getKeyFromInterleavedArguments'),
10189
+ 'SETNX' => $getKeyFromFirstArgument,
10190
+ 'SETRANGE' => $getKeyFromFirstArgument,
10191
+ 'STRLEN' => $getKeyFromFirstArgument,
10192
+ 'SUBSTR' => $getKeyFromFirstArgument,
10193
+ 'BITOP' => array($this, 'getKeyFromBitOp'),
10194
+ 'BITCOUNT' => $getKeyFromFirstArgument,
10195
 
10196
  /* commands operating on lists */
10197
+ 'LINSERT' => $getKeyFromFirstArgument,
10198
+ 'LINDEX' => $getKeyFromFirstArgument,
10199
+ 'LLEN' => $getKeyFromFirstArgument,
10200
+ 'LPOP' => $getKeyFromFirstArgument,
10201
+ 'RPOP' => $getKeyFromFirstArgument,
10202
+ 'RPOPLPUSH' => $getKeyFromAllArguments,
10203
+ 'BLPOP' => array($this, 'getKeyFromBlockingListCommands'),
10204
+ 'BRPOP' => array($this, 'getKeyFromBlockingListCommands'),
10205
+ 'BRPOPLPUSH' => array($this, 'getKeyFromBlockingListCommands'),
10206
+ 'LPUSH' => $getKeyFromFirstArgument,
10207
+ 'LPUSHX' => $getKeyFromFirstArgument,
10208
+ 'RPUSH' => $getKeyFromFirstArgument,
10209
+ 'RPUSHX' => $getKeyFromFirstArgument,
10210
+ 'LRANGE' => $getKeyFromFirstArgument,
10211
+ 'LREM' => $getKeyFromFirstArgument,
10212
+ 'LSET' => $getKeyFromFirstArgument,
10213
+ 'LTRIM' => $getKeyFromFirstArgument,
10214
 
10215
  /* commands operating on sets */
10216
+ 'SADD' => $getKeyFromFirstArgument,
10217
+ 'SCARD' => $getKeyFromFirstArgument,
10218
+ 'SDIFF' => $getKeyFromAllArguments,
10219
+ 'SDIFFSTORE' => $getKeyFromAllArguments,
10220
+ 'SINTER' => $getKeyFromAllArguments,
10221
+ 'SINTERSTORE' => $getKeyFromAllArguments,
10222
+ 'SUNION' => $getKeyFromAllArguments,
10223
+ 'SUNIONSTORE' => $getKeyFromAllArguments,
10224
+ 'SISMEMBER' => $getKeyFromFirstArgument,
10225
+ 'SMEMBERS' => $getKeyFromFirstArgument,
10226
+ 'SSCAN' => $getKeyFromFirstArgument,
10227
+ 'SPOP' => $getKeyFromFirstArgument,
10228
+ 'SRANDMEMBER' => $getKeyFromFirstArgument,
10229
+ 'SREM' => $getKeyFromFirstArgument,
10230
 
10231
  /* commands operating on sorted sets */
10232
+ 'ZADD' => $getKeyFromFirstArgument,
10233
+ 'ZCARD' => $getKeyFromFirstArgument,
10234
+ 'ZCOUNT' => $getKeyFromFirstArgument,
10235
+ 'ZINCRBY' => $getKeyFromFirstArgument,
10236
+ 'ZINTERSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
10237
+ 'ZRANGE' => $getKeyFromFirstArgument,
10238
+ 'ZRANGEBYSCORE' => $getKeyFromFirstArgument,
10239
+ 'ZRANK' => $getKeyFromFirstArgument,
10240
+ 'ZREM' => $getKeyFromFirstArgument,
10241
+ 'ZREMRANGEBYRANK' => $getKeyFromFirstArgument,
10242
+ 'ZREMRANGEBYSCORE' => $getKeyFromFirstArgument,
10243
+ 'ZREVRANGE' => $getKeyFromFirstArgument,
10244
+ 'ZREVRANGEBYSCORE' => $getKeyFromFirstArgument,
10245
+ 'ZREVRANK' => $getKeyFromFirstArgument,
10246
+ 'ZSCORE' => $getKeyFromFirstArgument,
10247
+ 'ZUNIONSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
10248
+ 'ZSCAN' => $getKeyFromFirstArgument,
10249
+ 'ZLEXCOUNT' => $getKeyFromFirstArgument,
10250
+ 'ZRANGEBYLEX' => $getKeyFromFirstArgument,
10251
+ 'ZREMRANGEBYLEX' => $getKeyFromFirstArgument,
10252
+ 'ZREVRANGEBYLEX' => $getKeyFromFirstArgument,
10253
 
10254
  /* commands operating on hashes */
10255
+ 'HDEL' => $getKeyFromFirstArgument,
10256
+ 'HEXISTS' => $getKeyFromFirstArgument,
10257
+ 'HGET' => $getKeyFromFirstArgument,
10258
+ 'HGETALL' => $getKeyFromFirstArgument,
10259
+ 'HMGET' => $getKeyFromFirstArgument,
10260
+ 'HMSET' => $getKeyFromFirstArgument,
10261
+ 'HINCRBY' => $getKeyFromFirstArgument,
10262
+ 'HINCRBYFLOAT' => $getKeyFromFirstArgument,
10263
+ 'HKEYS' => $getKeyFromFirstArgument,
10264
+ 'HLEN' => $getKeyFromFirstArgument,
10265
+ 'HSET' => $getKeyFromFirstArgument,
10266
+ 'HSETNX' => $getKeyFromFirstArgument,
10267
+ 'HVALS' => $getKeyFromFirstArgument,
10268
+ 'HSCAN' => $getKeyFromFirstArgument,
10269
+ 'HSTRLEN' => $getKeyFromFirstArgument,
10270
 
10271
  /* commands operating on HyperLogLog */
10272
+ 'PFADD' => $getKeyFromFirstArgument,
10273
+ 'PFCOUNT' => $getKeyFromAllArguments,
10274
+ 'PFMERGE' => $getKeyFromAllArguments,
10275
 
10276
  /* scripting */
10277
+ 'EVAL' => array($this, 'getKeyFromScriptingCommands'),
10278
+ 'EVALSHA' => array($this, 'getKeyFromScriptingCommands'),
10279
  );
10280
  }
10281
 
10314
  }
10315
 
10316
  if (!is_callable($callback)) {
10317
+ throw new \InvalidArgumentException(
10318
+ 'The argument must be a callable object or NULL.'
10319
  );
10320
  }
10321
 
10476
 
10477
  $currentSlot = $this->getSlotByKey($keys[0]);
10478
 
10479
+ for ($i = 1; $i < $count; ++$i) {
10480
  $nextSlot = $this->getSlotByKey($keys[$i]);
10481
 
10482
  if ($currentSlot !== $nextSlot) {
10551
 
10552
  $currentKey = $this->extractKeyTag($keys[0]);
10553
 
10554
+ for ($i = 1; $i < $count; ++$i) {
10555
  $nextKey = $this->extractKeyTag($keys[$i]);
10556
 
10557
  if ($currentKey !== $nextKey) {
10598
  */
10599
  public function getSlotByKey($key)
10600
  {
10601
+ $key = $this->extractKeyTag($key);
10602
  $slot = $this->hashGenerator->hash($key) & 0x3FFF;
10603
 
10604
  return $slot;
10699
  namespace Predis\Connection\Aggregate;
10700
 
10701
  use Predis\Connection\AggregateConnectionInterface;
 
 
10702
  use Predis\Command\CommandInterface;
10703
  use Predis\Connection\NodeConnectionInterface;
10704
  use Predis\Replication\ReplicationStrategy;
 
 
 
 
10705
  use Predis\Cluster\PredisStrategy;
10706
  use Predis\Cluster\StrategyInterface;
10707
+ use Predis\NotSupportedException;
10708
  use Predis\Cluster\RedisStrategy as RedisClusterStrategy;
10709
  use Predis\Command\RawCommand;
10710
  use Predis\Connection\FactoryInterface;
10779
  *
10780
  * @author Daniele Alessandri <suppakilla@gmail.com>
10781
  */
10782
+ class RedisCluster implements ClusterInterface, \IteratorAggregate, \Countable
10783
  {
10784
  private $useClusterSlots = true;
10785
  private $defaultParameters = array();
10969
  $last < 0x0000 || $last > 0x3FFF ||
10970
  $last < $first
10971
  ) {
10972
+ throw new \OutOfBoundsException(
10973
  "Invalid slot range for $connection: [$first-$last]."
10974
  );
10975
  }
11013
  */
11014
  protected function createConnection($connectionID)
11015
  {
11016
+ $separator = strrpos($connectionID, ':');
11017
 
11018
  $parameters = array_merge($this->defaultParameters, array(
11019
+ 'host' => substr($connectionID, 0, $separator),
11020
+ 'port' => substr($connectionID, $separator + 1),
11021
  ));
11022
 
11023
  $connection = $this->connections->create($parameters);
11050
  *
11051
  * @param int $slot Slot index.
11052
  *
 
 
11053
  * @throws \OutOfBoundsException
11054
+ *
11055
+ * @return NodeConnectionInterface
11056
  */
11057
  public function getConnectionBySlot($slot)
11058
  {
11059
  if ($slot < 0x0000 || $slot > 0x3FFF) {
11060
+ throw new \OutOfBoundsException("Invalid slot [$slot].");
11061
  }
11062
 
11063
  if (isset($this->slots[$slot])) {
11164
  * Handles -ASK responses by executing again the command against the node
11165
  * indicated by the Redis response.
11166
  *
11167
+ * @param CommandInterface $command Command that generated the -ASK response.
11168
+ * @param string $details Parameters of the -ASK response.
11169
+ *
11170
  * @return mixed
11171
  */
11172
  protected function onAskResponse(CommandInterface $command, $details)
11227
  */
11228
  public function getIterator()
11229
  {
11230
+ return new \ArrayIterator(array_values($this->pool));
11231
  }
11232
 
11233
  /**
11294
  * implementing client-side sharding based on pluggable distribution strategies.
11295
  *
11296
  * @author Daniele Alessandri <suppakilla@gmail.com>
11297
+ *
11298
  * @todo Add the ability to remove connections from pool.
11299
  */
11300
+ class PredisCluster implements ClusterInterface, \IteratorAggregate, \Countable
11301
  {
11302
  private $pool;
11303
  private $strategy;
11460
  */
11461
  public function getIterator()
11462
  {
11463
+ return new \ArrayIterator($this->pool);
11464
  }
11465
 
11466
  /**
11534
  protected function check()
11535
  {
11536
  if (!isset($this->master) || !$this->slaves) {
11537
+ throw new \RuntimeException('Replication needs one master and at least one slave.');
11538
  }
11539
  }
11540
 
11622
  return $this->slaves[$connectionId];
11623
  }
11624
 
11625
+ return;
11626
  }
11627
 
11628
  /**
11636
  $connection = $this->getConnectionById($connection);
11637
  }
11638
  if ($connection !== $this->master && !in_array($connection, $this->slaves, true)) {
11639
+ throw new \InvalidArgumentException('Invalid connection or connection not found.');
11640
  }
11641
 
11642
  $this->current = $connection;
11758
 
11759
  namespace Predis\Pipeline;
11760
 
 
11761
  use Predis\ClientException;
11762
  use Predis\ClientInterface;
11763
  use Predis\Connection\ConnectionInterface;
11765
  use Predis\Response\ErrorInterface as ErrorResponseInterface;
11766
  use Predis\Response\ResponseInterface;
11767
  use Predis\Response\ServerException;
 
11768
  use Predis\CommunicationException;
11769
  use Predis\Connection\Aggregate\ClusterInterface;
11770
+ use Predis\NotSupportedException;
 
11771
  use Predis\ClientContextInterface;
11772
  use Predis\Command\CommandInterface;
11773
  use Predis\Connection\Aggregate\ReplicationInterface;
11794
  public function __construct(ClientInterface $client)
11795
  {
11796
  $this->client = $client;
11797
+ $this->pipeline = new \SplQueue();
11798
  }
11799
 
11800
  /**
11874
  * from the current connection.
11875
  *
11876
  * @param ConnectionInterface $connection Current connection instance.
11877
+ * @param \SplQueue $commands Queued commands.
11878
  *
11879
  * @return array
11880
  */
11881
+ protected function executePipeline(ConnectionInterface $connection, \SplQueue $commands)
11882
  {
11883
  foreach ($commands as $command) {
11884
  $connection->writeRequest($command);
11916
  $responses = $this->executePipeline($this->getConnection(), $this->pipeline);
11917
  $this->responses = array_merge($this->responses, $responses);
11918
  } else {
11919
+ $this->pipeline = new \SplQueue();
11920
  }
11921
 
11922
  return $this;
11943
  *
11944
  * @param mixed $callable Optional callback for execution.
11945
  *
11946
+ * @throws \Exception
11947
+ * @throws \InvalidArgumentException
11948
  *
11949
+ * @return array
 
11950
  */
11951
  public function execute($callable = null)
11952
  {
11953
  if ($callable && !is_callable($callable)) {
11954
+ throw new \InvalidArgumentException('The argument must be a callable object.');
11955
  }
11956
 
11957
  $exception = null;
11963
  }
11964
 
11965
  $this->flushPipeline();
11966
+ } catch (\Exception $exception) {
11967
  // NOOP
11968
  }
11969
 
12007
  /**
12008
  * {@inheritdoc}
12009
  */
12010
+ protected function executePipeline(ConnectionInterface $connection, \SplQueue $commands)
12011
  {
12012
  while (!$commands->isEmpty()) {
12013
  $connection->writeRequest($commands->dequeue());
12024
  * returns the exception instances as the rest of the response elements.
12025
  *
12026
  * @todo Awful naming!
12027
+ *
12028
  * @author Daniele Alessandri <suppakilla@gmail.com>
12029
  */
12030
  class ConnectionErrorProof extends Pipeline
12040
  /**
12041
  * {@inheritdoc}
12042
  */
12043
+ protected function executePipeline(ConnectionInterface $connection, \SplQueue $commands)
12044
  {
12045
  if ($connection instanceof NodeConnectionInterface) {
12046
  return $this->executeSingleNode($connection, $commands);
12056
  /**
12057
  * {@inheritdoc}
12058
  */
12059
+ protected function executeSingleNode(NodeConnectionInterface $connection, \SplQueue $commands)
12060
  {
12061
+ $responses = array();
12062
  $sizeOfPipe = count($commands);
12063
 
12064
  foreach ($commands as $command) {
12069
  }
12070
  }
12071
 
12072
+ for ($i = 0; $i < $sizeOfPipe; ++$i) {
12073
  $command = $commands->dequeue();
12074
 
12075
  try {
12088
  /**
12089
  * {@inheritdoc}
12090
  */
12091
+ protected function executeCluster(ClusterInterface $connection, \SplQueue $commands)
12092
  {
12093
  $responses = array();
12094
  $sizeOfPipe = count($commands);
12108
  }
12109
  }
12110
 
12111
+ for ($i = 0; $i < $sizeOfPipe; ++$i) {
12112
  $command = $commands->dequeue();
12113
 
12114
  $cmdConnection = $connection->getConnection($command);
12171
  /**
12172
  * {@inheritdoc}
12173
  */
12174
+ protected function executePipeline(ConnectionInterface $connection, \SplQueue $commands)
12175
  {
12176
  $profile = $this->getClient()->getProfile();
12177
  $connection->executeCommand($profile->createCommand('multi'));
12211
  $sizeOfPipe = count($commands);
12212
  $exceptions = $this->throwServerExceptions();
12213
 
12214
+ for ($i = 0; $i < $sizeOfPipe; ++$i) {
12215
+ $command = $commands->dequeue();
12216
  $response = $executed[$i];
12217
 
12218
  if (!$response instanceof ResponseInterface) {
12235
  namespace Predis\Cluster\Distributor;
12236
 
12237
  use Predis\Cluster\Hash\HashGeneratorInterface;
 
12238
 
12239
  /**
12240
  * A distributor implements the logic to automatically distribute keys among
12315
  class HashRing implements DistributorInterface, HashGeneratorInterface
12316
  {
12317
  const DEFAULT_REPLICAS = 128;
12318
+ const DEFAULT_WEIGHT = 100;
12319
 
12320
  private $ring;
12321
  private $ringKeys;
12346
  // last wins, thus the order in which nodes are added is significant.
12347
  $this->nodes[] = array(
12348
  'object' => $node,
12349
+ 'weight' => (int) $weight ?: $this::DEFAULT_WEIGHT,
12350
  );
12351
 
12352
  $this->reset();
12451
  $nodeHash = $this->getNodeHash($nodeObject);
12452
  $replicas = (int) round($weightRatio * $totalNodes * $replicas);
12453
 
12454
+ for ($i = 0; $i < $replicas; ++$i) {
12455
  $key = crc32("$nodeHash:$i");
12456
  $ring[$key] = $nodeObject;
12457
  }
12589
  $nodeHash = $this->getNodeHash($nodeObject);
12590
  $replicas = (int) floor($weightRatio * $totalNodes * ($replicas / 4));
12591
 
12592
+ for ($i = 0; $i < $replicas; ++$i) {
12593
  $unpackedDigest = unpack('V4', md5("$nodeHash-$i", true));
12594
 
12595
  foreach ($unpackedDigest as $key) {
12624
  *
12625
  * @author Daniele Alessandri <suppakilla@gmail.com>
12626
  */
12627
+ class EmptyRingException extends \Exception
12628
  {
12629
  }
12630
 
12633
  namespace Predis\Response\Iterator;
12634
 
12635
  use Predis\Connection\NodeConnectionInterface;
 
 
12636
  use Predis\Response\ResponseInterface;
 
 
 
12637
 
12638
  /**
12639
  * Iterator that abstracts the access to multibulk responses allowing them to be
12647
  *
12648
  * @author Daniele Alessandri <suppakilla@gmail.com>
12649
  */
12650
+ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInterface
12651
  {
12652
  protected $current;
12653
  protected $position;
12743
  $this->connection = $connection;
12744
  $this->size = $size;
12745
  $this->position = 0;
12746
+ $this->current = $size > 0 ? $this->getValue() : null;
12747
  }
12748
 
12749
  /**
12797
  *
12798
  * @author Daniele Alessandri <suppakilla@gmail.com>
12799
  */
12800
+ class MultiBulkTuple extends MultiBulk implements \OuterIterator
12801
  {
12802
  private $iterator;
12803
 
12811
  $this->size = count($iterator) / 2;
12812
  $this->iterator = $iterator;
12813
  $this->position = $iterator->getPosition();
12814
+ $this->current = $this->size > 0 ? $this->getValue() : null;
12815
  }
12816
 
12817
  /**
12825
  protected function checkPreconditions(MultiBulk $iterator)
12826
  {
12827
  if ($iterator->getPosition() !== 0) {
12828
+ throw new \InvalidArgumentException(
12829
  'Cannot initialize a tuple iterator using an already initiated iterator.'
12830
  );
12831
  }
12832
 
12833
  if (($size = count($iterator)) % 2 !== 0) {
12834
+ throw new \UnexpectedValueException('Invalid response size for a tuple iterator.');
12835
  }
12836
  }
12837
 
12940
  $CCITT_16 = self::$CCITT_16;
12941
  $strlen = strlen($value);
12942
 
12943
+ for ($i = 0; $i < $strlen; ++$i) {
12944
  $crc = (($crc << 8) ^ $CCITT_16[($crc >> 8) ^ ord($value[$i])]) & 0xFFFF;
12945
  }
12946
 
12952
 
12953
  namespace Predis\Command\Processor;
12954
 
 
12955
  use Predis\Command\CommandInterface;
12956
  use Predis\Command\PrefixableCommandInterface;
 
 
12957
 
12958
  /**
12959
  * A command processor processes Redis commands before they are sent to Redis.
12975
  *
12976
  * @author Daniele Alessandri <suppakilla@gmail.com>
12977
  */
12978
+ class ProcessorChain implements \ArrayAccess, ProcessorInterface
12979
  {
12980
  private $processors = array();
12981
 
13012
  */
13013
  public function process(CommandInterface $command)
13014
  {
13015
+ for ($i = 0; $i < $count = count($this->processors); ++$i) {
13016
  $this->processors[$i]->process($command);
13017
  }
13018
  }
13028
  /**
13029
  * Returns an iterator over the list of command processor in the chain.
13030
  *
13031
+ * @return \ArrayIterator
13032
  */
13033
  public function getIterator()
13034
  {
13035
+ return new \ArrayIterator($this->processors);
13036
  }
13037
 
13038
  /**
13067
  public function offsetSet($index, $processor)
13068
  {
13069
  if (!$processor instanceof ProcessorInterface) {
13070
+ throw new \InvalidArgumentException(
13071
+ 'A processor chain accepts only instances of '.
13072
  "'Predis\Command\Processor\ProcessorInterface'."
13073
  );
13074
  }
13105
  $this->prefix = $prefix;
13106
  $this->commands = array(
13107
  /* ---------------- Redis 1.2 ---------------- */
13108
+ 'EXISTS' => 'static::first',
13109
+ 'DEL' => 'static::all',
13110
+ 'TYPE' => 'static::first',
13111
+ 'KEYS' => 'static::first',
13112
+ 'RENAME' => 'static::all',
13113
+ 'RENAMENX' => 'static::all',
13114
+ 'EXPIRE' => 'static::first',
13115
+ 'EXPIREAT' => 'static::first',
13116
+ 'TTL' => 'static::first',
13117
+ 'MOVE' => 'static::first',
13118
+ 'SORT' => 'static::sort',
13119
+ 'DUMP' => 'static::first',
13120
+ 'RESTORE' => 'static::first',
13121
+ 'SET' => 'static::first',
13122
+ 'SETNX' => 'static::first',
13123
+ 'MSET' => 'static::interleaved',
13124
+ 'MSETNX' => 'static::interleaved',
13125
+ 'GET' => 'static::first',
13126
+ 'MGET' => 'static::all',
13127
+ 'GETSET' => 'static::first',
13128
+ 'INCR' => 'static::first',
13129
+ 'INCRBY' => 'static::first',
13130
+ 'DECR' => 'static::first',
13131
+ 'DECRBY' => 'static::first',
13132
+ 'RPUSH' => 'static::first',
13133
+ 'LPUSH' => 'static::first',
13134
+ 'LLEN' => 'static::first',
13135
+ 'LRANGE' => 'static::first',
13136
+ 'LTRIM' => 'static::first',
13137
+ 'LINDEX' => 'static::first',
13138
+ 'LSET' => 'static::first',
13139
+ 'LREM' => 'static::first',
13140
+ 'LPOP' => 'static::first',
13141
+ 'RPOP' => 'static::first',
13142
+ 'RPOPLPUSH' => 'static::all',
13143
+ 'SADD' => 'static::first',
13144
+ 'SREM' => 'static::first',
13145
+ 'SPOP' => 'static::first',
13146
+ 'SMOVE' => 'static::skipLast',
13147
+ 'SCARD' => 'static::first',
13148
+ 'SISMEMBER' => 'static::first',
13149
+ 'SINTER' => 'static::all',
13150
+ 'SINTERSTORE' => 'static::all',
13151
+ 'SUNION' => 'static::all',
13152
+ 'SUNIONSTORE' => 'static::all',
13153
+ 'SDIFF' => 'static::all',
13154
+ 'SDIFFSTORE' => 'static::all',
13155
+ 'SMEMBERS' => 'static::first',
13156
+ 'SRANDMEMBER' => 'static::first',
13157
+ 'ZADD' => 'static::first',
13158
+ 'ZINCRBY' => 'static::first',
13159
+ 'ZREM' => 'static::first',
13160
+ 'ZRANGE' => 'static::first',
13161
+ 'ZREVRANGE' => 'static::first',
13162
+ 'ZRANGEBYSCORE' => 'static::first',
13163
+ 'ZCARD' => 'static::first',
13164
+ 'ZSCORE' => 'static::first',
13165
+ 'ZREMRANGEBYSCORE' => 'static::first',
13166
  /* ---------------- Redis 2.0 ---------------- */
13167
+ 'SETEX' => 'static::first',
13168
+ 'APPEND' => 'static::first',
13169
+ 'SUBSTR' => 'static::first',
13170
+ 'BLPOP' => 'static::skipLast',
13171
+ 'BRPOP' => 'static::skipLast',
13172
+ 'ZUNIONSTORE' => 'static::zsetStore',
13173
+ 'ZINTERSTORE' => 'static::zsetStore',
13174
+ 'ZCOUNT' => 'static::first',
13175
+ 'ZRANK' => 'static::first',
13176
+ 'ZREVRANK' => 'static::first',
13177
+ 'ZREMRANGEBYRANK' => 'static::first',
13178
+ 'HSET' => 'static::first',
13179
+ 'HSETNX' => 'static::first',
13180
+ 'HMSET' => 'static::first',
13181
+ 'HINCRBY' => 'static::first',
13182
+ 'HGET' => 'static::first',
13183
+ 'HMGET' => 'static::first',
13184
+ 'HDEL' => 'static::first',
13185
+ 'HEXISTS' => 'static::first',
13186
+ 'HLEN' => 'static::first',
13187
+ 'HKEYS' => 'static::first',
13188
+ 'HVALS' => 'static::first',
13189
+ 'HGETALL' => 'static::first',
13190
+ 'SUBSCRIBE' => 'static::all',
13191
+ 'UNSUBSCRIBE' => 'static::all',
13192
+ 'PSUBSCRIBE' => 'static::all',
13193
+ 'PUNSUBSCRIBE' => 'static::all',
13194
+ 'PUBLISH' => 'static::first',
13195
  /* ---------------- Redis 2.2 ---------------- */
13196
+ 'PERSIST' => 'static::first',
13197
+ 'STRLEN' => 'static::first',
13198
+ 'SETRANGE' => 'static::first',
13199
+ 'GETRANGE' => 'static::first',
13200
+ 'SETBIT' => 'static::first',
13201
+ 'GETBIT' => 'static::first',
13202
+ 'RPUSHX' => 'static::first',
13203
+ 'LPUSHX' => 'static::first',
13204
+ 'LINSERT' => 'static::first',
13205
+ 'BRPOPLPUSH' => 'static::skipLast',
13206
+ 'ZREVRANGEBYSCORE' => 'static::first',
13207
+ 'WATCH' => 'static::all',
13208
  /* ---------------- Redis 2.6 ---------------- */
13209
+ 'PTTL' => 'static::first',
13210
+ 'PEXPIRE' => 'static::first',
13211
+ 'PEXPIREAT' => 'static::first',
13212
+ 'PSETEX' => 'static::first',
13213
+ 'INCRBYFLOAT' => 'static::first',
13214
+ 'BITOP' => 'static::skipFirst',
13215
+ 'BITCOUNT' => 'static::first',
13216
+ 'HINCRBYFLOAT' => 'static::first',
13217
+ 'EVAL' => 'static::evalKeys',
13218
+ 'EVALSHA' => 'static::evalKeys',
13219
+ 'MIGRATE' => 'static::migrate',
13220
  /* ---------------- Redis 2.8 ---------------- */
13221
+ 'SSCAN' => 'static::first',
13222
+ 'ZSCAN' => 'static::first',
13223
+ 'HSCAN' => 'static::first',
13224
+ 'PFADD' => 'static::first',
13225
+ 'PFCOUNT' => 'static::all',
13226
+ 'PFMERGE' => 'static::all',
13227
+ 'ZLEXCOUNT' => 'static::first',
13228
+ 'ZRANGEBYLEX' => 'static::first',
13229
+ 'ZREMRANGEBYLEX' => 'static::first',
13230
+ 'ZREVRANGEBYLEX' => 'static::first',
13231
+ 'BITPOS' => 'static::first',
13232
+ /* ---------------- Redis 3.2 ---------------- */
13233
+ 'HSTRLEN' => 'static::first',
13234
  );
13235
  }
13236
 
13293
  }
13294
 
13295
  if (!is_callable($callback)) {
13296
+ throw new \InvalidArgumentException(
13297
+ 'Callback must be a valid callable object or NULL'
13298
  );
13299
  }
13300
 
13370
  if ($arguments = $command->getArguments()) {
13371
  $length = count($arguments);
13372
 
13373
+ for ($i = 1; $i < $length; ++$i) {
13374
  $arguments[$i] = "$prefix{$arguments[$i]}";
13375
  }
13376
 
13389
  if ($arguments = $command->getArguments()) {
13390
  $length = count($arguments);
13391
 
13392
+ for ($i = 0; $i < $length - 1; ++$i) {
13393
  $arguments[$i] = "$prefix{$arguments[$i]}";
13394
  }
13395
 
13409
  $arguments[0] = "$prefix{$arguments[0]}";
13410
 
13411
  if (($count = count($arguments)) > 1) {
13412
+ for ($i = 1; $i < $count; ++$i) {
13413
  switch ($arguments[$i]) {
13414
  case 'BY':
13415
  case 'STORE':
13443
  public static function evalKeys(CommandInterface $command, $prefix)
13444
  {
13445
  if ($arguments = $command->getArguments()) {
13446
+ for ($i = 2; $i < $arguments[1] + 2; ++$i) {
13447
  $arguments[$i] = "$prefix{$arguments[$i]}";
13448
  }
13449
 
13463
  $arguments[0] = "$prefix{$arguments[0]}";
13464
  $length = ((int) $arguments[1]) + 2;
13465
 
13466
+ for ($i = 2; $i < $length; ++$i) {
13467
  $arguments[$i] = "$prefix{$arguments[$i]}";
13468
  }
13469
 
13470
  $command->setRawArguments($arguments);
13471
  }
13472
  }
13473
+
13474
+ /**
13475
+ * Applies the specified prefix to the key of a MIGRATE command.
13476
+ *
13477
+ * @param CommandInterface $command Command instance.
13478
+ * @param string $prefix Prefix string.
13479
+ */
13480
+ public static function migrate(CommandInterface $command, $prefix)
13481
+ {
13482
+ if ($arguments = $command->getArguments()) {
13483
+ $arguments[2] = "$prefix{$arguments[2]}";
13484
+ $command->setRawArguments($arguments);
13485
+ }
13486
+ }
13487
  }
13488
 
13489
  /* --------------------------------------------------------------------------- */
13497
  use Predis\Protocol\ResponseReaderInterface;
13498
  use Predis\CommunicationException;
13499
  use Predis\Protocol\ProtocolException;
 
13500
  use Predis\Response\Error as ErrorResponse;
13501
  use Predis\Response\Iterator\MultiBulk as MultiBulkIterator;
13502
+ use Predis\Response\Status as StatusResponse;
13503
 
13504
  /**
13505
  * Response reader for the standard Redis wire protocol.
13506
  *
13507
  * @link http://redis.io/topics/protocol
13508
+ *
13509
  * @author Daniele Alessandri <suppakilla@gmail.com>
13510
  */
13511
  class ResponseReader implements ResponseReaderInterface
13560
  return $this->handlers[$prefix];
13561
  }
13562
 
13563
+ return;
13564
  }
13565
 
13566
  /**
13604
  * Request serializer for the standard Redis wire protocol.
13605
  *
13606
  * @link http://redis.io/topics/protocol
13607
+ *
13608
  * @author Daniele Alessandri <suppakilla@gmail.com>
13609
  */
13610
  class RequestSerializer implements RequestSerializerInterface
13622
 
13623
  $buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
13624
 
13625
+ for ($i = 0, $reqlen--; $i < $reqlen; ++$i) {
13626
  $argument = $arguments[$i];
13627
  $arglen = strlen($argument);
13628
  $buffer .= "\${$arglen}\r\n{$argument}\r\n";
13636
  * Protocol processor for the standard Redis wire protocol.
13637
  *
13638
  * @link http://redis.io/topics/protocol
13639
+ *
13640
  * @author Daniele Alessandri <suppakilla@gmail.com>
13641
  */
13642
  class ProtocolProcessor implements ProtocolProcessorInterface
13678
  case '$':
13679
  $size = (int) $payload;
13680
  if ($size === -1) {
13681
+ return;
13682
  }
13683
 
13684
  return substr($connection->readBuffer($size + 2), 0, -2);
13687
  $count = (int) $payload;
13688
 
13689
  if ($count === -1) {
13690
+ return;
13691
  }
13692
  if ($this->mbiterable) {
13693
  return new MultiBulkIterator($connection, $count);
13695
 
13696
  $multibulk = array();
13697
 
13698
+ for ($i = 0; $i < $count; ++$i) {
13699
  $multibulk[$i] = $this->read($connection);
13700
  }
13701
 
13738
  * pluggable handlers to serialize requests and deserialize responses.
13739
  *
13740
  * @link http://redis.io/topics/protocol
13741
+ *
13742
  * @author Daniele Alessandri <suppakilla@gmail.com>
13743
  */
13744
  class CompositeProtocolProcessor implements ProtocolProcessorInterface
13826
 
13827
  namespace Predis\PubSub;
13828
 
 
13829
  use Predis\ClientException;
13830
  use Predis\ClientInterface;
13831
  use Predis\Command\Command;
 
13832
  use Predis\Connection\AggregateConnectionInterface;
13833
+ use Predis\NotSupportedException;
13834
 
13835
  /**
13836
  * Base implementation of a PUB/SUB consumer abstraction based on PHP iterators.
13837
  *
13838
  * @author Daniele Alessandri <suppakilla@gmail.com>
13839
  */
13840
+ abstract class AbstractConsumer implements \Iterator
13841
  {
13842
  const SUBSCRIBE = 'subscribe';
13843
  const UNSUBSCRIBE = 'unsubscribe';
13847
  const PMESSAGE = 'pmessage';
13848
  const PONG = 'pong';
13849
 
13850
+ const STATUS_VALID = 1; // 0b0001
13851
+ const STATUS_SUBSCRIBED = 2; // 0b0010
13852
+ const STATUS_PSUBSCRIBED = 4; // 0b0100
13853
 
13854
  private $position = null;
13855
  private $statusFlags = self::STATUS_VALID;
14002
  public function next()
14003
  {
14004
  if ($this->valid()) {
14005
+ ++$this->position;
14006
  }
14007
 
14008
  return $this->position;
14027
  */
14028
  protected function invalidate()
14029
  {
14030
+ $this->statusFlags = 0; // 0b0000;
14031
  }
14032
 
14033
  /**
14072
  protected function assertCallback($callable)
14073
  {
14074
  if (!is_callable($callable)) {
14075
+ throw new \InvalidArgumentException('The given argument must be a callable object.');
14076
  }
14077
  }
14078
 
14123
  */
14124
  public function attachCallback($channel, $callback)
14125
  {
14126
+ $callbackName = $this->getPrefixKeys().$channel;
14127
 
14128
  $this->assertCallback($callback);
14129
  $this->callbacks[$callbackName] = $callback;
14137
  */
14138
  public function detachCallback($channel)
14139
  {
14140
+ $callbackName = $this->getPrefixKeys().$channel;
14141
 
14142
  if (isset($this->callbacks[$callbackName])) {
14143
  unset($this->callbacks[$callbackName]);
14181
  }
14182
 
14183
  /**
14184
+ * Return the prefix used for keys.
14185
  *
14186
  * @return string
14187
  */
14310
 
14311
  case self::MESSAGE:
14312
  return (object) array(
14313
+ 'kind' => $response[0],
14314
  'channel' => $response[1],
14315
  'payload' => $response[2],
14316
  );
14317
 
14318
  case self::PMESSAGE:
14319
  return (object) array(
14320
+ 'kind' => $response[0],
14321
  'pattern' => $response[1],
14322
  'channel' => $response[2],
14323
  'payload' => $response[3],
14325
 
14326
  case self::PONG:
14327
  return (object) array(
14328
+ 'kind' => $response[0],
14329
  'payload' => $response[1],
14330
  );
14331
 
14342
  namespace Predis\Transaction;
14343
 
14344
  use Predis\PredisException;
 
 
 
14345
  use Predis\ClientContextInterface;
14346
  use Predis\ClientException;
14347
  use Predis\ClientInterface;
14348
+ use Predis\Command\CommandInterface;
14349
  use Predis\CommunicationException;
14350
+ use Predis\Connection\AggregateConnectionInterface;
14351
  use Predis\NotSupportedException;
14352
+ use Predis\Protocol\ProtocolException;
14353
  use Predis\Response\ErrorInterface as ErrorResponseInterface;
14354
  use Predis\Response\ServerException;
14355
  use Predis\Response\Status as StatusResponse;
 
 
 
14356
 
14357
  /**
14358
  * Utility class used to track the state of a MULTI / EXEC transaction.
14522
  protected $client;
14523
  protected $commands;
14524
  protected $exceptions = true;
14525
+ protected $attempts = 0;
14526
+ protected $watchKeys = array();
14527
+ protected $modeCAS = false;
14528
 
14529
  /**
14530
  * @param ClientInterface $client Client instance used by the transaction.
14597
  protected function reset()
14598
  {
14599
  $this->state->reset();
14600
+ $this->commands = new \SplQueue();
14601
  }
14602
 
14603
  /**
14653
  * @param string $commandID Command ID.
14654
  * @param array $arguments Arguments for the command.
14655
  *
 
 
14656
  * @throws ServerException
14657
+ *
14658
+ * @return mixed
14659
  */
14660
  protected function call($commandID, array $arguments = array())
14661
  {
14675
  *
14676
  * @param CommandInterface $command Command instance.
14677
  *
 
 
14678
  * @throws AbortedMultiExecException
14679
  * @throws CommunicationException
14680
+ *
14681
+ * @return $this|mixed
14682
  */
14683
  public function executeCommand(CommandInterface $command)
14684
  {
14706
  *
14707
  * @param string|array $keys One or more keys.
14708
  *
 
 
14709
  * @throws NotSupportedException
14710
  * @throws ClientException
14711
+ *
14712
+ * @return mixed
14713
  */
14714
  public function watch($keys)
14715
  {
14747
  /**
14748
  * Executes UNWATCH.
14749
  *
 
 
14750
  * @throws NotSupportedException
14751
+ *
14752
+ * @return MultiExec
14753
  */
14754
  public function unwatch()
14755
  {
14798
  *
14799
  * @param mixed $callable Callback for execution.
14800
  *
14801
+ * @throws \InvalidArgumentException
14802
  * @throws ClientException
14803
  */
14804
  private function checkBeforeExecution($callable)
14811
 
14812
  if ($callable) {
14813
  if (!is_callable($callable)) {
14814
+ throw new \InvalidArgumentException('The argument must be a callable object.');
14815
  }
14816
 
14817
  if (!$this->commands->isEmpty()) {
14835
  *
14836
  * @param mixed $callable Optional callback for execution.
14837
  *
 
 
14838
  * @throws CommunicationException
14839
  * @throws AbortedMultiExecException
14840
  * @throws ServerException
14841
+ *
14842
+ * @return array
14843
  */
14844
  public function execute($callable = null)
14845
  {
14858
  $this->discard();
14859
  }
14860
 
14861
+ return;
14862
  }
14863
 
14864
  $execResponse = $this->call('EXEC');
14886
  $this->onProtocolError('EXEC returned an unexpected number of response items.');
14887
  }
14888
 
14889
+ for ($i = 0; $i < $size; ++$i) {
14890
  $cmdResponse = $execResponse[$i];
14891
 
14892
  if ($cmdResponse instanceof ErrorResponseInterface && $this->exceptions) {
14918
  // NOOP
14919
  } catch (ServerException $exception) {
14920
  // NOOP
14921
+ } catch (\Exception $exception) {
14922
  $this->discard();
14923
  }
14924
 
14980
 
14981
  namespace Predis\Session;
14982
 
 
14983
  use Predis\ClientInterface;
14984
 
14985
  /**
14992
  *
14993
  * @author Daniele Alessandri <suppakilla@gmail.com>
14994
  */
14995
+ class Handler implements \SessionHandlerInterface
14996
  {
14997
  protected $client;
14998
  protected $ttl;
15017
  */
15018
  public function register()
15019
  {
15020
+ if (PHP_VERSION_ID >= 50400) {
15021
  session_set_save_handler($this, true);
15022
  } else {
15023
  session_set_save_handler(
15114
 
15115
  namespace Predis\Monitor;
15116
 
 
15117
  use Predis\ClientInterface;
 
15118
  use Predis\Connection\AggregateConnectionInterface;
15119
+ use Predis\NotSupportedException;
15120
 
15121
  /**
15122
  * Redis MONITOR consumer.
15123
  *
15124
  * @author Daniele Alessandri <suppakilla@gmail.com>
15125
  */
15126
+ class Consumer implements \Iterator
15127
  {
15128
  private $client;
15129
  private $valid;
15222
  */
15223
  public function next()
15224
  {
15225
+ ++$this->position;
15226
  }
15227
 
15228
  /**
15267
 
15268
  return (object) array(
15269
  'timestamp' => (float) $timestamp,
15270
+ 'database' => $database,
15271
+ 'client' => $client,
15272
+ 'command' => substr($command, 1, -1),
15273
  'arguments' => $arguments,
15274
  );
15275
  }
15279
 
15280
  namespace Predis\Replication;
15281
 
 
15282
  use Predis\Command\CommandInterface;
15283
+ use Predis\NotSupportedException;
15284
 
15285
  /**
15286
  * Defines a strategy for master/slave replication.
15309
  *
15310
  * @param CommandInterface $command Command instance.
15311
  *
 
 
15312
  * @throws NotSupportedException
15313
+ *
15314
+ * @return bool
15315
  */
15316
  public function isReadOperation(CommandInterface $command)
15317
  {
15422
  protected function getDisallowedOperations()
15423
  {
15424
  return array(
15425
+ 'SHUTDOWN' => true,
15426
+ 'INFO' => true,
15427
+ 'DBSIZE' => true,
15428
+ 'LASTSAVE' => true,
15429
+ 'CONFIG' => true,
15430
+ 'MONITOR' => true,
15431
+ 'SLAVEOF' => true,
15432
+ 'SAVE' => true,
15433
+ 'BGSAVE' => true,
15434
+ 'BGREWRITEAOF' => true,
15435
+ 'SLOWLOG' => true,
15436
  );
15437
  }
15438
 
15444
  protected function getReadOnlyOperations()
15445
  {
15446
  return array(
15447
+ 'EXISTS' => true,
15448
+ 'TYPE' => true,
15449
+ 'KEYS' => true,
15450
+ 'SCAN' => true,
15451
+ 'RANDOMKEY' => true,
15452
+ 'TTL' => true,
15453
+ 'GET' => true,
15454
+ 'MGET' => true,
15455
+ 'SUBSTR' => true,
15456
+ 'STRLEN' => true,
15457
+ 'GETRANGE' => true,
15458
+ 'GETBIT' => true,
15459
+ 'LLEN' => true,
15460
+ 'LRANGE' => true,
15461
+ 'LINDEX' => true,
15462
+ 'SCARD' => true,
15463
+ 'SISMEMBER' => true,
15464
+ 'SINTER' => true,
15465
+ 'SUNION' => true,
15466
+ 'SDIFF' => true,
15467
+ 'SMEMBERS' => true,
15468
+ 'SSCAN' => true,
15469
+ 'SRANDMEMBER' => true,
15470
+ 'ZRANGE' => true,
15471
+ 'ZREVRANGE' => true,
15472
+ 'ZRANGEBYSCORE' => true,
15473
+ 'ZREVRANGEBYSCORE' => true,
15474
+ 'ZCARD' => true,
15475
+ 'ZSCORE' => true,
15476
+ 'ZCOUNT' => true,
15477
+ 'ZRANK' => true,
15478
+ 'ZREVRANK' => true,
15479
+ 'ZSCAN' => true,
15480
+ 'ZLEXCOUNT' => true,
15481
+ 'ZRANGEBYLEX' => true,
15482
+ 'ZREVRANGEBYLEX' => true,
15483
+ 'HGET' => true,
15484
+ 'HMGET' => true,
15485
+ 'HEXISTS' => true,
15486
+ 'HLEN' => true,
15487
+ 'HKEYS' => true,
15488
+ 'HVALS' => true,
15489
+ 'HGETALL' => true,
15490
+ 'HSCAN' => true,
15491
+ 'HSTRLEN' => true,
15492
+ 'PING' => true,
15493
+ 'AUTH' => true,
15494
+ 'SELECT' => true,
15495
+ 'ECHO' => true,
15496
+ 'QUIT' => true,
15497
+ 'OBJECT' => true,
15498
+ 'BITCOUNT' => true,
15499
+ 'BITPOS' => true,
15500
+ 'TIME' => true,
15501
+ 'PFCOUNT' => true,
15502
+ 'SORT' => array($this, 'isSortReadOnly'),
15503
  );
15504
  }
15505
  }
languages/redis-cache.pot CHANGED
@@ -1,20 +1,20 @@
1
- # Copyright (C) 2015 Redis Object Cache
2
  # This file is distributed under the same license as the Redis Object Cache package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Redis Object Cache 1.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/redis-cache\n"
7
- "POT-Creation-Date: 2015-06-16 09:42:28+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #. #-#-#-#-# plugin.pot (Redis Object Cache 1.2) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
- #: includes/admin-page.php:6 redis-cache.php:48
18
  msgid "Redis Object Cache"
19
  msgstr ""
20
 
@@ -74,70 +74,70 @@ msgstr ""
74
  msgid "Disable Object Cache"
75
  msgstr ""
76
 
77
- #: redis-cache.php:49
78
  msgid "Redis"
79
  msgstr ""
80
 
81
- #: redis-cache.php:155
82
  msgid "Not installed"
83
  msgstr ""
84
 
85
- #: redis-cache.php:159
86
  msgid "Connected"
87
  msgstr ""
88
 
89
- #: redis-cache.php:159
90
  msgid "Not connected"
91
  msgstr ""
92
 
93
- #: redis-cache.php:162
94
  msgid "Unknown"
95
  msgstr ""
96
 
97
- #: redis-cache.php:184
98
  msgid ""
99
  "The Redis object cache drop-in is outdated. <a href=\"%s\">Update it now</a>."
100
  msgstr ""
101
 
102
- #: redis-cache.php:190
103
  msgid ""
104
  "Another object cache drop-in is already active. To use Redis, <a href=\"%s"
105
  "\">please replace it now</a>."
106
  msgstr ""
107
 
108
- #: redis-cache.php:206
109
  msgid "This plugin requires PHP 5.4 or greater."
110
  msgstr ""
111
 
112
- #: redis-cache.php:215
113
  msgid "Object Cache enabled."
114
  msgstr ""
115
 
116
- #: redis-cache.php:218
117
  msgid "Object Cache could not be enabled."
118
  msgstr ""
119
 
120
- #: redis-cache.php:221
121
  msgid "Object Cache disabled."
122
  msgstr ""
123
 
124
- #: redis-cache.php:224
125
  msgid "Object Cache could not be disabled."
126
  msgstr ""
127
 
128
- #: redis-cache.php:227
129
  msgid "Object Cache flushed."
130
  msgstr ""
131
 
132
- #: redis-cache.php:230
133
  msgid "Object Cache could not be flushed."
134
  msgstr ""
135
 
136
- #: redis-cache.php:233
137
  msgid "Drop-in updated."
138
  msgstr ""
139
 
140
- #: redis-cache.php:236
141
  msgid "Drop-in could not be updated."
142
  msgstr ""
143
 
@@ -147,8 +147,8 @@ msgstr ""
147
 
148
  #. Description of the plugin/theme
149
  msgid ""
150
- "A Redis backend for the WordPress Object Cache based on the Predis client "
151
- "library for PHP."
152
  msgstr ""
153
 
154
  #. Author of the plugin/theme
1
+ # Copyright (C) 2016 Redis Object Cache
2
  # This file is distributed under the same license as the Redis Object Cache package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Redis Object Cache 1.2.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/redis-cache\n"
7
+ "POT-Creation-Date: 2016-02-10 19:39:42+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2016-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #. #-#-#-#-# plugin.pot (Redis Object Cache 1.2.2) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
+ #: includes/admin-page.php:6 redis-cache.php:50
18
  msgid "Redis Object Cache"
19
  msgstr ""
20
 
74
  msgid "Disable Object Cache"
75
  msgstr ""
76
 
77
+ #: redis-cache.php:51
78
  msgid "Redis"
79
  msgstr ""
80
 
81
+ #: redis-cache.php:157
82
  msgid "Not installed"
83
  msgstr ""
84
 
85
+ #: redis-cache.php:161
86
  msgid "Connected"
87
  msgstr ""
88
 
89
+ #: redis-cache.php:161
90
  msgid "Not connected"
91
  msgstr ""
92
 
93
+ #: redis-cache.php:164
94
  msgid "Unknown"
95
  msgstr ""
96
 
97
+ #: redis-cache.php:186
98
  msgid ""
99
  "The Redis object cache drop-in is outdated. <a href=\"%s\">Update it now</a>."
100
  msgstr ""
101
 
102
+ #: redis-cache.php:192
103
  msgid ""
104
  "Another object cache drop-in is already active. To use Redis, <a href=\"%s"
105
  "\">please replace it now</a>."
106
  msgstr ""
107
 
108
+ #: redis-cache.php:208
109
  msgid "This plugin requires PHP 5.4 or greater."
110
  msgstr ""
111
 
112
+ #: redis-cache.php:217
113
  msgid "Object Cache enabled."
114
  msgstr ""
115
 
116
+ #: redis-cache.php:220
117
  msgid "Object Cache could not be enabled."
118
  msgstr ""
119
 
120
+ #: redis-cache.php:223
121
  msgid "Object Cache disabled."
122
  msgstr ""
123
 
124
+ #: redis-cache.php:226
125
  msgid "Object Cache could not be disabled."
126
  msgstr ""
127
 
128
+ #: redis-cache.php:229
129
  msgid "Object Cache flushed."
130
  msgstr ""
131
 
132
+ #: redis-cache.php:232
133
  msgid "Object Cache could not be flushed."
134
  msgstr ""
135
 
136
+ #: redis-cache.php:235
137
  msgid "Drop-in updated."
138
  msgstr ""
139
 
140
+ #: redis-cache.php:238
141
  msgid "Drop-in could not be updated."
142
  msgstr ""
143
 
147
 
148
  #. Description of the plugin/theme
149
  msgid ""
150
+ "A persistent object cache backend powered by Redis. Supports HHVM's Redis "
151
+ "extension, the PCEL Redis Extension and the Predis library for PHP."
152
  msgstr ""
153
 
154
  #. Author of the plugin/theme
readme.txt CHANGED
@@ -1,19 +1,19 @@
1
  === Redis Object Cache ===
2
  Contributors: tillkruess
3
- Donate link: http://till.kruss.me/donations/
4
  Tags: redis, predis, hhvm, pecl, caching, cache, object cache, wp object cache, server, performance, optimize, speed, load
5
  Requires at least: 3.3
6
- Tested up to: 4.3
7
- Stable tag: 1.2
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
11
- A persistent object cache backend powered by Redis. Supports HHVM's Redis extension, the PCEL Redis Extension and the Predis library for PHP.
12
 
13
 
14
  == Description ==
15
 
16
- A persistent object cache backend powered by Redis. Supports [HHVM's Redis extension](https://github.com/facebook/hhvm/tree/master/hphp/system/php/redis), the [PCEL Redis Extension](https://github.com/phpredis/phpredis) and the [Predis](https://github.com/nrk/predis/) library for PHP *(Predis requires PHP 5.4 or greater)*.
17
 
18
  To adjust the connection parameters or prefixing cache keys, see [Other Notes](http://wordpress.org/extend/plugins/redis-cache/other_notes/).
19
 
@@ -26,9 +26,11 @@ For detailed installation instructions, please read the [standard installation p
26
 
27
  1. Make sure Redis in installed and running.
28
  2. Install and activate plugin.
29
- 3. Enable the object cache under _Tools -> Redis_.
30
  4. If necessary, adjust [connection parameters](http://wordpress.org/extend/plugins/redis-cache/other_notes/).
31
 
 
 
32
 
33
  == Connection Parameters ==
34
 
@@ -83,6 +85,23 @@ Users with setups where multiple installs share a common `wp-config.php` or `$ta
83
 
84
  == Changelog ==
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  = 1.2 =
87
 
88
  * Added Multisite support
@@ -96,7 +115,7 @@ Users with setups where multiple installs share a common `wp-config.php` or `$ta
96
  = 1.1 =
97
 
98
  * Added support for HHVM's Redis extension
99
- * Added support for PCEL Redis extension
100
  * Added `WP_REDIS_CLIENT` constant, to set prefered Redis client
101
  * Added `WP_REDIS_MAXTTL` constant, to force expiration of cache keys
102
  * Improved `add_or_replace()`, `get()`, `set()` and `delete()` methods
@@ -125,13 +144,21 @@ Users with setups where multiple installs share a common `wp-config.php` or `$ta
125
 
126
  == Upgrade Notice ==
127
 
 
 
 
 
 
 
 
 
128
  = 1.1.1 =
129
 
130
- This update fixes critial bugs with the HHVM extension
131
 
132
  = 1.1 =
133
 
134
- This update includes bug fixes and adds supports for HHVM/PCEL Redis extensions.
135
 
136
  = 1.0.2 =
137
 
1
  === Redis Object Cache ===
2
  Contributors: tillkruess
3
+ Donate link: https://www.paypal.me/tillkruss
4
  Tags: redis, predis, hhvm, pecl, caching, cache, object cache, wp object cache, server, performance, optimize, speed, load
5
  Requires at least: 3.3
6
+ Tested up to: 4.4
7
+ Stable tag: 1.2.2
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
11
+ A persistent object cache backend powered by Redis. Supports HHVM's Redis extension, the PECL Redis Extension and the Predis library for PHP.
12
 
13
 
14
  == Description ==
15
 
16
+ A persistent object cache backend powered by Redis. Supports [HHVM's Redis extension](https://github.com/facebook/hhvm/tree/master/hphp/system/php/redis), the [PECL Redis Extension](https://github.com/phpredis/phpredis) and the [Predis](https://github.com/nrk/predis/) library for PHP *(Predis requires PHP 5.4 or greater)*.
17
 
18
  To adjust the connection parameters or prefixing cache keys, see [Other Notes](http://wordpress.org/extend/plugins/redis-cache/other_notes/).
19
 
26
 
27
  1. Make sure Redis in installed and running.
28
  2. Install and activate plugin.
29
+ 3. Enable the object cache under _Settings -> Redis_.
30
  4. If necessary, adjust [connection parameters](http://wordpress.org/extend/plugins/redis-cache/other_notes/).
31
 
32
+ If you server doesn't support the [WordPress Filesystem API](https://codex.wordpress.org/Filesystem_API), you have to manually copy the `object-cache.php` file from the `/plugins/redis-cache/includes/` directory to the `/wp-content/` directory.
33
+
34
 
35
  == Connection Parameters ==
36
 
85
 
86
  == Changelog ==
87
 
88
+ = 1.2.2 =
89
+
90
+ * Added `redis_object_cache_set` action
91
+ * Added `redis_object_cache_get` action and filter
92
+ * Prevented duplicated admin status messages
93
+ * Load bundled Predis library only if necessary
94
+ * Load bundled Predis library using `WP_CONTENT_DIR` constant
95
+ * Updated `stats()` method output to be uniform with WordPress
96
+
97
+ = 1.2.1 =
98
+
99
+ * Added `composer.json`
100
+ * Added deactivation and uninstall hooks to delete `object-cache.php`
101
+ * Added local serialization functions for better `advanced-cache.php` support
102
+ * Updated bundled Predis version to `1.0.3`
103
+ * Updated heading structure to be semantic
104
+
105
  = 1.2 =
106
 
107
  * Added Multisite support
115
  = 1.1 =
116
 
117
  * Added support for HHVM's Redis extension
118
+ * Added support for PECL Redis extension
119
  * Added `WP_REDIS_CLIENT` constant, to set prefered Redis client
120
  * Added `WP_REDIS_MAXTTL` constant, to force expiration of cache keys
121
  * Improved `add_or_replace()`, `get()`, `set()` and `delete()` methods
144
 
145
  == Upgrade Notice ==
146
 
147
+ = 1.2.2 =
148
+
149
+ This updated includes several bug fixes and improvements.
150
+
151
+ = 1.2.1 =
152
+
153
+ This update includes several improvements and compatibility fixes.
154
+
155
  = 1.1.1 =
156
 
157
+ This update fixes critical bugs with the HHVM extension
158
 
159
  = 1.1 =
160
 
161
+ This update includes bug fixes and adds supports for HHVM/PECL Redis extensions.
162
 
163
  = 1.0.2 =
164
 
redis-cache.php CHANGED
@@ -2,8 +2,8 @@
2
  /*
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
- Description: A Redis backend for the WordPress Object Cache based on the Predis client library for PHP.
6
- Version: 1.2
7
  Text Domain: redis-cache
8
  Domain Path: /languages
9
  Author: Till Krüss
@@ -24,6 +24,8 @@ class RedisObjectCache {
24
 
25
  load_plugin_textdomain( 'redis-cache', false, 'redis-cache/languages' );
26
 
 
 
27
  $this->page = is_multisite() ? 'settings.php?page=redis-cache' : 'options-general.php?page=redis-cache';
28
 
29
  add_action( is_multisite() ? 'network_admin_menu' : 'admin_menu', array( $this, 'add_admin_menu_page' ) );
@@ -335,6 +337,16 @@ class RedisObjectCache {
335
 
336
  }
337
 
 
 
 
 
 
 
 
 
 
 
338
  }
339
 
340
  new RedisObjectCache;
2
  /*
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
+ Description: A persistent object cache backend powered by Redis. Supports HHVM's Redis extension, the PCEL Redis Extension and the Predis library for PHP.
6
+ Version: 1.2.2
7
  Text Domain: redis-cache
8
  Domain Path: /languages
9
  Author: Till Krüss
24
 
25
  load_plugin_textdomain( 'redis-cache', false, 'redis-cache/languages' );
26
 
27
+ register_deactivation_hook(__FILE__, array( $this, 'on_deactivation' ) );
28
+
29
  $this->page = is_multisite() ? 'settings.php?page=redis-cache' : 'options-general.php?page=redis-cache';
30
 
31
  add_action( is_multisite() ? 'network_admin_menu' : 'admin_menu', array( $this, 'add_admin_menu_page' ) );
337
 
338
  }
339
 
340
+ public function on_deactivation() {
341
+
342
+ global $wp_filesystem;
343
+
344
+ if ( $this->validate_object_cache_dropin() && $this->initialize_filesystem( '', true ) ) {
345
+ $wp_filesystem->delete( WP_CONTENT_DIR . '/object-cache.php' );
346
+ }
347
+
348
+ }
349
+
350
  }
351
 
352
  new RedisObjectCache;
uninstall.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) exit;
4
+
5
+ global $wp_filesystem;
6
+
7
+ ob_start();
8
+
9
+ if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) && method_exists( $GLOBALS[ 'wp_object_cache' ], 'redis_status' ) ) {
10
+
11
+ if ( WP_Filesystem( request_filesystem_credentials( '' ) ) ) {
12
+ $wp_filesystem->delete( WP_CONTENT_DIR . '/object-cache.php' );
13
+ }
14
+
15
+ }
16
+
17
+ ob_end_clean();