From 01414b1f4fbeae20f809a797db85ca4c3f7cc41c Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Sat, 12 Jul 2014 13:00:40 -0700 Subject: [PATCH] Implement remaining commands For certain commands that need to be directed at a node (CONFIG, CLIENT, SCRIPT, etc), the syntax can be complicated and highly variant. For this reason, these remaining commands have been implemented in a generic way, where users will rely on the error message from Redis to figure out what went wrong. All of the commands take our standardized "node" argument which can either take the form of a string key, or Array(host, port). --- redis_cluster.c | 137 ++++++++++++++++++++++++++++++++++++++++++++---- redis_cluster.h | 6 +++ 2 files changed, 134 insertions(+), 9 deletions(-) diff --git a/redis_cluster.c b/redis_cluster.c index 508c30b..d255211 100644 --- a/redis_cluster.c +++ b/redis_cluster.c @@ -204,7 +204,12 @@ zend_function_entry redis_cluster_functions[] = { PHP_ME(RedisCluster, ping, NULL, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, echo, NULL, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, command, NULL, ZEND_ACC_PUBLIC) - + PHP_ME(RedisCluster, cluster, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, client, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, config, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, pubsub, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, script, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, slowlog, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2031,6 +2036,72 @@ cluster_empty_node_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, efree(cmd); } +/* Generic routine for handling various commands which need to be directed at + * a node, but have complex syntax. We simply parse out the arguments and send + * the command as constructed by the caller */ +static void cluster_raw_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len) +{ + redisCluster *c = GET_CONTEXT(); + smart_str cmd = {0}; + zval **z_args; + short slot; + int cmd_len; + int i, argc = ZEND_NUM_ARGS(); + + /* Commands using this pass-thru don't need to be enabled in MULTI mode */ + if(!CLUSTER_IS_ATOMIC(c)) { + php_error_docref(0 TSRMLS_CC, E_WARNING, + "Command can't be issued in MULTI mode"); + RETURN_FALSE; + } + + /* We at least need the key or [host,port] argument */ + if(argc<1) { + php_error_docref(0 TSRMLS_CC, E_WARNING, + "Command requires at least an argument to direct to a node"); + RETURN_FALSE; + } + + /* Allocate an array to process arguments */ + z_args = emalloc(argc * sizeof(zval*)); + + /* Grab args */ + if(zend_get_parameters_array(ht, argc, z_args)==FAILURE) { + efree(z_args); + RETURN_FALSE; + } + + /* First argument needs to be the "where" */ + if((slot = cluster_cmd_get_slot(c, z_args[0]))<0) { + RETURN_FALSE; + } + + /* Initialize our command */ + redis_cmd_init_sstr(&cmd, argc-1, kw, kw_len); + + /* Iterate, appending args */ + for(i=1;i