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>2017-04-28 08:30:47 +0300
committermichael-grunder <michael.grunder@gmail.com>2017-04-28 08:30:47 +0300
commita5a0b08f4e9ed9c4bc05c06a08908a49391079e0 (patch)
tree3c564ee8037dbb6817acb45e354b0b5adf05210f /redis_commands.c
parentbdd287e9f7467656eef65dccefc6f389007b9468 (diff)
Refactore EVAL command
This commit moves EVAL and EVALSHA command construction to our redis_commands.c file because as with many other commands we can share the logic between Redis and RedisCluster. In addition it removes the last call to the legacy formatting function redis_cmd_format() which can now be removed.
Diffstat (limited to 'redis_commands.c')
-rw-r--r--redis_commands.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/redis_commands.c b/redis_commands.c
index 1c8b9130..329dea11 100644
--- a/redis_commands.c
+++ b/redis_commands.c
@@ -801,6 +801,72 @@ int redis_gen_zlex_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return SUCCESS;
}
+/* EVAL and EVALSHA */
+int redis_eval_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *kw,
+ char **cmd, int *cmd_len, short *slot, void **ctx)
+{
+ char *lua;
+ int argc = 0;
+ zval *z_arr = NULL, *z_ele;
+ HashTable *ht_arr;
+ zend_long num_keys = 0;
+ smart_string cmdstr = {0};
+ strlen_t lua_len;
+ zend_string *zstr;
+ short prevslot = -1;
+
+ /* Parse args */
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|al", &lua, &lua_len,
+ &z_arr, &num_keys)==FAILURE)
+ {
+ return FAILURE;
+ }
+
+ /* Grab arg count */
+ if (z_arr != NULL) {
+ ht_arr = Z_ARRVAL_P(z_arr);
+ argc = zend_hash_num_elements(ht_arr);
+ }
+
+ /* EVAL[SHA] {script || sha1} {num keys} */
+ redis_cmd_init_sstr(&cmdstr, 2 + argc, kw, strlen(kw));
+ redis_cmd_append_sstr(&cmdstr, lua, lua_len);
+ redis_cmd_append_sstr_long(&cmdstr, num_keys);
+
+ // Iterate over our args if we have any
+ if (argc > 0) {
+ ZEND_HASH_FOREACH_VAL(ht_arr, z_ele) {
+ zstr = zval_get_string(z_ele);
+
+ /* If we're still on a key, prefix it check slot */
+ if (num_keys-- > 0) {
+ redis_cmd_append_sstr_key(&cmdstr, zstr->val, zstr->len, redis_sock, slot);
+
+ /* If we have been passed a slot, all keys must match */
+ if (slot) {
+ if (prevslot != -1 && prevslot != *slot) {
+ zend_string_release(zstr);
+ php_error_docref(0 TSRMLS_CC, E_WARNING, "All keys do not map to the same slot");
+ return FAILURE;
+ }
+ prevslot = *slot;
+ }
+ } else {
+ redis_cmd_append_sstr(&cmdstr, zstr->val, zstr->len);
+ }
+
+ zend_string_release(zstr);
+ } ZEND_HASH_FOREACH_END();
+ } else {
+ /* Any slot will do */
+ CMD_RAND_SLOT(slot);
+ }
+
+ *cmd = cmdstr.c;
+ *cmd_len = cmdstr.len;
+ return SUCCESS;
+}
+
/* Commands that take a key followed by a variable list of serializable
* values (RPUSH, LPUSH, SADD, SREM, etc...) */
int redis_key_varval_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,