mirror of
https://github.com/predis/predis.git
synced 2026-08-31 12:43:31 +00:00
Updated INCREX arguments (#1677)
* Updated INCREX command arguments * Updated test image * Updated CHANGELOG.md * Updated test image
This commit is contained in:
committed by
GitHub
parent
d6f91964e0
commit
37ed2dcd77
@@ -42,7 +42,7 @@ jobs:
|
||||
run: |
|
||||
# Mapping of original redis versions to client test containers
|
||||
declare -A redis_clients_version_mapping=(
|
||||
["8.8"]="8.8-rc1"
|
||||
["8.8"]="custom-26235535976-debian"
|
||||
["8.6"]="8.6.1"
|
||||
["8.4"]="8.4.0"
|
||||
["8.2"]="8.2.2"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
### Changed
|
||||
- Include command name in unsupported container command error messages (#1653)
|
||||
- Updated arguments name for GCRA command (#1667)
|
||||
- Updated INCREX arguments (#1677)
|
||||
|
||||
### Fixed
|
||||
- Fixed handling of gap slots in `SlotMap::offsetUnset()` (#1660)
|
||||
|
||||
@@ -170,7 +170,7 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this incr($key)
|
||||
* @method $this incrby($key, $increment)
|
||||
* @method $this incrbyfloat($key, $increment)
|
||||
* @method $this increx(string $key, int|float|string $value, ?int $lbound = null, ?int $ubound = null, ?string $overflow = null, ?string $expireType = null, $expireValue = null, bool $enx = false)
|
||||
* @method $this increx(string $key, int|float|string $value, ?int $lbound = null, ?int $ubound = null, bool $saturate = false, ?string $expireType = null, $expireValue = null, bool $enx = false)
|
||||
* @method $this mget(array $keys)
|
||||
* @method $this mset(array $dictionary)
|
||||
* @method $this msetex(array $dictionary, ?string $existModifier = null, ?string $expireResolution = null, ?int $expireTTL = null)
|
||||
|
||||
@@ -180,7 +180,7 @@ use Predis\Response\Status;
|
||||
* @method int incr(string $key)
|
||||
* @method int incrby(string $key, int $increment)
|
||||
* @method string incrbyfloat(string $key, int|float $increment)
|
||||
* @method array increx(string $key, int|float|string $value, ?int $lbound = null, ?int $ubound = null, ?string $overflow = null, ?string $expireType = null, $expireValue = null, bool $enx = false)
|
||||
* @method array increx(string $key, int|float|string $value, ?int $lbound = null, ?int $ubound = null, bool $saturate = false, ?string $expireType = null, $expireValue = null, bool $enx = false)
|
||||
* @method array mget(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
* @method mixed mset(array $dictionary)
|
||||
* @method array msetex(array $dictionary, ?string $existModifier = null, ?string $expireResolution = null, ?int $expireTTL = null)
|
||||
|
||||
@@ -23,30 +23,12 @@ class INCREX extends RedisCommand
|
||||
public const BY_INT = 'BYINT';
|
||||
public const BY_FLOAT = 'BYFLOAT';
|
||||
|
||||
public const OVERFLOW_FAIL = 'FAIL';
|
||||
public const OVERFLOW_SAT = 'SAT';
|
||||
public const OVERFLOW_REJECT = 'REJECT';
|
||||
|
||||
public const EXPIRE_EX = 'EX';
|
||||
public const EXPIRE_PX = 'PX';
|
||||
public const EXPIRE_EXAT = 'EXAT';
|
||||
public const EXPIRE_PXAT = 'PXAT';
|
||||
public const EXPIRE_PERSIST = 'PERSIST';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $byEnum = [self::BY_INT, self::BY_FLOAT];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $overflowEnum = [
|
||||
self::OVERFLOW_FAIL,
|
||||
self::OVERFLOW_SAT,
|
||||
self::OVERFLOW_REJECT,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
@@ -69,7 +51,7 @@ class INCREX extends RedisCommand
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Arguments: [key, value, ?lbound, ?ubound, ?overflow, ?expireType, ?expireValue, ?enx]
|
||||
* Arguments: [key, value, ?lbound, ?ubound, ?saturate, ?expireType, ?expireValue, ?enx]
|
||||
*/
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
@@ -91,17 +73,8 @@ class INCREX extends RedisCommand
|
||||
$processed[] = $arguments[3];
|
||||
}
|
||||
|
||||
$overflow = $arguments[4] ?? null;
|
||||
if ($overflow !== null && $overflow !== '') {
|
||||
$overflow = strtoupper($overflow);
|
||||
|
||||
if (!in_array($overflow, self::$overflowEnum, true)) {
|
||||
$allowed = implode(', ', self::$overflowEnum);
|
||||
throw new UnexpectedValueException("Overflow policy accepts only: {$allowed} values");
|
||||
}
|
||||
|
||||
$processed[] = 'OVERFLOW';
|
||||
$processed[] = $overflow;
|
||||
if (!empty($arguments[4])) {
|
||||
$processed[] = 'SATURATE';
|
||||
}
|
||||
|
||||
$expireType = $arguments[5] ?? null;
|
||||
|
||||
@@ -89,29 +89,33 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
['key', 1, null, 100],
|
||||
['key', 'BYINT', 1, 'UBOUND', 100],
|
||||
],
|
||||
'with OVERFLOW SAT' => [
|
||||
['key', 5, null, 100, 'SAT'],
|
||||
['key', 'BYINT', 5, 'UBOUND', 100, 'OVERFLOW', 'SAT'],
|
||||
'with SATURATE' => [
|
||||
['key', 5, null, 100, true],
|
||||
['key', 'BYINT', 5, 'UBOUND', 100, 'SATURATE'],
|
||||
],
|
||||
'without SATURATE (default reject)' => [
|
||||
['key', 5, null, 100, false],
|
||||
['key', 'BYINT', 5, 'UBOUND', 100],
|
||||
],
|
||||
'with EX expiration' => [
|
||||
['key', 1, null, null, null, 'EX', 60],
|
||||
['key', 1, null, null, false, 'EX', 60],
|
||||
['key', 'BYINT', 1, 'EX', 60],
|
||||
],
|
||||
'with PERSIST' => [
|
||||
['key', 1, null, null, null, 'PERSIST'],
|
||||
['key', 1, null, null, false, 'PERSIST'],
|
||||
['key', 'BYINT', 1, 'PERSIST'],
|
||||
],
|
||||
'with ENX flag' => [
|
||||
['key', 1, null, null, null, 'EX', 60, true],
|
||||
['key', 1, null, null, false, 'EX', 60, true],
|
||||
['key', 'BYINT', 1, 'EX', 60, 'ENX'],
|
||||
],
|
||||
'all options with int' => [
|
||||
['key', 5, 0, 100, 'REJECT', 'PX', 5000, true],
|
||||
['key', 'BYINT', 5, 'LBOUND', 0, 'UBOUND', 100, 'OVERFLOW', 'REJECT', 'PX', 5000, 'ENX'],
|
||||
['key', 5, 0, 100, true, 'PX', 5000, true],
|
||||
['key', 'BYINT', 5, 'LBOUND', 0, 'UBOUND', 100, 'SATURATE', 'PX', 5000, 'ENX'],
|
||||
],
|
||||
'all options with float' => [
|
||||
['key', 1.5, 0, 100, 'REJECT', 'PX', 5000, true],
|
||||
['key', 'BYFLOAT', 1.5, 'LBOUND', 0, 'UBOUND', 100, 'OVERFLOW', 'REJECT', 'PX', 5000, 'ENX'],
|
||||
['key', 1.5, 0, 100, true, 'PX', 5000, true],
|
||||
['key', 'BYFLOAT', 1.5, 'LBOUND', 0, 'UBOUND', 100, 'SATURATE', 'PX', 5000, 'ENX'],
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -150,17 +154,6 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
$command->setArguments(['key', new stdClass()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
public function testThrowsExceptionOnInvalidOverflow(): void
|
||||
{
|
||||
$this->expectException(UnexpectedValueException::class);
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments(['key', 1, null, null, 'INVALID']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group disconnected
|
||||
*/
|
||||
@@ -169,7 +162,7 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
$this->expectException(UnexpectedValueException::class);
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments(['key', 1, null, null, null, 'INVALID', 60]);
|
||||
$command->setArguments(['key', 1, null, null, false, 'INVALID', 60]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +174,7 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
$this->expectExceptionMessage('EX requires a value');
|
||||
|
||||
$command = $this->getCommand();
|
||||
$command->setArguments(['key', 1, null, null, null, 'EX']);
|
||||
$command->setArguments(['key', 1, null, null, false, 'EX']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,44 +284,33 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 8.8.0
|
||||
*/
|
||||
public function testOverflowSatSaturatesToBound(): void
|
||||
public function testSaturateClampsResultToBound(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->set('cnt', 10);
|
||||
|
||||
$this->assertSame([50, 40], $redis->increx('cnt', 1000, null, 50, 'SAT'));
|
||||
$this->assertSame([50, 40], $redis->increx('cnt', 1000, null, 50, true));
|
||||
$this->assertSame('50', $redis->get('cnt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Without SATURATE, an out-of-bounds operation is rejected silently:
|
||||
* the key value and TTL remain unchanged and the reply is [current_value, 0].
|
||||
*
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 8.8.0
|
||||
*/
|
||||
public function testOverflowRejectLeavesValueUnchanged(): void
|
||||
public function testDefaultRejectLeavesValueUnchanged(): void
|
||||
{
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->set('cnt', 10);
|
||||
|
||||
$redis->increx('cnt', 1000, null, 50, 'REJECT');
|
||||
$this->assertSame([10, 0], $redis->increx('cnt', 1000, null, 50));
|
||||
$this->assertSame('10', $redis->get('cnt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 8.8.0
|
||||
*/
|
||||
public function testOverflowFailRaisesError(): void
|
||||
{
|
||||
$this->expectException('Predis\Response\ServerException');
|
||||
|
||||
$redis = $this->getClient();
|
||||
|
||||
$redis->set('cnt', 10);
|
||||
$redis->increx('cnt', 1000, null, 50, 'FAIL');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group connected
|
||||
* @requiresRedisVersion >= 8.8.0
|
||||
@@ -339,7 +321,7 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
|
||||
$redis->set('cnt', 10);
|
||||
|
||||
$redis->increx('cnt', 1, null, null, null, 'PX', 60000);
|
||||
$redis->increx('cnt', 1, null, null, false, 'PX', 60000);
|
||||
$this->assertGreaterThan(0, $redis->pttl('cnt'));
|
||||
}
|
||||
|
||||
@@ -355,7 +337,7 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
|
||||
$future = (int) ((microtime(true) + 60) * 1000);
|
||||
|
||||
$redis->increx('cnt', 1, null, null, null, 'PXAT', $future);
|
||||
$redis->increx('cnt', 1, null, null, false, 'PXAT', $future);
|
||||
$this->assertGreaterThan(0, $redis->pttl('cnt'));
|
||||
}
|
||||
|
||||
@@ -371,7 +353,7 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
$redis->expire('cnt', 60);
|
||||
$this->assertGreaterThan(0, $redis->ttl('cnt'));
|
||||
|
||||
$redis->increx('cnt', 1, null, null, null, 'PERSIST');
|
||||
$redis->increx('cnt', 1, null, null, false, 'PERSIST');
|
||||
$this->assertSame(-1, $redis->ttl('cnt'));
|
||||
}
|
||||
|
||||
@@ -385,11 +367,11 @@ class INCREX_Test extends PredisCommandTestCase
|
||||
|
||||
$redis->set('cnt', 10);
|
||||
|
||||
$redis->increx('cnt', 1, null, null, null, 'EX', 60, true);
|
||||
$redis->increx('cnt', 1, null, null, false, 'EX', 60, true);
|
||||
$firstTtl = $redis->ttl('cnt');
|
||||
$this->assertGreaterThan(0, $firstTtl);
|
||||
|
||||
$redis->increx('cnt', 1, null, null, null, 'EX', 9999, true);
|
||||
$redis->increx('cnt', 1, null, null, false, 'EX', 9999, true);
|
||||
$secondTtl = $redis->ttl('cnt');
|
||||
$this->assertLessThanOrEqual($firstTtl, $secondTtl);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user