Extended core support by implementing SORT_RO command (#1044)

* Added support for SORT_RO command

* Codestyle fixes

* Added command description

---------

Co-authored-by: Vladyslav Vildanov <vladyslavvildanov@Vladyslav-Vildanov-MacBook-Pro.local>
This commit is contained in:
Vladyslav Vildanov
2023-01-29 21:38:30 +02:00
committed by GitHub
parent 50e005bfe3
commit db65e5ebd3
18 changed files with 738 additions and 6 deletions
+2
View File
@@ -14,6 +14,7 @@ namespace Predis;
use Predis\Command\Argument\Geospatial\ByInterface;
use Predis\Command\Argument\Geospatial\FromInterface;
use Predis\Command\Argument\Server\LimitOffsetCount;
use Predis\Command\Argument\Server\To;
use Predis\Command\CommandInterface;
@@ -39,6 +40,7 @@ use Predis\Command\CommandInterface;
* @method $this renamenx($key, $target)
* @method $this scan($cursor, array $options = null)
* @method $this sort($key, array $options = null)
* @method $this sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false)
* @method $this ttl($key)
* @method $this type($key)
* @method $this append($key, $value)
+2
View File
@@ -14,6 +14,7 @@ namespace Predis;
use Predis\Command\Argument\Geospatial\ByInterface;
use Predis\Command\Argument\Geospatial\FromInterface;
use Predis\Command\Argument\Server\LimitOffsetCount;
use Predis\Command\Argument\Server\To;
use Predis\Command\CommandInterface;
use Predis\Command\FactoryInterface;
@@ -48,6 +49,7 @@ use Predis\Response\Status;
* @method int renamenx(string $key, string $target)
* @method array scan($cursor, array $options = null)
* @method array sort(string $key, array $options = null)
* @method array sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false)
* @method int ttl(string $key)
* @method mixed type(string $key)
* @method int append(string $key, $value)
@@ -0,0 +1,19 @@
<?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\Argument\Server;
use Predis\Command\Argument\ArrayableArgument;
interface LimitInterface extends ArrayableArgument
{
}
@@ -0,0 +1,42 @@
<?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\Argument\Server;
class LimitOffsetCount implements LimitInterface
{
private const KEYWORD = 'LIMIT';
/**
* @var int
*/
private $offset;
/**
* @var int
*/
private $count;
public function __construct(int $offset, int $count)
{
$this->offset = $offset;
$this->count = $count;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return [self::KEYWORD, $this->offset, $this->count];
}
}
+1 -1
View File
@@ -120,7 +120,7 @@ abstract class Command implements CommandInterface
public function filterArguments(): void
{
$this->arguments = array_filter($this->arguments, static function ($argument) {
return $argument !== false;
return $argument !== false && $argument !== null;
});
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
use Predis\Command\Traits\Keys;
use Predis\Command\Traits\Limit;
use Predis\Command\Traits\Limit\Limit;
class SINTERCARD extends RedisCommand
{
+74
View File
@@ -0,0 +1,74 @@
<?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\Redis;
use Predis\Command\Command as RedisCommand;
use Predis\Command\Traits\By\ByArgument;
use Predis\Command\Traits\Get\Get;
use Predis\Command\Traits\Limit\LimitObject;
use Predis\Command\Traits\Sorting;
/**
* @see https://redis.io/commands/sort_ro/
*
* Read-only variant of the SORT command.
* It is exactly like the original SORT but refuses the STORE option
* and can safely be used in read-only replicas.
*/
class SORT_RO extends RedisCommand
{
use ByArgument {
ByArgument::setArguments as setBy;
}
use LimitObject {
LimitObject::setArguments as setLimit;
}
use Get {
Get::setArguments as setGetArgument;
}
use Sorting {
Sorting::setArguments as setSorting;
}
protected static $byArgumentPositionOffset = 1;
protected static $getArgumentPositionOffset = 3;
protected static $sortArgumentPositionOffset = 4;
public function getId()
{
return 'SORT_RO';
}
public function setArguments(array $arguments)
{
$alpha = array_pop($arguments);
if (is_bool($alpha) && $alpha) {
$arguments[] = 'ALPHA';
} elseif (!is_bool($alpha)) {
$arguments[] = $alpha;
}
$this->setSorting($arguments);
$arguments = $this->getArguments();
$this->setGetArgument($arguments);
$arguments = $this->getArguments();
$this->setLimit($arguments);
$arguments = $this->getArguments();
$this->setBy($arguments);
$this->filterArguments();
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
use Predis\Command\Traits\Keys;
use Predis\Command\Traits\Limit;
use Predis\Command\Traits\Limit\Limit;
/**
* @see https://redis.io/commands/zintercard/
+1 -1
View File
@@ -14,7 +14,7 @@ namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
use Predis\Command\Traits\By\ByLexByScore;
use Predis\Command\Traits\Limit;
use Predis\Command\Traits\Limit\Limit;
use Predis\Command\Traits\Rev;
/**
+40
View File
@@ -0,0 +1,40 @@
<?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\Traits\By;
use Predis\Command\Command;
/**
* @mixin Command
*/
trait ByArgument
{
private $byModifier = 'BY';
public function setArguments(array $arguments)
{
$argumentsLength = count($arguments);
if (static::$byArgumentPositionOffset >= $argumentsLength || null === $arguments[static::$byArgumentPositionOffset]) {
parent::setArguments($arguments);
return;
}
$argument = $arguments[static::$byArgumentPositionOffset];
$argumentsBefore = array_slice($arguments, 0, static::$byArgumentPositionOffset);
$argumentsAfter = array_slice($arguments, static::$byArgumentPositionOffset + 1);
parent::setArguments(array_merge($argumentsBefore, [$this->byModifier, $argument], $argumentsAfter));
}
}
+47
View File
@@ -0,0 +1,47 @@
<?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\Traits\Get;
use UnexpectedValueException;
trait Get
{
private static $getModifier = 'GET';
public function setArguments(array $arguments)
{
$argumentsLength = count($arguments);
if (static::$getArgumentPositionOffset >= $argumentsLength) {
parent::setArguments($arguments);
return;
}
if (!is_array($arguments[static::$getArgumentPositionOffset])) {
throw new UnexpectedValueException('Wrong get argument type');
}
$patterns = [];
foreach ($arguments[static::$getArgumentPositionOffset] as $pattern) {
$patterns[] = self::$getModifier;
$patterns[] = $pattern;
}
$argumentsBeforeKeys = array_slice($arguments, 0, static::$getArgumentPositionOffset);
$argumentsAfterKeys = array_slice($arguments, static::$getArgumentPositionOffset + 1);
parent::setArguments(array_merge($argumentsBeforeKeys, $patterns, $argumentsAfterKeys));
}
}
@@ -10,7 +10,7 @@
* file that was distributed with this source code.
*/
namespace Predis\Command\Traits;
namespace Predis\Command\Traits\Limit;
use Predis\Command\Command;
use UnexpectedValueException;
+50
View File
@@ -0,0 +1,50 @@
<?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\Traits\Limit;
use Predis\Command\Argument\Server\LimitInterface;
trait LimitObject
{
public function setArguments(array $arguments)
{
$argumentPositionOffset = $this->getLimitArgumentPositionOffset($arguments);
if (null === $argumentPositionOffset) {
parent::setArguments($arguments);
return;
}
$limitObject = $arguments[$argumentPositionOffset];
$argumentsBefore = array_slice($arguments, 0, $argumentPositionOffset);
$argumentsAfter = array_slice($arguments, $argumentPositionOffset + 1);
parent::setArguments(array_merge(
$argumentsBefore,
$limitObject->toArray(),
$argumentsAfter
));
}
private function getLimitArgumentPositionOffset(array $arguments): ?int
{
foreach ($arguments as $i => $value) {
if ($value instanceof LimitInterface) {
return $i;
}
}
return null;
}
}