From 83fb0020a1362dfa8e16c8775988aaa8bd4f887d Mon Sep 17 00:00:00 2001 From: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> Date: Fri, 23 Dec 2022 21:17:24 +0200 Subject: [PATCH] Added support for GETEX command (#872) Co-authored-by: Vladyslav Vildanov --- src/ClientContextInterface.php | 1 + src/ClientInterface.php | 1 + src/Command/Redis/GETEX.php | 51 ++++++ tests/Predis/Command/Redis/GETEX_Test.php | 180 ++++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 src/Command/Redis/GETEX.php create mode 100644 tests/Predis/Command/Redis/GETEX_Test.php diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index 57475991..326bfdfb 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -47,6 +47,7 @@ use Predis\Command\CommandInterface; * @method $this decrby($key, $decrement) * @method $this get($key) * @method $this getbit($key, $offset) + * @method $this getex(string $key, $modifier = '', $value = false) * @method $this getrange($key, $start, $end) * @method $this getdel(string $key) * @method $this getset($key, $value) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index a223b550..aa9d2ffe 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -56,6 +56,7 @@ use Predis\Response\Status; * @method int decrby(string $key, int $decrement) * @method string|null get(string $key) * @method int getbit(string $key, $offset) + * @method int|null getex(string $key, $modifier = '', $value = false) * @method string getrange(string $key, $start, $end) * @method string getdel(string $key) * @method string|null getset(string $key, $value) diff --git a/src/Command/Redis/GETEX.php b/src/Command/Redis/GETEX.php new file mode 100644 index 00000000..32990d34 --- /dev/null +++ b/src/Command/Redis/GETEX.php @@ -0,0 +1,51 @@ + 'EX', + 'px' => 'PX', + 'exat' => 'EXAT', + 'pxat' => 'PXAT', + 'persist' => 'PERSIST', + ]; + + public function getId() + { + return 'GETEX'; + } + + public function setArguments(array $arguments) + { + if (!array_key_exists(1, $arguments) || $arguments[1] === '') { + parent::setArguments([$arguments[0]]); + return; + } + + if (!in_array(strtoupper($arguments[1]), self::$modifierEnum)) { + $enumValues = implode(', ', array_keys(self::$modifierEnum)); + throw new UnexpectedValueException("Modifier argument accepts only: {$enumValues} values"); + } + + if ($arguments[1] === 'persist') { + parent::setArguments([$arguments[0], self::$modifierEnum[$arguments[1]]]); + return; + } + + $arguments[1] = self::$modifierEnum[$arguments[1]]; + + if (!array_key_exists(2, $arguments)) { + throw new UnexpectedValueException('You should provide value for current modifier'); + } + + parent::setArguments($arguments); + } +} diff --git a/tests/Predis/Command/Redis/GETEX_Test.php b/tests/Predis/Command/Redis/GETEX_Test.php new file mode 100644 index 00000000..224fecba --- /dev/null +++ b/tests/Predis/Command/Redis/GETEX_Test.php @@ -0,0 +1,180 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Predis\Command\Redis; + +use UnexpectedValueException; + +/** + * @group commands + * @group realm-string + */ +class GETEX_Test extends PredisCommandTestCase +{ + /** + * {@inheritdoc} + */ + protected function getExpectedCommand(): string + { + return GETEX::class; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedId(): string + { + return 'GETEX'; + } + + /** + * @group disconnected + * @dataProvider argumentsProvider + */ + public function testFilterArguments(array $actualArguments, array $expectedArguments): void + { + $command = $this->getCommand(); + $command->setArguments($actualArguments); + + $this->assertSame($expectedArguments, $command->getArguments()); + } + + /** + * @group disconnected + */ + public function testParseResponse(): void + { + $command = $this->getCommand(); + + $this->assertSame(1, $command->parseResponse(1)); + } + + /** + * @group connected + * @dataProvider keysProvider + * @param array $kvPair + * @param array $arguments + * @param string $expectedResponse + * @return void + * @requiresRedisVersion >= 6.2.0 + */ + public function testReturnsValueAndSetExpirationTimeForGivenKey( + array $kvPair, + array $arguments, + string $expectedResponse + ): void { + $redis = $this->getClient(); + + $redis->set(...$kvPair); + + $this->assertSame($expectedResponse, $redis->getex(...$arguments)); + } + + /** + * @group connected + * @dataProvider unexpectedValuesProvider + * @param array $arguments + * @param string $expectedExceptionMessage + * @return void + * @requiresRedisVersion >= 6.2.0 + */ + public function testThrowsExceptionOnUnexpectedValueGiven( + array $arguments, + string $expectedExceptionMessage + ): void { + $redis = $this->getClient(); + + $this->expectException(UnexpectedValueException::class); + $this->expectExceptionMessage($expectedExceptionMessage); + + $redis->getex(...$arguments); + } + + public function argumentsProvider(): array + { + return [ + 'with default arguments' => [ + ['key'], + ['key'] + ], + 'with EX modifier' => [ + ['key', 'ex', 1], + ['key', 'EX', 1], + ], + 'with PX modifier' => [ + ['key', 'px', 1], + ['key', 'PX', 1], + ], + 'with EXAT modifier' => [ + ['key', 'exat', 1], + ['key', 'EXAT', 1], + ], + 'with PXAT modifier' => [ + ['key', 'pxat', 1], + ['key', 'PXAT', 1], + ], + 'with PERSIST modifier' => [ + ['key', 'persist'], + ['key', 'PERSIST'] + ] + ]; + } + + public function keysProvider(): array + { + return [ + 'without expiration time' => [ + ['key', 'value'], + ['key', '', false], + 'value', + ], + 'with expiration - EX modifier' => [ + ['key', 'value'], + ['key', 'ex', 10], + 'value' + ], + 'with expiration - PX modifier' => [ + ['key', 'value'], + ['key', 'px', 10], + 'value' + ], + 'with expiration - EXAT modifier' => [ + ['key', 'value'], + ['key', 'exat', 10], + 'value' + ], + 'with expiration - PXAT modifier' => [ + ['key', 'value'], + ['key', 'pxat', 10], + 'value' + ], + 'with expiration - PERSIST modifier' => [ + ['key', 'value'], + ['key', 'persist'], + 'value' + ], + ]; + } + + public function unexpectedValuesProvider(): array + { + return [ + 'with wrong modifier' => [ + ['key', 'wrong', 1], + 'Modifier argument accepts only: ex, px, exat, pxat, persist values' + ], + 'without value provided' => [ + ['key', 'ex'], + 'You should provide value for current modifier' + ] + ]; + } +}