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:
authorPavlo Yatsukhnenko <yatsukhnenko@gmail.com>2017-10-04 14:29:20 +0300
committerPavlo Yatsukhnenko <yatsukhnenko@gmail.com>2017-10-05 10:03:30 +0300
commitcb003239a6c50189fefb820eadbc51b3cf073006 (patch)
tree77997eba0bf1aa5069bedf5d951e165cf68734e4 /redis_cluster.c
parentdee8a6b1f39180bd0cc078c77eb12bb097e1ab33 (diff)
Issue #1245
Move building `script` command logic to `redis_build_script_cmd` and use it in Redis and RedisCluster objects. Fix arginfo for `RedisCluster::script`. Fix memory leak in `cluster_raw_cmd` when `cluster_cmd_get_slot` fails.
Diffstat (limited to 'redis_cluster.c')
-rw-r--r--redis_cluster.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/redis_cluster.c b/redis_cluster.c
index 9658f8d2..550b23c9 100644
--- a/redis_cluster.c
+++ b/redis_cluster.c
@@ -74,6 +74,16 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_cluster, 0, 0, 1)
#endif
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_script, 0, 0, 2)
+ ZEND_ARG_INFO(0, key_or_address)
+ ZEND_ARG_INFO(0, cmd)
+#if PHP_VERSION_ID >= 50600
+ ZEND_ARG_VARIADIC_INFO(0, args)
+#else
+ ZEND_ARG_INFO(0, ...)
+#endif
+ZEND_END_ARG_INFO()
+
/* Argument info for HSCAN, SSCAN, HSCAN */
ZEND_BEGIN_ARG_INFO_EX(arginfo_kscan_cl, 0, 0, 2)
ZEND_ARG_INFO(0, str_key)
@@ -2345,6 +2355,7 @@ static void cluster_raw_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len)
/* First argument needs to be the "where" */
if((slot = cluster_cmd_get_slot(c, &z_args[0] TSRMLS_CC))<0) {
+ efree(z_args);
RETURN_FALSE;
}
@@ -2778,8 +2789,52 @@ PHP_METHOD(RedisCluster, pubsub) {
/* {{{ proto mixed RedisCluster::script(string key, ...)
* proto mixed RedisCluster::script(array host_port, ...) */
PHP_METHOD(RedisCluster, script) {
- cluster_raw_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SCRIPT",
- sizeof("SCRIPT")-1);
+ redisCluster *c = GET_CONTEXT();
+ smart_string cmd = {0};
+ zval *z_args;
+ short slot;
+ 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 < 2) {
+ 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 = ecalloc(argc, sizeof(zval));
+
+ /* Grab args */
+ if (zend_get_parameters_array(ht, argc, z_args) == FAILURE ||
+ (slot = cluster_cmd_get_slot(c, &z_args[0] TSRMLS_CC)) < 0 ||
+ redis_build_script_cmd(&cmd, argc - 1, &z_args[1]) == NULL
+ ) {
+ efree(z_args);
+ RETURN_FALSE;
+ }
+
+ /* Send it off */
+ if (cluster_send_slot(c, slot, cmd.c, cmd.len, TYPE_EOF TSRMLS_CC) < 0) {
+ zend_throw_exception(redis_cluster_exception_ce,
+ "Couldn't send command to node", 0 TSRMLS_CC);
+ efree(cmd.c);
+ efree(z_args);
+ RETURN_FALSE;
+ }
+
+ /* Read the response variant */
+ cluster_variant_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
+
+ efree(cmd.c);
+ efree(z_args);
}
/* }}} */