diff options
author | Pavlo Yatsukhnenko <yatsukhnenko@gmail.com> | 2022-07-10 21:38:16 +0300 |
---|---|---|
committer | Pavlo Yatsukhnenko <yatsukhnenko@gmail.com> | 2022-07-12 17:15:55 +0300 |
commit | e858e8e333950a5501b865c280a95dcc6ea16462 (patch) | |
tree | 931309387c7641f3acefa9a8e2674d309c30a7b9 | |
parent | 765d3cdf24508ff4a38a505abb5985b01a9d83e1 (diff) |
Issue #1768
Allow multiple field-value pairs for hmset command.
-rw-r--r-- | redis_commands.c | 98 |
1 files changed, 78 insertions, 20 deletions
diff --git a/redis_commands.c b/redis_commands.c index 3b3fa917..f63c1131 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -2670,9 +2670,83 @@ int redis_smove_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, return SUCCESS; } -/* Generic command construction for HSET and HSETNX */ -static int gen_hset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, - char *kw, char **cmd, int *cmd_len, short *slot) +/* HSET */ +int redis_hset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char **cmd, int *cmd_len, short *slot, void **ctx) +{ + int i, argc; + smart_string cmdstr = {0}; + zend_string *zkey; + zval *z_args, *z_ele; + + if ((argc = ZEND_NUM_ARGS()) < 2) { + return FAILURE; + } + + z_args = ecalloc(argc, sizeof(*z_args)); + if (zend_get_parameters_array(ht, argc, z_args) == FAILURE) { + efree(z_args); + return FAILURE; + } + + if (argc == 2) { + if (Z_TYPE(z_args[1]) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL(z_args[1])) == 0) { + efree(z_args); + return FAILURE; + } + + /* Initialize our command */ + redis_cmd_init_sstr(&cmdstr, 1 + zend_hash_num_elements(Z_ARRVAL(z_args[1])), ZEND_STRL("HSET")); + + /* Append key */ + zkey = zval_get_string(&z_args[0]); + redis_cmd_append_sstr_key(&cmdstr, ZSTR_VAL(zkey), ZSTR_LEN(zkey), redis_sock, slot); + zend_string_release(zkey); + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL(z_args[1]), zkey, z_ele) { + if (zkey != NULL) { + ZVAL_DEREF(z_ele); + redis_cmd_append_sstr(&cmdstr, ZSTR_VAL(zkey), ZSTR_LEN(zkey)); + redis_cmd_append_sstr_zval(&cmdstr, z_ele, redis_sock); + } + } ZEND_HASH_FOREACH_END(); + } else { + if (argc % 2 == 0) { + efree(z_args); + return FAILURE; + } + /* Initialize our command */ + redis_cmd_init_sstr(&cmdstr, argc, ZEND_STRL("HSET")); + + /* Append key */ + zkey = zval_get_string(&z_args[0]); + redis_cmd_append_sstr_key(&cmdstr, ZSTR_VAL(zkey), ZSTR_LEN(zkey), redis_sock, slot); + zend_string_release(zkey); + + for (i = 1; i < argc; ++i) { + if (i % 2) { + zkey = zval_get_string(&z_args[i]); + redis_cmd_append_sstr(&cmdstr, ZSTR_VAL(zkey), ZSTR_LEN(zkey)); + zend_string_release(zkey); + } else { + redis_cmd_append_sstr_zval(&cmdstr, &z_args[i], redis_sock); + } + } + } + + // Push out values + *cmd = cmdstr.c; + *cmd_len = cmdstr.len; + + // Cleanup arg array + efree(z_args); + + return SUCCESS; +} + +/* HSETNX */ +int redis_hsetnx_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char **cmd, int *cmd_len, short *slot, void **ctx) { char *key, *mem; size_t key_len, mem_len; @@ -2685,28 +2759,12 @@ static int gen_hset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, } /* Construct command */ - *cmd_len = REDIS_CMD_SPPRINTF(cmd, kw, "ksv", key, key_len, mem, mem_len, z_val); + *cmd_len = REDIS_CMD_SPPRINTF(cmd, "HSETNX", "ksv", key, key_len, mem, mem_len, z_val); // Success return SUCCESS; } -/* HSET */ -int redis_hset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, - char **cmd, int *cmd_len, short *slot, void **ctx) -{ - return gen_hset_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, "HSET", - cmd, cmd_len, slot); -} - -/* HSETNX */ -int redis_hsetnx_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, - char **cmd, int *cmd_len, short *slot, void **ctx) -{ - return gen_hset_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, "HSETNX", - cmd, cmd_len, slot); -} - int redis_hrandfield_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx) |