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+
289359static 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