فهرست منبع

Backported changes from the mainline library to the PHP 5.2 branch (up to commit bd961a7)

Daniele Alessandri 15 سال پیش
والد
کامیت
49e151a3d0
4فایلهای تغییر یافته به همراه107 افزوده شده و 27 حذف شده
  1. 23 12
      CHANGELOG
  2. 1 1
      VERSION
  3. 48 14
      lib/Predis.php
  4. 35 0
      test/RedisCommandsTest.php

+ 23 - 12
CHANGELOG

@@ -1,13 +1,21 @@
-v0.6.1 (2010-xx-xx)
+v0.6.1 (2010-07-11)
+  * Minor internal improvements and clean ups.
+
   * New commands available in the Redis v2.2 profile (dev):
       - Misc.  : WATCH, UNWATCH
 
-  * Minor internal improvements and clean ups.
+  * Optional modifiers for ZRANGE, ZREVRANGE and ZRANGEBYSCORE queries are
+    supported using an associative array passed as the last argument of their
+    respective methods.
 
-  * The constructor of Predis_Client::__construct now accepts also instances
-    of Predis_ConnectionParameters.
+  * The LIMIT modifier for ZRANGEBYSCORE can be specified using either:
+      - an indexed array: array($offset, $count)
+      - an associative array: array('offset' => $offset, 'count' => $count)
 
-  * Predis_MultiExecBlock and Predis_PubSubContext will throw an exception
+  * The method Predis_Client::__construct() now accepts also instances of
+    Predis_ConnectionParameters.
+
+  * Predis_MultiExecBlock and Predis_PubSubContext now throw an exception
     when trying to create their instances using a profile that does not
     support the required Redis commands or when the client is connected to
     a cluster of connections.
@@ -17,14 +25,17 @@ v0.6.1 (2010-xx-xx)
       - support for WATCH and UNWATCH when using the current development
         profile (Redis v2.2) and aborted transactions.
 
-  * New method signature for Predis_Client::multiExec(). Now it is able to
-    accept an array of options for the underlying Predis_MultiExecBlock, but
-    it is still backwards compatible with previous releases of Predis.
+  * New signature for Predis_Client::multiExec() which is now able to accept
+    an array of options for the underlying instance of Predis_MultiExecBlock.
+    Backwards compatibility with previous releases of Predis is ensured.
+
+  * New signature for Predis_Client::pipeline() which is now able to accept
+    an array of options for the underlying instance of Predis_CommandPipeline.
+    Backwards compatibility with previous releases of Predis is ensured.
+    The method Predis_Client::pipelineSafe() is to be considered deprecated.
 
-  * New method signature for Predis_Client::pipeline(). Now it is able to
-    accept an array of options for the underlying Predis_CommandPipeline,
-    but it is still backwards compatible with previous releases of Predis.
-    Predis_Client::pipelineSafe() is to be considered obsolete.
+  * FIX: The WEIGHT modifier for ZUNIONSTORE and ZINTERSTORE was handled
+    incorrectly with more than two weights specified.
 
 v0.6.0 (2010-05-24)
   * Switched to the new multi-bulk request protocol for all of the commands 

+ 1 - 1
VERSION

@@ -1 +1 @@
-0.6.0
+0.6.1

+ 48 - 14
lib/Predis.php

@@ -56,7 +56,7 @@ class Predis_Client {
             throw new Predis_ClientException('Missing connection parameters');
         }
 
-        return new Predis_Client($argc === 1 ? $argv[0] : $argv, $serverProfile);
+        return new Predis_Client($argc === 1 ? $argv[0] : $argv, $options);
     }
 
     private static function filterClientOptions($options) {
@@ -2546,8 +2546,9 @@ class Predis_Commands_ZSetUnionStore extends Predis_MultiBulkCommand {
         $finalizedOpts = array();
         if (isset($opts['WEIGHTS']) && is_array($opts['WEIGHTS'])) {
             $finalizedOpts[] = 'WEIGHTS';
-            $finalizedOpts[] = $opts['WEIGHTS'][0];
-            $finalizedOpts[] = $opts['WEIGHTS'][1];
+            foreach ($opts['WEIGHTS'] as $weight) {
+                $finalizedOpts[] = $weight;
+            }
         }
         if (isset($opts['AGGREGATE'])) {
             $finalizedOpts[] = 'AGGREGATE';
@@ -2562,21 +2563,43 @@ class Predis_Commands_ZSetIntersectionStore extends Predis_Commands_ZSetUnionSto
 }
 
 class Predis_Commands_ZSetRange extends Predis_MultiBulkCommand {
+    private $_withScores = false;
     public function getCommandId() { return 'ZRANGE'; }
-    public function parseResponse($data) {
-        $arguments = $this->getArguments();
+    public function filterArguments(Array $arguments) {
         if (count($arguments) === 4) {
-            if (strtolower($arguments[3]) === 'withscores') {
-                if ($data instanceof Iterator) {
-                    return new Predis_Shared_MultiBulkResponseKVIterator($data);
-                }
-                $result = array();
-                for ($i = 0; $i < count($data); $i++) {
-                    $result[] = array($data[$i], $data[++$i]);
-                }
-                return $result;
+            $lastType = gettype($arguments[3]);
+            if ($lastType === 'string' && strtolower($arguments[3]) === 'withscores') {
+                // used for compatibility with older versions
+                $arguments[3] = array('WITHSCORES' => true);
+                $lastType = 'array';
+            }
+            if ($lastType === 'array') {
+                $options = $this->prepareOptions(array_pop($arguments));
+                return array_merge($arguments, $options);
             }
         }
+        return $arguments;
+    }
+    protected function prepareOptions($options) {
+        $opts = array_change_key_case($options, CASE_UPPER);
+        $finalizedOpts = array();
+        if (isset($opts['WITHSCORES'])) {
+            $finalizedOpts[] = 'WITHSCORES';
+            $this->_withScores = true;
+        }
+        return $finalizedOpts;
+    }
+    public function parseResponse($data) {
+        if ($this->_withScores) {
+            if ($data instanceof Iterator) {
+                return new Predis_Shared_MultiBulkResponseKVIterator($data);
+            }
+            $result = array();
+            for ($i = 0; $i < count($data); $i++) {
+                $result[] = array($data[$i], $data[++$i]);
+            }
+            return $result;
+        }
         return $data;
     }
 }
@@ -2587,6 +2610,17 @@ class Predis_Commands_ZSetReverseRange extends Predis_Commands_ZSetRange {
 
 class Predis_Commands_ZSetRangeByScore extends Predis_Commands_ZSetRange {
     public function getCommandId() { return 'ZRANGEBYSCORE'; }
+    protected function prepareOptions($options) {
+        $opts = array_change_key_case($options, CASE_UPPER);
+        $finalizedOpts = array();
+        if (isset($opts['LIMIT']) && is_array($opts['LIMIT'])) {
+            $limit = array_change_key_case($opts['LIMIT'], CASE_UPPER);
+            $finalizedOpts[] = 'LIMIT';
+            $finalizedOpts[] = isset($limit['OFFSET']) ? $limit['OFFSET'] : $limit[0];
+            $finalizedOpts[] = isset($limit['COUNT']) ? $limit['COUNT'] : $limit[1];
+        }
+        return array_merge($finalizedOpts, parent::prepareOptions($options));
+    }
 }
 
 class Predis_Commands_ZSetCount extends Predis_MultiBulkCommand {

+ 35 - 0
test/RedisCommandsTest.php

@@ -1097,6 +1097,11 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
             $this->redis->zrange('zset', 0, 2, 'withscores')
         );
 
+        $this->assertEquals(
+            array(array('a', -10), array('b', 0), array('c', 10)), 
+            $this->redis->zrange('zset', 0, 2, array('withscores' => true))
+        );
+
         RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
             \$test->redis->set('foo', 'bar');
             \$test->redis->zrange('foo', 0, -1);
@@ -1151,6 +1156,36 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
             $this->redis->zrevrange('zset', 0, 2, 'withscores')
         );
 
+        $this->assertEquals(
+            array(array('f', 30), array('e', 20), array('d', 20)), 
+            $this->redis->zrevrange('zset', 0, 2, array('withscores' => true))
+        );
+
+        $this->assertEquals(
+            array(array('c', 10), array('d', 20), array('e', 20)), 
+            $this->redis->zrangebyscore('zset', 10, 20, array('withscores' => true))
+        );
+
+        $this->assertEquals(
+            array('d', 'e'), 
+            $this->redis->zrangebyscore('zset', 10, 20, array('limit' => array(1, 2)))
+        );
+
+        $this->assertEquals(
+            array('d', 'e'), 
+            $this->redis->zrangebyscore('zset', 10, 20, array(
+                'limit' => array('offset' => 1, 'count' => 2)
+            ))
+        );
+
+        $this->assertEquals(
+            array(array('d', 20), array('e', 20)), 
+            $this->redis->zrangebyscore('zset', 10, 20, array(
+                'limit'      => array(1, 2), 
+                'withscores' => true, 
+            ))
+        );
+
         RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
             \$test->redis->set('foo', 'bar');
             \$test->redis->zrevrange('foo', 0, -1);