mirror of
https://github.com/predis/predis.git
synced 2026-09-12 11:27:05 +00:00
Added support for LMPOP command (#1013)
Co-authored-by: Vladyslav Vildanov <vladyslavvildanov@Vladyslav-Vildanov-MacBook-Pro.local>
This commit is contained in:
committed by
GitHub
parent
721c829042
commit
d1acca607e
@@ -93,6 +93,7 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this linsert($key, $whence, $pivot, $value)
|
||||
* @method $this llen($key)
|
||||
* @method $this lmove(string $source, string $destination, string $where, string $to)
|
||||
* @method $this lmpop(array $keys, string $modifier = 'left', int $count = 1)
|
||||
* @method $this lpop($key)
|
||||
* @method $this lpush($key, array $values)
|
||||
* @method $this lpushx($key, array $values)
|
||||
|
||||
@@ -102,6 +102,7 @@ use Predis\Response\Status;
|
||||
* @method int linsert(string $key, $whence, $pivot, $value)
|
||||
* @method int llen(string $key)
|
||||
* @method string lmove(string $source, string $destination, string $where, string $to)
|
||||
* @method array|null lmpop(array $keys, string $modifier = 'left', int $count = 1)
|
||||
* @method string|null lpop(string $key)
|
||||
* @method int lpush(string $key, array $values)
|
||||
* @method int lpushx(string $key, array $values)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\Count;
|
||||
use \Predis\Command\Traits\Keys;
|
||||
use Predis\Command\Traits\LeftRight;
|
||||
|
||||
class LMPOP extends RedisCommand
|
||||
{
|
||||
use Keys {
|
||||
Keys::setArguments as setKeys;
|
||||
}
|
||||
use LeftRight {
|
||||
LeftRight::setArguments as setLeftRight;
|
||||
}
|
||||
use Count {
|
||||
Count::setArguments as setCount;
|
||||
}
|
||||
|
||||
protected static $keysArgumentPositionOffset = 0;
|
||||
protected static $leftRightArgumentPositionOffset = 1;
|
||||
protected static $countArgumentPositionOffset = 2;
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'LMPOP';
|
||||
}
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->setCount($arguments);
|
||||
$arguments = $this->getArguments();
|
||||
|
||||
$this->setLeftRight($arguments);
|
||||
$arguments = $this->getArguments();
|
||||
|
||||
$this->setKeys($arguments);
|
||||
$this->filterArguments();
|
||||
}
|
||||
|
||||
public function parseResponse($data)
|
||||
{
|
||||
if (null !== $data) {
|
||||
return [$data[0] => $data[1]];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Predis\Command\Traits;
|
||||
|
||||
use Predis\Command\Command;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* @mixin Command
|
||||
*/
|
||||
trait LeftRight
|
||||
{
|
||||
/**
|
||||
* @var array{string: string}
|
||||
*/
|
||||
private static $leftRightEnum = [
|
||||
'left' => 'LEFT',
|
||||
'right' => 'RIGHT',
|
||||
];
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$argumentsLength = count($arguments);
|
||||
|
||||
if (static::$leftRightArgumentPositionOffset >= $argumentsLength) {
|
||||
$arguments[] = 'LEFT';
|
||||
parent::setArguments($arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
$argument = $arguments[static::$leftRightArgumentPositionOffset];
|
||||
|
||||
if (is_string($argument) && in_array(strtoupper($argument), self::$leftRightEnum, true)) {
|
||||
$argument = self::$leftRightEnum[$argument];
|
||||
} else {
|
||||
$enumValues = implode(', ', array_keys(self::$leftRightEnum));
|
||||
throw new UnexpectedValueException("Left/Right argument accepts only: {$enumValues} values");
|
||||
}
|
||||
|
||||
$argumentsBefore = array_slice($arguments, 0, static::$leftRightArgumentPositionOffset);
|
||||
$argumentsAfter = array_slice($arguments, static::$leftRightArgumentPositionOffset + 1);
|
||||
|
||||
parent::setArguments(array_merge(
|
||||
$argumentsBefore,
|
||||
[$argument],
|
||||
$argumentsAfter
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?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\Command\Redis;
|
||||
|
||||
use Predis\Response\ServerException;
|
||||
|
||||
/**
|
||||
* @group commands
|
||||
* @group realm-list
|
||||
*/
|
||||
class LMPOP_Test extends PredisCommandTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCommand(): string
|
||||
{
|
||||
return LMPOP::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedId(): string
|
||||
{
|
||||
return 'LMPOP';
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
$raw = ['key', ['elem1', 'elem2']];
|
||||
$expected = ['key' => ['elem1', 'elem2']];
|
||||
|
||||
$command = $this->getCommand();
|
||||
|
||||
$this->assertSame($expected, $command->parseResponse($raw));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @dataProvider listProvider
|
||||
* @param array $listArguments
|
||||
* @param string $key
|
||||
* @param string $modifier
|
||||
* @param int $count
|
||||
* @param array|null $expectedResponse
|
||||
* @param array $expectedModifiedList
|
||||
* @return void
|
||||
* @requiresRedisVersion >= 7.0.0
|
||||
*/
|
||||
public function testPopElementsFromGivenList(
|
||||
array $listArguments,
|
||||
string $key,
|
||||
string $modifier,
|
||||
int $count,
|
||||
?array $expectedResponse,
|
||||
array $expectedModifiedList
|
||||
): void {
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->lpush(...$listArguments);
|
||||
$actualResponse = $redis->lmpop(['key1', $key], $modifier, $count);
|
||||
|
||||
$this->assertSame($expectedResponse, $actualResponse);
|
||||
$this->assertSame($expectedModifiedList, $redis->lrange($key, 0, -1));
|
||||
}
|
||||
|
||||
public function argumentsProvider(): array
|
||||
{
|
||||
return [
|
||||
'with default arguments' => [
|
||||
[['key']],
|
||||
[1, 'key', 'LEFT']
|
||||
],
|
||||
'with LEFT/RIGHT argument' => [
|
||||
[['key'], 'right'],
|
||||
[1, 'key', 'RIGHT']
|
||||
],
|
||||
'with COUNT argument' => [
|
||||
[['key'], 'left', 2],
|
||||
[1, 'key', 'LEFT', 'COUNT', 2]
|
||||
],
|
||||
'with all arguments' => [
|
||||
[['key1', 'key2'], 'right', 2],
|
||||
[2, 'key1', 'key2', 'RIGHT', 'COUNT', 2]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function listProvider(): array
|
||||
{
|
||||
return [
|
||||
'pops single element - left' => [
|
||||
['key', 'elem1', 'elem2', 'elem3'],
|
||||
'key',
|
||||
'left',
|
||||
1,
|
||||
['key' => ['elem3']],
|
||||
['elem2', 'elem1']
|
||||
],
|
||||
'pops single element - right' => [
|
||||
['key', 'elem1', 'elem2', 'elem3'],
|
||||
'key',
|
||||
'right',
|
||||
1,
|
||||
['key' => ['elem1']],
|
||||
['elem3', 'elem2']
|
||||
],
|
||||
'pops multiple elements' => [
|
||||
['key', 'elem1', 'elem2', 'elem3'],
|
||||
'key',
|
||||
'right',
|
||||
2,
|
||||
['key' => ['elem1', 'elem2']],
|
||||
['elem3'],
|
||||
],
|
||||
'with empty list' => [
|
||||
['key', 'elem1', 'elem2', 'elem3'],
|
||||
'key2',
|
||||
'right',
|
||||
2,
|
||||
null,
|
||||
[],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Predis\Command\Traits;
|
||||
|
||||
use PredisTestCase;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use UnexpectedValueException;
|
||||
|
||||
class LeftRightTest extends PredisTestCase
|
||||
{
|
||||
private $testClass;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->testClass = new class extends RedisCommand {
|
||||
use LeftRight;
|
||||
|
||||
public static $leftRightArgumentPositionOffset = 0;
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'test';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider argumentsProvider
|
||||
* @param int $offset
|
||||
* @param array $actualArguments
|
||||
* @param array $expectedArguments
|
||||
* @return void
|
||||
*/
|
||||
public function testReturnsCorrectArguments(int $offset, array $actualArguments, array $expectedArguments): void
|
||||
{
|
||||
$this->testClass::$leftRightArgumentPositionOffset = $offset;
|
||||
|
||||
$this->testClass->setArguments($actualArguments);
|
||||
|
||||
$this->assertSame($expectedArguments, $this->testClass->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider unexpectedValuesProvider
|
||||
* @param array $actualArguments
|
||||
* @return void
|
||||
*/
|
||||
public function testThrowsExceptionOnUnexpectedValueGiven(array $actualArguments): void
|
||||
{
|
||||
$this->expectException(UnexpectedValueException::class);
|
||||
$this->expectExceptionMessage('Left/Right argument accepts only: left, right values');
|
||||
|
||||
$this->testClass->setArguments($actualArguments);
|
||||
}
|
||||
|
||||
public function argumentsProvider(): array
|
||||
{
|
||||
return [
|
||||
'with wrong offset' => [2, ['argument1'], ['argument1', 'LEFT']],
|
||||
'left/right argument first and there is arguments after' => [
|
||||
0,
|
||||
['left', 'second argument', 'third argument'],
|
||||
['LEFT', 'second argument', 'third argument']
|
||||
],
|
||||
'left/right argument last and there is arguments before' => [
|
||||
2,
|
||||
['first argument', 'second argument', 'right'],
|
||||
['first argument', 'second argument', 'RIGHT']
|
||||
],
|
||||
'left/right argument not the first and not the last' => [
|
||||
1,
|
||||
['first argument', 'left', 'third argument'],
|
||||
['first argument', 'LEFT','third argument']
|
||||
],
|
||||
'aggregate argument the only argument' => [
|
||||
0,
|
||||
['right'],
|
||||
['RIGHT']
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function unexpectedValuesProvider(): array
|
||||
{
|
||||
return [
|
||||
'with non-string argument' => [[1]],
|
||||
'with non enum value' => [['wrong']],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user