Extend Sorted Set support by implementing ZDIFFSTORE command (#828)

* Added support for ZDIFF, added new WITHSCORE trait

* Added trait to resolve numkeys argument

* Added trait for unpacking keys array

* Added static binding for Numkeys trait

* Added ZDIFFSTORE command support

* Changed access modifier type to more strict

* Removed version annotation for inconsistency

* Update ZDIFFSTORE.php

Co-authored-by: Vladislav <vladislav@Admins-MacBook-Pro.local>
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:
Vladyslav Vildanov
2022-11-30 23:23:08 +02:00
committed by GitHub
parent 35d18d739a
commit cfd6f030bc
6 changed files with 137 additions and 2 deletions
+1
View File
@@ -110,6 +110,7 @@ use Predis\Command\CommandInterface;
* @method $this zcard($key)
* @method $this zcount($key, $min, $max)
* @method $this zdiff(array $keys, bool $withScores = false)
* @method $this zdiffstore(string $destination, array $keys)
* @method $this zincrby($key, $increment, $member)
* @method $this zinterstore($destination, array|string $keys, array $options = null)
* @method $this zmscore(string $key, string ...$member)
+1
View File
@@ -126,6 +126,7 @@ use Predis\Response\Status;
* @method int zcard(string $key)
* @method string zcount(string $key, int|string $min, int|string $max)
* @method array zdiff(array $keys, bool $withScores = false)
* @method int zdiffstore(string $destination, array $keys)
* @method string zincrby(string $key, int $increment, string $member)
* @method int zinterstore(string $destination, array|string $keys, array $options = null)
* @method array zmscore(string $key, string ...$member)
+40
View File
@@ -0,0 +1,40 @@
<?php
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
use Predis\Command\Traits\Numkeys;
use Predis\Command\Traits\Keys;
/**
* @link https://redis.io/commands/zdiffstore/
*
* Computes the difference between the first and all successive input sorted sets
* and stores the result in destination. The total number of input keys is specified by numkeys.
*
* Keys that do not exist are considered to be empty sets.
*
* If destination already exists, it is overwritten.
*/
class ZDIFFSTORE extends RedisCommand
{
use Keys;
use Numkeys {
setArguments as setNumkeys;
}
public static $keysArgumentPositionOffset = 1;
public function getId()
{
return 'ZDIFFSTORE';
}
public function setArguments(array $arguments)
{
$this->setNumkeys($arguments);
$arguments = $this->getArguments();
$this->unpackKeysArray(self::$keysArgumentPositionOffset + 1, $arguments);
parent::setArguments($arguments);
}
}
-1
View File
@@ -12,7 +12,6 @@ use Predis\Command\Command as RedisCommand;
*
* For every member that does not exist in the sorted set, a null value is returned.
*
* @version >= 6.2.0
*/
class ZMSCORE extends RedisCommand
{
-1
View File
@@ -15,7 +15,6 @@ use Predis\Command\Traits\WithScores;
* If called with a negative count, the behavior changes and the command
* is allowed to return the same element multiple times.
*
* @version >= 6.2.0
*/
class ZRANDMEMBER extends RedisCommand
{
@@ -0,0 +1,95 @@
<?php
namespace Predis\Command\Redis;
class ZDIFFSTORE_Test extends PredisCommandTestCase
{
/**
* @inheritDoc
*/
protected function getExpectedCommand(): string
{
return ZDIFFSTORE::class;
}
/**
* @inheritDoc
*/
protected function getExpectedId(): string
{
return 'ZDIFFSTORE';
}
/**
* @group disconnected
*/
public function testFilterArguments(): void
{
$actualArguments = ['zset_diff', ['key1', 'key2']];
$expectedArguments = ['zset_diff', 2, 'key1', 'key2'];
$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 sortedSetsProvider
* @param array $firstSetDictionary
* @param array $secondSetDictionary
* @param array $expectedResponse
* @param int $expectedResultingElements
* @return void
* @requiresRedisVersion >= 6.2.0
*/
public function testStoresDifferenceBetweenSortedSets(
array $firstSetDictionary,
array $secondSetDictionary,
array $expectedResponse,
int $expectedResultingElements
): void {
$redis = $this->getClient();
$redis->zadd('test-zset-1', ...$firstSetDictionary);
$redis->zadd('test-zset-2', ...$secondSetDictionary);
$actualResponse = $redis->zdiffstore('zdiffstore', ['test-zset-1', 'test-zset-2']);
$this->assertSame($expectedResultingElements, $actualResponse);
$this->assertSame($expectedResponse, $redis->zrange('zdiffstore', 0, -1));
}
public function sortedSetsProvider(): array
{
return [
'no intersection' => [
[1, 'member1', 2, 'member2', 3, 'member3'],
[1, 'member4', 2, 'member5', 3, 'member6'],
['member1', 'member2', 'member3'],
3
],
'partial intersection' => [
[1, 'member1', 2, 'member2', 3, 'member3'],
[1, 'member1', 2, 'member2', 3, 'member4'],
['member3'],
1
],
'full intersection' => [
[1, 'member1', 2, 'member2', 3, 'member3'],
[1, 'member1', 2, 'member2', 3, 'member3'],
[],
0
],
];
}
}