mirror of
https://github.com/predis/predis.git
synced 2026-08-30 04:02:22 +00:00
Added new experimental CAS/CAD functionallity (#1609)
* Added new CAS/CAD functionallity * Updated CHANGELOG.md * Codestyle fixes * Fixed version constraint * Marked feature as experimental * Updated version constraints, added missing annotations
This commit is contained in:
committed by
GitHub
parent
d0f37f0bac
commit
80430b4cde
+2
-1
@@ -4,8 +4,10 @@
|
||||
### Added
|
||||
- Added cluster support for `XADD`, `XDEL` and `XRANGE` (#1587)
|
||||
- Added prefixable interface for `HEXPIRE` and `HEXPIRETIME` (#1592)
|
||||
- Added new experimental CAS/CAD functionality (#1609)
|
||||
- Added temporary XREADGROUP_CLAIM command (#1608)
|
||||
- Added support for MSET command (#1610)
|
||||
- Added experimental support for FT.HYBRID (#1607)
|
||||
|
||||
### Changed
|
||||
- Refactor pipeline data writing depends on connection type (#1586)
|
||||
@@ -20,7 +22,6 @@
|
||||
### Added
|
||||
- Added support for `XDELEX` and `XACKDEL` (#1580)
|
||||
- Added missing VSIM argument (#1582)
|
||||
- Added experimental support for FT.HYBRID (#1607)
|
||||
|
||||
### Changed
|
||||
- Extended `XTRIM` and `XADD` commands with new parameters (#1580)
|
||||
|
||||
@@ -53,6 +53,8 @@ use Predis\Command\Redis\VADD;
|
||||
*
|
||||
* @method $this copy(string $source, string $destination, int $db = -1, bool $replace = false)
|
||||
* @method $this del(array|string $keys)
|
||||
* @method $this delex(string $key, string $flag, $flagValue)
|
||||
* @method $this digest(string $key)
|
||||
* @method $this dump($key)
|
||||
* @method $this exists($key)
|
||||
* @method $this expire($key, $seconds, string $expireOption = '')
|
||||
@@ -153,7 +155,7 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this msetex(array $dictionary, ?string $existModifier = null, ?string $expireResolution = null, ?int $expireTTL = null)
|
||||
* @method $this msetnx(array $dictionary)
|
||||
* @method $this psetex($key, $milliseconds, $value)
|
||||
* @method $this set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
|
||||
* @method $this set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null, $flagValue = null)
|
||||
* @method $this setbit($key, $offset, $value)
|
||||
* @method $this setex($key, $seconds, $value)
|
||||
* @method $this setnx($key, $value)
|
||||
|
||||
@@ -63,6 +63,8 @@ use Predis\Response\Status;
|
||||
*
|
||||
* @method int copy(string $source, string $destination, int $db = -1, bool $replace = false)
|
||||
* @method int del(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
* @method int delex(string $key, string $flag, $flagValue)
|
||||
* @method string digest(string $key)
|
||||
* @method string|null dump(string $key)
|
||||
* @method int exists(string $key)
|
||||
* @method int expire(string $key, int $seconds, string $expireOption = '')
|
||||
@@ -163,7 +165,7 @@ use Predis\Response\Status;
|
||||
* @method array msetex(array $dictionary, ?string $existModifier = null, ?string $expireResolution = null, ?int $expireTTL = null)
|
||||
* @method int msetnx(array $dictionary)
|
||||
* @method Status psetex(string $key, $milliseconds, $value)
|
||||
* @method Status|null set(string $key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
|
||||
* @method Status|null set(string $key, $value, $expireResolution = null, $expireTTL = null, $flag = null, $flagValue = null)
|
||||
* @method int setbit(string $key, $offset, $value)
|
||||
* @method Status setex(string $key, $seconds, $value)
|
||||
* @method int setnx(string $key, $value)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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;
|
||||
|
||||
class DELEX extends PrefixableCommand
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return 'DELEX';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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;
|
||||
|
||||
class DIGEST extends PrefixableCommand
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return 'DIGEST';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\Utils;
|
||||
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
class CommandUtility
|
||||
@@ -54,6 +55,21 @@ class CommandUtility
|
||||
return $dict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value into XXH3 hash.
|
||||
*
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
public static function xxh3Hash($value): string
|
||||
{
|
||||
if (!in_array('xxh3', hash_algos(), true)) {
|
||||
throw new RuntimeException('XXH3 algorithm is not supported. Please install PECL xxhash extension.');
|
||||
}
|
||||
|
||||
return hash('xxh3', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts associative array into flatten array (key1, value1...keyN, valueN).
|
||||
*
|
||||
|
||||
@@ -241,6 +241,14 @@ class KeyPrefixProcessorTest extends PredisTestCase
|
||||
['key1', 'key2', 'key3'],
|
||||
['prefix:key1', 'prefix:key2', 'prefix:key3'],
|
||||
],
|
||||
['DELEX',
|
||||
['key1', 'IFEQ', 'value'],
|
||||
['prefix:key1', 'IFEQ', 'value'],
|
||||
],
|
||||
['DIGEST',
|
||||
['key1'],
|
||||
['prefix:key1'],
|
||||
],
|
||||
['TYPE',
|
||||
['key'],
|
||||
['prefix:key'],
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\Redis\Utils\CommandUtility;
|
||||
|
||||
class DELEX_Test extends PredisCommandTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getExpectedCommand(): string
|
||||
{
|
||||
return DELEX::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getExpectedId(): string
|
||||
{
|
||||
return 'DELEX';
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testFilterArguments(): void
|
||||
{
|
||||
$arguments = ['key1'];
|
||||
$expected = ['key1'];
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($arguments);
|
||||
$this->assertSame($expected, $command->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requires PHP >= 8.1
|
||||
* @requiresRedisVersion >= 8.3.224
|
||||
*/
|
||||
public function testDeleteValueWithDifferentModifiers(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', 'bar')
|
||||
);
|
||||
|
||||
$value = $redis->get('foo');
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$redis->delex('foo', 'IFEQ', $value)
|
||||
);
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', 'bar')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$redis->delex('foo', 'IFEQ', 'wrong')
|
||||
);
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$redis->delex('foo', 'IFNE', 'not equal')
|
||||
);
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', 'bar')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$redis->delex('foo', 'IFNE', $value)
|
||||
);
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$redis->delex('foo', 'IFDEQ', CommandUtility::xxh3Hash($value))
|
||||
);
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', 'bar')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$redis->delex('foo', 'IFDEQ', CommandUtility::xxh3Hash('wrong'))
|
||||
);
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$redis->delex('foo', 'IFDNE', CommandUtility::xxh3Hash('not equal'))
|
||||
);
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', 'bar')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$redis->delex('foo', 'IFDNE', CommandUtility::xxh3Hash($value))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\Redis\Utils\CommandUtility;
|
||||
|
||||
class DIGEST_Test extends PredisCommandTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getExpectedCommand(): string
|
||||
{
|
||||
return DIGEST::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getExpectedId(): string
|
||||
{
|
||||
return 'DIGEST';
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testFilterArguments(): void
|
||||
{
|
||||
$arguments = ['key1'];
|
||||
$expected = ['key1'];
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments($arguments);
|
||||
$this->assertSame($expected, $command->getArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requires PHP >= 8.1
|
||||
* @requiresRedisVersion >= 8.3.224
|
||||
*/
|
||||
public function testReturnsDigestOfGivenValue(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
|
||||
$this->assertEquals('OK', $redis->set('foo', 'bar'));
|
||||
$this->assertEquals(CommandUtility::xxh3Hash('bar'), $redis->digest('foo'));
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand;
|
||||
use Predis\Command\Redis\Utils\CommandUtility;
|
||||
|
||||
/**
|
||||
* @group commands
|
||||
@@ -256,6 +257,50 @@ class SET_Test extends PredisCommandTestCase
|
||||
$this->testSetStringValueWithModifierXX();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requires PHP >= 8.1
|
||||
* @requiresRedisVersion >= 8.3.224
|
||||
*/
|
||||
public function testSetStringValueWithNewModifiers(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', 'bar')
|
||||
);
|
||||
|
||||
$value = $redis->get('foo');
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', $value, null, null, 'IFEQ', $value)
|
||||
);
|
||||
$this->assertNull(
|
||||
$redis->set('foo', $value, null, null, 'IFEQ', 'wrong')
|
||||
);
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', $value, null, null, 'IFNE', 'not equal')
|
||||
);
|
||||
$this->assertNull(
|
||||
$redis->set('foo', $value, null, null, 'IFNE', $value)
|
||||
);
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', $value, null, null, 'IFDEQ', CommandUtility::xxh3Hash($value))
|
||||
);
|
||||
$this->assertNull(
|
||||
$redis->set('foo', $value, null, null, 'IFDEQ', CommandUtility::xxh3Hash('wrong'))
|
||||
);
|
||||
$this->assertEquals(
|
||||
'OK',
|
||||
$redis->set('foo', $value, null, null, 'IFDNE', CommandUtility::xxh3Hash('not equal'))
|
||||
);
|
||||
$this->assertNull(
|
||||
$redis->set('foo', $value, null, null, 'IFDNE', CommandUtility::xxh3Hash($value))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @group cluster
|
||||
|
||||
@@ -14,11 +14,13 @@ namespace Predis\Command\Utils;
|
||||
|
||||
use Predis\Command\Redis\Utils\CommandUtility;
|
||||
use PredisTestCase;
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
class CommandUtilityTest extends PredisTestCase
|
||||
{
|
||||
/**
|
||||
* @group disconnected
|
||||
* @dataProvider arrayProvider
|
||||
* @param array $actual
|
||||
* @param array $expected
|
||||
@@ -32,6 +34,7 @@ class CommandUtilityTest extends PredisTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
* @return void
|
||||
*/
|
||||
public function testArrayToDictionaryThrowsExceptionOnOddNumberOfElements()
|
||||
@@ -43,6 +46,32 @@ class CommandUtilityTest extends PredisTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
* @requires PHP >= 8.1
|
||||
* @return void
|
||||
*/
|
||||
public function testXXH3Hash()
|
||||
{
|
||||
$expectedHash = '87d57e269b9df0f0';
|
||||
|
||||
$this->assertEquals($expectedHash, CommandUtility::xxh3Hash('value'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
* @requires PHP < 8.1
|
||||
* @return void
|
||||
*/
|
||||
public function testXXH3HashRaiseExceptionOnPHPLowerThan81()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('XXH3 algorithm is not supported. Please install PECL xxhash extension.');
|
||||
|
||||
CommandUtility::xxh3Hash('value');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
* @return void
|
||||
*/
|
||||
public function testDictionaryToArray(): void
|
||||
|
||||
Reference in New Issue
Block a user