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

This commit is contained in:
Daniele Alessandri
2010-11-28 19:29:22 +01:00
parent 49e151a3d0
commit 2fc80a5f0d
5 changed files with 431 additions and 102 deletions
+22
View File
@@ -1,3 +1,25 @@
v0.6.2 (2010-xx-xx)
* Minor internal improvements and clean ups.
* New commands available in the Redis v2.2 profile (dev):
- Strings: STRLEN
- Lists : LINSERT, RPUSHX, LPUSHX
- ZSets : ZREVRANGEBYSCORE
- Misc. : PERSIST
* WATCH also accepts a single array parameter with the keys that should be
monitored during a transaction.
* Improved the behaviour of Predis_MultiExecBlock in certain corner cases.
* Improved parameters checking for the SORT command.
* FIX: the STORE parameter for the SORT command didn't work correctly when
using '0' as the target key (ISSUE #13).
* FIX: the methods for UNWATCH and DISCARD do not break anymore method
chaining with Predis\MultiExecBlock.
v0.6.1 (2010-07-11)
* Minor internal improvements and clean ups.
+115 -71
View File
@@ -175,7 +175,7 @@ class Predis_Client {
$newClient = new Predis_Client();
$newClient->setupClient($this->_options);
$newClient->setConnection($this->getConnection($connectionAlias));
$newClient->setConnection($connection);
return $newClient;
}
@@ -235,21 +235,25 @@ class Predis_Client {
return $this->_connection->rawCommand($rawCommandData, $closesConnection);
}
public function pipeline(/* arguments */) {
$argv = func_get_args();
$argc = func_num_args();
private function sharedInitializer($argv, $initializer) {
$argc = count($argv);
if ($argc === 0) {
return $this->initPipeline();
return $this->$initializer();
}
else if ($argc === 1) {
list($arg0) = $argv;
return is_array($arg0) ? $this->initPipeline($arg0) : $this->initPipeline(null, $arg0);
return is_array($arg0) ? $this->$initializer($arg0) : $this->$initializer(null, $arg0);
}
else if ($argc === 2) {
list($arg0, $arg1) = $argv;
return $this->initPipeline($arg0, $arg1);
return $this->$initializer($arg0, $arg1);
}
return $this->$initializer($this, $arguments);
}
public function pipeline(/* arguments */) {
$args = func_get_args();
return $this->sharedInitializer($args, 'initPipeline');
}
public function pipelineSafe($pipelineBlock = null) {
@@ -281,20 +285,8 @@ class Predis_Client {
}
public function multiExec(/* arguments */) {
$argv = func_get_args();
$argc = func_num_args();
if ($argc === 0) {
return $this->initMultiExec();
}
else if ($argc === 1) {
list($arg0) = $argv;
return is_array($arg0) ? $this->initMultiExec($arg0) : $this->initMultiExec(null, $arg0);
}
else if ($argc === 2) {
list($arg0, $arg1) = $argv;
return $this->initMultiExec($arg0, $arg1);
}
$args = func_get_args();
return $this->sharedInitializer($args, 'initMultiExec');
}
private function initMultiExec(Array $options = null, $transBlock = null) {
@@ -475,12 +467,12 @@ abstract class Predis_Command {
public function setArguments(/* arguments */) {
$this->_arguments = $this->filterArguments(func_get_args());
$this->_hash = null;
unset($this->_hash);
}
public function setArgumentsArray(Array $arguments) {
$this->_arguments = $this->filterArguments($arguments);
$this->_hash = null;
unset($this->_hash);
}
public function getArguments() {
@@ -938,45 +930,52 @@ class Predis_MultiExecBlock {
$blockException = null;
$returnValues = array();
try {
if ($block !== null) {
$this->setInsideBlock(true);
if ($block !== null) {
$this->setInsideBlock(true);
try {
$block($this);
$this->setInsideBlock(false);
}
if ($this->_discarded === true) {
return;
catch (Predis_CommunicationException $exception) {
$blockException = $exception;
}
$reply = $this->_redisClient->exec();
if ($reply === null) {
throw new Predis_AbortedMultiExec('The current transaction has been aborted by the server');
catch (Predis_ServerException $exception) {
$blockException = $exception;
}
$execReply = $reply instanceof Iterator ? iterator_to_array($reply) : $reply;
$commands = &$this->_commands;
$sizeofReplies = count($execReply);
if ($sizeofReplies !== count($commands)) {
$this->malformedServerResponse('Unexpected number of responses for a MultiExecBlock');
catch (Exception $exception) {
$blockException = $exception;
if ($this->_initialized === true) {
$this->discard();
}
}
for ($i = 0; $i < $sizeofReplies; $i++) {
$returnValues[] = $commands[$i]->parseResponse($execReply[$i] instanceof Iterator
? iterator_to_array($execReply[$i])
: $execReply[$i]
);
unset($commands[$i]);
}
}
catch (Exception $exception) {
$this->setInsideBlock(false);
$blockException = $exception;
if ($blockException !== null) {
throw $blockException;
}
}
if ($blockException !== null) {
throw $blockException;
if ($this->_initialized === false) {
return;
}
$reply = $this->_redisClient->exec();
if ($reply === null) {
throw new Predis_AbortedMultiExec('The current transaction has been aborted by the server');
}
$execReply = $reply instanceof Iterator ? iterator_to_array($reply) : $reply;
$commands = &$this->_commands;
$sizeofReplies = count($execReply);
if ($sizeofReplies !== count($commands)) {
$this->malformedServerResponse('Unexpected number of responses for a Predis_MultiExecBlock');
}
for ($i = 0; $i < $sizeofReplies; $i++) {
$returnValues[] = $commands[$i]->parseResponse($execReply[$i] instanceof Iterator
? iterator_to_array($execReply[$i])
: $execReply[$i]
);
unset($commands[$i]);
}
return $returnValues;
@@ -1005,8 +1004,7 @@ class Predis_PubSubContext implements Iterator {
public function __destruct() {
if ($this->valid()) {
$this->_redisClient->unsubscribe();
$this->_redisClient->punsubscribe();
$this->closeContext();
}
}
@@ -1824,6 +1822,20 @@ class Predis_RedisServer_vNext extends Predis_RedisServer_v2_0 {
/* transactions */
'watch' => 'Predis_Commands_Watch',
'unwatch' => 'Predis_Commands_Unwatch',
/* commands operating on string values */
'strlen' => 'Predis_Commands_Strlen',
/* commands operating on the key space */
'persist' => 'Predis_Commands_Persist',
/* commands operating on lists */
'rpushx' => 'Predis_Commands_ListPushTailX',
'lpushx' => 'Predis_Commands_ListPushHeadX',
'linsert' => 'Predis_Commands_ListInsert',
/* commands operating on sorted sets */
'zrevrangebyscore' => 'Predis_Commands_ZSetReverseRangeByScore',
));
}
}
@@ -2347,6 +2359,10 @@ class Predis_Commands_Substr extends Predis_MultiBulkCommand {
public function getCommandId() { return 'SUBSTR'; }
}
class Predis_Commands_Strlen extends Predis_MultiBulkCommand {
public function getCommandId() { return 'STRLEN'; }
}
/* commands operating on the key space */
class Predis_Commands_Keys extends Predis_MultiBulkCommand {
public function canBeHashed() { return false; }
@@ -2387,6 +2403,11 @@ class Predis_Commands_ExpireAt extends Predis_MultiBulkCommand {
public function parseResponse($data) { return (bool) $data; }
}
class Predis_Commands_Persist extends Predis_MultiBulkCommand {
public function getCommandId() { return 'PERSIST'; }
public function parseResponse($data) { return (bool) $data; }
}
class Predis_Commands_DatabaseSize extends Predis_MultiBulkCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'DBSIZE'; }
@@ -2401,10 +2422,18 @@ class Predis_Commands_ListPushTail extends Predis_MultiBulkCommand {
public function getCommandId() { return 'RPUSH'; }
}
class Predis_Commands_ListPushTailX extends Predis_MultiBulkCommand {
public function getCommandId() { return 'RPUSHX'; }
}
class Predis_Commands_ListPushHead extends Predis_MultiBulkCommand {
public function getCommandId() { return 'LPUSH'; }
}
class Predis_Commands_ListPushHeadX extends Predis_MultiBulkCommand {
public function getCommandId() { return 'LPUSHX'; }
}
class Predis_Commands_ListLength extends Predis_MultiBulkCommand {
public function getCommandId() { return 'LLEN'; }
}
@@ -2453,6 +2482,10 @@ class Predis_Commands_ListPopLastBlocking extends Predis_MultiBulkCommand {
public function getCommandId() { return 'BRPOP'; }
}
class Predis_Commands_ListInsert extends Predis_MultiBulkCommand {
public function getCommandId() { return 'LINSERT'; }
}
/* commands operating on sets */
class Predis_Commands_SetAdd extends Predis_MultiBulkCommand {
public function getCommandId() { return 'SADD'; }
@@ -2623,6 +2656,10 @@ class Predis_Commands_ZSetRangeByScore extends Predis_Commands_ZSetRange {
}
}
class Predis_Commands_ZSetReverseRangeByScore extends Predis_Commands_ZSetRangeByScore {
public function getCommandId() { return 'ZREVRANGEBYSCORE'; }
}
class Predis_Commands_ZSetCount extends Predis_MultiBulkCommand {
public function getCommandId() { return 'ZCOUNT'; }
}
@@ -2767,16 +2804,15 @@ class Predis_Commands_Sort extends Predis_MultiBulkCommand {
return $arguments;
}
// TODO: add more parameters checks
$query = array($arguments[0]);
$sortParams = $arguments[1];
$sortParams = array_change_key_case($arguments[1], CASE_UPPER);
if (isset($sortParams['by'])) {
if (isset($sortParams['BY'])) {
$query[] = 'BY';
$query[] = $sortParams['by'];
$query[] = $sortParams['BY'];
}
if (isset($sortParams['get'])) {
$getargs = $sortParams['get'];
if (isset($sortParams['GET'])) {
$getargs = $sortParams['GET'];
if (is_array($getargs)) {
foreach ($getargs as $getarg) {
$query[] = 'GET';
@@ -2788,20 +2824,22 @@ class Predis_Commands_Sort extends Predis_MultiBulkCommand {
$query[] = $getargs;
}
}
if (isset($sortParams['limit']) && is_array($sortParams['limit'])) {
if (isset($sortParams['LIMIT']) && is_array($sortParams['LIMIT'])
&& count($sortParams['LIMIT']) == 2) {
$query[] = 'LIMIT';
$query[] = $sortParams['limit'][0];
$query[] = $sortParams['limit'][1];
$query[] = $sortParams['LIMIT'][0];
$query[] = $sortParams['LIMIT'][1];
}
if (isset($sortParams['sort'])) {
$query[] = strtoupper($sortParams['sort']);
if (isset($sortParams['SORT'])) {
$query[] = strtoupper($sortParams['SORT']);
}
if (isset($sortParams['alpha']) && $sortParams['alpha'] == true) {
if (isset($sortParams['ALPHA']) && $sortParams['ALPHA'] == true) {
$query[] = 'ALPHA';
}
if (isset($sortParams['store']) && $sortParams['store'] == true) {
if (isset($sortParams['STORE'])) {
$query[] = 'STORE';
$query[] = $sortParams['store'];
$query[] = $sortParams['STORE'];
}
return $query;
@@ -2853,6 +2891,12 @@ class Predis_Commands_Publish extends Predis_MultiBulkCommand {
class Predis_Commands_Watch extends Predis_MultiBulkCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'WATCH'; }
public function filterArguments(Array $arguments) {
if (isset($arguments[0]) && is_array($arguments[0])) {
return $arguments[0];
}
return $arguments;
}
public function parseResponse($data) { return (bool) $data; }
}
+150 -5
View File
@@ -260,11 +260,15 @@ class PredisClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
function testConnection_WriteCommandAndCloseConnection() {
$cmd = Predis_RedisServerProfile::getDefault()->createCommand('quit');
$connection = new Predis_Connection(RC::getConnectionParameters());
$connection->connect();
$connection = new Predis_Connection(new Predis_ConnectionParameters(
RC::getConnectionArguments() + array('read_write_timeout' => 0.5)
));
$connection->connect();
$this->assertTrue($connection->isConnected());
$connection->writeCommand($cmd);
$connection->disconnect();
$expectedMessage = 'Error while reading line from the server';
$thrownException = null;
try {
@@ -275,7 +279,6 @@ class PredisClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
}
$this->assertType('Predis_CommunicationException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
//$this->assertFalse($connection->isConnected());
}
function testConnection_GetSocketOpensConnection() {
@@ -370,8 +373,8 @@ class PredisClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
function testResponseReader_OptionExceptionOnError() {
$connection = new Predis_Connection(RC::getConnectionParameters());
$responseReader = $connection->getResponseReader();
$connection->rawCommand("SET key 5\r\nvalue\r\n");
$rawCmdUnexpected = "LPUSH key 5\r\nvalue\r\n";
$connection->rawCommand("*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n");
$rawCmdUnexpected = "*3\r\n$5\r\nLPUSH\r\n$3\r\nkey\r\n$5\r\nvalue\r\n";
$responseReader->setHandler(
Predis_Protocol::PREFIX_ERROR,
@@ -499,5 +502,147 @@ class PredisClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals('bar', $replies[3][0]);
$this->assertEquals('piyo', $replies[3][1]);
}
/* Client + MultiExecBlock */
function testMultiExecBlock_Simple() {
$client = RC::getConnection();
$client->flushdb();
$multi = $client->multiExec();
$this->assertType('Predis_MultiExecBlock', $multi);
$this->assertType('Predis_MultiExecBlock', $multi->set('foo', 'bar'));
$this->assertType('Predis_MultiExecBlock', $multi->set('hoge', 'piyo'));
$this->assertType('Predis_MultiExecBlock', $multi->mset(array(
'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
)));
$this->assertType('Predis_MultiExecBlock', $multi->mget(array(
'foo', 'hoge', 'foofoo', 'hogehoge'
)));
$replies = $multi->execute();
$this->assertType('array', $replies);
$this->assertEquals(4, count($replies));
$this->assertEquals(4, count($replies[3]));
$this->assertEquals('barbar', $replies[3][2]);
}
function testMultiExecBlock_FluentInterface() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec()->ping()->set('foo', 'bar')->get('foo')->execute();
$this->assertType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
function testMultiExecBlock_CallableAnonymousBlock() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(p_anon("\$multi", "
\$multi->ping();
\$multi->set('foo', 'bar');
\$multi->get('foo');
"));
$this->assertType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
function testMultiExecBlock_EmptyCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(p_anon("\$multi", ""));
$this->assertEquals(0, count($replies));
}
function testMultiExecBlock_ClientExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$expectedMessage = 'TEST';
$thrownException = null;
try {
$client->multiExec(p_anon("\$multi", "
\$multi->ping();
\$multi->set('foo', 'bar');
throw new Predis_ClientException('$expectedMessage');
"));
}
catch (Predis_ClientException $exception) {
$thrownException = $exception;
}
$this->assertType('Predis_ClientException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
$this->assertFalse($client->exists('foo'));
}
function testMultiExecBlock_ServerExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$client->getResponseReader()->setHandler('-', new Predis_ResponseErrorSilentHandler());
$multi = $client->multiExec();
$multi->set('foo', 'bar');
$multi->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
$multi->set('hoge', 'piyo');
$replies = $multi->execute();
$this->assertType('array', $replies);
$this->assertType('Predis_ResponseError', $replies[1]);
$this->assertTrue($client->exists('foo'));
$this->assertTrue($client->exists('hoge'));
}
function testMultiExecBlock_Discard() {
$client = RC::getConnection();
$client->flushdb();
$multi = $client->multiExec();
$multi->set('foo', 'bar');
$multi->discard();
$multi->set('hoge', 'piyo');
$replies = $multi->execute();
$this->assertEquals(1, count($replies));
$this->assertFalse($client->exists('foo'));
$this->assertTrue($client->exists('hoge'));
}
function testMultiExecBlock_DiscardEmpty() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec()->discard()->execute();
$this->assertEquals(0, count($replies));
}
function testMultiExecBlock_Watch() {
$client1 = RC::getConnection();
$client2 = RC::getConnection(true);
$client1->flushdb();
$thrownException = null;
try {
$multi = $client1->multiExec(array('watch' => 'sentinel'));
$multi->set('sentinel', 'client1');
$multi->get('sentinel');
$client2->set('sentinel', 'client2');
$multi->execute();
}
catch (PredisException $exception) {
$thrownException = $exception;
}
$this->assertType('Predis_AbortedMultiExec', $thrownException);
$this->assertEquals('The current transaction has been aborted by the server', $thrownException->getMessage());
$this->assertEquals('client2', $client1->get('sentinel'));
}
}
?>
+4 -1
View File
@@ -48,7 +48,10 @@ class RC {
return $connection;
}
public static function getConnection() {
public static function getConnection($new = false) {
if ($new == true) {
return self::createConnection();
}
if (self::$_connection === null || !self::$_connection->isConnected()) {
self::$_connection = self::createConnection();
}
+140 -25
View File
@@ -241,6 +241,18 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
"));
}
function testStrlen() {
$this->redis->set('var', 'foobar');
$this->assertEquals(6, $this->redis->strlen('var'));
$this->assertEquals(9, $this->redis->append('var', '___'));
$this->assertEquals(9, $this->redis->strlen('var'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->rpush('metavars', 'foo');
\$test->redis->strlen('metavars');
"));
}
/* commands operating on the key space */
@@ -369,6 +381,20 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
"));
}
function testPushTailX() {
$this->assertEquals(0, $this->redis->rpushx('numbers', 1));
$this->assertEquals(1, $this->redis->rpush('numbers', 2));
$this->assertEquals(2, $this->redis->rpushx('numbers', 3));
$this->assertEquals(2, $this->redis->llen('numbers'));
$this->assertEquals(array(2, 3), $this->redis->lrange('numbers', 0, -1));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->rpushx('foo', 'bar');
"));
}
function testPushHead() {
// NOTE: List push operations return the list length since Redis commit 520b5a3
$this->assertEquals(1, $this->redis->lpush('metavars', 'foo'));
@@ -382,6 +408,20 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
"));
}
function testPushHeadX() {
$this->assertEquals(0, $this->redis->lpushx('numbers', 1));
$this->assertEquals(1, $this->redis->lpush('numbers', 2));
$this->assertEquals(2, $this->redis->lpushx('numbers', 3));
$this->assertEquals(2, $this->redis->llen('numbers'));
$this->assertEquals(array(3, 2), $this->redis->lrange('numbers', 0, -1));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->lpushx('foo', 'bar');
"));
}
function testListLength() {
$this->assertEquals(1, $this->redis->rpush('metavars', 'foo'));
$this->assertEquals(2, $this->redis->rpush('metavars', 'hoge'));
@@ -682,6 +722,22 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals((float)(time() - $start), 2, '', 1);
}
function testListInsert() {
$numbers = RC::pushTailAndReturn($this->redis, 'numbers', RC::getArrayOfNumbers());
$this->assertEquals(11, $this->redis->linsert('numbers', 'before', 0, -2));
$this->assertEquals(12, $this->redis->linsert('numbers', 'after', -2, -1));
$this->assertEquals(array(-2, -1, 0, 1), $this->redis->lrange('numbers', 0, 3));
$this->assertEquals(-1, $this->redis->linsert('numbers', 'after', 100, 200));
$this->assertEquals(-1, $this->redis->linsert('numbers', 'before', 100, 50));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->lset('foo', 0, 0);
"));
}
/* commands operating on sets */
@@ -1161,31 +1217,6 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$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);
@@ -1220,12 +1251,96 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->redis->zrangebyscore('zset', 10, 20, 'withscores')
);
$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->zrangebyscore('foo', 0, 0);
"));
}
function testZsetReverseRangeByScore() {
$zset = RC::zsetAddAndReturn($this->redis, 'zset', RC::getZSetArray());
$this->assertEquals(
array('a'),
$this->redis->zrevrangebyscore('zset', -10, -10)
);
$this->assertEquals(
array('b', 'a'),
$this->redis->zrevrangebyscore('zset', 0, -10)
);
$this->assertEquals(
array('e', 'd'),
$this->redis->zrevrangebyscore('zset', 20, 20)
);
$this->assertEquals(
array('f', 'e', 'd', 'c', 'b'),
$this->redis->zrevrangebyscore('zset', 30, 0)
);
$this->assertEquals(
array(array('e', 20), array('d', 20), array('c', 10)),
$this->redis->zrevrangebyscore('zset', 20, 10, 'withscores')
);
$this->assertEquals(
array(array('e', 20), array('d', 20), array('c', 10)),
$this->redis->zrevrangebyscore('zset', 20, 10, array('withscores' => true))
);
$this->assertEquals(
array('d', 'c'),
$this->redis->zrevrangebyscore('zset', 20, 10, array('limit' => array(1, 2)))
);
$this->assertEquals(
array('d', 'c'),
$this->redis->zrevrangebyscore('zset', 20, 10, array(
'limit' => array('offset' => 1, 'count' => 2)
))
);
$this->assertEquals(
array(array('d', 20), array('c', 10)),
$this->redis->zrevrangebyscore('zset', 20, 10, array(
'limit' => array(1, 2),
'withscores' => true,
))
);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zrevrangebyscore('foo', 0, 0);
"));
}
function testZsetUnionStore() {
$zsetA = RC::zsetAddAndReturn($this->redis, 'zseta', array('a' => 1, 'b' => 2, 'c' => 3));
$zsetB = RC::zsetAddAndReturn($this->redis, 'zsetb', array('b' => 1, 'c' => 2, 'd' => 3));