From 55aab868001e374e770653d0f29d6008ea063cee Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Sat, 25 Jul 2015 15:50:24 +0200 Subject: [PATCH] Add support for default connection parameters in Connection\Factory. These parameters augment the set of user-supplied parameters when creating a new connection, but they do not override specific parameters when already defined. An example of self-contained configuration using client options: $client = new Predis\Client('tcp://127.0.0.1', [ 'parameters' => [ 'timeout' => 10, ], 'connections' => function ($options) { $factory = $options->getDefault('connections'); $factory->setDefaultParameters($options->parameters); return $factory; }, ]); This change will be useful for both redis-cluster and redis-sentinel as it makes it easy to apply shared parameters such as a common password for authentication when the server returns one ore more new nodes from response (think of -MOVED). --- CHANGELOG.md | 4 + src/Connection/Factory.php | 39 ++++++- tests/Predis/Connection/FactoryTest.php | 133 ++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a728eb6..64c7bb7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ v1.1.0 (2015-xx-xx) is needed to prevent confusion with how `path` is used to select a database with the `redis` scheme. +- Add support for default connection parameters in Predis\Connection\Factory. + These parameters augment the user-supplied parameters when creating a new + connection but they do not override specific parameters when already defined. + v1.0.1 (2015-01-02) ================================================================================ diff --git a/src/Connection/Factory.php b/src/Connection/Factory.php index e7a4e17f..e83e75ea 100644 --- a/src/Connection/Factory.php +++ b/src/Connection/Factory.php @@ -20,6 +20,8 @@ use Predis\Command\RawCommand; */ class Factory implements FactoryInterface { + private $defaults = array(); + protected $schemes = array( 'tcp' => 'Predis\Connection\StreamConnection', 'unix' => 'Predis\Connection\StreamConnection', @@ -35,8 +37,8 @@ class Factory implements FactoryInterface * @param mixed $initializer FQN of a connection class or a callable for lazy initialization. * * @throws \InvalidArgumentException - * @return mixed * + * @return mixed */ protected function checkInitializer($initializer) { @@ -115,6 +117,29 @@ class Factory implements FactoryInterface } } + /** + * Assigns a default set of parameters applied to new connections. + * + * The set of parameters passed to create a new connection have precedence + * over the default values set for the connection factory. + * + * @param array $parameters Set of connection parameters. + */ + public function setDefaultParameters(array $parameters) + { + $this->defaults = $parameters; + } + + /** + * Returns the default set of parameters applied to new connections. + * + * @return array + */ + public function getDefaultParameters() + { + return $this->defaults; + } + /** * Creates a connection parameters instance from the supplied argument. * @@ -124,7 +149,17 @@ class Factory implements FactoryInterface */ protected function createParameters($parameters) { - return Parameters::create($parameters); + if (is_string($parameters)) { + $parameters = Parameters::parse($parameters); + } else { + $parameters = $parameters ?: array(); + } + + if ($this->defaults) { + $parameters += $this->defaults; + } + + return new Parameters($parameters); } /** diff --git a/tests/Predis/Connection/FactoryTest.php b/tests/Predis/Connection/FactoryTest.php index 4db2821e..773114a7 100644 --- a/tests/Predis/Connection/FactoryTest.php +++ b/tests/Predis/Connection/FactoryTest.php @@ -28,6 +28,24 @@ class FactoryTest extends PredisTestCase $this->assertInstanceOf('Predis\Connection\FactoryInterface', $factory); } + /** + * @group disconnected + */ + public function testSettingDefaultParameters() + { + $factory = new Factory(); + + $factory->setDefaultParameters($defaults = array( + 'password' => 'secret', + 'database' => 10, + 'custom' => 'foobar', + )); + + $this->assertSame($defaults, $factory->getDefaultParameters()); + + $parameters = array('database' => 10, 'persistent' => true); + } + /** * @group disconnected */ @@ -72,6 +90,39 @@ class FactoryTest extends PredisTestCase $this->assertEquals($unix->database, $parameters->database); } + /** + * @group disconnected + */ + public function testCreateConnectionWithParametersInstanceAndDefaultsDoesNotAlterOriginalParameters() + { + $factory = new Factory(); + + $factory->setDefaultParameters($defaultParams = array( + 'port' => 7000, + 'password' => 'secret', + 'database' => 10, + 'custom' => 'foobar', + )); + + $inputParams = new Parameters(array( + 'host' => 'localhost', + 'database' => 5, + )); + + $connection = $factory->create($inputParams); + $parameters = $connection->getParameters(); + + $this->assertEquals('localhost', $parameters->host); + $this->assertEquals(6379, $parameters->port); + $this->assertEquals(5, $parameters->database); + + $this->assertFalse(isset($parameters->password)); + $this->assertNull($parameters->password); + + $this->assertFalse(isset($parameters->custom)); + $this->assertNull($parameters->custom); + } + /** * @group disconnected */ @@ -88,6 +139,31 @@ class FactoryTest extends PredisTestCase $this->assertNull($parameters->custom); } + /** + * @group disconnected + */ + public function testCreateConnectionWithNullParametersAndDefaults() + { + $factory = new Factory(); + + $factory->setDefaultParameters($defaultParams = array( + 'port' => 7000, + 'password' => 'secret', + 'custom' => 'foobar', + )); + + $connection = $factory->create(null); + $parameters = $connection->getParameters(); + + $this->assertInstanceOf('Predis\Connection\NodeConnectionInterface', $connection); + + $this->assertEquals('127.0.0.1', $parameters->host); + $this->assertEquals($defaultParams['port'], $parameters->port); + $this->assertEquals($defaultParams['password'], $parameters->password); + $this->assertEquals($defaultParams['custom'], $parameters->custom); + $this->assertNull($parameters->path); + } + /** * @group disconnected */ @@ -104,6 +180,37 @@ class FactoryTest extends PredisTestCase $this->assertSame('foobar', $parameters->custom); } + /** + * @group disconnected + */ + public function testCreateConnectionWithArrayParametersAndDefaults() + { + $factory = new Factory(); + + $factory->setDefaultParameters($defaultParams = array( + 'port' => 7000, + 'password' => 'secret', + 'custom' => 'foobar', + )); + + $connection = $factory->create($inputParams = array( + 'host' => 'localhost', + 'port' => 8000, + 'persistent' => true, + )); + + $parameters = $connection->getParameters(); + + $this->assertInstanceOf('Predis\Connection\NodeConnectionInterface', $connection); + + $this->assertEquals($inputParams['host'], $parameters->host); + $this->assertEquals($inputParams['port'], $parameters->port); + $this->assertEquals($defaultParams['password'], $parameters->password); + $this->assertEquals($defaultParams['custom'], $parameters->custom); + $this->assertEquals($inputParams['persistent'], $parameters->persistent); + $this->assertNull($parameters->path); + } + /** * @group disconnected */ @@ -120,6 +227,32 @@ class FactoryTest extends PredisTestCase $this->assertSame('foobar', $parameters->custom); } + /** + * @group disconnected + */ + public function testCreateConnectionWithStrinURIAndDefaults() + { + $factory = new Factory(); + + $factory->setDefaultParameters($defaultParams = array( + 'port' => 7000, + 'password' => 'secret', + 'custom' => 'foobar', + )); + + $connection = $factory->create('tcp://localhost:8000?persistent=1'); + $parameters = $connection->getParameters(); + + $this->assertInstanceOf('Predis\Connection\NodeConnectionInterface', $connection); + + $this->assertEquals('localhost', $parameters->host); + $this->assertEquals('8000', $parameters->port); + $this->assertEquals($defaultParams['password'], $parameters->password); + $this->assertEquals($defaultParams['custom'], $parameters->custom); + $this->assertEquals(true, $parameters->persistent); + $this->assertNull($parameters->path); + } + /** * @group disconnected */