func_db: Add function to return cardinality at prefix

Adds the DB_KEYCOUNT function, which can be used to retrieve
the number of keys at a given prefix in AstDB.

ASTERISK-29968 #close

Change-Id: Ib2393b77b7e962dbaae6192f8576bc3f6ba92d09
This commit is contained in:
Naveen Albert 2022-03-15 01:41:29 +00:00 committed by Joshua Colp
parent fe50f049c4
commit 306ce09df2
2 changed files with 78 additions and 0 deletions

View File

@ -0,0 +1,6 @@
Subject: func_db
The function DB_KEYCOUNT has been added, which
returns the cardinality of the keys at a specified
prefix in AstDB, i.e. the number of keys at a
given prefix.

View File

@ -95,6 +95,25 @@
at the prefix specified within the Asterisk database. If no argument is
provided, then a list of key families will be returned.</para>
</description>
<see-also>
<ref type="function">DB_KEYCOUNT</ref>
</see-also>
</function>
<function name="DB_KEYCOUNT" language="en_US">
<synopsis>
Obtain the number of keys at a prefix within the Asterisk database.
</synopsis>
<syntax>
<parameter name="prefix" />
</syntax>
<description>
<para>This function will return the number of keys that exist
at the prefix specified within the Asterisk database. If no argument is
provided, then the number of all key families will be returned.</para>
</description>
<see-also>
<ref type="function">DB_KEYS</ref>
</see-also>
</function>
<function name="DB_DELETE" language="en_US">
<synopsis>
@ -286,6 +305,57 @@ static struct ast_custom_function db_keys_function = {
.read2 = function_db_keys,
};
static int function_db_keycount(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
{
size_t parselen = strlen(parse);
struct ast_db_entry *dbe, *orig_dbe;
const char *last = "";
int keycount = 0;
/* Remove leading and trailing slashes */
while (parse[0] == '/') {
parse++;
parselen--;
}
while (parse[parselen - 1] == '/') {
parse[--parselen] = '\0';
}
/* Nothing within the database at that prefix? */
if (!(orig_dbe = dbe = ast_db_gettree(parse, NULL))) {
snprintf(buf, len, "%d", keycount);
return 0;
}
for (; dbe; dbe = dbe->next) {
/* Find the current component */
char *curkey = &dbe->key[parselen + 1], *slash;
if (*curkey == '/') {
curkey++;
}
/* Remove everything after the current component */
if ((slash = strchr(curkey, '/'))) {
*slash = '\0';
}
/* Skip duplicates */
if (!strcasecmp(last, curkey)) {
continue;
}
last = curkey;
keycount++;
}
ast_db_freetree(orig_dbe);
snprintf(buf, len, "%d", keycount);
return 0;
}
static struct ast_custom_function db_keycount_function = {
.name = "DB_KEYCOUNT",
.read = function_db_keycount,
};
static int function_db_delete(struct ast_channel *chan, const char *cmd,
char *parse, char *buf, size_t len)
{
@ -347,6 +417,7 @@ static int unload_module(void)
res |= ast_custom_function_unregister(&db_exists_function);
res |= ast_custom_function_unregister(&db_delete_function);
res |= ast_custom_function_unregister(&db_keys_function);
res |= ast_custom_function_unregister(&db_keycount_function);
return res;
}
@ -359,6 +430,7 @@ static int load_module(void)
res |= ast_custom_function_register(&db_exists_function);
res |= ast_custom_function_register_escalating(&db_delete_function, AST_CFE_READ);
res |= ast_custom_function_register(&db_keys_function);
res |= ast_custom_function_register(&db_keycount_function);
return res;
}