diff options
author | michael-grunder <michael.grunder@gmail.com> | 2022-10-13 07:48:53 +0300 |
---|---|---|
committer | michael-grunder <michael.grunder@gmail.com> | 2022-10-13 07:48:53 +0300 |
commit | e8983404a29640b15b09e7ab95b4ed070f352eb1 (patch) | |
tree | 4e52341f8ebbc4f5db44c36f4665c4854b874c8e | |
parent | e392dd88dd89780633da3dd9ea6fb33dd187ff05 (diff) |
Implement Redis 7.0.0 [P]EXPIRE[AT] optionsissue.2068-expire-options
See #2068
-rw-r--r-- | redis.c | 8 | ||||
-rw-r--r-- | redis.stub.php | 8 | ||||
-rw-r--r-- | redis_arginfo.h | 8 | ||||
-rw-r--r-- | redis_cluster.c | 8 | ||||
-rw-r--r-- | redis_cluster.stub.php | 8 | ||||
-rw-r--r-- | redis_cluster_arginfo.h | 4 | ||||
-rw-r--r-- | redis_cluster_legacy_arginfo.h | 4 | ||||
-rw-r--r-- | redis_commands.c | 26 | ||||
-rw-r--r-- | redis_commands.h | 4 | ||||
-rw-r--r-- | redis_legacy_arginfo.h | 4 | ||||
-rw-r--r-- | tests/RedisTest.php | 28 |
11 files changed, 89 insertions, 21 deletions
@@ -1629,25 +1629,25 @@ PHP_METHOD(Redis, sortDescAlpha) /* {{{ proto array Redis::expire(string key, int timeout) */ PHP_METHOD(Redis, expire) { - REDIS_PROCESS_KW_CMD("EXPIRE", redis_key_long_cmd, redis_1_response); + REDIS_PROCESS_KW_CMD("EXPIRE", redis_expire_cmd, redis_1_response); } /* }}} */ /* {{{ proto bool Redis::pexpire(string key, long ms) */ PHP_METHOD(Redis, pexpire) { - REDIS_PROCESS_KW_CMD("PEXPIRE", redis_key_long_cmd, redis_1_response); + REDIS_PROCESS_KW_CMD("PEXPIRE", redis_expire_cmd, redis_1_response); } /* }}} */ /* {{{ proto array Redis::expireAt(string key, int timestamp) */ PHP_METHOD(Redis, expireAt) { - REDIS_PROCESS_KW_CMD("EXPIREAT", redis_key_long_cmd, redis_1_response); + REDIS_PROCESS_KW_CMD("EXPIREAT", redis_expire_cmd, redis_1_response); } /* }}} */ /* {{{ proto array Redis::pexpireAt(string key, int timestamp) */ PHP_METHOD(Redis, pexpireAt) { - REDIS_PROCESS_KW_CMD("PEXPIREAT", redis_key_long_cmd, redis_1_response); + REDIS_PROCESS_KW_CMD("PEXPIREAT", redis_expire_cmd, redis_1_response); } /* }}} */ diff --git a/redis.stub.php b/redis.stub.php index 8cdede95..1f0467d5 100644 --- a/redis.stub.php +++ b/redis.stub.php @@ -105,9 +105,9 @@ class Redis { public function exists(mixed $key, mixed ...$other_keys): Redis|int|bool; - public function expire(string $key, int $timeout): Redis|bool; + public function expire(string $key, int $timeout, ?string $mode = NULL): Redis|bool; - public function expireAt(string $key, int $timestamp): Redis|bool; + public function expireAt(string $key, int $timestamp, ?string $mode = NULL): Redis|bool; public function failover(?array $to = null, bool $abort = false, int $timeout = 0): Redis|bool; @@ -315,9 +315,9 @@ class Redis { public function persist(string $key): bool; - public function pexpire(string $key, int $timeout): bool; + public function pexpire(string $key, int $timeout, ?string $mode = NULL): bool; - public function pexpireAt(string $key, int $timestamp): bool; + public function pexpireAt(string $key, int $timestamp, ?string $mode = NULL): bool; public function pfadd(string $key, array $elements): int; diff --git a/redis_arginfo.h b/redis_arginfo.h index 37241bbf..3c711f3a 100644 --- a/redis_arginfo.h +++ b/redis_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1810caef11b38440e073059e2d9c65f92fa8a9a5 */ + * Stub hash: b53146f6b329f404b4bfa9e5df9dde9c36b50440 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null") @@ -201,11 +201,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_expire, 0, 2, Redis, MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_expireAt, 0, 2, Redis, MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_failover, 0, 0, Redis, MAY_BE_BOOL) @@ -287,7 +289,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_geosearchstore, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_get, 0, 1, Redis, MAY_BE_ANY|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_get, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -576,11 +578,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_pexpire, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_pexpireAt, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_pfadd, 0, 2, IS_LONG, 0) diff --git a/redis_cluster.c b/redis_cluster.c index cdd730ce..0a701ed8 100644 --- a/redis_cluster.c +++ b/redis_cluster.c @@ -1252,24 +1252,24 @@ PHP_METHOD(RedisCluster, decrbyfloat) { /* {{{ proto bool RedisCluster::expire(string key, long sec) */ PHP_METHOD(RedisCluster, expire) { - CLUSTER_PROCESS_KW_CMD("EXPIRE", redis_key_long_cmd, cluster_1_resp, 0); + CLUSTER_PROCESS_KW_CMD("EXPIRE", redis_expire_cmd, cluster_1_resp, 0); } /* }}} */ /* {{{ proto bool RedisCluster::expireat(string key, long ts) */ PHP_METHOD(RedisCluster, expireat) { - CLUSTER_PROCESS_KW_CMD("EXPIREAT", redis_key_long_cmd, cluster_1_resp, 0); + CLUSTER_PROCESS_KW_CMD("EXPIREAT", redis_expire_cmd, cluster_1_resp, 0); } /* {{{ proto bool RedisCluster::pexpire(string key, long ms) */ PHP_METHOD(RedisCluster, pexpire) { - CLUSTER_PROCESS_KW_CMD("PEXPIRE", redis_key_long_cmd, cluster_1_resp, 0); + CLUSTER_PROCESS_KW_CMD("PEXPIRE", redis_expire_cmd, cluster_1_resp, 0); } /* }}} */ /* {{{ proto bool RedisCluster::pexpireat(string key, long ts) */ PHP_METHOD(RedisCluster, pexpireat) { - CLUSTER_PROCESS_KW_CMD("PEXPIREAT", redis_key_long_cmd, cluster_1_resp, 0); + CLUSTER_PROCESS_KW_CMD("PEXPIREAT", redis_expire_cmd, cluster_1_resp, 0); } /* }}} */ diff --git a/redis_cluster.stub.php b/redis_cluster.stub.php index 517ca4c8..9080b4a1 100644 --- a/redis_cluster.stub.php +++ b/redis_cluster.stub.php @@ -95,9 +95,9 @@ class RedisCluster { public function exists(mixed $key, mixed ...$other_keys): RedisCluster|int|bool; - public function expire(string $key, int $timeout): RedisCluster|bool; + public function expire(string $key, int $timeout, ?string $mode = NULL): RedisCluster|bool; - public function expireat(string $key, int $timestamp): RedisCluster|bool; + public function expireat(string $key, int $timestamp, ?string $mode = NULL): RedisCluster|bool; public function expiretime(string $key): RedisCluster|int|false; @@ -218,9 +218,9 @@ class RedisCluster { public function persist(string $key): RedisCluster|bool; - public function pexpire(string $key, int $timeout): RedisCluster|bool; + public function pexpire(string $key, int $timeout, ?string $mode = NULL): RedisCluster|bool; - public function pexpireat(string $key, int $timestamp): RedisCluster|bool; + public function pexpireat(string $key, int $timestamp, ?string $mode = NULL): RedisCluster|bool; public function pfadd(string $key, array $elements): RedisCluster|bool; diff --git a/redis_cluster_arginfo.h b/redis_cluster_arginfo.h index 4b02f3e6..7cb61b51 100644 --- a/redis_cluster_arginfo.h +++ b/redis_cluster_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 280323a9e3fc028641ad1d8bcba2514dfa90fac9 */ + * Stub hash: a89d68c42f8ede578020b94feea3cd52ea8dfd22 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1) @@ -203,11 +203,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_expire, 0, 2, RedisCluster, MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_expireat, 0, 2, RedisCluster, MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_expiretime, 0, 1, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE) diff --git a/redis_cluster_legacy_arginfo.h b/redis_cluster_legacy_arginfo.h index c1552291..7421a7ce 100644 --- a/redis_cluster_legacy_arginfo.h +++ b/redis_cluster_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 280323a9e3fc028641ad1d8bcba2514dfa90fac9 */ + * Stub hash: a89d68c42f8ede578020b94feea3cd52ea8dfd22 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1) ZEND_ARG_INFO(0, name) @@ -177,11 +177,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_expire, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, timeout) + ZEND_ARG_INFO(0, mode) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_expireat, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, timestamp) + ZEND_ARG_INFO(0, mode) ZEND_END_ARG_INFO() #define arginfo_class_RedisCluster_expiretime arginfo_class_RedisCluster__prefix diff --git a/redis_commands.c b/redis_commands.c index 3c56f892..07f10d2b 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -5724,6 +5724,32 @@ int redis_xtrim_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, return SUCCESS; } +int redis_expire_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char *kw, char **cmd, int *cmd_len, short *slot, + void **ctx) +{ + zend_string *key = NULL, *mode = NULL; + smart_string cmdstr = {0}; + zend_long timeout = 0; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(key) + Z_PARAM_LONG(timeout) + Z_PARAM_OPTIONAL + Z_PARAM_STR(mode) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + + redis_cmd_init_sstr(&cmdstr, 2 + (mode != NULL), kw, strlen(kw)); + redis_cmd_append_sstr_key_zstr(&cmdstr, key, redis_sock, slot); + redis_cmd_append_sstr_long(&cmdstr, timeout); + if (mode != NULL) redis_cmd_append_sstr_zstr(&cmdstr, mode); + + *cmd = cmdstr.c; + *cmd_len = cmdstr.len; + + return SUCCESS; +} + int redis_sentinel_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *kw, char **cmd, int *cmd_len, short *slot, void **ctx) diff --git a/redis_commands.h b/redis_commands.h index a93be4a1..ac63bc41 100644 --- a/redis_commands.h +++ b/redis_commands.h @@ -354,6 +354,10 @@ int redis_xreadgroup_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, int redis_xtrim_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx); +int redis_expire_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char *kw, char **cmd, int *cmd_len, short *slot, + void **ctx); + int redis_sentinel_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *kw, char **cmd, int *cmd_len, short *slot, void **ctx); diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h index 66a63b32..3fbd3c4f 100644 --- a/redis_legacy_arginfo.h +++ b/redis_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1810caef11b38440e073059e2d9c65f92fa8a9a5 */ + * Stub hash: b53146f6b329f404b4bfa9e5df9dde9c36b50440 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_INFO(0, options) @@ -181,11 +181,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_expire, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, timeout) + ZEND_ARG_INFO(0, mode) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_expireAt, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, timestamp) + ZEND_ARG_INFO(0, mode) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_failover, 0, 0, 0) diff --git a/tests/RedisTest.php b/tests/RedisTest.php index e2c8b559..b8e743aa 100644 --- a/tests/RedisTest.php +++ b/tests/RedisTest.php @@ -703,6 +703,34 @@ class Redis_Test extends TestSuite $this->assertTrue($success); } + function testExpireOptions() { + if (!$this->minVersionCheck('7.0.0')) + return; + + $this->redis->set('eopts', 'value'); + + /* NX -- Only if expiry isn't set so success, then failure */ + $this->assertTrue($this->redis->expire('eopts', 1000, 'NX')); + $this->assertFalse($this->redis->expire('eopts', 1000, 'NX')); + + /* XX -- Only set if the key has an existing expiry */ + $this->assertTrue($this->redis->expire('eopts', 1000, 'XX')); + $this->assertTrue($this->redis->persist('eopts')); + $this->assertFalse($this->redis->expire('eopts', 1000, 'XX')); + + /* GT -- Only set when new expiry > current expiry */ + $this->assertTrue($this->redis->expire('eopts', 200)); + $this->assertTrue($this->redis->expire('eopts', 300, 'GT')); + $this->assertFalse($this->redis->expire('eopts', 100, 'GT')); + + /* LT -- Only set when expiry < current expiry */ + $this->assertTrue($this->redis->expire('eopts', 200)); + $this->assertTrue($this->redis->expire('eopts', 100, 'LT')); + $this->assertFalse($this->redis->expire('eopts', 300, 'LT')); + + $this->redis->del('eopts'); + } + public function testExpiretime() { if(version_compare($this->version, "7.0.0") < 0) { $this->markTestSkipped(); |