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:
authorPavlo Yatsukhnenko <yatsukhnenko@users.noreply.github.com>2022-08-03 22:41:30 +0300
committerGitHub <noreply@github.com>2022-08-03 22:41:30 +0300
commit677c9da3cbff53b74f7b26ca7dcbdf7e37e1da04 (patch)
treeb0477b24b7db7556fa563175a2d146cd28a1962e
parentb2bb2f519f626f20923c632bfc5dfe5d093ee30b (diff)
parent687a5c788064534b82764db3cdba08ee38bad2de (diff)
Merge pull request #2131 from phpredis/issue-1943
Issue #1943
-rw-r--r--library.c50
-rw-r--r--library.h1
-rw-r--r--redis.c7
-rw-r--r--redis.stub.php6
-rw-r--r--redis_arginfo.h20
-rw-r--r--redis_commands.c63
-rw-r--r--redis_commands.h3
-rw-r--r--redis_legacy_arginfo.h20
-rw-r--r--tests/RedisClusterTest.php1
-rw-r--r--tests/RedisTest.php13
10 files changed, 170 insertions, 14 deletions
diff --git a/library.c b/library.c
index 498c3b37..782f81bf 100644
--- a/library.c
+++ b/library.c
@@ -1335,6 +1335,56 @@ redis_pop_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_
}
PHP_REDIS_API int
+redis_lpos_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
+{
+ char inbuf[4096];
+ int i, numElems;
+ size_t len;
+ zval z_ret;
+
+ if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf), &len) < 0) {
+ goto failure;
+ }
+
+ if (ctx == NULL) {
+ if (*inbuf != TYPE_INT && *inbuf != TYPE_BULK) {
+ goto failure;
+ }
+ ZVAL_LONG(&z_ret, atol(inbuf + 1));
+ } else if (ctx == PHPREDIS_CTX_PTR) {
+ if (*inbuf != TYPE_MULTIBULK) {
+ goto failure;
+ }
+ array_init(&z_ret);
+ numElems = atol(inbuf + 1);
+ for (i = 0; i < numElems; ++i) {
+ if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf), &len) < 0) {
+ zval_dtor(&z_ret);
+ goto failure;
+ }
+ add_next_index_long(&z_ret, atol(inbuf + 1));
+ }
+ } else {
+ ZEND_ASSERT(!"memory corruption?");
+ }
+
+ if (IS_ATOMIC(redis_sock)) {
+ RETVAL_ZVAL(&z_ret, 0, 1);
+ } else {
+ add_next_index_zval(z_tab, &z_ret);
+ }
+ return SUCCESS;
+
+failure:
+ if (IS_ATOMIC(redis_sock)) {
+ RETVAL_FALSE;
+ } else {
+ add_next_index_bool(z_tab, 0);
+ }
+ return FAILURE;
+}
+
+PHP_REDIS_API int
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, void *ctx,
SuccessCallback success_callback)
diff --git a/library.h b/library.h
index e00e6939..48164f09 100644
--- a/library.h
+++ b/library.h
@@ -168,6 +168,7 @@ PHP_REDIS_API int redis_set_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *re
PHP_REDIS_API int redis_geosearch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_hrandfield_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_pop_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
+PHP_REDIS_API int redis_lpos_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
/* Helper methods to get configuration values from a HashTable. */
diff --git a/redis.c b/redis.c
index 8c4cada6..30e8f401 100644
--- a/redis.c
+++ b/redis.c
@@ -1253,6 +1253,13 @@ PHP_METHOD(Redis, lPop)
}
/* }}} */
+/* {{{ proto string Redis::lPos(string key, mixed value, [array options = null]) */
+PHP_METHOD(Redis, lPos)
+{
+ REDIS_PROCESS_CMD(lpos, redis_lpos_response);
+}
+/* }}} */
+
/* {{{ proto string Redis::rPop(string key, [int count = 0]) */
PHP_METHOD(Redis, rPop)
{
diff --git a/redis.stub.php b/redis.stub.php
index 0b7e1776..16b6164c 100644
--- a/redis.stub.php
+++ b/redis.stub.php
@@ -10,10 +10,10 @@ class Redis {
public function __construct(array $options = null);
- public function _compress(string $value): string;
-
public function __destruct();
+ public function _compress(string $value): string;
+
public function _pack(mixed $value): string;
public function _prefix(string $key): string;
@@ -241,6 +241,8 @@ class Redis {
public function lPop(string $key, int $count = 0): bool|string|array;
+ public function lPos(string $key, mixed $value, array $options = null): bool|int|array;
+
/**
* @param mixed $elements
* @return int|Redis
diff --git a/redis_arginfo.h b/redis_arginfo.h
index 74cde5dc..b5f67ad0 100644
--- a/redis_arginfo.h
+++ b/redis_arginfo.h
@@ -1,15 +1,15 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 954ed131a20d6939f9653dbc384e6244a0862b6e */
+ * Stub hash: 7fc0b991dc8404945a0081aef8a422c9c670eab9 */
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")
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis__compress, 0, 1, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___destruct, 0, 0, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___destruct, 0, 0, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis__compress, 0, 1, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis__pack, 0, 1, IS_STRING, 0)
@@ -416,6 +416,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Redis_lPop, 0, 1, MAY_BE_B
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, count, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Redis_lPos, 0, 2, MAY_BE_BOOL|MAY_BE_LONG|MAY_BE_ARRAY)
+ ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_lPush, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_VARIADIC_INFO(0, elements)
@@ -975,8 +981,8 @@ ZEND_END_ARG_INFO()
ZEND_METHOD(Redis, __construct);
-ZEND_METHOD(Redis, _compress);
ZEND_METHOD(Redis, __destruct);
+ZEND_METHOD(Redis, _compress);
ZEND_METHOD(Redis, _pack);
ZEND_METHOD(Redis, _prefix);
ZEND_METHOD(Redis, _serialize);
@@ -1072,6 +1078,7 @@ ZEND_METHOD(Redis, lInsert);
ZEND_METHOD(Redis, lLen);
ZEND_METHOD(Redis, lMove);
ZEND_METHOD(Redis, lPop);
+ZEND_METHOD(Redis, lPos);
ZEND_METHOD(Redis, lPush);
ZEND_METHOD(Redis, rPush);
ZEND_METHOD(Redis, lPushx);
@@ -1205,8 +1212,8 @@ ZEND_METHOD(Redis, zunionstore);
static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, __construct, arginfo_class_Redis___construct, ZEND_ACC_PUBLIC)
- ZEND_ME(Redis, _compress, arginfo_class_Redis__compress, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, __destruct, arginfo_class_Redis___destruct, ZEND_ACC_PUBLIC)
+ ZEND_ME(Redis, _compress, arginfo_class_Redis__compress, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, _pack, arginfo_class_Redis__pack, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, _prefix, arginfo_class_Redis__prefix, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, _serialize, arginfo_class_Redis__serialize, ZEND_ACC_PUBLIC)
@@ -1303,6 +1310,7 @@ static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, lLen, arginfo_class_Redis_lLen, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lMove, arginfo_class_Redis_lMove, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lPop, arginfo_class_Redis_lPop, ZEND_ACC_PUBLIC)
+ ZEND_ME(Redis, lPos, arginfo_class_Redis_lPos, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lPush, arginfo_class_Redis_lPush, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, rPush, arginfo_class_Redis_rPush, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lPushx, arginfo_class_Redis_lPushx, ZEND_ACC_PUBLIC)
diff --git a/redis_commands.c b/redis_commands.c
index f85a764b..ea1eedc7 100644
--- a/redis_commands.c
+++ b/redis_commands.c
@@ -2626,6 +2626,69 @@ int redis_lrem_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return SUCCESS;
}
+int
+redis_lpos_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
+ char **cmd, int *cmd_len, short *slot, void **ctx)
+{
+ char *key;
+ int argc = 2;
+ size_t key_len;
+ smart_string cmdstr = {0};
+ zend_bool withrank = 0;
+ zend_long rank = 0, count = -1, maxlen = -1;
+ zend_string *zkey;
+ zval *z_val, *z_ele, *z_opts = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|a",
+ &key, &key_len, &z_val, &z_opts) == FAILURE)
+ {
+ return FAILURE;
+ }
+
+ if (z_opts != NULL) {
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(z_opts), zkey, z_ele) {
+ if (zkey != NULL) {
+ ZVAL_DEREF(z_ele);
+ if (zend_string_equals_literal_ci(zkey, "count")) {
+ count = zval_get_long(z_ele);
+ } else if (zend_string_equals_literal_ci(zkey, "maxlen")) {
+ maxlen = zval_get_long(z_ele);
+ } else if (zend_string_equals_literal_ci(zkey, "rank")) {
+ rank = zval_get_long(z_ele);
+ withrank = 1;
+ }
+ }
+ } ZEND_HASH_FOREACH_END();
+ }
+
+ argc += (withrank ? 2 : 0) + (count >= 0 ? 2 : 0) + (maxlen >= 0 ? 2 : 0);
+ REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, argc, "LPOS");
+
+ redis_cmd_append_sstr_key(&cmdstr, key, key_len, redis_sock, slot);
+ redis_cmd_append_sstr_zval(&cmdstr, z_val, redis_sock);
+
+ if (withrank) {
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "RANK");
+ redis_cmd_append_sstr_long(&cmdstr, rank);
+ }
+
+ if (count >= 0) {
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "COUNT");
+ redis_cmd_append_sstr_long(&cmdstr, count);
+ *ctx = PHPREDIS_CTX_PTR;
+ }
+
+ if (maxlen >= 0) {
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "MAXLEN");
+ redis_cmd_append_sstr_long(&cmdstr, maxlen);
+ }
+
+ *cmd = cmdstr.c;
+ *cmd_len = cmdstr.len;
+
+ return SUCCESS;
+}
+
int redis_smove_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx)
{
diff --git a/redis_commands.h b/redis_commands.h
index e766e20d..e412d828 100644
--- a/redis_commands.h
+++ b/redis_commands.h
@@ -229,6 +229,9 @@ int redis_linsert_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
int redis_lrem_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);
+int redis_lpos_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
+ char **cmd, int *cmd_len, short *slot, void **ctx);
+
int redis_smove_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);
diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h
index 05645b02..5cced37a 100644
--- a/redis_legacy_arginfo.h
+++ b/redis_legacy_arginfo.h
@@ -1,15 +1,15 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 954ed131a20d6939f9653dbc384e6244a0862b6e */
+ * Stub hash: 7fc0b991dc8404945a0081aef8a422c9c670eab9 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis__compress, 0, 0, 1)
- ZEND_ARG_INFO(0, value)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___destruct, 0, 0, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___destruct, 0, 0, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis__compress, 0, 0, 1)
+ ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
#define arginfo_class_Redis__pack arginfo_class_Redis__compress
@@ -371,6 +371,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_lPop, 0, 0, 1)
ZEND_ARG_INFO(0, count)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_lPos, 0, 0, 2)
+ ZEND_ARG_INFO(0, key)
+ ZEND_ARG_INFO(0, value)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_lPush, 0, 0, 1)
ZEND_ARG_INFO(0, key)
ZEND_ARG_VARIADIC_INFO(0, elements)
@@ -871,8 +877,8 @@ ZEND_END_ARG_INFO()
ZEND_METHOD(Redis, __construct);
-ZEND_METHOD(Redis, _compress);
ZEND_METHOD(Redis, __destruct);
+ZEND_METHOD(Redis, _compress);
ZEND_METHOD(Redis, _pack);
ZEND_METHOD(Redis, _prefix);
ZEND_METHOD(Redis, _serialize);
@@ -968,6 +974,7 @@ ZEND_METHOD(Redis, lInsert);
ZEND_METHOD(Redis, lLen);
ZEND_METHOD(Redis, lMove);
ZEND_METHOD(Redis, lPop);
+ZEND_METHOD(Redis, lPos);
ZEND_METHOD(Redis, lPush);
ZEND_METHOD(Redis, rPush);
ZEND_METHOD(Redis, lPushx);
@@ -1101,8 +1108,8 @@ ZEND_METHOD(Redis, zunionstore);
static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, __construct, arginfo_class_Redis___construct, ZEND_ACC_PUBLIC)
- ZEND_ME(Redis, _compress, arginfo_class_Redis__compress, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, __destruct, arginfo_class_Redis___destruct, ZEND_ACC_PUBLIC)
+ ZEND_ME(Redis, _compress, arginfo_class_Redis__compress, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, _pack, arginfo_class_Redis__pack, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, _prefix, arginfo_class_Redis__prefix, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, _serialize, arginfo_class_Redis__serialize, ZEND_ACC_PUBLIC)
@@ -1199,6 +1206,7 @@ static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, lLen, arginfo_class_Redis_lLen, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lMove, arginfo_class_Redis_lMove, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lPop, arginfo_class_Redis_lPop, ZEND_ACC_PUBLIC)
+ ZEND_ME(Redis, lPos, arginfo_class_Redis_lPos, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lPush, arginfo_class_Redis_lPush, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, rPush, arginfo_class_Redis_rPush, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, lPushx, arginfo_class_Redis_lPushx, ZEND_ACC_PUBLIC)
diff --git a/tests/RedisClusterTest.php b/tests/RedisClusterTest.php
index 18e4ac21..6daa93bb 100644
--- a/tests/RedisClusterTest.php
+++ b/tests/RedisClusterTest.php
@@ -51,6 +51,7 @@ class Redis_Cluster_Test extends Redis_Test {
public function testInvalidAuthArgs() { return $this->markTestSkipped(); }
public function testlMove() { return $this->markTestSkipped(); }
+ public function testlPos() { return $this->marktestSkipped(); }
public function testsMisMember() { return $this->markTestSkipped(); }
public function testzDiff() { return $this->markTestSkipped(); }
public function testzInter() { return $this->markTestSkipped(); }
diff --git a/tests/RedisTest.php b/tests/RedisTest.php
index 43a0cb1e..de76e9b4 100644
--- a/tests/RedisTest.php
+++ b/tests/RedisTest.php
@@ -1015,6 +1015,19 @@ class Redis_Test extends TestSuite
$this->assertTrue($this->redis->lrange('key', 0, -1) === ['val2', 'val0', 'val1']);
}
+ public function testlPos()
+ {
+ $this->redis->del('key');
+ $this->redis->lPush('key', 'val0', 'val1', 'val1');
+ $this->assertEquals(2, $this->redis->lPos('key', 'val0'));
+ $this->assertEquals(0, $this->redis->lPos('key', 'val1'));
+ $this->assertEquals(1, $this->redis->lPos('key', 'val1', ['rank' => 2]));
+ $this->assertEquals([0, 1], $this->redis->lPos('key', 'val1', ['count' => 2]));
+ $this->assertEquals([0], $this->redis->lPos('key', 'val1', ['count' => 2, 'maxlen' => 1]));
+ $this->assertEquals([], $this->redis->lPos('key', 'val2', ['count' => 1]));
+ $this->assertEquals(-1, $this->redis->lPos('key', 'val2'));
+ }
+
// ltrim, lsize, lpop
public function testltrim()
{