diff --git a/README.md b/README.md index 62077d1..defa25d 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ local Redis server and send some requests: $loop = React\EventLoop\Factory::create(); $factory = new Factory($loop); -$factory->createClient('localhost:6379')->then(function (Client $client) use ($loop) { +$factory->createClient('localhost')->then(function (Client $client) use ($loop) { $client->set('greeting', 'Hello world'); $client->append('greeting', '!'); @@ -98,15 +98,9 @@ $connector = new \React\Socket\Connector($loop, array( $factory = new Factory($loop, $connector); ``` -> Legacy notice: As of `v1.2.0`, the optional connector should implement the new - `React\Socket\ConnectorInterface`. For BC reasons it also accepts the - legacy `React\SocketClient\ConnectorInterface`. - This legacy API will be removed in a future `v2.0.0` version, so it's highly - recommended to upgrade to the above API. - #### createClient() -The `createClient($redisUri = null)` method can be used to create a new [`Client`](#client). +The `createClient($redisUri)` method can be used to create a new [`Client`](#client). It helps with establishing a plain TCP/IP or secure TLS connection to Redis and optionally authenticating (AUTH) and selecting the right database (SELECT). @@ -143,12 +137,6 @@ $factory->createClient('redis://ignored:h%40llo@localhost'); $factory->createClient('redis://localhost?password=h%40llo'); ``` -> Legacy notice: The `redis://` scheme is defined and preferred as of `v1.2.0`. - For BC reasons, the `Factory` defaults to the `tcp://` scheme in which case - the authentication details would include the otherwise unused username. - This legacy API will be removed in a future `v2.0.0` version, so it's highly - recommended to upgrade to the above API. - You can optionally include a path that will be used to select (SELECT command) the right database: ```php @@ -164,15 +152,6 @@ You can use the [standard](https://www.iana.org/assignments/uri-schemes/prov/red $factory->createClient('rediss://redis.example.com:6340'); ``` -[Deprecated] You can omit the complete URI if you want to connect to the default -address `redis://localhost:6379`. This legacy API will be removed in a future -`v2.0.0` version, so it's highly recommended to upgrade to the above API. - -```php -// deprecated -$factory->createClient(); -``` - ### Client The `Client` is responsible for exchanging messages with Redis diff --git a/composer.json b/composer.json index d77e979..d8f9bad 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,6 @@ "react/event-loop": "0.3.*|0.4.*", "react/promise": "^2.0 || ^1.1", "react/socket": "^0.7", - "react/socket-client": "^0.7", "clue/redis-protocol": "0.3.*", "evenement/evenement": "~1.0|~2.0" }, diff --git a/examples/cli.php b/examples/cli.php index cde81ea..6cd3ed4 100644 --- a/examples/cli.php +++ b/examples/cli.php @@ -12,7 +12,7 @@ echo '# connecting to redis...' . PHP_EOL; -$factory->createClient()->then(function (Client $client) use ($loop) { +$factory->createClient('localhost')->then(function (Client $client) use ($loop) { echo '# connected! Entering interactive mode, hit CTRL-D to quit' . PHP_EOL; $client->on('data', function (ModelInterface $data) { diff --git a/examples/incr.php b/examples/incr.php index 9378f0c..35c0684 100644 --- a/examples/incr.php +++ b/examples/incr.php @@ -8,7 +8,7 @@ $loop = React\EventLoop\Factory::create(); $factory = new Factory($loop); -$factory->createClient()->then(function (Client $client) { +$factory->createClient('localhost')->then(function (Client $client) { $client->incr('test'); $client->get('test')->then(function ($result) { diff --git a/examples/monitor.php b/examples/monitor.php index 1043565..9a85169 100644 --- a/examples/monitor.php +++ b/examples/monitor.php @@ -9,7 +9,7 @@ $loop = React\EventLoop\Factory::create(); $factory = new Factory($loop); -$factory->createClient()->then(function (Client $client) { +$factory->createClient('localhost')->then(function (Client $client) { $client->monitor()->then(function ($result) { echo 'Now monitoring all commands' . PHP_EOL; }); diff --git a/examples/publish.php b/examples/publish.php index 1f36460..2d6e8f1 100644 --- a/examples/publish.php +++ b/examples/publish.php @@ -2,7 +2,6 @@ use Clue\React\Redis\Client; use Clue\React\Redis\Factory; -use Clue\Redis\Protocol\Model\StatusReply; require __DIR__ . '/../vendor/autoload.php'; @@ -12,7 +11,7 @@ $channel = isset($argv[1]) ? $argv[1] : 'channel'; $message = isset($argv[2]) ? $argv[2] : 'message'; -$factory->createClient()->then(function (Client $client) use ($channel, $message) { +$factory->createClient('localhost')->then(function (Client $client) use ($channel, $message) { $client->publish($channel, $message)->then(function ($received) { echo 'successfully published. Received by ' . $received . PHP_EOL; }); diff --git a/examples/subscribe.php b/examples/subscribe.php index 965cff2..efae0a4 100644 --- a/examples/subscribe.php +++ b/examples/subscribe.php @@ -2,7 +2,6 @@ use Clue\React\Redis\Client; use Clue\React\Redis\Factory; -use Clue\Redis\Protocol\Model\StatusReply; require __DIR__ . '/../vendor/autoload.php'; @@ -11,7 +10,7 @@ $channel = isset($argv[1]) ? $argv[1] : 'channel'; -$factory->createClient()->then(function (Client $client) use ($channel) { +$factory->createClient('localhost')->then(function (Client $client) use ($channel) { $client->subscribe($channel)->then(function () { echo 'Now subscribed to channel ' . PHP_EOL; }); diff --git a/src/ConnectionUpcaster.php b/src/ConnectionUpcaster.php deleted file mode 100644 index c2a0f8f..0000000 --- a/src/ConnectionUpcaster.php +++ /dev/null @@ -1,78 +0,0 @@ -stream = $stream; - - Util::forwardEvents($stream, $this, array('data', 'end', 'close', 'error', 'drain')); - $this->stream->on('close', array($this, 'close')); - } - - public function isReadable() - { - return $this->stream->isReadable(); - } - - public function isWritable() - { - return $this->isWritable(); - } - - public function pause() - { - $this->stream->pause(); - } - - public function resume() - { - $this->stream->resume(); - } - - public function pipe(WritableStreamInterface $dest, array $options = array()) - { - $this->stream->pipe($dest, $options); - } - - public function write($data) - { - return $this->stream->write($data); - } - - public function end($data = null) - { - return $this->stream->end($data); - } - - public function close() - { - $this->stream->close(); - $this->removeAllListeners(); - } - - public function getRemoteAddress() - { - return null; - } - - public function getLocalAddress() - { - return null; - } -} diff --git a/src/ConnectorUpcaster.php b/src/ConnectorUpcaster.php deleted file mode 100644 index 14b03a3..0000000 --- a/src/ConnectorUpcaster.php +++ /dev/null @@ -1,29 +0,0 @@ -legacy = $connector; - } - - public function connect($uri) - { - return $this->legacy->connect($uri)->then(function (DuplexStreamInterface $stream) { - return new ConnectionUpcaster($stream); - }); - } -} diff --git a/src/Factory.php b/src/Factory.php index 13aa461..0bb110e 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -18,19 +18,14 @@ class Factory /** * @param LoopInterface $loop - * @param ConnectorInterface|\React\SocketClient\ConnectorInterface|null $connector - * [optional] Connector to use. Should be `null` in order to use default - * Connector. Passing a `\React\SocketClient\ConnectorInterface` is - * deprecated and only supported for BC reasons and will be removed in - * future versions. + * @param ConnectorInterface|null $connector [optional] Connector to use. + * Should be `null` in order to use default Connector. * @param ProtocolFactory|null $protocol */ - public function __construct(LoopInterface $loop, $connector = null, ProtocolFactory $protocol = null) + public function __construct(LoopInterface $loop, ConnectorInterface $connector = null, ProtocolFactory $protocol = null) { if ($connector === null) { $connector = new Connector($loop); - } elseif (!$connector instanceof ConnectorInterface) { - $connector = new ConnectorUpcaster($connector); } if ($protocol === null) { @@ -44,12 +39,10 @@ public function __construct(LoopInterface $loop, $connector = null, ProtocolFact /** * create redis client connected to address of given redis instance * - * @param string|null $target Redis server URI to connect to. Not passing - * this parameter is deprecated and only supported for BC reasons and - * will be removed in future versions. + * @param string $target Redis server URI to connect to * @return \React\Promise\PromiseInterface resolves with Client or rejects with \Exception */ - public function createClient($target = null) + public function createClient($target) { try { $parts = $this->parseUrl($target); @@ -95,21 +88,18 @@ function ($error) use ($client) { } /** - * @param string|null $target + * @param string $target * @return array with keys host, port, auth and db * @throws InvalidArgumentException */ private function parseUrl($target) { - if ($target === null) { - $target = 'tcp://127.0.0.1'; - } if (strpos($target, '://') === false) { - $target = 'tcp://' . $target; + $target = 'redis://' . $target; } $parts = parse_url($target); - if ($parts === false || !isset($parts['scheme'], $parts['host']) || !in_array($parts['scheme'], array('tcp', 'redis', 'rediss'))) { + if ($parts === false || !isset($parts['scheme'], $parts['host']) || !in_array($parts['scheme'], array('redis', 'rediss'))) { throw new InvalidArgumentException('Given URL can not be parsed'); } @@ -121,15 +111,8 @@ private function parseUrl($target) $parts['host'] = '127.0.0.1'; } - $auth = null; - if (isset($parts['user']) && $parts['scheme'] === 'tcp') { - $auth = rawurldecode($parts['user']); - } if (isset($parts['pass'])) { - $auth .= ($parts['scheme'] === 'tcp' ? ':' : '') . rawurldecode($parts['pass']); - } - if ($auth !== null) { - $parts['auth'] = $auth; + $parts['auth'] = rawurldecode($parts['pass']); } if (isset($parts['path']) && $parts['path'] !== '') { diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index a2027cb..163e7aa 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -21,12 +21,6 @@ public function testCtor() $this->factory = new Factory($this->loop); } - public function testWillConnectToLocalIpWithDefaultPortIfTargetIsNotGiven() - { - $this->connector->expects($this->once())->method('connect')->with('127.0.0.1:6379')->willReturn(Promise\reject(new \RuntimeException())); - $this->factory->createClient(); - } - public function testWillConnectWithDefaultPort() { $this->connector->expects($this->once())->method('connect')->with('redis.example.com:6379')->willReturn(Promise\reject(new \RuntimeException())); @@ -36,16 +30,7 @@ public function testWillConnectWithDefaultPort() public function testWillConnectToLocalIpWhenTargetIsLocalhost() { $this->connector->expects($this->once())->method('connect')->with('127.0.0.1:1337')->willReturn(Promise\reject(new \RuntimeException())); - $this->factory->createClient('tcp://localhost:1337'); - } - - public function testWillUpcastLegacyConnectorAndConnect() - { - $this->connector = $this->getMockBuilder('React\SocketClient\ConnectorInterface')->getMock(); - $this->factory = new Factory($this->loop, $this->connector); - - $this->connector->expects($this->once())->method('connect')->with('example.com:1337')->willReturn(Promise\reject(new \RuntimeException())); - $this->factory->createClient('tcp://example.com:1337'); + $this->factory->createClient('localhost:1337'); } public function testWillResolveIfConnectorResolves() @@ -54,7 +39,7 @@ public function testWillResolveIfConnectorResolves() $stream->expects($this->never())->method('write'); $this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream)); - $promise = $this->factory->createClient(); + $promise = $this->factory->createClient('localhost'); $this->expectPromiseResolve($promise); } @@ -122,19 +107,10 @@ public function testWillWriteAuthCommandIfRedissUriContainsUserInfo() $this->factory->createClient('rediss://hello:world@example.com'); } - public function testWillWriteAuthCommandIfTcpUriContainsUserInfo() - { - $stream = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); - $stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$11\r\nhello:world\r\n"); - - $this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream)); - $this->factory->createClient('tcp://hello:world@127.0.0.1'); - } - public function testWillRejectIfConnectorRejects() { $this->connector->expects($this->once())->method('connect')->with('127.0.0.1:2')->willReturn(Promise\reject(new \RuntimeException())); - $promise = $this->factory->createClient('tcp://127.0.0.1:2'); + $promise = $this->factory->createClient('redis://127.0.0.1:2'); $this->expectPromiseReject($promise); } diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index 080a4ab..91fe4c4 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -1,11 +1,10 @@ client->close(); - $this->factory = new Factory($this->loop, new Connector($this->loop)); - $this->client = $this->createClient(getenv('REDIS_URI')); - - $promise = $this->client->ping(); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); - $promise->then($this->expectCallableOnce('PONG')); - - $this->client->end(); - $this->waitFor($this->client); - } - public function testMgetIsNotInterpretedAsSubMessage() { $client = $this->client;