Skip to content

Commit 306ce09

Browse files
InterLinked1jcolp
authored andcommitted
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
1 parent fe50f04 commit 306ce09

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

doc/CHANGES-staging/func_db.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Subject: func_db
2+
3+
The function DB_KEYCOUNT has been added, which
4+
returns the cardinality of the keys at a specified
5+
prefix in AstDB, i.e. the number of keys at a
6+
given prefix.

funcs/func_db.c

+72
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,25 @@
9595
at the prefix specified within the Asterisk database. If no argument is
9696
provided, then a list of key families will be returned.</para>
9797
</description>
98+
<see-also>
99+
<ref type="function">DB_KEYCOUNT</ref>
100+
</see-also>
101+
</function>
102+
<function name="DB_KEYCOUNT" language="en_US">
103+
<synopsis>
104+
Obtain the number of keys at a prefix within the Asterisk database.
105+
</synopsis>
106+
<syntax>
107+
<parameter name="prefix" />
108+
</syntax>
109+
<description>
110+
<para>This function will return the number of keys that exist
111+
at the prefix specified within the Asterisk database. If no argument is
112+
provided, then the number of all key families will be returned.</para>
113+
</description>
114+
<see-also>
115+
<ref type="function">DB_KEYS</ref>
116+
</see-also>
98117
</function>
99118
<function name="DB_DELETE" language="en_US">
100119
<synopsis>
@@ -286,6 +305,57 @@ static struct ast_custom_function db_keys_function = {
286305
.read2 = function_db_keys,
287306
};
288307

308+
static int function_db_keycount(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
309+
{
310+
size_t parselen = strlen(parse);
311+
struct ast_db_entry *dbe, *orig_dbe;
312+
const char *last = "";
313+
int keycount = 0;
314+
315+
/* Remove leading and trailing slashes */
316+
while (parse[0] == '/') {
317+
parse++;
318+
parselen--;
319+
}
320+
while (parse[parselen - 1] == '/') {
321+
parse[--parselen] = '\0';
322+
}
323+
324+
/* Nothing within the database at that prefix? */
325+
if (!(orig_dbe = dbe = ast_db_gettree(parse, NULL))) {
326+
snprintf(buf, len, "%d", keycount);
327+
return 0;
328+
}
329+
330+
for (; dbe; dbe = dbe->next) {
331+
/* Find the current component */
332+
char *curkey = &dbe->key[parselen + 1], *slash;
333+
if (*curkey == '/') {
334+
curkey++;
335+
}
336+
/* Remove everything after the current component */
337+
if ((slash = strchr(curkey, '/'))) {
338+
*slash = '\0';
339+
}
340+
341+
/* Skip duplicates */
342+
if (!strcasecmp(last, curkey)) {
343+
continue;
344+
}
345+
last = curkey;
346+
347+
keycount++;
348+
}
349+
ast_db_freetree(orig_dbe);
350+
snprintf(buf, len, "%d", keycount);
351+
return 0;
352+
}
353+
354+
static struct ast_custom_function db_keycount_function = {
355+
.name = "DB_KEYCOUNT",
356+
.read = function_db_keycount,
357+
};
358+
289359
static int function_db_delete(struct ast_channel *chan, const char *cmd,
290360
char *parse, char *buf, size_t len)
291361
{
@@ -347,6 +417,7 @@ static int unload_module(void)
347417
res |= ast_custom_function_unregister(&db_exists_function);
348418
res |= ast_custom_function_unregister(&db_delete_function);
349419
res |= ast_custom_function_unregister(&db_keys_function);
420+
res |= ast_custom_function_unregister(&db_keycount_function);
350421

351422
return res;
352423
}
@@ -359,6 +430,7 @@ static int load_module(void)
359430
res |= ast_custom_function_register(&db_exists_function);
360431
res |= ast_custom_function_register_escalating(&db_delete_function, AST_CFE_READ);
361432
res |= ast_custom_function_register(&db_keys_function);
433+
res |= ast_custom_function_register(&db_keycount_function);
362434

363435
return res;
364436
}

0 commit comments

Comments
 (0)