mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Support caching with Redis (#1009)
This commit is contained in:
parent
f180c2fbec
commit
7e4479d655
264 changed files with 18830 additions and 5 deletions
|
|
@ -21,8 +21,8 @@ if (!\defined('RAINLOOP_APP_LIBRARIES_PATH'))
|
||||||
*/
|
*/
|
||||||
function rainLoopSplAutoloadNamespaces()
|
function rainLoopSplAutoloadNamespaces()
|
||||||
{
|
{
|
||||||
return RAINLOOP_INCLUDE_AS_API_DEF ? array('RainLoop') :
|
return RAINLOOP_INCLUDE_AS_API_DEF ? array('RainLoop', 'Predis') :
|
||||||
array('RainLoop', 'Facebook', 'GuzzleHttp', 'PHPThumb', 'SabreForRainLoop', 'Imagine', 'Detection');
|
array('RainLoop', 'Facebook', 'GuzzleHttp', 'PHPThumb', 'Predis', 'SabreForRainLoop', 'Imagine', 'Detection');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
160
rainloop/v/0.0.0/app/libraries/MailSo/Cache/Drivers/Redis.php
Normal file
160
rainloop/v/0.0.0/app/libraries/MailSo/Cache/Drivers/Redis.php
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of MailSo.
|
||||||
|
*
|
||||||
|
* (c) 2014 Usenko Timur
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MailSo\Cache\Drivers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category MailSo
|
||||||
|
* @package Cache
|
||||||
|
* @subpackage Drivers
|
||||||
|
*/
|
||||||
|
class Redis implements \MailSo\Cache\DriverInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $sHost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $iPost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $iExpire;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Memcache|null
|
||||||
|
*/
|
||||||
|
private $oRedis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $sKeyPrefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sHost = '127.0.0.1'
|
||||||
|
* @param int $iPost = 6379
|
||||||
|
* @param int $iExpire = 43200
|
||||||
|
* @param string $sKeyPrefix = ''
|
||||||
|
*/
|
||||||
|
private function __construct($sHost = '127.0.0.1', $iPost = 6379, $iExpire = 43200, $sKeyPrefix = '')
|
||||||
|
{
|
||||||
|
$this->sHost = $sHost;
|
||||||
|
$this->iPost = $iPost;
|
||||||
|
$this->iExpire = 0 < $iExpire ? $iExpire : 43200;
|
||||||
|
|
||||||
|
$this->oRedis = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$this->oRedis = new \Predis\Client('unix:' === substr($sHost, 0, 5) ? $sHost : array(
|
||||||
|
'host' => $sHost,
|
||||||
|
'port' => $iPost
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->oRedis->connect();
|
||||||
|
|
||||||
|
if (!$this->oRedis->isConnected())
|
||||||
|
{
|
||||||
|
$this->oRedis = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $oExc)
|
||||||
|
{
|
||||||
|
$this->oRedis = null;
|
||||||
|
unset($oExc);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sKeyPrefix = $sKeyPrefix;
|
||||||
|
if (!empty($this->sKeyPrefix))
|
||||||
|
{
|
||||||
|
$this->sKeyPrefix =
|
||||||
|
\preg_replace('/[^a-zA-Z0-9_]/', '_', rtrim(trim($this->sKeyPrefix), '\\/')).'/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sHost = '127.0.0.1'
|
||||||
|
* @param int $iPost = 11211
|
||||||
|
* @param int $iExpire = 43200
|
||||||
|
* @param string $sKeyPrefix = ''
|
||||||
|
*
|
||||||
|
* @return \MailSo\Cache\Drivers\APC
|
||||||
|
*/
|
||||||
|
public static function NewInstance($sHost = '127.0.0.1', $iPost = 6379, $iExpire = 43200, $sKeyPrefix = '')
|
||||||
|
{
|
||||||
|
return new self($sHost, $iPost, $iExpire, $sKeyPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sKey
|
||||||
|
* @param string $sValue
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function Set($sKey, $sValue)
|
||||||
|
{
|
||||||
|
return $this->oRedis ? $this->oRedis->setex($this->generateCachedKey($sKey), $this->iExpire, $sValue) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sKey
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function Get($sKey)
|
||||||
|
{
|
||||||
|
$sValue = $this->oRedis ? $this->oRedis->get($this->generateCachedKey($sKey)) : '';
|
||||||
|
return \is_string($sValue) ? $sValue : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sKey
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function Delete($sKey)
|
||||||
|
{
|
||||||
|
if ($this->oRedis)
|
||||||
|
{
|
||||||
|
$this->oRedis->del($this->generateCachedKey($sKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $iTimeToClearInHours = 24
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function GC($iTimeToClearInHours = 24)
|
||||||
|
{
|
||||||
|
if (0 === $iTimeToClearInHours && $this->oRedis)
|
||||||
|
{
|
||||||
|
return $this->oRedis->flushdb();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sKey
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function generateCachedKey($sKey)
|
||||||
|
{
|
||||||
|
return $this->sKeyPrefix.\sha1($sKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
rainloop/v/0.0.0/app/libraries/Predis/Autoloader.php
Normal file
62
rainloop/v/0.0.0/app/libraries/Predis/Autoloader.php
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a lightweight PSR-0 compliant autoloader for Predis.
|
||||||
|
*
|
||||||
|
* @author Eric Naeseth <eric@thumbtack.com>
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class Autoloader
|
||||||
|
{
|
||||||
|
private $directory;
|
||||||
|
private $prefix;
|
||||||
|
private $prefixLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $baseDirectory Base directory where the source files are located.
|
||||||
|
*/
|
||||||
|
public function __construct($baseDirectory = __DIR__)
|
||||||
|
{
|
||||||
|
$this->directory = $baseDirectory;
|
||||||
|
$this->prefix = __NAMESPACE__.'\\';
|
||||||
|
$this->prefixLength = strlen($this->prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the autoloader class with the PHP SPL autoloader.
|
||||||
|
*
|
||||||
|
* @param bool $prepend Prepend the autoloader on the stack instead of appending it.
|
||||||
|
*/
|
||||||
|
public static function register($prepend = false)
|
||||||
|
{
|
||||||
|
spl_autoload_register(array(new self(), 'autoload'), true, $prepend);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)) {
|
||||||
|
$parts = explode('\\', substr($className, $this->prefixLength));
|
||||||
|
$filepath = $this->directory.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts).'.php';
|
||||||
|
|
||||||
|
if (is_file($filepath)) {
|
||||||
|
require $filepath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
523
rainloop/v/0.0.0/app/libraries/Predis/Client.php
Normal file
523
rainloop/v/0.0.0/app/libraries/Predis/Client.php
Normal file
|
|
@ -0,0 +1,523 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis;
|
||||||
|
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
use Predis\Command\RawCommand;
|
||||||
|
use Predis\Command\ScriptCommand;
|
||||||
|
use Predis\Configuration\Options;
|
||||||
|
use Predis\Configuration\OptionsInterface;
|
||||||
|
use Predis\Connection\AggregateConnectionInterface;
|
||||||
|
use Predis\Connection\ConnectionInterface;
|
||||||
|
use Predis\Connection\ParametersInterface;
|
||||||
|
use Predis\Monitor\Consumer as MonitorConsumer;
|
||||||
|
use Predis\Pipeline\Pipeline;
|
||||||
|
use Predis\PubSub\Consumer as PubSubConsumer;
|
||||||
|
use Predis\Response\ErrorInterface as ErrorResponseInterface;
|
||||||
|
use Predis\Response\ResponseInterface;
|
||||||
|
use Predis\Response\ServerException;
|
||||||
|
use Predis\Transaction\MultiExec as MultiExecTransaction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client class used for connecting and executing commands on Redis.
|
||||||
|
*
|
||||||
|
* This is the main high-level abstraction of Predis upon which various other
|
||||||
|
* abstractions are built. Internally it aggregates various other classes each
|
||||||
|
* one with its own responsibility and scope.
|
||||||
|
*
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class Client implements ClientInterface
|
||||||
|
{
|
||||||
|
const VERSION = '1.0.3';
|
||||||
|
|
||||||
|
protected $connection;
|
||||||
|
protected $options;
|
||||||
|
private $profile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $parameters Connection parameters for one or more servers.
|
||||||
|
* @param mixed $options Options to configure some behaviours of the client.
|
||||||
|
*/
|
||||||
|
public function __construct($parameters = null, $options = null)
|
||||||
|
{
|
||||||
|
$this->options = $this->createOptions($options ?: array());
|
||||||
|
$this->connection = $this->createConnection($parameters ?: array());
|
||||||
|
$this->profile = $this->options->profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of Predis\Configuration\Options from different
|
||||||
|
* types of arguments or simply returns the passed argument if it is an
|
||||||
|
* instance of Predis\Configuration\OptionsInterface.
|
||||||
|
*
|
||||||
|
* @param mixed $options Client options.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return OptionsInterface
|
||||||
|
*/
|
||||||
|
protected function createOptions($options)
|
||||||
|
{
|
||||||
|
if (is_array($options)) {
|
||||||
|
return new Options($options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($options instanceof OptionsInterface) {
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \InvalidArgumentException('Invalid type for client options.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates single or aggregate connections from different types of arguments
|
||||||
|
* (string, array) or returns the passed argument if it is an instance of a
|
||||||
|
* class implementing Predis\Connection\ConnectionInterface.
|
||||||
|
*
|
||||||
|
* Accepted types for connection parameters are:
|
||||||
|
*
|
||||||
|
* - Instance of Predis\Connection\ConnectionInterface.
|
||||||
|
* - Instance of Predis\Connection\ParametersInterface.
|
||||||
|
* - Array
|
||||||
|
* - String
|
||||||
|
* - Callable
|
||||||
|
*
|
||||||
|
* @param mixed $parameters Connection parameters or connection instance.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return ConnectionInterface
|
||||||
|
*/
|
||||||
|
protected function createConnection($parameters)
|
||||||
|
{
|
||||||
|
if ($parameters instanceof ConnectionInterface) {
|
||||||
|
return $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($parameters instanceof ParametersInterface || is_string($parameters)) {
|
||||||
|
return $this->options->connections->create($parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($parameters)) {
|
||||||
|
if (!isset($parameters[0])) {
|
||||||
|
return $this->options->connections->create($parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = $this->options;
|
||||||
|
|
||||||
|
if ($options->defined('aggregate')) {
|
||||||
|
$initializer = $this->getConnectionInitializerWrapper($options->aggregate);
|
||||||
|
$connection = $initializer($parameters, $options);
|
||||||
|
} else {
|
||||||
|
if ($options->defined('replication') && $replication = $options->replication) {
|
||||||
|
$connection = $replication;
|
||||||
|
} else {
|
||||||
|
$connection = $options->cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
$options->connections->aggregate($connection, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_callable($parameters)) {
|
||||||
|
$initializer = $this->getConnectionInitializerWrapper($parameters);
|
||||||
|
$connection = $initializer($this->options);
|
||||||
|
|
||||||
|
return $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \InvalidArgumentException('Invalid type for connection parameters.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a callable to make sure that its returned value represents a valid
|
||||||
|
* connection type.
|
||||||
|
*
|
||||||
|
* @param mixed $callable
|
||||||
|
*
|
||||||
|
* @return \Closure
|
||||||
|
*/
|
||||||
|
protected function getConnectionInitializerWrapper($callable)
|
||||||
|
{
|
||||||
|
return function () use ($callable) {
|
||||||
|
$connection = call_user_func_array($callable, func_get_args());
|
||||||
|
|
||||||
|
if (!$connection instanceof ConnectionInterface) {
|
||||||
|
throw new \UnexpectedValueException(
|
||||||
|
'The callable connection initializer returned an invalid type.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $connection;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getProfile()
|
||||||
|
{
|
||||||
|
return $this->profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getOptions()
|
||||||
|
{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new client instance for the specified connection ID or alias,
|
||||||
|
* only when working with an aggregate connection (cluster, replication).
|
||||||
|
* The new client instances uses the same options of the original one.
|
||||||
|
*
|
||||||
|
* @param string $connectionID Identifier of a connection.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return Client
|
||||||
|
*/
|
||||||
|
public function getClientFor($connectionID)
|
||||||
|
{
|
||||||
|
if (!$connection = $this->getConnectionById($connectionID)) {
|
||||||
|
throw new \InvalidArgumentException("Invalid connection ID: $connectionID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new static($connection, $this->options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the underlying connection and connects to the server.
|
||||||
|
*/
|
||||||
|
public function connect()
|
||||||
|
{
|
||||||
|
$this->connection->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the underlying connection and disconnects from the server.
|
||||||
|
*/
|
||||||
|
public function disconnect()
|
||||||
|
{
|
||||||
|
$this->connection->disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the underlying connection and disconnects from the server.
|
||||||
|
*
|
||||||
|
* This is the same as `Client::disconnect()` as it does not actually send
|
||||||
|
* the `QUIT` command to Redis, but simply closes the connection.
|
||||||
|
*/
|
||||||
|
public function quit()
|
||||||
|
{
|
||||||
|
$this->disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current state of the underlying connection.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isConnected()
|
||||||
|
{
|
||||||
|
return $this->connection->isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getConnection()
|
||||||
|
{
|
||||||
|
return $this->connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the specified connection from the aggregate connection when the
|
||||||
|
* client is in cluster or replication mode.
|
||||||
|
*
|
||||||
|
* @param string $connectionID Index or alias of the single connection.
|
||||||
|
*
|
||||||
|
* @throws NotSupportedException
|
||||||
|
*
|
||||||
|
* @return Connection\NodeConnectionInterface
|
||||||
|
*/
|
||||||
|
public function getConnectionById($connectionID)
|
||||||
|
{
|
||||||
|
if (!$this->connection instanceof AggregateConnectionInterface) {
|
||||||
|
throw new NotSupportedException(
|
||||||
|
'Retrieving connections by ID is supported only by aggregate connections.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->connection->getConnectionById($connectionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a command without filtering its arguments, parsing the response,
|
||||||
|
* applying any prefix to keys or throwing exceptions on Redis errors even
|
||||||
|
* regardless of client options.
|
||||||
|
*
|
||||||
|
* It is possibile to indentify Redis error responses from normal responses
|
||||||
|
* using the second optional argument which is populated by reference.
|
||||||
|
*
|
||||||
|
* @param array $arguments Command arguments as defined by the command signature.
|
||||||
|
* @param bool $error Set to TRUE when Redis returned an error response.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function executeRaw(array $arguments, &$error = null)
|
||||||
|
{
|
||||||
|
$error = false;
|
||||||
|
|
||||||
|
$response = $this->connection->executeCommand(
|
||||||
|
new RawCommand($arguments)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($response instanceof ResponseInterface) {
|
||||||
|
if ($response instanceof ErrorResponseInterface) {
|
||||||
|
$error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __call($commandID, $arguments)
|
||||||
|
{
|
||||||
|
return $this->executeCommand(
|
||||||
|
$this->createCommand($commandID, $arguments)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createCommand($commandID, $arguments = array())
|
||||||
|
{
|
||||||
|
return $this->profile->createCommand($commandID, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function executeCommand(CommandInterface $command)
|
||||||
|
{
|
||||||
|
$response = $this->connection->executeCommand($command);
|
||||||
|
|
||||||
|
if ($response instanceof ResponseInterface) {
|
||||||
|
if ($response instanceof ErrorResponseInterface) {
|
||||||
|
$response = $this->onErrorResponse($command, $response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $command->parseResponse($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles -ERR responses returned by Redis.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Redis command that generated the error.
|
||||||
|
* @param ErrorResponseInterface $response Instance of the error response.
|
||||||
|
*
|
||||||
|
* @throws ServerException
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function onErrorResponse(CommandInterface $command, ErrorResponseInterface $response)
|
||||||
|
{
|
||||||
|
if ($command instanceof ScriptCommand && $response->getErrorType() === 'NOSCRIPT') {
|
||||||
|
$eval = $this->createCommand('EVAL');
|
||||||
|
$eval->setRawArguments($command->getEvalArguments());
|
||||||
|
|
||||||
|
$response = $this->executeCommand($eval);
|
||||||
|
|
||||||
|
if (!$response instanceof ResponseInterface) {
|
||||||
|
$response = $command->parseResponse($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->options->exceptions) {
|
||||||
|
throw new ServerException($response->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the specified initializer method on `$this` by adjusting the
|
||||||
|
* actual invokation depending on the arity (0, 1 or 2 arguments). This is
|
||||||
|
* simply an utility method to create Redis contexts instances since they
|
||||||
|
* follow a common initialization path.
|
||||||
|
*
|
||||||
|
* @param string $initializer Method name.
|
||||||
|
* @param array $argv Arguments for the method.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function sharedContextFactory($initializer, $argv = null)
|
||||||
|
{
|
||||||
|
switch (count($argv)) {
|
||||||
|
case 0:
|
||||||
|
return $this->$initializer();
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return is_array($argv[0])
|
||||||
|
? $this->$initializer($argv[0])
|
||||||
|
: $this->$initializer(null, $argv[0]);
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
list($arg0, $arg1) = $argv;
|
||||||
|
|
||||||
|
return $this->$initializer($arg0, $arg1);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return $this->$initializer($this, $argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new pipeline context and returns it, or returns the results of
|
||||||
|
* a pipeline executed inside the optionally provided callable object.
|
||||||
|
*
|
||||||
|
* @param mixed ... Array of options, a callable for execution, or both.
|
||||||
|
*
|
||||||
|
* @return Pipeline|array
|
||||||
|
*/
|
||||||
|
public function pipeline(/* arguments */)
|
||||||
|
{
|
||||||
|
return $this->sharedContextFactory('createPipeline', func_get_args());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actual pipeline context initializer method.
|
||||||
|
*
|
||||||
|
* @param array $options Options for the context.
|
||||||
|
* @param mixed $callable Optional callable used to execute the context.
|
||||||
|
*
|
||||||
|
* @return Pipeline|array
|
||||||
|
*/
|
||||||
|
protected function createPipeline(array $options = null, $callable = null)
|
||||||
|
{
|
||||||
|
if (isset($options['atomic']) && $options['atomic']) {
|
||||||
|
$class = 'Predis\Pipeline\Atomic';
|
||||||
|
} elseif (isset($options['fire-and-forget']) && $options['fire-and-forget']) {
|
||||||
|
$class = 'Predis\Pipeline\FireAndForget';
|
||||||
|
} else {
|
||||||
|
$class = 'Predis\Pipeline\Pipeline';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @var ClientContextInterface
|
||||||
|
*/
|
||||||
|
$pipeline = new $class($this);
|
||||||
|
|
||||||
|
if (isset($callable)) {
|
||||||
|
return $pipeline->execute($callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $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 ... Array of options, a callable for execution, or both.
|
||||||
|
*
|
||||||
|
* @return MultiExecTransaction|array
|
||||||
|
*/
|
||||||
|
public function transaction(/* arguments */)
|
||||||
|
{
|
||||||
|
return $this->sharedContextFactory('createTransaction', func_get_args());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actual transaction context initializer method.
|
||||||
|
*
|
||||||
|
* @param array $options Options for the context.
|
||||||
|
* @param mixed $callable Optional callable used to execute the context.
|
||||||
|
*
|
||||||
|
* @return MultiExecTransaction|array
|
||||||
|
*/
|
||||||
|
protected function createTransaction(array $options = null, $callable = null)
|
||||||
|
{
|
||||||
|
$transaction = new MultiExecTransaction($this, $options);
|
||||||
|
|
||||||
|
if (isset($callable)) {
|
||||||
|
return $transaction->execute($callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new publis/subscribe context and returns it, or starts its loop
|
||||||
|
* inside the optionally provided callable object.
|
||||||
|
*
|
||||||
|
* @param mixed ... Array of options, a callable for execution, or both.
|
||||||
|
*
|
||||||
|
* @return PubSubConsumer|null
|
||||||
|
*/
|
||||||
|
public function pubSubLoop(/* arguments */)
|
||||||
|
{
|
||||||
|
return $this->sharedContextFactory('createPubSub', func_get_args());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actual publish/subscribe context initializer method.
|
||||||
|
*
|
||||||
|
* @param array $options Options for the context.
|
||||||
|
* @param mixed $callable Optional callable used to execute the context.
|
||||||
|
*
|
||||||
|
* @return PubSubConsumer|null
|
||||||
|
*/
|
||||||
|
protected function createPubSub(array $options = null, $callable = null)
|
||||||
|
{
|
||||||
|
$pubsub = new PubSubConsumer($this, $options);
|
||||||
|
|
||||||
|
if (!isset($callable)) {
|
||||||
|
return $pubsub;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($pubsub as $message) {
|
||||||
|
if (call_user_func($callable, $pubsub, $message) === false) {
|
||||||
|
$pubsub->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new monitor consumer and returns it.
|
||||||
|
*
|
||||||
|
* @return MonitorConsumer
|
||||||
|
*/
|
||||||
|
public function monitor()
|
||||||
|
{
|
||||||
|
return new MonitorConsumer($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
189
rainloop/v/0.0.0/app/libraries/Predis/ClientContextInterface.php
Normal file
189
rainloop/v/0.0.0/app/libraries/Predis/ClientContextInterface.php
Normal file
|
|
@ -0,0 +1,189 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis;
|
||||||
|
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface defining a client-side context such as a pipeline or transaction.
|
||||||
|
*
|
||||||
|
* @method $this del(array $keys)
|
||||||
|
* @method $this dump($key)
|
||||||
|
* @method $this exists($key)
|
||||||
|
* @method $this expire($key, $seconds)
|
||||||
|
* @method $this expireat($key, $timestamp)
|
||||||
|
* @method $this keys($pattern)
|
||||||
|
* @method $this move($key, $db)
|
||||||
|
* @method $this object($subcommand, $key)
|
||||||
|
* @method $this persist($key)
|
||||||
|
* @method $this pexpire($key, $milliseconds)
|
||||||
|
* @method $this pexpireat($key, $timestamp)
|
||||||
|
* @method $this pttl($key)
|
||||||
|
* @method $this randomkey()
|
||||||
|
* @method $this rename($key, $target)
|
||||||
|
* @method $this renamenx($key, $target)
|
||||||
|
* @method $this scan($cursor, array $options = null)
|
||||||
|
* @method $this sort($key, array $options = null)
|
||||||
|
* @method $this ttl($key)
|
||||||
|
* @method $this type($key)
|
||||||
|
* @method $this append($key, $value)
|
||||||
|
* @method $this bitcount($key, $start = null, $end = null)
|
||||||
|
* @method $this bitop($operation, $destkey, $key)
|
||||||
|
* @method $this decr($key)
|
||||||
|
* @method $this decrby($key, $decrement)
|
||||||
|
* @method $this get($key)
|
||||||
|
* @method $this getbit($key, $offset)
|
||||||
|
* @method $this getrange($key, $start, $end)
|
||||||
|
* @method $this getset($key, $value)
|
||||||
|
* @method $this incr($key)
|
||||||
|
* @method $this incrby($key, $increment)
|
||||||
|
* @method $this incrbyfloat($key, $increment)
|
||||||
|
* @method $this mget(array $keys)
|
||||||
|
* @method $this mset(array $dictionary)
|
||||||
|
* @method $this msetnx(array $dictionary)
|
||||||
|
* @method $this psetex($key, $milliseconds, $value)
|
||||||
|
* @method $this set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
|
||||||
|
* @method $this setbit($key, $offset, $value)
|
||||||
|
* @method $this setex($key, $seconds, $value)
|
||||||
|
* @method $this setnx($key, $value)
|
||||||
|
* @method $this setrange($key, $offset, $value)
|
||||||
|
* @method $this strlen($key)
|
||||||
|
* @method $this hdel($key, array $fields)
|
||||||
|
* @method $this hexists($key, $field)
|
||||||
|
* @method $this hget($key, $field)
|
||||||
|
* @method $this hgetall($key)
|
||||||
|
* @method $this hincrby($key, $field, $increment)
|
||||||
|
* @method $this hincrbyfloat($key, $field, $increment)
|
||||||
|
* @method $this hkeys($key)
|
||||||
|
* @method $this hlen($key)
|
||||||
|
* @method $this hmget($key, array $fields)
|
||||||
|
* @method $this hmset($key, array $dictionary)
|
||||||
|
* @method $this hscan($key, $cursor, array $options = null)
|
||||||
|
* @method $this hset($key, $field, $value)
|
||||||
|
* @method $this hsetnx($key, $field, $value)
|
||||||
|
* @method $this hvals($key)
|
||||||
|
* @method $this blpop(array $keys, $timeout)
|
||||||
|
* @method $this brpop(array $keys, $timeout)
|
||||||
|
* @method $this brpoplpush($source, $destination, $timeout)
|
||||||
|
* @method $this lindex($key, $index)
|
||||||
|
* @method $this linsert($key, $whence, $pivot, $value)
|
||||||
|
* @method $this llen($key)
|
||||||
|
* @method $this lpop($key)
|
||||||
|
* @method $this lpush($key, array $values)
|
||||||
|
* @method $this lpushx($key, $value)
|
||||||
|
* @method $this lrange($key, $start, $stop)
|
||||||
|
* @method $this lrem($key, $count, $value)
|
||||||
|
* @method $this lset($key, $index, $value)
|
||||||
|
* @method $this ltrim($key, $start, $stop)
|
||||||
|
* @method $this rpop($key)
|
||||||
|
* @method $this rpoplpush($source, $destination)
|
||||||
|
* @method $this rpush($key, array $values)
|
||||||
|
* @method $this rpushx($key, $value)
|
||||||
|
* @method $this sadd($key, array $members)
|
||||||
|
* @method $this scard($key)
|
||||||
|
* @method $this sdiff(array $keys)
|
||||||
|
* @method $this sdiffstore($destination, array $keys)
|
||||||
|
* @method $this sinter(array $keys)
|
||||||
|
* @method $this sinterstore($destination, array $keys)
|
||||||
|
* @method $this sismember($key, $member)
|
||||||
|
* @method $this smembers($key)
|
||||||
|
* @method $this smove($source, $destination, $member)
|
||||||
|
* @method $this spop($key)
|
||||||
|
* @method $this srandmember($key, $count = null)
|
||||||
|
* @method $this srem($key, $member)
|
||||||
|
* @method $this sscan($key, $cursor, array $options = null)
|
||||||
|
* @method $this sunion(array $keys)
|
||||||
|
* @method $this sunionstore($destination, array $keys)
|
||||||
|
* @method $this zadd($key, array $membersAndScoresDictionary)
|
||||||
|
* @method $this zcard($key)
|
||||||
|
* @method $this zcount($key, $min, $max)
|
||||||
|
* @method $this zincrby($key, $increment, $member)
|
||||||
|
* @method $this zinterstore($destination, array $keys, array $options = null)
|
||||||
|
* @method $this zrange($key, $start, $stop, array $options = null)
|
||||||
|
* @method $this zrangebyscore($key, $min, $max, array $options = null)
|
||||||
|
* @method $this zrank($key, $member)
|
||||||
|
* @method $this zrem($key, $member)
|
||||||
|
* @method $this zremrangebyrank($key, $start, $stop)
|
||||||
|
* @method $this zremrangebyscore($key, $min, $max)
|
||||||
|
* @method $this zrevrange($key, $start, $stop, array $options = null)
|
||||||
|
* @method $this zrevrangebyscore($key, $min, $max, array $options = null)
|
||||||
|
* @method $this zrevrank($key, $member)
|
||||||
|
* @method $this zunionstore($destination, array $keys, array $options = null)
|
||||||
|
* @method $this zscore($key, $member)
|
||||||
|
* @method $this zscan($key, $cursor, array $options = null)
|
||||||
|
* @method $this zrangebylex($key, $start, $stop, array $options = null)
|
||||||
|
* @method $this zremrangebylex($key, $min, $max)
|
||||||
|
* @method $this zlexcount($key, $min, $max)
|
||||||
|
* @method $this pfadd($key, array $elements)
|
||||||
|
* @method $this pfmerge($destinationKey, array $sourceKeys)
|
||||||
|
* @method $this pfcount(array $keys)
|
||||||
|
* @method $this pubsub($subcommand, $argument)
|
||||||
|
* @method $this publish($channel, $message)
|
||||||
|
* @method $this discard()
|
||||||
|
* @method $this exec()
|
||||||
|
* @method $this multi()
|
||||||
|
* @method $this unwatch()
|
||||||
|
* @method $this watch($key)
|
||||||
|
* @method $this eval($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||||
|
* @method $this evalsha($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||||
|
* @method $this script($subcommand, $argument = null)
|
||||||
|
* @method $this auth($password)
|
||||||
|
* @method $this echo($message)
|
||||||
|
* @method $this ping($message = null)
|
||||||
|
* @method $this select($database)
|
||||||
|
* @method $this bgrewriteaof()
|
||||||
|
* @method $this bgsave()
|
||||||
|
* @method $this client($subcommand, $argument = null)
|
||||||
|
* @method $this config($subcommand, $argument = null)
|
||||||
|
* @method $this dbsize()
|
||||||
|
* @method $this flushall()
|
||||||
|
* @method $this flushdb()
|
||||||
|
* @method $this info($section = null)
|
||||||
|
* @method $this lastsave()
|
||||||
|
* @method $this save()
|
||||||
|
* @method $this slaveof($host, $port)
|
||||||
|
* @method $this slowlog($subcommand, $argument = null)
|
||||||
|
* @method $this time()
|
||||||
|
* @method $this command()
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ClientContextInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sends the specified command instance to Redis.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function executeCommand(CommandInterface $command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the specified command with its arguments to Redis.
|
||||||
|
*
|
||||||
|
* @param string $method Command ID.
|
||||||
|
* @param array $arguments Arguments for the command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __call($method, $arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the execution of the context.
|
||||||
|
*
|
||||||
|
* @param mixed $callable Optional callback for execution.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function execute($callable = null);
|
||||||
|
}
|
||||||
21
rainloop/v/0.0.0/app/libraries/Predis/ClientException.php
Normal file
21
rainloop/v/0.0.0/app/libraries/Predis/ClientException.php
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception class that identifies client-side errors.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ClientException extends PredisException
|
||||||
|
{
|
||||||
|
}
|
||||||
230
rainloop/v/0.0.0/app/libraries/Predis/ClientInterface.php
Normal file
230
rainloop/v/0.0.0/app/libraries/Predis/ClientInterface.php
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis;
|
||||||
|
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
use Predis\Configuration\OptionsInterface;
|
||||||
|
use Predis\Connection\ConnectionInterface;
|
||||||
|
use Predis\Profile\ProfileInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface defining a client able to execute commands against Redis.
|
||||||
|
*
|
||||||
|
* All the commands exposed by the client generally have the same signature as
|
||||||
|
* described by the Redis documentation, but some of them offer an additional
|
||||||
|
* and more friendly interface to ease programming which is described in the
|
||||||
|
* following list of methods:
|
||||||
|
*
|
||||||
|
* @method int del(array $keys)
|
||||||
|
* @method string dump($key)
|
||||||
|
* @method int exists($key)
|
||||||
|
* @method int expire($key, $seconds)
|
||||||
|
* @method int expireat($key, $timestamp)
|
||||||
|
* @method array keys($pattern)
|
||||||
|
* @method int move($key, $db)
|
||||||
|
* @method mixed object($subcommand, $key)
|
||||||
|
* @method int persist($key)
|
||||||
|
* @method int pexpire($key, $milliseconds)
|
||||||
|
* @method int pexpireat($key, $timestamp)
|
||||||
|
* @method int pttl($key)
|
||||||
|
* @method string randomkey()
|
||||||
|
* @method mixed rename($key, $target)
|
||||||
|
* @method int renamenx($key, $target)
|
||||||
|
* @method array scan($cursor, array $options = null)
|
||||||
|
* @method array sort($key, array $options = null)
|
||||||
|
* @method int ttl($key)
|
||||||
|
* @method mixed type($key)
|
||||||
|
* @method int append($key, $value)
|
||||||
|
* @method int bitcount($key, $start = null, $end = null)
|
||||||
|
* @method int bitop($operation, $destkey, $key)
|
||||||
|
* @method int decr($key)
|
||||||
|
* @method int decrby($key, $decrement)
|
||||||
|
* @method string get($key)
|
||||||
|
* @method int getbit($key, $offset)
|
||||||
|
* @method string getrange($key, $start, $end)
|
||||||
|
* @method string getset($key, $value)
|
||||||
|
* @method int incr($key)
|
||||||
|
* @method int incrby($key, $increment)
|
||||||
|
* @method string incrbyfloat($key, $increment)
|
||||||
|
* @method array mget(array $keys)
|
||||||
|
* @method mixed mset(array $dictionary)
|
||||||
|
* @method int msetnx(array $dictionary)
|
||||||
|
* @method mixed psetex($key, $milliseconds, $value)
|
||||||
|
* @method mixed set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
|
||||||
|
* @method int setbit($key, $offset, $value)
|
||||||
|
* @method int setex($key, $seconds, $value)
|
||||||
|
* @method int setnx($key, $value)
|
||||||
|
* @method int setrange($key, $offset, $value)
|
||||||
|
* @method int strlen($key)
|
||||||
|
* @method int hdel($key, array $fields)
|
||||||
|
* @method int hexists($key, $field)
|
||||||
|
* @method string hget($key, $field)
|
||||||
|
* @method array hgetall($key)
|
||||||
|
* @method int hincrby($key, $field, $increment)
|
||||||
|
* @method string hincrbyfloat($key, $field, $increment)
|
||||||
|
* @method array hkeys($key)
|
||||||
|
* @method int hlen($key)
|
||||||
|
* @method array hmget($key, array $fields)
|
||||||
|
* @method mixed hmset($key, array $dictionary)
|
||||||
|
* @method array hscan($key, $cursor, array $options = null)
|
||||||
|
* @method int hset($key, $field, $value)
|
||||||
|
* @method int hsetnx($key, $field, $value)
|
||||||
|
* @method array hvals($key)
|
||||||
|
* @method array blpop(array $keys, $timeout)
|
||||||
|
* @method array brpop(array $keys, $timeout)
|
||||||
|
* @method array brpoplpush($source, $destination, $timeout)
|
||||||
|
* @method string lindex($key, $index)
|
||||||
|
* @method int linsert($key, $whence, $pivot, $value)
|
||||||
|
* @method int llen($key)
|
||||||
|
* @method string lpop($key)
|
||||||
|
* @method int lpush($key, array $values)
|
||||||
|
* @method int lpushx($key, $value)
|
||||||
|
* @method array lrange($key, $start, $stop)
|
||||||
|
* @method int lrem($key, $count, $value)
|
||||||
|
* @method mixed lset($key, $index, $value)
|
||||||
|
* @method mixed ltrim($key, $start, $stop)
|
||||||
|
* @method string rpop($key)
|
||||||
|
* @method string rpoplpush($source, $destination)
|
||||||
|
* @method int rpush($key, array $values)
|
||||||
|
* @method int rpushx($key, $value)
|
||||||
|
* @method int sadd($key, array $members)
|
||||||
|
* @method int scard($key)
|
||||||
|
* @method array sdiff(array $keys)
|
||||||
|
* @method int sdiffstore($destination, array $keys)
|
||||||
|
* @method array sinter(array $keys)
|
||||||
|
* @method int sinterstore($destination, array $keys)
|
||||||
|
* @method int sismember($key, $member)
|
||||||
|
* @method array smembers($key)
|
||||||
|
* @method int smove($source, $destination, $member)
|
||||||
|
* @method string spop($key)
|
||||||
|
* @method string srandmember($key, $count = null)
|
||||||
|
* @method int srem($key, $member)
|
||||||
|
* @method array sscan($key, $cursor, array $options = null)
|
||||||
|
* @method array sunion(array $keys)
|
||||||
|
* @method int sunionstore($destination, array $keys)
|
||||||
|
* @method int zadd($key, array $membersAndScoresDictionary)
|
||||||
|
* @method int zcard($key)
|
||||||
|
* @method string zcount($key, $min, $max)
|
||||||
|
* @method string zincrby($key, $increment, $member)
|
||||||
|
* @method int zinterstore($destination, array $keys, array $options = null)
|
||||||
|
* @method array zrange($key, $start, $stop, array $options = null)
|
||||||
|
* @method array zrangebyscore($key, $min, $max, array $options = null)
|
||||||
|
* @method int zrank($key, $member)
|
||||||
|
* @method int zrem($key, $member)
|
||||||
|
* @method int zremrangebyrank($key, $start, $stop)
|
||||||
|
* @method int zremrangebyscore($key, $min, $max)
|
||||||
|
* @method array zrevrange($key, $start, $stop, array $options = null)
|
||||||
|
* @method array zrevrangebyscore($key, $min, $max, array $options = null)
|
||||||
|
* @method int zrevrank($key, $member)
|
||||||
|
* @method int zunionstore($destination, array $keys, array $options = null)
|
||||||
|
* @method string zscore($key, $member)
|
||||||
|
* @method array zscan($key, $cursor, array $options = null)
|
||||||
|
* @method array zrangebylex($key, $start, $stop, array $options = null)
|
||||||
|
* @method int zremrangebylex($key, $min, $max)
|
||||||
|
* @method int zlexcount($key, $min, $max)
|
||||||
|
* @method int pfadd($key, array $elements)
|
||||||
|
* @method mixed pfmerge($destinationKey, array $sourceKeys)
|
||||||
|
* @method int pfcount(array $keys)
|
||||||
|
* @method mixed pubsub($subcommand, $argument)
|
||||||
|
* @method int publish($channel, $message)
|
||||||
|
* @method mixed discard()
|
||||||
|
* @method array exec()
|
||||||
|
* @method mixed multi()
|
||||||
|
* @method mixed unwatch()
|
||||||
|
* @method mixed watch($key)
|
||||||
|
* @method mixed eval($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||||
|
* @method mixed evalsha($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||||
|
* @method mixed script($subcommand, $argument = null)
|
||||||
|
* @method mixed auth($password)
|
||||||
|
* @method string echo($message)
|
||||||
|
* @method mixed ping($message = null)
|
||||||
|
* @method mixed select($database)
|
||||||
|
* @method mixed bgrewriteaof()
|
||||||
|
* @method mixed bgsave()
|
||||||
|
* @method mixed client($subcommand, $argument = null)
|
||||||
|
* @method mixed config($subcommand, $argument = null)
|
||||||
|
* @method int dbsize()
|
||||||
|
* @method mixed flushall()
|
||||||
|
* @method mixed flushdb()
|
||||||
|
* @method array info($section = null)
|
||||||
|
* @method int lastsave()
|
||||||
|
* @method mixed save()
|
||||||
|
* @method mixed slaveof($host, $port)
|
||||||
|
* @method mixed slowlog($subcommand, $argument = null)
|
||||||
|
* @method array time()
|
||||||
|
* @method array command()
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ClientInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the server profile used by the client.
|
||||||
|
*
|
||||||
|
* @return ProfileInterface
|
||||||
|
*/
|
||||||
|
public function getProfile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the client options specified upon initialization.
|
||||||
|
*
|
||||||
|
* @return OptionsInterface
|
||||||
|
*/
|
||||||
|
public function getOptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the underlying connection to the server.
|
||||||
|
*/
|
||||||
|
public function connect();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the underlying connection from the server.
|
||||||
|
*/
|
||||||
|
public function disconnect();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the underlying connection instance.
|
||||||
|
*
|
||||||
|
* @return ConnectionInterface
|
||||||
|
*/
|
||||||
|
public function getConnection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the specified Redis command.
|
||||||
|
*
|
||||||
|
* @param string $method Command ID.
|
||||||
|
* @param array $arguments Arguments for the command.
|
||||||
|
*
|
||||||
|
* @return CommandInterface
|
||||||
|
*/
|
||||||
|
public function createCommand($method, $arguments = array());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the specified Redis command.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function executeCommand(CommandInterface $command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Redis command with the specified arguments and sends a request
|
||||||
|
* to the server.
|
||||||
|
*
|
||||||
|
* @param string $method Command ID.
|
||||||
|
* @param array $arguments Arguments for the command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __call($method, $arguments);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,398 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster;
|
||||||
|
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
use Predis\Command\ScriptCommand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common class implementing the logic needed to support clustering strategies.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class ClusterStrategy implements StrategyInterface
|
||||||
|
{
|
||||||
|
protected $commands;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->commands = $this->getDefaultCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default map of supported commands with their handlers.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getDefaultCommands()
|
||||||
|
{
|
||||||
|
$getKeyFromFirstArgument = array($this, 'getKeyFromFirstArgument');
|
||||||
|
$getKeyFromAllArguments = array($this, 'getKeyFromAllArguments');
|
||||||
|
|
||||||
|
return array(
|
||||||
|
/* commands operating on the key space */
|
||||||
|
'EXISTS' => $getKeyFromFirstArgument,
|
||||||
|
'DEL' => $getKeyFromAllArguments,
|
||||||
|
'TYPE' => $getKeyFromFirstArgument,
|
||||||
|
'EXPIRE' => $getKeyFromFirstArgument,
|
||||||
|
'EXPIREAT' => $getKeyFromFirstArgument,
|
||||||
|
'PERSIST' => $getKeyFromFirstArgument,
|
||||||
|
'PEXPIRE' => $getKeyFromFirstArgument,
|
||||||
|
'PEXPIREAT' => $getKeyFromFirstArgument,
|
||||||
|
'TTL' => $getKeyFromFirstArgument,
|
||||||
|
'PTTL' => $getKeyFromFirstArgument,
|
||||||
|
'SORT' => $getKeyFromFirstArgument, // TODO
|
||||||
|
'DUMP' => $getKeyFromFirstArgument,
|
||||||
|
'RESTORE' => $getKeyFromFirstArgument,
|
||||||
|
|
||||||
|
/* commands operating on string values */
|
||||||
|
'APPEND' => $getKeyFromFirstArgument,
|
||||||
|
'DECR' => $getKeyFromFirstArgument,
|
||||||
|
'DECRBY' => $getKeyFromFirstArgument,
|
||||||
|
'GET' => $getKeyFromFirstArgument,
|
||||||
|
'GETBIT' => $getKeyFromFirstArgument,
|
||||||
|
'MGET' => $getKeyFromAllArguments,
|
||||||
|
'SET' => $getKeyFromFirstArgument,
|
||||||
|
'GETRANGE' => $getKeyFromFirstArgument,
|
||||||
|
'GETSET' => $getKeyFromFirstArgument,
|
||||||
|
'INCR' => $getKeyFromFirstArgument,
|
||||||
|
'INCRBY' => $getKeyFromFirstArgument,
|
||||||
|
'INCRBYFLOAT' => $getKeyFromFirstArgument,
|
||||||
|
'SETBIT' => $getKeyFromFirstArgument,
|
||||||
|
'SETEX' => $getKeyFromFirstArgument,
|
||||||
|
'MSET' => array($this, 'getKeyFromInterleavedArguments'),
|
||||||
|
'MSETNX' => array($this, 'getKeyFromInterleavedArguments'),
|
||||||
|
'SETNX' => $getKeyFromFirstArgument,
|
||||||
|
'SETRANGE' => $getKeyFromFirstArgument,
|
||||||
|
'STRLEN' => $getKeyFromFirstArgument,
|
||||||
|
'SUBSTR' => $getKeyFromFirstArgument,
|
||||||
|
'BITOP' => array($this, 'getKeyFromBitOp'),
|
||||||
|
'BITCOUNT' => $getKeyFromFirstArgument,
|
||||||
|
|
||||||
|
/* commands operating on lists */
|
||||||
|
'LINSERT' => $getKeyFromFirstArgument,
|
||||||
|
'LINDEX' => $getKeyFromFirstArgument,
|
||||||
|
'LLEN' => $getKeyFromFirstArgument,
|
||||||
|
'LPOP' => $getKeyFromFirstArgument,
|
||||||
|
'RPOP' => $getKeyFromFirstArgument,
|
||||||
|
'RPOPLPUSH' => $getKeyFromAllArguments,
|
||||||
|
'BLPOP' => array($this, 'getKeyFromBlockingListCommands'),
|
||||||
|
'BRPOP' => array($this, 'getKeyFromBlockingListCommands'),
|
||||||
|
'BRPOPLPUSH' => array($this, 'getKeyFromBlockingListCommands'),
|
||||||
|
'LPUSH' => $getKeyFromFirstArgument,
|
||||||
|
'LPUSHX' => $getKeyFromFirstArgument,
|
||||||
|
'RPUSH' => $getKeyFromFirstArgument,
|
||||||
|
'RPUSHX' => $getKeyFromFirstArgument,
|
||||||
|
'LRANGE' => $getKeyFromFirstArgument,
|
||||||
|
'LREM' => $getKeyFromFirstArgument,
|
||||||
|
'LSET' => $getKeyFromFirstArgument,
|
||||||
|
'LTRIM' => $getKeyFromFirstArgument,
|
||||||
|
|
||||||
|
/* commands operating on sets */
|
||||||
|
'SADD' => $getKeyFromFirstArgument,
|
||||||
|
'SCARD' => $getKeyFromFirstArgument,
|
||||||
|
'SDIFF' => $getKeyFromAllArguments,
|
||||||
|
'SDIFFSTORE' => $getKeyFromAllArguments,
|
||||||
|
'SINTER' => $getKeyFromAllArguments,
|
||||||
|
'SINTERSTORE' => $getKeyFromAllArguments,
|
||||||
|
'SUNION' => $getKeyFromAllArguments,
|
||||||
|
'SUNIONSTORE' => $getKeyFromAllArguments,
|
||||||
|
'SISMEMBER' => $getKeyFromFirstArgument,
|
||||||
|
'SMEMBERS' => $getKeyFromFirstArgument,
|
||||||
|
'SSCAN' => $getKeyFromFirstArgument,
|
||||||
|
'SPOP' => $getKeyFromFirstArgument,
|
||||||
|
'SRANDMEMBER' => $getKeyFromFirstArgument,
|
||||||
|
'SREM' => $getKeyFromFirstArgument,
|
||||||
|
|
||||||
|
/* commands operating on sorted sets */
|
||||||
|
'ZADD' => $getKeyFromFirstArgument,
|
||||||
|
'ZCARD' => $getKeyFromFirstArgument,
|
||||||
|
'ZCOUNT' => $getKeyFromFirstArgument,
|
||||||
|
'ZINCRBY' => $getKeyFromFirstArgument,
|
||||||
|
'ZINTERSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
|
||||||
|
'ZRANGE' => $getKeyFromFirstArgument,
|
||||||
|
'ZRANGEBYSCORE' => $getKeyFromFirstArgument,
|
||||||
|
'ZRANK' => $getKeyFromFirstArgument,
|
||||||
|
'ZREM' => $getKeyFromFirstArgument,
|
||||||
|
'ZREMRANGEBYRANK' => $getKeyFromFirstArgument,
|
||||||
|
'ZREMRANGEBYSCORE' => $getKeyFromFirstArgument,
|
||||||
|
'ZREVRANGE' => $getKeyFromFirstArgument,
|
||||||
|
'ZREVRANGEBYSCORE' => $getKeyFromFirstArgument,
|
||||||
|
'ZREVRANK' => $getKeyFromFirstArgument,
|
||||||
|
'ZSCORE' => $getKeyFromFirstArgument,
|
||||||
|
'ZUNIONSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
|
||||||
|
'ZSCAN' => $getKeyFromFirstArgument,
|
||||||
|
'ZLEXCOUNT' => $getKeyFromFirstArgument,
|
||||||
|
'ZRANGEBYLEX' => $getKeyFromFirstArgument,
|
||||||
|
'ZREMRANGEBYLEX' => $getKeyFromFirstArgument,
|
||||||
|
'ZREVRANGEBYLEX' => $getKeyFromFirstArgument,
|
||||||
|
|
||||||
|
/* commands operating on hashes */
|
||||||
|
'HDEL' => $getKeyFromFirstArgument,
|
||||||
|
'HEXISTS' => $getKeyFromFirstArgument,
|
||||||
|
'HGET' => $getKeyFromFirstArgument,
|
||||||
|
'HGETALL' => $getKeyFromFirstArgument,
|
||||||
|
'HMGET' => $getKeyFromFirstArgument,
|
||||||
|
'HMSET' => $getKeyFromFirstArgument,
|
||||||
|
'HINCRBY' => $getKeyFromFirstArgument,
|
||||||
|
'HINCRBYFLOAT' => $getKeyFromFirstArgument,
|
||||||
|
'HKEYS' => $getKeyFromFirstArgument,
|
||||||
|
'HLEN' => $getKeyFromFirstArgument,
|
||||||
|
'HSET' => $getKeyFromFirstArgument,
|
||||||
|
'HSETNX' => $getKeyFromFirstArgument,
|
||||||
|
'HVALS' => $getKeyFromFirstArgument,
|
||||||
|
'HSCAN' => $getKeyFromFirstArgument,
|
||||||
|
'HSTRLEN' => $getKeyFromFirstArgument,
|
||||||
|
|
||||||
|
/* commands operating on HyperLogLog */
|
||||||
|
'PFADD' => $getKeyFromFirstArgument,
|
||||||
|
'PFCOUNT' => $getKeyFromAllArguments,
|
||||||
|
'PFMERGE' => $getKeyFromAllArguments,
|
||||||
|
|
||||||
|
/* scripting */
|
||||||
|
'EVAL' => array($this, 'getKeyFromScriptingCommands'),
|
||||||
|
'EVALSHA' => array($this, 'getKeyFromScriptingCommands'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of IDs for the supported commands.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getSupportedCommands()
|
||||||
|
{
|
||||||
|
return array_keys($this->commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an handler for the specified command ID.
|
||||||
|
*
|
||||||
|
* The signature of the callback must have a single parameter of type
|
||||||
|
* Predis\Command\CommandInterface.
|
||||||
|
*
|
||||||
|
* When the callback argument is omitted or NULL, the previously associated
|
||||||
|
* handler for the specified command ID is removed.
|
||||||
|
*
|
||||||
|
* @param string $commandID Command ID.
|
||||||
|
* @param mixed $callback A valid callable object, or NULL to unset the handler.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setCommandHandler($commandID, $callback = null)
|
||||||
|
{
|
||||||
|
$commandID = strtoupper($commandID);
|
||||||
|
|
||||||
|
if (!isset($callback)) {
|
||||||
|
unset($this->commands[$commandID]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_callable($callback)) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'The argument must be a callable object or NULL.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->commands[$commandID] = $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the key from the first argument of a command instance.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getKeyFromFirstArgument(CommandInterface $command)
|
||||||
|
{
|
||||||
|
return $command->getArgument(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the key from a command with multiple keys only when all keys in
|
||||||
|
* the arguments array produce the same hash.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getKeyFromAllArguments(CommandInterface $command)
|
||||||
|
{
|
||||||
|
$arguments = $command->getArguments();
|
||||||
|
|
||||||
|
if ($this->checkSameSlotForKeys($arguments)) {
|
||||||
|
return $arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the key from a command with multiple keys only when all keys in
|
||||||
|
* the arguments array produce the same hash.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getKeyFromInterleavedArguments(CommandInterface $command)
|
||||||
|
{
|
||||||
|
$arguments = $command->getArguments();
|
||||||
|
$keys = array();
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($arguments); $i += 2) {
|
||||||
|
$keys[] = $arguments[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->checkSameSlotForKeys($keys)) {
|
||||||
|
return $arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the key from BLPOP and BRPOP commands.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getKeyFromBlockingListCommands(CommandInterface $command)
|
||||||
|
{
|
||||||
|
$arguments = $command->getArguments();
|
||||||
|
|
||||||
|
if ($this->checkSameSlotForKeys(array_slice($arguments, 0, count($arguments) - 1))) {
|
||||||
|
return $arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the key from BITOP command.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getKeyFromBitOp(CommandInterface $command)
|
||||||
|
{
|
||||||
|
$arguments = $command->getArguments();
|
||||||
|
|
||||||
|
if ($this->checkSameSlotForKeys(array_slice($arguments, 1, count($arguments)))) {
|
||||||
|
return $arguments[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the key from ZINTERSTORE and ZUNIONSTORE commands.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getKeyFromZsetAggregationCommands(CommandInterface $command)
|
||||||
|
{
|
||||||
|
$arguments = $command->getArguments();
|
||||||
|
$keys = array_merge(array($arguments[0]), array_slice($arguments, 2, $arguments[1]));
|
||||||
|
|
||||||
|
if ($this->checkSameSlotForKeys($keys)) {
|
||||||
|
return $arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the key from EVAL and EVALSHA commands.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
protected function getKeyFromScriptingCommands(CommandInterface $command)
|
||||||
|
{
|
||||||
|
if ($command instanceof ScriptCommand) {
|
||||||
|
$keys = $command->getKeys();
|
||||||
|
} else {
|
||||||
|
$keys = array_slice($args = $command->getArguments(), 2, $args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($keys && $this->checkSameSlotForKeys($keys)) {
|
||||||
|
return $keys[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSlot(CommandInterface $command)
|
||||||
|
{
|
||||||
|
$slot = $command->getSlot();
|
||||||
|
|
||||||
|
if (!isset($slot) && isset($this->commands[$cmdID = $command->getId()])) {
|
||||||
|
$key = call_user_func($this->commands[$cmdID], $command);
|
||||||
|
|
||||||
|
if (isset($key)) {
|
||||||
|
$slot = $this->getSlotByKey($key);
|
||||||
|
$command->setSlot($slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the specified array of keys will generate the same hash.
|
||||||
|
*
|
||||||
|
* @param array $keys Array of keys.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function checkSameSlotForKeys(array $keys)
|
||||||
|
{
|
||||||
|
if (!$count = count($keys)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentSlot = $this->getSlotByKey($keys[0]);
|
||||||
|
|
||||||
|
for ($i = 1; $i < $count; ++$i) {
|
||||||
|
$nextSlot = $this->getSlotByKey($keys[$i]);
|
||||||
|
|
||||||
|
if ($currentSlot !== $nextSlot) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentSlot = $nextSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
protected function extractKeyTag($key)
|
||||||
|
{
|
||||||
|
if (false !== $start = strpos($key, '{')) {
|
||||||
|
if (false !== ($end = strpos($key, '}', $start)) && $end !== ++$start) {
|
||||||
|
$key = substr($key, $start, $end - $start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster\Distributor;
|
||||||
|
|
||||||
|
use Predis\Cluster\Hash\HashGeneratorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A distributor implements the logic to automatically distribute keys among
|
||||||
|
* several nodes for client-side sharding.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface DistributorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the corresponding slot of a node from the distributor using the
|
||||||
|
* computed hash of a key.
|
||||||
|
*
|
||||||
|
* @param mixed $hash
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getSlot($hash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a node from the distributor using its assigned slot ID.
|
||||||
|
*
|
||||||
|
* @param mixed $slot
|
||||||
|
*
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
public function getBySlot($slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a node from the distributor using the computed hash of a key.
|
||||||
|
*
|
||||||
|
* @param mixed $hash
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getByHash($hash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a node from the distributor mapping to the specified value.
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function get($value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the underlying hash generator instance.
|
||||||
|
*
|
||||||
|
* @return HashGeneratorInterface
|
||||||
|
*/
|
||||||
|
public function getHashGenerator();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster\Distributor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception class that identifies empty rings.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class EmptyRingException extends \Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,270 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster\Distributor;
|
||||||
|
|
||||||
|
use Predis\Cluster\Hash\HashGeneratorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 <suppakilla@gmail.com>
|
||||||
|
* @author Lorenzo Castelli <lcastelli@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashRing implements DistributorInterface, HashGeneratorInterface
|
||||||
|
{
|
||||||
|
const DEFAULT_REPLICAS = 128;
|
||||||
|
const DEFAULT_WEIGHT = 100;
|
||||||
|
|
||||||
|
private $ring;
|
||||||
|
private $ringKeys;
|
||||||
|
private $ringKeysCount;
|
||||||
|
private $replicas;
|
||||||
|
private $nodeHashCallback;
|
||||||
|
private $nodes = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $replicas Number of replicas in the ring.
|
||||||
|
* @param mixed $nodeHashCallback Callback returning a string used to calculate the hash of nodes.
|
||||||
|
*/
|
||||||
|
public function __construct($replicas = self::DEFAULT_REPLICAS, $nodeHashCallback = null)
|
||||||
|
{
|
||||||
|
$this->replicas = $replicas;
|
||||||
|
$this->nodeHashCallback = $nodeHashCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
// last wins, thus the order in which nodes are added is significant.
|
||||||
|
$this->nodes[] = array(
|
||||||
|
'object' => $node,
|
||||||
|
'weight' => (int) $weight ?: $this::DEFAULT_WEIGHT,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function remove($node)
|
||||||
|
{
|
||||||
|
// A node is removed by resetting the ring so that it's recreated from
|
||||||
|
// scratch, in order to reassign possible hashes with collisions to the
|
||||||
|
// right node according to the order in which they were added in the
|
||||||
|
// first place.
|
||||||
|
for ($i = 0; $i < count($this->nodes); ++$i) {
|
||||||
|
if ($this->nodes[$i]['object'] === $node) {
|
||||||
|
array_splice($this->nodes, $i, 1);
|
||||||
|
$this->reset();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the distributor.
|
||||||
|
*/
|
||||||
|
private function reset()
|
||||||
|
{
|
||||||
|
unset(
|
||||||
|
$this->ring,
|
||||||
|
$this->ringKeys,
|
||||||
|
$this->ringKeysCount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the initialization status of the distributor.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
foreach ($this->nodes as $node) {
|
||||||
|
$totalWeight += $node['weight'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $totalWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the distributor.
|
||||||
|
*/
|
||||||
|
private function initialize()
|
||||||
|
{
|
||||||
|
if ($this->isInitialized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->nodes) {
|
||||||
|
throw new EmptyRingException('Cannot initialize an empty hashring.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ring = array();
|
||||||
|
$totalWeight = $this->computeTotalWeight();
|
||||||
|
$nodesCount = count($this->nodes);
|
||||||
|
|
||||||
|
foreach ($this->nodes as $node) {
|
||||||
|
$weightRatio = $node['weight'] / $totalWeight;
|
||||||
|
$this->addNodeToRing($this->ring, $node, $nodesCount, $this->replicas, $weightRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($this->ring, SORT_NUMERIC);
|
||||||
|
$this->ringKeys = array_keys($this->ring);
|
||||||
|
$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'];
|
||||||
|
$nodeHash = $this->getNodeHash($nodeObject);
|
||||||
|
$replicas = (int) round($weightRatio * $totalNodes * $replicas);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $replicas; ++$i) {
|
||||||
|
$key = crc32("$nodeHash:$i");
|
||||||
|
$ring[$key] = $nodeObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getNodeHash($nodeObject)
|
||||||
|
{
|
||||||
|
if (!isset($this->nodeHashCallback)) {
|
||||||
|
return (string) $nodeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_user_func($this->nodeHashCallback, $nodeObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function hash($value)
|
||||||
|
{
|
||||||
|
return crc32($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getByHash($hash)
|
||||||
|
{
|
||||||
|
return $this->ring[$this->getSlot($hash)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getBySlot($slot)
|
||||||
|
{
|
||||||
|
$this->initialize();
|
||||||
|
|
||||||
|
if (isset($this->ring[$slot])) {
|
||||||
|
return $this->ring[$slot];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSlot($hash)
|
||||||
|
{
|
||||||
|
$this->initialize();
|
||||||
|
|
||||||
|
$ringKeys = $this->ringKeys;
|
||||||
|
$upper = $this->ringKeysCount - 1;
|
||||||
|
$lower = 0;
|
||||||
|
|
||||||
|
while ($lower <= $upper) {
|
||||||
|
$index = ($lower + $upper) >> 1;
|
||||||
|
$item = $ringKeys[$index];
|
||||||
|
|
||||||
|
if ($item > $hash) {
|
||||||
|
$upper = $index - 1;
|
||||||
|
} elseif ($item < $hash) {
|
||||||
|
$lower = $index + 1;
|
||||||
|
} else {
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ringKeys[$this->wrapAroundStrategy($upper, $lower, $this->ringKeysCount)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function get($value)
|
||||||
|
{
|
||||||
|
$hash = $this->hash($value);
|
||||||
|
$node = $this->getByHash($hash);
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
// equal to the key. If no such item exists, return the last item.
|
||||||
|
return $upper >= 0 ? $upper : $ringKeysCount - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getHashGenerator()
|
||||||
|
{
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster\Distributor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 <suppakilla@gmail.com>
|
||||||
|
* @author Lorenzo Castelli <lcastelli@gmail.com>
|
||||||
|
*/
|
||||||
|
class KetamaRing extends HashRing
|
||||||
|
{
|
||||||
|
const DEFAULT_REPLICAS = 160;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $nodeHashCallback Callback returning a string used to calculate the hash of nodes.
|
||||||
|
*/
|
||||||
|
public function __construct($nodeHashCallback = null)
|
||||||
|
{
|
||||||
|
parent::__construct($this::DEFAULT_REPLICAS, $nodeHashCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function addNodeToRing(&$ring, $node, $totalNodes, $replicas, $weightRatio)
|
||||||
|
{
|
||||||
|
$nodeObject = $node['object'];
|
||||||
|
$nodeHash = $this->getNodeHash($nodeObject);
|
||||||
|
$replicas = (int) floor($weightRatio * $totalNodes * ($replicas / 4));
|
||||||
|
|
||||||
|
for ($i = 0; $i < $replicas; ++$i) {
|
||||||
|
$unpackedDigest = unpack('V4', md5("$nodeHash-$i", true));
|
||||||
|
|
||||||
|
foreach ($unpackedDigest as $key) {
|
||||||
|
$ring[$key] = $nodeObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function hash($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
|
||||||
|
// or equal to the key. If no such item exists, return the first item.
|
||||||
|
return $lower < $ringKeysCount ? $lower : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
72
rainloop/v/0.0.0/app/libraries/Predis/Cluster/Hash/CRC16.php
Normal file
72
rainloop/v/0.0.0/app/libraries/Predis/Cluster/Hash/CRC16.php
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster\Hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash generator implementing the CRC-CCITT-16 algorithm used by redis-cluster.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class CRC16 implements HashGeneratorInterface
|
||||||
|
{
|
||||||
|
private static $CCITT_16 = array(
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||||
|
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||||
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||||
|
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||||
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||||
|
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||||
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||||
|
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||||
|
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||||
|
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||||
|
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||||
|
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||||
|
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||||
|
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||||
|
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||||
|
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||||
|
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||||
|
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||||
|
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
|
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||||
|
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
|
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||||
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||||
|
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||||
|
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||||
|
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||||
|
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||||
|
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||||
|
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function hash($value)
|
||||||
|
{
|
||||||
|
// CRC-CCITT-16 algorithm
|
||||||
|
$crc = 0;
|
||||||
|
$CCITT_16 = self::$CCITT_16;
|
||||||
|
$strlen = strlen($value);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $strlen; ++$i) {
|
||||||
|
$crc = (($crc << 8) ^ $CCITT_16[($crc >> 8) ^ ord($value[$i])]) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $crc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster\Hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An hash generator implements the logic used to calculate the hash of a key to
|
||||||
|
* distribute operations among Redis nodes.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface HashGeneratorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generates an hash from a string to be used for distribution.
|
||||||
|
*
|
||||||
|
* @param string $value String value.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function hash($value);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster;
|
||||||
|
|
||||||
|
use Predis\Cluster\Distributor\DistributorInterface;
|
||||||
|
use Predis\Cluster\Distributor\HashRing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default cluster strategy used by Predis to handle client-side sharding.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class PredisStrategy extends ClusterStrategy
|
||||||
|
{
|
||||||
|
protected $distributor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DistributorInterface $distributor Optional distributor instance.
|
||||||
|
*/
|
||||||
|
public function __construct(DistributorInterface $distributor = null)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->distributor = $distributor ?: new HashRing();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSlotByKey($key)
|
||||||
|
{
|
||||||
|
$key = $this->extractKeyTag($key);
|
||||||
|
$hash = $this->distributor->hash($key);
|
||||||
|
$slot = $this->distributor->getSlot($hash);
|
||||||
|
|
||||||
|
return $slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function checkSameSlotForKeys(array $keys)
|
||||||
|
{
|
||||||
|
if (!$count = count($keys)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentKey = $this->extractKeyTag($keys[0]);
|
||||||
|
|
||||||
|
for ($i = 1; $i < $count; ++$i) {
|
||||||
|
$nextKey = $this->extractKeyTag($keys[$i]);
|
||||||
|
|
||||||
|
if ($currentKey !== $nextKey) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentKey = $nextKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getDistributor()
|
||||||
|
{
|
||||||
|
return $this->distributor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster;
|
||||||
|
|
||||||
|
use Predis\Cluster\Hash\CRC16;
|
||||||
|
use Predis\Cluster\Hash\HashGeneratorInterface;
|
||||||
|
use Predis\NotSupportedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default class used by Predis to calculate hashes out of keys of
|
||||||
|
* commands supported by redis-cluster.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class RedisStrategy extends ClusterStrategy
|
||||||
|
{
|
||||||
|
protected $hashGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param HashGeneratorInterface $hashGenerator Hash generator instance.
|
||||||
|
*/
|
||||||
|
public function __construct(HashGeneratorInterface $hashGenerator = null)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->hashGenerator = $hashGenerator ?: new CRC16();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSlotByKey($key)
|
||||||
|
{
|
||||||
|
$key = $this->extractKeyTag($key);
|
||||||
|
$slot = $this->hashGenerator->hash($key) & 0x3FFF;
|
||||||
|
|
||||||
|
return $slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getDistributor()
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(
|
||||||
|
'This cluster strategy does not provide an external distributor'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Cluster;
|
||||||
|
|
||||||
|
use Predis\Cluster\Distributor\DistributorInterface;
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for classes defining the strategy used to calculate an hash out of
|
||||||
|
* keys extracted from supported commands.
|
||||||
|
*
|
||||||
|
* This is mostly useful to support clustering via client-side sharding.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface StrategyInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns a slot for the given command used for clustering distribution or
|
||||||
|
* NULL when this is not possible.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getSlot(CommandInterface $command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a slot for the given key used for clustering distribution or NULL
|
||||||
|
* when this is not possible.
|
||||||
|
*
|
||||||
|
* @param string $key Key string.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getSlotByKey($key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a distributor instance to be used by the cluster.
|
||||||
|
*
|
||||||
|
* @return DistributorInterface
|
||||||
|
*/
|
||||||
|
public function getDistributor();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Collection\Iterator;
|
||||||
|
|
||||||
|
use Predis\ClientInterface;
|
||||||
|
use Predis\NotSupportedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the base implementation for a fully-rewindable PHP iterator that can
|
||||||
|
* incrementally iterate over cursor-based collections stored on Redis using the
|
||||||
|
* commands in the `SCAN` family.
|
||||||
|
*
|
||||||
|
* Given their incremental nature with multiple fetches, these kind of iterators
|
||||||
|
* offer limited guarantees about the returned elements because the collection
|
||||||
|
* can change several times during the iteration process.
|
||||||
|
*
|
||||||
|
* @see http://redis.io/commands/scan
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class CursorBasedIterator implements \Iterator
|
||||||
|
{
|
||||||
|
protected $client;
|
||||||
|
protected $match;
|
||||||
|
protected $count;
|
||||||
|
|
||||||
|
protected $valid;
|
||||||
|
protected $fetchmore;
|
||||||
|
protected $elements;
|
||||||
|
protected $cursor;
|
||||||
|
protected $position;
|
||||||
|
protected $current;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ClientInterface $client Client connected to Redis.
|
||||||
|
* @param string $match Pattern to match during the server-side iteration.
|
||||||
|
* @param int $count Hint used by Redis to compute the number of results per iteration.
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, $match = null, $count = null)
|
||||||
|
{
|
||||||
|
$this->client = $client;
|
||||||
|
$this->match = $match;
|
||||||
|
$this->count = $count;
|
||||||
|
|
||||||
|
$this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that the client supports the specified Redis command required to
|
||||||
|
* fetch elements from the server to perform the iteration.
|
||||||
|
*
|
||||||
|
* @param ClientInterface $client Client connected to Redis.
|
||||||
|
* @param string $commandID Command ID.
|
||||||
|
*
|
||||||
|
* @throws NotSupportedException
|
||||||
|
*/
|
||||||
|
protected function requiredCommand(ClientInterface $client, $commandID)
|
||||||
|
{
|
||||||
|
if (!$client->getProfile()->supportsCommand($commandID)) {
|
||||||
|
throw new NotSupportedException("The current profile does not support '$commandID'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the inner state of the iterator.
|
||||||
|
*/
|
||||||
|
protected function reset()
|
||||||
|
{
|
||||||
|
$this->valid = true;
|
||||||
|
$this->fetchmore = true;
|
||||||
|
$this->elements = array();
|
||||||
|
$this->cursor = 0;
|
||||||
|
$this->position = -1;
|
||||||
|
$this->current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of options for the `SCAN` command.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getScanOptions()
|
||||||
|
{
|
||||||
|
$options = array();
|
||||||
|
|
||||||
|
if (strlen($this->match) > 0) {
|
||||||
|
$options['MATCH'] = $this->match;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->count > 0) {
|
||||||
|
$options['COUNT'] = $this->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a new set of elements from the remote collection, effectively
|
||||||
|
* advancing the iteration process.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
abstract protected function executeCommand();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the local buffer of elements fetched from the server during
|
||||||
|
* the iteration.
|
||||||
|
*/
|
||||||
|
protected function fetch()
|
||||||
|
{
|
||||||
|
list($cursor, $elements) = $this->executeCommand();
|
||||||
|
|
||||||
|
if (!$cursor) {
|
||||||
|
$this->fetchmore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cursor = $cursor;
|
||||||
|
$this->elements = $elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts next values for key() and current().
|
||||||
|
*/
|
||||||
|
protected function extractNext()
|
||||||
|
{
|
||||||
|
++$this->position;
|
||||||
|
$this->current = array_shift($this->elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
$this->reset();
|
||||||
|
$this->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
return $this->current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function key()
|
||||||
|
{
|
||||||
|
return $this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function next()
|
||||||
|
{
|
||||||
|
tryFetch: {
|
||||||
|
if (!$this->elements && $this->fetchmore) {
|
||||||
|
$this->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->elements) {
|
||||||
|
$this->extractNext();
|
||||||
|
} elseif ($this->cursor) {
|
||||||
|
goto tryFetch;
|
||||||
|
} else {
|
||||||
|
$this->valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function valid()
|
||||||
|
{
|
||||||
|
return $this->valid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Collection\Iterator;
|
||||||
|
|
||||||
|
use Predis\ClientInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstracts the iteration of fields and values of an hash by leveraging the
|
||||||
|
* HSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* @link http://redis.io/commands/scan
|
||||||
|
*/
|
||||||
|
class HashKey extends CursorBasedIterator
|
||||||
|
{
|
||||||
|
protected $key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, $key, $match = null, $count = null)
|
||||||
|
{
|
||||||
|
$this->requiredCommand($client, 'HSCAN');
|
||||||
|
|
||||||
|
parent::__construct($client, $match, $count);
|
||||||
|
|
||||||
|
$this->key = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function executeCommand()
|
||||||
|
{
|
||||||
|
return $this->client->hscan($this->key, $this->cursor, $this->getScanOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function extractNext()
|
||||||
|
{
|
||||||
|
$this->position = key($this->elements);
|
||||||
|
$this->current = array_shift($this->elements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Collection\Iterator;
|
||||||
|
|
||||||
|
use Predis\ClientInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstracts the iteration of the keyspace on a Redis instance by leveraging the
|
||||||
|
* SCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* @link http://redis.io/commands/scan
|
||||||
|
*/
|
||||||
|
class Keyspace extends CursorBasedIterator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, $match = null, $count = null)
|
||||||
|
{
|
||||||
|
$this->requiredCommand($client, 'SCAN');
|
||||||
|
|
||||||
|
parent::__construct($client, $match, $count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function executeCommand()
|
||||||
|
{
|
||||||
|
return $this->client->scan($this->cursor, $this->getScanOptions());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,176 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Collection\Iterator;
|
||||||
|
|
||||||
|
use Predis\ClientInterface;
|
||||||
|
use Predis\NotSupportedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstracts the iteration of items stored in a list by leveraging the LRANGE
|
||||||
|
* command wrapped in a fully-rewindable PHP iterator.
|
||||||
|
*
|
||||||
|
* This iterator tries to emulate the behaviour of cursor-based iterators based
|
||||||
|
* on the SCAN-family of commands introduced in Redis <= 2.8, meaning that due
|
||||||
|
* to its incremental nature with multiple fetches it can only offer limited
|
||||||
|
* guarantees on the returned elements because the collection can change several
|
||||||
|
* times (trimmed, deleted, overwritten) during the iteration process.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* @link http://redis.io/commands/lrange
|
||||||
|
*/
|
||||||
|
class ListKey implements \Iterator
|
||||||
|
{
|
||||||
|
protected $client;
|
||||||
|
protected $count;
|
||||||
|
protected $key;
|
||||||
|
|
||||||
|
protected $valid;
|
||||||
|
protected $fetchmore;
|
||||||
|
protected $elements;
|
||||||
|
protected $position;
|
||||||
|
protected $current;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ClientInterface $client Client connected to Redis.
|
||||||
|
* @param string $key Redis list key.
|
||||||
|
* @param int $count Number of items retrieved on each fetch operation.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, $key, $count = 10)
|
||||||
|
{
|
||||||
|
$this->requiredCommand($client, 'LRANGE');
|
||||||
|
|
||||||
|
if ((false === $count = filter_var($count, FILTER_VALIDATE_INT)) || $count < 0) {
|
||||||
|
throw new \InvalidArgumentException('The $count argument must be a positive integer.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->client = $client;
|
||||||
|
$this->key = $key;
|
||||||
|
$this->count = $count;
|
||||||
|
|
||||||
|
$this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that the client instance supports the specified Redis command
|
||||||
|
* required to fetch elements from the server to perform the iteration.
|
||||||
|
*
|
||||||
|
* @param ClientInterface $client Client connected to Redis.
|
||||||
|
* @param string $commandID Command ID.
|
||||||
|
*
|
||||||
|
* @throws NotSupportedException
|
||||||
|
*/
|
||||||
|
protected function requiredCommand(ClientInterface $client, $commandID)
|
||||||
|
{
|
||||||
|
if (!$client->getProfile()->supportsCommand($commandID)) {
|
||||||
|
throw new NotSupportedException("The current profile does not support '$commandID'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the inner state of the iterator.
|
||||||
|
*/
|
||||||
|
protected function reset()
|
||||||
|
{
|
||||||
|
$this->valid = true;
|
||||||
|
$this->fetchmore = true;
|
||||||
|
$this->elements = array();
|
||||||
|
$this->position = -1;
|
||||||
|
$this->current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a new set of elements from the remote collection, effectively
|
||||||
|
* advancing the iteration process.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function executeCommand()
|
||||||
|
{
|
||||||
|
return $this->client->lrange($this->key, $this->position + 1, $this->position + $this->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the local buffer of elements fetched from the server during the
|
||||||
|
* iteration.
|
||||||
|
*/
|
||||||
|
protected function fetch()
|
||||||
|
{
|
||||||
|
$elements = $this->executeCommand();
|
||||||
|
|
||||||
|
if (count($elements) < $this->count) {
|
||||||
|
$this->fetchmore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elements = $elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts next values for key() and current().
|
||||||
|
*/
|
||||||
|
protected function extractNext()
|
||||||
|
{
|
||||||
|
++$this->position;
|
||||||
|
$this->current = array_shift($this->elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
$this->reset();
|
||||||
|
$this->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
return $this->current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function key()
|
||||||
|
{
|
||||||
|
return $this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function next()
|
||||||
|
{
|
||||||
|
if (!$this->elements && $this->fetchmore) {
|
||||||
|
$this->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->elements) {
|
||||||
|
$this->extractNext();
|
||||||
|
} else {
|
||||||
|
$this->valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function valid()
|
||||||
|
{
|
||||||
|
return $this->valid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Collection\Iterator;
|
||||||
|
|
||||||
|
use Predis\ClientInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstracts the iteration of members stored in a set by leveraging the SSCAN
|
||||||
|
* command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* @link http://redis.io/commands/scan
|
||||||
|
*/
|
||||||
|
class SetKey extends CursorBasedIterator
|
||||||
|
{
|
||||||
|
protected $key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, $key, $match = null, $count = null)
|
||||||
|
{
|
||||||
|
$this->requiredCommand($client, 'SSCAN');
|
||||||
|
|
||||||
|
parent::__construct($client, $match, $count);
|
||||||
|
|
||||||
|
$this->key = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function executeCommand()
|
||||||
|
{
|
||||||
|
return $this->client->sscan($this->key, $this->cursor, $this->getScanOptions());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Collection\Iterator;
|
||||||
|
|
||||||
|
use Predis\ClientInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstracts the iteration of members stored in a sorted set by leveraging the
|
||||||
|
* ZSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* @link http://redis.io/commands/scan
|
||||||
|
*/
|
||||||
|
class SortedSetKey extends CursorBasedIterator
|
||||||
|
{
|
||||||
|
protected $key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ClientInterface $client, $key, $match = null, $count = null)
|
||||||
|
{
|
||||||
|
$this->requiredCommand($client, 'ZSCAN');
|
||||||
|
|
||||||
|
parent::__construct($client, $match, $count);
|
||||||
|
|
||||||
|
$this->key = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function executeCommand()
|
||||||
|
{
|
||||||
|
return $this->client->zscan($this->key, $this->cursor, $this->getScanOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function extractNext()
|
||||||
|
{
|
||||||
|
if ($kv = each($this->elements)) {
|
||||||
|
$this->position = $kv[0];
|
||||||
|
$this->current = $kv[1];
|
||||||
|
|
||||||
|
unset($this->elements[$this->position]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
129
rainloop/v/0.0.0/app/libraries/Predis/Command/Command.php
Normal file
129
rainloop/v/0.0.0/app/libraries/Predis/Command/Command.php
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for Redis commands.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class Command implements CommandInterface
|
||||||
|
{
|
||||||
|
private $slot;
|
||||||
|
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->slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setRawArguments(array $arguments)
|
||||||
|
{
|
||||||
|
$this->arguments = $arguments;
|
||||||
|
unset($this->slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getArguments()
|
||||||
|
{
|
||||||
|
return $this->arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getArgument($index)
|
||||||
|
{
|
||||||
|
if (isset($this->arguments[$index])) {
|
||||||
|
return $this->arguments[$index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setSlot($slot)
|
||||||
|
{
|
||||||
|
$this->slot = $slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSlot()
|
||||||
|
{
|
||||||
|
if (isset($this->slot)) {
|
||||||
|
return $this->slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the arguments array passed to a Redis command.
|
||||||
|
*
|
||||||
|
* @param array $arguments Arguments for a command.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function normalizeArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (count($arguments) === 1 && is_array($arguments[0])) {
|
||||||
|
return $arguments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the arguments array passed to a variadic Redis command.
|
||||||
|
*
|
||||||
|
* @param array $arguments Arguments for a command.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function normalizeVariadic(array $arguments)
|
||||||
|
{
|
||||||
|
if (count($arguments) === 2 && is_array($arguments[1])) {
|
||||||
|
return array_merge(array($arguments[0]), $arguments[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an abstraction representing a Redis command.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface CommandInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the ID of the Redis command. By convention, command identifiers
|
||||||
|
* must always be uppercase.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign the specified slot to the command for clustering distribution.
|
||||||
|
*
|
||||||
|
* @param int $slot Slot ID.
|
||||||
|
*/
|
||||||
|
public function setSlot($slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the assigned slot of the command for clustering distribution.
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function getSlot();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the arguments for the command.
|
||||||
|
*
|
||||||
|
* @param array $arguments List of arguments.
|
||||||
|
*/
|
||||||
|
public function setArguments(array $arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the raw arguments for the command without processing them.
|
||||||
|
*
|
||||||
|
* @param array $arguments List of arguments.
|
||||||
|
*/
|
||||||
|
public function setRawArguments(array $arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the arguments of the command.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getArguments();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the argument of the command at the specified index.
|
||||||
|
*
|
||||||
|
* @param int $index Index of the desired argument.
|
||||||
|
*
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
public function getArgument($index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a raw response and returns a PHP object.
|
||||||
|
*
|
||||||
|
* @param string $data Binary string containing the whole response.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function parseResponse($data);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/auth
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ConnectionAuth extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'AUTH';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/echo
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ConnectionEcho extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'ECHO';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/ping
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ConnectionPing extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PING';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/quit
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ConnectionQuit extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'QUIT';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/select
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ConnectionSelect extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'SELECT';
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/HashDelete.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/HashDelete.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hdel
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashDelete extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HDEL';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeVariadic($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/HashExists.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/HashExists.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hexists
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashExists extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HEXISTS';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashGet.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashGet.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hget
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashGet extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HGET';
|
||||||
|
}
|
||||||
|
}
|
||||||
42
rainloop/v/0.0.0/app/libraries/Predis/Command/HashGetAll.php
Normal file
42
rainloop/v/0.0.0/app/libraries/Predis/Command/HashGetAll.php
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hgetall
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashGetAll extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HGETALL';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($data); ++$i) {
|
||||||
|
$result[$data[$i]] = $data[++$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hmget
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashGetMultiple extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HMGET';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeVariadic($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hincrby
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashIncrementBy extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HINCRBY';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hincrbyfloat
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashIncrementByFloat extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HINCRBYFLOAT';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashKeys.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashKeys.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hkeys
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashKeys extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HKEYS';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashLength.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashLength.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hlen
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashLength extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HLEN';
|
||||||
|
}
|
||||||
|
}
|
||||||
85
rainloop/v/0.0.0/app/libraries/Predis/Command/HashScan.php
Normal file
85
rainloop/v/0.0.0/app/libraries/Predis/Command/HashScan.php
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hscan
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashScan extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HSCAN';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (count($arguments) === 3 && is_array($arguments[2])) {
|
||||||
|
$options = $this->prepareOptions(array_pop($arguments));
|
||||||
|
$arguments = array_merge($arguments, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of options and modifiers compatible with Redis.
|
||||||
|
*
|
||||||
|
* @param array $options List of options.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function prepareOptions($options)
|
||||||
|
{
|
||||||
|
$options = array_change_key_case($options, CASE_UPPER);
|
||||||
|
$normalized = array();
|
||||||
|
|
||||||
|
if (!empty($options['MATCH'])) {
|
||||||
|
$normalized[] = 'MATCH';
|
||||||
|
$normalized[] = $options['MATCH'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options['COUNT'])) {
|
||||||
|
$normalized[] = 'COUNT';
|
||||||
|
$normalized[] = $options['COUNT'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
if (is_array($data)) {
|
||||||
|
$fields = $data[1];
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($fields); ++$i) {
|
||||||
|
$result[$fields[$i]] = $fields[++$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
$data[1] = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/HashSet.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/HashSet.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hset
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashSet extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HSET';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hmset
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashSetMultiple extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HMSET';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (count($arguments) === 2 && is_array($arguments[1])) {
|
||||||
|
$flattenedKVs = array($arguments[0]);
|
||||||
|
$args = $arguments[1];
|
||||||
|
|
||||||
|
foreach ($args as $k => $v) {
|
||||||
|
$flattenedKVs[] = $k;
|
||||||
|
$flattenedKVs[] = $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $flattenedKVs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hsetnx
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashSetPreserve extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HSETNX';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hstrlen
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashStringLength extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HSTRLEN';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashValues.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/HashValues.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/hvals
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HashValues extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'HVALS';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/pfadd
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HyperLogLogAdd extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PFADD';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeVariadic($arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/pfcount
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HyperLogLogCount extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PFCOUNT';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/pfmerge
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class HyperLogLogMerge extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PFMERGE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyDelete.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyDelete.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/del
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyDelete extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'DEL';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyDump.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyDump.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/dump
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyDump extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'DUMP';
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyExists.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyExists.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/exists
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyExists extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'EXISTS';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyExpire.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyExpire.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/expire
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyExpire extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'EXPIRE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/expireat
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyExpireAt extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'EXPIREAT';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyKeys.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyKeys.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/keys
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyKeys extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'KEYS';
|
||||||
|
}
|
||||||
|
}
|
||||||
50
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyMigrate.php
Normal file
50
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyMigrate.php
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/migrate
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyMigrate extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'MIGRATE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (is_array(end($arguments))) {
|
||||||
|
foreach (array_pop($arguments) as $modifier => $value) {
|
||||||
|
$modifier = strtoupper($modifier);
|
||||||
|
|
||||||
|
if ($modifier === 'COPY' && $value == true) {
|
||||||
|
$arguments[] = $modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($modifier === 'REPLACE' && $value == true) {
|
||||||
|
$arguments[] = $modifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyMove.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyMove.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/move
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyMove extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'MOVE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyPersist.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyPersist.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/persist
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyPersist extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PERSIST';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/pexpire
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyPreciseExpire extends KeyExpire
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PEXPIRE';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/pexpireat
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyPreciseExpireAt extends KeyExpireAt
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PEXPIREAT';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/pttl
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyPreciseTimeToLive extends KeyTimeToLive
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PTTL';
|
||||||
|
}
|
||||||
|
}
|
||||||
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyRandom.php
Normal file
36
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyRandom.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/randomkey
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyRandom extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RANDOMKEY';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return $data !== '' ? $data : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyRename.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyRename.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/rename
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyRename extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RENAME';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/renamenx
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyRenamePreserve extends KeyRename
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RENAMENX';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return (bool) $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyRestore.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyRestore.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/restore
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyRestore extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RESTORE';
|
||||||
|
}
|
||||||
|
}
|
||||||
66
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyScan.php
Normal file
66
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyScan.php
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/scan
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyScan extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'SCAN';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (count($arguments) === 2 && is_array($arguments[1])) {
|
||||||
|
$options = $this->prepareOptions(array_pop($arguments));
|
||||||
|
$arguments = array_merge($arguments, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of options and modifiers compatible with Redis.
|
||||||
|
*
|
||||||
|
* @param array $options List of options.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function prepareOptions($options)
|
||||||
|
{
|
||||||
|
$options = array_change_key_case($options, CASE_UPPER);
|
||||||
|
$normalized = array();
|
||||||
|
|
||||||
|
if (!empty($options['MATCH'])) {
|
||||||
|
$normalized[] = 'MATCH';
|
||||||
|
$normalized[] = $options['MATCH'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options['COUNT'])) {
|
||||||
|
$normalized[] = 'COUNT';
|
||||||
|
$normalized[] = $options['COUNT'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $normalized;
|
||||||
|
}
|
||||||
|
}
|
||||||
83
rainloop/v/0.0.0/app/libraries/Predis/Command/KeySort.php
Normal file
83
rainloop/v/0.0.0/app/libraries/Predis/Command/KeySort.php
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/sort
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeySort extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'SORT';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (count($arguments) === 1) {
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = array($arguments[0]);
|
||||||
|
$sortParams = array_change_key_case($arguments[1], CASE_UPPER);
|
||||||
|
|
||||||
|
if (isset($sortParams['BY'])) {
|
||||||
|
$query[] = 'BY';
|
||||||
|
$query[] = $sortParams['BY'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($sortParams['GET'])) {
|
||||||
|
$getargs = $sortParams['GET'];
|
||||||
|
|
||||||
|
if (is_array($getargs)) {
|
||||||
|
foreach ($getargs as $getarg) {
|
||||||
|
$query[] = 'GET';
|
||||||
|
$query[] = $getarg;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$query[] = 'GET';
|
||||||
|
$query[] = $getargs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($sortParams['LIMIT']) &&
|
||||||
|
is_array($sortParams['LIMIT']) &&
|
||||||
|
count($sortParams['LIMIT']) == 2) {
|
||||||
|
$query[] = 'LIMIT';
|
||||||
|
$query[] = $sortParams['LIMIT'][0];
|
||||||
|
$query[] = $sortParams['LIMIT'][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($sortParams['SORT'])) {
|
||||||
|
$query[] = strtoupper($sortParams['SORT']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($sortParams['ALPHA']) && $sortParams['ALPHA'] == true) {
|
||||||
|
$query[] = 'ALPHA';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($sortParams['STORE'])) {
|
||||||
|
$query[] = 'STORE';
|
||||||
|
$query[] = $sortParams['STORE'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/ttl
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyTimeToLive extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'TTL';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyType.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/KeyType.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/type
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyType extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'TYPE';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListIndex.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListIndex.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/lindex
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListIndex extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LINDEX';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListInsert.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListInsert.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/linsert
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListInsert extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LINSERT';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListLength.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListLength.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/llen
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListLength extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LLEN';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/lpop
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPopFirst extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LPOP';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/blpop
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPopFirstBlocking extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'BLPOP';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (count($arguments) === 2 && is_array($arguments[0])) {
|
||||||
|
list($arguments, $timeout) = $arguments;
|
||||||
|
array_push($arguments, $timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/rpop
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPopLast extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RPOP';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/brpop
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPopLastBlocking extends ListPopFirstBlocking
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'BRPOP';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/rpoplpush
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPopLastPushHead extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RPOPLPUSH';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/brpoplpush
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPopLastPushHeadBlocking extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'BRPOPLPUSH';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/lpush
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPushHead extends ListPushTail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LPUSH';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/lpushx
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPushHeadX extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LPUSHX';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/rpush
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPushTail extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RPUSH';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeVariadic($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/rpushx
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListPushTailX extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'RPUSHX';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListRange.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListRange.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/lrange
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListRange extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LRANGE';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListRemove.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListRemove.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/lrem
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListRemove extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LREM';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListSet.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListSet.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/lset
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListSet extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LSET';
|
||||||
|
}
|
||||||
|
}
|
||||||
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListTrim.php
Normal file
28
rainloop/v/0.0.0/app/libraries/Predis/Command/ListTrim.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/ltrim
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ListTrim extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'LTRIM';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a command whose keys can be prefixed.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface PrefixableCommandInterface extends CommandInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Prefixes all the keys found in the arguments of the command.
|
||||||
|
*
|
||||||
|
* @param string $prefix String used to prefix the keys.
|
||||||
|
*/
|
||||||
|
public function prefixKeys($prefix);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,415 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command\Processor;
|
||||||
|
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
use Predis\Command\PrefixableCommandInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command processor capable of prefixing keys stored in the arguments of Redis
|
||||||
|
* commands supported.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class KeyPrefixProcessor implements ProcessorInterface
|
||||||
|
{
|
||||||
|
private $prefix;
|
||||||
|
private $commands;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $prefix Prefix for the keys.
|
||||||
|
*/
|
||||||
|
public function __construct($prefix)
|
||||||
|
{
|
||||||
|
$this->prefix = $prefix;
|
||||||
|
$this->commands = array(
|
||||||
|
/* ---------------- Redis 1.2 ---------------- */
|
||||||
|
'EXISTS' => 'static::first',
|
||||||
|
'DEL' => 'static::all',
|
||||||
|
'TYPE' => 'static::first',
|
||||||
|
'KEYS' => 'static::first',
|
||||||
|
'RENAME' => 'static::all',
|
||||||
|
'RENAMENX' => 'static::all',
|
||||||
|
'EXPIRE' => 'static::first',
|
||||||
|
'EXPIREAT' => 'static::first',
|
||||||
|
'TTL' => 'static::first',
|
||||||
|
'MOVE' => 'static::first',
|
||||||
|
'SORT' => 'static::sort',
|
||||||
|
'DUMP' => 'static::first',
|
||||||
|
'RESTORE' => 'static::first',
|
||||||
|
'SET' => 'static::first',
|
||||||
|
'SETNX' => 'static::first',
|
||||||
|
'MSET' => 'static::interleaved',
|
||||||
|
'MSETNX' => 'static::interleaved',
|
||||||
|
'GET' => 'static::first',
|
||||||
|
'MGET' => 'static::all',
|
||||||
|
'GETSET' => 'static::first',
|
||||||
|
'INCR' => 'static::first',
|
||||||
|
'INCRBY' => 'static::first',
|
||||||
|
'DECR' => 'static::first',
|
||||||
|
'DECRBY' => 'static::first',
|
||||||
|
'RPUSH' => 'static::first',
|
||||||
|
'LPUSH' => 'static::first',
|
||||||
|
'LLEN' => 'static::first',
|
||||||
|
'LRANGE' => 'static::first',
|
||||||
|
'LTRIM' => 'static::first',
|
||||||
|
'LINDEX' => 'static::first',
|
||||||
|
'LSET' => 'static::first',
|
||||||
|
'LREM' => 'static::first',
|
||||||
|
'LPOP' => 'static::first',
|
||||||
|
'RPOP' => 'static::first',
|
||||||
|
'RPOPLPUSH' => 'static::all',
|
||||||
|
'SADD' => 'static::first',
|
||||||
|
'SREM' => 'static::first',
|
||||||
|
'SPOP' => 'static::first',
|
||||||
|
'SMOVE' => 'static::skipLast',
|
||||||
|
'SCARD' => 'static::first',
|
||||||
|
'SISMEMBER' => 'static::first',
|
||||||
|
'SINTER' => 'static::all',
|
||||||
|
'SINTERSTORE' => 'static::all',
|
||||||
|
'SUNION' => 'static::all',
|
||||||
|
'SUNIONSTORE' => 'static::all',
|
||||||
|
'SDIFF' => 'static::all',
|
||||||
|
'SDIFFSTORE' => 'static::all',
|
||||||
|
'SMEMBERS' => 'static::first',
|
||||||
|
'SRANDMEMBER' => 'static::first',
|
||||||
|
'ZADD' => 'static::first',
|
||||||
|
'ZINCRBY' => 'static::first',
|
||||||
|
'ZREM' => 'static::first',
|
||||||
|
'ZRANGE' => 'static::first',
|
||||||
|
'ZREVRANGE' => 'static::first',
|
||||||
|
'ZRANGEBYSCORE' => 'static::first',
|
||||||
|
'ZCARD' => 'static::first',
|
||||||
|
'ZSCORE' => 'static::first',
|
||||||
|
'ZREMRANGEBYSCORE' => 'static::first',
|
||||||
|
/* ---------------- Redis 2.0 ---------------- */
|
||||||
|
'SETEX' => 'static::first',
|
||||||
|
'APPEND' => 'static::first',
|
||||||
|
'SUBSTR' => 'static::first',
|
||||||
|
'BLPOP' => 'static::skipLast',
|
||||||
|
'BRPOP' => 'static::skipLast',
|
||||||
|
'ZUNIONSTORE' => 'static::zsetStore',
|
||||||
|
'ZINTERSTORE' => 'static::zsetStore',
|
||||||
|
'ZCOUNT' => 'static::first',
|
||||||
|
'ZRANK' => 'static::first',
|
||||||
|
'ZREVRANK' => 'static::first',
|
||||||
|
'ZREMRANGEBYRANK' => 'static::first',
|
||||||
|
'HSET' => 'static::first',
|
||||||
|
'HSETNX' => 'static::first',
|
||||||
|
'HMSET' => 'static::first',
|
||||||
|
'HINCRBY' => 'static::first',
|
||||||
|
'HGET' => 'static::first',
|
||||||
|
'HMGET' => 'static::first',
|
||||||
|
'HDEL' => 'static::first',
|
||||||
|
'HEXISTS' => 'static::first',
|
||||||
|
'HLEN' => 'static::first',
|
||||||
|
'HKEYS' => 'static::first',
|
||||||
|
'HVALS' => 'static::first',
|
||||||
|
'HGETALL' => 'static::first',
|
||||||
|
'SUBSCRIBE' => 'static::all',
|
||||||
|
'UNSUBSCRIBE' => 'static::all',
|
||||||
|
'PSUBSCRIBE' => 'static::all',
|
||||||
|
'PUNSUBSCRIBE' => 'static::all',
|
||||||
|
'PUBLISH' => 'static::first',
|
||||||
|
/* ---------------- Redis 2.2 ---------------- */
|
||||||
|
'PERSIST' => 'static::first',
|
||||||
|
'STRLEN' => 'static::first',
|
||||||
|
'SETRANGE' => 'static::first',
|
||||||
|
'GETRANGE' => 'static::first',
|
||||||
|
'SETBIT' => 'static::first',
|
||||||
|
'GETBIT' => 'static::first',
|
||||||
|
'RPUSHX' => 'static::first',
|
||||||
|
'LPUSHX' => 'static::first',
|
||||||
|
'LINSERT' => 'static::first',
|
||||||
|
'BRPOPLPUSH' => 'static::skipLast',
|
||||||
|
'ZREVRANGEBYSCORE' => 'static::first',
|
||||||
|
'WATCH' => 'static::all',
|
||||||
|
/* ---------------- Redis 2.6 ---------------- */
|
||||||
|
'PTTL' => 'static::first',
|
||||||
|
'PEXPIRE' => 'static::first',
|
||||||
|
'PEXPIREAT' => 'static::first',
|
||||||
|
'PSETEX' => 'static::first',
|
||||||
|
'INCRBYFLOAT' => 'static::first',
|
||||||
|
'BITOP' => 'static::skipFirst',
|
||||||
|
'BITCOUNT' => 'static::first',
|
||||||
|
'HINCRBYFLOAT' => 'static::first',
|
||||||
|
'EVAL' => 'static::evalKeys',
|
||||||
|
'EVALSHA' => 'static::evalKeys',
|
||||||
|
'MIGRATE' => 'static::migrate',
|
||||||
|
/* ---------------- Redis 2.8 ---------------- */
|
||||||
|
'SSCAN' => 'static::first',
|
||||||
|
'ZSCAN' => 'static::first',
|
||||||
|
'HSCAN' => 'static::first',
|
||||||
|
'PFADD' => 'static::first',
|
||||||
|
'PFCOUNT' => 'static::all',
|
||||||
|
'PFMERGE' => 'static::all',
|
||||||
|
'ZLEXCOUNT' => 'static::first',
|
||||||
|
'ZRANGEBYLEX' => 'static::first',
|
||||||
|
'ZREMRANGEBYLEX' => 'static::first',
|
||||||
|
'ZREVRANGEBYLEX' => 'static::first',
|
||||||
|
'BITPOS' => 'static::first',
|
||||||
|
/* ---------------- Redis 3.2 ---------------- */
|
||||||
|
'HSTRLEN' => 'static::first',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a prefix that is applied to all the keys.
|
||||||
|
*
|
||||||
|
* @param string $prefix Prefix for the keys.
|
||||||
|
*/
|
||||||
|
public function setPrefix($prefix)
|
||||||
|
{
|
||||||
|
$this->prefix = $prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current prefix.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPrefix()
|
||||||
|
{
|
||||||
|
return $this->prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function process(CommandInterface $command)
|
||||||
|
{
|
||||||
|
if ($command instanceof PrefixableCommandInterface) {
|
||||||
|
$command->prefixKeys($this->prefix);
|
||||||
|
} elseif (isset($this->commands[$commandID = strtoupper($command->getId())])) {
|
||||||
|
call_user_func($this->commands[$commandID], $command, $this->prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an handler for the specified command ID.
|
||||||
|
*
|
||||||
|
* The callback signature must have 2 parameters of the following types:
|
||||||
|
*
|
||||||
|
* - Predis\Command\CommandInterface (command instance)
|
||||||
|
* - String (prefix)
|
||||||
|
*
|
||||||
|
* When the callback argument is omitted or NULL, the previously
|
||||||
|
* associated handler for the specified command ID is removed.
|
||||||
|
*
|
||||||
|
* @param string $commandID The ID of the command to be handled.
|
||||||
|
* @param mixed $callback A valid callable object or NULL.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setCommandHandler($commandID, $callback = null)
|
||||||
|
{
|
||||||
|
$commandID = strtoupper($commandID);
|
||||||
|
|
||||||
|
if (!isset($callback)) {
|
||||||
|
unset($this->commands[$commandID]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_callable($callback)) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'Callback must be a valid callable object or NULL'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->commands[$commandID] = $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->getPrefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix only the first argument.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function first(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
$arguments[0] = "$prefix{$arguments[0]}";
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix to all the arguments.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function all(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
foreach ($arguments as &$key) {
|
||||||
|
$key = "$prefix$key";
|
||||||
|
}
|
||||||
|
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix only to even arguments in the list.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function interleaved(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
$length = count($arguments);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $length; $i += 2) {
|
||||||
|
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix to all the arguments but the first one.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function skipFirst(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
$length = count($arguments);
|
||||||
|
|
||||||
|
for ($i = 1; $i < $length; ++$i) {
|
||||||
|
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix to all the arguments but the last one.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function skipLast(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
$length = count($arguments);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $length - 1; ++$i) {
|
||||||
|
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix to the keys of a SORT command.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function sort(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
$arguments[0] = "$prefix{$arguments[0]}";
|
||||||
|
|
||||||
|
if (($count = count($arguments)) > 1) {
|
||||||
|
for ($i = 1; $i < $count; ++$i) {
|
||||||
|
switch ($arguments[$i]) {
|
||||||
|
case 'BY':
|
||||||
|
case 'STORE':
|
||||||
|
$arguments[$i] = "$prefix{$arguments[++$i]}";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'GET':
|
||||||
|
$value = $arguments[++$i];
|
||||||
|
if ($value !== '#') {
|
||||||
|
$arguments[$i] = "$prefix$value";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'LIMIT';
|
||||||
|
$i += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix to the keys of an EVAL-based command.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function evalKeys(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
for ($i = 2; $i < $arguments[1] + 2; ++$i) {
|
||||||
|
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix to the keys of Z[INTERSECTION|UNION]STORE.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function zsetStore(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
$arguments[0] = "$prefix{$arguments[0]}";
|
||||||
|
$length = ((int) $arguments[1]) + 2;
|
||||||
|
|
||||||
|
for ($i = 2; $i < $length; ++$i) {
|
||||||
|
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the specified prefix to the key of a MIGRATE command.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
* @param string $prefix Prefix string.
|
||||||
|
*/
|
||||||
|
public static function migrate(CommandInterface $command, $prefix)
|
||||||
|
{
|
||||||
|
if ($arguments = $command->getArguments()) {
|
||||||
|
$arguments[2] = "$prefix{$arguments[2]}";
|
||||||
|
$command->setRawArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command\Processor;
|
||||||
|
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of a command processors chain.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||||
|
{
|
||||||
|
private $processors = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $processors List of instances of ProcessorInterface.
|
||||||
|
*/
|
||||||
|
public function __construct($processors = array())
|
||||||
|
{
|
||||||
|
foreach ($processors as $processor) {
|
||||||
|
$this->add($processor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function add(ProcessorInterface $processor)
|
||||||
|
{
|
||||||
|
$this->processors[] = $processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function remove(ProcessorInterface $processor)
|
||||||
|
{
|
||||||
|
if (false !== $index = array_search($processor, $this->processors, true)) {
|
||||||
|
unset($this[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function process(CommandInterface $command)
|
||||||
|
{
|
||||||
|
for ($i = 0; $i < $count = count($this->processors); ++$i) {
|
||||||
|
$this->processors[$i]->process($command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@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 ProcessorInterface) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'A processor chain accepts only instances of '.
|
||||||
|
"'Predis\Command\Processor\ProcessorInterface'."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->processors[$index] = $processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function offsetUnset($index)
|
||||||
|
{
|
||||||
|
unset($this->processors[$index]);
|
||||||
|
$this->processors = array_values($this->processors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command\Processor;
|
||||||
|
|
||||||
|
use Predis\Command\CommandInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A command processor processes Redis commands before they are sent to Redis.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ProcessorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Processes the given Redis command.
|
||||||
|
*
|
||||||
|
* @param CommandInterface $command Command instance.
|
||||||
|
*/
|
||||||
|
public function process(CommandInterface $command);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/publish
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class PubSubPublish extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PUBLISH';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/pubsub
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class PubSubPubsub extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PUBSUB';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
switch (strtolower($this->getArgument(0))) {
|
||||||
|
case 'numsub':
|
||||||
|
return self::processNumsub($data);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the processed response to PUBSUB NUMSUB.
|
||||||
|
*
|
||||||
|
* @param array $channels List of channels
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected static function processNumsub(array $channels)
|
||||||
|
{
|
||||||
|
$processed = array();
|
||||||
|
$count = count($channels);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $count; ++$i) {
|
||||||
|
$processed[$channels[$i]] = $channels[++$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $processed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/subscribe
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class PubSubSubscribe extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'SUBSCRIBE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/psubscribe
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class PubSubSubscribeByPattern extends PubSubSubscribe
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PSUBSCRIBE';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/unsubscribe
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class PubSubUnsubscribe extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'UNSUBSCRIBE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
return self::normalizeArguments($arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/punsubscribe
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class PubSubUnsubscribeByPattern extends PubSubUnsubscribe
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'PUNSUBSCRIBE';
|
||||||
|
}
|
||||||
|
}
|
||||||
131
rainloop/v/0.0.0/app/libraries/Predis/Command/RawCommand.php
Normal file
131
rainloop/v/0.0.0/app/libraries/Predis/Command/RawCommand.php
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for generic "anonymous" Redis commands.
|
||||||
|
*
|
||||||
|
* This command class does not filter input arguments or parse responses, but
|
||||||
|
* can be used to leverage the standard Predis API to execute any command simply
|
||||||
|
* by providing the needed arguments following the command signature as defined
|
||||||
|
* by Redis in its documentation.
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class RawCommand implements CommandInterface
|
||||||
|
{
|
||||||
|
private $slot;
|
||||||
|
private $commandID;
|
||||||
|
private $arguments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $arguments Command ID and its arguments.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(array $arguments)
|
||||||
|
{
|
||||||
|
if (!$arguments) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'The arguments array must contain at least the command ID.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->commandID = strtoupper(array_shift($arguments));
|
||||||
|
$this->arguments = $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new raw command using a variadic method.
|
||||||
|
*
|
||||||
|
* @param string $commandID Redis command ID.
|
||||||
|
* @param string ... Arguments list for the command.
|
||||||
|
*
|
||||||
|
* @return CommandInterface
|
||||||
|
*/
|
||||||
|
public static function create($commandID /* [ $arg, ... */)
|
||||||
|
{
|
||||||
|
$arguments = func_get_args();
|
||||||
|
$command = new self($arguments);
|
||||||
|
|
||||||
|
return $command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->commandID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setArguments(array $arguments)
|
||||||
|
{
|
||||||
|
$this->arguments = $arguments;
|
||||||
|
unset($this->slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setRawArguments(array $arguments)
|
||||||
|
{
|
||||||
|
$this->setArguments($arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getArguments()
|
||||||
|
{
|
||||||
|
return $this->arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getArgument($index)
|
||||||
|
{
|
||||||
|
if (isset($this->arguments[$index])) {
|
||||||
|
return $this->arguments[$index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setSlot($slot)
|
||||||
|
{
|
||||||
|
$this->slot = $slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSlot()
|
||||||
|
{
|
||||||
|
if (isset($this->slot)) {
|
||||||
|
return $this->slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class used to implement an higher level abstraction for commands based
|
||||||
|
* on Lua scripting with EVAL and EVALSHA.
|
||||||
|
*
|
||||||
|
* @link http://redis.io/commands/eval
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class ScriptCommand extends ServerEvalSHA
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Gets the body of a Lua script.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function getScript();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the number of arguments that should be considered as keys.
|
||||||
|
*
|
||||||
|
* The default behaviour for the base class is to return 0 to indicate that
|
||||||
|
* all the elements of the arguments array should be considered as keys, but
|
||||||
|
* subclasses can enforce a static number of keys.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function getKeysCount()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the elements from the arguments that are identified as keys.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getKeys()
|
||||||
|
{
|
||||||
|
return array_slice($this->getArguments(), 2, $this->getKeysCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function filterArguments(array $arguments)
|
||||||
|
{
|
||||||
|
if (($numkeys = $this->getKeysCount()) && $numkeys < 0) {
|
||||||
|
$numkeys = count($arguments) + $numkeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_merge(array(sha1($this->getScript()), (int) $numkeys), $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getEvalArguments()
|
||||||
|
{
|
||||||
|
$arguments = $this->getArguments();
|
||||||
|
$arguments[0] = $this->getScript();
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/bgrewriteaof
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ServerBackgroundRewriteAOF extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'BGREWRITEAOF';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return $data == 'Background append only file rewriting started';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/bgsave
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ServerBackgroundSave extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'BGSAVE';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
return $data === 'Background saving started' ? true : $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Predis package.
|
||||||
|
*
|
||||||
|
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Predis\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://redis.io/commands/client-list
|
||||||
|
* @link http://redis.io/commands/client-kill
|
||||||
|
* @link http://redis.io/commands/client-getname
|
||||||
|
* @link http://redis.io/commands/client-setname
|
||||||
|
*
|
||||||
|
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||||
|
*/
|
||||||
|
class ServerClient extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return 'CLIENT';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parseResponse($data)
|
||||||
|
{
|
||||||
|
$args = array_change_key_case($this->getArguments(), CASE_UPPER);
|
||||||
|
|
||||||
|
switch (strtoupper($args[0])) {
|
||||||
|
case 'LIST':
|
||||||
|
return $this->parseClientList($data);
|
||||||
|
case 'KILL':
|
||||||
|
case 'GETNAME':
|
||||||
|
case 'SETNAME':
|
||||||
|
default:
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the response to CLIENT LIST and returns a structured list.
|
||||||
|
*
|
||||||
|
* @param string $data Response buffer.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function parseClientList($data)
|
||||||
|
{
|
||||||
|
$clients = array();
|
||||||
|
|
||||||
|
foreach (explode("\n", $data, -1) as $clientData) {
|
||||||
|
$client = array();
|
||||||
|
|
||||||
|
foreach (explode(' ', $clientData) as $kv) {
|
||||||
|
@list($k, $v) = explode('=', $kv);
|
||||||
|
$client[$k] = $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
$clients[] = $client;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $clients;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue