Compare commits

..

18 Commits

Author SHA1 Message Date
Daniele Alessandri c546351e1d Backported changes from the mainline library to the PHP 5.2 branch (up to commit 3c33c74) 2010-05-24 19:37:00 +02:00
Daniele Alessandri 6ca4087118 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 0e69438) 2010-05-23 10:04:05 +02:00
Daniele Alessandri 654b11ba6d Backported changes from the mainline library to the PHP 5.2 branch (up to commit c781e91) 2010-05-22 17:26:01 +02:00
Daniele Alessandri cf758f23d4 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 84cb28e) 2010-05-18 20:28:54 +02:00
Daniele Alessandri 7806614041 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 35f7ea2) 2010-05-16 13:05:56 +02:00
Daniele Alessandri 852959cbd1 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 3edcdc5) 2010-01-28 00:00:01 +01:00
Daniele Alessandri 3ebdf16d1c Backported changes from the mainline library to the PHP 5.2 branch (up to commit c81e02b) 2010-01-23 16:51:07 +01:00
Daniele Alessandri 35142cfbcf Backported changes from the mainline library to the PHP 5.2 branch (up to commit 35016ba) 2010-01-09 14:54:20 +01:00
Daniele Alessandri 0f1d4675cf Backported the test suite to PHP 5.2. This was the last blocking point for a full PHP 5.2-compatible release of Predis." 2009-12-31 17:32:24 +01:00
Daniele Alessandri 465bd45147 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 2a06d84) 2009-12-31 15:21:48 +01:00
Daniele Alessandri 3bfe3897a7 Backported changes from the mainline library to the PHP 5.2 branch (up to commit b757afe) 2009-12-27 11:06:30 +01:00
Daniele Alessandri 0f966af8e3 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 6814845) 2009-12-26 19:48:55 +01:00
Daniele Alessandri e3e0475826 Fixed the pipline example in the README. 2009-12-26 19:17:48 +01:00
Daniele Alessandri 767c488d35 Updated README to reflect the differences of the PHP 5.2 version of Predis. 2009-12-26 18:59:14 +01:00
Daniele Alessandri 1205026fb1 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 6e39491) 2009-12-26 18:22:39 +01:00
Daniele Alessandri 9c314c5b5f Backported changes from the mainline library to the PHP 5.2 branch. 2009-12-16 16:12:51 +01:00
Daniele Alessandri d05a62e82c Updated the examples to match the PHP 5.2 version. 2009-12-04 22:10:54 +01:00
Daniele Alessandri 6769e0de56 First drop of Predis backported to PHP 5.2.x. The library seems to work but it is completely untested (the test suite needs to be backported too). 2009-12-04 22:08:08 +01:00
18 changed files with 1878 additions and 3625 deletions
+19 -143
View File
@@ -1,127 +1,3 @@
v0.6.6 (2011-04-01)
* Switched to Redis 2.2 as the default server profile (there are no changes
that would break compatibility with previous releases). Long command names
are no more supported by default but if you need them you can still require
Predis_Compatibility.php to avoid breaking compatibility.
* Added a VERSION constant to Predis\Client.
* Some performance improvements for multibulk replies (parsing them is about
16% faster than the previous version). A few core classes have been heavily
optimized to reduce overhead when creating new instances.
* Predis now uses by default a new protocol reader, more lightweight and
faster than the default handler-based one. Users can revert to the old
protocol reader with the 'reader' client option set to 'composable'.
This client option can also accept custom reader classes implementing the
new Predis\IResponseReader interface.
* Added support for connecting to Redis using UNIX domain sockets (ISSUE #25).
* The "read_write_timeout" connection parameter can now be set to 0 or false
to disable read and write timeouts on connections. The old behaviour of -1
is still intact.
* ZUNIONSTORE and ZINTERSTORE can accept an array to specify a list of the
source keys to be used to populate the destination key.
* MGET, SINTER, SUNION and SDIFF can accept an array to specify the list of
keys. SINTERSTORE, SUNIONSTORE and SDIFFSTORE can also accept an array to
specify the list of source keys.
* SUBSCRIBE and PSUBSCRIBE can accept a list of channels for subscription.
* FIX: some client-side clean-ups for MULTI/EXEC were handled incorrectly in
a couple of corner cases. See also ISSUE #27.
v0.6.5 (2011-02-12)
* FIX: due to an untested internal change introduced in v0.6.4, a wrong
handling of bulk reads of zero-length values was producing protocol
desynchronization errors (ISSUE #20).
v0.6.4 (2011-02-12)
* Various performance improvements (15% ~ 25%) especially when dealing with
long multibulk replies or when using clustered connections.
* Added the "on_retry" option to Predis\MultiExecBlock that can be used to
specify an external callback (or any callable object) that gets invoked
whenever a transaction is aborted by the server.
* Added inline (p)subscribtion via options when initializing an instance of
Predis\PubSubContext.
v0.6.3 (2011-01-01)
* New commands available in the Redis v2.2 profile (dev):
- Strings: SETRANGE, GETRANGE, SETBIT, GETBIT
- Lists : BRPOPLPUSH
* The abstraction for MULTI/EXEC transactions has been dramatically improved
by providing support for check-and-set (CAS) operations when using Redis >=
2.2. Aborted transactions can also be optionally replayed in automatic up
to a user-defined number of times, after which a Predis\AbortedMultiExec
exception is thrown.
v0.6.2 (2010-11-28)
* 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.
* New commands available in the Redis v2.2 profile (dev):
- Misc. : WATCH, UNWATCH
* Optional modifiers for ZRANGE, ZREVRANGE and ZRANGEBYSCORE queries are
supported using an associative array passed as the last argument of their
respective methods.
* The LIMIT modifier for ZRANGEBYSCORE can be specified using either:
- an indexed array: array($offset, $count)
- an associative array: array('offset' => $offset, 'count' => $count)
* 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.
* Various improvements to Predis\MultiExecBlock:
- fixes and more consistent behaviour across various usage cases.
- support for WATCH and UNWATCH when using the current development
profile (Redis v2.2) and aborted transactions.
* 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.
* 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
in the Redis 1.2 and Redis 2.0 profiles. Inline and bulk requests are now
@@ -133,7 +9,7 @@ v0.6.0 (2010-05-24)
to instances of Redis 1.2.x).
* Support for Redis 1.0 is now optional and it is provided by requiring
'Predis_Compatibility.php' before creating an instance of Predis\Client.
'Predis_Compatibility.php' before creating an instance of Predis_Client.
* New commands added to the Redis 2.0 profile since Predis 0.5.1:
- Strings: SETEX, APPEND, SUBSTR
@@ -143,22 +19,22 @@ v0.6.0 (2010-05-24)
- PubSub : PUBLISH, SUBSCRIBE, UNSUBSCRIBE
- Misc. : DISCARD, CONFIG
* Introduced client-level options with the new Predis\ClientOptions class.
Options can be passed to Predis\Client::__construct in its second argument
as an array or an instance of Predis\ClientOptions. For brevity's sake and
compatibility with older versions, the constructor of Predis\Client still
accepts an instance of Predis\RedisServerProfile in its second argument.
* Introduced client-level options with the new Predis_ClientOptions class.
Options can be passed to Predis_Client::__construct in its second argument
as an array or an instance of Predis_ClientOptions. For brevity's sake and
compatibility with older versions, the constructor of Predis_Client still
accepts an instance of Predis_RedisServerProfile in its second argument.
The currently supported client options are:
- profile [default: "2.0" as of Predis 0.6.0]
specifies which server profile to use when connecting to Redis. This
option accepts an instance of Predis\RedisServerProfile or a string
option accepts an instance of Predis_RedisServerProfile or a string
that indicates the target version.
- key_distribution [default: Predis\Distribution\HashRing]
- key_distribution [default: Predis_Distribution_HashRing]
specifies which key distribution strategy to use to distribute keys
among the servers that compose a cluster. This option accepts an
instance of Predis\Distribution\IDistributionStrategy so that users
instance of Predis_Distribution_IDistributionStrategy so that users
can implement their own key distribution strategy. Optionally, the new
Predis\Distribution\KetamaPureRing class also provides a pure-PHP
Predis_Distribution_KetamaPureRing class also provides a pure-PHP
implementation of the same algorithm used by libketama.
- throw_on_error [default: TRUE]
server errors can optionally be handled "silently": instead of throwing
@@ -187,30 +63,30 @@ v0.6.0 (2010-05-24)
lifecycle. Persistent connections can lead to unpredictable or strange
behaviours, so they should be used with extreme care.
* Introduced the Predis\Pipeline\IPipelineExecutor interface. Classes that
implements this interface are used internally by the Predis\CommandPipeline
* Introduced the Predis_Pipeline_IPipelineExecutor interface. Classes that
implements this interface are used internally by the Predis_CommandPipeline
class to change the behaviour of the pipeline when writing/reading commands
from one or multiple servers. Here is the list of the default executors:
- Predis\Pipeline\StandardExecutor
- Predis_Pipeline_StandardExecutor
Exceptions generated by server errors might be thrown depending on the
options passed to the client (see "throw_on_error"). Instead, protocol
or network errors always throw exceptions. This is the default executor
for single and clustered connections and shares the same behaviour of
Predis 0.5.x.
- Predis\Pipeline\SafeExecutor
- Predis_Pipeline_SafeExecutor
Exceptions generated by server, protocol or network errors are not
thrown, instead they are returned in the response array as instances of
ResponseError or CommunicationException.
- Predis\Pipeline\SafeClusterExecutor
This executor shares the same behaviour of Predis\Pipeline\SafeExecutor
- Predis_Pipeline_SafeClusterExecutor
This executor shares the same behaviour of Predis_Pipeline_SafeExecutor
but it is geared towards clustered connections.
* Support for PUBSUB is handled by the new Predis\PubSubContext class, which
* Support for PUBSUB is handled by the new Predis_PubSubContext class, which
could also be used to build a callback dispatcher for PUBSUB scenarios.
* When connected to a cluster of connections, it is now possible to get a
new Predis\Client instance for a single connection of the cluster by
passing its alias/index to the new Predis\Client::getClientFor() method.
new Predis_Client instance for a single connection of the cluster by
passing its alias/index to the new Predis_Client::getClientFor() method.
* CommandPipeline and MultiExecBlock return their instances when invoking
commands, thus allowing method chaining in pipelines and multi-exec blocks.
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2009-2011 Daniele Alessandri
Copyright (c) 2009-2010 Daniele Alessandri
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
+19 -21
View File
@@ -17,12 +17,10 @@ to be implemented soon in Predis.
## Main features ##
- Full support for Redis 2.0 and 2.2. Different versions of Redis are supported via server profiles.
- Full support for Redis 2.0. Different versions of Redis are supported via server profiles.
- Client-side sharding (support for consistent hashing and custom distribution strategies).
- Command pipelining on single and multiple connections (transparent).
- Abstraction for Redis transactions (>= 2.0) with support for CAS operations (>= 2.2).
- Lazy connections (connections to Redis instances are only established just in time).
- Ability to connect to Redis using TCP/IP or UNIX domain sockets.
- Flexible system to define and register your own set of commands to a client instance.
@@ -36,7 +34,7 @@ complete coverage of all the features available in Predis.
You don't have to specify a tcp host and port when connecting to Redis instances
running on the localhost on the default port:
$redis = new Predis\Client();
$redis = new Predis_Client();
$redis->set('library', 'predis');
$value = $redis->get('library');
@@ -46,13 +44,13 @@ running on the localhost on the default port:
Pipelining helps with performances when there is the need to issue many commands
to a server in one go:
$redis = new Predis\Client('redis://10.0.0.1:6379/');
$replies = $redis->pipeline(function($pipe) {
$pipe->ping();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->get('counter');
});
$redis = new Predis_Client('redis://10.0.0.1:6379/');
$pipe = $redis->pipeline();
$pipe->ping();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->get('counter');
$replies = $pipe->execute();
### Pipelining multiple commands to multiple instances of Redis (sharding) ##
@@ -62,17 +60,17 @@ Furthermore, a pipeline can be initialized on a cluster of redis instances in th
same exact way they are created on single connection. Sharding is still transparent
to the user:
$redis = new Predis\Client(array(
$redis = Predis_Client::create(
array('host' => '10.0.0.1', 'port' => 6379),
array('host' => '10.0.0.2', 'port' => 6379)
));
);
$replies = $redis->pipeline(function($pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", str_pad($i, 4, '0', 0));
$pipe->get("key:$i");
}
});
$pipe = $redis->pipeline();
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", str_pad($i, 4, '0', 0));
$pipe->get("key:$i");
}
$replies = $pipe->flushPipeline();
### Definition and runtime registration of new commands on the client ###
@@ -84,11 +82,11 @@ its way into a stable Predis release, then you can start off by creating a new
class that matches the command type and its behaviour and then bind it to a
client instance at runtime. Actually, it is easier done than said:
class BrandNewRedisCommand extends \Predis\MultiBulkCommand {
class BrandNewRedisCommand extends Predis_MultiBulkCommand {
public function getCommandId() { return 'NEWCMD'; }
}
$redis = new Predis\Client();
$redis = new Predis_Client();
$redis->getProfile()->registerCommand('BrandNewRedisCommand', 'newcmd');
$redis->newcmd();
+1 -1
View File
@@ -1 +1 @@
0.6.6
0.6.0
+10 -10
View File
@@ -4,17 +4,17 @@ require_once 'SharedConfigurations.php';
// When you have a whole set of consecutive commands to send to
// a redis server, you can use a pipeline to improve performances.
$redis = new Predis\Client($single_server);
$redis = new Predis_Client($single_server);
$replies = $redis->pipeline(function($pipe) {
$pipe->ping();
$pipe->flushdb();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->exists('counter');
$pipe->get('counter');
$pipe->mget('does_not_exist', 'counter');
});
$pipe = $redis->pipeline();
$pipe->ping();
$pipe->flushdb();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->exists('counter');
$pipe->get('counter');
$pipe->mget('does_not_exist', 'counter');
$replies = $pipe->execute();
print_r($replies);
+14 -6
View File
@@ -3,10 +3,10 @@ require_once 'SharedConfigurations.php';
// Developers can customize the distribution strategy used by the client
// to distribute keys among a cluster of servers simply by creating a class
// that implements the Predis\Distribution\IDistributionStrategy interface.
// that implements the Predis_Distribution_IDistributionAlgorithm interface.
class NaiveDistributionStrategy
implements Predis\Distribution\IDistributionStrategy {
implements Predis_Distribution_IDistributionStrategy {
private $_nodes, $_nodesCount;
@@ -20,10 +20,18 @@ class NaiveDistributionStrategy
$this->_nodesCount++;
}
private static function array_remove($array, $value) {
$newArray = array();
foreach ($array as $k => $v) {
if ($v !== $value) {
$newArray[] = $v;
}
}
return $newArray;
}
public function remove($node) {
$this->_nodes = array_filter($this->_nodes, function($n) use($node) {
return $n !== $node;
});
$this->_nodes = self::array_remove($this->_nodes, $node);
$this->_nodesCount = count($this->_nodes);
}
@@ -44,7 +52,7 @@ $options = array(
'key_distribution' => new NaiveDistributionStrategy(),
);
$redis = new Predis\Client($multiple_servers, $options);
$redis = new Predis_Client($multiple_servers, $options);
for ($i = 0; $i < 100; $i++) {
$redis->set("key:$i", str_pad($i, 4, '0', 0));
-41
View File
@@ -1,41 +0,0 @@
<?php
require_once 'SharedConfigurations.php';
/*
This is an implementation of an atomic client-side ZPOP using the support for
check-and-set (CAS) operations with MULTI/EXEC transactions, as described in
"WATCH explained" from http://redis.io/topics/transactions
First, populate your database with a tiny sample data set:
./redis-cli
SELECT 15
ZADD zset 1 a
ZADD zset 2 b
ZADD zset 3 c
*/
function zpop($client, $zsetKey) {
$element = null;
$options = array(
'cas' => true, // Initialize with support for CAS operations
'watch' => $zsetKey, // Key that needs to be WATCHed to detect changes
'retry' => 3, // Number of retries on aborted transactions, after
// which the client bails out with an exception.
);
$txReply = $client->multiExec($options, function($tx)
use ($zsetKey, &$element) {
@list($element) = $tx->zrange($zsetKey, 0, 0);
if (isset($element)) {
$tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
$tx->zrem($zsetKey, $element);
}
});
return $element;
}
$redis = new Predis\Client($single_server, 'dev');
$zpopped = zpop($redis, 'zset');
echo isset($zpopped) ? "ZPOPed $zpopped" : "Nothing to ZPOP!", "\n";
?>
+1 -1
View File
@@ -11,7 +11,7 @@ $mkv = array(
'usr:0003' => 'Third user'
);
$redis = new Predis\Client($single_server);
$redis = new Predis_Client($single_server);
$redis->mset($mkv);
$retval = $redis->mget(array_keys($mkv));
+1 -1
View File
@@ -5,7 +5,7 @@ require_once 'SharedConfigurations.php';
// events published on certain channels (PUBSUB).
// Create a client and disable r/w timeout on the socket
$redis = new Predis\Client($single_server + array('read_write_timeout' => 0));
$redis = new Predis_Client($single_server + array('read_write_timeout' => -1));
// Initialize a new pubsub context
$pubsub = $redis->pubSubContext();
+1 -1
View File
@@ -3,7 +3,7 @@ require_once 'SharedConfigurations.php';
// simple set and get scenario
$redis = new Predis\Client($single_server);
$redis = new Predis_Client($single_server);
$redis->set('library', 'predis');
$retval = $redis->get('library');
+844 -1601
View File
File diff suppressed because it is too large Load Diff
+164 -406
View File
@@ -1,382 +1,140 @@
<?php
namespace Predis;
Predis_RedisServerProfile::registerProfile('Predis_RedisServer_v1_0', '1.0');
RedisServerProfile::registerProfile('\Predis\RedisServer_v1_0', '1.0');
RedisServerProfile::registerProfile('\Predis\RedisServer_v1_2_LongNames', '1.2');
RedisServerProfile::registerProfile('\Predis\RedisServer_v2_0_LongNames', '2.0');
class RedisServer_v1_0 extends \Predis\RedisServerProfile {
class Predis_RedisServer_v1_0 extends Predis_RedisServerProfile {
public function getVersion() { return '1.0'; }
public function getSupportedCommands() {
return array(
/* miscellaneous commands */
'ping' => '\Predis\Compatibility\v1_0\Commands\Ping',
'echo' => '\Predis\Compatibility\v1_0\Commands\DoEcho',
'auth' => '\Predis\Compatibility\v1_0\Commands\Auth',
'ping' => 'Predis_Compatibility_v1_0_Commands_Ping',
'echo' => 'Predis_Compatibility_v1_0_Commands_DoEcho',
'auth' => 'Predis_Compatibility_v1_0_Commands_Auth',
/* connection handling */
'quit' => '\Predis\Compatibility\v1_0\Commands\Quit',
'quit' => 'Predis_Compatibility_v1_0_Commands_Quit',
/* commands operating on string values */
'set' => '\Predis\Compatibility\v1_0\Commands\Set',
'setnx' => '\Predis\Compatibility\v1_0\Commands\SetPreserve',
'setPreserve' => '\Predis\Compatibility\v1_0\Commands\SetPreserve',
'get' => '\Predis\Compatibility\v1_0\Commands\Get',
'mget' => '\Predis\Compatibility\v1_0\Commands\GetMultiple',
'getMultiple' => '\Predis\Compatibility\v1_0\Commands\GetMultiple',
'getset' => '\Predis\Compatibility\v1_0\Commands\GetSet',
'getSet' => '\Predis\Compatibility\v1_0\Commands\GetSet',
'incr' => '\Predis\Compatibility\v1_0\Commands\Increment',
'increment' => '\Predis\Compatibility\v1_0\Commands\Increment',
'incrby' => '\Predis\Compatibility\v1_0\Commands\IncrementBy',
'incrementBy' => '\Predis\Compatibility\v1_0\Commands\IncrementBy',
'decr' => '\Predis\Compatibility\v1_0\Commands\Decrement',
'decrement' => '\Predis\Compatibility\v1_0\Commands\Decrement',
'decrby' => '\Predis\Compatibility\v1_0\Commands\DecrementBy',
'decrementBy' => '\Predis\Compatibility\v1_0\Commands\DecrementBy',
'exists' => '\Predis\Compatibility\v1_0\Commands\Exists',
'del' => '\Predis\Compatibility\v1_0\Commands\Delete',
'delete' => '\Predis\Compatibility\v1_0\Commands\Delete',
'type' => '\Predis\Compatibility\v1_0\Commands\Type',
'set' => 'Predis_Compatibility_v1_0_Commands_Set',
'setnx' => 'Predis_Compatibility_v1_0_Commands_SetPreserve',
'setPreserve' => 'Predis_Compatibility_v1_0_Commands_SetPreserve',
'get' => 'Predis_Compatibility_v1_0_Commands_Get',
'mget' => 'Predis_Compatibility_v1_0_Commands_GetMultiple',
'getMultiple' => 'Predis_Compatibility_v1_0_Commands_GetMultiple',
'getset' => 'Predis_Compatibility_v1_0_Commands_GetSet',
'getSet' => 'Predis_Compatibility_v1_0_Commands_GetSet',
'incr' => 'Predis_Compatibility_v1_0_Commands_Increment',
'increment' => 'Predis_Compatibility_v1_0_Commands_Increment',
'incrby' => 'Predis_Compatibility_v1_0_Commands_IncrementBy',
'incrementBy' => 'Predis_Compatibility_v1_0_Commands_IncrementBy',
'decr' => 'Predis_Compatibility_v1_0_Commands_Decrement',
'decrement' => 'Predis_Compatibility_v1_0_Commands_Decrement',
'decrby' => 'Predis_Compatibility_v1_0_Commands_DecrementBy',
'decrementBy' => 'Predis_Compatibility_v1_0_Commands_DecrementBy',
'exists' => 'Predis_Compatibility_v1_0_Commands_Exists',
'del' => 'Predis_Compatibility_v1_0_Commands_Delete',
'delete' => 'Predis_Compatibility_v1_0_Commands_Delete',
'type' => 'Predis_Compatibility_v1_0_Commands_Type',
/* commands operating on the key space */
'keys' => '\Predis\Compatibility\v1_0\Commands\Keys',
'randomkey' => '\Predis\Compatibility\v1_0\Commands\RandomKey',
'randomKey' => '\Predis\Compatibility\v1_0\Commands\RandomKey',
'rename' => '\Predis\Compatibility\v1_0\Commands\Rename',
'renamenx' => '\Predis\Compatibility\v1_0\Commands\RenamePreserve',
'renamePreserve' => '\Predis\Compatibility\v1_0\Commands\RenamePreserve',
'expire' => '\Predis\Compatibility\v1_0\Commands\Expire',
'expireat' => '\Predis\Compatibility\v1_0\Commands\ExpireAt',
'expireAt' => '\Predis\Compatibility\v1_0\Commands\ExpireAt',
'dbsize' => '\Predis\Compatibility\v1_0\Commands\DatabaseSize',
'databaseSize' => '\Predis\Compatibility\v1_0\Commands\DatabaseSize',
'ttl' => '\Predis\Compatibility\v1_0\Commands\TimeToLive',
'timeToLive' => '\Predis\Compatibility\v1_0\Commands\TimeToLive',
'keys' => 'Predis_Compatibility_v1_0_Commands_Keys',
'randomkey' => 'Predis_Compatibility_v1_0_Commands_RandomKey',
'randomKey' => 'Predis_Compatibility_v1_0_Commands_RandomKey',
'rename' => 'Predis_Compatibility_v1_0_Commands_Rename',
'renamenx' => 'Predis_Compatibility_v1_0_Commands_RenamePreserve',
'renamePreserve' => 'Predis_Compatibility_v1_0_Commands_RenamePreserve',
'expire' => 'Predis_Compatibility_v1_0_Commands_Expire',
'expireat' => 'Predis_Compatibility_v1_0_Commands_ExpireAt',
'expireAt' => 'Predis_Compatibility_v1_0_Commands_ExpireAt',
'dbsize' => 'Predis_Compatibility_v1_0_Commands_DatabaseSize',
'databaseSize' => 'Predis_Compatibility_v1_0_Commands_DatabaseSize',
'ttl' => 'Predis_Compatibility_v1_0_Commands_TimeToLive',
'timeToLive' => 'Predis_Compatibility_v1_0_Commands_TimeToLive',
/* commands operating on lists */
'rpush' => '\Predis\Compatibility\v1_0\Commands\ListPushTail',
'pushTail' => '\Predis\Compatibility\v1_0\Commands\ListPushTail',
'lpush' => '\Predis\Compatibility\v1_0\Commands\ListPushHead',
'pushHead' => '\Predis\Compatibility\v1_0\Commands\ListPushHead',
'llen' => '\Predis\Compatibility\v1_0\Commands\ListLength',
'listLength' => '\Predis\Compatibility\v1_0\Commands\ListLength',
'lrange' => '\Predis\Compatibility\v1_0\Commands\ListRange',
'listRange' => '\Predis\Compatibility\v1_0\Commands\ListRange',
'ltrim' => '\Predis\Compatibility\v1_0\Commands\ListTrim',
'listTrim' => '\Predis\Compatibility\v1_0\Commands\ListTrim',
'lindex' => '\Predis\Compatibility\v1_0\Commands\ListIndex',
'listIndex' => '\Predis\Compatibility\v1_0\Commands\ListIndex',
'lset' => '\Predis\Compatibility\v1_0\Commands\ListSet',
'listSet' => '\Predis\Compatibility\v1_0\Commands\ListSet',
'lrem' => '\Predis\Compatibility\v1_0\Commands\ListRemove',
'listRemove' => '\Predis\Compatibility\v1_0\Commands\ListRemove',
'lpop' => '\Predis\Compatibility\v1_0\Commands\ListPopFirst',
'popFirst' => '\Predis\Compatibility\v1_0\Commands\ListPopFirst',
'rpop' => '\Predis\Compatibility\v1_0\Commands\ListPopLast',
'popLast' => '\Predis\Compatibility\v1_0\Commands\ListPopLast',
'rpush' => 'Predis_Compatibility_v1_0_Commands_ListPushTail',
'pushTail' => 'Predis_Compatibility_v1_0_Commands_ListPushTail',
'lpush' => 'Predis_Compatibility_v1_0_Commands_ListPushHead',
'pushHead' => 'Predis_Compatibility_v1_0_Commands_ListPushHead',
'llen' => 'Predis_Compatibility_v1_0_Commands_ListLength',
'listLength' => 'Predis_Compatibility_v1_0_Commands_ListLength',
'lrange' => 'Predis_Compatibility_v1_0_Commands_ListRange',
'listRange' => 'Predis_Compatibility_v1_0_Commands_ListRange',
'ltrim' => 'Predis_Compatibility_v1_0_Commands_ListTrim',
'listTrim' => 'Predis_Compatibility_v1_0_Commands_ListTrim',
'lindex' => 'Predis_Compatibility_v1_0_Commands_ListIndex',
'listIndex' => 'Predis_Compatibility_v1_0_Commands_ListIndex',
'lset' => 'Predis_Compatibility_v1_0_Commands_ListSet',
'listSet' => 'Predis_Compatibility_v1_0_Commands_ListSet',
'lrem' => 'Predis_Compatibility_v1_0_Commands_ListRemove',
'listRemove' => 'Predis_Compatibility_v1_0_Commands_ListRemove',
'lpop' => 'Predis_Compatibility_v1_0_Commands_ListPopFirst',
'popFirst' => 'Predis_Compatibility_v1_0_Commands_ListPopFirst',
'rpop' => 'Predis_Compatibility_v1_0_Commands_ListPopLast',
'popLast' => 'Predis_Compatibility_v1_0_Commands_ListPopLast',
/* commands operating on sets */
'sadd' => '\Predis\Compatibility\v1_0\Commands\SetAdd',
'setAdd' => '\Predis\Compatibility\v1_0\Commands\SetAdd',
'srem' => '\Predis\Compatibility\v1_0\Commands\SetRemove',
'setRemove' => '\Predis\Compatibility\v1_0\Commands\SetRemove',
'spop' => '\Predis\Compatibility\v1_0\Commands\SetPop',
'setPop' => '\Predis\Compatibility\v1_0\Commands\SetPop',
'smove' => '\Predis\Compatibility\v1_0\Commands\SetMove',
'setMove' => '\Predis\Compatibility\v1_0\Commands\SetMove',
'scard' => '\Predis\Compatibility\v1_0\Commands\SetCardinality',
'setCardinality' => '\Predis\Compatibility\v1_0\Commands\SetCardinality',
'sismember' => '\Predis\Compatibility\v1_0\Commands\SetIsMember',
'setIsMember' => '\Predis\Compatibility\v1_0\Commands\SetIsMember',
'sinter' => '\Predis\Compatibility\v1_0\Commands\SetIntersection',
'setIntersection' => '\Predis\Compatibility\v1_0\Commands\SetIntersection',
'sinterstore' => '\Predis\Compatibility\v1_0\Commands\SetIntersectionStore',
'setIntersectionStore' => '\Predis\Compatibility\v1_0\Commands\SetIntersectionStore',
'sunion' => '\Predis\Compatibility\v1_0\Commands\SetUnion',
'setUnion' => '\Predis\Compatibility\v1_0\Commands\SetUnion',
'sunionstore' => '\Predis\Compatibility\v1_0\Commands\SetUnionStore',
'setUnionStore' => '\Predis\Compatibility\v1_0\Commands\SetUnionStore',
'sdiff' => '\Predis\Compatibility\v1_0\Commands\SetDifference',
'setDifference' => '\Predis\Compatibility\v1_0\Commands\SetDifference',
'sdiffstore' => '\Predis\Compatibility\v1_0\Commands\SetDifferenceStore',
'setDifferenceStore' => '\Predis\Compatibility\v1_0\Commands\SetDifferenceStore',
'smembers' => '\Predis\Compatibility\v1_0\Commands\SetMembers',
'setMembers' => '\Predis\Compatibility\v1_0\Commands\SetMembers',
'srandmember' => '\Predis\Compatibility\v1_0\Commands\SetRandomMember',
'setRandomMember' => '\Predis\Compatibility\v1_0\Commands\SetRandomMember',
'sadd' => 'Predis_Compatibility_v1_0_Commands_SetAdd',
'setAdd' => 'Predis_Compatibility_v1_0_Commands_SetAdd',
'srem' => 'Predis_Compatibility_v1_0_Commands_SetRemove',
'setRemove' => 'Predis_Compatibility_v1_0_Commands_SetRemove',
'spop' => 'Predis_Compatibility_v1_0_Commands_SetPop',
'setPop' => 'Predis_Compatibility_v1_0_Commands_SetPop',
'smove' => 'Predis_Compatibility_v1_0_Commands_SetMove',
'setMove' => 'Predis_Compatibility_v1_0_Commands_SetMove',
'scard' => 'Predis_Compatibility_v1_0_Commands_SetCardinality',
'setCardinality' => 'Predis_Compatibility_v1_0_Commands_SetCardinality',
'sismember' => 'Predis_Compatibility_v1_0_Commands_SetIsMember',
'setIsMember' => 'Predis_Compatibility_v1_0_Commands_SetIsMember',
'sinter' => 'Predis_Compatibility_v1_0_Commands_SetIntersection',
'setIntersection' => 'Predis_Compatibility_v1_0_Commands_SetIntersection',
'sinterstore' => 'Predis_Compatibility_v1_0_Commands_SetIntersectionStore',
'setIntersectionStore' => 'Predis_Compatibility_v1_0_Commands_SetIntersectionStore',
'sunion' => 'Predis_Compatibility_v1_0_Commands_SetUnion',
'setUnion' => 'Predis_Compatibility_v1_0_Commands_SetUnion',
'sunionstore' => 'Predis_Compatibility_v1_0_Commands_SetUnionStore',
'setUnionStore' => 'Predis_Compatibility_v1_0_Commands_SetUnionStore',
'sdiff' => 'Predis_Compatibility_v1_0_Commands_SetDifference',
'setDifference' => 'Predis_Compatibility_v1_0_Commands_SetDifference',
'sdiffstore' => 'Predis_Compatibility_v1_0_Commands_SetDifferenceStore',
'setDifferenceStore' => 'Predis_Compatibility_v1_0_Commands_SetDifferenceStore',
'smembers' => 'Predis_Compatibility_v1_0_Commands_SetMembers',
'setMembers' => 'Predis_Compatibility_v1_0_Commands_SetMembers',
'srandmember' => 'Predis_Compatibility_v1_0_Commands_SetRandomMember',
'setRandomMember' => 'Predis_Compatibility_v1_0_Commands_SetRandomMember',
/* multiple databases handling commands */
'select' => '\Predis\Compatibility\v1_0\Commands\SelectDatabase',
'selectDatabase' => '\Predis\Compatibility\v1_0\Commands\SelectDatabase',
'move' => '\Predis\Compatibility\v1_0\Commands\MoveKey',
'moveKey' => '\Predis\Compatibility\v1_0\Commands\MoveKey',
'flushdb' => '\Predis\Compatibility\v1_0\Commands\FlushDatabase',
'flushDatabase' => '\Predis\Compatibility\v1_0\Commands\FlushDatabase',
'flushall' => '\Predis\Compatibility\v1_0\Commands\FlushAll',
'flushDatabases' => '\Predis\Compatibility\v1_0\Commands\FlushAll',
'select' => 'Predis_Compatibility_v1_0_Commands_SelectDatabase',
'selectDatabase' => 'Predis_Compatibility_v1_0_Commands_SelectDatabase',
'move' => 'Predis_Compatibility_v1_0_Commands_MoveKey',
'moveKey' => 'Predis_Compatibility_v1_0_Commands_MoveKey',
'flushdb' => 'Predis_Compatibility_v1_0_Commands_FlushDatabase',
'flushDatabase' => 'Predis_Compatibility_v1_0_Commands_FlushDatabase',
'flushall' => 'Predis_Compatibility_v1_0_Commands_FlushAll',
'flushDatabases' => 'Predis_Compatibility_v1_0_Commands_FlushAll',
/* sorting */
'sort' => '\Predis\Compatibility\v1_0\Commands\Sort',
'sort' => 'Predis_Compatibility_v1_0_Commands_Sort',
/* remote server control commands */
'info' => '\Predis\Compatibility\v1_0\Commands\Info',
'slaveof' => '\Predis\Compatibility\v1_0\Commands\SlaveOf',
'slaveOf' => '\Predis\Compatibility\v1_0\Commands\SlaveOf',
'info' => 'Predis_Compatibility_v1_0_Commands_Info',
'slaveof' => 'Predis_Compatibility_v1_0_Commands_SlaveOf',
'slaveOf' => 'Predis_Compatibility_v1_0_Commands_SlaveOf',
/* persistence control commands */
'save' => '\Predis\Compatibility\v1_0\Commands\Save',
'bgsave' => '\Predis\Compatibility\v1_0\Commands\BackgroundSave',
'backgroundSave' => '\Predis\Compatibility\v1_0\Commands\BackgroundSave',
'lastsave' => '\Predis\Compatibility\v1_0\Commands\LastSave',
'lastSave' => '\Predis\Compatibility\v1_0\Commands\LastSave',
'shutdown' => '\Predis\Compatibility\v1_0\Commands\Shutdown',
'save' => 'Predis_Compatibility_v1_0_Commands_Save',
'bgsave' => 'Predis_Compatibility_v1_0_Commands_BackgroundSave',
'backgroundSave' => 'Predis_Compatibility_v1_0_Commands_BackgroundSave',
'lastsave' => 'Predis_Compatibility_v1_0_Commands_LastSave',
'lastSave' => 'Predis_Compatibility_v1_0_Commands_LastSave',
'shutdown' => 'Predis_Compatibility_v1_0_Commands_Shutdown',
);
}
}
class RedisServer_v1_2_LongNames extends \Predis\RedisServerProfile {
public function getVersion() { return '1.2'; }
public function getSupportedCommands() {
return array(
/* miscellaneous commands */
'ping' => '\Predis\Commands\Ping',
'echo' => '\Predis\Commands\DoEcho',
'auth' => '\Predis\Commands\Auth',
/* connection handling */
'quit' => '\Predis\Commands\Quit',
/* commands operating on string values */
'set' => '\Predis\Commands\Set',
'setnx' => '\Predis\Commands\SetPreserve',
'setPreserve' => '\Predis\Commands\SetPreserve',
'mset' => '\Predis\Commands\SetMultiple',
'setMultiple' => '\Predis\Commands\SetMultiple',
'msetnx' => '\Predis\Commands\SetMultiplePreserve',
'setMultiplePreserve' => '\Predis\Commands\SetMultiplePreserve',
'get' => '\Predis\Commands\Get',
'mget' => '\Predis\Commands\GetMultiple',
'getMultiple' => '\Predis\Commands\GetMultiple',
'getset' => '\Predis\Commands\GetSet',
'getSet' => '\Predis\Commands\GetSet',
'incr' => '\Predis\Commands\Increment',
'increment' => '\Predis\Commands\Increment',
'incrby' => '\Predis\Commands\IncrementBy',
'incrementBy' => '\Predis\Commands\IncrementBy',
'decr' => '\Predis\Commands\Decrement',
'decrement' => '\Predis\Commands\Decrement',
'decrby' => '\Predis\Commands\DecrementBy',
'decrementBy' => '\Predis\Commands\DecrementBy',
'exists' => '\Predis\Commands\Exists',
'del' => '\Predis\Commands\Delete',
'delete' => '\Predis\Commands\Delete',
'type' => '\Predis\Commands\Type',
/* commands operating on the key space */
'keys' => '\Predis\Commands\Keys_v1_2',
'randomkey' => '\Predis\Commands\RandomKey',
'randomKey' => '\Predis\Commands\RandomKey',
'rename' => '\Predis\Commands\Rename',
'renamenx' => '\Predis\Commands\RenamePreserve',
'renamePreserve' => '\Predis\Commands\RenamePreserve',
'expire' => '\Predis\Commands\Expire',
'expireat' => '\Predis\Commands\ExpireAt',
'expireAt' => '\Predis\Commands\ExpireAt',
'dbsize' => '\Predis\Commands\DatabaseSize',
'databaseSize' => '\Predis\Commands\DatabaseSize',
'ttl' => '\Predis\Commands\TimeToLive',
'timeToLive' => '\Predis\Commands\TimeToLive',
/* commands operating on lists */
'rpush' => '\Predis\Commands\ListPushTail',
'pushTail' => '\Predis\Commands\ListPushTail',
'lpush' => '\Predis\Commands\ListPushHead',
'pushHead' => '\Predis\Commands\ListPushHead',
'llen' => '\Predis\Commands\ListLength',
'listLength' => '\Predis\Commands\ListLength',
'lrange' => '\Predis\Commands\ListRange',
'listRange' => '\Predis\Commands\ListRange',
'ltrim' => '\Predis\Commands\ListTrim',
'listTrim' => '\Predis\Commands\ListTrim',
'lindex' => '\Predis\Commands\ListIndex',
'listIndex' => '\Predis\Commands\ListIndex',
'lset' => '\Predis\Commands\ListSet',
'listSet' => '\Predis\Commands\ListSet',
'lrem' => '\Predis\Commands\ListRemove',
'listRemove' => '\Predis\Commands\ListRemove',
'lpop' => '\Predis\Commands\ListPopFirst',
'popFirst' => '\Predis\Commands\ListPopFirst',
'rpop' => '\Predis\Commands\ListPopLast',
'popLast' => '\Predis\Commands\ListPopLast',
'rpoplpush' => '\Predis\Commands\ListPopLastPushHead',
'listPopLastPushHead' => '\Predis\Commands\ListPopLastPushHead',
/* commands operating on sets */
'sadd' => '\Predis\Commands\SetAdd',
'setAdd' => '\Predis\Commands\SetAdd',
'srem' => '\Predis\Commands\SetRemove',
'setRemove' => '\Predis\Commands\SetRemove',
'spop' => '\Predis\Commands\SetPop',
'setPop' => '\Predis\Commands\SetPop',
'smove' => '\Predis\Commands\SetMove',
'setMove' => '\Predis\Commands\SetMove',
'scard' => '\Predis\Commands\SetCardinality',
'setCardinality' => '\Predis\Commands\SetCardinality',
'sismember' => '\Predis\Commands\SetIsMember',
'setIsMember' => '\Predis\Commands\SetIsMember',
'sinter' => '\Predis\Commands\SetIntersection',
'setIntersection' => '\Predis\Commands\SetIntersection',
'sinterstore' => '\Predis\Commands\SetIntersectionStore',
'setIntersectionStore' => '\Predis\Commands\SetIntersectionStore',
'sunion' => '\Predis\Commands\SetUnion',
'setUnion' => '\Predis\Commands\SetUnion',
'sunionstore' => '\Predis\Commands\SetUnionStore',
'setUnionStore' => '\Predis\Commands\SetUnionStore',
'sdiff' => '\Predis\Commands\SetDifference',
'setDifference' => '\Predis\Commands\SetDifference',
'sdiffstore' => '\Predis\Commands\SetDifferenceStore',
'setDifferenceStore' => '\Predis\Commands\SetDifferenceStore',
'smembers' => '\Predis\Commands\SetMembers',
'setMembers' => '\Predis\Commands\SetMembers',
'srandmember' => '\Predis\Commands\SetRandomMember',
'setRandomMember' => '\Predis\Commands\SetRandomMember',
/* commands operating on sorted sets */
'zadd' => '\Predis\Commands\ZSetAdd',
'zsetAdd' => '\Predis\Commands\ZSetAdd',
'zincrby' => '\Predis\Commands\ZSetIncrementBy',
'zsetIncrementBy' => '\Predis\Commands\ZSetIncrementBy',
'zrem' => '\Predis\Commands\ZSetRemove',
'zsetRemove' => '\Predis\Commands\ZSetRemove',
'zrange' => '\Predis\Commands\ZSetRange',
'zsetRange' => '\Predis\Commands\ZSetRange',
'zrevrange' => '\Predis\Commands\ZSetReverseRange',
'zsetReverseRange' => '\Predis\Commands\ZSetReverseRange',
'zrangebyscore' => '\Predis\Commands\ZSetRangeByScore',
'zsetRangeByScore' => '\Predis\Commands\ZSetRangeByScore',
'zcard' => '\Predis\Commands\ZSetCardinality',
'zsetCardinality' => '\Predis\Commands\ZSetCardinality',
'zscore' => '\Predis\Commands\ZSetScore',
'zsetScore' => '\Predis\Commands\ZSetScore',
'zremrangebyscore' => '\Predis\Commands\ZSetRemoveRangeByScore',
'zsetRemoveRangeByScore' => '\Predis\Commands\ZSetRemoveRangeByScore',
/* multiple databases handling commands */
'select' => '\Predis\Commands\SelectDatabase',
'selectDatabase' => '\Predis\Commands\SelectDatabase',
'move' => '\Predis\Commands\MoveKey',
'moveKey' => '\Predis\Commands\MoveKey',
'flushdb' => '\Predis\Commands\FlushDatabase',
'flushDatabase' => '\Predis\Commands\FlushDatabase',
'flushall' => '\Predis\Commands\FlushAll',
'flushDatabases' => '\Predis\Commands\FlushAll',
/* sorting */
'sort' => '\Predis\Commands\Sort',
/* remote server control commands */
'info' => '\Predis\Commands\Info',
'slaveof' => '\Predis\Commands\SlaveOf',
'slaveOf' => '\Predis\Commands\SlaveOf',
/* persistence control commands */
'save' => '\Predis\Commands\Save',
'bgsave' => '\Predis\Commands\BackgroundSave',
'backgroundSave' => '\Predis\Commands\BackgroundSave',
'lastsave' => '\Predis\Commands\LastSave',
'lastSave' => '\Predis\Commands\LastSave',
'shutdown' => '\Predis\Commands\Shutdown',
'bgrewriteaof' => '\Predis\Commands\BackgroundRewriteAppendOnlyFile',
'backgroundRewriteAppendOnlyFile' => '\Predis\Commands\BackgroundRewriteAppendOnlyFile',
);
}
}
class RedisServer_v2_0_LongNames extends RedisServer_v1_2_LongNames {
public function getVersion() { return '2.0'; }
public function getSupportedCommands() {
return array_merge(parent::getSupportedCommands(), array(
/* transactions */
'multi' => '\Predis\Commands\Multi',
'exec' => '\Predis\Commands\Exec',
'discard' => '\Predis\Commands\Discard',
/* commands operating on string values */
'setex' => '\Predis\Commands\SetExpire',
'setExpire' => '\Predis\Commands\SetExpire',
'append' => '\Predis\Commands\Append',
'substr' => '\Predis\Commands\Substr',
/* commands operating on the key space */
'keys' => '\Predis\Commands\Keys',
/* commands operating on lists */
'blpop' => '\Predis\Commands\ListPopFirstBlocking',
'popFirstBlocking' => '\Predis\Commands\ListPopFirstBlocking',
'brpop' => '\Predis\Commands\ListPopLastBlocking',
'popLastBlocking' => '\Predis\Commands\ListPopLastBlocking',
/* commands operating on sorted sets */
'zunionstore' => '\Predis\Commands\ZSetUnionStore',
'zsetUnionStore' => '\Predis\Commands\ZSetUnionStore',
'zinterstore' => '\Predis\Commands\ZSetIntersectionStore',
'zsetIntersectionStore' => '\Predis\Commands\ZSetIntersectionStore',
'zcount' => '\Predis\Commands\ZSetCount',
'zsetCount' => '\Predis\Commands\ZSetCount',
'zrank' => '\Predis\Commands\ZSetRank',
'zsetRank' => '\Predis\Commands\ZSetRank',
'zrevrank' => '\Predis\Commands\ZSetReverseRank',
'zsetReverseRank' => '\Predis\Commands\ZSetReverseRank',
'zremrangebyrank' => '\Predis\Commands\ZSetRemoveRangeByRank',
'zsetRemoveRangeByRank' => '\Predis\Commands\ZSetRemoveRangeByRank',
/* commands operating on hashes */
'hset' => '\Predis\Commands\HashSet',
'hashSet' => '\Predis\Commands\HashSet',
'hsetnx' => '\Predis\Commands\HashSetPreserve',
'hashSetPreserve' => '\Predis\Commands\HashSetPreserve',
'hmset' => '\Predis\Commands\HashSetMultiple',
'hashSetMultiple' => '\Predis\Commands\HashSetMultiple',
'hincrby' => '\Predis\Commands\HashIncrementBy',
'hashIncrementBy' => '\Predis\Commands\HashIncrementBy',
'hget' => '\Predis\Commands\HashGet',
'hashGet' => '\Predis\Commands\HashGet',
'hmget' => '\Predis\Commands\HashGetMultiple',
'hashGetMultiple' => '\Predis\Commands\HashGetMultiple',
'hdel' => '\Predis\Commands\HashDelete',
'hashDelete' => '\Predis\Commands\HashDelete',
'hexists' => '\Predis\Commands\HashExists',
'hashExists' => '\Predis\Commands\HashExists',
'hlen' => '\Predis\Commands\HashLength',
'hashLength' => '\Predis\Commands\HashLength',
'hkeys' => '\Predis\Commands\HashKeys',
'hashKeys' => '\Predis\Commands\HashKeys',
'hvals' => '\Predis\Commands\HashValues',
'hashValues' => '\Predis\Commands\HashValues',
'hgetall' => '\Predis\Commands\HashGetAll',
'hashGetAll' => '\Predis\Commands\HashGetAll',
/* publish - subscribe */
'subscribe' => '\Predis\Commands\Subscribe',
'unsubscribe' => '\Predis\Commands\Unsubscribe',
'psubscribe' => '\Predis\Commands\SubscribeByPattern',
'punsubscribe' => '\Predis\Commands\UnsubscribeByPattern',
'publish' => '\Predis\Commands\Publish',
/* remote server control commands */
'config' => '\Predis\Commands\Config',
'configuration' => '\Predis\Commands\Config',
));
}
}
/* ------------------------------------------------------------------------- */
namespace Predis\Compatibility\v1_0\Commands;
/* miscellaneous commands */
class Ping extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Ping extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'PING'; }
public function parseResponse($data) {
@@ -384,77 +142,77 @@ class Ping extends \Predis\InlineCommand {
}
}
class DoEcho extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_DoEcho extends Predis_BulkCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'ECHO'; }
}
class Auth extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Auth extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'AUTH'; }
}
/* connection handling */
class Quit extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Quit extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'QUIT'; }
public function closesConnection() { return true; }
}
/* commands operating on string values */
class Set extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_Set extends Predis_BulkCommand {
public function getCommandId() { return 'SET'; }
}
class SetPreserve extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_SetPreserve extends Predis_BulkCommand {
public function getCommandId() { return 'SETNX'; }
public function parseResponse($data) { return (bool) $data; }
}
class Get extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Get extends Predis_InlineCommand {
public function getCommandId() { return 'GET'; }
}
class GetMultiple extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_GetMultiple extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'MGET'; }
}
class GetSet extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_GetSet extends Predis_BulkCommand {
public function getCommandId() { return 'GETSET'; }
}
class Increment extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Increment extends Predis_InlineCommand {
public function getCommandId() { return 'INCR'; }
}
class IncrementBy extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_IncrementBy extends Predis_InlineCommand {
public function getCommandId() { return 'INCRBY'; }
}
class Decrement extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Decrement extends Predis_InlineCommand {
public function getCommandId() { return 'DECR'; }
}
class DecrementBy extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_DecrementBy extends Predis_InlineCommand {
public function getCommandId() { return 'DECRBY'; }
}
class Exists extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Exists extends Predis_InlineCommand {
public function getCommandId() { return 'EXISTS'; }
public function parseResponse($data) { return (bool) $data; }
}
class Delete extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Delete extends Predis_InlineCommand {
public function getCommandId() { return 'DEL'; }
}
class Type extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Type extends Predis_InlineCommand {
public function getCommandId() { return 'TYPE'; }
}
/* commands operating on the key space */
class Keys extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Keys extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'KEYS'; }
public function parseResponse($data) {
@@ -462,169 +220,169 @@ class Keys extends \Predis\InlineCommand {
}
}
class RandomKey extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_RandomKey extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'RANDOMKEY'; }
public function parseResponse($data) { return $data !== '' ? $data : null; }
}
class Rename extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Rename extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'RENAME'; }
}
class RenamePreserve extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_RenamePreserve extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'RENAMENX'; }
public function parseResponse($data) { return (bool) $data; }
}
class Expire extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Expire extends Predis_InlineCommand {
public function getCommandId() { return 'EXPIRE'; }
public function parseResponse($data) { return (bool) $data; }
}
class ExpireAt extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_ExpireAt extends Predis_InlineCommand {
public function getCommandId() { return 'EXPIREAT'; }
public function parseResponse($data) { return (bool) $data; }
}
class DatabaseSize extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_DatabaseSize extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'DBSIZE'; }
}
class TimeToLive extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_TimeToLive extends Predis_InlineCommand {
public function getCommandId() { return 'TTL'; }
}
/* commands operating on lists */
class ListPushTail extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_ListPushTail extends Predis_BulkCommand {
public function getCommandId() { return 'RPUSH'; }
}
class ListPushHead extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_ListPushHead extends Predis_BulkCommand {
public function getCommandId() { return 'LPUSH'; }
}
class ListLength extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_ListLength extends Predis_InlineCommand {
public function getCommandId() { return 'LLEN'; }
}
class ListRange extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_ListRange extends Predis_InlineCommand {
public function getCommandId() { return 'LRANGE'; }
}
class ListTrim extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_ListTrim extends Predis_InlineCommand {
public function getCommandId() { return 'LTRIM'; }
}
class ListIndex extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_ListIndex extends Predis_InlineCommand {
public function getCommandId() { return 'LINDEX'; }
}
class ListSet extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_ListSet extends Predis_BulkCommand {
public function getCommandId() { return 'LSET'; }
}
class ListRemove extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_ListRemove extends Predis_BulkCommand {
public function getCommandId() { return 'LREM'; }
}
class ListPopFirst extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_ListPopFirst extends Predis_InlineCommand {
public function getCommandId() { return 'LPOP'; }
}
class ListPopLast extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_ListPopLast extends Predis_InlineCommand {
public function getCommandId() { return 'RPOP'; }
}
/* commands operating on sets */
class SetAdd extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_SetAdd extends Predis_BulkCommand {
public function getCommandId() { return 'SADD'; }
public function parseResponse($data) { return (bool) $data; }
}
class SetRemove extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_SetRemove extends Predis_BulkCommand {
public function getCommandId() { return 'SREM'; }
public function parseResponse($data) { return (bool) $data; }
}
class SetPop extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetPop extends Predis_InlineCommand {
public function getCommandId() { return 'SPOP'; }
}
class SetMove extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_SetMove extends Predis_BulkCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'SMOVE'; }
public function parseResponse($data) { return (bool) $data; }
}
class SetCardinality extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetCardinality extends Predis_InlineCommand {
public function getCommandId() { return 'SCARD'; }
}
class SetIsMember extends \Predis\BulkCommand {
class Predis_Compatibility_v1_0_Commands_SetIsMember extends Predis_BulkCommand {
public function getCommandId() { return 'SISMEMBER'; }
public function parseResponse($data) { return (bool) $data; }
}
class SetIntersection extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetIntersection extends Predis_InlineCommand {
public function getCommandId() { return 'SINTER'; }
}
class SetIntersectionStore extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetIntersectionStore extends Predis_InlineCommand {
public function getCommandId() { return 'SINTERSTORE'; }
}
class SetUnion extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetUnion extends Predis_InlineCommand {
public function getCommandId() { return 'SUNION'; }
}
class SetUnionStore extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetUnionStore extends Predis_InlineCommand {
public function getCommandId() { return 'SUNIONSTORE'; }
}
class SetDifference extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetDifference extends Predis_InlineCommand {
public function getCommandId() { return 'SDIFF'; }
}
class SetDifferenceStore extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetDifferenceStore extends Predis_InlineCommand {
public function getCommandId() { return 'SDIFFSTORE'; }
}
class SetMembers extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetMembers extends Predis_InlineCommand {
public function getCommandId() { return 'SMEMBERS'; }
}
class SetRandomMember extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SetRandomMember extends Predis_InlineCommand {
public function getCommandId() { return 'SRANDMEMBER'; }
}
/* multiple databases handling commands */
class SelectDatabase extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SelectDatabase extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'SELECT'; }
}
class MoveKey extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_MoveKey extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'MOVE'; }
public function parseResponse($data) { return (bool) $data; }
}
class FlushDatabase extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_FlushDatabase extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'FLUSHDB'; }
}
class FlushAll extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_FlushAll extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'FLUSHALL'; }
}
/* sorting */
class Sort extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Sort extends Predis_InlineCommand {
public function getCommandId() { return 'SORT'; }
public function filterArguments(Array $arguments) {
if (count($arguments) === 1) {
@@ -673,12 +431,12 @@ class Sort extends \Predis\InlineCommand {
}
/* persistence control commands */
class Save extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Save extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'SAVE'; }
}
class BackgroundSave extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_BackgroundSave extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'BGSAVE'; }
public function parseResponse($data) {
@@ -689,19 +447,19 @@ class BackgroundSave extends \Predis\InlineCommand {
}
}
class LastSave extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_LastSave extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'LASTSAVE'; }
}
class Shutdown extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Shutdown extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'SHUTDOWN'; }
public function closesConnection() { return true; }
}
/* remote server control commands */
class Info extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_Info extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'INFO'; }
public function parseResponse($data) {
@@ -725,7 +483,7 @@ class Info extends \Predis\InlineCommand {
}
}
class SlaveOf extends \Predis\InlineCommand {
class Predis_Compatibility_v1_0_Commands_SlaveOf extends Predis_InlineCommand {
public function canBeHashed() { return false; }
public function getCommandId() { return 'SLAVEOF'; }
public function filterArguments(Array $arguments) {
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="test/bootstrap.php">
<testsuites>
<testsuite name="Predis Test Suite">
<directory>test/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">lib/Predis/</directory>
</whitelist>
</filter>
</phpunit>
-743
View File
@@ -1,743 +0,0 @@
<?php
class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
public $redis;
protected function setUp() {
$this->redis = RC::getConnection();
$this->redis->flushdb();
}
protected function tearDown() {
}
protected function onNotSuccessfulTest(Exception $exception) {
// drops and reconnect to a redis server on uncaught exceptions
RC::resetConnection();
parent::onNotSuccessfulTest($exception);
}
/* ConnectionParameters */
function testConnectionParametersDefaultValues() {
$params = new \Predis\ConnectionParameters();
$this->assertEquals(\Predis\ConnectionParameters::DEFAULT_HOST, $params->host);
$this->assertEquals(\Predis\ConnectionParameters::DEFAULT_PORT, $params->port);
$this->assertEquals(\Predis\ConnectionParameters::DEFAULT_TIMEOUT, $params->connection_timeout);
$this->assertNull($params->read_write_timeout);
$this->assertNull($params->database);
$this->assertNull($params->password);
$this->assertNull($params->alias);
}
function testConnectionParametersSetupValuesArray() {
$paramsArray = RC::getConnectionParametersArgumentsArray();
$params = new \Predis\ConnectionParameters($paramsArray);
$this->assertEquals($paramsArray['host'], $params->host);
$this->assertEquals($paramsArray['port'], $params->port);
$this->assertEquals($paramsArray['connection_timeout'], $params->connection_timeout);
$this->assertEquals($paramsArray['read_write_timeout'], $params->read_write_timeout);
$this->assertEquals($paramsArray['database'], $params->database);
$this->assertEquals($paramsArray['password'], $params->password);
$this->assertEquals($paramsArray['alias'], $params->alias);
}
function testConnectionParametersSetupValuesString() {
$paramsArray = RC::getConnectionParametersArgumentsArray();
$paramsString = RC::getConnectionParametersArgumentsString($paramsArray);
$params = new \Predis\ConnectionParameters($paramsArray);
$this->assertEquals($paramsArray['host'], $params->host);
$this->assertEquals($paramsArray['port'], $params->port);
$this->assertEquals($paramsArray['connection_timeout'], $params->connection_timeout);
$this->assertEquals($paramsArray['read_write_timeout'], $params->read_write_timeout);
$this->assertEquals($paramsArray['database'], $params->database);
$this->assertEquals($paramsArray['password'], $params->password);
$this->assertEquals($paramsArray['alias'], $params->alias);
}
/* Command and derivates */
function testCommand_TestArguments() {
$cmdArgs = array('key1', 'key2', 'key3');
$cmd = new \Predis\Commands\GetMultiple();
$cmd->setArgumentsArray($cmdArgs);
$this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
$this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
$this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
$cmd = new \Predis\Commands\GetMultiple();
$cmd->setArguments('key1', 'key2', 'key3');
$this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
$this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
$this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
$cmd = new \Predis\Commands\Ping();
$this->assertNull($cmd->getArgument(0));
}
function testCommand_InlineWithNoArguments() {
$cmd = new \Predis\Compatibility\v1_0\Commands\Ping();
$this->assertInstanceOf('\Predis\InlineCommand', $cmd);
$this->assertEquals('PING', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertFalse($cmd->canBeHashed());
$this->assertNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("PING\r\n", $cmd());
}
function testCommand_InlineWithArguments() {
$cmd = new \Predis\Compatibility\v1_0\Commands\Get();
$cmd->setArgumentsArray(array('key'));
$this->assertInstanceOf('\Predis\InlineCommand', $cmd);
$this->assertEquals('GET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertTrue($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("GET key\r\n", $cmd());
}
function testCommand_BulkWithArguments() {
$cmd = new \Predis\Compatibility\v1_0\Commands\Set();
$cmd->setArgumentsArray(array('key', 'value'));
$this->assertInstanceOf('\Predis\BulkCommand', $cmd);
$this->assertEquals('SET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertTrue($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("SET key 5\r\nvalue\r\n", $cmd());
}
function testCommand_MultiBulkWithArguments() {
$cmd = new \Predis\Commands\SetMultiple();
$cmd->setArgumentsArray(array('key1', 'value1', 'key2', 'value2'));
$this->assertInstanceOf('\Predis\MultiBulkCommand', $cmd);
$this->assertEquals('MSET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertFalse($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("*5\r\n$4\r\nMSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n", $cmd());
}
function testCommand_ParseResponse() {
// default parser
$cmd = new \Predis\Commands\Get();
$this->assertEquals('test', $cmd->parseResponse('test'));
// overridden parser (boolean)
$cmd = new \Predis\Commands\Exists();
$this->assertTrue($cmd->parseResponse('1'));
$this->assertFalse($cmd->parseResponse('0'));
// overridden parser (boolean)
$cmd = new \Predis\Commands\Ping();
$this->assertTrue($cmd->parseResponse('PONG'));
// overridden parser (complex)
// TODO: emulate a respons to INFO
}
/* RedisServerProfile and derivates */
function testRedisServerProfile_GetSpecificVersions() {
$this->assertInstanceOf('\Predis\RedisServer_v1_0', \Predis\RedisServerProfile::get('1.0'));
$this->assertInstanceOf('\Predis\RedisServer_v1_2', \Predis\RedisServerProfile::get('1.2'));
$this->assertInstanceOf('\Predis\RedisServer_v2_0', \Predis\RedisServerProfile::get('2.0'));
$this->assertInstanceOf('\Predis\RedisServer_vNext', \Predis\RedisServerProfile::get('dev'));
$this->assertInstanceOf('\Predis\RedisServerProfile', \Predis\RedisServerProfile::get('default'));
$this->assertEquals(\Predis\RedisServerProfile::get('default'), \Predis\RedisServerProfile::getDefault());
}
function testRedisServerProfile_SupportedCommands() {
$profile_10 = \Predis\RedisServerProfile::get('1.0');
$profile_12 = \Predis\RedisServerProfile::get('1.2');
$this->assertTrue($profile_10->supportsCommand('info'));
$this->assertTrue($profile_12->supportsCommand('info'));
$this->assertFalse($profile_10->supportsCommand('mset'));
$this->assertTrue($profile_12->supportsCommand('mset'));
$this->assertFalse($profile_10->supportsCommand('multi'));
$this->assertFalse($profile_12->supportsCommand('multi'));
}
function testRedisServerProfile_CommandsCreation() {
$profile = \Predis\RedisServerProfile::get('1.0');
$cmdNoArgs = $profile->createCommand('info');
$this->assertInstanceOf('\Predis\Compatibility\v1_0\Commands\Info', $cmdNoArgs);
$this->assertNull($cmdNoArgs->getArgument());
$args = array('key1', 'key2');
$cmdWithArgs = $profile->createCommand('mget', $args);
$this->assertInstanceOf('\Predis\Compatibility\v1_0\Commands\GetMultiple', $cmdWithArgs);
$this->assertEquals($args[0], $cmdWithArgs->getArgument()); // TODO: why?
$this->assertEquals($args[0], $cmdWithArgs->getArgument(0));
$this->assertEquals($args[1], $cmdWithArgs->getArgument(1));
$bogusCommand = 'not_existing_command';
$expectedMessage = "'$bogusCommand' is not a registered Redis command";
RC::testForClientException($this, $expectedMessage, function()
use($profile, $bogusCommand) {
$profile->createCommand($bogusCommand);
});
}
function testRedisServerProfile_CommandsRegistration() {
$profile = \Predis\RedisServerProfile::get('1.0');
$cmdId = 'mset';
$cmdClass = '\Predis\Commands\SetMultiple';
$this->assertFalse($profile->supportsCommand($cmdId));
$profile->registerCommand(new $cmdClass(), $cmdId);
$this->assertTrue($profile->supportsCommand($cmdId));
$this->assertInstanceOf($cmdClass, $profile->createCommand($cmdId));
}
/* ResponseQueued */
function testResponseQueued() {
$response = new \Predis\ResponseQueued();
$this->assertTrue($response->skipParse);
$this->assertTrue($response->queued);
$this->assertEquals(\Predis\Protocol::QUEUED, (string)$response);
}
/* ResponseError */
function testResponseError() {
$errorMessage = 'ERROR MESSAGE';
$response = new \Predis\ResponseError($errorMessage);
$this->assertTrue($response->skipParse);
$this->assertTrue($response->error);
$this->assertEquals($errorMessage, $response->message);
$this->assertEquals($errorMessage, (string)$response);
}
/* Connection */
function testConnection_StringCastReturnsIPAndPort() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$this->assertEquals(RC::SERVER_HOST . ':' . RC::SERVER_PORT, (string) $connection);
}
function testConnection_ConnectDisconnect() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$connection->connect();
$this->assertTrue($connection->isConnected());
$connection->disconnect();
$this->assertFalse($connection->isConnected());
}
function testConnection_WriteAndReadCommand() {
$cmd = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection->connect();
$connection->writeCommand($cmd);
$this->assertTrue($connection->readResponse($cmd));
}
function testConnection_WriteCommandAndCloseConnection() {
$cmd = \Predis\RedisServerProfile::getDefault()->createCommand('quit');
$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();
$exceptionMessage = 'Error while reading line from the server';
RC::testForCommunicationException($this, $exceptionMessage, function() use($connection, $cmd) {
$connection->readResponse($cmd);
});
}
function testConnection_GetSocketOpensConnection() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$this->assertInternalType('resource', $connection->getSocket());
$this->assertTrue($connection->isConnected());
}
function testConnection_LazyConnect() {
$cmd = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
$connection = new \Predis\Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$connection->writeCommand($cmd);
$this->assertTrue($connection->isConnected());
$this->assertTrue($connection->readResponse($cmd));
}
function testConnection_RawCommand() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$this->assertEquals('PONG', $connection->rawCommand("PING\r\n"));
}
function testConnection_Alias() {
$connection1 = new \Predis\Connection(RC::getConnectionParameters());
$this->assertNull($connection1->getParameters()->alias);
$args = array_merge(RC::getConnectionArguments(), array('alias' => 'servername'));
$connection2 = new \Predis\Connection(new \Predis\ConnectionParameters($args));
$this->assertEquals('servername', $connection2->getParameters()->alias);
}
function testConnection_ConnectionTimeout() {
$timeout = 3;
$args = array('host' => '1.0.0.1', 'connection_timeout' => $timeout);
$connection = new \Predis\Connection(new \Predis\ConnectionParameters($args));
$start = time();
RC::testForCommunicationException($this, null, function() use($connection) {
$connection->connect();
});
$this->assertEquals((float)(time() - $start), $timeout, '', 1);
}
function testConnection_ReadTimeout() {
$timeout = 1;
$args = array_merge(RC::getConnectionArguments(), array('read_write_timeout' => $timeout));
$cmdFake = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
$connection = new \Predis\Connection(new \Predis\ConnectionParameters($args));
$expectedMessage = 'Error while reading line from the server';
$start = time();
RC::testForCommunicationException($this, $expectedMessage, function() use($connection, $cmdFake) {
$connection->readResponse($cmdFake);
});
$this->assertEquals((float)(time() - $start), $timeout, '', 1);
}
/* ResponseReader */
function testResponseReader_OptionIterableMultiBulkReplies() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection->getResponseReader()->setOption('iterable_multibulk', false);
$this->assertInternalType('array', $connection->rawCommand("KEYS *\r\n"));
$connection->getResponseReader()->setOption('iterable_multibulk', true);
$this->assertInstanceOf('\Iterator', $connection->rawCommand("KEYS *\r\n"));
}
function testResponseReader_OptionExceptionOnError() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$responseReader = $connection->getResponseReader();
$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->setOption('throw_on_error', false);
$errorReply = $connection->rawCommand($rawCmdUnexpected);
$this->assertInstanceOf('\Predis\ResponseError', $errorReply);
$this->assertEquals(RC::EXCEPTION_WRONG_TYPE, $errorReply->message);
$responseReader->setOption('throw_on_error', true);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function()
use ($connection, $rawCmdUnexpected) {
$connection->rawCommand($rawCmdUnexpected);
});
}
function testResponseReader_EmptyBulkResponse() {
$this->assertTrue($this->redis->set('foo', ''));
$this->assertEquals('', $this->redis->get('foo'));
$this->assertEquals('', $this->redis->get('foo'));
}
/* Client + CommandPipeline */
function testCommandPipeline_Simple() {
$client = RC::getConnection();
$client->flushdb();
$pipe = $client->pipeline();
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe);
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->set('foo', 'bar'));
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->set('hoge', 'piyo'));
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->mset(array(
'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
)));
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->mget(array(
'foo', 'hoge', 'foofoo', 'hogehoge'
)));
$replies = $pipe->execute();
$this->assertInternalType('array', $replies);
$this->assertEquals(4, count($replies));
$this->assertEquals(4, count($replies[3]));
$this->assertEquals('barbar', $replies[3][2]);
}
function testCommandPipeline_FluentInterface() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->pipeline()->ping()->set('foo', 'bar')->get('foo')->execute();
$this->assertInternalType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
function testCommandPipeline_CallableAnonymousBlock() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->pipeline(function($pipe) {
$pipe->ping();
$pipe->set('foo', 'bar');
$pipe->get('foo');
});
$this->assertInternalType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
function testCommandPipeline_ClientExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
RC::testForClientException($this, 'TEST', function() use($client) {
$client->pipeline(function($pipe) {
$pipe->ping();
$pipe->set('foo', 'bar');
throw new \Predis\ClientException("TEST");
});
});
$this->assertFalse($client->exists('foo'));
}
function testCommandPipeline_ServerExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$client->getResponseReader()->setOption('throw_on_error', false);
$replies = $client->pipeline(function($pipe) {
$pipe->set('foo', 'bar');
$pipe->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
$pipe->set('hoge', 'piyo');
});
$this->assertInternalType('array', $replies);
$this->assertInstanceOf('\Predis\ResponseError', $replies[1]);
$this->assertTrue($client->exists('foo'));
$this->assertTrue($client->exists('hoge'));
}
function testCommandPipeline_Flush() {
$client = RC::getConnection();
$client->flushdb();
$pipe = $client->pipeline();
$pipe->set('foo', 'bar')->set('hoge', 'piyo');
$pipe->flushPipeline();
$pipe->ping()->mget(array('foo', 'hoge'));
$replies = $pipe->execute();
$this->assertInternalType('array', $replies);
$this->assertEquals(4, count($replies));
$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->assertInstanceOf('\Predis\MultiExecBlock', $multi);
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->set('foo', 'bar'));
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->set('hoge', 'piyo'));
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->mset(array(
'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
)));
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->mget(array(
'foo', 'hoge', 'foofoo', 'hogehoge'
)));
$replies = $multi->execute();
$this->assertInternalType('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->assertInternalType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
function testMultiExecBlock_CallableAnonymousBlock() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(function($multi) {
$multi->ping();
$multi->set('foo', 'bar');
$multi->get('foo');
});
$this->assertInternalType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
/**
* @expectedException Predis\ClientException
*/
function testMultiExecBlock_CannotMixFluentInterfaceAndAnonymousBlock() {
$emptyBlock = function($tx) { };
$tx = RC::getConnection()->multiExec()->get('foo')->execute($emptyBlock);
}
function testMultiExecBlock_EmptyCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(function($multi) { });
$this->assertEquals(0, count($replies));
$options = array('cas' => true);
$replies = $client->multiExec($options, function($multi) { });
$this->assertEquals(0, count($replies));
$options = array('cas' => true);
$replies = $client->multiExec($options, function($multi) {
$multi->multi();
});
$this->assertEquals(0, count($replies));
}
function testMultiExecBlock_ClientExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
RC::testForClientException($this, 'TEST', function() use($client) {
$client->multiExec(function($multi) {
$multi->ping();
$multi->set('foo', 'bar');
throw new \Predis\ClientException("TEST");
});
});
$this->assertFalse($client->exists('foo'));
}
function testMultiExecBlock_ServerExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$client->getResponseReader()->setOption('throw_on_error', false);
$replies = $client->multiExec(function($multi) {
$multi->set('foo', 'bar');
$multi->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
$multi->set('hoge', 'piyo');
});
$this->assertInternalType('array', $replies);
$this->assertInstanceOf('\Predis\ResponseError', $replies[1]);
$this->assertTrue($client->exists('foo'));
$this->assertTrue($client->exists('hoge'));
}
function testMultiExecBlock_Discard() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(function($multi) {
$multi->set('foo', 'bar');
$multi->discard();
$multi->set('hoge', 'piyo');
});
$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(function($multi) {
$multi->discard();
});
$this->assertEquals(0, count($replies));
}
function testMultiExecBlock_Watch() {
$client1 = RC::getConnection();
$client2 = RC::getConnection(true);
$client1->flushdb();
RC::testForAbortedMultiExecException($this, function()
use($client1, $client2) {
$client1->multiExec(array('watch' => 'sentinel'), function($multi)
use ($client2) {
$multi->set('sentinel', 'client1');
$multi->get('sentinel');
$client2->set('sentinel', 'client2');
});
});
$this->assertEquals('client2', $client1->get('sentinel'));
}
function testMultiExecBlock_CheckAndSet() {
$client = RC::getConnection();
$client->flushdb();
$client->set('foo', 'bar');
$options = array('watch' => 'foo', 'cas' => true);
$replies = $client->multiExec($options, function($tx) {
$tx->watch('foobar');
$foo = $tx->get('foo');
$tx->multi();
$tx->set('foobar', $foo);
$tx->mget('foo', 'foobar');
});
$this->assertInternalType('array', $replies);
$this->assertEquals(array(true, array('bar', 'bar')), $replies);
$tx = $client->multiExec($options);
$tx->watch('foobar');
$foo = $tx->get('foo');
$replies = $tx->multi()
->set('foobar', $foo)
->mget('foo', 'foobar')
->execute();
$this->assertInternalType('array', $replies);
$this->assertEquals(array(true, array('bar', 'bar')), $replies);
}
function testMultiExecBlock_RetryOnServerAbort() {
$client1 = RC::getConnection();
$client2 = RC::getConnection(true);
$client1->flushdb();
$retry = 3;
$attempts = 0;
RC::testForAbortedMultiExecException($this, function()
use($client1, $client2, $retry, &$attempts) {
$options = array('watch' => 'sentinel', 'retry' => $retry);
$client1->multiExec($options, function($tx)
use ($client2, &$attempts) {
$attempts++;
$tx->set('sentinel', 'client1');
$tx->get('sentinel');
$client2->set('sentinel', 'client2');
});
});
$this->assertEquals('client2', $client1->get('sentinel'));
$this->assertEquals($retry + 1, $attempts);
$retry = 3;
$attempts = 0;
RC::testForAbortedMultiExecException($this, function()
use($client1, $client2, $retry, &$attempts) {
$options = array(
'watch' => 'sentinel',
'cas' => true,
'retry' => $retry
);
$client1->multiExec($options, function($tx)
use ($client2, &$attempts) {
$attempts++;
$tx->incr('attempts');
$tx->multi();
$tx->set('sentinel', 'client1');
$tx->get('sentinel');
$client2->set('sentinel', 'client2');
});
});
$this->assertEquals('client2', $client1->get('sentinel'));
$this->assertEquals($retry + 1, $attempts);
$this->assertEquals($attempts, $client1->get('attempts'));
}
/**
* @expectedException InvalidArgumentException
*/
function testMultiExecBlock_RetryNotAvailableWithoutBlock() {
$options = array('watch' => 'foo', 'retry' => 1);
$tx = RC::getConnection()->multiExec($options);
$tx->multi()->get('foo')->exec();
}
function testMultiExecBlock_CheckAndSet_Discard() {
$client = RC::getConnection();
$client->flushdb();
$client->set('foo', 'bar');
$options = array('watch' => 'foo', 'cas' => true);
$replies = $client->multiExec($options, function($tx) {
$tx->watch('foobar');
$foo = $tx->get('foo');
$tx->multi();
$tx->set('foobar', $foo);
$tx->discard();
$tx->mget('foo', 'foobar');
});
$this->assertInternalType('array', $replies);
$this->assertEquals(array(array('bar', null)), $replies);
$hijack = true;
$client->set('foo', 'bar');
$client2 = RC::getConnection(true);
$options = array('watch' => 'foo', 'cas' => true, 'retry' => 1);
$replies = $client->multiExec($options, function($tx)
use ($client2, &$hijack) {
$foo = $tx->get('foo');
$tx->multi();
$tx->set('foobar', $foo);
$tx->discard();
if ($hijack) {
$hijack = false;
$client2->set('foo', 'hijacked!');
}
$tx->mget('foo', 'foobar');
});
$this->assertInternalType('array', $replies);
$this->assertEquals(array(array('hijacked!', null)), $replies);
}
}
?>
+503
View File
@@ -0,0 +1,503 @@
<?php
define('I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE', false);
require_once 'PHPUnit/Framework.php';
require_once 'PredisShared.php';
require_once '../lib/Predis_Compatibility.php';
class PredisClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
public $redis;
protected function setUp() {
$this->redis = RC::getConnection();
$this->redis->flushDatabase();
}
protected function tearDown() {
}
protected function onNotSuccessfulTest(Exception $exception) {
// drops and reconnect to a redis server on uncaught exceptions
RC::resetConnection();
parent::onNotSuccessfulTest($exception);
}
/* ConnectionParameters */
function testConnectionParametersDefaultValues() {
$params = new Predis_ConnectionParameters();
$this->assertEquals(Predis_ConnectionParameters::DEFAULT_HOST, $params->host);
$this->assertEquals(Predis_ConnectionParameters::DEFAULT_PORT, $params->port);
$this->assertEquals(Predis_ConnectionParameters::DEFAULT_TIMEOUT, $params->connection_timeout);
$this->assertNull($params->read_write_timeout);
$this->assertNull($params->database);
$this->assertNull($params->password);
$this->assertNull($params->alias);
}
function testConnectionParametersSetupValuesArray() {
$paramsArray = RC::getConnectionParametersArgumentsArray();
$params = new Predis_ConnectionParameters($paramsArray);
$this->assertEquals($paramsArray['host'], $params->host);
$this->assertEquals($paramsArray['port'], $params->port);
$this->assertEquals($paramsArray['connection_timeout'], $params->connection_timeout);
$this->assertEquals($paramsArray['read_write_timeout'], $params->read_write_timeout);
$this->assertEquals($paramsArray['database'], $params->database);
$this->assertEquals($paramsArray['password'], $params->password);
$this->assertEquals($paramsArray['alias'], $params->alias);
}
function testConnectionParametersSetupValuesString() {
$paramsArray = RC::getConnectionParametersArgumentsArray();
$paramsString = RC::getConnectionParametersArgumentsString($paramsArray);
$params = new Predis_ConnectionParameters($paramsArray);
$this->assertEquals($paramsArray['host'], $params->host);
$this->assertEquals($paramsArray['port'], $params->port);
$this->assertEquals($paramsArray['connection_timeout'], $params->connection_timeout);
$this->assertEquals($paramsArray['read_write_timeout'], $params->read_write_timeout);
$this->assertEquals($paramsArray['database'], $params->database);
$this->assertEquals($paramsArray['password'], $params->password);
$this->assertEquals($paramsArray['alias'], $params->alias);
}
/* Command and derivates */
function testCommand_TestArguments() {
$cmdArgs = array('key1', 'key2', 'key3');
$cmd = new Predis_Commands_GetMultiple();
$cmd->setArgumentsArray($cmdArgs);
$this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
$this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
$this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
$cmd = new Predis_Commands_GetMultiple();
$cmd->setArguments('key1', 'key2', 'key3');
$this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
$this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
$this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
$cmd = new Predis_Commands_Ping();
$this->assertNull($cmd->getArgument(0));
}
function testCommand_InlineWithNoArguments() {
$cmd = new Predis_Compatibility_v1_0_Commands_Ping();
$this->assertType('Predis_InlineCommand', $cmd);
$this->assertEquals('PING', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertFalse($cmd->canBeHashed());
$this->assertNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("PING\r\n", $cmd->invoke());
}
function testCommand_InlineWithArguments() {
$cmd = new Predis_Compatibility_v1_0_Commands_Get();
$cmd->setArgumentsArray(array('key'));
$this->assertType('Predis_InlineCommand', $cmd);
$this->assertEquals('GET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertTrue($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("GET key\r\n", $cmd->invoke());
}
function testCommand_BulkWithArguments() {
$cmd = new Predis_Compatibility_v1_0_Commands_Set();
$cmd->setArgumentsArray(array('key', 'value'));
$this->assertType('Predis_BulkCommand', $cmd);
$this->assertEquals('SET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertTrue($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("SET key 5\r\nvalue\r\n", $cmd->invoke());
}
function testCommand_MultiBulkWithArguments() {
$cmd = new Predis_Commands_SetMultiple();
$cmd->setArgumentsArray(array('key1', 'value1', 'key2', 'value2'));
$this->assertType('Predis_MultiBulkCommand', $cmd);
$this->assertEquals('MSET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertFalse($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("*5\r\n$4\r\nMSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n", $cmd->invoke());
}
function testCommand_ParseResponse() {
// default parser
$cmd = new Predis_Commands_Get();
$this->assertEquals('test', $cmd->parseResponse('test'));
// overridden parser (boolean)
$cmd = new Predis_Commands_Exists();
$this->assertTrue($cmd->parseResponse('1'));
$this->assertFalse($cmd->parseResponse('0'));
// overridden parser (boolean)
$cmd = new Predis_Commands_Ping();
$this->assertTrue($cmd->parseResponse('PONG'));
// overridden parser (complex)
// TODO: emulate a respons to INFO
}
/* RedisServerProfile and derivates */
function testRedisServerProfile_GetSpecificVersions() {
$this->assertType('Predis_RedisServer_v1_0', Predis_RedisServerProfile::get('1.0'));
$this->assertType('Predis_RedisServer_v1_2', Predis_RedisServerProfile::get('1.2'));
$this->assertType('Predis_RedisServer_v2_0', Predis_RedisServerProfile::get('2.0'));
$this->assertType('Predis_RedisServer_vNext', Predis_RedisServerProfile::get('dev'));
$this->assertType('Predis_RedisServerProfile', Predis_RedisServerProfile::get('default'));
$this->assertEquals(Predis_RedisServerProfile::get('default'), Predis_RedisServerProfile::getDefault());
}
function testRedisServerProfile_SupportedCommands() {
$profile_10 = Predis_RedisServerProfile::get('1.0');
$profile_12 = Predis_RedisServerProfile::get('1.2');
$this->assertTrue($profile_10->supportsCommand('info'));
$this->assertTrue($profile_12->supportsCommand('info'));
$this->assertFalse($profile_10->supportsCommand('mset'));
$this->assertTrue($profile_12->supportsCommand('mset'));
$this->assertFalse($profile_10->supportsCommand('multi'));
$this->assertFalse($profile_12->supportsCommand('multi'));
}
function testRedisServerProfile_CommandsCreation() {
$profile = Predis_RedisServerProfile::get('1.0');
$cmdNoArgs = $profile->createCommand('info');
$this->assertType('Predis_Compatibility_v1_0_Commands_Info', $cmdNoArgs);
$this->assertNull($cmdNoArgs->getArgument());
$args = array('key1', 'key2');
$cmdWithArgs = $profile->createCommand('mget', $args);
$this->assertType('Predis_Compatibility_v1_0_Commands_GetMultiple', $cmdWithArgs);
$this->assertEquals($args[0], $cmdWithArgs->getArgument()); // TODO: why?
$this->assertEquals($args[0], $cmdWithArgs->getArgument(0));
$this->assertEquals($args[1], $cmdWithArgs->getArgument(1));
$bogusCommand = 'not_existing_command';
$expectedMessage = "'$bogusCommand' is not a registered Redis command";
RC::testForClientException($this, $expectedMessage, p_anon("\$test", "
\$profile = Predis_RedisServerProfile::getDefault();
\$profile->createCommand('$bogusCommand');
"));
}
function testRedisServerProfile_CommandsRegistration() {
$profile = Predis_RedisServerProfile::get('1.0');
$cmdId = 'mset';
$cmdClass = 'Predis_Commands_SetMultiple';
$this->assertFalse($profile->supportsCommand($cmdId));
$profile->registerCommand(new $cmdClass(), $cmdId);
$this->assertTrue($profile->supportsCommand($cmdId));
$this->assertType($cmdClass, $profile->createCommand($cmdId));
}
/* ResponseQueued */
function testResponseQueued() {
$response = new Predis_ResponseQueued();
$this->assertTrue($response->queued);
$this->assertEquals(Predis_Protocol::QUEUED, (string)$response);
}
/* ResponseError */
function testResponseError() {
$errorMessage = 'ERROR MESSAGE';
$response = new Predis_ResponseError($errorMessage);
$this->assertTrue($response->error);
$this->assertEquals($errorMessage, $response->message);
$this->assertEquals($errorMessage, (string)$response);
}
/* Connection */
function testConnection_StringCastReturnsIPAndPort() {
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertEquals(RC::SERVER_HOST . ':' . RC::SERVER_PORT, (string) $connection);
}
function testConnection_ConnectDisconnect() {
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$connection->connect();
$this->assertTrue($connection->isConnected());
$connection->disconnect();
$this->assertFalse($connection->isConnected());
}
function testConnection_WriteAndReadCommand() {
$cmd = Predis_RedisServerProfile::getDefault()->createCommand('ping');
$connection = new Predis_Connection(RC::getConnectionParameters());
$connection->connect();
$connection->writeCommand($cmd);
$this->assertTrue($connection->readResponse($cmd));
}
function testConnection_WriteCommandAndCloseConnection() {
$cmd = Predis_RedisServerProfile::getDefault()->createCommand('quit');
$connection = new Predis_Connection(RC::getConnectionParameters());
$connection->connect();
$this->assertTrue($connection->isConnected());
$connection->writeCommand($cmd);
$expectedMessage = 'Error while reading line from the server';
$thrownException = null;
try {
$connection->readResponse($cmd);
}
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$this->assertType('Predis_CommunicationException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
//$this->assertFalse($connection->isConnected());
}
function testConnection_GetSocketOpensConnection() {
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$this->assertType('resource', $connection->getSocket());
$this->assertTrue($connection->isConnected());
}
function testConnection_LazyConnect() {
$cmd = Predis_RedisServerProfile::getDefault()->createCommand('ping');
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$connection->writeCommand($cmd);
$this->assertTrue($connection->isConnected());
$this->assertTrue($connection->readResponse($cmd));
}
function testConnection_RawCommand() {
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertEquals('PONG', $connection->rawCommand("PING\r\n"));
}
function testConnection_Alias() {
$connection1 = new Predis_Connection(RC::getConnectionParameters());
$this->assertNull($connection1->getParameters()->alias);
$args = array_merge(RC::getConnectionArguments(), array('alias' => 'servername'));
$connection2 = new Predis_Connection(new Predis_ConnectionParameters($args));
$this->assertEquals('servername', $connection2->getParameters()->alias);
}
function testConnection_ConnectionTimeout() {
$timeout = 3;
$args = array('host' => '1.0.0.1', 'connection_timeout' => $timeout);
$connection = new Predis_Connection(new Predis_ConnectionParameters($args));
$start = time();
$thrownException = null;
try {
$connection->connect();
}
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$this->assertType('Predis_CommunicationException', $thrownException);
$this->assertEquals((float)(time() - $start), $timeout, '', 1);
}
function testConnection_ReadTimeout() {
$timeout = 1;
$args = array_merge(RC::getConnectionArguments(), array('read_write_timeout' => $timeout));
$cmdFake = Predis_RedisServerProfile::getDefault()->createCommand('ping');
$connection = new Predis_Connection(new Predis_ConnectionParameters($args));
$expectedMessage = 'Error while reading line from the server';
$start = time();
$thrownException = null;
try {
$connection->readResponse($cmdFake);
}
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$this->assertType('Predis_CommunicationException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
$this->assertEquals((float)(time() - $start), $timeout, '', 1);
}
/* ResponseReader */
function testResponseReader_OptionIterableMultiBulkReplies() {
$connection = new Predis_Connection(RC::getConnectionParameters());
$responseReader = $connection->getResponseReader();
$responseReader->setHandler(
Predis_Protocol::PREFIX_MULTI_BULK,
new Predis_ResponseMultiBulkHandler()
);
$this->assertType('array', $connection->rawCommand("KEYS *\r\n"));
$responseReader->setHandler(
Predis_Protocol::PREFIX_MULTI_BULK,
new Predis_ResponseMultiBulkStreamHandler()
);
$this->assertType('Iterator', $connection->rawCommand("KEYS *\r\n"));
}
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";
$responseReader->setHandler(
Predis_Protocol::PREFIX_ERROR,
new Predis_ResponseErrorSilentHandler()
);
$errorReply = $connection->rawCommand($rawCmdUnexpected);
$this->assertType('Predis_ResponseError', $errorReply);
$this->assertEquals(RC::EXCEPTION_WRONG_TYPE, $errorReply->message);
$responseReader->setHandler(
Predis_Protocol::PREFIX_ERROR,
new Predis_ResponseErrorHandler()
);
$thrownException = null;
try {
$connection->rawCommand($rawCmdUnexpected);
}
catch (Predis_ServerException $exception) {
$thrownException = $exception;
}
$this->assertType('Predis_ServerException', $thrownException);
$this->assertEquals(RC::EXCEPTION_WRONG_TYPE, $thrownException->getMessage());
}
/* Client + CommandPipeline */
function testCommandPipeline_Simple() {
$client = RC::getConnection();
$client->flushdb();
$pipe = $client->pipeline();
$this->assertType('Predis_CommandPipeline', $pipe);
$this->assertType('Predis_CommandPipeline', $pipe->set('foo', 'bar'));
$this->assertType('Predis_CommandPipeline', $pipe->set('hoge', 'piyo'));
$this->assertType('Predis_CommandPipeline', $pipe->mset(array(
'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
)));
$this->assertType('Predis_CommandPipeline', $pipe->mget(array(
'foo', 'hoge', 'foofoo', 'hogehoge'
)));
$replies = $pipe->execute();
$this->assertType('array', $replies);
$this->assertEquals(4, count($replies));
$this->assertEquals(4, count($replies[3]));
$this->assertEquals('barbar', $replies[3][2]);
}
function testCommandPipeline_FluentInterface() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->pipeline()->ping()->set('foo', 'bar')->get('foo')->execute();
$this->assertType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
function testCommandPipeline_CallableAnonymousBlock() {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->pipeline(p_anon("\$pipe", "
\$pipe->ping();
\$pipe->set('foo', 'bar');
\$pipe->get('foo');
"));
$this->assertType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
function testCommandPipeline_ClientExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$expectedMessage = 'TEST';
$thrownException = null;
try {
$client->pipeline(p_anon("\$pipe", "
\$pipe->ping();
\$pipe->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 testCommandPipeline_ServerExceptionInCallableBlock() {
$client = RC::getConnection();
$client->flushdb();
$client->getResponseReader()->setHandler('-', new Predis_ResponseErrorSilentHandler());
$replies = $client->pipeline(p_anon("\$pipe", "
\$pipe->set('foo', 'bar');
\$pipe->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
\$pipe->set('hoge', 'piyo');
"));
$this->assertType('array', $replies);
$this->assertType('Predis_ResponseError', $replies[1]);
$this->assertTrue($client->exists('foo'));
$this->assertTrue($client->exists('hoge'));
}
function testCommandPipeline_Flush() {
$client = RC::getConnection();
$client->flushdb();
$pipe = $client->pipeline();
$pipe->set('foo', 'bar')->set('hoge', 'piyo');
$pipe->flushPipeline();
$pipe->ping()->mget(array('foo', 'hoge'));
$replies = $pipe->execute();
$this->assertType('array', $replies);
$this->assertEquals(4, count($replies));
$this->assertEquals('bar', $replies[3][0]);
$this->assertEquals('piyo', $replies[3][1]);
}
}
?>
+25 -50
View File
@@ -1,27 +1,20 @@
<?php
// -------------------------------------------------------------------------- //
define('I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE', false);
// -------------------------------------------------------------------------- //
require_once '../lib/Predis.php';
if (I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE !== true) {
exit(
"Please set the I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE " .
"constant to TRUE in PredisShared.php if you want to proceed.\n"
);
exit('Please set the I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE constant to TRUE if you want to proceed.');
}
Predis\RedisServerProfile::registerProfile('\Predis\RedisServer_v1_2', '1.2');
Predis\RedisServerProfile::registerProfile('\Predis\RedisServer_v2_0', '2.0');
Predis\RedisServerProfile::registerProfile('\Predis\RedisServer_v2_2', '2.2');
if (!function_exists('array_union')) {
function array_union(Array $a, Array $b) {
function array_union(Array $a, Array $b) {
return array_merge($a, array_diff($b, $a));
}
}
function p_anon($param, $function) {
return create_function($param, $function);
}
class RC {
const SERVER_HOST = '127.0.0.1';
const SERVER_PORT = 6379;
@@ -31,37 +24,31 @@ class RC {
const EXCEPTION_WRONG_TYPE = 'Operation against a key holding the wrong kind of value';
const EXCEPTION_NO_SUCH_KEY = 'no such key';
const EXCEPTION_OUT_OF_RANGE = 'index out of range';
const EXCEPTION_OFFSET_RANGE = 'offset is out of range';
const EXCEPTION_INVALID_DB_IDX = 'invalid DB index';
const EXCEPTION_VALUE_NOT_INT = 'value is not an integer';
const EXCEPTION_EXEC_NO_MULTI = 'EXEC without MULTI';
const EXCEPTION_SETEX_TTL = 'invalid expire time in SETEX';
const EXCEPTION_HASH_VALNOTINT = 'hash value is not an integer';
const EXCEPTION_BIT_VALUE = 'bit is not an integer or out of range';
const EXCEPTION_BIT_OFFSET = 'bit offset is not an integer or out of range';
private static $_connection;
public static function getConnectionArguments() {
public static function getConnectionArguments() {
return array('host' => RC::SERVER_HOST, 'port' => RC::SERVER_PORT);
}
public static function getConnectionParameters() {
return new Predis\ConnectionParameters(array('host' => RC::SERVER_HOST, 'port' => RC::SERVER_PORT));
public static function getConnectionParameters() {
return new Predis_ConnectionParameters(array('host' => RC::SERVER_HOST, 'port' => RC::SERVER_PORT));
}
private static function createConnection() {
$serverProfile = Predis\RedisServerProfile::get('2.2');
$connection = new Predis\Client(RC::getConnectionArguments(), $serverProfile);
$serverProfile = Predis_RedisServerProfile::get('dev');
$connection = new Predis_Client(RC::getConnectionArguments(), $serverProfile);
$connection->connect();
$connection->select(RC::DEFAULT_DATABASE);
return $connection;
}
public static function getConnection($new = false) {
if ($new == true) {
return self::createConnection();
}
public static function getConnection() {
if (self::$_connection === null || !self::$_connection->isConnected()) {
self::$_connection = self::createConnection();
}
@@ -80,10 +67,9 @@ class RC {
// in a separate process to properly test BLPOP/BRPOP
$redisUri = sprintf('redis://%s:%d/?database=%d', RC::SERVER_HOST, RC::SERVER_PORT, RC::DEFAULT_DATABASE);
$handle = popen('php', 'w');
$dir = __DIR__;
fwrite($handle, "<?php
require '{$dir}/../lib/Predis.php';
\$redis = Predis\Client::create('$redisUri');
require '../lib/Predis.php';
\$redis = Predis_Client::create('$redisUri');
\$redis->rpush('{$op}1', 'a');
\$redis->rpush('{$op}2', 'b');
\$redis->rpush('{$op}3', 'c');
@@ -130,10 +116,10 @@ class RC {
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\ServerException $exception) {
catch (Predis_ServerException $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\ServerException', $thrownException);
$testcaseInstance->assertType('Predis_ServerException', $thrownException);
if (isset($expectedMessage)) {
$testcaseInstance->assertEquals($expectedMessage, $thrownException->getMessage());
}
@@ -144,10 +130,10 @@ class RC {
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\ClientException $exception) {
catch (Predis_ClientException $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\ClientException', $thrownException);
$testcaseInstance->assertType('Predis_ClientException', $thrownException);
if (isset($expectedMessage)) {
$testcaseInstance->assertEquals($expectedMessage, $thrownException->getMessage());
}
@@ -158,27 +144,16 @@ class RC {
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\CommunicationException $exception) {
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\CommunicationException', $thrownException);
$testcaseInstance->assertType('Predis_CommunicationException', $thrownException);
if (isset($expectedMessage)) {
$testcaseInstance->assertEquals($expectedMessage, $thrownException->getMessage());
}
}
public static function testForAbortedMultiExecException($testcaseInstance, $wrapFunction) {
$thrownException = null;
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\AbortedMultiExec $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\AbortedMultiExec', $thrownException);
}
public static function pushTailAndReturn(Predis\Client $client, $keyName, Array $values, $wipeOut = 0) {
public static function pushTailAndReturn(Predis_Client $client, $keyName, Array $values, $wipeOut = 0) {
if ($wipeOut == true) {
$client->del($keyName);
}
@@ -188,7 +163,7 @@ class RC {
return $values;
}
public static function setAddAndReturn(Predis\Client $client, $keyName, Array $values, $wipeOut = 0) {
public static function setAddAndReturn(Predis_Client $client, $keyName, Array $values, $wipeOut = 0) {
if ($wipeOut == true) {
$client->del($keyName);
}
@@ -198,7 +173,7 @@ class RC {
return $values;
}
public static function zsetAddAndReturn(Predis\Client $client, $keyName, Array $values, $wipeOut = 0) {
public static function zsetAddAndReturn(Predis_Client $client, $keyName, Array $values, $wipeOut = 0) {
// $values: array(SCORE => VALUE, ...);
if ($wipeOut == true) {
$client->del($keyName);
@@ -218,7 +193,7 @@ class RC {
public static function getConnectionParametersArgumentsString($arguments = null) {
// TODO: must be improved
$args = $arguments ?: RC::getConnectionParametersArgumentsArray();
$args = $arguments !== null ? $arguments : RC::getConnectionParametersArgumentsArray();
$paramsString = "redis://{$args['host']}:{$args['port']}/";
$paramsString .= "?connection_timeout={$args['connection_timeout']}&read_write_timeout={$args['read_write_timeout']}";
$paramsString .= "&database={$args['database']}&password={$args['password']}&alias={$args['alias']}";
+275 -578
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -1,6 +0,0 @@
<?php
require_once(__DIR__ . '/../lib/Predis.php');
require_once(__DIR__ . '/../lib/Predis_Compatibility.php');
require_once(__DIR__ . '/../test/PredisShared.php');