Unverified Commit 70ff26b4 authored by yoav-steinberg's avatar yoav-steinberg Committed by GitHub
Browse files

Multiparam config get. (#9914)

Support doing `CONFIG GET <x> <y> <z>`, each of them can also be
a pattern with wildcards.

This avoids duplicates in the result by looping over the configs and for
each once checking all the patterns, once a match is found for a pattern
we move on to the next config.
parent 28b5a653
This diff is collapsed.
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
"complexity": "O(N) when N is the number of configuration parameters provided", "complexity": "O(N) when N is the number of configuration parameters provided",
"group": "server", "group": "server",
"since": "2.0.0", "since": "2.0.0",
"arity": 3, "arity": -3,
"container": "CONFIG", "container": "CONFIG",
"function": "configGetCommand", "function": "configGetCommand",
"history": [ "history": [
[ [
"7.0.0", "7.0.0",
"Added the ability to pass multiple pattern parameters in one" "Added the ability to pass multiple pattern parameters in one call"
] ]
], ],
"command_flags": [ "command_flags": [
......
...@@ -810,37 +810,34 @@ end: ...@@ -810,37 +810,34 @@ end:
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void configGetCommand(client *c) { void configGetCommand(client *c) {
robj *o = c->argv[2];
void *replylen = addReplyDeferredLen(c); void *replylen = addReplyDeferredLen(c);
char *pattern = o->ptr;
int matches = 0; int matches = 0;
serverAssertWithInfo(c,o,sdsEncodedObject(o)); int i;
for (standardConfig *config = configs; config->name != NULL; config++) { for (standardConfig *config = configs; config->name != NULL; config++) {
/* Hidden configs require an exact match (not a pattern) */ int matched_conf = 0;
if (config->flags & HIDDEN_CONFIG) { int matched_alias = 0;
if (!strcasecmp(pattern, config->name)) { for (i = 0; i < c->argc - 2 && (!matched_conf || !matched_alias); i++) {
robj *o = c->argv[2+i];
char *pattern = o->ptr;
/* Note that hidden configs require an exact match (not a pattern) */
if (!matched_conf &&
(((config->flags & HIDDEN_CONFIG) && !strcasecmp(pattern, config->name)) ||
(!(config->flags & HIDDEN_CONFIG) && stringmatch(pattern, config->name, 1)))) {
addReplyBulkCString(c, config->name); addReplyBulkCString(c, config->name);
addReplyBulkSds(c, config->interface.get(config->data)); addReplyBulkSds(c, config->interface.get(config->data));
matches++; matches++;
break; matched_conf = 1;
} else if (config->alias && !strcasecmp(pattern, config->alias)) { }
if (!matched_alias && config->alias &&
(((config->flags & HIDDEN_CONFIG) && !strcasecmp(pattern, config->alias)) ||
(!(config->flags & HIDDEN_CONFIG) && stringmatch(pattern, config->alias, 1)))) {
addReplyBulkCString(c, config->alias); addReplyBulkCString(c, config->alias);
addReplyBulkSds(c, config->interface.get(config->data)); addReplyBulkSds(c, config->interface.get(config->data));
matches++; matches++;
break; matched_alias = 1;
} }
continue;
}
if (stringmatch(pattern,config->name,1)) {
addReplyBulkCString(c,config->name);
addReplyBulkSds(c, config->interface.get(config->data));
matches++;
}
if (config->alias && stringmatch(pattern,config->alias,1)) {
addReplyBulkCString(c,config->alias);
addReplyBulkSds(c, config->interface.get(config->data));
matches++;
} }
} }
......
...@@ -412,6 +412,22 @@ start_server {tags {"introspection"}} { ...@@ -412,6 +412,22 @@ start_server {tags {"introspection"}} {
assert {[dict exists [r config get $hidden_config] "$hidden_config"]} assert {[dict exists [r config get $hidden_config] "$hidden_config"]}
} }
test {CONFIG GET multiple args} {
set res [r config get maxmemory maxmemory* bind *of]
# Verify there are no duplicates in the result
assert_equal [expr [llength [dict keys $res]]*2] [llength $res]
# Verify we got both name and alias in result
assert {[dict exists $res slaveof] && [dict exists $res replicaof]}
# Verify pattern found multiple maxmemory* configs
assert {[dict exists $res maxmemory] && [dict exists $res maxmemory-samples] && [dict exists $res maxmemory-clients]}
# Verify we also got the explicit config
assert {[dict exists $res bind]}
}
# Config file at this point is at a weird state, and includes all # Config file at this point is at a weird state, and includes all
# known keywords. Might be a good idea to avoid adding tests here. # known keywords. Might be a good idea to avoid adding tests here.
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment