Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichael-grunder <michael.grunder@gmail.com>2022-10-08 21:06:23 +0300
committerMichael Grunder <michael.grunder@gmail.com>2022-10-08 21:35:10 +0300
commit6b34d17fc480c99f7c7c9c8fae1a55c13b7e94f3 (patch)
tree1798f19b9b3eec99fa59330bda00d8896603dacb
parentd2044c9fa49eefecebad48aa169ab7bead1af121 (diff)
Add new Redis 6.2.0 XTRIM options
Fixes #1961
-rw-r--r--library.c4
-rw-r--r--library.h1
-rw-r--r--redis.stub.php2
-rw-r--r--redis_arginfo.h6
-rw-r--r--redis_cluster.stub.php2
-rw-r--r--redis_cluster_arginfo.h6
-rw-r--r--redis_cluster_legacy_arginfo.h4
-rw-r--r--redis_commands.c52
-rw-r--r--redis_legacy_arginfo.h4
-rw-r--r--tests/RedisTest.php21
10 files changed, 81 insertions, 21 deletions
diff --git a/library.c b/library.c
index 09b31e6c..91f8fca9 100644
--- a/library.c
+++ b/library.c
@@ -1062,6 +1062,10 @@ int redis_cmd_append_sstr_key(smart_string *str, char *key, size_t len, RedisSoc
return retval;
}
+int redis_cmd_append_sstr_key_zstr(smart_string *dst, zend_string *key, RedisSock *redis_sock, short *slot) {
+ return redis_cmd_append_sstr_key(dst, ZSTR_VAL(key), ZSTR_LEN(key), redis_sock, slot);
+}
+
/* Append an array key to a redis smart string command. This function
* handles the boilerplate conditionals around string or integer keys */
int redis_cmd_append_sstr_arrkey(smart_string *cmd, zend_string *kstr, zend_ulong idx)
diff --git a/library.h b/library.h
index ded5d3c8..b67d72f8 100644
--- a/library.h
+++ b/library.h
@@ -50,6 +50,7 @@ int redis_cmd_append_sstr_dbl(smart_string *str, double value);
int redis_cmd_append_sstr_zstr(smart_string *str, zend_string *zstr);
int redis_cmd_append_sstr_zval(smart_string *str, zval *z, RedisSock *redis_sock);
int redis_cmd_append_sstr_key(smart_string *str, char *key, size_t len, RedisSock *redis_sock, short *slot);
+int redis_cmd_append_sstr_key_zstr(smart_string *str, zend_string *key, RedisSock *redis_sock, short *slot);
int redis_cmd_append_sstr_arrkey(smart_string *cmd, zend_string *kstr, zend_ulong idx);
PHP_REDIS_API int redis_spprintf(RedisSock *redis_sock, short *slot, char **ret, char *kw, char *fmt, ...);
diff --git a/redis.stub.php b/redis.stub.php
index e415a5b8..89e6f0c9 100644
--- a/redis.stub.php
+++ b/redis.stub.php
@@ -515,7 +515,7 @@ public function persist(string $key): bool;
public function xrevrange(string $key, string $start, string $end, int $count = -1): bool|array;
- public function xtrim(string $key, int $maxlen, bool $approx = false): int;
+ public function xtrim(string $key, int $maxlen, bool $approx = false, bool $minid = false, int $limit = -1): Redis|int|false;
public function zAdd(string $key, array|float $score_or_options, mixed ...$more_scores_and_mems): Redis|int|false;
diff --git a/redis_arginfo.h b/redis_arginfo.h
index 8b54c21b..acd15086 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: 2c4ee6dc4a5aa66b1700df8859233c349aa00519 */
+ * Stub hash: 0ace014dc4f3f94eedd835f1d6895703aea3e607 */
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")
@@ -920,10 +920,12 @@ ZEND_END_ARG_INFO()
#define arginfo_class_Redis_xrevrange arginfo_class_Redis_xrange
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_xtrim, 0, 2, IS_LONG, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_xtrim, 0, 2, Redis, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, maxlen, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, approx, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, minid, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_zAdd, 0, 2, Redis, MAY_BE_LONG|MAY_BE_FALSE)
diff --git a/redis_cluster.stub.php b/redis_cluster.stub.php
index f3475f01..d4d9518a 100644
--- a/redis_cluster.stub.php
+++ b/redis_cluster.stub.php
@@ -358,7 +358,7 @@ class RedisCluster {
public function xrevrange(string $key, string $start, string $end, int $count = -1): bool|array;
- public function xtrim(string $key, int $maxlen, bool $approx = false): int;
+ public function xtrim(string $key, int $maxlen, bool $approx = false, bool $minid = false, int $limit = -1): RedisCluster|int|false;
public function zadd(string $key, float $score, string $member, mixed ...$extra_args): int;
diff --git a/redis_cluster_arginfo.h b/redis_cluster_arginfo.h
index f5f6cc86..f3357408 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: 956f295e74025def86150d0acdf7a11594c72d47 */
+ * Stub hash: 39c0741e5bf358e116f5ed2caa35c1ca226fd593 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)
@@ -780,10 +780,12 @@ ZEND_END_ARG_INFO()
#define arginfo_class_RedisCluster_xrevrange arginfo_class_RedisCluster_xrange
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_RedisCluster_xtrim, 0, 2, IS_LONG, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_xtrim, 0, 2, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, maxlen, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, approx, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, minid, _IS_BOOL, 0, "false")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_RedisCluster_zadd, 0, 3, IS_LONG, 0)
diff --git a/redis_cluster_legacy_arginfo.h b/redis_cluster_legacy_arginfo.h
index a491d494..fb31eefe 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: 956f295e74025def86150d0acdf7a11594c72d47 */
+ * Stub hash: 39c0741e5bf358e116f5ed2caa35c1ca226fd593 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
ZEND_ARG_INFO(0, name)
@@ -684,6 +684,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_xtrim, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, maxlen)
ZEND_ARG_INFO(0, approx)
+ ZEND_ARG_INFO(0, minid)
+ ZEND_ARG_INFO(0, limit)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_zadd, 0, 0, 3)
diff --git a/redis_commands.c b/redis_commands.c
index 3d1b674d..867ad15e 100644
--- a/redis_commands.c
+++ b/redis_commands.c
@@ -5650,29 +5650,55 @@ int redis_xinfo_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return SUCCESS;
}
-/* XTRIM MAXLEN [~] count */
+// XTRIM key <MAXLEN | MINID> [= | ~] threshold [LIMIT count]
int redis_xtrim_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx)
{
- char *key;
- size_t keylen;
- zend_long maxlen;
- zend_bool approx = 0;
+ zend_long threshold = 0, limit = -1;
+ zend_bool approx = 0, minid = 0;
+ smart_string cmdstr = {0};
+ zend_string *key = NULL;
+ int argc;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|b", &key, &keylen,
- &maxlen, &approx) == FAILURE)
- {
- return FAILURE;
+ ZEND_PARSE_PARAMETERS_START(2, 5)
+ Z_PARAM_STR(key)
+ Z_PARAM_LONG(threshold)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_BOOL(approx)
+ Z_PARAM_BOOL(minid)
+ Z_PARAM_LONG(limit)
+ ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
+
+ argc = 4 + (approx && limit > -1 ? 2 : 0);
+ REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, argc, "XTRIM");
+
+ redis_cmd_append_sstr_key_zstr(&cmdstr, key, redis_sock, slot);
+
+ if (minid) {
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "MINID");
+ } else {
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "MAXLEN");
}
if (approx) {
- *cmd_len = REDIS_CMD_SPPRINTF(cmd, "XTRIM", "kssl", key, keylen,
- "MAXLEN", 6, "~", 1, maxlen);
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "~");
} else {
- *cmd_len = REDIS_CMD_SPPRINTF(cmd, "XTRIM", "ksl", key, keylen,
- "MAXLEN", 6, maxlen);
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "=");
}
+ redis_cmd_append_sstr_long(&cmdstr, threshold);
+
+ if (limit > -1 && approx) {
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "LIMIT");
+ redis_cmd_append_sstr_long(&cmdstr, limit);
+ } else if (limit > -1) {
+ php_error_docref(NULL, E_WARNING, "Cannot use LIMIT without an approximate match, ignoring");
+ } else if (ZEND_NUM_ARGS() == 5) {
+ php_error_docref(NULL, E_WARNING, "Limit must be >= 0");
+ }
+
+ *cmd = cmdstr.c;
+ *cmd_len = cmdstr.len;
return SUCCESS;
}
diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h
index a4972491..b68b5367 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: 2c4ee6dc4a5aa66b1700df8859233c349aa00519 */
+ * Stub hash: 0ace014dc4f3f94eedd835f1d6895703aea3e607 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_INFO(0, options)
@@ -807,6 +807,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_xtrim, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, maxlen)
ZEND_ARG_INFO(0, approx)
+ ZEND_ARG_INFO(0, minid)
+ ZEND_ARG_INFO(0, limit)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_zAdd, 0, 0, 2)
diff --git a/tests/RedisTest.php b/tests/RedisTest.php
index 57faf1af..d44b0364 100644
--- a/tests/RedisTest.php
+++ b/tests/RedisTest.php
@@ -6625,6 +6625,27 @@ class Redis_Test extends TestSuite
can call it with the flag */
$this->addStreamEntries('stream', 100);
$this->assertFalse($this->redis->xTrim('stream', 1, true) === false);
+
+ /* We need Redis >= 6.2.0 for MINID and LIMIT options */
+ if (!$this->minVersionCheck("6.2.0"))
+ return;
+
+ $this->assertEquals(1, $this->redis->del('stream'));
+
+ /* Test minid by generating a stream with more than one */
+ for ($i = 1; $i < 3; $i++) {
+ for ($j = 0; $j < 3; $j++) {
+ $this->redis->xadd('stream', "$i-$j", ['foo' => 'bar']);
+ }
+ }
+
+ /* MINID of 2-0 */
+ $this->assertEquals(3, $this->redis->xtrim('stream', 2, false, true));
+ $this->assertEquals(['2-0', '2-1', '2-2'], array_keys($this->redis->xrange('stream', '0', '+')));
+
+ /* TODO: Figure oiut how to test LIMIT deterministically. For now just
+ send a LIMIT and verify we don't get a failure from Redis. */
+ $this->assertTrue(is_int($this->redis->xtrim('stream', 2, true, false, 3)));
}
/* XCLAIM is one of the most complicated commands, with a great deal of different options