Redis Object Cache - Version 1.2.3

Version Description

  • UI improvements
Download this release

Release Info

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

Code changes from version 1.2 to 1.2.3

includes/admin-page.css CHANGED
@@ -1,4 +1,10 @@
1
 
 
 
 
 
 
 
2
  .wrap .button.delete {
3
  background: #d54e21;
4
  border-color: #a83d1a;
@@ -29,7 +35,3 @@
29
  0 0 0 1px #d54e21,
30
  0 0 2px 1px rgba( 30, 140, 190, .8 );
31
  }
32
-
33
- .form-table table td {
34
- padding: 0 1em 0 0;
35
- }
1
 
2
+ .settings_page_redis-cache .form-table th,
3
+ .settings_page_redis-cache .form-table td {
4
+ padding-top: 7px;
5
+ padding-bottom: 7px;
6
+ }
7
+
8
  .wrap .button.delete {
9
  background: #d54e21;
10
  border-color: #a83d1a;
35
  0 0 0 1px #d54e21,
36
  0 0 2px 1px rgba( 30, 140, 190, .8 );
37
  }
 
 
 
 
includes/admin-page.php CHANGED
@@ -3,74 +3,86 @@
3
 
4
  <div class="wrap">
5
 
6
- <h2><?php _e( 'Redis Object Cache', 'redis-cache' ); ?></h2>
7
 
8
- <?php settings_errors(); ?>
9
 
10
  <table class="form-table">
11
 
12
- <tr valign="top">
13
- <th scope="row"><?php _e( 'Redis Status', 'redis-cache' ); ?></th>
14
- <td><code><?php echo $this->get_redis_status(); ?></code></td>
15
  </tr>
16
 
17
- <tr valign="top">
18
- <th scope="row"><?php _e( 'Configuration', 'redis-cache' ); ?></th>
19
- <td>
20
- <table>
21
- <?php if ( ! is_null( $this->get_redis_client_name() ) ) : ?>
22
- <tr>
23
- <td><?php _e( 'Client:', 'redis-cache' ); ?></td>
24
- <td><code><?php echo $this->get_redis_client_name(); ?></code></td>
25
- </tr>
26
- <?php endif; ?>
27
- <tr>
28
- <td><?php _e( 'Protocol:', 'redis-cache' ); ?></td>
29
- <td><code><?php echo strtoupper( esc_html( $this->get_redis_scheme() ) ); ?></code></td>
30
- </tr>
31
- <?php if ( strcasecmp( 'tcp', $this->get_redis_scheme() ) === 0 ) : ?>
32
- <tr>
33
- <td><?php _e( 'Host:', 'redis-cache' ); ?></td>
34
- <td><code><?php echo esc_html( $this->get_redis_host() ); ?></code></td>
35
- </tr>
36
-
37
- <tr>
38
- <td><?php _e( 'Port:', 'redis-cache' ); ?></td>
39
- <td><code><?php echo esc_html( $this->get_redis_port() ); ?></code></td>
40
- </tr>
41
- <?php endif; ?>
42
- <?php if ( strcasecmp( 'unix', $this->get_redis_scheme() ) === 0 ) : ?>
43
- <tr>
44
- <td><?php _e( 'Path:', 'redis-cache' ); ?></td>
45
- <td><code><?php echo esc_html( $this->get_redis_path() ); ?></code></td>
46
- </tr>
47
- <?php endif; ?>
48
- <tr>
49
- <td><?php _e( 'Database:', 'redis-cache' ); ?></td>
50
- <td> <code><?php echo esc_html( $this->get_redis_database() ); ?></code></td>
51
- </tr>
52
- <?php if ( ! is_null( $this->get_redis_password() ) ) : ?>
53
- <tr>
54
- <td><?php _e( 'Password:', 'redis-cache' ); ?></td>
55
- <td><code><?php echo str_repeat( '*', strlen( $this->get_redis_password() ) ); ?></code></td>
56
- </tr>
57
- <?php endif; ?>
58
- <?php if ( ! is_null( $this->get_redis_cachekey_prefix() ) && trim( $this->get_redis_cachekey_prefix() ) !== '' ) : ?>
59
- <tr>
60
- <td><?php _e( 'Key Prefix:', 'redis-cache' ); ?></td>
61
- <td><code><?php echo esc_html( $this->get_redis_cachekey_prefix() ); ?></code></td>
62
- </tr>
63
- <?php endif; ?>
64
- <?php if ( ! is_null( $this->get_redis_maxttl() ) ) : ?>
65
- <tr>
66
- <td><?php _e( 'Max. TTL:', 'redis-cache' ); ?></td>
67
- <td><code><?php echo esc_html( $this->get_redis_maxttl() ); ?></code></td>
68
- </tr>
69
- <?php endif; ?>
70
- </table>
71
- </td>
72
  </tr>
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  </table>
75
 
76
  <p class="submit">
3
 
4
  <div class="wrap">
5
 
6
+ <h1><?php _e( 'Redis Object Cache', 'redis-cache' ); ?></h1>
7
 
8
+ <h2 class="title"><?php _e( 'Status', 'redis-cache' ); ?></h2>
9
 
10
  <table class="form-table">
11
 
12
+ <tr>
13
+ <th><?php _e( 'Dropin', 'redis-cache' ); ?></th>
14
+ <td><code><?php echo $this->get_dropin_status(); ?></code></td>
15
  </tr>
16
 
17
+ <?php if ( $this->validate_object_cache_dropin() ) : ?>
18
+ <tr>
19
+ <th><?php _e( 'Redis', 'redis-cache' ); ?></th>
20
+ <td><code><?php echo $this->get_redis_status(); ?></code></td>
21
+ </tr>
22
+ <?php endif; ?>
23
+
24
+ </table>
25
+
26
+ <h2 class="title"><?php _e( 'Configuration', 'redis-cache' ); ?></h2>
27
+
28
+ <table class="form-table">
29
+
30
+ <?php if ( ! is_null( $this->get_redis_client_name() ) ) : ?>
31
+ <tr>
32
+ <th><?php _e( 'Client:', 'redis-cache' ); ?></th>
33
+ <td><code><?php echo esc_html( $this->get_redis_client_name() ); ?></code></td>
34
+ </tr>
35
+ <?php endif; ?>
36
+
37
+ <tr>
38
+ <th><?php _e( 'Protocol:', 'redis-cache' ); ?></th>
39
+ <td><code><?php echo strtoupper( esc_html( $this->get_redis_scheme() ) ); ?></code></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  </tr>
41
 
42
+ <?php if ( strcasecmp( 'tcp', $this->get_redis_scheme() ) === 0 ) : ?>
43
+ <tr>
44
+ <th><?php _e( 'Host:', 'redis-cache' ); ?></th>
45
+ <td><code><?php echo esc_html( $this->get_redis_host() ); ?></code></td>
46
+ </tr>
47
+ <tr>
48
+ <th><?php _e( 'Port:', 'redis-cache' ); ?></th>
49
+ <td><code><?php echo esc_html( $this->get_redis_port() ); ?></code></td>
50
+ </tr>
51
+ <?php endif; ?>
52
+
53
+ <?php if ( strcasecmp( 'unix', $this->get_redis_scheme() ) === 0 ) : ?>
54
+ <tr>
55
+ <th><?php _e( 'Path:', 'redis-cache' ); ?></th>
56
+ <td><code><?php echo esc_html( $this->get_redis_path() ); ?></code></td>
57
+ </tr>
58
+ <?php endif; ?>
59
+
60
+ <tr>
61
+ <th><?php _e( 'Database:', 'redis-cache' ); ?></th>
62
+ <td><code><?php echo esc_html( $this->get_redis_database() ); ?></code></td>
63
+ </tr>
64
+
65
+ <?php if ( ! is_null( $this->get_redis_password() ) ) : ?>
66
+ <tr>
67
+ <th><?php _e( 'Password:', 'redis-cache' ); ?></th>
68
+ <td><code><?php echo str_repeat( '*', strlen( $this->get_redis_password() ) ); ?></code></td>
69
+ </tr>
70
+ <?php endif; ?>
71
+
72
+ <?php if ( ! is_null( $this->get_redis_cachekey_prefix() ) && trim( $this->get_redis_cachekey_prefix() ) !== '' ) : ?>
73
+ <tr>
74
+ <th><?php _e( 'Key Prefix:', 'redis-cache' ); ?></th>
75
+ <td><code><?php echo esc_html( $this->get_redis_cachekey_prefix() ); ?></code></td>
76
+ </tr>
77
+ <?php endif; ?>
78
+
79
+ <?php if ( ! is_null( $this->get_redis_maxttl() ) ) : ?>
80
+ <tr>
81
+ <th><?php _e( 'Max. TTL:', 'redis-cache' ); ?></th>
82
+ <td><code><?php echo esc_html( $this->get_redis_maxttl() ); ?></code></td>
83
+ </tr>
84
+ <?php endif; ?>
85
+
86
  </table>
87
 
88
  <p class="submit">
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
 
@@ -365,18 +365,16 @@ class WP_Object_Cache {
365
 
366
  if ( strcasecmp( 'hhvm', $redis_client ) === 0 ) {
367
 
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,11 +384,9 @@ 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';
394
  $this->redis = new Redis();
395
 
396
  if ( strcasecmp( 'unix', $redis[ 'scheme' ] ) === 0 ) {
@@ -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
 
@@ -785,17 +786,14 @@ class WP_Object_Cache {
785
  public function stats() { ?>
786
 
787
  <p>
788
- <strong>Cache Status:</strong> <?php echo $this->redis_status() ? 'Connected' : 'Not connected'; ?><br />
789
  <strong>Cache Hits:</strong> <?php echo $this->cache_hits; ?><br />
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 PECL Redis Extension and the Predis library for PHP.
6
+ Version: 1.2.3
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
 
365
 
366
  if ( strcasecmp( 'hhvm', $redis_client ) === 0 ) {
367
 
368
+ $this->redis_client = sprintf( 'HHVM Extension (v%s)', 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 = sprintf( 'PECL Extension (v%s)', phpversion('redis') );
390
  $this->redis = new Redis();
391
 
392
  if ( strcasecmp( 'unix', $redis[ 'scheme' ] ) === 0 ) {
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 .= sprintf( ' (v%s)', 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
 
786
  public function stats() { ?>
787
 
788
  <p>
789
+ <strong>Cache Status:</strong> <?php echo $this->redis_status() ? 'Connected' : 'Not Connected'; ?><br />
790
  <strong>Cache Hits:</strong> <?php echo $this->cache_hits; ?><br />
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,143 +1,152 @@
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
 
 
 
 
 
21
  #: includes/admin-page.php:13
22
- msgid "Redis Status"
 
 
 
 
23
  msgstr ""
24
 
25
- #: includes/admin-page.php:18
26
  msgid "Configuration"
27
  msgstr ""
28
 
29
- #: includes/admin-page.php:23
30
  msgid "Client:"
31
  msgstr ""
32
 
33
- #: includes/admin-page.php:28
34
  msgid "Protocol:"
35
  msgstr ""
36
 
37
- #: includes/admin-page.php:33
38
  msgid "Host:"
39
  msgstr ""
40
 
41
- #: includes/admin-page.php:38
42
  msgid "Port:"
43
  msgstr ""
44
 
45
- #: includes/admin-page.php:44
46
  msgid "Path:"
47
  msgstr ""
48
 
49
- #: includes/admin-page.php:49
50
  msgid "Database:"
51
  msgstr ""
52
 
53
- #: includes/admin-page.php:54
54
  msgid "Password:"
55
  msgstr ""
56
 
57
- #: includes/admin-page.php:60
58
  msgid "Key Prefix:"
59
  msgstr ""
60
 
61
- #: includes/admin-page.php:66
62
  msgid "Max. TTL:"
63
  msgstr ""
64
 
65
- #: includes/admin-page.php:79
66
  msgid "Flush Cache"
67
  msgstr ""
68
 
69
- #: includes/admin-page.php:84
70
  msgid "Enable Object Cache"
71
  msgstr ""
72
 
73
- #: includes/admin-page.php:86
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 +156,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.3\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/redis-cache\n"
7
+ "POT-Creation-Date: 2016-03-03 06:43:56+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.3) #-#-#-#-#
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
 
21
+ #: includes/admin-page.php:8
22
+ msgid "Status"
23
+ msgstr ""
24
+
25
  #: includes/admin-page.php:13
26
+ msgid "Dropin"
27
+ msgstr ""
28
+
29
+ #: includes/admin-page.php:19 redis-cache.php:51
30
+ msgid "Redis"
31
  msgstr ""
32
 
33
+ #: includes/admin-page.php:26
34
  msgid "Configuration"
35
  msgstr ""
36
 
37
+ #: includes/admin-page.php:32
38
  msgid "Client:"
39
  msgstr ""
40
 
41
+ #: includes/admin-page.php:38
42
  msgid "Protocol:"
43
  msgstr ""
44
 
45
+ #: includes/admin-page.php:44
46
  msgid "Host:"
47
  msgstr ""
48
 
49
+ #: includes/admin-page.php:48
50
  msgid "Port:"
51
  msgstr ""
52
 
53
+ #: includes/admin-page.php:55
54
  msgid "Path:"
55
  msgstr ""
56
 
57
+ #: includes/admin-page.php:61
58
  msgid "Database:"
59
  msgstr ""
60
 
61
+ #: includes/admin-page.php:67
62
  msgid "Password:"
63
  msgstr ""
64
 
65
+ #: includes/admin-page.php:74
66
  msgid "Key Prefix:"
67
  msgstr ""
68
 
69
+ #: includes/admin-page.php:81
70
  msgid "Max. TTL:"
71
  msgstr ""
72
 
73
+ #: includes/admin-page.php:91
74
  msgid "Flush Cache"
75
  msgstr ""
76
 
77
+ #: includes/admin-page.php:96
78
  msgid "Enable Object Cache"
79
  msgstr ""
80
 
81
+ #: includes/admin-page.php:98
82
  msgid "Disable Object Cache"
83
  msgstr ""
84
 
85
+ #: redis-cache.php:179
86
+ msgid "Disabled"
87
  msgstr ""
88
 
89
+ #: redis-cache.php:183 redis-cache.php:198
90
+ msgid "Unknown"
91
  msgstr ""
92
 
93
+ #: redis-cache.php:186
94
+ msgid "Enabled"
95
  msgstr ""
96
 
97
+ #: redis-cache.php:195
98
+ msgid "Connected"
99
  msgstr ""
100
 
101
+ #: redis-cache.php:195
102
+ msgid "Not Connected"
103
  msgstr ""
104
 
105
+ #: redis-cache.php:219
106
  msgid ""
107
+ "The Redis object cache drop-in is outdated. Please <a href=\"%s\">update it "
108
+ "now</a>."
109
  msgstr ""
110
 
111
+ #: redis-cache.php:224
112
  msgid ""
113
+ "Another object cache drop-in was found. To use Redis, <a href=\"%s\">please "
114
+ "replace it now</a>."
115
  msgstr ""
116
 
117
+ #: redis-cache.php:240
118
  msgid "This plugin requires PHP 5.4 or greater."
119
  msgstr ""
120
 
121
+ #: redis-cache.php:249
122
  msgid "Object Cache enabled."
123
  msgstr ""
124
 
125
+ #: redis-cache.php:252
126
  msgid "Object Cache could not be enabled."
127
  msgstr ""
128
 
129
+ #: redis-cache.php:255
130
  msgid "Object Cache disabled."
131
  msgstr ""
132
 
133
+ #: redis-cache.php:258
134
  msgid "Object Cache could not be disabled."
135
  msgstr ""
136
 
137
+ #: redis-cache.php:261
138
  msgid "Object Cache flushed."
139
  msgstr ""
140
 
141
+ #: redis-cache.php:264
142
  msgid "Object Cache could not be flushed."
143
  msgstr ""
144
 
145
+ #: redis-cache.php:267
146
  msgid "Drop-in updated."
147
  msgstr ""
148
 
149
+ #: redis-cache.php:270
150
  msgid "Drop-in could not be updated."
151
  msgstr ""
152
 
156
 
157
  #. Description of the plugin/theme
158
  msgid ""
159
+ "A persistent object cache backend powered by Redis. Supports HHVM's Redis "
160
+ "extension, the PECL Redis Extension and the Predis library for PHP."
161
  msgstr ""
162
 
163
  #. 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,27 @@ 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 +119,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 +148,25 @@ 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.5
7
+ Stable tag: 1.2.3
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.3 =
89
+
90
+ * UI improvements
91
+
92
+ = 1.2.2 =
93
+
94
+ * Added `redis_object_cache_set` action
95
+ * Added `redis_object_cache_get` action and filter
96
+ * Prevented duplicated admin status messages
97
+ * Load bundled Predis library only if necessary
98
+ * Load bundled Predis library using `WP_CONTENT_DIR` constant
99
+ * Updated `stats()` method output to be uniform with WordPress
100
+
101
+ = 1.2.1 =
102
+
103
+ * Added `composer.json`
104
+ * Added deactivation and uninstall hooks to delete `object-cache.php`
105
+ * Added local serialization functions for better `advanced-cache.php` support
106
+ * Updated bundled Predis version to `1.0.3`
107
+ * Updated heading structure to be semantic
108
+
109
  = 1.2 =
110
 
111
  * Added Multisite support
119
  = 1.1 =
120
 
121
  * Added support for HHVM's Redis extension
122
+ * Added support for PECL Redis extension
123
  * Added `WP_REDIS_CLIENT` constant, to set prefered Redis client
124
  * Added `WP_REDIS_MAXTTL` constant, to force expiration of cache keys
125
  * Improved `add_or_replace()`, `get()`, `set()` and `delete()` methods
148
 
149
  == Upgrade Notice ==
150
 
151
+ = 1.2.3 =
152
+
153
+ This updated includes several UI improvements.
154
+
155
+ = 1.2.2 =
156
+
157
+ This updated includes several bug fixes and improvements.
158
+
159
+ = 1.2.1 =
160
+
161
+ This update includes several improvements and compatibility fixes.
162
+
163
  = 1.1.1 =
164
 
165
+ This update fixes critical bugs with the HHVM extension
166
 
167
  = 1.1 =
168
 
169
+ This update includes bug fixes and adds supports for HHVM/PECL Redis extensions.
170
 
171
  = 1.0.2 =
172
 
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' ) );
@@ -107,12 +109,36 @@ class RedisObjectCache {
107
  }
108
 
109
  public function validate_object_cache_dropin() {
110
- return $this->object_cache_dropin_exists() && method_exists( $GLOBALS[ 'wp_object_cache' ], 'redis_status' );
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
112
 
113
  public function get_redis_client_name() {
 
114
  global $wp_object_cache;
115
- return isset( $wp_object_cache->redis_client ) ? $wp_object_cache->redis_client : null;
 
 
 
 
 
 
 
 
 
 
116
  }
117
 
118
  public function get_redis_scheme() {
@@ -147,16 +173,26 @@ class RedisObjectCache {
147
  return defined( 'WP_REDIS_MAXTTL' ) ? WP_REDIS_MAXTTL : null;
148
  }
149
 
150
- public function get_redis_status() {
151
-
152
- global $wp_object_cache;
153
 
154
  if ( ! $this->object_cache_dropin_exists() ) {
155
- return __( 'Not installed', 'redis-cache' );
 
 
 
 
156
  }
157
 
 
 
 
 
 
 
 
 
158
  if ( $this->validate_object_cache_dropin() ) {
159
- return $wp_object_cache->redis_status() ? __( 'Connected', 'redis-cache' ) : __( 'Not connected', 'redis-cache' );
160
  }
161
 
162
  return __( 'Unknown', 'redis-cache' );
@@ -179,15 +215,13 @@ class RedisObjectCache {
179
  $dropin = get_plugin_data( WP_CONTENT_DIR . '/object-cache.php' );
180
  $plugin = get_plugin_data( plugin_dir_path( __FILE__ ) . '/includes/object-cache.php' );
181
 
182
- // outdated `object-cache.php` notice
183
  if ( version_compare( $dropin[ 'Version' ], $plugin[ 'Version' ], '<' ) ) {
184
- $message = sprintf( __( 'The Redis object cache drop-in is outdated. <a href="%s">Update it now</a>.', 'redis-cache' ), $url );
185
  }
186
 
187
  } else {
188
 
189
- // show foreign `object-cache.php` notice
190
- $message = sprintf( __( 'Another object cache drop-in is already active. To use Redis, <a href="%s">please replace it now</a>.', 'redis-cache' ), $url );
191
 
192
  }
193
 
@@ -335,6 +369,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 PECL Redis Extension and the Predis library for PHP.
6
+ Version: 1.2.3
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' ) );
109
  }
110
 
111
  public function validate_object_cache_dropin() {
112
+
113
+ if ( ! $this->object_cache_dropin_exists() ) {
114
+ return false;
115
+ }
116
+
117
+ $dropin = get_plugin_data( WP_CONTENT_DIR . '/object-cache.php' );
118
+ $plugin = get_plugin_data( plugin_dir_path( __FILE__ ) . '/includes/object-cache.php' );
119
+
120
+ if ( strcmp( $dropin[ 'PluginURI' ], $plugin[ 'PluginURI' ] ) !== 0 ) {
121
+ return false;
122
+ }
123
+
124
+ return true;
125
+
126
  }
127
 
128
  public function get_redis_client_name() {
129
+
130
  global $wp_object_cache;
131
+
132
+ if ( isset( $wp_object_cache->redis_client ) ) {
133
+ return $wp_object_cache->redis_client;
134
+ }
135
+
136
+ if ( defined( 'WP_REDIS_CLIENT' ) ) {
137
+ return WP_REDIS_CLIENT;
138
+ }
139
+
140
+ return null;
141
+
142
  }
143
 
144
  public function get_redis_scheme() {
173
  return defined( 'WP_REDIS_MAXTTL' ) ? WP_REDIS_MAXTTL : null;
174
  }
175
 
176
+ public function get_dropin_status() {
 
 
177
 
178
  if ( ! $this->object_cache_dropin_exists() ) {
179
+ return __( 'Disabled', 'redis-cache' );
180
+ }
181
+
182
+ if ( ! $this->validate_object_cache_dropin() ) {
183
+ return __( 'Unknown', 'redis-cache' );
184
  }
185
 
186
+ return __( 'Enabled', 'redis-cache' );
187
+
188
+ }
189
+
190
+ public function get_redis_status() {
191
+
192
+ global $wp_object_cache;
193
+
194
  if ( $this->validate_object_cache_dropin() ) {
195
+ return $wp_object_cache->redis_status() ? __( 'Connected', 'redis-cache' ) : __( 'Not Connected', 'redis-cache' );
196
  }
197
 
198
  return __( 'Unknown', 'redis-cache' );
215
  $dropin = get_plugin_data( WP_CONTENT_DIR . '/object-cache.php' );
216
  $plugin = get_plugin_data( plugin_dir_path( __FILE__ ) . '/includes/object-cache.php' );
217
 
 
218
  if ( version_compare( $dropin[ 'Version' ], $plugin[ 'Version' ], '<' ) ) {
219
+ $message = sprintf( __( 'The Redis object cache drop-in is outdated. Please <a href="%s">update it now</a>.', 'redis-cache' ), $url );
220
  }
221
 
222
  } else {
223
 
224
+ $message = sprintf( __( 'Another object cache drop-in was found. To use Redis, <a href="%s">please replace it now</a>.', 'redis-cache' ), $url );
 
225
 
226
  }
227
 
369
 
370
  }
371
 
372
+ public function on_deactivation() {
373
+
374
+ global $wp_filesystem;
375
+
376
+ if ( $this->validate_object_cache_dropin() && $this->initialize_filesystem( '', true ) ) {
377
+ $wp_filesystem->delete( WP_CONTENT_DIR . '/object-cache.php' );
378
+ }
379
+
380
+ }
381
+
382
  }
383
 
384
  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();