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:
-rw-r--r--library.c23
-rw-r--r--library.h2
-rw-r--r--php_redis.h2
-rw-r--r--redis.c24
-rw-r--r--redis_commands.c83
-rw-r--r--redis_commands.h6
-rw-r--r--tests/RedisTest.php33
7 files changed, 171 insertions, 2 deletions
diff --git a/library.c b/library.c
index f3118cc4..79847c7f 100644
--- a/library.c
+++ b/library.c
@@ -1285,6 +1285,15 @@ redis_parse_client_list_response(char *response, zval *z_ret)
}
PHP_REDIS_API int
+redis_zdiff_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
+{
+ if (ctx == NULL) {
+ return redis_mbulk_reply_raw(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
+ }
+ return redis_mbulk_reply_zipped_keys_dbl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
+}
+
+PHP_REDIS_API int
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, void *ctx,
SuccessCallback success_callback)
@@ -1455,7 +1464,12 @@ redis_mbulk_reply_zipped(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
size_t len;
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
- return -1;
+ if (IS_ATOMIC(redis_sock)) {
+ RETVAL_FALSE;
+ } else {
+ add_next_index_bool(z_tab, 0);
+ }
+ return FAILURE;
}
if(inbuf[0] != '*') {
@@ -2514,7 +2528,12 @@ redis_mbulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval
size_t len;
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
- return -1;
+ if (IS_ATOMIC(redis_sock)) {
+ RETVAL_FALSE;
+ } else {
+ add_next_index_bool(z_tab, 0);
+ }
+ return FAILURE;
}
if(inbuf[0] != '*') {
diff --git a/library.h b/library.h
index a7938735..0c8a55df 100644
--- a/library.h
+++ b/library.h
@@ -151,6 +151,8 @@ PHP_REDIS_API int redis_read_raw_variant_reply(INTERNAL_FUNCTION_PARAMETERS, Red
PHP_REDIS_API int redis_read_variant_reply_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
+PHP_REDIS_API int redis_zdiff_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
+
/* Helper methods to get configuration values from a HashTable. */
#define REDIS_HASH_STR_FIND_STATIC(ht, sstr) \
diff --git a/php_redis.h b/php_redis.h
index 9d44e513..975b8ab5 100644
--- a/php_redis.h
+++ b/php_redis.h
@@ -144,6 +144,8 @@ PHP_METHOD(Redis, zRevRangeByLex);
PHP_METHOD(Redis, zRevRangeByScore);
PHP_METHOD(Redis, zRevRank);
PHP_METHOD(Redis, zScore);
+PHP_METHOD(Redis, zdiff);
+PHP_METHOD(Redis, zdiffstore);
PHP_METHOD(Redis, zinterstore);
PHP_METHOD(Redis, zunionstore);
diff --git a/redis.c b/redis.c
index 91eba589..10b0e159 100644
--- a/redis.c
+++ b/redis.c
@@ -115,6 +115,16 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_connect, 0, 0, 1)
ZEND_ARG_INFO(0, retry_interval)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zdiff, 0, 0, 1)
+ ZEND_ARG_ARRAY_INFO(0, keys, 0)
+ ZEND_ARG_ARRAY_INFO(0, options, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zdiffstore, 0, 0, 2)
+ ZEND_ARG_INFO(0, destination)
+ ZEND_ARG_ARRAY_INFO(0, keys, 0)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_info, 0, 0, 0)
ZEND_ARG_INFO(0, option)
ZEND_END_ARG_INFO()
@@ -472,6 +482,8 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, zRevRangeByScore, arginfo_zrangebyscore, ZEND_ACC_PUBLIC)
PHP_ME(Redis, zRevRank, arginfo_key_member, ZEND_ACC_PUBLIC)
PHP_ME(Redis, zScore, arginfo_key_member, ZEND_ACC_PUBLIC)
+ PHP_ME(Redis, zdiff, arginfo_zdiff, ZEND_ACC_PUBLIC)
+ PHP_ME(Redis, zdiffstore, arginfo_zdiffstore, ZEND_ACC_PUBLIC)
PHP_ME(Redis, zinterstore, arginfo_zstore, ZEND_ACC_PUBLIC)
PHP_ME(Redis, zscan, arginfo_kscan, ZEND_ACC_PUBLIC)
PHP_ME(Redis, zunionstore, arginfo_zstore, ZEND_ACC_PUBLIC)
@@ -2299,6 +2311,18 @@ PHP_METHOD(Redis, zIncrBy)
}
/* }}} */
+/* {{{ proto array Redis::zdiff(array keys, array options) */
+PHP_METHOD(Redis, zdiff) {
+ REDIS_PROCESS_CMD(zdiff, redis_zdiff_response);
+}
+/* }}} */
+
+/* {{{ proto array Redis::zdiffstore(string destination, array keys) */
+PHP_METHOD(Redis, zdiffstore) {
+ REDIS_PROCESS_CMD(zdiffstore, redis_long_response);
+}
+/* }}} */
+
/* zinterstore */
PHP_METHOD(Redis, zinterstore) {
REDIS_PROCESS_KW_CMD("ZINTERSTORE", redis_zinter_cmd, redis_long_response);
diff --git a/redis_commands.c b/redis_commands.c
index 027fbda0..e18690a4 100644
--- a/redis_commands.c
+++ b/redis_commands.c
@@ -625,6 +625,89 @@ int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return SUCCESS;
}
+int
+redis_zdiff_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
+ char **cmd, int *cmd_len, short *slot, void **ctx)
+{
+ int numkeys;
+ smart_string cmdstr = {0};
+ zval *z_keys, *z_opts = NULL, *z_ele;
+ zend_bool withscores = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|a",
+ &z_keys, &z_opts) == FAILURE)
+ {
+ return FAILURE;
+ }
+
+ if ((numkeys = zend_hash_num_elements(Z_ARRVAL_P(z_keys))) == 0) {
+ return FAILURE;
+ }
+
+ if (z_opts && Z_TYPE_P(z_opts) == IS_ARRAY) {
+ zend_ulong idx;
+ zend_string *zkey;
+ ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(z_opts), idx, zkey, z_ele) {
+ if (zkey != NULL) {
+ ZVAL_DEREF(z_ele);
+ if (zend_string_equals_literal_ci(zkey, "withscores")) {
+ withscores = zval_is_true(z_ele);
+ }
+ }
+ } ZEND_HASH_FOREACH_END();
+ }
+
+ REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 1 + numkeys + withscores, "ZDIFF");
+ redis_cmd_append_sstr_long(&cmdstr, numkeys);
+
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_keys), z_ele) {
+ ZVAL_DEREF(z_ele);
+ redis_cmd_append_sstr_zval(&cmdstr, z_ele, redis_sock);
+ } ZEND_HASH_FOREACH_END();
+
+ if (withscores) {
+ REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "WITHSCORES");
+ *ctx = redis_sock;
+ }
+
+ *cmd = cmdstr.c;
+ *cmd_len = cmdstr.len;
+ return SUCCESS;
+}
+
+int
+redis_zdiffstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
+ char **cmd, int *cmd_len, short *slot, void **ctx)
+{
+ char *dst;
+ size_t dst_len;
+ int numkeys;
+ zval *z_keys, *z_ele;
+ smart_string cmdstr = {0};
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa",
+ &dst, &dst_len, &z_keys) == FAILURE)
+ {
+ return FAILURE;
+ }
+
+ if ((numkeys = zend_hash_num_elements(Z_ARRVAL_P(z_keys))) == 0) {
+ return FAILURE;
+ }
+
+ REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 2 + numkeys, "ZDIFFSTORE");
+ redis_cmd_append_sstr(&cmdstr, dst, dst_len);
+ redis_cmd_append_sstr_long(&cmdstr, numkeys);
+
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_keys), z_ele) {
+ ZVAL_DEREF(z_ele);
+ redis_cmd_append_sstr_zval(&cmdstr, z_ele, redis_sock);
+ } ZEND_HASH_FOREACH_END();
+
+ *cmd = cmdstr.c;
+ *cmd_len = cmdstr.len;
+ return SUCCESS;
+}
/* ZUNIONSTORE, ZINTERSTORE */
int redis_zinter_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
diff --git a/redis_commands.h b/redis_commands.h
index 3a3e0491..c2f79095 100644
--- a/redis_commands.h
+++ b/redis_commands.h
@@ -103,6 +103,12 @@ int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char *kw, char **cmd, int *cmd_len, int *withscores, short *slot,
void **ctx);
+int redis_zdiff_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
+ char **cmd, int *cmd_len, short *slot, void **ctx);
+
+int redis_zdiffstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
+ char **cmd, int *cmd_len, short *slot, void **ctx);
+
int redis_zinter_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
diff --git a/tests/RedisTest.php b/tests/RedisTest.php
index d4b3cfe1..fcf5d811 100644
--- a/tests/RedisTest.php
+++ b/tests/RedisTest.php
@@ -2530,6 +2530,39 @@ class Redis_Test extends TestSuite
}
}
+ public function testzDiff()
+ {
+ // Only available since 6.2.0
+ if (version_compare($this->version, '6.2.0') < 0) {
+ $this->markTestSkipped();
+ return;
+ }
+
+ $this->redis->del('key');
+ foreach (range('a', 'c') as $c) {
+ $this->redis->zAdd('key', 1, $c);
+ }
+
+ $this->assertEquals(['a', 'b', 'c'], $this->redis->zDiff(['key']));
+ $this->assertEquals(['a' => 1.0, 'b' => 1.0, 'c' => 1.0], $this->redis->zDiff(['key'], ['withscores' => true]));
+ }
+
+ public function testzDiffStore()
+ {
+ // Only available since 6.2.0
+ if (version_compare($this->version, '6.2.0') < 0) {
+ $this->markTestSkipped();
+ return;
+ }
+
+ $this->redis->del('key');
+ foreach (range('a', 'c') as $c) {
+ $this->redis->zAdd('key', 1, $c);
+ }
+ $this->assertEquals(3, $this->redis->zDiffStore('key2', ['key']));
+ $this->assertEquals(['a', 'b', 'c'], $this->redis->zRange('key2', 0, -1));
+ }
+
public function testzMscore()
{
// Only available since 6.2.0