mirror of
https://github.com/predis/predis.git
synced 2026-09-14 20:37:29 +00:00
Extended Bloom filters by implementing BF.INFO command (#886)
* Added CommandResolver, moved resolve command logic there, added ClientConfiguration object * Fixed test, added dependecies * Added resolved command to commands array * Used aggregation approach for modules * Added decorator to check Redis JSON module version * Added support for JSON.SET and JSON.GET commands * Added separate workflow for redis-stack tests * Changed docker imange name to correct one * Fixed indentation * Added test coverage for JSON.GET command * Changed module version resolving using annotations mapping * Re-written CommandResolver test * Update ClientInterface.php * Changes to CI, readme, removed unused modules from configuration * Fixed build badge URL * Refactored annotation check to be generic for each module * Added support for BF.ADD and BF.EXISTS commands * Added support for BF.INFO command * Fixed arguments data provider * Fixed bug with incorrect tests skip * Added command description * Removed unused import * Removed old directory Co-authored-by: Vladyslav Vildanov <vladyslavvildanov@Vladyslav-Vildanov-MacBook-Pro.local> Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
ca498b67a1
commit
1170d09ac5
@@ -44,6 +44,7 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this append($key, $value)
|
||||
* @method $this bfadd(string $key, $item)
|
||||
* @method $this bfexists(string $key, $item)
|
||||
* @method $this bfinfo(string $key, string $modifier = '')
|
||||
* @method $this bitcount($key, $start = null, $end = null)
|
||||
* @method $this bitop($operation, $destkey, $key)
|
||||
* @method $this bitfield($key, $subcommand, ...$subcommandArg)
|
||||
|
||||
@@ -53,6 +53,7 @@ use Predis\Response\Status;
|
||||
* @method int append(string $key, $value)
|
||||
* @method int bfadd(string $key, $item)
|
||||
* @method int bfexists(string $key, $item)
|
||||
* @method array bfinfo(string $key, string $modifier = '')
|
||||
* @method int bitcount(string $key, $start = null, $end = null)
|
||||
* @method int bitop($operation, $destkey, $key)
|
||||
* @method array|null bitfield(string $key, $subcommand, ...$subcommandArg)
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?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\BloomFilter;
|
||||
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bf.info/
|
||||
*
|
||||
* Return information about key filter.
|
||||
*/
|
||||
class BFINFO extends RedisCommand
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $modifierEnum = [
|
||||
'capacity' => 'CAPACITY',
|
||||
'size' => 'SIZE',
|
||||
'filters' => 'FILTERS',
|
||||
'items' => 'ITEMS',
|
||||
'expansion' => 'EXPANSION',
|
||||
];
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'BF.INFO';
|
||||
}
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
if (isset($arguments[1])) {
|
||||
$modifier = array_pop($arguments);
|
||||
|
||||
if ($modifier === '') {
|
||||
parent::setArguments($arguments);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array(strtoupper($modifier), $this->modifierEnum)) {
|
||||
$enumValues = implode(', ', array_keys($this->modifierEnum));
|
||||
throw new UnexpectedValueException("Argument accepts only: {$enumValues} values");
|
||||
}
|
||||
|
||||
$arguments[] = $this->modifierEnum[strtolower($modifier)];
|
||||
}
|
||||
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
|
||||
public function parseResponse($data)
|
||||
{
|
||||
if (count($data) > 1) {
|
||||
$result = [];
|
||||
|
||||
for ($i = 0, $iMax = count($data); $i < $iMax; ++$i) {
|
||||
if ($data[$i + 1] ?? false) {
|
||||
$result[(string) $data[$i]] = $data[++$i];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
<?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\BloomFilter;
|
||||
|
||||
use Predis\Command\Redis\PredisCommandTestCase;
|
||||
use Predis\Response\ServerException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* @group commands
|
||||
* @group realm-bloom
|
||||
*/
|
||||
class BFINFO_Test extends PredisCommandTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getExpectedCommand(): string
|
||||
{
|
||||
return BFINFO::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getExpectedId(): string
|
||||
{
|
||||
return 'BFINFO';
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @dataProvider responsesProvider
|
||||
*/
|
||||
public function testParseResponse(array $actualResponse, array $expectedResponse): void
|
||||
{
|
||||
$this->assertSame($expectedResponse, $this->getCommand()->parseResponse($actualResponse));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @dataProvider filtersProvider
|
||||
* @param array $filter
|
||||
* @param string $key
|
||||
* @param string $modifier
|
||||
* @param array $expectedResponse
|
||||
* @return void
|
||||
* @requiresRedisBfVersion 1.0.0
|
||||
*/
|
||||
public function testInfoReturnsCorrectInformationAboutBloomFilter(
|
||||
array $filter,
|
||||
string $key,
|
||||
string $modifier,
|
||||
array $expectedResponse
|
||||
): void {
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->bfadd(...$filter);
|
||||
$this->assertSame($expectedResponse, $redis->bfinfo($key, $modifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @return void
|
||||
* @requiresRedisBfVersion 1.0.0
|
||||
*/
|
||||
public function testThrowsExceptionOnUnexpectedValueGiven(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
|
||||
$this->expectException(UnexpectedValueException::class);
|
||||
$this->expectExceptionMessage('Argument accepts only: capacity, size, filters, items, expansion values');
|
||||
|
||||
$redis->bfinfo('key', 'wrong');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requiresRedisBfVersion >= 1.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('binfo_foo', 'bar');
|
||||
$redis->bfinfo('binfo_foo');
|
||||
}
|
||||
|
||||
public function argumentsProvider(): array
|
||||
{
|
||||
return [
|
||||
'without argument' => [
|
||||
[],
|
||||
[],
|
||||
],
|
||||
'with default modifier value' => [
|
||||
['key', ''],
|
||||
['key'],
|
||||
],
|
||||
'with CAPACITY modifier' => [
|
||||
['key', 'capacity'],
|
||||
['key', 'CAPACITY'],
|
||||
],
|
||||
'with SIZE modifier' => [
|
||||
['key', 'size'],
|
||||
['key', 'SIZE'],
|
||||
],
|
||||
'with FILTERS modifier' => [
|
||||
['key', 'filters'],
|
||||
['key', 'FILTERS'],
|
||||
],
|
||||
'with ITEMS modifier' => [
|
||||
['key', 'items'],
|
||||
['key', 'ITEMS'],
|
||||
],
|
||||
'with EXPANSION modifier' => [
|
||||
['key', 'expansion'],
|
||||
['key', 'EXPANSION'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function responsesProvider(): array
|
||||
{
|
||||
return [
|
||||
'with one modifier' => [
|
||||
[100],
|
||||
[100],
|
||||
],
|
||||
'with all modifiers' => [
|
||||
[
|
||||
'Capacity',
|
||||
100,
|
||||
'Size',
|
||||
296,
|
||||
'Number of filters',
|
||||
1,
|
||||
'Number of items inserted',
|
||||
1,
|
||||
'Expansion rate',
|
||||
2,
|
||||
],
|
||||
[
|
||||
'Capacity' => 100,
|
||||
'Size' => 296,
|
||||
'Number of filters' => 1,
|
||||
'Number of items inserted' => 1,
|
||||
'Expansion rate' => 2,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function filtersProvider(): array
|
||||
{
|
||||
return [
|
||||
'without modifier' => [
|
||||
['key', 'item'],
|
||||
'key',
|
||||
'',
|
||||
[
|
||||
'Capacity' => 100,
|
||||
'Size' => 240,
|
||||
'Number of filters' => 1,
|
||||
'Number of items inserted' => 1,
|
||||
'Expansion rate' => 2,
|
||||
],
|
||||
],
|
||||
'with CAPACITY modifier' => [
|
||||
['key', 'item'],
|
||||
'key',
|
||||
'capacity',
|
||||
[100],
|
||||
],
|
||||
'with SIZE modifier' => [
|
||||
['key', 'item'],
|
||||
'key',
|
||||
'size',
|
||||
[240],
|
||||
],
|
||||
'with FILTERS modifier' => [
|
||||
['key', 'item'],
|
||||
'key',
|
||||
'filters',
|
||||
[1],
|
||||
],
|
||||
'with ITEMS modifier' => [
|
||||
['key', 'item'],
|
||||
'key',
|
||||
'items',
|
||||
[1],
|
||||
],
|
||||
'with EXPANSION modifier' => [
|
||||
['key', 'item'],
|
||||
'key',
|
||||
'expansion',
|
||||
[2],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user