diff options
author | Michael Grunder <michael.grunder@gmail.com> | 2019-06-03 03:44:26 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-03 03:44:26 +0300 |
commit | 19f3efcfe6e1a32451a543fa186a8f38d250d941 (patch) | |
tree | a05366b25768d5ec2056b43130d2c9181dd77abe /redis_commands.c | |
parent | 07b1e7738e462f5bf8a34061156a93c0d00400ce (diff) |
Issue.1555 zrange withscores arg (#1565)
Allows ZRANGE to be called either with `true` or `['withscores' => true]` so it's consistent with `ZRANGEBYSCORE` but also backward compatible.
Fixes #1555
Diffstat (limited to 'redis_commands.c')
-rw-r--r-- | redis_commands.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/redis_commands.c b/redis_commands.c index 77c7366e..7466ca0a 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -491,6 +491,12 @@ int redis_fmt_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len, return cmdstr.len; } +/* ZRANGEBYSCORE/ZREVRANGEBYSCORE */ +#define IS_WITHSCORES_ARG(s, l) \ + (l == sizeof("withscores") - 1 && !strncasecmp(s, "withscores", l)) +#define IS_LIMIT_ARG(s, l) \ + (l == sizeof("limit") - 1 && !strncasecmp(s,"limit", l)) + /* ZRANGE/ZREVRANGE */ int redis_zrange_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *kw, char **cmd, int *cmd_len, int *withscores, @@ -499,33 +505,43 @@ int redis_zrange_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *key; size_t key_len; zend_long start, end; - zend_bool ws = 0; + zend_string *zkey; + zval *z_ws = NULL, *z_ele; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|b", &key, &key_len, - &start, &end, &ws) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|z", &key, &key_len, + &start, &end, &z_ws) == FAILURE) { return FAILURE; } - if (ws) { + // Clear withscores arg + *withscores = 0; + + /* Accept ['withscores' => true], or the legacy `true` value */ + if (z_ws) { + if (Z_TYPE_P(z_ws) == IS_ARRAY) { + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(z_ws), zkey, z_ele) { + ZVAL_DEREF(z_ele); + if (IS_WITHSCORES_ARG(ZSTR_VAL(zkey), ZSTR_LEN(zkey))) { + *withscores = zval_is_true(z_ele); + break; + } + } ZEND_HASH_FOREACH_END(); + } else if (Z_TYPE_P(z_ws) == IS_TRUE) { + *withscores = Z_TYPE_P(z_ws) == IS_TRUE; + } + } + + if (*withscores) { *cmd_len = REDIS_CMD_SPPRINTF(cmd, kw, "kdds", key, key_len, start, end, "WITHSCORES", sizeof("WITHSCORES") - 1); } else { *cmd_len = REDIS_CMD_SPPRINTF(cmd, kw, "kdd", key, key_len, start, end); } - // Push out WITHSCORES option - *withscores = ws; - return SUCCESS; } -/* ZRANGEBYSCORE/ZREVRANGEBYSCORE */ -#define IS_WITHSCORES_ARG(s, l) \ - (l == sizeof("withscores") - 1 && !strncasecmp(s, "withscores", l)) -#define IS_LIMIT_ARG(s, l) \ - (l == sizeof("limit") - 1 && !strncasecmp(s,"limit", l)) - int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *kw, char **cmd, int *cmd_len, int *withscores, short *slot, void **ctx) |