diff --git a/lib/Predis/Autoloader.php b/lib/Predis/Autoloader.php index 3c626714..33ebfd5a 100644 --- a/lib/Predis/Autoloader.php +++ b/lib/Predis/Autoloader.php @@ -11,22 +11,38 @@ namespace Predis; +/** + * Implements a lightweight PSR-0 compliant autoloader. + * + * @author Eric Naeseth + */ class Autoloader { private $_baseDir; private $_prefix; + /** + * @param string $baseDirectory Base directory where the source files are located. + */ public function __construct($baseDirectory = null) { $this->_baseDir = $baseDirectory ?: dirname(__FILE__); $this->_prefix = __NAMESPACE__ . '\\'; } + /** + * Registers the autoloader class with the PHP SPL autoloader. + */ public static function register() { spl_autoload_register(array(new self, 'autoload')); } + /** + * Loads a class from a file using its fully qualified name. + * + * @param string $className Fully qualified name of a class. + */ public function autoload($className) { if (0 !== strpos($className, $this->_prefix)) { diff --git a/lib/Predis/Client.php b/lib/Predis/Client.php index bf2a66da..114703dc 100644 --- a/lib/Predis/Client.php +++ b/lib/Predis/Client.php @@ -19,6 +19,11 @@ use Predis\Profiles\ServerProfile; use Predis\Pipeline\PipelineContext; use Predis\Transaction\MultiExecContext; +/** + * Main class that exposes the most high-level interface to interact with Redis. + * + * @author Daniele Alessandri + */ class Client { const VERSION = '0.7.0-dev'; @@ -28,6 +33,12 @@ class Client private $_connection; private $_connectionFactory; + /** + * Initializes a new client with optional connection parameters and client options. + * + * @param mixed $parameters Connection parameters for one or multiple Redis servers. + * @param mixed $options Options that specify certain behaviours for the client. + */ public function __construct($parameters = null, $options = null) { $options = $this->filterOptions($options); @@ -43,6 +54,14 @@ class Client $this->_connection = $this->initializeConnection($parameters); } + /** + * Creates an instance of Predis\Options\ClientOptions from various types of + * parameters (string, array, Predis\Profiles\ServerProfile) or returns the + * passed object if its an instance of Predis\Options\ClientOptions. + * + * @param mixed $options Client options. + * @return ClientOptions + */ private function filterOptions($options) { if ($options === null) { @@ -64,6 +83,14 @@ class Client throw new \InvalidArgumentException("Invalid type for client options"); } + /** + * Initialize one or multiple connection (cluster) objects from various types of + * parameters (string, array) or returns the passed object if it implements the + * Predis\Network\IConnection interface. + * + * @param mixed $parameters Connection parameters or object. + * @return IConnection + */ private function initializeConnection($parameters) { if ($parameters === null) { @@ -89,6 +116,12 @@ class Client return $this->createConnection($parameters); } + /** + * Create a new connection to a single Redis server using the provided parameters. + * + * @param mixed $parameters Connection parameters. + * @return IConnectionSingle + */ protected function createConnection($parameters) { $connection = $this->_connectionFactory->create($parameters); @@ -107,21 +140,43 @@ class Client return $connection; } + /** + * Returns the server profile used by the client. + * + * @return IServerProfile + */ public function getProfile() { return $this->_profile; } + /** + * Returns the client options specified upon client initialization. + * + * @return ClientOptions + */ public function getOptions() { return $this->_options; } + /** + * Returns the connection factory object used by the client. + * + * @return IConnectionFactory + */ public function getConnectionFactory() { return $this->_connectionFactory; } + /** + * Returns a new client instance for the specified connection when the client + * is connected to a cluster. The new client will use the same options of the + * the original instance. + * + * @return Client + */ public function getClientFor($connectionAlias) { if (($connection = $this->getConnection($connectionAlias)) === null) { @@ -131,26 +186,48 @@ class Client return new Client($connection, $this->_options); } + /** + * Opens the connection to Redis. + */ public function connect() { $this->_connection->connect(); } + /** + * Disconnects from Redis. + */ public function disconnect() { $this->_connection->disconnect(); } + /** + * Disconnects from Redis. This method is an alias of disconnect(). + */ public function quit() { $this->disconnect(); } + /** + * Checks if the underlying connection is connected to Redis. + * + * @return Boolean True means that the connection is open. + * False means that the connection is closed. + */ public function isConnected() { return $this->_connection->isConnected(); } + /** + * Returns the underlying connection instance or, when connected to a cluster, + * one of the connection instances identified by its alias. + * + * @param string $id The alias of a connection when connected to a cluster. + * @return IConnection + */ public function getConnection($id = null) { if (isset($id)) { @@ -166,22 +243,48 @@ class Client return $this->_connection; } + /** + * Dinamically invokes a Redis command with the specified arguments. + * + * @param string $method The name of a Redis command. + * @param array $arguments The arguments for the command. + * @return mixed + */ public function __call($method, $arguments) { $command = $this->_profile->createCommand($method, $arguments); return $this->_connection->executeCommand($command); } + /** + * Creates a new instance of the specified Redis command. + * + * @param string $method The name of a Redis command. + * @param array $arguments The arguments for the command. + * @return ICommand + */ public function createCommand($method, $arguments = array()) { return $this->_profile->createCommand($method, $arguments); } + /** + * Executes the specified Redis command. + * + * @param ICommand $command A Redis command. + * @return mixed + */ public function executeCommand(ICommand $command) { return $this->_connection->executeCommand($command); } + /** + * Executes the specified Redis command on all the nodes of a cluster. + * + * @param ICommand $command A Redis command. + * @return array + */ public function executeCommandOnShards(ICommand $command) { if (Helpers::isCluster($this->_connection)) { @@ -197,6 +300,15 @@ class Client return array($this->_connection->executeCommand($command)); } + /** + * Call the specified initializer method on $this with 0, 1 or 2 arguments. + * + * TODO: Invert $argv and $initializer. + * + * @param array $argv Arguments for the initializer. + * @param string $initializer The initializer method. + * @return mixed + */ private function sharedInitializer($argv, $initializer) { switch (count($argv)) { @@ -216,53 +328,107 @@ class Client } } + /** + * Creates a new pipeline context and returns it, or returns the results of + * a pipeline executed inside the optionally provided callable object. + * + * @param mixed $arg,... Options for the context, a callable object, or both. + * @return PipelineContext|array + */ public function pipeline(/* arguments */) { return $this->sharedInitializer(func_get_args(), 'initPipeline'); } - protected function initPipeline(Array $options = null, $pipelineBlock = null) + /** + * Pipeline context initializer. + * + * @param array $options Options for the context. + * @param mixed $callable Optional callable object used to execute the context. + * @return PipelineContext|array + */ + protected function initPipeline(Array $options = null, $callable = null) { $pipeline = new PipelineContext($this, $options); - return $this->pipelineExecute($pipeline, $pipelineBlock); + return $this->pipelineExecute($pipeline, $callable); } - private function pipelineExecute(PipelineContext $pipeline, $block) + /** + * Executes a pipeline context when a callable object is passed. + * + * @param array $options Options of the context initialization. + * @param mixed $callable Optional callable object used to execute the context. + * @return PipelineContext|array + */ + private function pipelineExecute(PipelineContext $pipeline, $callable) { - return $block !== null ? $pipeline->execute($block) : $pipeline; + return isset($callable) ? $pipeline->execute($callable) : $pipeline; } + /** + * Creates a new transaction context and returns it, or returns the results of + * a transaction executed inside the optionally provided callable object. + * + * @param mixed $arg,... Options for the context, a callable object, or both. + * @return MultiExecContext|array + */ public function multiExec(/* arguments */) { return $this->sharedInitializer(func_get_args(), 'initMultiExec'); } - protected function initMultiExec(Array $options = null, $block = null) + /** + * Transaction context initializer. + * + * @param array $options Options for the context. + * @param mixed $callable Optional callable object used to execute the context. + * @return MultiExecContext|array + */ + protected function initMultiExec(Array $options = null, $callable = null) { $transaction = new MultiExecContext($this, $options ?: array()); - return isset($block) ? $transaction->execute($block) : $transaction; + return isset($callable) ? $transaction->execute($callable) : $transaction; } + /** + * Creates a new Publish / Subscribe context and returns it, or executes it + * inside the optionally provided callable object. + * + * @param mixed $arg,... Options for the context, a callable object, or both. + * @return MultiExecContext|array + */ public function pubSub(/* arguments */) { return $this->sharedInitializer(func_get_args(), 'initPubSub'); } - protected function initPubSub(Array $options = null, $block = null) + /** + * Publish / Subscribe context initializer. + * + * @param array $options Options for the context. + * @param mixed $callable Optional callable object used to execute the context. + * @return PubSubContext + */ + protected function initPubSub(Array $options = null, $callable = null) { $pubsub = new PubSubContext($this, $options); - if (!isset($block)) { + if (!isset($callable)) { return $pubsub; } foreach ($pubsub as $message) { - if ($block($pubsub, $message) === false) { + if ($callable($pubsub, $message) === false) { $pubsub->closeContext(); } } } + /** + * Returns a new monitor context. + * + * @return MonitorContext + */ public function monitor() { return new MonitorContext($this); diff --git a/lib/Predis/ClientException.php b/lib/Predis/ClientException.php index 5ae8f769..6c07aaf0 100644 --- a/lib/Predis/ClientException.php +++ b/lib/Predis/ClientException.php @@ -11,6 +11,11 @@ namespace Predis; +/** + * Exception class that identifies client-side errors. + * + * @author Daniele Alessandri + */ class ClientException extends PredisException { } diff --git a/lib/Predis/ClientOptions.php b/lib/Predis/ClientOptions.php index faecb2a9..a2f11af4 100644 --- a/lib/Predis/ClientOptions.php +++ b/lib/Predis/ClientOptions.php @@ -17,6 +17,11 @@ use Predis\Options\ClientProfile; use Predis\Options\ClientCluster; use Predis\Options\ClientConnectionFactory; +/** + * Class that manages validation and conversion of client options. + * + * @author Daniele Alessandri + */ class ClientOptions { private static $_sharedOptions; @@ -26,12 +31,20 @@ class ClientOptions private $_options = array(); + /** + * @param array $options Array of client options. + */ public function __construct(Array $options = array()) { $this->_handlers = $this->initialize($options); $this->_defined = array_keys($options); } + /** + * Ensures that the default options are initialized. + * + * @return array + */ private static function getSharedOptions() { if (isset(self::$_sharedOptions)) { @@ -48,18 +61,35 @@ class ClientOptions return self::$_sharedOptions; } + /** + * Defines an option handler or overrides an existing one. + * + * @param string $option Name of the option. + * @param IOption $handler Handler for the option. + */ public static function define($option, IOption $handler) { self::getSharedOptions(); self::$_sharedOptions[$option] = $handler; } + /** + * Undefines the handler for the specified option. + * + * @param string $option Name of the option. + */ public static function undefine($option) { self::getSharedOptions(); unset(self::$_sharedOptions[$option]); } + /** + * Initializes client options handlers. + * + * @param array $options List of client options values. + * @return array + */ private function initialize($options) { $handlers = self::getSharedOptions(); @@ -76,11 +106,23 @@ class ClientOptions return $handlers; } + /** + * Checks if the specified option is set. + * + * @param string $option Name of the option. + * @return Boolean + */ public function __isset($option) { return in_array($option, $this->_defined); } + /** + * Returns the value of the specified option. + * + * @param string $option Name of the option. + * @return mixed + */ public function __get($option) { if (isset($this->_options[$option])) { diff --git a/lib/Predis/Commands/Command.php b/lib/Predis/Commands/Command.php index 8a345e69..7a4872b3 100644 --- a/lib/Predis/Commands/Command.php +++ b/lib/Predis/Commands/Command.php @@ -14,33 +14,60 @@ namespace Predis\Commands; use Predis\Helpers; use Predis\Distribution\INodeKeyGenerator; +/** + * Base class for Redis commands. + * + * @author Daniele Alessandri + */ abstract class Command implements ICommand { private $_hash; private $_arguments = array(); + /** + * Returns a filtered array of the arguments. + * + * @param array $arguments List of arguments. + * @return array + */ protected function filterArguments(Array $arguments) { return $arguments; } + /** + * {@inheritdoc} + */ public function setArguments(Array $arguments) { $this->_arguments = $this->filterArguments($arguments); unset($this->_hash); } + /** + * Sets the arguments array without filtering. + * + * @param array $arguments List of arguments. + */ public function setRawArguments(Array $arguments) { $this->_arguments = $arguments; unset($this->_hash); } + /** + * {@inheritdoc} + */ public function getArguments() { return $this->_arguments; } + /** + * Get the argument from the arguments list at the specified index. + * + * @param array $arguments Position of the argument. + */ public function getArgument($index = 0) { if (isset($this->_arguments[$index]) === true) { @@ -48,12 +75,23 @@ abstract class Command implements ICommand } } + /** + * Implements the rule that is used to prefix the keys and returns a new + * array of arguments with the modified keys. + * + * @param array $arguments Arguments of the command. + * @param string $prefix Prefix appended to each key in the arguments. + * @return array + */ protected function onPrefixKeys(Array $arguments, $prefix) { $arguments[0] = "$prefix{$arguments[0]}"; return $arguments; } + /** + * {@inheritdoc} + */ public function prefixKeys($prefix) { $arguments = $this->onPrefixKeys($this->_arguments, $prefix); @@ -63,11 +101,22 @@ abstract class Command implements ICommand } } + /** + * Checks if the command can return an hash for client-side sharding. + * + * @return Boolean + */ protected function canBeHashed() { return isset($this->_arguments[0]); } + /** + * Checks if the specified array of keys will generate the same hash. + * + * @param array $keys Array of keys. + * @return Boolean + */ protected function checkSameHashForKeys(Array $keys) { if (($count = count($keys)) === 0) { @@ -87,6 +136,9 @@ abstract class Command implements ICommand return true; } + /** + * {@inheritdoc} + */ public function getHash(INodeKeyGenerator $distributor) { if (isset($this->_hash)) { @@ -103,11 +155,21 @@ abstract class Command implements ICommand return null; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return $data; } + /** + * Helper function used to reduce a list of arguments to a string. + * + * @param string $accumulator Temporary string. + * @param string $argument Current argument. + * @return string + */ protected function toStringArgumentReducer($accumulator, $argument) { if (strlen($argument) > 32) { @@ -118,6 +180,11 @@ abstract class Command implements ICommand return $accumulator; } + /** + * Returns a partial string representation of the command with its arguments. + * + * @return string + */ public function __toString() { return array_reduce( diff --git a/lib/Predis/Commands/ConnectionAuth.php b/lib/Predis/Commands/ConnectionAuth.php index 1f202036..8e2bc7db 100644 --- a/lib/Predis/Commands/ConnectionAuth.php +++ b/lib/Predis/Commands/ConnectionAuth.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/auth + * @author Daniele Alessandri + */ class ConnectionAuth extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'AUTH'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ConnectionEcho.php b/lib/Predis/Commands/ConnectionEcho.php index 317f44b3..49e90274 100644 --- a/lib/Predis/Commands/ConnectionEcho.php +++ b/lib/Predis/Commands/ConnectionEcho.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/echo + * @author Daniele Alessandri + */ class ConnectionEcho extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ECHO'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ConnectionPing.php b/lib/Predis/Commands/ConnectionPing.php index eef40fe4..ed99495d 100644 --- a/lib/Predis/Commands/ConnectionPing.php +++ b/lib/Predis/Commands/ConnectionPing.php @@ -11,23 +11,39 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/ping + * @author Daniele Alessandri + */ class ConnectionPing extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'PING'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return $data === 'PONG' ? true : false; diff --git a/lib/Predis/Commands/ConnectionQuit.php b/lib/Predis/Commands/ConnectionQuit.php index 848eac86..6ce20df5 100644 --- a/lib/Predis/Commands/ConnectionQuit.php +++ b/lib/Predis/Commands/ConnectionQuit.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/quit + * @author Daniele Alessandri + */ class ConnectionQuit extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'QUIT'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ConnectionSelect.php b/lib/Predis/Commands/ConnectionSelect.php index f4ab030a..6ecf0070 100644 --- a/lib/Predis/Commands/ConnectionSelect.php +++ b/lib/Predis/Commands/ConnectionSelect.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/select + * @author Daniele Alessandri + */ class ConnectionSelect extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SELECT'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/HashDelete.php b/lib/Predis/Commands/HashDelete.php index 76fc5d0e..ee4a2d3b 100644 --- a/lib/Predis/Commands/HashDelete.php +++ b/lib/Predis/Commands/HashDelete.php @@ -13,18 +13,31 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/hdel + * @author Daniele Alessandri + */ class HashDelete extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HDEL'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterVariadicValues($arguments); } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/HashExists.php b/lib/Predis/Commands/HashExists.php index 531672eb..7e7a5a84 100644 --- a/lib/Predis/Commands/HashExists.php +++ b/lib/Predis/Commands/HashExists.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hexists + * @author Daniele Alessandri + */ class HashExists extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HEXISTS'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/HashGet.php b/lib/Predis/Commands/HashGet.php index 0010ddcd..a7ab6773 100644 --- a/lib/Predis/Commands/HashGet.php +++ b/lib/Predis/Commands/HashGet.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hget + * @author Daniele Alessandri + */ class HashGet extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HGET'; diff --git a/lib/Predis/Commands/HashGetAll.php b/lib/Predis/Commands/HashGetAll.php index cb9acc74..499151c4 100644 --- a/lib/Predis/Commands/HashGetAll.php +++ b/lib/Predis/Commands/HashGetAll.php @@ -13,13 +13,23 @@ namespace Predis\Commands; use Predis\Iterators\MultiBulkResponseTuple; +/** + * @link http://redis.io/commands/hgetall + * @author Daniele Alessandri + */ class HashGetAll extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HGETALL'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { if ($data instanceof \Iterator) { diff --git a/lib/Predis/Commands/HashGetMultiple.php b/lib/Predis/Commands/HashGetMultiple.php index b53148d2..f298f50c 100644 --- a/lib/Predis/Commands/HashGetMultiple.php +++ b/lib/Predis/Commands/HashGetMultiple.php @@ -13,13 +13,23 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/hmget + * @author Daniele Alessandri + */ class HashGetMultiple extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HMGET'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterVariadicValues($arguments); diff --git a/lib/Predis/Commands/HashIncrementBy.php b/lib/Predis/Commands/HashIncrementBy.php index fd9d5d6e..af3ad93d 100644 --- a/lib/Predis/Commands/HashIncrementBy.php +++ b/lib/Predis/Commands/HashIncrementBy.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hincrby + * @author Daniele Alessandri + */ class HashIncrementBy extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HINCRBY'; diff --git a/lib/Predis/Commands/HashKeys.php b/lib/Predis/Commands/HashKeys.php index 0319c5bc..6fa05184 100644 --- a/lib/Predis/Commands/HashKeys.php +++ b/lib/Predis/Commands/HashKeys.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hkeys + * @author Daniele Alessandri + */ class HashKeys extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HKEYS'; diff --git a/lib/Predis/Commands/HashLength.php b/lib/Predis/Commands/HashLength.php index 3f71624b..acf93266 100644 --- a/lib/Predis/Commands/HashLength.php +++ b/lib/Predis/Commands/HashLength.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hlen + * @author Daniele Alessandri + */ class HashLength extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HLEN'; diff --git a/lib/Predis/Commands/HashSet.php b/lib/Predis/Commands/HashSet.php index fd520a8b..85aafeba 100644 --- a/lib/Predis/Commands/HashSet.php +++ b/lib/Predis/Commands/HashSet.php @@ -11,12 +11,23 @@ namespace Predis\Commands; -class HashSet extends Command { +/** + * @link http://redis.io/commands/hset + * @author Daniele Alessandri + */ +class HashSet extends Command +{ + /** + * {@inheritdoc} + */ public function getId() { return 'HSET'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/HashSetMultiple.php b/lib/Predis/Commands/HashSetMultiple.php index 3ef0ef68..64e615ad 100644 --- a/lib/Predis/Commands/HashSetMultiple.php +++ b/lib/Predis/Commands/HashSetMultiple.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hmset + * @author Daniele Alessandri + */ class HashSetMultiple extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HMSET'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { if (count($arguments) === 2 && is_array($arguments[1])) { diff --git a/lib/Predis/Commands/HashSetPreserve.php b/lib/Predis/Commands/HashSetPreserve.php index 664ae49e..9f908083 100644 --- a/lib/Predis/Commands/HashSetPreserve.php +++ b/lib/Predis/Commands/HashSetPreserve.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hsetnx + * @author Daniele Alessandri + */ class HashSetPreserve extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HSETNX'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/HashValues.php b/lib/Predis/Commands/HashValues.php index 48c629b9..7be5e35b 100644 --- a/lib/Predis/Commands/HashValues.php +++ b/lib/Predis/Commands/HashValues.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/hvals + * @author Daniele Alessandri + */ class HashValues extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'HVALS'; diff --git a/lib/Predis/Commands/ICommand.php b/lib/Predis/Commands/ICommand.php index d84b48d4..ec147496 100644 --- a/lib/Predis/Commands/ICommand.php +++ b/lib/Predis/Commands/ICommand.php @@ -13,12 +13,54 @@ namespace Predis\Commands; use Predis\Distribution\INodeKeyGenerator; +/** + * Defines an abstraction representing a Redis command. + * @author Daniele Alessandri + */ interface ICommand { + /** + * Gets the ID of a Redis command. + * + * @return string + */ public function getId(); + + /** + * Returns an hash of the command using the provided algorithm against the + * key (used to calculate the distribution of keys with client-side sharding). + * + * @param INodeKeyGenerator $distributor Distribution algorithm. + * @return int + */ public function getHash(INodeKeyGenerator $distributor); + + /** + * Set the arguments of the command. + * + * @param array $arguments List of arguments. + */ public function setArguments(Array $arguments); + + /** + * Get the arguments of the command. + * + * @return array + */ public function getArguments(); + + /** + * Prefixes all the keys in the arguments of the command. + * + * @param string $prefix String user to prefix the keys. + */ public function prefixKeys($prefix); + + /** + * Parses a reply buffer and returns a PHP object. + * + * @param string $data Binary string containing the whole reply. + * @return mixed + */ public function parseResponse($data); } diff --git a/lib/Predis/Commands/KeyDelete.php b/lib/Predis/Commands/KeyDelete.php index 591ac7df..e31bdbff 100644 --- a/lib/Predis/Commands/KeyDelete.php +++ b/lib/Predis/Commands/KeyDelete.php @@ -13,23 +13,39 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/del + * @author Daniele Alessandri + */ class KeyDelete extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'DEL'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterArrayArguments($arguments); } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { $args = $this->getArguments(); diff --git a/lib/Predis/Commands/KeyExists.php b/lib/Predis/Commands/KeyExists.php index 4e5d0597..b5edf42a 100644 --- a/lib/Predis/Commands/KeyExists.php +++ b/lib/Predis/Commands/KeyExists.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/exists + * @author Daniele Alessandri + */ class KeyExists extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'EXISTS'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/KeyExpire.php b/lib/Predis/Commands/KeyExpire.php index 9570cf76..35fddeff 100644 --- a/lib/Predis/Commands/KeyExpire.php +++ b/lib/Predis/Commands/KeyExpire.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/expire + * @author Daniele Alessandri + */ class KeyExpire extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'EXPIRE'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/KeyExpireAt.php b/lib/Predis/Commands/KeyExpireAt.php index e9ce891a..55df2cb6 100644 --- a/lib/Predis/Commands/KeyExpireAt.php +++ b/lib/Predis/Commands/KeyExpireAt.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/expireat + * @author Daniele Alessandri + */ class KeyExpireAt extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'EXPIREAT'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/KeyKeys.php b/lib/Predis/Commands/KeyKeys.php index 9f3e2a72..82b3a8f0 100644 --- a/lib/Predis/Commands/KeyKeys.php +++ b/lib/Predis/Commands/KeyKeys.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/keys + * @author Daniele Alessandri + */ class KeyKeys extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'KEYS'; } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/KeyKeysV12x.php b/lib/Predis/Commands/KeyKeysV12x.php index 1b4b636d..262cc3b5 100644 --- a/lib/Predis/Commands/KeyKeysV12x.php +++ b/lib/Predis/Commands/KeyKeysV12x.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/keys + * @author Daniele Alessandri + */ class KeyKeysV12x extends KeyKeys { + /** + * {@inheritdoc} + */ public function parseResponse($data) { return explode(' ', $data); diff --git a/lib/Predis/Commands/KeyMove.php b/lib/Predis/Commands/KeyMove.php index 1a38c95d..c0848c1f 100644 --- a/lib/Predis/Commands/KeyMove.php +++ b/lib/Predis/Commands/KeyMove.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/move + * @author Daniele Alessandri + */ class KeyMove extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'MOVE'; } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/KeyPersist.php b/lib/Predis/Commands/KeyPersist.php index 66a2fac4..4d238fbe 100644 --- a/lib/Predis/Commands/KeyPersist.php +++ b/lib/Predis/Commands/KeyPersist.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/persist + * @author Daniele Alessandri + */ class KeyPersist extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'PERSIST'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/KeyRandom.php b/lib/Predis/Commands/KeyRandom.php index 3c83ac1f..51c34f61 100644 --- a/lib/Predis/Commands/KeyRandom.php +++ b/lib/Predis/Commands/KeyRandom.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/randomkey + * @author Daniele Alessandri + */ class KeyRandom extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'RANDOMKEY'; } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return $data !== '' ? $data : null; diff --git a/lib/Predis/Commands/KeyRename.php b/lib/Predis/Commands/KeyRename.php index f2b17c4b..e0d16621 100644 --- a/lib/Predis/Commands/KeyRename.php +++ b/lib/Predis/Commands/KeyRename.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/rename + * @author Daniele Alessandri + */ class KeyRename extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'RENAME'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/KeyRenamePreserve.php b/lib/Predis/Commands/KeyRenamePreserve.php index 0f10c5d0..2553aa46 100644 --- a/lib/Predis/Commands/KeyRenamePreserve.php +++ b/lib/Predis/Commands/KeyRenamePreserve.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/renamenx + * @author Daniele Alessandri + */ class KeyRenamePreserve extends KeyRename { + /** + * {@inheritdoc} + */ public function getId() { return 'RENAMENX'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/KeySort.php b/lib/Predis/Commands/KeySort.php index 8966eb18..d3935be1 100644 --- a/lib/Predis/Commands/KeySort.php +++ b/lib/Predis/Commands/KeySort.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/sort + * @author Daniele Alessandri + */ class KeySort extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SORT'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { if (count($arguments) === 1) { @@ -70,6 +80,9 @@ class KeySort extends Command return $query; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { $arguments[0] = "$prefix{$arguments[0]}"; diff --git a/lib/Predis/Commands/KeyTimeToLive.php b/lib/Predis/Commands/KeyTimeToLive.php index 14d84755..471c04f2 100644 --- a/lib/Predis/Commands/KeyTimeToLive.php +++ b/lib/Predis/Commands/KeyTimeToLive.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/ttl + * @author Daniele Alessandri + */ class KeyTimeToLive extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'TTL'; diff --git a/lib/Predis/Commands/KeyType.php b/lib/Predis/Commands/KeyType.php index b6cc6a6e..5187d97e 100644 --- a/lib/Predis/Commands/KeyType.php +++ b/lib/Predis/Commands/KeyType.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/type + * @author Daniele Alessandri + */ class KeyType extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'TYPE'; diff --git a/lib/Predis/Commands/ListIndex.php b/lib/Predis/Commands/ListIndex.php index fa091137..6caf2fd3 100644 --- a/lib/Predis/Commands/ListIndex.php +++ b/lib/Predis/Commands/ListIndex.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lindex + * @author Daniele Alessandri + */ class ListIndex extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LINDEX'; diff --git a/lib/Predis/Commands/ListInsert.php b/lib/Predis/Commands/ListInsert.php index a805f660..1d482786 100644 --- a/lib/Predis/Commands/ListInsert.php +++ b/lib/Predis/Commands/ListInsert.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/linsert + * @author Daniele Alessandri + */ class ListInsert extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LINSERT'; diff --git a/lib/Predis/Commands/ListLength.php b/lib/Predis/Commands/ListLength.php index 6d46d6e0..ca8bb033 100644 --- a/lib/Predis/Commands/ListLength.php +++ b/lib/Predis/Commands/ListLength.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/llen + * @author Daniele Alessandri + */ class ListLength extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LLEN'; diff --git a/lib/Predis/Commands/ListPopFirst.php b/lib/Predis/Commands/ListPopFirst.php index ca78f04f..575d2c3c 100644 --- a/lib/Predis/Commands/ListPopFirst.php +++ b/lib/Predis/Commands/ListPopFirst.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lpop + * @author Daniele Alessandri + */ class ListPopFirst extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LPOP'; diff --git a/lib/Predis/Commands/ListPopFirstBlocking.php b/lib/Predis/Commands/ListPopFirstBlocking.php index ee6243d5..1d1e7d9b 100644 --- a/lib/Predis/Commands/ListPopFirstBlocking.php +++ b/lib/Predis/Commands/ListPopFirstBlocking.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/blpop + * @author Daniele Alessandri + */ class ListPopFirstBlocking extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'BLPOP'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::skipLastArgument($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return $this->checkSameHashForKeys( diff --git a/lib/Predis/Commands/ListPopLast.php b/lib/Predis/Commands/ListPopLast.php index 301e5722..23577fca 100644 --- a/lib/Predis/Commands/ListPopLast.php +++ b/lib/Predis/Commands/ListPopLast.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/rpop + * @author Daniele Alessandri + */ class ListPopLast extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'RPOP'; diff --git a/lib/Predis/Commands/ListPopLastBlocking.php b/lib/Predis/Commands/ListPopLastBlocking.php index 5d5e95ae..777e1eed 100644 --- a/lib/Predis/Commands/ListPopLastBlocking.php +++ b/lib/Predis/Commands/ListPopLastBlocking.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/brpop + * @author Daniele Alessandri + */ class ListPopLastBlocking extends ListPopFirstBlocking { + /** + * {@inheritdoc} + */ public function getId() { return 'BRPOP'; diff --git a/lib/Predis/Commands/ListPopLastPushHead.php b/lib/Predis/Commands/ListPopLastPushHead.php index f6d185b3..7025379b 100644 --- a/lib/Predis/Commands/ListPopLastPushHead.php +++ b/lib/Predis/Commands/ListPopLastPushHead.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/rpoplpush + * @author Daniele Alessandri + */ class ListPopLastPushHead extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'RPOPLPUSH'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return $this->checkSameHashForKeys($this->getArguments()); diff --git a/lib/Predis/Commands/ListPopLastPushHeadBlocking.php b/lib/Predis/Commands/ListPopLastPushHeadBlocking.php index c75488d5..87a043b1 100644 --- a/lib/Predis/Commands/ListPopLastPushHeadBlocking.php +++ b/lib/Predis/Commands/ListPopLastPushHeadBlocking.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/brpoplpush + * @author Daniele Alessandri + */ class ListPopLastPushHeadBlocking extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'BRPOPLPUSH'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::skipLastArgument($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return $this->checkSameHashForKeys( diff --git a/lib/Predis/Commands/ListPushHead.php b/lib/Predis/Commands/ListPushHead.php index 051181f2..02bf6f62 100644 --- a/lib/Predis/Commands/ListPushHead.php +++ b/lib/Predis/Commands/ListPushHead.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lpush + * @author Daniele Alessandri + */ class ListPushHead extends ListPushTail { + /** + * {@inheritdoc} + */ public function getId() { return 'LPUSH'; diff --git a/lib/Predis/Commands/ListPushHeadX.php b/lib/Predis/Commands/ListPushHeadX.php index 30881219..cefb005c 100644 --- a/lib/Predis/Commands/ListPushHeadX.php +++ b/lib/Predis/Commands/ListPushHeadX.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lpushx + * @author Daniele Alessandri + */ class ListPushHeadX extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LPUSHX'; diff --git a/lib/Predis/Commands/ListPushTail.php b/lib/Predis/Commands/ListPushTail.php index 2244f7d0..efb2481f 100644 --- a/lib/Predis/Commands/ListPushTail.php +++ b/lib/Predis/Commands/ListPushTail.php @@ -13,13 +13,23 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/rpush + * @author Daniele Alessandri + */ class ListPushTail extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'RPUSH'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterVariadicValues($arguments); diff --git a/lib/Predis/Commands/ListPushTailX.php b/lib/Predis/Commands/ListPushTailX.php index 2b0f793b..50d93e16 100644 --- a/lib/Predis/Commands/ListPushTailX.php +++ b/lib/Predis/Commands/ListPushTailX.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/rpushx + * @author Daniele Alessandri + */ class ListPushTailX extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'RPUSHX'; diff --git a/lib/Predis/Commands/ListRange.php b/lib/Predis/Commands/ListRange.php index 26d7c254..1539d046 100644 --- a/lib/Predis/Commands/ListRange.php +++ b/lib/Predis/Commands/ListRange.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lrange + * @author Daniele Alessandri + */ class ListRange extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LRANGE'; diff --git a/lib/Predis/Commands/ListRemove.php b/lib/Predis/Commands/ListRemove.php index f3f8897d..924dbedc 100644 --- a/lib/Predis/Commands/ListRemove.php +++ b/lib/Predis/Commands/ListRemove.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lrem + * @author Daniele Alessandri + */ class ListRemove extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LREM'; diff --git a/lib/Predis/Commands/ListSet.php b/lib/Predis/Commands/ListSet.php index ae13afaf..b76888ae 100644 --- a/lib/Predis/Commands/ListSet.php +++ b/lib/Predis/Commands/ListSet.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lset + * @author Daniele Alessandri + */ class ListSet extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LSET'; diff --git a/lib/Predis/Commands/ListTrim.php b/lib/Predis/Commands/ListTrim.php index e9d113e5..9b7d7895 100644 --- a/lib/Predis/Commands/ListTrim.php +++ b/lib/Predis/Commands/ListTrim.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/ltrim + * @author Daniele Alessandri + */ class ListTrim extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LTRIM'; diff --git a/lib/Predis/Commands/PrefixHelpers.php b/lib/Predis/Commands/PrefixHelpers.php index 64d9e957..7110d5a2 100644 --- a/lib/Predis/Commands/PrefixHelpers.php +++ b/lib/Predis/Commands/PrefixHelpers.php @@ -11,8 +11,20 @@ namespace Predis\Commands; +/** + * Class that defines a few helpers method for prefixing keys. + * + * @author Daniele Alessandri + */ class PrefixHelpers { + /** + * Applies the specified prefix to all the arguments. + * + * @param array $arguments Array of arguments. + * @param string $prefix The prefix string. + * @return array + */ public static function multipleKeys(Array $arguments, $prefix) { foreach ($arguments as &$key) { @@ -22,6 +34,13 @@ class PrefixHelpers return $arguments; } + /** + * Applies the specified prefix to all the arguments but the last one. + * + * @param array $arguments Array of arguments. + * @param string $prefix The prefix string. + * @return array + */ public static function skipLastArgument(Array $arguments, $prefix) { $length = count($arguments); diff --git a/lib/Predis/Commands/Processors/ICommandProcessor.php b/lib/Predis/Commands/Processors/ICommandProcessor.php index 141d72fd..7b530700 100644 --- a/lib/Predis/Commands/Processors/ICommandProcessor.php +++ b/lib/Predis/Commands/Processors/ICommandProcessor.php @@ -13,7 +13,17 @@ namespace Predis\Commands\Processors; use Predis\Commands\ICommand; +/** + * A command processor processes commands before they are sent to Redis. + * + * @author Daniele Alessandri + */ interface ICommandProcessor { + /** + * Processes a Redis command. + * + * @param ICommand $command Redis command. + */ public function process(ICommand $command); } diff --git a/lib/Predis/Commands/Processors/ICommandProcessorChain.php b/lib/Predis/Commands/Processors/ICommandProcessorChain.php index a25cdee3..233e2b67 100644 --- a/lib/Predis/Commands/Processors/ICommandProcessorChain.php +++ b/lib/Predis/Commands/Processors/ICommandProcessorChain.php @@ -11,10 +11,32 @@ namespace Predis\Commands\Processors; +/** + * A command processor chain processes a command using multiple chained command + * processor before it is sent to Redis. + * + * @author Daniele Alessandri + */ interface ICommandProcessorChain extends ICommandProcessor, \IteratorAggregate, \Countable { + /** + * Adds a command processor. + * + * @param ICommandProcessor $processor A command processor. + */ + public function add(ICommandProcessor $processor); - public function add(ICommandProcessor $preprocessor); - public function remove(ICommandProcessor $preprocessor); + /** + * Removes a command processor from the chain. + * + * @param ICommandProcessor $processor A command processor. + */ + public function remove(ICommandProcessor $processor); + + /** + * Gets the ordered list of command processors in the chain. + * + * @return array + */ public function getProcessors(); } diff --git a/lib/Predis/Commands/Processors/IProcessingSupport.php b/lib/Predis/Commands/Processors/IProcessingSupport.php index 9c5cdc3a..3e5a2987 100644 --- a/lib/Predis/Commands/Processors/IProcessingSupport.php +++ b/lib/Predis/Commands/Processors/IProcessingSupport.php @@ -11,8 +11,24 @@ namespace Predis\Commands\Processors; +/** + * Defines an object that can process commands using command processors. + * + * @author Daniele Alessandri + */ interface IProcessingSupport { + /** + * Associates a command processor. + * + * @param ICommandProcessor $processor The command processor. + */ public function setProcessor(ICommandProcessor $processor); + + /** + * Returns the associated command processor. + * + * @return ICommandProcessor + */ public function getProcessor(); } diff --git a/lib/Predis/Commands/Processors/KeyPrefixProcessor.php b/lib/Predis/Commands/Processors/KeyPrefixProcessor.php index 4a0aed72..d964d5ec 100644 --- a/lib/Predis/Commands/Processors/KeyPrefixProcessor.php +++ b/lib/Predis/Commands/Processors/KeyPrefixProcessor.php @@ -13,25 +13,47 @@ namespace Predis\Commands\Processors; use Predis\Commands\ICommand; +/** + * Command processor that is used to prefix the keys contained in the arguments + * of a Redis command. + * + * @author Daniele Alessandri + */ class KeyPrefixProcessor implements ICommandProcessor { private $_prefix; + /** + * @param string $prefix Prefix for the keys. + */ public function __construct($prefix) { $this->setPrefix($prefix); } + /** + * Sets a prefix that is applied to all the keys. + * + * @param string $prefix Prefix for the keys. + */ public function setPrefix($prefix) { $this->_prefix = $prefix; } + /** + * Get the current prefix. + * + * @return string + */ public function getPrefix() { return $this->_prefix; } + /** + * {@inheritdoc} + */ public function process(ICommand $command) { $command->prefixKeys($this->_prefix); diff --git a/lib/Predis/Commands/Processors/ProcessorChain.php b/lib/Predis/Commands/Processors/ProcessorChain.php index 39bc94e0..14271a76 100644 --- a/lib/Predis/Commands/Processors/ProcessorChain.php +++ b/lib/Predis/Commands/Processors/ProcessorChain.php @@ -13,10 +13,18 @@ namespace Predis\Commands\Processors; use Predis\Commands\ICommand; +/** + * Default implementation of a command processors chain. + * + * @author Daniele Alessandri + */ class ProcessorChain implements ICommandProcessorChain, \ArrayAccess { private $_processors; + /** + * @param array $processors List of instances of ICommandProcessor. + */ public function __construct($processors = array()) { foreach ($processors as $processor) { @@ -24,11 +32,17 @@ class ProcessorChain implements ICommandProcessorChain, \ArrayAccess } } + /** + * {@inheritdoc} + */ public function add(ICommandProcessor $processor) { $this->_processors[] = $processor; } + /** + * {@inheritdoc} + */ public function remove(ICommandProcessor $processor) { $index = array_search($processor, $this->_processors, true); @@ -37,6 +51,9 @@ class ProcessorChain implements ICommandProcessorChain, \ArrayAccess } } + /** + * {@inheritdoc} + */ public function process(ICommand $command) { $count = count($this->_processors); @@ -45,31 +62,53 @@ class ProcessorChain implements ICommandProcessorChain, \ArrayAccess } } + /** + * {@inheritdoc} + */ public function getProcessors() { return $this->_processors; } + /** + * Returns an iterator over the list of command processor in the chain. + * + * @return \ArrayIterator + */ public function getIterator() { return new \ArrayIterator($this->_processors); } + /** + * Returns the number of command processors in the chain. + * + * @return int + */ public function count() { return count($this->_processors); } + /** + * {@inheritdoc} + */ public function offsetExists($index) { return isset($this->_processors[$index]); } + /** + * {@inheritdoc} + */ public function offsetGet($index) { return $this->_processors[$index]; } + /** + * {@inheritdoc} + */ public function offsetSet($index, $processor) { if (!$processor instanceof ICommandProcessor) { @@ -82,6 +121,9 @@ class ProcessorChain implements ICommandProcessorChain, \ArrayAccess $this->_processors[$index] = $processor; } + /** + * {@inheritdoc} + */ public function offsetUnset($index) { unset($this->_processors[$index]); diff --git a/lib/Predis/Commands/PubSubPublish.php b/lib/Predis/Commands/PubSubPublish.php index b57dc005..91dc3e76 100644 --- a/lib/Predis/Commands/PubSubPublish.php +++ b/lib/Predis/Commands/PubSubPublish.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/publish + * @author Daniele Alessandri + */ class PubSubPublish extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'PUBLISH'; } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/PubSubSubscribe.php b/lib/Predis/Commands/PubSubSubscribe.php index 0012e9c3..e733b5ef 100644 --- a/lib/Predis/Commands/PubSubSubscribe.php +++ b/lib/Predis/Commands/PubSubSubscribe.php @@ -13,23 +13,39 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/subscribe + * @author Daniele Alessandri + */ class PubSubSubscribe extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SUBSCRIBE'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterArrayArguments($arguments); } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/PubSubSubscribeByPattern.php b/lib/Predis/Commands/PubSubSubscribeByPattern.php index 58ef7734..897b0bef 100644 --- a/lib/Predis/Commands/PubSubSubscribeByPattern.php +++ b/lib/Predis/Commands/PubSubSubscribeByPattern.php @@ -13,8 +13,15 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/psubscribe + * @author Daniele Alessandri + */ class PubSubSubscribeByPattern extends PubSubSubscribe { + /** + * {@inheritdoc} + */ public function getId() { return 'PSUBSCRIBE'; diff --git a/lib/Predis/Commands/PubSubUnsubscribe.php b/lib/Predis/Commands/PubSubUnsubscribe.php index 3b711af1..5b788f6b 100644 --- a/lib/Predis/Commands/PubSubUnsubscribe.php +++ b/lib/Predis/Commands/PubSubUnsubscribe.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/unsubscribe + * @author Daniele Alessandri + */ class PubSubUnsubscribe extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'UNSUBSCRIBE'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/PubSubUnsubscribeByPattern.php b/lib/Predis/Commands/PubSubUnsubscribeByPattern.php index 412ee525..5129c02f 100644 --- a/lib/Predis/Commands/PubSubUnsubscribeByPattern.php +++ b/lib/Predis/Commands/PubSubUnsubscribeByPattern.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/punsubscribe + * @author Daniele Alessandri + */ class PubSubUnsubscribeByPattern extends PubSubUnsubscribe { + /** + * {@inheritdoc} + */ public function getId() { return 'PUNSUBSCRIBE'; diff --git a/lib/Predis/Commands/ScriptedCommand.php b/lib/Predis/Commands/ScriptedCommand.php index 51721e01..769457a1 100644 --- a/lib/Predis/Commands/ScriptedCommand.php +++ b/lib/Predis/Commands/ScriptedCommand.php @@ -11,10 +11,27 @@ namespace Predis\Commands; +/** + * Base class used to implement an higher level abstraction for "virtual" + * commands based on EVAL. + * + * @link http://redis.io/commands/eval + * @author Daniele Alessandri + */ abstract class ScriptedCommand extends ServerEval { + /** + * Gets the body of a Lua script. + * + * @return string + */ public abstract function getScript(); + /* + * Gets the number of arguments that should be considered as keys. + * + * @return int + */ protected function keysCount() { // The default behaviour for the base class is to use all the arguments @@ -22,11 +39,17 @@ abstract class ScriptedCommand extends ServerEval return count($this->getArguments()); } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return array_merge(array($this->getScript(), $this->keysCount()), $arguments); } + /** + * {@inheritdoc} + */ protected function getKeys() { return array_slice($this->getArguments(), 2, $this->keysCount()); diff --git a/lib/Predis/Commands/ServerBackgroundRewriteAOF.php b/lib/Predis/Commands/ServerBackgroundRewriteAOF.php index 8085e8fe..a10b3c75 100644 --- a/lib/Predis/Commands/ServerBackgroundRewriteAOF.php +++ b/lib/Predis/Commands/ServerBackgroundRewriteAOF.php @@ -11,23 +11,39 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/bgrewriteaof + * @author Daniele Alessandri + */ class ServerBackgroundRewriteAOF extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'BGREWRITEAOF'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return $data == 'Background append only file rewriting started'; diff --git a/lib/Predis/Commands/ServerBackgroundSave.php b/lib/Predis/Commands/ServerBackgroundSave.php index aa93cfed..fe600e4a 100644 --- a/lib/Predis/Commands/ServerBackgroundSave.php +++ b/lib/Predis/Commands/ServerBackgroundSave.php @@ -11,23 +11,39 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/bgsave + * @author Daniele Alessandri + */ class ServerBackgroundSave extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'BGSAVE'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { if ($data == 'Background saving started') { diff --git a/lib/Predis/Commands/ServerClient.php b/lib/Predis/Commands/ServerClient.php index 6eeca82e..73f7e2e0 100644 --- a/lib/Predis/Commands/ServerClient.php +++ b/lib/Predis/Commands/ServerClient.php @@ -11,23 +11,39 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/client + * @author Daniele Alessandri + */ class ServerClient extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'CLIENT'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { $args = array_change_key_case($this->getArguments(), CASE_UPPER); @@ -41,6 +57,13 @@ class ServerClient extends Command } } + /** + * Parses the reply buffer and returns the list of clients returned by + * the CLIENT LIST command. + * + * @param string $data Reply buffer + * @return array + */ protected function parseClientList($data) { $clients = array(); diff --git a/lib/Predis/Commands/ServerConfig.php b/lib/Predis/Commands/ServerConfig.php index 06c8f10a..ef8f3102 100644 --- a/lib/Predis/Commands/ServerConfig.php +++ b/lib/Predis/Commands/ServerConfig.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/config + * @author Daniele Alessandri + */ class ServerConfig extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'CONFIG'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerDatabaseSize.php b/lib/Predis/Commands/ServerDatabaseSize.php index 334d4e99..7ff75731 100644 --- a/lib/Predis/Commands/ServerDatabaseSize.php +++ b/lib/Predis/Commands/ServerDatabaseSize.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/dbsize + * @author Daniele Alessandri + */ class ServerDatabaseSize extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'DBSIZE'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerEval.php b/lib/Predis/Commands/ServerEval.php index 9cfd789e..f6b60deb 100644 --- a/lib/Predis/Commands/ServerEval.php +++ b/lib/Predis/Commands/ServerEval.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/eval + * @author Daniele Alessandri + */ class ServerEval extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'EVAL'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { $arguments = $this->getArguments(); @@ -29,6 +39,9 @@ class ServerEval extends Command return $arguments; } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerEvalSHA.php b/lib/Predis/Commands/ServerEvalSHA.php index 8315422a..2e546fea 100644 --- a/lib/Predis/Commands/ServerEvalSHA.php +++ b/lib/Predis/Commands/ServerEvalSHA.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/evalsha + * @author Daniele Alessandri + */ class ServerEvalSHA extends ServerEval { + /** + * {@inheritdoc} + */ public function getId() { return 'EVALSHA'; diff --git a/lib/Predis/Commands/ServerFlushAll.php b/lib/Predis/Commands/ServerFlushAll.php index 887500af..e9545f20 100644 --- a/lib/Predis/Commands/ServerFlushAll.php +++ b/lib/Predis/Commands/ServerFlushAll.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/flushall + * @author Daniele Alessandri + */ class ServerFlushAll extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'FLUSHALL'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerFlushDatabase.php b/lib/Predis/Commands/ServerFlushDatabase.php index a68fafde..9454e6a6 100644 --- a/lib/Predis/Commands/ServerFlushDatabase.php +++ b/lib/Predis/Commands/ServerFlushDatabase.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/flushdb + * @author Daniele Alessandri + */ class ServerFlushDatabase extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'FLUSHDB'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerInfo.php b/lib/Predis/Commands/ServerInfo.php index 8db601a9..bc58f41c 100644 --- a/lib/Predis/Commands/ServerInfo.php +++ b/lib/Predis/Commands/ServerInfo.php @@ -11,23 +11,39 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/info + * @author Daniele Alessandri + */ class ServerInfo extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'INFO'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { $info = array(); @@ -55,6 +71,12 @@ class ServerInfo extends Command return $info; } + /** + * Parses the reply buffer and extracts the statistics of each logical DB. + * + * @param string $str Reply buffer. + * @return array + */ protected function parseDatabaseStats($str) { $db = array(); @@ -67,6 +89,12 @@ class ServerInfo extends Command return $db; } + /** + * Parses the reply buffer and extracts the allocation statistics. + * + * @param string $str Reply buffer. + * @return array + */ protected function parseAllocationStats($str) { $stats = array(); diff --git a/lib/Predis/Commands/ServerInfoV26x.php b/lib/Predis/Commands/ServerInfoV26x.php index 82f36999..cc58c0ee 100644 --- a/lib/Predis/Commands/ServerInfoV26x.php +++ b/lib/Predis/Commands/ServerInfoV26x.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/info + * @author Daniele Alessandri + */ class ServerInfoV26x extends ServerInfo { + /** + * {@inheritdoc} + */ public function parseResponse($data) { $info = array(); diff --git a/lib/Predis/Commands/ServerLastSave.php b/lib/Predis/Commands/ServerLastSave.php index be31ffea..01ce262d 100644 --- a/lib/Predis/Commands/ServerLastSave.php +++ b/lib/Predis/Commands/ServerLastSave.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/lastsave + * @author Daniele Alessandri + */ class ServerLastSave extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'LASTSAVE'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerMonitor.php b/lib/Predis/Commands/ServerMonitor.php index f1ac2795..d50c35e3 100644 --- a/lib/Predis/Commands/ServerMonitor.php +++ b/lib/Predis/Commands/ServerMonitor.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/monitor + * @author Daniele Alessandri + */ class ServerMonitor extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'MONITOR'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerObject.php b/lib/Predis/Commands/ServerObject.php index 2e0b6bd8..a77bc992 100644 --- a/lib/Predis/Commands/ServerObject.php +++ b/lib/Predis/Commands/ServerObject.php @@ -13,18 +13,31 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/object + * @author Daniele Alessandri + */ class ServerObject extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'OBJECT'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerSave.php b/lib/Predis/Commands/ServerSave.php index 65fd99ce..51a7a21c 100644 --- a/lib/Predis/Commands/ServerSave.php +++ b/lib/Predis/Commands/ServerSave.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/save + * @author Daniele Alessandri + */ class ServerSave extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SAVE'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerShutdown.php b/lib/Predis/Commands/ServerShutdown.php index 26f54fff..61e2b0e6 100644 --- a/lib/Predis/Commands/ServerShutdown.php +++ b/lib/Predis/Commands/ServerShutdown.php @@ -11,17 +11,30 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/shutdown + * @author Daniele Alessandri + */ class ServerShutdown extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SHUTDOWN'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/ServerSlaveOf.php b/lib/Predis/Commands/ServerSlaveOf.php index 86d67875..91f3bcc9 100644 --- a/lib/Predis/Commands/ServerSlaveOf.php +++ b/lib/Predis/Commands/ServerSlaveOf.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/slaveof + * @author Daniele Alessandri + */ class ServerSlaveOf extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SLAVEOF'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { if (count($arguments) === 0 || $arguments[0] === 'NO ONE') { @@ -27,11 +37,17 @@ class ServerSlaveOf extends Command return $arguments; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/SetAdd.php b/lib/Predis/Commands/SetAdd.php index 98d51ec4..0e99e9de 100644 --- a/lib/Predis/Commands/SetAdd.php +++ b/lib/Predis/Commands/SetAdd.php @@ -13,18 +13,31 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/sadd + * @author Daniele Alessandri + */ class SetAdd extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SADD'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterVariadicValues($arguments); } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/SetCardinality.php b/lib/Predis/Commands/SetCardinality.php index b487ca1b..ecbb3162 100644 --- a/lib/Predis/Commands/SetCardinality.php +++ b/lib/Predis/Commands/SetCardinality.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/scard + * @author Daniele Alessandri + */ class SetCardinality extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SCARD'; diff --git a/lib/Predis/Commands/SetDifference.php b/lib/Predis/Commands/SetDifference.php index 065816a4..a67b1009 100644 --- a/lib/Predis/Commands/SetDifference.php +++ b/lib/Predis/Commands/SetDifference.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/sdiff + * @author Daniele Alessandri + */ class SetDifference extends SetIntersection { + /** + * {@inheritdoc} + */ public function getId() { return 'SDIFF'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); diff --git a/lib/Predis/Commands/SetDifferenceStore.php b/lib/Predis/Commands/SetDifferenceStore.php index 1c92cd69..d0f29721 100644 --- a/lib/Predis/Commands/SetDifferenceStore.php +++ b/lib/Predis/Commands/SetDifferenceStore.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/sdiffstore + * @author Daniele Alessandri + */ class SetDifferenceStore extends SetIntersectionStore { + /** + * {@inheritdoc} + */ public function getId() { return 'SDIFFSTORE'; diff --git a/lib/Predis/Commands/SetIntersection.php b/lib/Predis/Commands/SetIntersection.php index 711418d5..8f548f7d 100644 --- a/lib/Predis/Commands/SetIntersection.php +++ b/lib/Predis/Commands/SetIntersection.php @@ -13,23 +13,39 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/sinter + * @author Daniele Alessandri + */ class SetIntersection extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SINTER'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterArrayArguments($arguments); } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return $this->checkSameHashForKeys($this->getArguments()); diff --git a/lib/Predis/Commands/SetIntersectionStore.php b/lib/Predis/Commands/SetIntersectionStore.php index 4e2e8b35..2782a5d0 100644 --- a/lib/Predis/Commands/SetIntersectionStore.php +++ b/lib/Predis/Commands/SetIntersectionStore.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/sinterstore + * @author Daniele Alessandri + */ class SetIntersectionStore extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SINTERSTORE'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { if (count($arguments) === 2 && is_array($arguments[1])) { @@ -27,11 +37,17 @@ class SetIntersectionStore extends Command return $arguments; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return $this->checkSameHashForKeys($this->getArguments()); diff --git a/lib/Predis/Commands/SetIsMember.php b/lib/Predis/Commands/SetIsMember.php index fe618af8..ce6f69f5 100644 --- a/lib/Predis/Commands/SetIsMember.php +++ b/lib/Predis/Commands/SetIsMember.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/sismember + * @author Daniele Alessandri + */ class SetIsMember extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SISMEMBER'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/SetMembers.php b/lib/Predis/Commands/SetMembers.php index a992650a..c3fc5d02 100644 --- a/lib/Predis/Commands/SetMembers.php +++ b/lib/Predis/Commands/SetMembers.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/smembers + * @author Daniele Alessandri + */ class SetMembers extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SMEMBERS'; diff --git a/lib/Predis/Commands/SetMove.php b/lib/Predis/Commands/SetMove.php index a8f58959..38284c5d 100644 --- a/lib/Predis/Commands/SetMove.php +++ b/lib/Predis/Commands/SetMove.php @@ -11,23 +11,39 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/smove + * @author Daniele Alessandri + */ class SetMove extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SMOVE'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::skipLastArgument($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/SetPop.php b/lib/Predis/Commands/SetPop.php index dfa84235..8e094620 100644 --- a/lib/Predis/Commands/SetPop.php +++ b/lib/Predis/Commands/SetPop.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/spop + * @author Daniele Alessandri + */ class SetPop extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SPOP'; diff --git a/lib/Predis/Commands/SetRandomMember.php b/lib/Predis/Commands/SetRandomMember.php index 5e514997..0289b69f 100644 --- a/lib/Predis/Commands/SetRandomMember.php +++ b/lib/Predis/Commands/SetRandomMember.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/srandmember + * @author Daniele Alessandri + */ class SetRandomMember extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SRANDMEMBER'; diff --git a/lib/Predis/Commands/SetRemove.php b/lib/Predis/Commands/SetRemove.php index 7fbf9dfb..fa696b0c 100644 --- a/lib/Predis/Commands/SetRemove.php +++ b/lib/Predis/Commands/SetRemove.php @@ -13,18 +13,31 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/srem + * @author Daniele Alessandri + */ class SetRemove extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SREM'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterVariadicValues($arguments); } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/SetUnion.php b/lib/Predis/Commands/SetUnion.php index 802b7dca..bbb1ff0f 100644 --- a/lib/Predis/Commands/SetUnion.php +++ b/lib/Predis/Commands/SetUnion.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/sunion + * @author Daniele Alessandri + */ class SetUnion extends SetIntersection { + /** + * {@inheritdoc} + */ public function getId() { return 'SUNION'; diff --git a/lib/Predis/Commands/SetUnionStore.php b/lib/Predis/Commands/SetUnionStore.php index 591f9ad5..0259af13 100644 --- a/lib/Predis/Commands/SetUnionStore.php +++ b/lib/Predis/Commands/SetUnionStore.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/sunionstore + * @author Daniele Alessandri + */ class SetUnionStore extends SetIntersectionStore { + /** + * {@inheritdoc} + */ public function getId() { return 'SUNIONSTORE'; diff --git a/lib/Predis/Commands/StringAppend.php b/lib/Predis/Commands/StringAppend.php index d0bc414e..06556d88 100644 --- a/lib/Predis/Commands/StringAppend.php +++ b/lib/Predis/Commands/StringAppend.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/append + * @author Daniele Alessandri + */ class StringAppend extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'APPEND'; diff --git a/lib/Predis/Commands/StringDecrement.php b/lib/Predis/Commands/StringDecrement.php index 4afad619..3db6f6c9 100644 --- a/lib/Predis/Commands/StringDecrement.php +++ b/lib/Predis/Commands/StringDecrement.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/decr + * @author Daniele Alessandri + */ class StringDecrement extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'DECR'; diff --git a/lib/Predis/Commands/StringDecrementBy.php b/lib/Predis/Commands/StringDecrementBy.php index 1d4f070c..5a7ba26d 100644 --- a/lib/Predis/Commands/StringDecrementBy.php +++ b/lib/Predis/Commands/StringDecrementBy.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/decrby + * @author Daniele Alessandri + */ class StringDecrementBy extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'DECRBY'; diff --git a/lib/Predis/Commands/StringGet.php b/lib/Predis/Commands/StringGet.php index 6a3e34d9..9285faac 100644 --- a/lib/Predis/Commands/StringGet.php +++ b/lib/Predis/Commands/StringGet.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/get + * @author Daniele Alessandri + */ class StringGet extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'GET'; diff --git a/lib/Predis/Commands/StringGetBit.php b/lib/Predis/Commands/StringGetBit.php index 79cdcd3d..a9d4ef5e 100644 --- a/lib/Predis/Commands/StringGetBit.php +++ b/lib/Predis/Commands/StringGetBit.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/getbit + * @author Daniele Alessandri + */ class StringGetBit extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'GETBIT'; diff --git a/lib/Predis/Commands/StringGetMultiple.php b/lib/Predis/Commands/StringGetMultiple.php index cc942e6f..49d1425d 100644 --- a/lib/Predis/Commands/StringGetMultiple.php +++ b/lib/Predis/Commands/StringGetMultiple.php @@ -13,23 +13,39 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/mget + * @author Daniele Alessandri + */ class StringGetMultiple extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'MGET'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterArrayArguments($arguments); } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return $this->checkSameHashForKeys($this->getArguments()); diff --git a/lib/Predis/Commands/StringGetRange.php b/lib/Predis/Commands/StringGetRange.php index 4fd0718c..698a6bb7 100644 --- a/lib/Predis/Commands/StringGetRange.php +++ b/lib/Predis/Commands/StringGetRange.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/getrange + * @author Daniele Alessandri + */ class StringGetRange extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'GETRANGE'; diff --git a/lib/Predis/Commands/StringGetSet.php b/lib/Predis/Commands/StringGetSet.php index 44d9c293..df5f4122 100644 --- a/lib/Predis/Commands/StringGetSet.php +++ b/lib/Predis/Commands/StringGetSet.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/getset + * @author Daniele Alessandri + */ class StringGetSet extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'GETSET'; diff --git a/lib/Predis/Commands/StringIncrement.php b/lib/Predis/Commands/StringIncrement.php index 5b8f7425..f4d6dff9 100644 --- a/lib/Predis/Commands/StringIncrement.php +++ b/lib/Predis/Commands/StringIncrement.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/incr + * @author Daniele Alessandri + */ class StringIncrement extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'INCR'; diff --git a/lib/Predis/Commands/StringIncrementBy.php b/lib/Predis/Commands/StringIncrementBy.php index aac04055..a0e97500 100644 --- a/lib/Predis/Commands/StringIncrementBy.php +++ b/lib/Predis/Commands/StringIncrementBy.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/incrby + * @author Daniele Alessandri + */ class StringIncrementBy extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'INCRBY'; diff --git a/lib/Predis/Commands/StringSet.php b/lib/Predis/Commands/StringSet.php index 377de535..68d08f53 100644 --- a/lib/Predis/Commands/StringSet.php +++ b/lib/Predis/Commands/StringSet.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/set + * @author Daniele Alessandri + */ class StringSet extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SET'; diff --git a/lib/Predis/Commands/StringSetBit.php b/lib/Predis/Commands/StringSetBit.php index 4bd78a09..f6bdc1fc 100644 --- a/lib/Predis/Commands/StringSetBit.php +++ b/lib/Predis/Commands/StringSetBit.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/setbit + * @author Daniele Alessandri + */ class StringSetBit extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SETBIT'; diff --git a/lib/Predis/Commands/StringSetExpire.php b/lib/Predis/Commands/StringSetExpire.php index 46b17c91..47fcfd1f 100644 --- a/lib/Predis/Commands/StringSetExpire.php +++ b/lib/Predis/Commands/StringSetExpire.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/setex + * @author Daniele Alessandri + */ class StringSetExpire extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SETEX'; diff --git a/lib/Predis/Commands/StringSetMultiple.php b/lib/Predis/Commands/StringSetMultiple.php index 4fd36974..ffbbd9ed 100644 --- a/lib/Predis/Commands/StringSetMultiple.php +++ b/lib/Predis/Commands/StringSetMultiple.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/mset + * @author Daniele Alessandri + */ class StringSetMultiple extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'MSET'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { if (count($arguments) === 1 && is_array($arguments[0])) { @@ -35,6 +45,9 @@ class StringSetMultiple extends Command return $arguments; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { $length = count($arguments); @@ -46,6 +59,9 @@ class StringSetMultiple extends Command return $arguments; } + /** + * {@inheritdoc} + */ protected function canBeHashed() { $args = $this->getArguments(); diff --git a/lib/Predis/Commands/StringSetMultiplePreserve.php b/lib/Predis/Commands/StringSetMultiplePreserve.php index d8e67ef7..bbe397d6 100644 --- a/lib/Predis/Commands/StringSetMultiplePreserve.php +++ b/lib/Predis/Commands/StringSetMultiplePreserve.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/msetnx + * @author Daniele Alessandri + */ class StringSetMultiplePreserve extends StringSetMultiple { + /** + * {@inheritdoc} + */ public function getId() { return 'MSETNX'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/StringSetPreserve.php b/lib/Predis/Commands/StringSetPreserve.php index e627ecb6..04463502 100644 --- a/lib/Predis/Commands/StringSetPreserve.php +++ b/lib/Predis/Commands/StringSetPreserve.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/setnx + * @author Daniele Alessandri + */ class StringSetPreserve extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SETNX'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/StringSetRange.php b/lib/Predis/Commands/StringSetRange.php index 7106efd9..d848cd37 100644 --- a/lib/Predis/Commands/StringSetRange.php +++ b/lib/Predis/Commands/StringSetRange.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/setrange + * @author Daniele Alessandri + */ class StringSetRange extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SETRANGE'; diff --git a/lib/Predis/Commands/StringStrlen.php b/lib/Predis/Commands/StringStrlen.php index 1db79368..782d3f20 100644 --- a/lib/Predis/Commands/StringStrlen.php +++ b/lib/Predis/Commands/StringStrlen.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/strlen + * @author Daniele Alessandri + */ class StringStrlen extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'STRLEN'; diff --git a/lib/Predis/Commands/StringSubstr.php b/lib/Predis/Commands/StringSubstr.php index aeaa8d7d..9725d208 100644 --- a/lib/Predis/Commands/StringSubstr.php +++ b/lib/Predis/Commands/StringSubstr.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/substr + * @author Daniele Alessandri + */ class StringSubstr extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'SUBSTR'; diff --git a/lib/Predis/Commands/TransactionDiscard.php b/lib/Predis/Commands/TransactionDiscard.php index 8c75da3c..4a3b734b 100644 --- a/lib/Predis/Commands/TransactionDiscard.php +++ b/lib/Predis/Commands/TransactionDiscard.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/discard + * @author Daniele Alessandri + */ class TransactionDiscard extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'DISCARD'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/TransactionExec.php b/lib/Predis/Commands/TransactionExec.php index 12dd0b36..d245cbd0 100644 --- a/lib/Predis/Commands/TransactionExec.php +++ b/lib/Predis/Commands/TransactionExec.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/exec + * @author Daniele Alessandri + */ class TransactionExec extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'EXEC'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/TransactionMulti.php b/lib/Predis/Commands/TransactionMulti.php index dfd2419a..c9bde22c 100644 --- a/lib/Predis/Commands/TransactionMulti.php +++ b/lib/Predis/Commands/TransactionMulti.php @@ -11,18 +11,31 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/multi + * @author Daniele Alessandri + */ class TransactionMulti extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'MULTI'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; diff --git a/lib/Predis/Commands/TransactionUnwatch.php b/lib/Predis/Commands/TransactionUnwatch.php index 199d9e22..c4e5b0b6 100644 --- a/lib/Predis/Commands/TransactionUnwatch.php +++ b/lib/Predis/Commands/TransactionUnwatch.php @@ -11,23 +11,39 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/unwatch + * @author Daniele Alessandri + */ class TransactionUnwatch extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'UNWATCH'; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { /* NOOP */ } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/TransactionWatch.php b/lib/Predis/Commands/TransactionWatch.php index b7138c94..15c7c72d 100644 --- a/lib/Predis/Commands/TransactionWatch.php +++ b/lib/Predis/Commands/TransactionWatch.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/watch + * @author Daniele Alessandri + */ class TransactionWatch extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'WATCH'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { if (isset($arguments[0]) && is_array($arguments[0])) { @@ -27,16 +37,25 @@ class TransactionWatch extends Command return $arguments; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { return PrefixHelpers::multipleKeys($arguments, $prefix); } + /** + * {@inheritdoc} + */ protected function canBeHashed() { return false; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/ZSetAdd.php b/lib/Predis/Commands/ZSetAdd.php index 12fb44a6..3db17aa7 100644 --- a/lib/Predis/Commands/ZSetAdd.php +++ b/lib/Predis/Commands/ZSetAdd.php @@ -13,18 +13,31 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/zadd + * @author Daniele Alessandri + */ class ZSetAdd extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZADD'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterVariadicValues($arguments); } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/ZSetCardinality.php b/lib/Predis/Commands/ZSetCardinality.php index f4505620..4a3e1289 100644 --- a/lib/Predis/Commands/ZSetCardinality.php +++ b/lib/Predis/Commands/ZSetCardinality.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zcard + * @author Daniele Alessandri + */ class ZSetCardinality extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZCARD'; diff --git a/lib/Predis/Commands/ZSetCount.php b/lib/Predis/Commands/ZSetCount.php index b81ff934..70ee77eb 100644 --- a/lib/Predis/Commands/ZSetCount.php +++ b/lib/Predis/Commands/ZSetCount.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zcount + * @author Daniele Alessandri + */ class ZSetCount extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZCOUNT'; diff --git a/lib/Predis/Commands/ZSetIncrementBy.php b/lib/Predis/Commands/ZSetIncrementBy.php index acd098a6..83188a84 100644 --- a/lib/Predis/Commands/ZSetIncrementBy.php +++ b/lib/Predis/Commands/ZSetIncrementBy.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zincrby + * @author Daniele Alessandri + */ class ZSetIncrementBy extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZINCRBY'; diff --git a/lib/Predis/Commands/ZSetIntersectionStore.php b/lib/Predis/Commands/ZSetIntersectionStore.php index 87a7d550..23afdb8f 100644 --- a/lib/Predis/Commands/ZSetIntersectionStore.php +++ b/lib/Predis/Commands/ZSetIntersectionStore.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zinterstore + * @author Daniele Alessandri + */ class ZSetIntersectionStore extends ZSetUnionStore { + /** + * {@inheritdoc} + */ public function getId() { return 'ZINTERSTORE'; diff --git a/lib/Predis/Commands/ZSetRange.php b/lib/Predis/Commands/ZSetRange.php index 7ad68835..c45f2d50 100644 --- a/lib/Predis/Commands/ZSetRange.php +++ b/lib/Predis/Commands/ZSetRange.php @@ -13,13 +13,23 @@ namespace Predis\Commands; use Predis\Iterators\MultiBulkResponseTuple; +/** + * @link http://redis.io/commands/zrange + * @author Daniele Alessandri + */ class ZSetRange extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZRANGE'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { if (count($arguments) === 4) { @@ -40,6 +50,12 @@ class ZSetRange extends Command return $arguments; } + /** + * Return a list of options and modifiers compatible with Redis. + * + * @param array $options List of options. + * @return array + */ protected function prepareOptions($options) { $opts = array_change_key_case($options, CASE_UPPER); @@ -52,6 +68,11 @@ class ZSetRange extends Command return $finalizedOpts; } + /** + * Checks for the presence of the WITHSCORES modifier. + * + * @return Boolean + */ protected function withScores() { $arguments = $this->getArguments(); @@ -63,6 +84,9 @@ class ZSetRange extends Command return strtoupper($arguments[3]) === 'WITHSCORES'; } + /** + * {@inheritdoc} + */ public function parseResponse($data) { if ($this->withScores()) { diff --git a/lib/Predis/Commands/ZSetRangeByScore.php b/lib/Predis/Commands/ZSetRangeByScore.php index 0e6d9d32..bb25c3dc 100644 --- a/lib/Predis/Commands/ZSetRangeByScore.php +++ b/lib/Predis/Commands/ZSetRangeByScore.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zrangebyscore + * @author Daniele Alessandri + */ class ZSetRangeByScore extends ZSetRange { + /** + * {@inheritdoc} + */ public function getId() { return 'ZRANGEBYSCORE'; } + /** + * {@inheritdoc} + */ protected function prepareOptions($options) { $opts = array_change_key_case($options, CASE_UPPER); @@ -34,6 +44,9 @@ class ZSetRangeByScore extends ZSetRange return array_merge($finalizedOpts, parent::prepareOptions($options)); } + /** + * {@inheritdoc} + */ protected function withScores() { $arguments = $this->getArguments(); diff --git a/lib/Predis/Commands/ZSetRank.php b/lib/Predis/Commands/ZSetRank.php index acf2e766..5e6721d4 100644 --- a/lib/Predis/Commands/ZSetRank.php +++ b/lib/Predis/Commands/ZSetRank.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zrank + * @author Daniele Alessandri + */ class ZSetRank extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZRANK'; diff --git a/lib/Predis/Commands/ZSetRemove.php b/lib/Predis/Commands/ZSetRemove.php index a9213e95..c786ad92 100644 --- a/lib/Predis/Commands/ZSetRemove.php +++ b/lib/Predis/Commands/ZSetRemove.php @@ -13,18 +13,31 @@ namespace Predis\Commands; use Predis\Helpers; +/** + * @link http://redis.io/commands/zrem + * @author Daniele Alessandri + */ class ZSetRemove extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZREM'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { return Helpers::filterVariadicValues($arguments); } + /** + * {@inheritdoc} + */ public function parseResponse($data) { return (bool) $data; diff --git a/lib/Predis/Commands/ZSetRemoveRangeByRank.php b/lib/Predis/Commands/ZSetRemoveRangeByRank.php index fedbb261..f5192b76 100644 --- a/lib/Predis/Commands/ZSetRemoveRangeByRank.php +++ b/lib/Predis/Commands/ZSetRemoveRangeByRank.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zremrangebyrank + * @author Daniele Alessandri + */ class ZSetRemoveRangeByRank extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZREMRANGEBYRANK'; diff --git a/lib/Predis/Commands/ZSetRemoveRangeByScore.php b/lib/Predis/Commands/ZSetRemoveRangeByScore.php index 42a59846..95ff2766 100644 --- a/lib/Predis/Commands/ZSetRemoveRangeByScore.php +++ b/lib/Predis/Commands/ZSetRemoveRangeByScore.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zremrangebyscore + * @author Daniele Alessandri + */ class ZSetRemoveRangeByScore extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZREMRANGEBYSCORE'; diff --git a/lib/Predis/Commands/ZSetReverseRange.php b/lib/Predis/Commands/ZSetReverseRange.php index cb02eb84..0e4f4162 100644 --- a/lib/Predis/Commands/ZSetReverseRange.php +++ b/lib/Predis/Commands/ZSetReverseRange.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zrevrange + * @author Daniele Alessandri + */ class ZSetReverseRange extends ZSetRange { + /** + * {@inheritdoc} + */ public function getId() { return 'ZREVRANGE'; diff --git a/lib/Predis/Commands/ZSetReverseRangeByScore.php b/lib/Predis/Commands/ZSetReverseRangeByScore.php index 55b25ef3..16376556 100644 --- a/lib/Predis/Commands/ZSetReverseRangeByScore.php +++ b/lib/Predis/Commands/ZSetReverseRangeByScore.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zrevrangebyscore + * @author Daniele Alessandri + */ class ZSetReverseRangeByScore extends ZSetRangeByScore { + /** + * {@inheritdoc} + */ public function getId() { return 'ZREVRANGEBYSCORE'; diff --git a/lib/Predis/Commands/ZSetReverseRank.php b/lib/Predis/Commands/ZSetReverseRank.php index 3a26670b..6689154b 100644 --- a/lib/Predis/Commands/ZSetReverseRank.php +++ b/lib/Predis/Commands/ZSetReverseRank.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zrevrank + * @author Daniele Alessandri + */ class ZSetReverseRank extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZREVRANK'; diff --git a/lib/Predis/Commands/ZSetScore.php b/lib/Predis/Commands/ZSetScore.php index 7cca76e8..842026cc 100644 --- a/lib/Predis/Commands/ZSetScore.php +++ b/lib/Predis/Commands/ZSetScore.php @@ -11,8 +11,15 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zscore + * @author Daniele Alessandri + */ class ZSetScore extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZSCORE'; diff --git a/lib/Predis/Commands/ZSetUnionStore.php b/lib/Predis/Commands/ZSetUnionStore.php index a81db870..84d9c3a5 100644 --- a/lib/Predis/Commands/ZSetUnionStore.php +++ b/lib/Predis/Commands/ZSetUnionStore.php @@ -11,13 +11,23 @@ namespace Predis\Commands; +/** + * @link http://redis.io/commands/zunionstore + * @author Daniele Alessandri + */ class ZSetUnionStore extends Command { + /** + * {@inheritdoc} + */ public function getId() { return 'ZUNIONSTORE'; } + /** + * {@inheritdoc} + */ protected function filterArguments(Array $arguments) { $options = array(); @@ -37,6 +47,12 @@ class ZSetUnionStore extends Command return array_merge($arguments, $options); } + /** + * Return a list of options and modifiers compatible with Redis. + * + * @param array $options List of options. + * @return array + */ private function prepareOptions($options) { $opts = array_change_key_case($options, CASE_UPPER); @@ -57,6 +73,9 @@ class ZSetUnionStore extends Command return $finalizedOpts; } + /** + * {@inheritdoc} + */ protected function onPrefixKeys(Array $arguments, $prefix) { $arguments[0] = "$prefix{$arguments[0]}"; @@ -69,6 +88,9 @@ class ZSetUnionStore extends Command return $arguments; } + /** + * {@inheritdoc} + */ protected function canBeHashed() { $args = $this->getArguments(); diff --git a/lib/Predis/CommunicationException.php b/lib/Predis/CommunicationException.php index 9e201b85..fa09a8a5 100644 --- a/lib/Predis/CommunicationException.php +++ b/lib/Predis/CommunicationException.php @@ -13,22 +13,44 @@ namespace Predis; use Predis\Network\IConnectionSingle; +/** + * Base exception class for network-related errors. + * + * @author Daniele Alessandri + */ abstract class CommunicationException extends PredisException { private $_connection; - public function __construct(IConnectionSingle $connection, $message = null, $code = null, \Exception $innerException = null) + /** + * @param IConnectionSingle $connection Connection that generated the exception. + * @param string $message Error message. + * @param int $code Error code. + * @param \Exception $innerException Inner exception for wrapping the original error. + */ + public function __construct(IConnectionSingle $connection, + $message = null, $code = null, \Exception $innerException = null) { parent::__construct($message, $code, $innerException); $this->_connection = $connection; } + /** + * Gets the connection that generated the exception. + * + * @return IConnectionSingle + */ public function getConnection() { return $this->_connection; } + /** + * Indicates if the receiver should reset the underlying connection. + * + * @return Boolean + */ public function shouldResetConnection() { return true; diff --git a/lib/Predis/ConnectionFactory.php b/lib/Predis/ConnectionFactory.php index 717b2a78..040a8cfb 100644 --- a/lib/Predis/ConnectionFactory.php +++ b/lib/Predis/ConnectionFactory.php @@ -13,12 +13,22 @@ namespace Predis; use Predis\Network\IConnectionSingle; +/** + * Provides a default factory for Redis connections that maps URI schemes + * to connection classes implementing the Predis\Network\IConnectionSingle + * interface. + * + * @author Daniele Alessandri + */ class ConnectionFactory implements IConnectionFactory { private static $_globalSchemes; private $_instanceSchemes = array(); + /** + * @param array $schemesMap Map of URI schemes to connection classes. + */ public function __construct(Array $schemesMap = null) { $this->_instanceSchemes = self::ensureDefaultSchemes(); @@ -30,6 +40,13 @@ class ConnectionFactory implements IConnectionFactory } } + /** + * Checks if the provided argument represents a valid connection class + * implementing the Predis\Network\IConnectionSingle interface. Optionally, + * callable objects are used for lazy initialization of connection objects. + * + * @param mixed $initializer FQN of a connection class or a callable for lazy initialization. + */ private static function checkConnectionInitializer($initializer) { if (is_callable($initializer)) { @@ -45,6 +62,11 @@ class ConnectionFactory implements IConnectionFactory } } + /** + * Ensures that the default global URI schemes map is initialized. + * + * @return array + */ private static function ensureDefaultSchemes() { if (!isset(self::$_globalSchemes)) { @@ -57,6 +79,12 @@ class ConnectionFactory implements IConnectionFactory return self::$_globalSchemes; } + /** + * Defines a new URI scheme => connection class relation at class level. + * + * @param string $scheme URI scheme + * @param mixed $connectionInitializer FQN of a connection class or a callable for lazy initialization. + */ public static function define($scheme, $connectionInitializer) { self::ensureDefaultSchemes(); @@ -64,12 +92,21 @@ class ConnectionFactory implements IConnectionFactory self::$_globalSchemes[$scheme] = $connectionInitializer; } + /** + * Defines a new URI scheme => connection class relation at instance level. + * + * @param string $scheme URI scheme + * @param mixed $connectionInitializer FQN of a connection class or a callable for lazy initialization. + */ public function defineConnection($scheme, $connectionInitializer) { self::checkConnectionInitializer($connectionInitializer); $this->_instanceSchemes[$scheme] = $connectionInitializer; } + /** + * {@inheritdoc} + */ public function create($parameters) { if (!$parameters instanceof IConnectionParameters) { diff --git a/lib/Predis/ConnectionParameters.php b/lib/Predis/ConnectionParameters.php index 84ddde99..17d20d25 100644 --- a/lib/Predis/ConnectionParameters.php +++ b/lib/Predis/ConnectionParameters.php @@ -14,6 +14,11 @@ namespace Predis; use Predis\IConnectionParameters; use Predis\Options\IOption; +/** + * Handles parsing and validation of connection parameters. + * + * @author Daniele Alessandri + */ class ConnectionParameters implements IConnectionParameters { private static $_defaultParameters; @@ -22,6 +27,9 @@ class ConnectionParameters implements IConnectionParameters private $_parameters; private $_userDefined; + /** + * @param string|array Connection parameters in the form of an URI string or a named array. + */ public function __construct($parameters = array()) { self::ensureDefaults(); @@ -34,6 +42,9 @@ class ConnectionParameters implements IConnectionParameters $this->_parameters = $this->filter($parameters) + self::$_defaultParameters; } + /** + * Ensures that the default values and validators are initialized. + */ private static function ensureDefaults() { if (!isset(self::$_defaultParameters)) { @@ -72,6 +83,13 @@ class ConnectionParameters implements IConnectionParameters } } + /** + * Defines a default value and a validator for the specified parameter. + * + * @param string $parameter Name of the parameter. + * @param mixed $default Default value or an instance of IOption. + * @param mixed $callable A validator callback. + */ public static function define($parameter, $default, $callable = null) { self::ensureDefaults(); @@ -96,12 +114,23 @@ class ConnectionParameters implements IConnectionParameters self::$_validators[$parameter] = $callable; } + /** + * Undefines the default value and validator for the specified parameter. + * + * @param string $parameter Name of the parameter. + */ public static function undefine($parameter) { self::ensureDefaults(); unset(self::$_defaultParameters[$parameter], self::$_validators[$parameter]); } + /** + * Parses an URI string and returns an array of connection parameters. + * + * @param string $uri Connection string. + * @return array + */ private function parseURI($uri) { if (stripos($uri, 'unix') === 0) { @@ -124,6 +153,12 @@ class ConnectionParameters implements IConnectionParameters return $parsed; } + /** + * Validates and converts each value of the connection parameters array. + * + * @param array $parameters Connection parameters. + * @return array + */ private function filter(Array $parameters) { if (count($parameters) > 0) { @@ -136,6 +171,9 @@ class ConnectionParameters implements IConnectionParameters return $parameters; } + /** + * {@inheritdoc} + */ public function __get($parameter) { $value = $this->_parameters[$parameter]; @@ -147,16 +185,28 @@ class ConnectionParameters implements IConnectionParameters return $value; } + /** + * {@inheritdoc} + */ public function __isset($parameter) { return isset($this->_parameters[$parameter]); } + /** + * Checks if the specified parameter has been set by the user. + * + * @param string $parameter Name of the parameter. + * @return Boolean + */ public function isSetByUser($parameter) { return in_array($parameter, $this->_userDefined); } + /** + * {@inheritdoc} + */ protected function getBaseURI() { if ($this->scheme === 'unix') { @@ -166,16 +216,29 @@ class ConnectionParameters implements IConnectionParameters return "{$this->scheme}://{$this->host}:{$this->port}"; } + /** + * Returns the URI parts that must be omitted when calling __toString(). + * + * @return array + */ protected function getDisallowedURIParts() { return array('scheme', 'host', 'port', 'password', 'path'); } + /** + * {@inheritdoc} + */ public function toArray() { return $this->_parameters; } + /** + * Returns a string representation of the parameters. + * + * @return string + */ public function __toString() { $query = array(); @@ -197,11 +260,17 @@ class ConnectionParameters implements IConnectionParameters return $this->getBaseURI() . '/?' . implode('&', $query); } + /** + * {@inheritdoc} + */ public function __sleep() { return array('_parameters', '_userDefined'); } + /** + * {@inheritdoc} + */ public function __wakeup() { self::ensureDefaults(); diff --git a/lib/Predis/DispatcherLoop.php b/lib/Predis/DispatcherLoop.php index 1462e978..3219c27b 100644 --- a/lib/Predis/DispatcherLoop.php +++ b/lib/Predis/DispatcherLoop.php @@ -11,6 +11,12 @@ namespace Predis; +/** + * Method-dispatcher loop built around the client-side abstraction of a Redis + * Publish / Subscribe context. + * + * @author Daniele Alessandri + */ class DispatcherLoop { private $_client; @@ -19,6 +25,9 @@ class DispatcherLoop private $_defaultCallback; private $_subscriptionCallback; + /** + * @param Client Client instance used by the context. + */ public function __construct(Client $client) { $this->_callbacks = array(); @@ -26,36 +35,61 @@ class DispatcherLoop $this->_pubSubContext = $client->pubSub(); } - protected function validateCallback($callback) + /** + * Checks if the passed argument is a valid callback. + * + * @param mixed A callback. + */ + protected function validateCallback($callable) { - if (!is_callable($callback)) { - throw new ClientException( - "The callback parameter must be a valid callable object" - ); + if (!is_callable($callable)) { + throw new ClientException("A valid callable object must be provided"); } } + /** + * Returns the underlying Publish / Subscribe context. + * + * @return PubSubContext + */ public function getPubSubContext() { return $this->_pubSubContext; } - public function subscriptionCallback($callback = null) + /** + * Sets a callback that gets invoked upon new subscriptions. + * + * @param mixed $callable A callback. + */ + public function subscriptionCallback($callable = null) { - if (isset($callback)) { - $this->validateCallback($callback); + if (isset($callable)) { + $this->validateCallback($callable); } - $this->_subscriptionCallback = $callback; + $this->_subscriptionCallback = $callable; } - public function defaultCallback($callback = null) + /** + * Sets a callback that gets invoked when a message is received on a + * channel that does not have an associated callback. + * + * @param mixed $callable A callback. + */ + public function defaultCallback($callable = null) { - if (isset($callback)) { - $this->validateCallback($callback); + if (isset($callable)) { + $this->validateCallback($callable); } - $this->_subscriptionCallback = $callback; + $this->_subscriptionCallback = $callable; } + /** + * Binds a callback to a channel. + * + * @param string $channel Channel name. + * @param Callable $callback A callback. + */ public function attachCallback($channel, $callback) { $this->validateCallback($callback); @@ -63,6 +97,11 @@ class DispatcherLoop $this->_pubSubContext->subscribe($channel); } + /** + * Stops listening to a channel and removes the associated callback. + * + * @param string $channel Redis channel. + */ public function detachCallback($channel) { if (isset($this->_callbacks[$channel])) { @@ -71,6 +110,9 @@ class DispatcherLoop } } + /** + * Starts the dispatcher loop. + */ public function run() { foreach ($this->_pubSubContext as $message) { @@ -95,6 +137,9 @@ class DispatcherLoop } } + /** + * Terminates the dispatcher loop. + */ public function stop() { $this->_pubSubContext->closeContext(); diff --git a/lib/Predis/Distribution/EmptyRingException.php b/lib/Predis/Distribution/EmptyRingException.php index 1faa37f6..ffc39076 100644 --- a/lib/Predis/Distribution/EmptyRingException.php +++ b/lib/Predis/Distribution/EmptyRingException.php @@ -11,6 +11,11 @@ namespace Predis\Distribution; +/** + * Exception class that identifies empty rings. + * + * @author Daniele Alessandri + */ class EmptyRingException extends \Exception { } diff --git a/lib/Predis/Distribution/HashRing.php b/lib/Predis/Distribution/HashRing.php index c5c69663..8104617e 100644 --- a/lib/Predis/Distribution/HashRing.php +++ b/lib/Predis/Distribution/HashRing.php @@ -11,6 +11,14 @@ namespace Predis\Distribution; +/** + * This class implements an hashring-based distributor that uses the same + * algorithm of memcache to distribute keys in a cluster using client-side + * sharding. + * + * @author Daniele Alessandri + * @author Lorenzo Castelli + */ class HashRing implements IDistributionStrategy { const DEFAULT_REPLICAS = 128; @@ -22,12 +30,21 @@ class HashRing implements IDistributionStrategy private $_ringKeysCount; private $_replicas; + /** + * @param int $replicas Number of replicas in the ring. + */ public function __construct($replicas = self::DEFAULT_REPLICAS) { $this->_replicas = $replicas; $this->_nodes = array(); } + /** + * Adds a node to the ring with an optional weight. + * + * @param mixed $node Node object. + * @param int $weight Weight for the node. + */ public function add($node, $weight = null) { // In case of collisions in the hashes of the nodes, the node added @@ -36,6 +53,9 @@ class HashRing implements IDistributionStrategy $this->reset(); } + /** + * {@inheritdoc} + */ public function remove($node) { // A node is removed by resetting the ring so that it's recreated from @@ -51,6 +71,9 @@ class HashRing implements IDistributionStrategy } } + /** + * Resets the distributor. + */ private function reset() { unset( @@ -60,11 +83,21 @@ class HashRing implements IDistributionStrategy ); } + /** + * Returns the initialization status of the distributor. + * + * @return Boolean + */ private function isInitialized() { return isset($this->_ringKeys); } + /** + * Calculates the total weight of all the nodes in the distributor. + * + * @return int + */ private function computeTotalWeight() { $totalWeight = 0; @@ -75,6 +108,9 @@ class HashRing implements IDistributionStrategy return $totalWeight; } + /** + * Initializes the distributor. + */ private function initialize() { if ($this->isInitialized()) { @@ -99,6 +135,15 @@ class HashRing implements IDistributionStrategy $this->_ringKeysCount = count($this->_ringKeys); } + /** + * Implements the logic needed to add a node to the hashring. + * + * @param array $ring Source hashring. + * @param mixed $node Node object to be added. + * @param int $totalNodes Total number of nodes. + * @param int $replicas Number of replicas in the ring. + * @param float $weightRatio Weight ratio for the node. + */ protected function addNodeToRing(&$ring, $node, $totalNodes, $replicas, $weightRatio) { $nodeObject = $node['object']; @@ -111,21 +156,39 @@ class HashRing implements IDistributionStrategy } } + /** + * {@inheritdoc} + */ protected function getNodeHash($nodeObject) { return (string) $nodeObject; } + /** + * Calculates the hash for the specified value. + * + * @param string $value Input value. + * @return int + */ public function generateKey($value) { return crc32($value); } + /** + * {@inheritdoc} + */ public function get($key) { return $this->_ring[$this->getNodeKey($key)]; } + /** + * Calculates the corrisponding key of a node distributed in the hashring. + * + * @param int $key Computed hash of a key. + * @return int + */ private function getNodeKey($key) { $this->initialize(); @@ -150,9 +213,17 @@ class HashRing implements IDistributionStrategy return $ringKeys[$this->wrapAroundStrategy($upper, $lower, $this->_ringKeysCount)]; } + /** + * Implements a strategy to deal with wrap-around errors during binary searches. + * + * @param int $upper + * @param int $lower + * @param int $ringKeysCount + * @return int + */ protected function wrapAroundStrategy($upper, $lower, $ringKeysCount) { - // Binary search for the last item in _ringkeys with a value less or + // Binary search for the last item in ringkeys with a value less or // equal to the key. If no such item exists, return the last item. return $upper >= 0 ? $upper : $ringKeysCount - 1; } diff --git a/lib/Predis/Distribution/IDistributionStrategy.php b/lib/Predis/Distribution/IDistributionStrategy.php index 10a56373..42b97350 100644 --- a/lib/Predis/Distribution/IDistributionStrategy.php +++ b/lib/Predis/Distribution/IDistributionStrategy.php @@ -11,9 +11,33 @@ namespace Predis\Distribution; +/** + * A distributor implements the logic to automatically distribute + * keys among several nodes for client-side sharding. + * + * @author Daniele Alessandri + */ interface IDistributionStrategy extends INodeKeyGenerator { + /** + * Adds a node to the distributor with an optional weight. + * + * @param mixed $node Node object. + * @param int $weight Weight for the node. + */ public function add($node, $weight = null); + + /** + * Removes a node from the distributor. + * + * @param mixed $node Node object. + */ public function remove($node); + + /** + * Gets a node from the distributor using the computed hash of a key. + * + * @return mixed + */ public function get($key); } diff --git a/lib/Predis/Distribution/INodeKeyGenerator.php b/lib/Predis/Distribution/INodeKeyGenerator.php index 332dd110..690bb39a 100644 --- a/lib/Predis/Distribution/INodeKeyGenerator.php +++ b/lib/Predis/Distribution/INodeKeyGenerator.php @@ -11,7 +11,19 @@ namespace Predis\Distribution; +/** + * A generator of node keys implements the logic used to calculate the hash of + * a key to distribute the respective operations among nodes. + * + * @author Daniele Alessandri + */ interface INodeKeyGenerator { + /** + * Generates an hash that is used by the distributor algorithm + * + * @param string $value Value used to generate the hash. + * @return int + */ public function generateKey($value); } diff --git a/lib/Predis/Distribution/KetamaPureRing.php b/lib/Predis/Distribution/KetamaPureRing.php index 757a5d33..3868b4f9 100644 --- a/lib/Predis/Distribution/KetamaPureRing.php +++ b/lib/Predis/Distribution/KetamaPureRing.php @@ -11,15 +11,29 @@ namespace Predis\Distribution; +/** + * This class implements an hashring-based distributor that uses the same + * algorithm of libketama to distribute keys in a cluster using client-side + * sharding. + * + * @author Daniele Alessandri + * @author Lorenzo Castelli + */ class KetamaPureRing extends HashRing { const DEFAULT_REPLICAS = 160; + /** + * + */ public function __construct() { parent::__construct($this::DEFAULT_REPLICAS); } + /** + * {@inheritdoc} + */ protected function addNodeToRing(&$ring, $node, $totalNodes, $replicas, $weightRatio) { $nodeObject = $node['object']; @@ -34,12 +48,18 @@ class KetamaPureRing extends HashRing } } + /** + * {@inheritdoc} + */ public function generateKey($value) { $hash = unpack('V', md5($value, true)); return $hash[1]; } + /** + * {@inheritdoc} + */ protected function wrapAroundStrategy($upper, $lower, $ringKeysCount) { // Binary search for the first item in _ringkeys with a value greater diff --git a/lib/Predis/Helpers.php b/lib/Predis/Helpers.php index 65e0cd83..5fd8065e 100644 --- a/lib/Predis/Helpers.php +++ b/lib/Predis/Helpers.php @@ -14,13 +14,30 @@ namespace Predis; use Predis\Network\IConnection; use Predis\Network\IConnectionCluster; +/** + * Defines a few helper methods. + * + * @author Daniele Alessandri + */ class Helpers { + /** + * Checks if the specified connection represents a cluster. + * + * @param IConnection $connection Connection object. + * @return Boolean + */ public static function isCluster(IConnection $connection) { return $connection instanceof IConnectionCluster; } + /** + * Offers a generic and reusable method to handle exceptions generated by + * a connection object. + * + * @param CommunicationException $exception Exception. + */ public static function onCommunicationException(CommunicationException $exception) { if ($exception->shouldResetConnection()) { @@ -33,6 +50,12 @@ class Helpers throw $exception; } + /** + * Normalizes the arguments array passed to a Redis command. + * + * @param array $arguments Arguments for a command. + * @return array + */ public static function filterArrayArguments(Array $arguments) { if (count($arguments) === 1 && is_array($arguments[0])) { @@ -42,6 +65,12 @@ class Helpers return $arguments; } + /** + * Normalizes the arguments array passed to a variadic Redis command. + * + * @param array $arguments Arguments for a command. + * @return array + */ public static function filterVariadicValues(Array $arguments) { if (count($arguments) === 2 && is_array($arguments[1])) { @@ -51,6 +80,13 @@ class Helpers return $arguments; } + /** + * Returns only the hashable part of a key (delimited by "{...}"), or the + * whole key if a key tag is not found in the string. + * + * @param string $key A key. + * @return string + */ public static function getKeyHashablePart($key) { $start = strpos($key, '{'); diff --git a/lib/Predis/IConnectionFactory.php b/lib/Predis/IConnectionFactory.php index 6e439550..884a019d 100644 --- a/lib/Predis/IConnectionFactory.php +++ b/lib/Predis/IConnectionFactory.php @@ -11,7 +11,19 @@ namespace Predis; +/** + * Interface that must be implemented by classes that provide their own mechanism + * to create and initialize new instances of Predis\Network\IConnectionSingle. + * + * @author Daniele Alessandri + */ interface IConnectionFactory { + /** + * Creates a new connection object. + * + * @param mixed $parameters Parameters for the connection. + * @return Predis\Network\IConnectionSingle + */ public function create($parameters); } diff --git a/lib/Predis/IConnectionParameters.php b/lib/Predis/IConnectionParameters.php index ad5e18a3..d215c778 100644 --- a/lib/Predis/IConnectionParameters.php +++ b/lib/Predis/IConnectionParameters.php @@ -11,9 +11,34 @@ namespace Predis; +/** + * Interface that must be implemented by classes that provide their own mechanism + * to parse and handle connection parameters. + * + * @author Daniele Alessandri + */ interface IConnectionParameters { + /** + * Checks if the specified parameters is set. + * + * @param string $property Name of the property. + * @return Boolean + */ public function __isset($parameter); + + /** + * Returns the value of the specified parameter. + * + * @param string $parameter Name of the parameter. + * @return mixed + */ public function __get($parameter); + + /** + * Returns an array representation of the connection parameters. + * + * @return array + */ public function toArray(); } diff --git a/lib/Predis/IRedisServerError.php b/lib/Predis/IRedisServerError.php index 873d81c6..34cb5f0f 100644 --- a/lib/Predis/IRedisServerError.php +++ b/lib/Predis/IRedisServerError.php @@ -11,8 +11,25 @@ namespace Predis; +/** + * Represents an error returned by Redis (replies identified by "-" in the + * Redis response protocol) during the execution of an operation on the server. + * + * @author Daniele Alessandri + */ interface IRedisServerError extends IReplyObject { + /** + * Returns the error message + * + * @return string + */ public function getMessage(); + + /** + * Returns the error type (e.g. ERR, ASK, MOVED) + * + * @return string + */ public function getErrorType(); } diff --git a/lib/Predis/IReplyObject.php b/lib/Predis/IReplyObject.php index 0a1d30d3..29f63529 100644 --- a/lib/Predis/IReplyObject.php +++ b/lib/Predis/IReplyObject.php @@ -11,6 +11,11 @@ namespace Predis; +/** + * Represents a complex reply object from Redis. + * + * @author Daniele Alessandri + */ interface IReplyObject { } diff --git a/lib/Predis/Iterators/MultiBulkResponse.php b/lib/Predis/Iterators/MultiBulkResponse.php index fd45df8d..3bd9dfe1 100644 --- a/lib/Predis/Iterators/MultiBulkResponse.php +++ b/lib/Predis/Iterators/MultiBulkResponse.php @@ -11,27 +11,45 @@ namespace Predis\Iterators; +/** + * Iterator that abstracts the access to multibulk replies and allows + * them to be consumed by user's code in a streaming fashion. + * + * @author Daniele Alessandri + */ abstract class MultiBulkResponse implements \Iterator, \Countable { protected $_position; protected $_current; protected $_replySize; + /** + * {@inheritdoc} + */ public function rewind() { // NOOP } + /** + * {@inheritdoc} + */ public function current() { return $this->_current; } + /** + * {@inheritdoc} + */ public function key() { return $this->_position; } + /** + * {@inheritdoc} + */ public function next() { if (++$this->_position < $this->_replySize) { @@ -41,18 +59,30 @@ abstract class MultiBulkResponse implements \Iterator, \Countable return $this->_position; } + /** + * {@inheritdoc} + */ public function valid() { return $this->_position < $this->_replySize; } + /** + * Returns the number of items of the whole multibulk reply. + * + * This method should be used to get the size of the current multibulk + * reply without using iterator_count, which actually consumes the + * iterator to calculate the size (rewinding is not supported). + * + * @return int + */ public function count() { - // Use count if you want to get the size of the current multi-bulk - // response without using iterator_count (which actually consumes our - // iterator to calculate the size, and we cannot perform a rewind) return $this->_replySize; } + /** + * {@inheritdoc} + */ protected abstract function getValue(); } diff --git a/lib/Predis/Iterators/MultiBulkResponseSimple.php b/lib/Predis/Iterators/MultiBulkResponseSimple.php index 503c6fde..f1a106c8 100644 --- a/lib/Predis/Iterators/MultiBulkResponseSimple.php +++ b/lib/Predis/Iterators/MultiBulkResponseSimple.php @@ -14,10 +14,19 @@ namespace Predis\Iterators; use Predis\Network\IConnection; use Predis\Network\IConnectionSingle; +/** + * Streams a multibulk reply. + * + * @author Daniele Alessandri + */ class MultiBulkResponseSimple extends MultiBulkResponse { private $_connection; + /** + * @param IConnectionSingle $connection Connection to Redis. + * @param int $size Number of elements of the multibulk reply. + */ public function __construct(IConnectionSingle $connection, $size) { $this->_connection = $connection; @@ -26,15 +35,24 @@ class MultiBulkResponseSimple extends MultiBulkResponse $this->_replySize = $size; } + /** + * Handles the synchronization of the client with the Redis protocol + * then PHP's garbage collector kicks in (e.g. then the iterator goes + * out of the scope of a foreach). + */ public function __destruct() { - // When the iterator is garbage-collected (e.g. it goes out of the - // scope of a foreach) but it has not reached its end, we must sync - // the client with the queued elements that have not been read from - // the connection with the server. $this->sync(); } + /** + * Synchronizes the client with the queued elements that have not been + * read from the connection by consuming the rest of the multibulk reply, + * or simply by dropping the connection. + * + * @param Boolean $drop True to synchronize the client by dropping the connection. + * False to synchronize the client by consuming the multibulk reply. + */ public function sync($drop = false) { if ($drop == true) { @@ -50,6 +68,11 @@ class MultiBulkResponseSimple extends MultiBulkResponse } } + /** + * Reads the next item of the multibulk reply from the server. + * + * @return mixed + */ protected function getValue() { return $this->_connection->read(); diff --git a/lib/Predis/Iterators/MultiBulkResponseTuple.php b/lib/Predis/Iterators/MultiBulkResponseTuple.php index 2349dbcb..59522b8e 100644 --- a/lib/Predis/Iterators/MultiBulkResponseTuple.php +++ b/lib/Predis/Iterators/MultiBulkResponseTuple.php @@ -11,10 +11,19 @@ namespace Predis\Iterators; +/** + * Abstract the access to a streamable list of tuples represented + * as a multibulk reply that alternates keys and values. + * + * @author Daniele Alessandri + */ class MultiBulkResponseTuple extends MultiBulkResponse { private $_iterator; + /** + * @param MultiBulkResponseSimple $iterator Multibulk reply iterator. + */ public function __construct(MultiBulkResponseSimple $iterator) { $virtualSize = count($iterator) / 2; @@ -24,11 +33,17 @@ class MultiBulkResponseTuple extends MultiBulkResponse $this->_replySize = $virtualSize; } + /** + * {@inheritdoc} + */ public function __destruct() { $this->_iterator->sync(); } + /** + * {@inheritdoc} + */ protected function getValue() { $k = $this->_iterator->current(); diff --git a/lib/Predis/MonitorContext.php b/lib/Predis/MonitorContext.php index 1e68be53..abebc001 100644 --- a/lib/Predis/MonitorContext.php +++ b/lib/Predis/MonitorContext.php @@ -11,12 +11,20 @@ namespace Predis; +/** + * Client-side abstraction of a Redis monitor context. + * + * @author Daniele Alessandri + */ class MonitorContext implements \Iterator { private $_client; private $_isValid; private $_position; + /** + * @param Client Client instance used by the context. + */ public function __construct(Client $client) { $this->checkCapabilities($client); @@ -24,11 +32,20 @@ class MonitorContext implements \Iterator $this->openContext(); } + /** + * Automatically closes the context when PHP's garbage collector kicks in. + */ public function __destruct() { $this->closeContext(); } + /** + * Checks if the passed client instance satisfies the required conditions + * needed to initialize a monitor context. + * + * @param Client Client instance used by the context. + */ private function checkCapabilities(Client $client) { if (Helpers::isCluster($client->getConnection())) { @@ -44,6 +61,11 @@ class MonitorContext implements \Iterator } } + /** + * Initializes the context and sends the MONITOR command to the server. + * + * @param Client Client instance used by the context. + */ protected function openContext() { $this->_isValid = true; @@ -51,37 +73,66 @@ class MonitorContext implements \Iterator $this->_client->executeCommand($monitor); } + /** + * Closes the context. Internally this is done by disconnecting from server + * since there is no way to terminate the stream initialized by MONITOR. + */ public function closeContext() { $this->_client->disconnect(); $this->_isValid = false; } + /** + * {@inheritdoc} + */ public function rewind() { // NOOP } + /** + * Returns the last message payload retrieved from the server. + * + * @return Object + */ public function current() { return $this->getValue(); } + /** + * {@inheritdoc} + */ public function key() { return $this->_position; } + /** + * {@inheritdoc} + */ public function next() { $this->_position++; } + /** + * Checks if the the context is still in a valid state to continue. + * + * @return Boolean + */ public function valid() { return $this->_isValid; } + /** + * Waits for a new message from the server generated by MONITOR and + * returns it when available. + * + * @return Object + */ private function getValue() { $database = 0; diff --git a/lib/Predis/Network/ComposableStreamConnection.php b/lib/Predis/Network/ComposableStreamConnection.php index a0adaf6a..08fa63be 100644 --- a/lib/Predis/Network/ComposableStreamConnection.php +++ b/lib/Predis/Network/ComposableStreamConnection.php @@ -16,10 +16,20 @@ use Predis\Commands\ICommand; use Predis\Protocol\IProtocolProcessor; use Predis\Protocol\Text\TextProtocol; +/** + * Connection abstraction to Redis servers based on PHP's stream that uses an + * external protocol processor defining the protocol used for the communication. + * + * @author Daniele Alessandri + */ class ComposableStreamConnection extends StreamConnection implements IConnectionComposable { private $_protocol; + /** + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @param IProtocolProcessor $protocol A protocol processor. + */ public function __construct(IConnectionParameters $parameters, IProtocolProcessor $protocol = null) { $this->setProtocol($protocol ?: new TextProtocol()); @@ -27,12 +37,18 @@ class ComposableStreamConnection extends StreamConnection implements IConnection parent::__construct($parameters); } + /** + * {@inheritdoc} + */ protected function initializeProtocol(IConnectionParameters $parameters) { $this->_protocol->setOption('throw_errors', $parameters->throw_errors); $this->_protocol->setOption('iterable_multibulk', $parameters->iterable_multibulk); } + /** + * {@inheritdoc} + */ public function setProtocol(IProtocolProcessor $protocol) { if ($protocol === null) { @@ -41,16 +57,25 @@ class ComposableStreamConnection extends StreamConnection implements IConnection $this->_protocol = $protocol; } + /** + * {@inheritdoc} + */ public function getProtocol() { return $this->_protocol; } + /** + * {@inheritdoc} + */ public function writeBytes($buffer) { parent::writeBytes($buffer); } + /** + * {@inheritdoc} + */ public function readBytes($length) { if ($length <= 0) { @@ -72,6 +97,9 @@ class ComposableStreamConnection extends StreamConnection implements IConnection return $value; } + /** + * {@inheritdoc} + */ public function readLine() { $value = ''; @@ -89,11 +117,17 @@ class ComposableStreamConnection extends StreamConnection implements IConnection return substr($value, 0, -2); } + /** + * {@inheritdoc} + */ public function writeCommand(ICommand $command) { $this->_protocol->write($this, $command); } + /** + * {@inheritdoc} + */ public function read() { return $this->_protocol->read($this); diff --git a/lib/Predis/Network/ConnectionBase.php b/lib/Predis/Network/ConnectionBase.php index d19da774..a3466751 100644 --- a/lib/Predis/Network/ConnectionBase.php +++ b/lib/Predis/Network/ConnectionBase.php @@ -19,6 +19,11 @@ use Predis\ClientException; use Predis\Commands\ICommand; use Predis\Protocol\ProtocolException; +/** + * Base class with the common logic used by connection classes to communicate with Redis. + * + * @author Daniele Alessandri + */ abstract class ConnectionBase implements IConnectionSingle { private $_resource; @@ -27,6 +32,9 @@ abstract class ConnectionBase implements IConnectionSingle protected $_params; protected $_initCmds; + /** + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + */ public function __construct(IConnectionParameters $parameters) { $this->_initCmds = array(); @@ -34,11 +42,20 @@ abstract class ConnectionBase implements IConnectionSingle $this->initializeProtocol($parameters); } + /** + * Disconnect from the server and destroys the underlying resource when + * PHP's garbage collector kicks in. + */ public function __destruct() { $this->disconnect(); } + /** + * Checks some of the parameters used to initialize the connection. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + */ protected function checkParameters(IConnectionParameters $parameters) { switch ($parameters->scheme) { @@ -55,18 +72,35 @@ abstract class ConnectionBase implements IConnectionSingle } } + /** + * Initializes some common configurations of the underlying protocol processor + * from the connection parameters. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + */ protected function initializeProtocol(IConnectionParameters $parameters) { // NOOP } + /** + * Creates the underlying resource used to communicate with Redis. + * + * @return mixed + */ protected abstract function createResource(); + /** + * {@inheritdoc} + */ public function isConnected() { return isset($this->_resource); } + /** + * {@inheritdoc} + */ public function connect() { if ($this->isConnected()) { @@ -75,22 +109,34 @@ abstract class ConnectionBase implements IConnectionSingle $this->_resource = $this->createResource(); } + /** + * {@inheritdoc} + */ public function disconnect() { unset($this->_resource); } + /** + * {@inheritdoc} + */ public function pushInitCommand(ICommand $command) { $this->_initCmds[] = $command; } + /** + * {@inheritdoc} + */ public function executeCommand(ICommand $command) { $this->writeCommand($command); return $this->readResponse($command); } + /** + * {@inheritdoc} + */ public function readResponse(ICommand $command) { $reply = $this->read(); @@ -102,16 +148,33 @@ abstract class ConnectionBase implements IConnectionSingle return $command->parseResponse($reply); } + /** + * Helper method to handle connection errors. + * + * @param string $message Error message. + * @param int $code Error code. + */ protected function onConnectionError($message, $code = null) { Helpers::onCommunicationException(new ConnectionException($this, $message, $code)); } + /** + * Helper method to handle protocol errors. + * + * @param string $message Error message. + */ protected function onProtocolError($message) { Helpers::onCommunicationException(new ProtocolException($this, $message)); } + /** + * Helper method to handle invalid connection parameters. + * + * @param string $option Name of the option. + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + */ protected function onInvalidOption($option, $parameters = null) { $message = "Invalid option: $option"; @@ -122,6 +185,9 @@ abstract class ConnectionBase implements IConnectionSingle throw new InvalidArgumentException($message); } + /** + * {@inheritdoc} + */ public function getResource() { if (isset($this->_resource)) { @@ -133,11 +199,19 @@ abstract class ConnectionBase implements IConnectionSingle return $this->_resource; } + /** + * {@inheritdoc} + */ public function getParameters() { return $this->_params; } + /** + * Gets an identifier for the connection. + * + * @return string + */ protected function getIdentifier() { if ($this->_params->scheme === 'unix') { @@ -147,6 +221,9 @@ abstract class ConnectionBase implements IConnectionSingle return "{$this->_params->host}:{$this->_params->port}"; } + /** + * {@inheritdoc} + */ public function __toString() { if (!isset($this->_cachedId)) { diff --git a/lib/Predis/Network/ConnectionException.php b/lib/Predis/Network/ConnectionException.php index 18c788c9..b85970e0 100644 --- a/lib/Predis/Network/ConnectionException.php +++ b/lib/Predis/Network/ConnectionException.php @@ -13,6 +13,11 @@ namespace Predis\Network; use Predis\CommunicationException; +/** + * Exception class that identifies connection-related errors. + * + * @author Daniele Alessandri + */ class ConnectionException extends CommunicationException { } diff --git a/lib/Predis/Network/IConnection.php b/lib/Predis/Network/IConnection.php index c3921629..212378aa 100644 --- a/lib/Predis/Network/IConnection.php +++ b/lib/Predis/Network/IConnection.php @@ -13,12 +13,51 @@ namespace Predis\Network; use Predis\Commands\ICommand; +/** + * Defines a connection object used to communicate with one or multiple + * Redis servers. + * + * @author Daniele Alessandri + */ interface IConnection { + /** + * Opens the connection. + */ public function connect(); + + /** + * Closes the connection. + */ public function disconnect(); + + /** + * Returns if the connection is open. + * + * @return Boolean + */ public function isConnected(); + + /** + * Write a Redis command on the connection. + * + * @param ICommand $command Instance of a Redis command. + */ public function writeCommand(ICommand $command); + + /** + * Reads the reply for a Redis command from the connection. + * + * @param ICommand $command Instance of a Redis command. + * @return mixed + */ public function readResponse(ICommand $command); + + /** + * Writes a Redis command to the connection and reads back the reply. + * + * @param ICommand $command Instance of a Redis command. + * @return mixed + */ public function executeCommand(ICommand $command); } diff --git a/lib/Predis/Network/IConnectionCluster.php b/lib/Predis/Network/IConnectionCluster.php index 45694b79..655b99a9 100644 --- a/lib/Predis/Network/IConnectionCluster.php +++ b/lib/Predis/Network/IConnectionCluster.php @@ -13,9 +13,34 @@ namespace Predis\Network; use Predis\Commands\ICommand; +/** + * Defines a cluster of Redis servers formed by aggregating multiple + * connection objects. + * + * @author Daniele Alessandri + */ interface IConnectionCluster extends IConnection { + /** + * Adds a connection instance to the cluster. + * + * @param IConnectionSingle $connection Instance of a connection. + */ public function add(IConnectionSingle $connection); + + /** + * Gets the actual connection instance in charge of the specified command. + * + * @param ICommand $command Instance of a Redis command. + * @return IConnectionSingle + */ public function getConnection(ICommand $command); + + /** + * Retrieves a connection instance from the cluster using an alias. + * + * @param string $connectionId Alias of a connection + * @return IConnectionSingle + */ public function getConnectionById($connectionId); } diff --git a/lib/Predis/Network/IConnectionComposable.php b/lib/Predis/Network/IConnectionComposable.php index 4a0c540f..f41945f1 100644 --- a/lib/Predis/Network/IConnectionComposable.php +++ b/lib/Predis/Network/IConnectionComposable.php @@ -13,11 +13,45 @@ namespace Predis\Network; use Predis\Protocol\IProtocolProcessor; +/** + * Defines a connection object used to communicate with a single Redis server + * that leverages an external protocol processor to handle pluggable protocol + * handlers. + * + * @author Daniele Alessandri + */ interface IConnectionComposable extends IConnectionSingle { + /** + * Sets the protocol processor used by the connection. + * + * @param IProtocolProcessor $protocol Protocol processor. + */ public function setProtocol(IProtocolProcessor $protocol); + + /** + * Gets the protocol processor used by the connection. + */ public function getProtocol(); + + /** + * Writes a buffer that contains a serialized Redis command. + * + * @param string $buffer Serialized Redis command. + */ public function writeBytes($buffer); + + /** + * Reads a specified number of bytes from the connection. + * + * @param string + */ public function readBytes($length); + + /** + * Reads a line from the connection. + * + * @param string + */ public function readLine(); } diff --git a/lib/Predis/Network/IConnectionSingle.php b/lib/Predis/Network/IConnectionSingle.php index 6607a536..e5ba8392 100644 --- a/lib/Predis/Network/IConnectionSingle.php +++ b/lib/Predis/Network/IConnectionSingle.php @@ -13,11 +13,47 @@ namespace Predis\Network; use Predis\Commands\ICommand; +/** + * Defines a connection object used to communicate with a single Redis server. + * + * @author Daniele Alessandri + */ interface IConnectionSingle extends IConnection { + /** + * Returns a string representation of the connection. + * + * @return string + */ public function __toString(); + + /** + * Returns the underlying resource used to communicate with a Redis server. + * + * @return mixed + */ public function getResource(); + + /** + * Gets the parameters used to initialize the connection object. + * + * @return IConnectionParameters + */ public function getParameters(); + + /** + * Pushes the instance of a Redis command to the queue of commands executed + * when the actual connection to a server is estabilished. + * + * @param ICommand $command Instance of a Redis command. + * @return IConnectionParameters + */ public function pushInitCommand(ICommand $command); + + /** + * Reads a reply from the server. + * + * @return mixed + */ public function read(); } diff --git a/lib/Predis/Network/PhpiredisConnection.php b/lib/Predis/Network/PhpiredisConnection.php index db5da04b..4b0fc761 100644 --- a/lib/Predis/Network/PhpiredisConnection.php +++ b/lib/Predis/Network/PhpiredisConnection.php @@ -33,10 +33,20 @@ use Predis\ServerException; use Predis\IConnectionParameters; use Predis\Commands\ICommand; +/** + * Connection abstraction to Redis servers based on PHP's sockets to + * handle the actual network connection and the phpiredis extension to + * handle the parsing of Redis protocol. + * + * @author Daniele Alessandri + */ class PhpiredisConnection extends ConnectionBase { private $_reader; + /** + * {@inheritdoc} + */ public function __construct(IConnectionParameters $parameters) { if (!function_exists('socket_create')) { @@ -49,6 +59,10 @@ class PhpiredisConnection extends ConnectionBase parent::__construct($parameters); } + /** + * Disconnect from the server and destroys the underlying resource and the + * protocol reader resource when PHP's garbage collector kicks in. + */ public function __destruct() { phpiredis_reader_destroy($this->_reader); @@ -56,6 +70,9 @@ class PhpiredisConnection extends ConnectionBase parent::__destruct(); } + /** + * {@inheritdoc} + */ protected function checkParameters(IConnectionParameters $parameters) { if ($parameters->isSetByUser('iterable_multibulk')) { @@ -68,6 +85,11 @@ class PhpiredisConnection extends ConnectionBase return parent::checkParameters($parameters); } + /** + * Initializes the protocol reader resource. + * + * @param Boolean $throw_errors Specify if Redis errors throw exceptions. + */ private function initializeReader($throw_errors = true) { if (!function_exists('phpiredis_reader_create')) { @@ -85,11 +107,19 @@ class PhpiredisConnection extends ConnectionBase $this->_reader = $reader; } + /** + * {@inheritdoc} + */ protected function initializeProtocol(IConnectionParameters $parameters) { $this->initializeReader($parameters->throw_errors); } + /** + * Gets the handler used by the protocol reader to handle status replies. + * + * @return \Closure + */ private function getStatusHandler() { return function($payload) { @@ -106,6 +136,12 @@ class PhpiredisConnection extends ConnectionBase }; } + /** + * Gets the handler used by the protocol reader to handle Redis errors. + * + * @param Boolean $throw_errors Specify if Redis errors throw exceptions. + * @return \Closure + */ private function getErrorHandler($throwErrors = true) { if ($throwErrors) { @@ -119,6 +155,9 @@ class PhpiredisConnection extends ConnectionBase }; } + /** + * Helper method used to throw exceptions on socket errors. + */ private function emitSocketError() { $errno = socket_last_error(); @@ -129,6 +168,9 @@ class PhpiredisConnection extends ConnectionBase $this->onConnectionError(trim($errstr), $errno); } + /** + * {@inheritdoc} + */ protected function createResource() { $parameters = $this->_params; @@ -141,6 +183,12 @@ class PhpiredisConnection extends ConnectionBase return $socket; } + /** + * Initializes a TCP socket resource. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return resource + */ private function tcpSocketInitializer(IConnectionParameters $parameters) { $socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); @@ -151,6 +199,12 @@ class PhpiredisConnection extends ConnectionBase return $socket; } + /** + * Initializes a UNIX socket resource. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return resource + */ private function unixSocketInitializer(IConnectionParameters $parameters) { $socket = @socket_create(AF_UNIX, SOCK_STREAM, 0); @@ -162,6 +216,12 @@ class PhpiredisConnection extends ConnectionBase return $socket; } + /** + * Sets options on the socket resource from the connection parameters. + * + * @param resource $socket Socket resource. + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + */ private function setSocketOptions($socket, IConnectionParameters $parameters) { if ($parameters->scheme !== 'tcp') { @@ -196,6 +256,12 @@ class PhpiredisConnection extends ConnectionBase } } + /** + * Gets the address from the connection parameters. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return string + */ private function getAddress(IConnectionParameters $parameters) { if ($parameters->scheme === 'unix') { @@ -214,6 +280,12 @@ class PhpiredisConnection extends ConnectionBase return $host; } + /** + * Opens the actual connection to the server with a timeout. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return string + */ private function connectWithTimeout(IConnectionParameters $parameters) { $host = self::getAddress($parameters); $socket = $this->getResource(); @@ -249,6 +321,9 @@ class PhpiredisConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ public function connect() { parent::connect(); @@ -259,6 +334,9 @@ class PhpiredisConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ public function disconnect() { if ($this->isConnected()) { @@ -268,6 +346,9 @@ class PhpiredisConnection extends ConnectionBase } } + /** + * Sends the initialization commands to Redis when the connection is opened. + */ private function sendInitializationCommands() { foreach ($this->_initCmds as $command) { @@ -278,6 +359,9 @@ class PhpiredisConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ private function write($buffer) { $socket = $this->getResource(); @@ -296,6 +380,9 @@ class PhpiredisConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ public function read() { $socket = $this->getResource(); @@ -317,6 +404,9 @@ class PhpiredisConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ public function writeCommand(ICommand $command) { $cmdargs = $command->getArguments(); diff --git a/lib/Predis/Network/PredisCluster.php b/lib/Predis/Network/PredisCluster.php index 3a42fa11..3531b674 100644 --- a/lib/Predis/Network/PredisCluster.php +++ b/lib/Predis/Network/PredisCluster.php @@ -17,17 +17,29 @@ use Predis\Commands\ICommand; use Predis\Distribution\IDistributionStrategy; use Predis\Distribution\HashRing; +/** + * Abstraction for a cluster of aggregated connections to various Redis servers + * implementing client-side sharding based on pluggable distribution strategies. + * + * @author Daniele Alessandri + */ class PredisCluster implements IConnectionCluster, \IteratorAggregate { private $_pool; private $_distributor; + /** + * @param IDistributionStrategy $distributor Distribution strategy used by the cluster. + */ public function __construct(IDistributionStrategy $distributor = null) { $this->_pool = array(); $this->_distributor = $distributor ?: new HashRing(); } + /** + * {@inheritdoc} + */ public function isConnected() { foreach ($this->_pool as $connection) { @@ -39,6 +51,9 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate return false; } + /** + * {@inheritdoc} + */ public function connect() { foreach ($this->_pool as $connection) { @@ -46,6 +61,9 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate } } + /** + * {@inheritdoc} + */ public function disconnect() { foreach ($this->_pool as $connection) { @@ -53,6 +71,9 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate } } + /** + * {@inheritdoc} + */ public function add(IConnectionSingle $connection) { $parameters = $connection->getParameters(); @@ -67,6 +88,9 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate $this->_distributor->add($connection, $parameters->weight); } + /** + * {@inheritdoc} + */ public function getConnection(ICommand $command) { $cmdHash = $command->getHash($this->_distributor); @@ -80,6 +104,9 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate ); } + /** + * {@inheritdoc} + */ public function getConnectionById($id = null) { $alias = $id ?: 0; @@ -87,6 +114,13 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate return isset($this->_pool[$alias]) ? $this->_pool[$alias] : null; } + + /** + * Retrieves a connection instance from the cluster using a key. + * + * @param string $key Key of a Redis value. + * @return IConnectionSingle + */ public function getConnectionByKey($key) { $hashablePart = Helpers::getKeyHashablePart($key); @@ -95,21 +129,33 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate return $this->_distributor->get($keyHash); } + /** + * {@inheritdoc} + */ public function getIterator() { return new \ArrayIterator($this->_pool); } + /** + * {@inheritdoc} + */ public function writeCommand(ICommand $command) { $this->getConnection($command)->writeCommand($command); } + /** + * {@inheritdoc} + */ public function readResponse(ICommand $command) { return $this->getConnection($command)->readResponse($command); } + /** + * {@inheritdoc} + */ public function executeCommand(ICommand $command) { return $this->getConnection($command)->executeCommand($command); diff --git a/lib/Predis/Network/StreamConnection.php b/lib/Predis/Network/StreamConnection.php index 245460cb..09899b7c 100644 --- a/lib/Predis/Network/StreamConnection.php +++ b/lib/Predis/Network/StreamConnection.php @@ -18,11 +18,21 @@ use Predis\IConnectionParameters; use Predis\Commands\ICommand; use Predis\Iterators\MultiBulkResponseSimple; +/** + * Connection abstraction to Redis servers based on PHP's streams. + * + * @author Daniele Alessandri + */ class StreamConnection extends ConnectionBase { private $_mbiterable; private $_throwErrors; + /** + * Disconnect from the server and destroys the underlying resource when + * PHP's garbage collector kicks in only if the connection has not been + * marked as persistent. + */ public function __destruct() { if (!$this->_params->connection_persistent) { @@ -30,12 +40,18 @@ class StreamConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ protected function initializeProtocol(IConnectionParameters $parameters) { $this->_throwErrors = $parameters->throw_errors; $this->_mbiterable = $parameters->iterable_multibulk; } + /** + * {@inheritdoc} + */ protected function createResource() { $parameters = $this->_params; @@ -44,6 +60,12 @@ class StreamConnection extends ConnectionBase return $this->$initializer($parameters); } + /** + * Initializes a TCP stream resource. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return resource + */ private function tcpStreamInitializer(IConnectionParameters $parameters) { $uri = "tcp://{$parameters->host}:{$parameters->port}/"; @@ -75,6 +97,12 @@ class StreamConnection extends ConnectionBase return $resource; } + /** + * Initializes a UNIX stream resource. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return resource + */ private function unixStreamInitializer(IConnectionParameters $parameters) { $uri = "unix://{$parameters->path}"; @@ -95,6 +123,9 @@ class StreamConnection extends ConnectionBase return $resource; } + /** + * {@inheritdoc} + */ public function connect() { parent::connect(); @@ -104,6 +135,9 @@ class StreamConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ public function disconnect() { if ($this->isConnected()) { @@ -113,6 +147,9 @@ class StreamConnection extends ConnectionBase } } + /** + * Sends the initialization commands to Redis when the connection is opened. + */ private function sendInitializationCommands() { foreach ($this->_initCmds as $command) { @@ -123,6 +160,12 @@ class StreamConnection extends ConnectionBase } } + /** + * Perform a write operation on the stream of the buffer containing a command + * serialized with the Redis wire protocol. + * + * @param string $buffer Redis wire protocol representation of a command. + */ protected function writeBytes($buffer) { $socket = $this->getResource(); @@ -139,6 +182,9 @@ class StreamConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ public function read() { $socket = $this->getResource(); @@ -216,6 +262,9 @@ class StreamConnection extends ConnectionBase } } + /** + * {@inheritdoc} + */ public function writeCommand(ICommand $command) { $commandId = $command->getId(); diff --git a/lib/Predis/Network/WebdisConnection.php b/lib/Predis/Network/WebdisConnection.php index dcd0f857..52586334 100644 --- a/lib/Predis/Network/WebdisConnection.php +++ b/lib/Predis/Network/WebdisConnection.php @@ -31,12 +31,21 @@ use Predis\Protocol\ProtocolException; const ERR_MSG_EXTENSION = 'The %s extension must be loaded in order to be able to use this connection class'; +/** + * Connection abstraction to Webdis servers. + * + * @link http://webd.is/ + * @author Daniele Alessandri + */ class WebdisConnection implements IConnectionSingle { private $_parameters; private $_resource; private $_reader; + /** + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + */ public function __construct(IConnectionParameters $parameters) { $this->_parameters = $parameters; @@ -50,18 +59,28 @@ class WebdisConnection implements IConnectionSingle $this->_reader = $this->initializeReader($parameters); } + /** + * Frees the underlying cURL and protocol reader resources when PHP's + * garbage collector kicks in. + */ public function __destruct() { curl_close($this->_resource); phpiredis_reader_destroy($this->_reader); } + /** + * Helper method used to throw on unsupported methods. + */ private function throwNotSupportedException($function) { $class = __CLASS__; throw new \RuntimeException("The method $class::$function() is not supported"); } + /** + * Checks if the cURL and phpiredis extensions are loaded in PHP. + */ private function checkExtensions() { if (!function_exists('curl_init')) { @@ -72,6 +91,12 @@ class WebdisConnection implements IConnectionSingle } } + /** + * Initializes cURL. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return resource + */ private function initializeCurl(IConnectionParameters $parameters) { $options = array( @@ -93,6 +118,12 @@ class WebdisConnection implements IConnectionSingle return $resource; } + /** + * Initializes phpiredis' protocol reader. + * + * @param IConnectionParameters $parameters Parameters used to initialize the connection. + * @return resource + */ private function initializeReader(IConnectionParameters $parameters) { $reader = phpiredis_reader_create(); @@ -103,6 +134,11 @@ class WebdisConnection implements IConnectionSingle return $reader; } + /** + * Gets the handler used by the protocol reader to handle status replies. + * + * @return \Closure + */ private function getStatusHandler() { return function($payload) { @@ -110,6 +146,12 @@ class WebdisConnection implements IConnectionSingle }; } + /** + * Gets the handler used by the protocol reader to handle Redis errors. + * + * @param Boolean $throwErrors Specify if Redis errors throw exceptions. + * @return \Closure + */ private function getErrorHandler($throwErrors) { if ($throwErrors) { @@ -123,6 +165,13 @@ class WebdisConnection implements IConnectionSingle }; } + /** + * Feeds phpredis' reader resource with the data read from the network. + * + * @param resource $resource Reader resource. + * @param string $buffer Buffer with the reply read from the network. + * @return int + */ protected function feedReader($resource, $buffer) { phpiredis_reader_feed($this->_reader, $buffer); @@ -130,21 +179,36 @@ class WebdisConnection implements IConnectionSingle return strlen($buffer); } + /** + * {@inheritdoc} + */ public function connect() { // NOOP } + /** + * {@inheritdoc} + */ public function disconnect() { // NOOP } + /** + * {@inheritdoc} + */ public function isConnected() { return true; } + /** + * Checks if the specified command is supported by this connection class. + * + * @param ICommand $command The instance of a Redis command. + * @return string + */ protected function getCommandId(ICommand $command) { switch (($commandId = $command->getId())) { @@ -162,16 +226,25 @@ class WebdisConnection implements IConnectionSingle } } + /** + * {@inheritdoc} + */ public function writeCommand(ICommand $command) { $this->throwNotSupportedException(__FUNCTION__); } + /** + * {@inheritdoc} + */ public function readResponse(ICommand $command) { $this->throwNotSupportedException(__FUNCTION__); } + /** + * {@inheritdoc} + */ public function executeCommand(ICommand $command) { $resource = $this->_resource; @@ -208,26 +281,41 @@ class WebdisConnection implements IConnectionSingle } } + /** + * {@inheritdoc} + */ public function getResource() { return $this->_resource; } + /** + * {@inheritdoc} + */ public function getParameters() { return $this->_parameters; } + /** + * {@inheritdoc} + */ public function pushInitCommand(ICommand $command) { $this->throwNotSupportedException(__FUNCTION__); } + /** + * {@inheritdoc} + */ public function read() { $this->throwNotSupportedException(__FUNCTION__); } + /** + * {@inheritdoc} + */ public function __toString() { return "{$this->_parameters->host}:{$this->_parameters->port}"; diff --git a/lib/Predis/Options/ClientCluster.php b/lib/Predis/Options/ClientCluster.php index ef58c016..05e61382 100644 --- a/lib/Predis/Options/ClientCluster.php +++ b/lib/Predis/Options/ClientCluster.php @@ -14,8 +14,19 @@ namespace Predis\Options; use Predis\Network\IConnectionCluster; use Predis\Network\PredisCluster; +/** + * Option class that returns a connection cluster to be used by a client. + * + * @author Daniele Alessandri + */ class ClientCluster extends Option { + /** + * Checks if the specified value is a valid instance of IConnectionCluster. + * + * @param IConnectionCluster $cluster Instance of a connection cluster. + * @return IConnectionCluster + */ protected function checkInstance($cluster) { if (!$cluster instanceof IConnectionCluster) { @@ -27,6 +38,9 @@ class ClientCluster extends Option return $cluster; } + /** + * {@inheritdoc} + */ public function validate($value) { if (is_callable($value)) { @@ -37,6 +51,12 @@ class ClientCluster extends Option return $this->checkInstance($initializer()); } + /** + * Returns an initializer for the specified FQN or type. + * + * @param string $fqnOrType Type of cluster of FQN of a class implementing IConnectionCluster + * @return \Closure + */ protected function getInitializer($fqnOrType) { switch ($fqnOrType) { @@ -50,6 +70,9 @@ class ClientCluster extends Option } } + /** + * {@inheritdoc} + */ public function getDefault() { return new PredisCluster(); diff --git a/lib/Predis/Options/ClientConnectionFactory.php b/lib/Predis/Options/ClientConnectionFactory.php index 93337fc6..33429d74 100644 --- a/lib/Predis/Options/ClientConnectionFactory.php +++ b/lib/Predis/Options/ClientConnectionFactory.php @@ -14,8 +14,16 @@ namespace Predis\Options; use Predis\IConnectionFactory; use Predis\ConnectionFactory; +/** + * Option class that returns a connection factory to be used by a client. + * + * @author Daniele Alessandri + */ class ClientConnectionFactory extends Option { + /** + * {@inheritdoc} + */ public function validate($value) { if ($value instanceof IConnectionFactory) { @@ -26,6 +34,9 @@ class ClientConnectionFactory extends Option } } + /** + * {@inheritdoc} + */ public function getDefault() { return new ConnectionFactory(); diff --git a/lib/Predis/Options/ClientPrefix.php b/lib/Predis/Options/ClientPrefix.php index 631f47a1..644efe3c 100644 --- a/lib/Predis/Options/ClientPrefix.php +++ b/lib/Predis/Options/ClientPrefix.php @@ -13,8 +13,16 @@ namespace Predis\Options; use Predis\Commands\Processors\KeyPrefixProcessor; +/** + * Option class that handles the prefixing of keys in commands. + * + * @author Daniele Alessandri + */ class ClientPrefix extends Option { + /** + * {@inheritdoc} + */ public function validate($value) { return new KeyPrefixProcessor($value); diff --git a/lib/Predis/Options/ClientProfile.php b/lib/Predis/Options/ClientProfile.php index b247689e..3e71644e 100644 --- a/lib/Predis/Options/ClientProfile.php +++ b/lib/Predis/Options/ClientProfile.php @@ -14,8 +14,16 @@ namespace Predis\Options; use Predis\Profiles\ServerProfile; use Predis\Profiles\IServerProfile; +/** + * Option class that handles server profiles to be used by a client. + * + * @author Daniele Alessandri + */ class ClientProfile extends Option { + /** + * {@inheritdoc} + */ public function validate($value) { if ($value instanceof IServerProfile) { @@ -31,6 +39,9 @@ class ClientProfile extends Option ); } + /** + * {@inheritdoc} + */ public function getDefault() { return ServerProfile::getDefault(); diff --git a/lib/Predis/Options/CustomOption.php b/lib/Predis/Options/CustomOption.php index c3599a51..a5ada736 100644 --- a/lib/Predis/Options/CustomOption.php +++ b/lib/Predis/Options/CustomOption.php @@ -11,17 +11,31 @@ namespace Predis\Options; +/** + * Implements a generic class used to dinamically define a client option. + * + * @author Daniele Alessandri + */ class CustomOption implements IOption { private $_validate; private $_default; + /** + * @param array $options List of options + */ public function __construct(Array $options) { $this->_validate = $this->filterCallable($options, 'validate'); $this->_default = $this->filterCallable($options, 'default'); } + /** + * Checks if the specified value in the options array is a callable object. + * + * @param array $options Array of options + * @param string $key Target option. + */ private function filterCallable($options, $key) { if (!isset($options[$key])) { @@ -36,6 +50,9 @@ class CustomOption implements IOption throw new \InvalidArgumentException("The parameter $key must be callable"); } + /** + * {@inheritdoc} + */ public function validate($value) { if (isset($value)) { @@ -48,6 +65,9 @@ class CustomOption implements IOption } } + /** + * {@inheritdoc} + */ public function getDefault() { if (!isset($this->_default)) { @@ -58,6 +78,9 @@ class CustomOption implements IOption return $default(); } + /** + * {@inheritdoc} + */ public function __invoke($value) { if (isset($value)) { diff --git a/lib/Predis/Options/IOption.php b/lib/Predis/Options/IOption.php index 24306b7e..9b966c8a 100644 --- a/lib/Predis/Options/IOption.php +++ b/lib/Predis/Options/IOption.php @@ -11,9 +11,35 @@ namespace Predis\Options; +/** + * Interface that defines a client option. + * + * @author Daniele Alessandri + */ interface IOption { + /** + * Validates (and optionally converts) the passed value. + * + * @param mixed $value Input value. + * @return mixed + */ public function validate($value); + + /** + * Returns a default value for the option. + * + * @param mixed $value Input value. + * @return mixed + */ public function getDefault(); + + /** + * Validates a value and, if no value is specified, returns + * the default one defined by the option. + * + * @param mixed $value Input value. + * @return mixed + */ public function __invoke($value); } diff --git a/lib/Predis/Options/Option.php b/lib/Predis/Options/Option.php index 40d94b4e..46044e0e 100644 --- a/lib/Predis/Options/Option.php +++ b/lib/Predis/Options/Option.php @@ -11,18 +11,32 @@ namespace Predis\Options; +/** + * Implements a client option. + * + * @author Daniele Alessandri + */ class Option implements IOption { + /** + * {@inheritdoc} + */ public function validate($value) { return $value; } + /** + * {@inheritdoc} + */ public function getDefault() { return null; } + /** + * {@inheritdoc} + */ public function __invoke($value) { if (isset($value)) { diff --git a/lib/Predis/Pipeline/FireAndForgetExecutor.php b/lib/Predis/Pipeline/FireAndForgetExecutor.php index a632c439..9c66fa41 100644 --- a/lib/Predis/Pipeline/FireAndForgetExecutor.php +++ b/lib/Predis/Pipeline/FireAndForgetExecutor.php @@ -13,8 +13,17 @@ namespace Predis\Pipeline; use Predis\Network\IConnection; +/** + * Implements a pipeline executor strategy that writes a list of commands to + * the connection object but does not read back their replies. + * + * @author Daniele Alessandri + */ class FireAndForgetExecutor implements IPipelineExecutor { + /** + * {@inheritdoc} + */ public function execute(IConnection $connection, &$commands) { foreach ($commands as $command) { diff --git a/lib/Predis/Pipeline/IPipelineExecutor.php b/lib/Predis/Pipeline/IPipelineExecutor.php index 4691dc7b..9f6dfd09 100644 --- a/lib/Predis/Pipeline/IPipelineExecutor.php +++ b/lib/Predis/Pipeline/IPipelineExecutor.php @@ -13,7 +13,20 @@ namespace Predis\Pipeline; use Predis\Network\IConnection; +/** + * Defines a strategy to write a list of commands to the network + * and read back their replies. + * + * @author Daniele Alessandri + */ interface IPipelineExecutor { + /** + * Writes a list of commands to the network and reads back their replies. + * + * @param IConnection $connection Connection to Redis. + * @param array $commands List of commands. + * @return array + */ public function execute(IConnection $connection, &$commands); } diff --git a/lib/Predis/Pipeline/PipelineContext.php b/lib/Predis/Pipeline/PipelineContext.php index c2d22238..6641ba97 100644 --- a/lib/Predis/Pipeline/PipelineContext.php +++ b/lib/Predis/Pipeline/PipelineContext.php @@ -16,6 +16,12 @@ use Predis\Helpers; use Predis\ClientException; use Predis\Commands\ICommand; +/** + * Abstraction of a pipeline context where write and read operations + * of commands and their replies over the network are pipelined. + * + * @author Daniele Alessandri + */ class PipelineContext { private $_client; @@ -25,12 +31,24 @@ class PipelineContext private $_replies = array(); private $_running = false; + /** + * @param Client Client instance used by the context. + * @param array Options for the context initialization. + */ public function __construct(Client $client, Array $options = null) { $this->_client = $client; $this->_executor = $this->getExecutor($client, $options ?: array()); } + /** + * Returns a pipeline executor depending on the kind of the underlying + * connection and the passed options. + * + * @param Client Client instance used by the context. + * @param array Options for the context initialization. + * @return IPipelineExecutor + */ protected function getExecutor(Client $client, Array $options) { if (!$options) { @@ -56,6 +74,13 @@ class PipelineContext return new StandardExecutor(); } + /** + * Queues a command into the pipeline buffer. + * + * @param string $method Command ID. + * @param array $arguments Arguments for the command. + * @return PipelineContext + */ public function __call($method, $arguments) { $command = $this->_client->createCommand($method, $arguments); @@ -64,16 +89,28 @@ class PipelineContext return $this; } + /** + * Queues a command instance into the pipeline buffer. + */ protected function recordCommand(ICommand $command) { $this->_pipeline[] = $command; } + /** + * Queues a command instance into the pipeline buffer. + */ public function executeCommand(ICommand $command) { $this->recordCommand($command); } + /** + * Flushes the queued commands by writing the buffer to Redis and reading + * all the replies into the reply buffer. + * + * @return PipelineContext + */ public function flushPipeline() { if (count($this->_pipeline) > 0) { @@ -86,6 +123,12 @@ class PipelineContext return $this; } + /** + * Marks the running status of the pipeline. + * + * @param Boolean $bool True if the pipeline is running. + * False if the pipeline is not running. + */ private function setRunning($bool) { if ($bool === true && $this->_running === true) { @@ -94,9 +137,15 @@ class PipelineContext $this->_running = $bool; } - public function execute($block = null) + /** + * Handles the actual execution of the whole pipeline. + * + * @param mixed $callable Callback for execution. + * @return array + */ + public function execute($callable = null) { - if ($block && !is_callable($block)) { + if ($callable && !is_callable($callable)) { throw new \InvalidArgumentException('Argument passed must be a callable object'); } @@ -104,8 +153,8 @@ class PipelineContext $pipelineBlockException = null; try { - if ($block !== null) { - $block($this); + if ($callable !== null) { + $callable($this); } $this->flushPipeline(); } diff --git a/lib/Predis/Pipeline/SafeClusterExecutor.php b/lib/Predis/Pipeline/SafeClusterExecutor.php index 07c98430..c78bbdfb 100644 --- a/lib/Predis/Pipeline/SafeClusterExecutor.php +++ b/lib/Predis/Pipeline/SafeClusterExecutor.php @@ -15,8 +15,18 @@ use Predis\ServerException; use Predis\CommunicationException; use Predis\Network\IConnection; +/** + * Implements a pipeline executor strategy for connection clusters that does + * not fail when an error is encountered, but adds the returned error in the + * replies array. + * + * @author Daniele Alessandri + */ class SafeClusterExecutor implements IPipelineExecutor { + /** + * {@inheritdoc} + */ public function execute(IConnection $connection, &$commands) { $connectionExceptions = array(); diff --git a/lib/Predis/Pipeline/SafeExecutor.php b/lib/Predis/Pipeline/SafeExecutor.php index 0470d796..b50d188f 100644 --- a/lib/Predis/Pipeline/SafeExecutor.php +++ b/lib/Predis/Pipeline/SafeExecutor.php @@ -15,8 +15,17 @@ use Predis\ServerException; use Predis\CommunicationException; use Predis\Network\IConnection; +/** + * Implements a pipeline executor strategy that does not fail when an error is + * encountered, but adds the returned error in the replies array. + * + * @author Daniele Alessandri + */ class SafeExecutor implements IPipelineExecutor { + /** + * {@inheritdoc} + */ public function execute(IConnection $connection, &$commands) { $sizeofPipe = count($commands); diff --git a/lib/Predis/Pipeline/StandardExecutor.php b/lib/Predis/Pipeline/StandardExecutor.php index 3791dd02..1bbf6d01 100644 --- a/lib/Predis/Pipeline/StandardExecutor.php +++ b/lib/Predis/Pipeline/StandardExecutor.php @@ -14,8 +14,18 @@ namespace Predis\Pipeline; use Predis\ServerException; use Predis\Network\IConnection; +/** + * Implements the standard pipeline executor strategy used + * to write a list of commands and read their replies over + * a connection to Redis. + * + * @author Daniele Alessandri + */ class StandardExecutor implements IPipelineExecutor { + /** + * {@inheritdoc} + */ public function execute(IConnection $connection, &$commands) { $sizeofPipe = count($commands); diff --git a/lib/Predis/PredisException.php b/lib/Predis/PredisException.php index ac04ef7a..122bde16 100644 --- a/lib/Predis/PredisException.php +++ b/lib/Predis/PredisException.php @@ -11,6 +11,11 @@ namespace Predis; +/** + * Base exception class for Predis-related errors. + * + * @author Daniele Alessandri + */ abstract class PredisException extends \Exception { } diff --git a/lib/Predis/Profiles/IServerProfile.php b/lib/Predis/Profiles/IServerProfile.php index ec4627be..d1cf8273 100644 --- a/lib/Predis/Profiles/IServerProfile.php +++ b/lib/Predis/Profiles/IServerProfile.php @@ -11,10 +11,45 @@ namespace Predis\Profiles; + +/** + * A server profile defines features and commands supported by certain + * versions of Redis. Instances of Predis\Client should use a server + * profile matching the version of Redis in use. + * + * @author Daniele Alessandri + */ interface IServerProfile { + /** + * Gets a profile version corresponding to a Redis version. + * + * @return string + */ public function getVersion(); + + /** + * Checks if the profile supports the specified command. + * + * @param string $command Command ID. + * @return Boolean + */ public function supportsCommand($command); + + /** + * Checks if the profile supports the specified list of commands. + * + * @param array $commands List of command IDs. + * @return string + */ public function supportsCommands(Array $commands); + + /** + * Creates a new command instance. + * + * @param string $method Command ID. + * @param array $arguments Arguments for the command. + * @return Predis\Commands\ICommand + */ public function createCommand($method, $arguments = array()); } diff --git a/lib/Predis/Profiles/ServerProfile.php b/lib/Predis/Profiles/ServerProfile.php index 03231894..3e5c0ebb 100644 --- a/lib/Predis/Profiles/ServerProfile.php +++ b/lib/Predis/Profiles/ServerProfile.php @@ -15,6 +15,11 @@ use Predis\ClientException; use Predis\Commands\Processors\ICommandProcessor; use Predis\Commands\Processors\IProcessingSupport; +/** + * Base class that implements common functionalities of server profiles. + * + * @author Daniele Alessandri + */ abstract class ServerProfile implements IServerProfile, IProcessingSupport { private static $_profiles; @@ -22,23 +27,48 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport private $_registeredCommands; private $_processor; + /** + * + */ public function __construct() { $this->_registeredCommands = $this->getSupportedCommands(); } + /** + * Returns a map of all the commands supported by the profile and their + * actual PHP classes. + * + * @return array + */ protected abstract function getSupportedCommands(); + /** + * Returns the default server profile. + * + * @return IServerProfile + */ public static function getDefault() { return self::get('default'); } + /** + * Returns the development server profile. + * + * @return IServerProfile + */ public static function getDevelopment() { return self::get('dev'); } + /** + * Returns a map of all the server profiles supported by default and their + * actual PHP classes. + * + * @return array + */ private static function getDefaultProfiles() { return array( @@ -51,6 +81,12 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport ); } + /** + * Registers a new server profile. + * + * @param string $alias Profile version or alias. + * @param string $profileClass FQN of a class implementing Predis\Profiles\IServerProfile. + */ public static function define($alias, $profileClass) { if (!isset(self::$_profiles)) { @@ -68,6 +104,12 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport self::$_profiles[$alias] = $profileClass; } + /** + * Returns the specified server profile. + * + * @param string $version Profile version or alias. + * @return IServerProfile + */ public static function get($version) { if (!isset(self::$_profiles)) { @@ -82,6 +124,9 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport return new $profile(); } + /** + * {@inheritdoc} + */ public function supportsCommands(Array $commands) { foreach ($commands as $command) { @@ -93,11 +138,17 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport return true; } + /** + * {@inheritdoc} + */ public function supportsCommand($command) { return isset($this->_registeredCommands[strtolower($command)]); } + /** + * {@inheritdoc} + */ public function createCommand($method, $arguments = array()) { $method = strtolower($method); @@ -116,6 +167,11 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport return $command; } + /** + * Defines new commands in the server profile. + * + * @param array $commands Named list of command IDs and their classes. + */ public function defineCommands(Array $commands) { foreach ($commands as $alias => $command) { @@ -123,6 +179,12 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport } } + /** + * Defines a new commands in the server profile. + * + * @param string $alias Command ID. + * @param string $command FQN of a class implementing Predis\Commands\ICommand. + */ public function defineCommand($alias, $command) { $commandReflection = new \ReflectionClass($command); @@ -132,6 +194,9 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport $this->_registeredCommands[strtolower($alias)] = $command; } + /** + * {@inheritdoc} + */ public function setProcessor(ICommandProcessor $processor) { if (!isset($processor)) { @@ -141,11 +206,19 @@ abstract class ServerProfile implements IServerProfile, IProcessingSupport $this->_processor = $processor; } + /** + * {@inheritdoc} + */ public function getProcessor() { return $this->_processor; } + /** + * Returns the version of server profile as its string representation. + * + * @return string + */ public function __toString() { return $this->getVersion(); diff --git a/lib/Predis/Profiles/ServerVersion12.php b/lib/Predis/Profiles/ServerVersion12.php index e1208e97..d89caebb 100644 --- a/lib/Predis/Profiles/ServerVersion12.php +++ b/lib/Predis/Profiles/ServerVersion12.php @@ -11,13 +11,24 @@ namespace Predis\Profiles; +/** + * Server profile for Redis v1.2.x. + * + * @author Daniele Alessandri + */ class ServerVersion12 extends ServerProfile { + /** + * {@inheritdoc} + */ public function getVersion() { return '1.2'; } + /** + * {@inheritdoc} + */ public function getSupportedCommands() { return array( diff --git a/lib/Predis/Profiles/ServerVersion20.php b/lib/Predis/Profiles/ServerVersion20.php index c811a628..8c64a597 100644 --- a/lib/Predis/Profiles/ServerVersion20.php +++ b/lib/Predis/Profiles/ServerVersion20.php @@ -11,13 +11,24 @@ namespace Predis\Profiles; +/** + * Server profile for Redis v2.0.x. + * + * @author Daniele Alessandri + */ class ServerVersion20 extends ServerProfile { + /** + * {@inheritdoc} + */ public function getVersion() { return '2.0'; } + /** + * {@inheritdoc} + */ public function getSupportedCommands() { return array( diff --git a/lib/Predis/Profiles/ServerVersion22.php b/lib/Predis/Profiles/ServerVersion22.php index baeaa14f..bd38c55c 100644 --- a/lib/Predis/Profiles/ServerVersion22.php +++ b/lib/Predis/Profiles/ServerVersion22.php @@ -11,13 +11,24 @@ namespace Predis\Profiles; +/** + * Server profile for Redis v2.2.x. + * + * @author Daniele Alessandri + */ class ServerVersion22 extends ServerProfile { + /** + * {@inheritdoc} + */ public function getVersion() { return '2.2'; } + /** + * {@inheritdoc} + */ public function getSupportedCommands() { return array( diff --git a/lib/Predis/Profiles/ServerVersion24.php b/lib/Predis/Profiles/ServerVersion24.php index e73c796e..133cf715 100644 --- a/lib/Predis/Profiles/ServerVersion24.php +++ b/lib/Predis/Profiles/ServerVersion24.php @@ -11,13 +11,24 @@ namespace Predis\Profiles; +/** + * Server profile for Redis v2.4.x. + * + * @author Daniele Alessandri + */ class ServerVersion24 extends ServerProfile { + /** + * {@inheritdoc} + */ public function getVersion() { return '2.4'; } + /** + * {@inheritdoc} + */ public function getSupportedCommands() { return array( diff --git a/lib/Predis/Profiles/ServerVersionNext.php b/lib/Predis/Profiles/ServerVersionNext.php index 5babe0d4..40a72c80 100644 --- a/lib/Predis/Profiles/ServerVersionNext.php +++ b/lib/Predis/Profiles/ServerVersionNext.php @@ -11,13 +11,24 @@ namespace Predis\Profiles; +/** + * Server profile for the current development version of Redis. + * + * @author Daniele Alessandri + */ class ServerVersionNext extends ServerVersion24 { + /** + * {@inheritdoc} + */ public function getVersion() { return '2.6'; } + /** + * {@inheritdoc} + */ public function getSupportedCommands() { return array_merge(parent::getSupportedCommands(), array( diff --git a/lib/Predis/Protocol/ICommandSerializer.php b/lib/Predis/Protocol/ICommandSerializer.php index 99a2f1ef..e0a71501 100644 --- a/lib/Predis/Protocol/ICommandSerializer.php +++ b/lib/Predis/Protocol/ICommandSerializer.php @@ -13,7 +13,18 @@ namespace Predis\Protocol; use Predis\Commands\ICommand; +/** + * Interface that defines a custom serializer for Redis commands. + * + * @author Daniele Alessandri + */ interface ICommandSerializer { + /** + * Serializes a Redis command. + * + * @param ICommand $command Redis command. + * @return string + */ public function serialize(ICommand $command); } diff --git a/lib/Predis/Protocol/IComposableProtocolProcessor.php b/lib/Predis/Protocol/IComposableProtocolProcessor.php index 268238c5..c9eefca1 100644 --- a/lib/Predis/Protocol/IComposableProtocolProcessor.php +++ b/lib/Predis/Protocol/IComposableProtocolProcessor.php @@ -11,10 +11,40 @@ namespace Predis\Protocol; +/** + * Interface that defines a customizable protocol processor that serializes + * Redis commands and parses replies returned by the server to PHP objects + * using a pluggable set of classes defining the underlying wire protocol. + * + * @author Daniele Alessandri + */ interface IComposableProtocolProcessor extends IProtocolProcessor { + /** + * Sets the command serializer to be used by the protocol processor. + * + * @param ICommandSerializer $serializer Command serializer. + */ public function setSerializer(ICommandSerializer $serializer); + + /** + * Returns the command serializer used by the protocol processor. + * + * @return ICommandSerializer + */ public function getSerializer(); + + /** + * Sets the response reader to be used by the protocol processor. + * + * @param IResponseReader $reader Response reader. + */ public function setReader(IResponseReader $reader); + + /** + * Returns the response reader used by the protocol processor. + * + * @return IResponseReader + */ public function getReader(); } diff --git a/lib/Predis/Protocol/IProtocolProcessor.php b/lib/Predis/Protocol/IProtocolProcessor.php index cecf896f..1a149da1 100644 --- a/lib/Predis/Protocol/IProtocolProcessor.php +++ b/lib/Predis/Protocol/IProtocolProcessor.php @@ -14,8 +14,27 @@ namespace Predis\Protocol; use Predis\Commands\ICommand; use Predis\Network\IConnectionComposable; +/** + * Interface that defines a protocol processor that serializes Redis commands + * and parses replies returned by the server to PHP objects. + * + * @author Daniele Alessandri + */ interface IProtocolProcessor extends IResponseReader { + /** + * Writes a Redis command on the specified connection. + * + * @param IConnectionComposable $connection Connection to Redis. + * @param ICommand $command Redis command. + */ public function write(IConnectionComposable $connection, ICommand $command); + + /** + * Sets the options for the protocol processor. + * + * @param string $option Name of the option. + * @param mixed $value Value of the option. + */ public function setOption($option, $value); } diff --git a/lib/Predis/Protocol/IResponseHandler.php b/lib/Predis/Protocol/IResponseHandler.php index d79ffa8d..fa14ccbb 100644 --- a/lib/Predis/Protocol/IResponseHandler.php +++ b/lib/Predis/Protocol/IResponseHandler.php @@ -13,7 +13,20 @@ namespace Predis\Protocol; use Predis\Network\IConnectionComposable; +/** + * Interface that defines an handler able to parse a reply. + * + * @author Daniele Alessandri + */ interface IResponseHandler { + /** + * Parses a type of reply returned by Redis and reads more data from the + * connection if needed. + * + * @param IConnectionComposable $connection Connection to Redis. + * @param string $payload Initial payload of the reply. + * @return mixed + */ function handle(IConnectionComposable $connection, $payload); } diff --git a/lib/Predis/Protocol/IResponseReader.php b/lib/Predis/Protocol/IResponseReader.php index f1d7f009..f185b247 100644 --- a/lib/Predis/Protocol/IResponseReader.php +++ b/lib/Predis/Protocol/IResponseReader.php @@ -13,7 +13,19 @@ namespace Predis\Protocol; use Predis\Network\IConnectionComposable; +/** + * Interface that defines a response reader able to parse replies returned by + * Redis and deserialize them to PHP objects. + * + * @author Daniele Alessandri + */ interface IResponseReader { + /** + * Reads replies from a connection to Redis and deserializes them. + * + * @param IConnectionComposable $connection Connection to Redis. + * @return mixed + */ public function read(IConnectionComposable $connection); } diff --git a/lib/Predis/Protocol/ProtocolException.php b/lib/Predis/Protocol/ProtocolException.php index 16718d89..a39565d7 100644 --- a/lib/Predis/Protocol/ProtocolException.php +++ b/lib/Predis/Protocol/ProtocolException.php @@ -13,6 +13,12 @@ namespace Predis\Protocol; use Predis\CommunicationException; +/** + * Exception class that identifies errors encountered while + * handling the Redis wire protocol. + * + * @author Daniele Alessandri + */ class ProtocolException extends CommunicationException { } diff --git a/lib/Predis/Protocol/Text/ComposableTextProtocol.php b/lib/Predis/Protocol/Text/ComposableTextProtocol.php index f0b90467..f3446263 100644 --- a/lib/Predis/Protocol/Text/ComposableTextProtocol.php +++ b/lib/Predis/Protocol/Text/ComposableTextProtocol.php @@ -17,11 +17,22 @@ use Predis\Protocol\ICommandSerializer; use Predis\Protocol\IComposableProtocolProcessor; use Predis\Network\IConnectionComposable; +/** + * Implements a customizable protocol processor that uses the standard Redis + * wire protocol to serialize Redis commands and parse replies returned by + * the server using a pluggable set of classes. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ComposableTextProtocol implements IComposableProtocolProcessor { private $_serializer; private $_reader; + /** + * @param array $options Set of options used to initialize the protocol processor. + */ public function __construct(Array $options = array()) { $this->setSerializer(new TextCommandSerializer()); @@ -32,6 +43,11 @@ class ComposableTextProtocol implements IComposableProtocolProcessor } } + /** + * Initializes the protocol processor using a set of options. + * + * @param array $options Set of options. + */ private function initializeOptions(Array $options) { foreach ($options as $k => $v) { @@ -39,6 +55,9 @@ class ComposableTextProtocol implements IComposableProtocolProcessor } } + /** + * {@inheritdoc} + */ public function setOption($option, $value) { switch ($option) { @@ -57,36 +76,57 @@ class ComposableTextProtocol implements IComposableProtocolProcessor } } + /** + * {@inheritdoc} + */ public function serialize(ICommand $command) { return $this->_serializer->serialize($command); } + /** + * {@inheritdoc} + */ public function write(IConnectionComposable $connection, ICommand $command) { $connection->writeBytes($this->_serializer->serialize($command)); } + /** + * {@inheritdoc} + */ public function read(IConnectionComposable $connection) { return $this->_reader->read($connection); } + /** + * {@inheritdoc} + */ public function setSerializer(ICommandSerializer $serializer) { $this->_serializer = $serializer; } + /** + * {@inheritdoc} + */ public function getSerializer() { return $this->_serializer; } + /** + * {@inheritdoc} + */ public function setReader(IResponseReader $reader) { $this->_reader = $reader; } + /** + * {@inheritdoc} + */ public function getReader() { return $this->_reader; diff --git a/lib/Predis/Protocol/Text/ResponseBulkHandler.php b/lib/Predis/Protocol/Text/ResponseBulkHandler.php index b641e2f3..f709480b 100644 --- a/lib/Predis/Protocol/Text/ResponseBulkHandler.php +++ b/lib/Predis/Protocol/Text/ResponseBulkHandler.php @@ -16,8 +16,22 @@ use Predis\Protocol\IResponseHandler; use Predis\Protocol\ProtocolException; use Predis\Network\IConnectionComposable; +/** + * Implements a response handler for bulk replies using the standard wire + * protocol defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ResponseBulkHandler implements IResponseHandler { + /** + * Handles a bulk reply returned by Redis. + * + * @param IConnectionComposable $connection Connection to Redis. + * @param string $lengthString Bytes size of the bulk reply. + * @return string + */ public function handle(IConnectionComposable $connection, $lengthString) { $length = (int) $lengthString; diff --git a/lib/Predis/Protocol/Text/ResponseErrorHandler.php b/lib/Predis/Protocol/Text/ResponseErrorHandler.php index 3f8011f6..724b7076 100644 --- a/lib/Predis/Protocol/Text/ResponseErrorHandler.php +++ b/lib/Predis/Protocol/Text/ResponseErrorHandler.php @@ -15,8 +15,21 @@ use Predis\ServerException; use Predis\Protocol\IResponseHandler; use Predis\Network\IConnectionComposable; +/** + * Implements a response handler for error replies using the standard wire + * protocol defined by Redis. + * + * This handler throws an exception to notify the user that an error has + * occurred on the server. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ResponseErrorHandler implements IResponseHandler { + /** + * {@inheritdoc} + */ public function handle(IConnectionComposable $connection, $errorMessage) { throw new ServerException($errorMessage); diff --git a/lib/Predis/Protocol/Text/ResponseErrorSilentHandler.php b/lib/Predis/Protocol/Text/ResponseErrorSilentHandler.php index 0e3a9306..48390918 100644 --- a/lib/Predis/Protocol/Text/ResponseErrorSilentHandler.php +++ b/lib/Predis/Protocol/Text/ResponseErrorSilentHandler.php @@ -15,8 +15,21 @@ use Predis\ResponseError; use Predis\Protocol\IResponseHandler; use Predis\Network\IConnectionComposable; +/** + * Implements a response handler for error replies using the standard wire + * protocol defined by Redis. + * + * This handler returns a reply object to notify the user that an error has + * occurred on the server. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ResponseErrorSilentHandler implements IResponseHandler { + /** + * {@inheritdoc} + */ public function handle(IConnectionComposable $connection, $errorMessage) { return new ResponseError($errorMessage); diff --git a/lib/Predis/Protocol/Text/ResponseIntegerHandler.php b/lib/Predis/Protocol/Text/ResponseIntegerHandler.php index 15c009a3..03aa8c86 100644 --- a/lib/Predis/Protocol/Text/ResponseIntegerHandler.php +++ b/lib/Predis/Protocol/Text/ResponseIntegerHandler.php @@ -16,8 +16,22 @@ use Predis\Protocol\IResponseHandler; use Predis\Protocol\ProtocolException; use Predis\Network\IConnectionComposable; +/** + * Implements a response handler for integer replies using the standard wire + * protocol defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ResponseIntegerHandler implements IResponseHandler { + /** + * Handles an integer reply returned by Redis. + * + * @param IConnectionComposable $connection Connection to Redis. + * @param string $number String representation of an integer. + * @return int + */ public function handle(IConnectionComposable $connection, $number) { if (is_numeric($number)) { diff --git a/lib/Predis/Protocol/Text/ResponseMultiBulkHandler.php b/lib/Predis/Protocol/Text/ResponseMultiBulkHandler.php index daa5cdf9..6a137482 100644 --- a/lib/Predis/Protocol/Text/ResponseMultiBulkHandler.php +++ b/lib/Predis/Protocol/Text/ResponseMultiBulkHandler.php @@ -16,8 +16,22 @@ use Predis\Protocol\IResponseHandler; use Predis\Protocol\ProtocolException; use Predis\Network\IConnectionComposable; +/** + * Implements a response handler for multi-bulk replies using the standard + * wire protocol defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ResponseMultiBulkHandler implements IResponseHandler { + /** + * Handles a multi-bulk reply returned by Redis. + * + * @param IConnectionComposable $connection Connection to Redis. + * @param string $lengthString Number of items in the multi-bulk reply. + * @return array + */ public function handle(IConnectionComposable $connection, $lengthString) { $length = (int) $lengthString; diff --git a/lib/Predis/Protocol/Text/ResponseMultiBulkStreamHandler.php b/lib/Predis/Protocol/Text/ResponseMultiBulkStreamHandler.php index 864117b0..37dba45b 100644 --- a/lib/Predis/Protocol/Text/ResponseMultiBulkStreamHandler.php +++ b/lib/Predis/Protocol/Text/ResponseMultiBulkStreamHandler.php @@ -17,8 +17,22 @@ use Predis\Protocol\ProtocolException; use Predis\Network\IConnectionComposable; use Predis\Iterators\MultiBulkResponseSimple; +/** + * Implements a response handler for iterable multi-bulk replies using the + * standard wire protocol defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ResponseMultiBulkStreamHandler implements IResponseHandler { + /** + * Handles a multi-bulk reply returned by Redis in a streamable fashion. + * + * @param IConnectionComposable $connection Connection to Redis. + * @param string $lengthString Number of items in the multi-bulk reply. + * @return MultiBulkResponseSimple + */ public function handle(IConnectionComposable $connection, $lengthString) { $length = (int) $lengthString; diff --git a/lib/Predis/Protocol/Text/ResponseStatusHandler.php b/lib/Predis/Protocol/Text/ResponseStatusHandler.php index a05fd405..79bd54af 100644 --- a/lib/Predis/Protocol/Text/ResponseStatusHandler.php +++ b/lib/Predis/Protocol/Text/ResponseStatusHandler.php @@ -15,8 +15,18 @@ use Predis\ResponseQueued; use Predis\Protocol\IResponseHandler; use Predis\Network\IConnectionComposable; +/** + * Implements a response handler for status replies using the standard wire + * protocol defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class ResponseStatusHandler implements IResponseHandler { + /** + * {@inheritdoc} + */ public function handle(IConnectionComposable $connection, $status) { switch ($status) { diff --git a/lib/Predis/Protocol/Text/TextCommandSerializer.php b/lib/Predis/Protocol/Text/TextCommandSerializer.php index 2757559f..3e0357d1 100644 --- a/lib/Predis/Protocol/Text/TextCommandSerializer.php +++ b/lib/Predis/Protocol/Text/TextCommandSerializer.php @@ -14,8 +14,18 @@ namespace Predis\Protocol\Text; use Predis\Commands\ICommand; use Predis\Protocol\ICommandSerializer; +/** + * Implements a pluggable command serializer using the standard wire protocol + * defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class TextCommandSerializer implements ICommandSerializer { + /** + * {@inheritdoc} + */ public function serialize(ICommand $command) { $commandId = $command->getId(); diff --git a/lib/Predis/Protocol/Text/TextProtocol.php b/lib/Predis/Protocol/Text/TextProtocol.php index d5051d23..b9349bde 100644 --- a/lib/Predis/Protocol/Text/TextProtocol.php +++ b/lib/Predis/Protocol/Text/TextProtocol.php @@ -21,6 +21,12 @@ use Predis\Protocol\ProtocolException; use Predis\Network\IConnectionComposable; use Predis\Iterators\MultiBulkResponseSimple; +/** + * Implements a protocol processor for the standard wire protocol defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class TextProtocol implements IProtocolProcessor { const NEWLINE = "\r\n"; @@ -41,6 +47,9 @@ class TextProtocol implements IProtocolProcessor private $_throwErrors; private $_serializer; + /** + * + */ public function __construct() { $this->_mbiterable = false; @@ -48,11 +57,17 @@ class TextProtocol implements IProtocolProcessor $this->_serializer = new TextCommandSerializer(); } + /** + * {@inheritdoc} + */ public function write(IConnectionComposable $connection, ICommand $command) { $connection->writeBytes($this->_serializer->serialize($command)); } + /** + * {@inheritdoc} + */ public function read(IConnectionComposable $connection) { $chunk = $connection->readLine(); @@ -112,6 +127,9 @@ class TextProtocol implements IProtocolProcessor } } + /** + * {@inheritdoc} + */ public function setOption($option, $value) { switch ($option) { diff --git a/lib/Predis/Protocol/Text/TextResponseReader.php b/lib/Predis/Protocol/Text/TextResponseReader.php index cc6e0f12..81f8a005 100644 --- a/lib/Predis/Protocol/Text/TextResponseReader.php +++ b/lib/Predis/Protocol/Text/TextResponseReader.php @@ -17,15 +17,29 @@ use Predis\Protocol\IResponseHandler; use Predis\Protocol\ProtocolException; use Predis\Network\IConnectionComposable; +/** + * Implements a pluggable response reader using the standard wire protocol + * defined by Redis. + * + * @link http://redis.io/topics/protocol + * @author Daniele Alessandri + */ class TextResponseReader implements IResponseReader { private $_prefixHandlers; + /** + * + */ public function __construct() { $this->_prefixHandlers = $this->getDefaultHandlers(); } + /** + * Returns the default set of response handlers for all the type of replies + * that can be returned by Redis. + */ private function getDefaultHandlers() { return array( @@ -37,11 +51,25 @@ class TextResponseReader implements IResponseReader ); } + /** + * Sets a response handler for a certain prefix that identifies a type of + * reply that can be returned by Redis. + * + * @param string $prefix Identifier for a type of reply. + * @param IResponseHandler $handler Response handler for the reply. + */ public function setHandler($prefix, IResponseHandler $handler) { $this->_prefixHandlers[$prefix] = $handler; } + /** + * Returns the response handler associated to a certain type of reply that + * can be returned by Redis. + * + * @param string $prefix Identifier for a type of reply. + * @return IResponseHandler + */ public function getHandler($prefix) { if (isset($this->_prefixHandlers[$prefix])) { @@ -49,6 +77,9 @@ class TextResponseReader implements IResponseReader } } + /** + * {@inheritdoc} + */ public function read(IConnectionComposable $connection) { $header = $connection->readLine(); @@ -66,6 +97,13 @@ class TextResponseReader implements IResponseReader return $handler->handle($connection, substr($header, 1)); } + /** + * Helper method used to handle a protocol error generated while reading a + * reply from a connection to Redis. + * + * @param IConnectionComposable $connection Connection to Redis that generated the error. + * @param string $message Error message. + */ private function protocolError(IConnectionComposable $connection, $message) { Helpers::onCommunicationException(new ProtocolException($connection, $message)); diff --git a/lib/Predis/PubSubContext.php b/lib/Predis/PubSubContext.php index d0e7ded2..a5832b29 100644 --- a/lib/Predis/PubSubContext.php +++ b/lib/Predis/PubSubContext.php @@ -11,6 +11,11 @@ namespace Predis; +/** + * Client-side abstraction of a Publish / Subscribe context. + * + * @author Daniele Alessandri + */ class PubSubContext implements \Iterator { const SUBSCRIBE = 'subscribe'; @@ -28,6 +33,10 @@ class PubSubContext implements \Iterator private $_position; private $_options; + /** + * @param Client Client instance used by the context. + * @param array Options for the context initialization. + */ public function __construct(Client $client, Array $options = null) { $this->checkCapabilities($client); @@ -39,11 +48,20 @@ class PubSubContext implements \Iterator $this->genericSubscribeInit('psubscribe'); } + /** + * Automatically closes the context when PHP's garbage collector kicks in. + */ public function __destruct() { $this->closeContext(); } + /** + * Checks if the passed client instance satisfies the required conditions + * needed to initialize a Publish / Subscribe context. + * + * @param Client Client instance used by the context. + */ private function checkCapabilities(Client $client) { if (Helpers::isCluster($client->getConnection())) { @@ -61,6 +79,11 @@ class PubSubContext implements \Iterator } } + /** + * This method shares the logic to handle both SUBSCRIBE and PSUBSCRIBE. + * + * @param string $subscribeAction Type of subscription. + */ private function genericSubscribeInit($subscribeAction) { if (isset($this->_options[$subscribeAction])) { @@ -68,33 +91,62 @@ class PubSubContext implements \Iterator } } + /** + * Checks if the specified flag is valid in the state of the context. + * + * @param int $value Flag. + * @return Boolean + */ private function isFlagSet($value) { return ($this->_statusFlags & $value) === $value; } + /** + * Subscribes to the specified channels. + * + * @param mixed $arg,... One or more channel names. + */ public function subscribe(/* arguments */) { $this->writeCommand(self::SUBSCRIBE, func_get_args()); $this->_statusFlags |= self::STATUS_SUBSCRIBED; } + /** + * Unsubscribes from the specified channels. + * + * @param mixed $arg,... One or more channel names. + */ public function unsubscribe(/* arguments */) { $this->writeCommand(self::UNSUBSCRIBE, func_get_args()); } + /** + * Subscribes to the specified channels using a pattern. + * + * @param mixed $arg,... One or more channel name patterns. + */ public function psubscribe(/* arguments */) { $this->writeCommand(self::PSUBSCRIBE, func_get_args()); $this->_statusFlags |= self::STATUS_PSUBSCRIBED; } + /** + * Unsubscribes from the specified channels using a pattern. + * + * @param mixed $arg,... One or more channel name patterns. + */ public function punsubscribe(/* arguments */) { $this->writeCommand(self::PUNSUBSCRIBE, func_get_args()); } + /** + * Closes the context by unsubscribing from all the subscribed channels. + */ public function closeContext() { if ($this->valid()) { @@ -107,6 +159,12 @@ class PubSubContext implements \Iterator } } + /** + * Write a Redis command on the underlying connection. + * + * @param string $method ID of the command. + * @param array $arguments List of arguments. + */ private function writeCommand($method, $arguments) { $arguments = Helpers::filterArrayArguments($arguments); @@ -114,21 +172,36 @@ class PubSubContext implements \Iterator $this->_client->getConnection()->writeCommand($command); } + /** + * {@inheritdoc} + */ public function rewind() { // NOOP } + /** + * Returns the last message payload retrieved from the server and generated + * by one of the active subscriptions. + * + * @return array + */ public function current() { return $this->getValue(); } + /** + * {@inheritdoc} + */ public function key() { return $this->_position; } + /** + * {@inheritdoc} + */ public function next() { if ($this->isFlagSet(self::STATUS_VALID)) { @@ -138,6 +211,11 @@ class PubSubContext implements \Iterator return $this->_position; } + /** + * Checks if the the context is still in a valid state to continue. + * + * @return Boolean + */ public function valid() { $isValid = $this->isFlagSet(self::STATUS_VALID); @@ -147,11 +225,20 @@ class PubSubContext implements \Iterator return $isValid && $hasSubscriptions; } + /** + * Resets the state of the context. + */ private function invalidate() { $this->_statusFlags = 0x0000; } + /** + * Waits for a new message from the server generated by one of the active + * subscriptions and returns it when available. + * + * @return array + */ private function getValue() { $response = $this->_client->getConnection()->read(); diff --git a/lib/Predis/ResponseError.php b/lib/Predis/ResponseError.php index ce241506..2140e192 100644 --- a/lib/Predis/ResponseError.php +++ b/lib/Predis/ResponseError.php @@ -11,26 +11,46 @@ namespace Predis; +/** + * Represents an error returned by Redis (-ERR replies) during the execution + * of a command on the server. + * + * @author Daniele Alessandri + */ class ResponseError implements IRedisServerError { private $_message; + /** + * @param string $message Error message returned by Redis + */ public function __construct($message) { $this->_message = $message; } + /** + * {@inheritdoc} + */ public function getMessage() { return $this->_message; } + /** + * {@inheritdoc} + */ public function getErrorType() { list($errorType, ) = explode(' ', $this->getMessage(), 2); return $errorType; } + /** + * Converts the object to its string representation. + * + * @return string + */ public function __toString() { return $this->getMessage(); diff --git a/lib/Predis/ResponseQueued.php b/lib/Predis/ResponseQueued.php index 38d34fc1..31f4f4b5 100644 --- a/lib/Predis/ResponseQueued.php +++ b/lib/Predis/ResponseQueued.php @@ -11,18 +11,41 @@ namespace Predis; +/** + * Represents a +QUEUED response returned by Redis as a reply to each command + * executed inside a MULTI/ EXEC transaction. + * + * @author Daniele Alessandri + */ class ResponseQueued implements IReplyObject { + /** + * Converts the object to its string representation. + * + * @return string + */ public function __toString() { return 'QUEUED'; } + /** + * Returns the value of the specified property. + * + * @param string $property Name of the property. + * @return mixed + */ public function __get($property) { return $property === 'queued'; } + /** + * Checks if the specified property is set. + * + * @param string $property Name of the property. + * @return Boolean + */ public function __isset($property) { return $property === 'queued'; diff --git a/lib/Predis/ServerException.php b/lib/Predis/ServerException.php index 9464e015..15d898b1 100644 --- a/lib/Predis/ServerException.php +++ b/lib/Predis/ServerException.php @@ -11,14 +11,29 @@ namespace Predis; +/** + * Exception class that identifies server-side Redis errors. + * + * @author Daniele Alessandri + */ class ServerException extends PredisException implements IRedisServerError { + /** + * Gets the type of the error returned by Redis. + * + * @return string + */ public function getErrorType() { list($errorType, ) = explode(' ', $this->getMessage(), 2); return $errorType; } + /** + * Converts the exception to an instance of ResponseError. + * + * @return ResponseError + */ public function toResponseError() { return new ResponseError($this->getMessage()); diff --git a/lib/Predis/Transaction/AbortedMultiExecException.php b/lib/Predis/Transaction/AbortedMultiExecException.php index 08a8b5b5..9be48387 100644 --- a/lib/Predis/Transaction/AbortedMultiExecException.php +++ b/lib/Predis/Transaction/AbortedMultiExecException.php @@ -13,10 +13,20 @@ namespace Predis\Transaction; use Predis\PredisException; +/** + * Exception class that identifies MULTI / EXEC transactions aborted by Redis. + * + * @author Daniele Alessandri + */ class AbortedMultiExecException extends PredisException { private $_transaction; + /** + * @param MultiExecContext $transaction Transaction that generated the exception. + * @param string $message Error message. + * @param int $code Error code. + */ public function __construct(MultiExecContext $transaction, $message, $code = null) { parent::__construct($message, $code); @@ -24,6 +34,11 @@ class AbortedMultiExecException extends PredisException $this->_transaction = $transaction; } + /** + * Returns the transaction that generated the exception. + * + * @return MultiExecContext + */ public function getTransaction() { return $this->_transaction; diff --git a/lib/Predis/Transaction/MultiExecContext.php b/lib/Predis/Transaction/MultiExecContext.php index c352c1e4..b035bb53 100644 --- a/lib/Predis/Transaction/MultiExecContext.php +++ b/lib/Predis/Transaction/MultiExecContext.php @@ -19,6 +19,11 @@ use Predis\ServerException; use Predis\CommunicationException; use Predis\Protocol\ProtocolException; +/** + * Client-side abstraction of a Redis transaction based on MULTI / EXEC. + * + * @author Daniele Alessandri + */ class MultiExecContext { const STATE_RESET = 0x00000; @@ -35,6 +40,10 @@ class MultiExecContext protected $_options; protected $_commands; + /** + * @param Client Client instance used by the context. + * @param array Options for the context initialization. + */ public function __construct(Client $client, Array $options = null) { $this->checkCapabilities($client); @@ -43,31 +52,63 @@ class MultiExecContext $this->reset(); } + /** + * Sets the internal state flags. + * + * @param int $flags Set of flags + */ protected function setState($flags) { $this->_state = $flags; } + /** + * Gets the internal state flags. + * + * @return int + */ protected function getState() { return $this->_state; } + /** + * Sets one or more flags. + * + * @param int $flags Set of flags + */ protected function flagState($flags) { $this->_state |= $flags; } + /** + * Resets one or more flags. + * + * @param int $flags Set of flags + */ protected function unflagState($flags) { $this->_state &= ~$flags; } + /** + * Checks is a flag is set. + * + * @param int $flags Flag + * @return Boolean + */ protected function checkState($flags) { return ($this->_state & $flags) === $flags; } + /** + * Checks if the passed client instance satisfies the required conditions + * needed to initialize a transaction context. + * + * @param Client Client instance used by the context. + */ private function checkCapabilities(Client $client) { if (Helpers::isCluster($client->getConnection())) { @@ -87,6 +128,9 @@ class MultiExecContext $this->_canWatch = $profile->supportsCommands(array('watch', 'unwatch')); } + /** + * Checks if WATCH and UNWATCH are supported by the server profile. + */ private function isWatchSupported() { if ($this->_canWatch === false) { @@ -96,12 +140,18 @@ class MultiExecContext } } + /** + * Resets the state of a transaction. + */ protected function reset() { $this->setState(self::STATE_RESET); $this->_commands = array(); } + /** + * Initializes a new transaction. + */ protected function initialize() { if ($this->checkState(self::STATE_INITIALIZED)) { @@ -131,6 +181,13 @@ class MultiExecContext $this->flagState(self::STATE_INITIALIZED); } + /** + * Dinamically invokes a Redis command with the specified arguments. + * + * @param string $method Command ID. + * @param array $arguments Arguments for the command. + * @return MultiExecContext + */ public function __call($method, $arguments) { $this->initialize(); @@ -152,6 +209,12 @@ class MultiExecContext return $this; } + /** + * Executes WATCH on one or more keys. + * + * @param string|array $keys One or more keys. + * @return mixed + */ public function watch($keys) { $this->isWatchSupported(); @@ -166,6 +229,11 @@ class MultiExecContext return $watchReply; } + /** + * Finalizes the transaction on the server by executing MULTI on the server. + * + * @return MultiExecContext + */ public function multi() { if ($this->checkState(self::STATE_INITIALIZED | self::STATE_CAS)) { @@ -179,6 +247,11 @@ class MultiExecContext return $this; } + /** + * Executes UNWATCH. + * + * @return MultiExecContext + */ public function unwatch() { $this->isWatchSupported(); @@ -188,6 +261,12 @@ class MultiExecContext return $this; } + /** + * Resets a transaction by UNWATCHing the keys that are being WATCHed and + * DISCARDing the pending commands that have been already sent to the server. + * + * @return MultiExecContext + */ public function discard() { if ($this->checkState(self::STATE_INITIALIZED)) { @@ -200,12 +279,22 @@ class MultiExecContext return $this; } + /** + * Executes the whole transaction. + * + * @return mixed + */ public function exec() { return $this->execute(); } - private function checkBeforeExecution($block) + /** + * Checks the state of the transaction before execution. + * + * @param mixed $callable Callback for execution. + */ + private function checkBeforeExecution($callable) { if ($this->checkState(self::STATE_INSIDEBLOCK)) { throw new ClientException( @@ -213,8 +302,8 @@ class MultiExecContext ); } - if ($block) { - if (!is_callable($block)) { + if ($callable) { + if (!is_callable($callable)) { throw new \InvalidArgumentException( 'Argument passed must be a callable object' ); @@ -228,7 +317,7 @@ class MultiExecContext } } - if (isset($this->_options['retry']) && !isset($block)) { + if (isset($this->_options['retry']) && !isset($callable)) { $this->discard(); throw new \InvalidArgumentException( 'Automatic retries can be used only when a transaction block is provided' @@ -236,17 +325,23 @@ class MultiExecContext } } - public function execute($block = null) + /** + * Handles the actual execution of the whole transaction. + * + * @param mixed $callable Callback for execution. + * @return array + */ + public function execute($callable = null) { - $this->checkBeforeExecution($block); + $this->checkBeforeExecution($callable); $reply = null; $returnValues = array(); $attemptsLeft = isset($this->_options['retry']) ? (int)$this->_options['retry'] : 0; do { - if ($block !== null) { - $this->executeTransactionBlock($block); + if ($callable !== null) { + $this->executeTransactionBlock($callable); } if (count($this->_commands) === 0) { @@ -298,13 +393,18 @@ class MultiExecContext return $returnValues; } - protected function executeTransactionBlock($block) + /** + * Passes the current transaction context to a callable block for execution. + * + * @param mixed $callable Callback. + */ + protected function executeTransactionBlock($callable) { $blockException = null; $this->flagState(self::STATE_INSIDEBLOCK); try { - $block($this); + $callable($this); } catch (CommunicationException $exception) { $blockException = $exception; @@ -324,6 +424,11 @@ class MultiExecContext } } + /** + * Helper method that handles protocol errors encountered inside a transaction. + * + * @param string $message Error message. + */ private function onProtocolError($message) { // Since a MULTI/EXEC block cannot be initialized over a clustered