Skip to content

Commit 03082de

Browse files
COMMAND command
Implement the new COMMAND command in Redis for both cluster and non cluster classes. This command is really more of a debug tool but should actually be useful for updating the unit tests as we can now simply detect which commands do and don't exist, etc.
1 parent 6594746 commit 03082de

7 files changed

Lines changed: 88 additions & 1 deletion

File tree

cluster_library.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ cluster_multibulk_resp_recursive(RedisSock *sock, size_t elements,
132132
*err = 1;
133133
return;
134134
}
135-
r->str = estrndup(buf,r->len);
136135
break;
137136
case TYPE_INT:
138137
r->integer = len;

php_redis.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ PHP_METHOD(Redis, wait);
197197
PHP_METHOD(Redis, pubsub);
198198

199199
PHP_METHOD(Redis, client);
200+
PHP_METHOD(Redis, command);
200201

201202
/* SCAN and friends */
202203
PHP_METHOD(Redis, scan);

redis.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ static zend_function_entry redis_functions[] = {
261261
PHP_ME(Redis, _unserialize, NULL, ZEND_ACC_PUBLIC)
262262

263263
PHP_ME(Redis, client, NULL, ZEND_ACC_PUBLIC)
264+
PHP_ME(Redis, command, NULL, ZEND_ACC_PUBLIC)
264265

265266
/* SCAN and friends */
266267
PHP_ME(Redis, scan, arginfo_scan, ZEND_ACC_PUBLIC)
@@ -3718,6 +3719,14 @@ PHP_METHOD(Redis, client) {
37183719
}
37193720
}
37203721

3722+
/* proto array Redis::command()
3723+
* proto array Redis::command('info', string cmd)
3724+
* proto array Redis::command('getkeys', array cmd_args) */
3725+
PHP_METHOD(Redis, command) {
3726+
REDIS_PROCESS_CMD(command, redis_read_variant_reply);
3727+
}
3728+
/* }}} */
3729+
37213730
/* Helper to format any combination of SCAN arguments */
37223731
PHPAPI int
37233732
redis_build_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len,

redis_cluster.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ zend_function_entry redis_cluster_functions[] = {
203203
PHP_ME(RedisCluster, randomkey, NULL, ZEND_ACC_PUBLIC)
204204
PHP_ME(RedisCluster, ping, NULL, ZEND_ACC_PUBLIC)
205205
PHP_ME(RedisCluster, echo, NULL, ZEND_ACC_PUBLIC)
206+
PHP_ME(RedisCluster, command, NULL, ZEND_ACC_PUBLIC)
206207

207208
{NULL, NULL, NULL}
208209
};
@@ -2340,4 +2341,12 @@ PHP_METHOD(RedisCluster, echo) {
23402341
}
23412342
/* }}} */
23422343

2344+
/* {{{ proto array RedisCluster::command()
2345+
* proto array RedisCluster::command('INFO', string cmd)
2346+
* proto array RedisCluster::command('GETKEYS', array cmd_args) */
2347+
PHP_METHOD(RedisCluster, command) {
2348+
CLUSTER_PROCESS_CMD(command, cluster_variant_resp);
2349+
}
2350+
/* }}} */
2351+
23432352
/* vim: set tabstop=4 softtabstops=4 noexpandtab shiftwidth=4: */

redis_cluster.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ PHP_METHOD(RedisCluster, time);
256256
PHP_METHOD(RedisCluster, randomkey);
257257
PHP_METHOD(RedisCluster, ping);
258258
PHP_METHOD(RedisCluster, echo);
259+
PHP_METHOD(RedisCluster, command);
259260

260261
/* Introspection */
261262
PHP_METHOD(RedisCluster, getoption);

redis_commands.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,6 +2492,71 @@ int redis_sdiffstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
24922492
"SDIFFSTORE", sizeof("SDIFFSTORE")-1, 2, 0, cmd, cmd_len, slot);
24932493
}
24942494

2495+
/* COMMAND */
2496+
int redis_command_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
2497+
char **cmd, int *cmd_len, short *slot, void **ctx)
2498+
{
2499+
char *kw=NULL;
2500+
zval *z_arg;
2501+
int kw_len;
2502+
2503+
/* Parse our args */
2504+
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sz", &kw, &kw_len,
2505+
&z_arg)==FAILURE)
2506+
{
2507+
return FAILURE;
2508+
}
2509+
2510+
/* Construct our command */
2511+
if(!kw) {
2512+
*cmd_len = redis_cmd_format_static(cmd, "COMMAND", "");
2513+
} else if(kw && !z_arg) {
2514+
/* Sanity check */
2515+
if(strncasecmp(kw, "info", sizeof("info")-1) ||
2516+
Z_TYPE_P(z_arg)!=IS_STRING)
2517+
{
2518+
return FAILURE;
2519+
}
2520+
2521+
/* COMMAND INFO <cmd> */
2522+
*cmd_len = redis_cmd_format_static(cmd, "COMMAND", "ss", "INFO",
2523+
sizeof("INFO")-1, Z_STRVAL_P(z_arg), Z_STRLEN_P(z_arg));
2524+
} else {
2525+
int arr_len;
2526+
2527+
/* Sanity check on args */
2528+
if(strncasecmp(kw, "getkeys", sizeof("getkeys")-1) ||
2529+
Z_TYPE_P(z_arg)!=IS_ARRAY ||
2530+
(arr_len=zend_hash_num_elements(Z_ARRVAL_P(z_arg)))<1)
2531+
{
2532+
return FAILURE;
2533+
}
2534+
2535+
zval **z_ele;
2536+
HashTable *ht_arr = Z_ARRVAL_P(z_arg);
2537+
smart_str cmdstr = {0};
2538+
2539+
redis_cmd_init_sstr(&cmdstr, 1 + arr_len, "COMMAND", sizeof("COMMAND")-1);
2540+
redis_cmd_append_sstr(&cmdstr, "GETKEYS", sizeof("GETKEYS")-1);
2541+
2542+
for(zend_hash_internal_pointer_reset(ht_arr);
2543+
zend_hash_get_current_data(ht_arr, (void**)&z_ele)==SUCCESS;
2544+
zend_hash_move_forward(ht_arr))
2545+
{
2546+
convert_to_string(*z_ele);
2547+
redis_cmd_append_sstr(&cmdstr, Z_STRVAL_PP(z_ele), Z_STRLEN_PP(z_ele));
2548+
}
2549+
2550+
*cmd = cmdstr.c;
2551+
*cmd_len = cmdstr.len;
2552+
}
2553+
2554+
/* Any slot will do */
2555+
CMD_RAND_SLOT(slot);
2556+
2557+
return SUCCESS;
2558+
}
2559+
24952560
/*
24962561
* Redis commands that don't deal with the server at all. The RedisSock*
24972562
* pointer is the only thing retreived differently, so we just take that

redis_commands.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ int redis_sdiff_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
203203
int redis_sdiffstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
204204
char **cmd, int *cmd_len, short *slot, void **ctx);
205205

206+
int redis_command_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
207+
char **cmd, int *cmd_len, short *slot, void **ctx);
208+
206209
int redis_fmt_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len,
207210
long it, char *pat, int pat_len, long count);
208211

0 commit comments

Comments
 (0)