Moved cache drivers outside core to extensions (plugins)

This commit is contained in:
the-djmaze 2024-03-22 04:03:39 +01:00
parent d5690fc579
commit 4fc04648cf
267 changed files with 39 additions and 64 deletions

View file

@ -0,0 +1,76 @@
<?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\Configuration;
use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\PredisCluster;
use Predis\Connection\Aggregate\RedisCluster;
/**
* Configures an aggregate connection used for clustering
* multiple Redis nodes using various implementations with
* different algorithms or strategies.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class ClusterOption implements OptionInterface
{
/**
* Creates a new cluster connection from on a known descriptive name.
*
* @param OptionsInterface $options Instance of the client options.
* @param string $id Descriptive identifier of the cluster type (`predis`, `redis-cluster`)
*
* @return ClusterInterface|null
*/
protected function createByDescription(OptionsInterface $options, $id)
{
switch ($id) {
case 'predis':
case 'predis-cluster':
return new PredisCluster();
case 'redis':
case 'redis-cluster':
return new RedisCluster($options->connections);
default:
return;
}
}
/**
* {@inheritdoc}
*/
public function filter(OptionsInterface $options, $value)
{
if (is_string($value)) {
$value = $this->createByDescription($options, $value);
}
if (!$value instanceof ClusterInterface) {
throw new \InvalidArgumentException(
"An instance of type 'Predis\Connection\Aggregate\ClusterInterface' was expected."
);
}
return $value;
}
/**
* {@inheritdoc}
*/
public function getDefault(OptionsInterface $options)
{
return new PredisCluster();
}
}

View file

@ -0,0 +1,54 @@
<?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\Configuration;
use Predis\Connection\Factory;
use Predis\Connection\FactoryInterface;
/**
* Configures a connection factory used by the client to create new connection
* instances for single Redis nodes.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class ConnectionFactoryOption implements OptionInterface
{
/**
* {@inheritdoc}
*/
public function filter(OptionsInterface $options, $value)
{
if ($value instanceof FactoryInterface) {
return $value;
} elseif (is_array($value)) {
$factory = $this->getDefault($options);
foreach ($value as $scheme => $initializer) {
$factory->define($scheme, $initializer);
}
return $factory;
} else {
throw new \InvalidArgumentException(
'Invalid value provided for the connections option.'
);
}
}
/**
* {@inheritdoc}
*/
public function getDefault(OptionsInterface $options)
{
return new Factory();
}
}

View file

@ -0,0 +1,37 @@
<?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\Configuration;
/**
* Configures whether consumers (such as the client) should throw exceptions on
* Redis errors (-ERR responses) or just return instances of error responses.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class ExceptionsOption implements OptionInterface
{
/**
* {@inheritdoc}
*/
public function filter(OptionsInterface $options, $value)
{
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
/**
* {@inheritdoc}
*/
public function getDefault(OptionsInterface $options)
{
return true;
}
}

View file

@ -0,0 +1,40 @@
<?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\Configuration;
/**
* Defines an handler used by Predis\Configuration\Options to filter, validate
* or return default values for a given option.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
interface OptionInterface
{
/**
* Filters and validates the passed value.
*
* @param OptionsInterface $options Options container.
* @param mixed $value Input value.
*
* @return mixed
*/
public function filter(OptionsInterface $options, $value);
/**
* Returns the default value for the option.
*
* @param OptionsInterface $options Options container.
*
* @return mixed
*/
public function getDefault(OptionsInterface $options);
}

View file

@ -0,0 +1,122 @@
<?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\Configuration;
/**
* Manages Predis options with filtering, conversion and lazy initialization of
* values using a mini-DI container approach.
*
* {@inheritdoc}
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class Options implements OptionsInterface
{
protected $input;
protected $options;
protected $handlers;
/**
* @param array $options Array of options with their values
*/
public function __construct(array $options = array())
{
$this->input = $options;
$this->options = array();
$this->handlers = $this->getHandlers();
}
/**
* Ensures that the default options are initialized.
*
* @return array
*/
protected function getHandlers()
{
return array(
'cluster' => 'Predis\Configuration\ClusterOption',
'connections' => 'Predis\Configuration\ConnectionFactoryOption',
'exceptions' => 'Predis\Configuration\ExceptionsOption',
'prefix' => 'Predis\Configuration\PrefixOption',
'profile' => 'Predis\Configuration\ProfileOption',
'replication' => 'Predis\Configuration\ReplicationOption',
);
}
/**
* {@inheritdoc}
*/
public function getDefault($option)
{
if (isset($this->handlers[$option])) {
$handler = $this->handlers[$option];
$handler = new $handler();
return $handler->getDefault($this);
}
}
/**
* {@inheritdoc}
*/
public function defined($option)
{
return (
array_key_exists($option, $this->options) ||
array_key_exists($option, $this->input)
);
}
/**
* {@inheritdoc}
*/
public function __isset($option)
{
return (
array_key_exists($option, $this->options) ||
array_key_exists($option, $this->input)
) && $this->__get($option) !== null;
}
/**
* {@inheritdoc}
*/
public function __get($option)
{
if (isset($this->options[$option]) || array_key_exists($option, $this->options)) {
return $this->options[$option];
}
if (isset($this->input[$option]) || array_key_exists($option, $this->input)) {
$value = $this->input[$option];
unset($this->input[$option]);
if (is_object($value) && method_exists($value, '__invoke')) {
$value = $value($this, $option);
}
if (isset($this->handlers[$option])) {
$handler = $this->handlers[$option];
$handler = new $handler();
$value = $handler->filter($this, $value);
}
return $this->options[$option] = $value;
}
if (isset($this->handlers[$option])) {
return $this->options[$option] = $this->getDefault($option);
}
return;
}
}

View file

@ -0,0 +1,64 @@
<?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\Configuration;
/**
* Interface defining a container for client options.
*
* @property-read mixed aggregate Custom connection aggregator.
* @property-read mixed cluster Aggregate connection for clustering.
* @property-read mixed connections Connection factory.
* @property-read mixed exceptions Toggles exceptions in client for -ERR responses.
* @property-read mixed prefix Key prefixing strategy using the given prefix.
* @property-read mixed profile Server profile.
* @property-read mixed replication Aggregate connection for replication.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
interface OptionsInterface
{
/**
* Returns the default value for the given option.
*
* @param string $option Name of the option.
*
* @return mixed|null
*/
public function getDefault($option);
/**
* Checks if the given option has been set by the user upon initialization.
*
* @param string $option Name of the option.
*
* @return bool
*/
public function defined($option);
/**
* Checks if the given option has been set and does not evaluate to NULL.
*
* @param string $option Name of the option.
*
* @return bool
*/
public function __isset($option);
/**
* Returns the value of the given option.
*
* @param string $option Name of the option.
*
* @return mixed|null
*/
public function __get($option);
}

View file

@ -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\Configuration;
use Predis\Command\Processor\KeyPrefixProcessor;
use Predis\Command\Processor\ProcessorInterface;
/**
* Configures a command processor that apply the specified prefix string to a
* series of Redis commands considered prefixable.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class PrefixOption implements OptionInterface
{
/**
* {@inheritdoc}
*/
public function filter(OptionsInterface $options, $value)
{
if ($value instanceof ProcessorInterface) {
return $value;
}
return new KeyPrefixProcessor($value);
}
/**
* {@inheritdoc}
*/
public function getDefault(OptionsInterface $options)
{
// NOOP
}
}

View file

@ -0,0 +1,69 @@
<?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\Configuration;
use Predis\Profile\Factory;
use Predis\Profile\ProfileInterface;
use Predis\Profile\RedisProfile;
/**
* Configures the server profile to be used by the client to create command
* instances depending on the specified version of the Redis server.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class ProfileOption implements OptionInterface
{
/**
* Sets the commands processors that need to be applied to the profile.
*
* @param OptionsInterface $options Client options.
* @param ProfileInterface $profile Server profile.
*/
protected function setProcessors(OptionsInterface $options, ProfileInterface $profile)
{
if (isset($options->prefix) && $profile instanceof RedisProfile) {
// NOTE: directly using __get('prefix') is actually a workaround for
// HHVM 2.3.0. It's correct and respects the options interface, it's
// just ugly. We will remove this hack when HHVM will fix re-entrant
// calls to __get() once and for all.
$profile->setProcessor($options->__get('prefix'));
}
}
/**
* {@inheritdoc}
*/
public function filter(OptionsInterface $options, $value)
{
if (is_string($value)) {
$value = Factory::get($value);
$this->setProcessors($options, $value);
} elseif (!$value instanceof ProfileInterface) {
throw new \InvalidArgumentException('Invalid value for the profile option.');
}
return $value;
}
/**
* {@inheritdoc}
*/
public function getDefault(OptionsInterface $options)
{
$profile = Factory::getDefault();
$this->setProcessors($options, $profile);
return $profile;
}
}

View file

@ -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\Configuration;
use Predis\Connection\Aggregate\MasterSlaveReplication;
use Predis\Connection\Aggregate\ReplicationInterface;
/**
* Configures an aggregate connection used for master/slave replication among
* multiple Redis nodes.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class ReplicationOption implements OptionInterface
{
/**
* {@inheritdoc}
*
* @todo There's more code than needed due to a bug in filter_var() as
* discussed here https://bugs.php.net/bug.php?id=49510 and different
* behaviours when encountering NULL values on PHP 5.3.
*/
public function filter(OptionsInterface $options, $value)
{
if ($value instanceof ReplicationInterface) {
return $value;
}
if (is_bool($value) || $value === null) {
return $value ? $this->getDefault($options) : null;
}
if (
!is_object($value) &&
null !== $asbool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
) {
return $asbool ? $this->getDefault($options) : null;
}
throw new \InvalidArgumentException(
"An instance of type 'Predis\Connection\Aggregate\ReplicationInterface' was expected."
);
}
/**
* {@inheritdoc}
*/
public function getDefault(OptionsInterface $options)
{
return new MasterSlaveReplication();
}
}