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>2022-11-12 14:06:24 +0300
committerPavlo Yatsukhnenko <yatsukhnenko@gmail.com>2022-11-13 12:29:12 +0300
commit7b4861fc8e282843624ae1e34c2353151a73696f (patch)
tree568bc3bf7dbff7500cf95aba4e7e7fb4ba41e4a5
parentcf63e96ec5f6c9363bc5c6955d29c726fc7ec6fe (diff)
[WIP] Refactor commandissue-2068-command
-rw-r--r--library.c42
-rw-r--r--library.h1
-rw-r--r--redis.c2
-rw-r--r--redis.stub.php2
-rw-r--r--redis_arginfo.h6
-rw-r--r--redis_commands.c89
-rw-r--r--redis_legacy_arginfo.h6
7 files changed, 90 insertions, 58 deletions
diff --git a/library.c b/library.c
index 1560e6b0..4bc52a88 100644
--- a/library.c
+++ b/library.c
@@ -1858,6 +1858,48 @@ redis_client_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval
return redis_client_trackinginfo_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
} else {
ZEND_ASSERT(!"memory corruption?");
+ return FAILURE;
+ }
+}
+
+static int
+redis_command_info_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
+{
+ int numElems;
+ zval z_ret;
+
+ if (read_mbulk_header(redis_sock, &numElems) < 0) {
+ if (IS_ATOMIC(redis_sock)) {
+ RETVAL_FALSE;
+ } else {
+ add_next_index_bool(z_tab, 0);
+ }
+ return FAILURE;
+ }
+
+ array_init(&z_ret);
+ redis_read_multibulk_recursive(redis_sock, numElems, 0, &z_ret);
+ if (IS_ATOMIC(redis_sock)) {
+ RETVAL_ZVAL(&z_ret, 0, 1);
+ } else {
+ add_next_index_zval(z_tab, &z_ret);
+ }
+
+ return SUCCESS;
+}
+
+PHP_REDIS_API int
+redis_command_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
+{
+ if (ctx == NULL) {
+ return redis_command_info_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
+ } else if (ctx == PHPREDIS_CTX_PTR) {
+ return redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
+ } else if (ctx == PHPREDIS_CTX_PTR + 1) {
+ return redis_mbulk_reply_raw(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
+ } else {
+ ZEND_ASSERT(!"memory corruption?");
+ return FAILURE;
}
}
diff --git a/library.h b/library.h
index c52b0f2f..d3ae8df5 100644
--- a/library.h
+++ b/library.h
@@ -187,6 +187,7 @@ PHP_REDIS_API int redis_hrandfield_response(INTERNAL_FUNCTION_PARAMETERS, RedisS
PHP_REDIS_API int redis_pop_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_lpos_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_client_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
+PHP_REDIS_API int redis_command_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
/* Helper methods to get configuration values from a HashTable. */
diff --git a/redis.c b/redis.c
index 2aef973d..d90a0689 100644
--- a/redis.c
+++ b/redis.c
@@ -3077,7 +3077,7 @@ PHP_METHOD(Redis, rawcommand) {
* proto array Redis::command('info', string cmd)
* proto array Redis::command('getkeys', array cmd_args) */
PHP_METHOD(Redis, command) {
- REDIS_PROCESS_CMD(command, redis_read_variant_reply);
+ REDIS_PROCESS_CMD(command, redis_command_response);
}
/* }}} */
diff --git a/redis.stub.php b/redis.stub.php
index 12f77301..66a2aa8a 100644
--- a/redis.stub.php
+++ b/redis.stub.php
@@ -434,7 +434,7 @@ class Redis {
public function close(): bool;
- public function command(string $opt = null, string|array $arg): mixed;
+ public function command(string $opt = null, mixed ...$args): mixed;
/**
* Execute the Redis CONFIG command in a variety of ways. What the command does in particular depends
diff --git a/redis_arginfo.h b/redis_arginfo.h
index a13002a1..bc3b8846 100644
--- a/redis_arginfo.h
+++ b/redis_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 42952974e3686f29934dfff1ebba07150942a405 */
+ * Stub hash: babd74e96036b211b97579605f9739698de2e65d */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
@@ -120,9 +120,9 @@ ZEND_END_ARG_INFO()
#define arginfo_class_Redis_close arginfo_class_Redis_clearLastError
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_command, 0, 2, IS_MIXED, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_command, 0, 0, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, opt, IS_STRING, 0, "null")
- ZEND_ARG_TYPE_MASK(0, arg, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
+ ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_config, 0, 1, IS_MIXED, 0)
diff --git a/redis_commands.c b/redis_commands.c
index e75b1892..899839ef 100644
--- a/redis_commands.c
+++ b/redis_commands.c
@@ -5245,63 +5245,52 @@ redis_client_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
int redis_command_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx)
{
- char *kw=NULL;
- zval *z_arg;
- size_t kw_len;
-
- /* Parse our args */
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sz", &kw, &kw_len,
- &z_arg) == FAILURE)
- {
- return FAILURE;
- }
+ smart_string cmdstr = {0};
+ zend_string *op = NULL, *zstr;
+ zval *z_args = NULL;
+ int i, argc = 0;
- /* Construct our command */
- if (!kw) {
- *cmd_len = REDIS_CMD_SPPRINTF(cmd, "COMMAND", "");
- } else if (!z_arg) {
- /* Sanity check */
- if (strncasecmp(kw, "count", sizeof("count") - 1)) {
- return FAILURE;
- }
- /* COMMAND COUNT */
- *cmd_len = REDIS_CMD_SPPRINTF(cmd, "COMMAND", "s", "COUNT", sizeof("COUNT") - 1);
- } else if (Z_TYPE_P(z_arg) == IS_STRING) {
- /* Sanity check */
- if (strncasecmp(kw, "info", sizeof("info") - 1)) {
- return FAILURE;
- }
+ ZEND_PARSE_PARAMETERS_START(0, -1)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_STR(op)
+ Z_PARAM_VARIADIC('*', z_args, argc)
+ ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
- /* COMMAND INFO <cmd> */
- *cmd_len = REDIS_CMD_SPPRINTF(cmd, "COMMAND", "ss", "INFO", sizeof("INFO") - 1,
- Z_STRVAL_P(z_arg), Z_STRLEN_P(z_arg));
+ if (op == NULL) {
+ *ctx = NULL;
+ argc = 0;
+ } else if (zend_string_equals_literal_ci(op, "COUNT")) {
+ *ctx = PHPREDIS_CTX_PTR;
+ argc = 0;
+ } else if (zend_string_equals_literal_ci(op, "DOCS") ||
+ zend_string_equals_literal_ci(op, "INFO")
+ ) {
+ *ctx = NULL;
+ } else if (zend_string_equals_literal_ci(op, "GETKEYS")) {
+ *ctx = PHPREDIS_CTX_PTR + 1;
+ } else if (zend_string_equals_literal_ci(op, "GETKEYSANDFLAGS")) {
+ *ctx = PHPREDIS_CTX_PTR + 2;
+ } else if (zend_string_equals_literal_ci(op, "LIST")) {
+ *ctx = PHPREDIS_CTX_PTR + 1;
} else {
- int arr_len;
-
- /* Sanity check on args */
- if (strncasecmp(kw, "getkeys", sizeof("getkeys")-1) ||
- Z_TYPE_P(z_arg)!=IS_ARRAY ||
- (arr_len=zend_hash_num_elements(Z_ARRVAL_P(z_arg)))<1)
- {
- return FAILURE;
- }
+ php_error_docref(NULL, E_WARNING, "Unknown COMMAND operation '%s'", ZSTR_VAL(op));
+ return FAILURE;
+ }
- zval *z_ele;
- HashTable *ht_arr = Z_ARRVAL_P(z_arg);
- smart_string cmdstr = {0};
+ REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, !!op + argc, "COMMAND");
+ if (op) redis_cmd_append_sstr_zstr(&cmdstr, op);
- redis_cmd_init_sstr(&cmdstr, 1 + arr_len, ZEND_STRL("COMMAND"));
- redis_cmd_append_sstr(&cmdstr, ZEND_STRL("GETKEYS"));
+ for (i = 0; i < argc; ++i) {
+ zstr = zval_get_string(&z_args[i]);
+ redis_cmd_append_sstr(&cmdstr, ZSTR_VAL(zstr), ZSTR_LEN(zstr));
+ zend_string_release(zstr);
+ }
- ZEND_HASH_FOREACH_VAL(ht_arr, z_ele) {
- zend_string *zstr = zval_get_string(z_ele);
- redis_cmd_append_sstr(&cmdstr, ZSTR_VAL(zstr), ZSTR_LEN(zstr));
- zend_string_release(zstr);
- } ZEND_HASH_FOREACH_END();
+ puts(cmdstr.c);
- *cmd = cmdstr.c;
- *cmd_len = cmdstr.len;
- }
+ // Push out values
+ *cmd = cmdstr.c;
+ *cmd_len = cmdstr.len;
/* Any slot will do */
CMD_RAND_SLOT(slot);
diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h
index 196ea90a..a099cec5 100644
--- a/redis_legacy_arginfo.h
+++ b/redis_legacy_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 42952974e3686f29934dfff1ebba07150942a405 */
+ * Stub hash: babd74e96036b211b97579605f9739698de2e65d */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_INFO(0, options)
@@ -114,9 +114,9 @@ ZEND_END_ARG_INFO()
#define arginfo_class_Redis_close arginfo_class_Redis___destruct
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_command, 0, 0, 2)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_command, 0, 0, 0)
ZEND_ARG_INFO(0, opt)
- ZEND_ARG_INFO(0, arg)
+ ZEND_ARG_VARIADIC_INFO(0, args)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_config, 0, 0, 1)