mirror of
https://github.com/predis/predis.git
synced 2026-08-30 12:15:03 +00:00
Added support for HRANDFIELD command (#870)
Co-authored-by: Vladyslav Vildanov <vladyslavvildanov@Vladyslav-Vildanov-MacBook-Pro.local>
This commit is contained in:
committed by
GitHub
parent
83fb0020a1
commit
9c543ef5b1
@@ -74,6 +74,7 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this hlen($key)
|
||||
* @method $this hmget($key, array $fields)
|
||||
* @method $this hmset($key, array $dictionary)
|
||||
* @method $this hrandfield(string $key, int $count = 1, bool $withValues = false)
|
||||
* @method $this hscan($key, $cursor, array $options = null)
|
||||
* @method $this hset($key, $field, $value)
|
||||
* @method $this hsetnx($key, $field, $value)
|
||||
|
||||
@@ -83,6 +83,7 @@ use Predis\Response\Status;
|
||||
* @method int hlen(string $key)
|
||||
* @method array hmget(string $key, array $fields)
|
||||
* @method mixed hmset(string $key, array $dictionary)
|
||||
* @method array hrandfield(string $key, int $count = 1, bool $withValues = false)
|
||||
* @method array hscan(string $key, $cursor, array $options = null)
|
||||
* @method int hset(string $key, string $field, string $value)
|
||||
* @method int hsetnx(string $key, string $field, string $value)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\With\WithValues;
|
||||
|
||||
/**
|
||||
* @link https://redis.io/commands/hrandfield/
|
||||
*
|
||||
* When called with just the key argument, return a random field from the hash value stored at key.
|
||||
*
|
||||
* If the provided count argument is positive, return an array of distinct fields.
|
||||
* The array's length is either count or the hash's number of fields (HLEN), whichever is lower.
|
||||
*/
|
||||
class HRANDFIELD extends RedisCommand
|
||||
{
|
||||
use WithValues;
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'HRANDFIELD';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Predis\Command\Traits\With;
|
||||
|
||||
use Predis\Command\Command;
|
||||
|
||||
/**
|
||||
* @mixin Command
|
||||
*/
|
||||
trait WithValues
|
||||
{
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$withValues = array_pop($arguments);
|
||||
|
||||
if (is_bool($withValues) && $withValues) {
|
||||
$arguments[] = 'WITHVALUES';
|
||||
} else if (!is_bool($withValues)) {
|
||||
$arguments[] = $withValues;
|
||||
}
|
||||
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace PHPUnit;
|
||||
|
||||
use PHPUnit\Framework\Constraint\Constraint;
|
||||
|
||||
class OneOfConstraint extends Constraint
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $array;
|
||||
|
||||
public function __construct(array $array)
|
||||
{
|
||||
$this->array = $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $other
|
||||
* @return bool
|
||||
*/
|
||||
protected function matches($other): bool
|
||||
{
|
||||
if (is_array($other)) {
|
||||
return !empty(array_intersect($other, $this->array));
|
||||
}
|
||||
|
||||
if (in_array($other, $this->array, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $other
|
||||
* @return string
|
||||
*/
|
||||
protected function failureDescription($other): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'given value matches any values from array';
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\OneOfConstraint;
|
||||
use PHPUnit\Util\Test as TestUtil;
|
||||
use Predis\Client;
|
||||
use Predis\Command;
|
||||
@@ -94,6 +95,19 @@ abstract class PredisTestCase extends \PHPUnit\Framework\TestCase
|
||||
$this->assertThat($actual, new ArrayHasSameValuesConstraint($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that actual value is one of the values from expected array.
|
||||
*
|
||||
* @param mixed $expected Expected array.
|
||||
* @param mixed $actual Actual value. If array given searching for any matching value between two arrays.
|
||||
* @param string $message Optional assertion message
|
||||
* @return void
|
||||
*/
|
||||
public function assertOneOf(array $expected, $actual, string $message = ''): void
|
||||
{
|
||||
$this->assertThat($actual, new OneOfConstraint($expected), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a string matches a given regular expression.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Response\ServerException;
|
||||
|
||||
class HRANDFIELD_Test extends PredisCommandTestCase
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getExpectedCommand(): string
|
||||
{
|
||||
return HRANDFIELD::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getExpectedId(): string
|
||||
{
|
||||
return 'HRANDFIELD';
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
* @dataProvider argumentsProvider
|
||||
* @param array $actualArguments
|
||||
* @param array $expectedArguments
|
||||
* @return void
|
||||
*/
|
||||
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
|
||||
{
|
||||
$this->assertSame(1, $this->getCommand()->parseResponse(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @dataProvider hashesProvider
|
||||
* @param array $hash
|
||||
* @param string $key
|
||||
* @param int $count
|
||||
* @param bool $withValues
|
||||
* @param array $expectedResponse
|
||||
* @return void
|
||||
* @requiresRedisVersion >= 6.2.0
|
||||
*/
|
||||
public function testReturnsRandomFieldsFromHash(
|
||||
array $hash,
|
||||
string $key,
|
||||
int $count,
|
||||
bool $withValues,
|
||||
array $expectedResponse
|
||||
): void {
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->hset($key, ...$hash);
|
||||
$actualResponse = $redis->hrandfield($key, $count, $withValues);
|
||||
|
||||
$this->assertOneOf($expectedResponse, $actualResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 6.2.0
|
||||
*/
|
||||
public function testThrowsExceptionOnWrongType(): void
|
||||
{
|
||||
$this->expectException(ServerException::class);
|
||||
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
|
||||
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->set('foo', 'bar');
|
||||
$redis->hrandfield('foo');
|
||||
}
|
||||
|
||||
public function argumentsProvider(): array
|
||||
{
|
||||
return [
|
||||
'with default arguments' => [
|
||||
['key'],
|
||||
['key']
|
||||
],
|
||||
'with count argument' => [
|
||||
['key', 1],
|
||||
['key', 1]
|
||||
],
|
||||
'with WITHVALUES argument' => [
|
||||
['key', 1, true],
|
||||
['key', 1, 'WITHVALUES']
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function hashesProvider(): array
|
||||
{
|
||||
return [
|
||||
'one field - without values' => [
|
||||
['key1', 'value1', 'key2', 'value2', 'key3', 'value3'],
|
||||
'key',
|
||||
1,
|
||||
false,
|
||||
['key1', 'key2', 'key3']
|
||||
],
|
||||
'one field - with values' => [
|
||||
['key1', 'value1', 'key2', 'value2', 'key3', 'value3'],
|
||||
'key',
|
||||
1,
|
||||
true,
|
||||
['key1', 'value1', 'key2', 'value2', 'key3', 'value3']
|
||||
],
|
||||
'multiple fields - without values' => [
|
||||
['key1', 'value1', 'key2', 'value2', 'key3', 'value3'],
|
||||
'key',
|
||||
2,
|
||||
false,
|
||||
['key1', 'key2', 'key3'],
|
||||
],
|
||||
'multiple fields - with values' => [
|
||||
['key1', 'value1', 'key2', 'value2', 'key3', 'value3'],
|
||||
'key',
|
||||
2,
|
||||
true,
|
||||
['key1', 'value1', 'key2', 'value2', 'key3', 'value3'],
|
||||
],
|
||||
'multiple fields - allows same fields' => [
|
||||
['key1', 'value1', 'key2', 'value2', 'key3', 'value3'],
|
||||
'key',
|
||||
-2,
|
||||
false,
|
||||
['key1', 'key2', 'key3'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ if (file_exists(__DIR__.'/../autoload.php')) {
|
||||
}
|
||||
|
||||
require __DIR__.'/PHPUnit/ArrayHasSameValuesConstraint.php';
|
||||
require __DIR__.'/PHPUnit/OneOfConstraint.php';
|
||||
require __DIR__.'/PHPUnit/RedisCommandConstraint.php';
|
||||
require __DIR__.'/PHPUnit/PredisTestCase.php';
|
||||
require __DIR__.'/PHPUnit/PredisCommandTestCase.php';
|
||||
|
||||
Reference in New Issue
Block a user