mirror of
https://github.com/predis/predis.git
synced 2026-09-13 03:47:03 +00:00
Re-implement CLIENT command as container command (#1337)
This commit is contained in:
committed by
GitHub
parent
e8daf1abaf
commit
00e87640a7
@@ -38,11 +38,12 @@ use Predis\Command\Argument\TimeSeries\MGetArguments;
|
||||
use Predis\Command\Argument\TimeSeries\MRangeArguments;
|
||||
use Predis\Command\Argument\TimeSeries\RangeArguments;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\Redis\Container\ACL;
|
||||
use Predis\Command\Redis\Container\FunctionContainer;
|
||||
use Predis\Command\Redis\Container\Json\JSONDEBUG;
|
||||
use Predis\Command\Redis\Container\Search\FTCONFIG;
|
||||
use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||
use Predis\Command\Container\ACL;
|
||||
use Predis\Command\Container\CLIENT;
|
||||
use Predis\Command\Container\FUNCTIONS;
|
||||
use Predis\Command\Container\Json\JSONDEBUG;
|
||||
use Predis\Command\Container\Search\FTCONFIG;
|
||||
use Predis\Command\Container\Search\FTCURSOR;
|
||||
|
||||
/**
|
||||
* Interface defining a client-side context such as a pipeline or transaction.
|
||||
@@ -316,7 +317,6 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||
* @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()
|
||||
@@ -338,11 +338,12 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||
* @method $this geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||
*
|
||||
* Container commands
|
||||
* @property FunctionContainer $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
* @property CLIENT $client
|
||||
* @property FUNCTIONS $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
*/
|
||||
interface ClientContextInterface
|
||||
{
|
||||
|
||||
+12
-11
@@ -38,12 +38,13 @@ use Predis\Command\Argument\TimeSeries\MGetArguments;
|
||||
use Predis\Command\Argument\TimeSeries\MRangeArguments;
|
||||
use Predis\Command\Argument\TimeSeries\RangeArguments;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\Container\ACL;
|
||||
use Predis\Command\Container\CLIENT;
|
||||
use Predis\Command\Container\FUNCTIONS;
|
||||
use Predis\Command\Container\Json\JSONDEBUG;
|
||||
use Predis\Command\Container\Search\FTCONFIG;
|
||||
use Predis\Command\Container\Search\FTCURSOR;
|
||||
use Predis\Command\FactoryInterface;
|
||||
use Predis\Command\Redis\Container\ACL;
|
||||
use Predis\Command\Redis\Container\FunctionContainer;
|
||||
use Predis\Command\Redis\Container\Json\JSONDEBUG;
|
||||
use Predis\Command\Redis\Container\Search\FTCONFIG;
|
||||
use Predis\Command\Redis\Container\Search\FTCURSOR;
|
||||
use Predis\Configuration\OptionsInterface;
|
||||
use Predis\Connection\ConnectionInterface;
|
||||
use Predis\Response\Status;
|
||||
@@ -334,7 +335,6 @@ use Predis\Response\Status;
|
||||
* @method mixed select(int $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()
|
||||
@@ -356,11 +356,12 @@ use Predis\Response\Status;
|
||||
* @method int geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||
*
|
||||
* Container commands
|
||||
* @property FunctionContainer $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
* @property CLIENT $client
|
||||
* @property FUNCTIONS $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
*/
|
||||
interface ClientInterface
|
||||
{
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container;
|
||||
|
||||
use Predis\Response\Status;
|
||||
|
||||
/**
|
||||
* @method string getName()
|
||||
* @method Status kill(...$arguments)
|
||||
* @method string list(string $type = null, int ...$clientId)
|
||||
* @method Status noTouch(bool $enable = null)
|
||||
* @method Status setInfo(string $modifier = null, string $value = null)
|
||||
* @method Status setName(string $connectionName)
|
||||
*/
|
||||
class CLIENT extends AbstractContainer
|
||||
{
|
||||
public function getContainerCommandId(): string
|
||||
{
|
||||
return 'CLIENT';
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,73 @@ class CLIENT extends RedisCommand
|
||||
return 'CLIENT';
|
||||
}
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
switch ($arguments[0]) {
|
||||
case 'LIST':
|
||||
$this->setListArguments($arguments);
|
||||
break;
|
||||
case 'NOTOUCH':
|
||||
$arguments[0] = 'NO-TOUCH';
|
||||
$this->setNoTouchArguments($arguments);
|
||||
break;
|
||||
case 'SETINFO':
|
||||
$this->setSetInfoArguments($arguments);
|
||||
break;
|
||||
default:
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
private function setListArguments(array $arguments): void
|
||||
{
|
||||
$processedArguments = [$arguments[0]];
|
||||
|
||||
if (array_key_exists(1, $arguments) && null !== $arguments[1]) {
|
||||
array_push($processedArguments, 'TYPE', strtoupper($arguments[1]));
|
||||
}
|
||||
|
||||
if (array_key_exists(2, $arguments)) {
|
||||
array_push($processedArguments, 'ID', $arguments[2]);
|
||||
}
|
||||
|
||||
if (count($arguments) > 3) {
|
||||
for ($i = 3, $iMax = count($arguments); $i < $iMax; $i++) {
|
||||
$processedArguments[] = $arguments[$i];
|
||||
}
|
||||
}
|
||||
|
||||
parent::setArguments($processedArguments);
|
||||
}
|
||||
|
||||
private function setNoTouchArguments(array $arguments): void
|
||||
{
|
||||
$processedArguments = [$arguments[0]];
|
||||
|
||||
if (array_key_exists(1, $arguments) && null !== $arguments[1]) {
|
||||
$modifier = ($arguments[1]) ? 'ON' : 'OFF';
|
||||
$processedArguments[] = $modifier;
|
||||
}
|
||||
|
||||
parent::setArguments($processedArguments);
|
||||
}
|
||||
|
||||
private function setSetInfoArguments(array $arguments): void
|
||||
{
|
||||
$processedArguments = [$arguments[0]];
|
||||
|
||||
if (
|
||||
array_key_exists(1, $arguments)
|
||||
&& null !== $arguments[1]
|
||||
&& array_key_exists(2, $arguments)
|
||||
&& null !== $arguments[2]
|
||||
) {
|
||||
array_push($processedArguments, strtoupper($arguments[1]), $arguments[2]);
|
||||
}
|
||||
|
||||
parent::setArguments($processedArguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -39,8 +39,8 @@ class CLIENT_Test extends PredisCommandTestCase
|
||||
*/
|
||||
public function testFilterArgumentsOfClientKill(): void
|
||||
{
|
||||
$arguments = ['kill', '127.0.0.1:45393'];
|
||||
$expected = ['kill', '127.0.0.1:45393'];
|
||||
$arguments = ['KILL', '127.0.0.1:45393'];
|
||||
$expected = ['KILL', '127.0.0.1:45393'];
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($arguments);
|
||||
@@ -49,17 +49,15 @@ class CLIENT_Test extends PredisCommandTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider listArgumentsProvider
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testFilterArgumentsOfClientList(): void
|
||||
public function testFilterArgumentsOfClientList(array $actualArguments, array $expectedArguments): void
|
||||
{
|
||||
$arguments = ['list'];
|
||||
$expected = ['list'];
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($arguments);
|
||||
$command->setArguments($actualArguments);
|
||||
|
||||
$this->assertSame($expected, $command->getArguments());
|
||||
$this->assertSame($expectedArguments, $command->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +65,7 @@ class CLIENT_Test extends PredisCommandTestCase
|
||||
*/
|
||||
public function testFilterArgumentsOfClientGetname(): void
|
||||
{
|
||||
$arguments = $expected = ['getname'];
|
||||
$arguments = $expected = ['GETNAME'];
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($arguments);
|
||||
@@ -80,7 +78,7 @@ class CLIENT_Test extends PredisCommandTestCase
|
||||
*/
|
||||
public function testFilterArgumentsOfClientSetname(): void
|
||||
{
|
||||
$arguments = $expected = ['setname', 'connection-a'];
|
||||
$arguments = $expected = ['SETNAME', 'connection-a'];
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($arguments);
|
||||
@@ -88,6 +86,30 @@ class CLIENT_Test extends PredisCommandTestCase
|
||||
$this->assertSame($expected, $command->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider noTouchArgumentsProvider
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testFilterArgumentsNoTouch(array $actualArguments, array $expectedArguments): void
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($actualArguments);
|
||||
|
||||
$this->assertSame($expectedArguments, $command->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider setInfoArgumentsProvider
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testFilterArgumentsSetInfo(array $actualArguments, array $expectedArguments): void
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($actualArguments);
|
||||
|
||||
$this->assertSame($expectedArguments, $command->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
@@ -131,7 +153,7 @@ BUFFER;
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
|
||||
$this->assertIsArray($clients = $redis->client('LIST'));
|
||||
$this->assertIsArray($clients = $redis->client->list());
|
||||
$this->assertGreaterThanOrEqual(1, count($clients));
|
||||
$this->assertIsArray($clients[0]);
|
||||
$this->assertArrayHasKey('addr', $clients[0]);
|
||||
@@ -151,12 +173,12 @@ BUFFER;
|
||||
public function testGetsNameOfConnection(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
$clientName = $redis->client('GETNAME');
|
||||
$clientName = $redis->client->getName();
|
||||
$this->assertNull($clientName);
|
||||
|
||||
$expectedConnectionName = 'foo-bar';
|
||||
$this->assertEquals('OK', $redis->client('SETNAME', $expectedConnectionName));
|
||||
$this->assertEquals($expectedConnectionName, $redis->client('GETNAME'));
|
||||
$this->assertEquals('OK', $redis->client->setName($expectedConnectionName));
|
||||
$this->assertEquals($expectedConnectionName, $redis->client->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,8 +190,33 @@ BUFFER;
|
||||
$redis = $this->getClient();
|
||||
|
||||
$expectedConnectionName = 'foo-baz';
|
||||
$this->assertEquals('OK', $redis->client('SETNAME', $expectedConnectionName));
|
||||
$this->assertEquals($expectedConnectionName, $redis->client('GETNAME'));
|
||||
$this->assertEquals('OK', $redis->client->setName($expectedConnectionName));
|
||||
$this->assertEquals($expectedConnectionName, $redis->client->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 7.2.0
|
||||
*/
|
||||
public function testNoTouchTurnOnControlOnKeys(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
|
||||
$this->assertEquals('OK', $redis->client->noTouch(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 7.2.0
|
||||
*/
|
||||
public function testSetInfoToCurrentClientConnection(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
|
||||
$this->assertEquals('OK', $redis->client->setInfo('LIB-NAME', 'lib'));
|
||||
$this->assertEquals('OK', $redis->client->setInfo('LIB-VER', '1.0.0'));
|
||||
$this->assertSame('lib', $redis->client->list()[0]['lib-name']);
|
||||
$this->assertSame('1.0.0', $redis->client->list()[0]['lib-ver']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,20 +243,7 @@ BUFFER;
|
||||
$this->expectException('Predis\Response\ServerException');
|
||||
|
||||
$redis = $this->getClient();
|
||||
$redis->client('SETNAME', $invalidConnectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 2.4.0
|
||||
*/
|
||||
public function testThrowsExceptioOnWrongModifier(): void
|
||||
{
|
||||
$this->expectException('Predis\Response\ServerException');
|
||||
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->client('FOO');
|
||||
$redis->client->setName($invalidConnectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,6 +257,64 @@ BUFFER;
|
||||
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->client('KILL', '127.0.0.1:65535');
|
||||
$redis->client->kill('127.0.0.1:65535');
|
||||
}
|
||||
|
||||
public function listArgumentsProvider(): array
|
||||
{
|
||||
return [
|
||||
'with default arguments' => [
|
||||
['LIST'],
|
||||
['LIST'],
|
||||
],
|
||||
'with TYPE modifier' => [
|
||||
['LIST', 'MASTER'],
|
||||
['LIST', 'TYPE', 'MASTER'],
|
||||
],
|
||||
'with ID modifier' => [
|
||||
['LIST', null, 1, 2, 3],
|
||||
['LIST', 'ID', 1, 2, 3],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function noTouchArgumentsProvider(): array
|
||||
{
|
||||
return [
|
||||
'with default arguments' => [
|
||||
['NOTOUCH'],
|
||||
['NO-TOUCH'],
|
||||
],
|
||||
'with enabled modifier' => [
|
||||
['NOTOUCH', true],
|
||||
['NO-TOUCH', 'ON'],
|
||||
],
|
||||
'with disabled modifier' => [
|
||||
['NOTOUCH', false],
|
||||
['NO-TOUCH', 'OFF'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function setInfoArgumentsProvider(): array
|
||||
{
|
||||
return [
|
||||
'with default arguments' => [
|
||||
['SETINFO'],
|
||||
['SETINFO'],
|
||||
],
|
||||
'with LIB-NAME modifier' => [
|
||||
['SETINFO', 'LIB-NAME', 'lib'],
|
||||
['SETINFO', 'LIB-NAME', 'lib'],
|
||||
],
|
||||
'with LIB-VER modifier' => [
|
||||
['SETINFO', 'LIB-VER', '1.0.0'],
|
||||
['SETINFO', 'LIB-VER', '1.0.0'],
|
||||
],
|
||||
'with only modifier given' => [
|
||||
['SETINFO', 'LIB-VER'],
|
||||
['SETINFO'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user