mirror of
https://github.com/predis/predis.git
synced 2026-11-10 20:07:59 +00:00
feat: bless commands family (#1733)
* feat: bless commands family * fix: bless scan args processing
This commit is contained in:
@@ -42,6 +42,7 @@ use Predis\Command\Argument\TimeSeries\RangeArguments;
|
||||
use Predis\Command\Argument\TimeSeries\ReadArguments;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\Container\ACL;
|
||||
use Predis\Command\Container\BLESS;
|
||||
use Predis\Command\Container\CLIENT;
|
||||
use Predis\Command\Container\FUNCTIONS;
|
||||
use Predis\Command\Container\HIMPORT;
|
||||
@@ -431,6 +432,7 @@ use Predis\Command\Redis\VADD;
|
||||
* @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 BLESS $bless
|
||||
* @property CLIENT $client
|
||||
* @property HIMPORT $himport
|
||||
* @property HOTKEYS $hotkeys
|
||||
|
||||
@@ -42,6 +42,7 @@ use Predis\Command\Argument\TimeSeries\RangeArguments;
|
||||
use Predis\Command\Argument\TimeSeries\ReadArguments;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\Container\ACL;
|
||||
use Predis\Command\Container\BLESS;
|
||||
use Predis\Command\Container\CLIENT;
|
||||
use Predis\Command\Container\FUNCTIONS;
|
||||
use Predis\Command\Container\HIMPORT;
|
||||
@@ -446,6 +447,7 @@ 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 BLESS $bless
|
||||
* @property CLIENT $client
|
||||
* @property HIMPORT $himport
|
||||
* @property HOTKEYS $hotkeys
|
||||
|
||||
@@ -214,6 +214,9 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'XSETID' => $getKeyFromFirstArgument,
|
||||
'XTRIM' => $getKeyFromFirstArgument,
|
||||
|
||||
/* commands operating on blessings */
|
||||
'BLESS' => [$this, 'getKeyFromBlessCommands'],
|
||||
|
||||
/* commands operating on vector sets */
|
||||
'VADD' => $getKeyFromFirstArgument,
|
||||
'VCARD' => $getKeyFromFirstArgument,
|
||||
@@ -482,6 +485,28 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
return $arguments[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the key from BLESS commands.
|
||||
*
|
||||
* BLESS GET/SET/CLEAR operate on a key at position 1, after the subcommand.
|
||||
* BLESS SCAN takes a cursor and a flag instead of a key, so it has no slot
|
||||
* and this returns null.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getKeyFromBlessCommands(CommandInterface $command)
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
|
||||
if (isset($arguments[0], $arguments[1]) && in_array(strtoupper($arguments[0]), ['GET', 'SET', 'CLEAR'], true)) {
|
||||
return $arguments[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the key from HIMPORT commands.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2026 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;
|
||||
|
||||
/**
|
||||
* @method array get(string $key) Returns the flags currently set on the key.
|
||||
* @method int set(string $key, string $flag) Returns 1 if the flag was added, 0 if it was already set.
|
||||
* @method int clear(string $key, string $flag) Returns 1 if the flag was removed, 0 if it was not set.
|
||||
*/
|
||||
class BLESS extends AbstractContainer
|
||||
{
|
||||
public function getContainerCommandId(): string
|
||||
{
|
||||
return 'BLESS';
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over the keys carrying the given flag.
|
||||
*
|
||||
* Mirrors the plain SCAN command signature: options are passed as an
|
||||
* array, e.g. ['COUNT' => 10].
|
||||
*
|
||||
* @param string|int $cursor Cursor returned by the previous call, 0 to start a new iteration.
|
||||
* @param string $flag Flag to scan for.
|
||||
* @param array|null $options Scan options, supports COUNT.
|
||||
* @return array|mixed [next cursor, list of keys]; an error response when the client runs with exceptions disabled
|
||||
*/
|
||||
public function scan($cursor, string $flag, ?array $options = null)
|
||||
{
|
||||
return $this->__call('SCAN', func_get_args());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2026 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\PrefixableCommand as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/?name=bless
|
||||
*
|
||||
* Container command corresponds to any BLESS *.
|
||||
* Represents any BLESS command with subcommand as first argument.
|
||||
*/
|
||||
class BLESS extends RedisCommand
|
||||
{
|
||||
private const KEYED_SUBCOMMANDS = ['GET', 'SET', 'CLEAR'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return 'BLESS';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
if (isset($arguments[0]) && strtoupper($arguments[0]) === 'SCAN') {
|
||||
$this->setScanArguments($arguments);
|
||||
} else {
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BLESS SCAN cursor flag [COUNT count].
|
||||
*
|
||||
* Mirrors the plain SCAN command: options are passed as an array
|
||||
* (e.g. ['COUNT' => 10]) and expanded into Redis modifiers.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return void
|
||||
*/
|
||||
private function setScanArguments(array $arguments): void
|
||||
{
|
||||
if (count($arguments) === 4) {
|
||||
$options = array_pop($arguments);
|
||||
if (is_array($options)) {
|
||||
$options = $this->prepareScanOptions($options);
|
||||
$arguments = array_merge($arguments, $options);
|
||||
}
|
||||
}
|
||||
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of SCAN options and modifiers compatible with Redis.
|
||||
*
|
||||
* @param array $options List of options.
|
||||
* @return array
|
||||
*/
|
||||
private function prepareScanOptions(array $options): array
|
||||
{
|
||||
$options = array_change_key_case($options, CASE_UPPER);
|
||||
$normalized = [];
|
||||
|
||||
if (!empty($options['COUNT'])) {
|
||||
$normalized[] = 'COUNT';
|
||||
$normalized[] = $options['COUNT'];
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$arguments = $this->getArguments();
|
||||
|
||||
// BLESS GET/SET/CLEAR operate on a key at index 1, right after the subcommand.
|
||||
// BLESS SCAN takes a cursor and a flag, never a key.
|
||||
if (isset($arguments[0], $arguments[1]) && in_array(strtoupper($arguments[0]), self::KEYED_SUBCOMMANDS, true)) {
|
||||
$arguments[1] = $prefix . $arguments[1];
|
||||
$this->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user