2005-05-08 17:08:25 +00:00
|
|
|
/*
|
2005-09-14 20:46:50 +00:00
|
|
|
* Asterisk -- An open source telephony toolkit.
|
2005-05-08 17:08:25 +00:00
|
|
|
*
|
2006-02-12 04:28:58 +00:00
|
|
|
* Copyright (C) 2005-2006, Russell Bryant <russelb@clemson.edu>
|
2005-05-08 17:08:25 +00:00
|
|
|
*
|
|
|
|
* func_db.c adapted from the old app_db.c, copyright by the following people
|
|
|
|
* Copyright (C) 2005, Mark Spencer <markster@digium.com>
|
|
|
|
* Copyright (C) 2003, Jefferson Noxon <jeff@debian.org>
|
|
|
|
*
|
2005-09-14 20:46:50 +00:00
|
|
|
* See http://www.asterisk.org for more information about
|
|
|
|
* the Asterisk project. Please do not directly contact
|
|
|
|
* any of the maintainers of this project for assistance;
|
|
|
|
* the project provides a web site, mailing lists and IRC
|
|
|
|
* channels for your use.
|
|
|
|
*
|
2005-05-08 17:08:25 +00:00
|
|
|
* This program is free software, distributed under the terms of
|
2005-09-14 20:46:50 +00:00
|
|
|
* the GNU General Public License Version 2. See the LICENSE file
|
|
|
|
* at the top of the source tree.
|
|
|
|
*/
|
|
|
|
|
2005-10-24 20:12:06 +00:00
|
|
|
/*! \file
|
2005-09-14 20:46:50 +00:00
|
|
|
*
|
2005-10-24 20:12:06 +00:00
|
|
|
* \brief Functions for interaction with the Asterisk database
|
2005-12-30 21:18:06 +00:00
|
|
|
*
|
|
|
|
* \author Russell Bryant <russelb@clemson.edu>
|
2007-01-24 09:05:29 +00:00
|
|
|
*
|
|
|
|
* \ingroup functions
|
2005-05-08 17:08:25 +00:00
|
|
|
*/
|
|
|
|
|
2011-07-14 20:28:54 +00:00
|
|
|
/*** MODULEINFO
|
|
|
|
<support_level>core</support_level>
|
|
|
|
***/
|
|
|
|
|
2006-06-07 18:54:56 +00:00
|
|
|
#include "asterisk.h"
|
|
|
|
|
2005-05-08 17:08:25 +00:00
|
|
|
#include <regex.h>
|
|
|
|
|
2006-02-11 03:14:05 +00:00
|
|
|
#include "asterisk/module.h"
|
2005-05-08 17:08:25 +00:00
|
|
|
#include "asterisk/channel.h"
|
|
|
|
#include "asterisk/pbx.h"
|
|
|
|
#include "asterisk/utils.h"
|
|
|
|
#include "asterisk/app.h"
|
|
|
|
#include "asterisk/astdb.h"
|
|
|
|
|
2008-11-01 21:10:07 +00:00
|
|
|
/*** DOCUMENTATION
|
|
|
|
<function name="DB" language="en_US">
|
|
|
|
<synopsis>
|
|
|
|
Read from or write to the Asterisk database.
|
|
|
|
</synopsis>
|
|
|
|
<syntax argsep="/">
|
|
|
|
<parameter name="family" required="true" />
|
|
|
|
<parameter name="key" required="true" />
|
|
|
|
</syntax>
|
|
|
|
<description>
|
|
|
|
<para>This function will read from or write a value to the Asterisk database. On a
|
|
|
|
read, this function returns the corresponding value from the database, or blank
|
|
|
|
if it does not exist. Reading a database value will also set the variable
|
|
|
|
DB_RESULT. If you wish to find out if an entry exists, use the DB_EXISTS
|
|
|
|
function.</para>
|
|
|
|
</description>
|
2008-11-05 12:13:57 +00:00
|
|
|
<see-also>
|
|
|
|
<ref type="application">DBdel</ref>
|
|
|
|
<ref type="function">DB_DELETE</ref>
|
|
|
|
<ref type="application">DBdeltree</ref>
|
|
|
|
<ref type="function">DB_EXISTS</ref>
|
|
|
|
</see-also>
|
2008-11-01 21:10:07 +00:00
|
|
|
</function>
|
|
|
|
<function name="DB_EXISTS" language="en_US">
|
|
|
|
<synopsis>
|
|
|
|
Check to see if a key exists in the Asterisk database.
|
|
|
|
</synopsis>
|
|
|
|
<syntax argsep="/">
|
|
|
|
<parameter name="family" required="true" />
|
|
|
|
<parameter name="key" required="true" />
|
|
|
|
</syntax>
|
|
|
|
<description>
|
|
|
|
<para>This function will check to see if a key exists in the Asterisk
|
|
|
|
database. If it exists, the function will return <literal>1</literal>. If not,
|
|
|
|
it will return <literal>0</literal>. Checking for existence of a database key will
|
|
|
|
also set the variable DB_RESULT to the key's value if it exists.</para>
|
|
|
|
</description>
|
2008-11-05 12:13:57 +00:00
|
|
|
<see-also>
|
|
|
|
<ref type="function">DB</ref>
|
|
|
|
</see-also>
|
2008-11-01 21:10:07 +00:00
|
|
|
</function>
|
Add DB_KEYS.
Discussion on #asterisk on 2011-01-19:
(02:07:03 PM) boch: i wonder how to cycle all entries in a tree
(02:07:11 PM) leifmadsen: use While()
(02:07:17 PM) leifmadsen: you need to know the tree structure already though
(02:07:36 PM) boch: what you mean?
(02:09:02 PM) leifmadsen: you need to know the structure prior to looping, because you can't just return the structure from the dialplan
(02:09:43 PM) leifmadsen: the only way I can think of doing that is via something like writing the output of: asterisk -rx "database show" to a file, then looping through that to know the structure of the database and check everything
(02:09:59 PM) leifmadsen: but at that point you're better off just using either a relational database or an external script
(02:10:13 PM) boch: for example i need to know all entries in the tree
(02:10:15 PM) boch: got it
(02:10:20 PM) leifmadsen: exactly
(02:10:22 PM) leifmadsen: that's the problem
(02:10:22 PM) boch: thank you
(02:13:09 PM) mateu: yeah, i'm surprised there isn't something from the dialplan like 'database show family' so one can get all keys in a family to loop over.
(02:15:35 PM) leifmadsen: database shows everything
(02:16:22 PM) mateu: i mean something from the dial plan that mimics 'database show <family>'
(02:16:41 PM) leifmadsen: guess no one has found that important enough to program :)
(02:16:52 PM) leifmadsen: at that point you should probably just use a relational database...
(02:17:10 PM) mateu: i dunno
(02:17:16 PM) mateu: seems pretty basic to me.
(02:17:16 PM) leifmadsen: me either
(02:17:19 PM) leifmadsen: sure does
(02:17:24 PM) leifmadsen: no one has programmed it though
(02:17:28 PM) ***leifmadsen shrugs
(02:17:43 PM) mateu: ok, well at least we know how it currently stands. thanks leifmadsen
(02:28:52 PM) Corydon76-home: leifmadsen: something like HASHKEYS() ?
(02:30:11 PM) leifmadsen: Corydon76-home: ummm, I was thinking more like DUNDI_QUERY() and DUNDI_RESULT()
(02:30:31 PM) leifmadsen: although HASHKEYS() might work
(02:30:58 PM) leifmadsen: actually ya, looking at it, similar to HASHKEYS()
(02:31:01 PM) leifmadsen: DBKEYS() I guess?
(02:31:45 PM) Corydon76-home: So with no argument, retrieves families, with an argument, retrieves keys of that family?
(02:34:02 PM) leifmadsen: ya
(02:34:16 PM) leifmadsen: how would you iterate through layers of them?
(02:34:30 PM) leifmadsen: i.e. family/key/key/key ?
(02:34:43 PM) Corydon76-home: Essentially, yes
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@303198 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-01-21 08:13:18 +00:00
|
|
|
<function name="DB_KEYS" language="en_US">
|
|
|
|
<synopsis>
|
|
|
|
Obtain a list of keys within the Asterisk database.
|
|
|
|
</synopsis>
|
|
|
|
<syntax>
|
|
|
|
<parameter name="prefix" />
|
|
|
|
</syntax>
|
|
|
|
<description>
|
|
|
|
<para>This function will return a comma-separated list of keys existing
|
|
|
|
at the prefix specified within the Asterisk database. If no argument is
|
|
|
|
provided, then a list of key families will be returned.</para>
|
|
|
|
</description>
|
|
|
|
</function>
|
2008-11-01 21:10:07 +00:00
|
|
|
<function name="DB_DELETE" language="en_US">
|
|
|
|
<synopsis>
|
|
|
|
Return a value from the database and delete it.
|
|
|
|
</synopsis>
|
|
|
|
<syntax argsep="/">
|
|
|
|
<parameter name="family" required="true" />
|
|
|
|
<parameter name="key" required="true" />
|
|
|
|
</syntax>
|
|
|
|
<description>
|
|
|
|
<para>This function will retrieve a value from the Asterisk database
|
|
|
|
and then remove that key from the database. <variable>DB_RESULT</variable>
|
|
|
|
will be set to the key's value if it exists.</para>
|
2013-12-16 19:11:51 +00:00
|
|
|
<note>
|
|
|
|
<para>If <literal>live_dangerously</literal> in <literal>asterisk.conf</literal>
|
|
|
|
is set to <literal>no</literal>, this function can only be read from the
|
|
|
|
dialplan, and not directly from external protocols. It can, however, be
|
|
|
|
executed as a write operation (<literal>DB_DELETE(family, key)=ignored</literal>)</para>
|
|
|
|
</note>
|
2008-11-01 21:10:07 +00:00
|
|
|
</description>
|
2008-11-05 12:13:57 +00:00
|
|
|
<see-also>
|
|
|
|
<ref type="application">DBdel</ref>
|
|
|
|
<ref type="function">DB</ref>
|
|
|
|
<ref type="application">DBdeltree</ref>
|
|
|
|
</see-also>
|
2008-11-01 21:10:07 +00:00
|
|
|
</function>
|
|
|
|
***/
|
|
|
|
|
2007-01-06 00:13:33 +00:00
|
|
|
static int function_db_read(struct ast_channel *chan, const char *cmd,
|
2006-02-12 04:28:58 +00:00
|
|
|
char *parse, char *buf, size_t len)
|
2005-05-08 17:08:25 +00:00
|
|
|
{
|
2006-01-23 18:07:12 +00:00
|
|
|
AST_DECLARE_APP_ARGS(args,
|
2008-10-30 19:18:16 +00:00
|
|
|
AST_APP_ARG(family);
|
|
|
|
AST_APP_ARG(key);
|
2006-01-23 18:07:12 +00:00
|
|
|
);
|
2005-05-08 17:08:25 +00:00
|
|
|
|
2006-02-12 04:28:58 +00:00
|
|
|
buf[0] = '\0';
|
|
|
|
|
|
|
|
if (ast_strlen_zero(parse)) {
|
2005-05-08 17:08:25 +00:00
|
|
|
ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
|
2006-02-12 04:28:58 +00:00
|
|
|
return -1;
|
2005-05-08 17:08:25 +00:00
|
|
|
}
|
|
|
|
|
2006-01-23 18:07:12 +00:00
|
|
|
AST_NONSTANDARD_APP_ARGS(args, parse, '/');
|
2006-02-12 04:28:58 +00:00
|
|
|
|
2006-01-23 18:07:12 +00:00
|
|
|
if (args.argc < 2) {
|
2005-05-08 17:08:25 +00:00
|
|
|
ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
|
2006-02-12 04:28:58 +00:00
|
|
|
return -1;
|
2005-05-08 17:08:25 +00:00
|
|
|
}
|
|
|
|
|
2006-02-12 04:28:58 +00:00
|
|
|
if (ast_db_get(args.family, args.key, buf, len - 1)) {
|
2007-06-14 19:39:12 +00:00
|
|
|
ast_debug(1, "DB: %s/%s not found in database.\n", args.family, args.key);
|
2008-10-30 19:18:16 +00:00
|
|
|
} else {
|
2005-05-19 17:49:14 +00:00
|
|
|
pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
|
2008-10-30 19:18:16 +00:00
|
|
|
}
|
2005-05-19 17:49:14 +00:00
|
|
|
|
2006-02-12 04:28:58 +00:00
|
|
|
return 0;
|
2005-05-08 17:08:25 +00:00
|
|
|
}
|
|
|
|
|
2007-01-06 00:13:33 +00:00
|
|
|
static int function_db_write(struct ast_channel *chan, const char *cmd, char *parse,
|
2006-02-12 04:28:58 +00:00
|
|
|
const char *value)
|
2005-05-08 17:08:25 +00:00
|
|
|
{
|
2006-01-23 18:07:12 +00:00
|
|
|
AST_DECLARE_APP_ARGS(args,
|
2008-10-30 19:18:16 +00:00
|
|
|
AST_APP_ARG(family);
|
|
|
|
AST_APP_ARG(key);
|
2006-01-23 18:07:12 +00:00
|
|
|
);
|
2005-05-08 17:08:25 +00:00
|
|
|
|
2006-02-12 04:28:58 +00:00
|
|
|
if (ast_strlen_zero(parse)) {
|
2005-05-08 17:08:25 +00:00
|
|
|
ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=<value>\n");
|
2006-02-12 04:28:58 +00:00
|
|
|
return -1;
|
2006-01-23 18:07:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AST_NONSTANDARD_APP_ARGS(args, parse, '/');
|
|
|
|
|
|
|
|
if (args.argc < 2) {
|
2005-05-08 17:08:25 +00:00
|
|
|
ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=value\n");
|
2006-02-12 04:28:58 +00:00
|
|
|
return -1;
|
2005-05-08 17:08:25 +00:00
|
|
|
}
|
|
|
|
|
2008-10-30 19:18:16 +00:00
|
|
|
if (ast_db_put(args.family, args.key, value)) {
|
2005-05-08 17:08:25 +00:00
|
|
|
ast_log(LOG_WARNING, "DB: Error writing value to database.\n");
|
2008-10-30 19:18:16 +00:00
|
|
|
}
|
2006-02-12 04:28:58 +00:00
|
|
|
|
|
|
|
return 0;
|
2005-05-08 17:08:25 +00:00
|
|
|
}
|
|
|
|
|
2006-02-11 03:14:05 +00:00
|
|
|
static struct ast_custom_function db_function = {
|
2005-05-08 17:08:25 +00:00
|
|
|
.name = "DB",
|
|
|
|
.read = function_db_read,
|
|
|
|
.write = function_db_write,
|
|
|
|
};
|
|
|
|
|
2007-01-06 00:13:33 +00:00
|
|
|
static int function_db_exists(struct ast_channel *chan, const char *cmd,
|
2006-02-12 04:28:58 +00:00
|
|
|
char *parse, char *buf, size_t len)
|
2005-05-18 23:38:25 +00:00
|
|
|
{
|
2006-01-23 18:07:12 +00:00
|
|
|
AST_DECLARE_APP_ARGS(args,
|
2008-10-30 19:18:16 +00:00
|
|
|
AST_APP_ARG(family);
|
|
|
|
AST_APP_ARG(key);
|
2006-01-23 18:07:12 +00:00
|
|
|
);
|
2005-05-18 23:38:25 +00:00
|
|
|
|
2006-02-12 04:28:58 +00:00
|
|
|
buf[0] = '\0';
|
|
|
|
|
|
|
|
if (ast_strlen_zero(parse)) {
|
2005-05-18 23:38:25 +00:00
|
|
|
ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
|
2006-02-12 04:28:58 +00:00
|
|
|
return -1;
|
2005-05-18 23:38:25 +00:00
|
|
|
}
|
|
|
|
|
2006-01-23 18:07:12 +00:00
|
|
|
AST_NONSTANDARD_APP_ARGS(args, parse, '/');
|
2006-02-12 04:28:58 +00:00
|
|
|
|
2006-01-23 18:07:12 +00:00
|
|
|
if (args.argc < 2) {
|
2005-05-18 23:38:25 +00:00
|
|
|
ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
|
2006-02-12 04:28:58 +00:00
|
|
|
return -1;
|
2005-05-18 23:38:25 +00:00
|
|
|
}
|
|
|
|
|
2008-10-30 19:18:16 +00:00
|
|
|
if (ast_db_get(args.family, args.key, buf, len - 1)) {
|
2006-02-12 04:28:58 +00:00
|
|
|
strcpy(buf, "0");
|
2008-10-30 19:18:16 +00:00
|
|
|
} else {
|
2005-05-19 17:49:14 +00:00
|
|
|
pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
|
2006-02-12 04:28:58 +00:00
|
|
|
strcpy(buf, "1");
|
2005-05-19 17:49:14 +00:00
|
|
|
}
|
2006-02-12 04:28:58 +00:00
|
|
|
|
|
|
|
return 0;
|
2005-05-18 23:38:25 +00:00
|
|
|
}
|
|
|
|
|
2006-02-11 03:14:05 +00:00
|
|
|
static struct ast_custom_function db_exists_function = {
|
2005-05-18 23:38:25 +00:00
|
|
|
.name = "DB_EXISTS",
|
|
|
|
.read = function_db_exists,
|
2009-04-29 18:53:01 +00:00
|
|
|
.read_max = 2,
|
2005-05-18 23:38:25 +00:00
|
|
|
};
|
2006-02-11 03:14:05 +00:00
|
|
|
|
Add DB_KEYS.
Discussion on #asterisk on 2011-01-19:
(02:07:03 PM) boch: i wonder how to cycle all entries in a tree
(02:07:11 PM) leifmadsen: use While()
(02:07:17 PM) leifmadsen: you need to know the tree structure already though
(02:07:36 PM) boch: what you mean?
(02:09:02 PM) leifmadsen: you need to know the structure prior to looping, because you can't just return the structure from the dialplan
(02:09:43 PM) leifmadsen: the only way I can think of doing that is via something like writing the output of: asterisk -rx "database show" to a file, then looping through that to know the structure of the database and check everything
(02:09:59 PM) leifmadsen: but at that point you're better off just using either a relational database or an external script
(02:10:13 PM) boch: for example i need to know all entries in the tree
(02:10:15 PM) boch: got it
(02:10:20 PM) leifmadsen: exactly
(02:10:22 PM) leifmadsen: that's the problem
(02:10:22 PM) boch: thank you
(02:13:09 PM) mateu: yeah, i'm surprised there isn't something from the dialplan like 'database show family' so one can get all keys in a family to loop over.
(02:15:35 PM) leifmadsen: database shows everything
(02:16:22 PM) mateu: i mean something from the dial plan that mimics 'database show <family>'
(02:16:41 PM) leifmadsen: guess no one has found that important enough to program :)
(02:16:52 PM) leifmadsen: at that point you should probably just use a relational database...
(02:17:10 PM) mateu: i dunno
(02:17:16 PM) mateu: seems pretty basic to me.
(02:17:16 PM) leifmadsen: me either
(02:17:19 PM) leifmadsen: sure does
(02:17:24 PM) leifmadsen: no one has programmed it though
(02:17:28 PM) ***leifmadsen shrugs
(02:17:43 PM) mateu: ok, well at least we know how it currently stands. thanks leifmadsen
(02:28:52 PM) Corydon76-home: leifmadsen: something like HASHKEYS() ?
(02:30:11 PM) leifmadsen: Corydon76-home: ummm, I was thinking more like DUNDI_QUERY() and DUNDI_RESULT()
(02:30:31 PM) leifmadsen: although HASHKEYS() might work
(02:30:58 PM) leifmadsen: actually ya, looking at it, similar to HASHKEYS()
(02:31:01 PM) leifmadsen: DBKEYS() I guess?
(02:31:45 PM) Corydon76-home: So with no argument, retrieves families, with an argument, retrieves keys of that family?
(02:34:02 PM) leifmadsen: ya
(02:34:16 PM) leifmadsen: how would you iterate through layers of them?
(02:34:30 PM) leifmadsen: i.e. family/key/key/key ?
(02:34:43 PM) Corydon76-home: Essentially, yes
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@303198 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-01-21 08:13:18 +00:00
|
|
|
static int function_db_keys(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **result, ssize_t maxlen)
|
|
|
|
{
|
|
|
|
size_t parselen = strlen(parse);
|
|
|
|
struct ast_db_entry *dbe, *orig_dbe;
|
|
|
|
struct ast_str *escape_buf = NULL;
|
|
|
|
const char *last = "";
|
|
|
|
|
|
|
|
/* Remove leading and trailing slashes */
|
|
|
|
while (parse[0] == '/') {
|
|
|
|
parse++;
|
|
|
|
parselen--;
|
|
|
|
}
|
|
|
|
while (parse[parselen - 1] == '/') {
|
|
|
|
parse[--parselen] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
ast_str_reset(*result);
|
|
|
|
|
|
|
|
/* Nothing within the database at that prefix? */
|
|
|
|
if (!(orig_dbe = dbe = ast_db_gettree(parse, NULL))) {
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (orig_dbe != dbe) {
|
|
|
|
ast_str_append(result, maxlen, ",");
|
|
|
|
}
|
|
|
|
ast_str_append_escapecommas(result, maxlen, curkey, strlen(curkey));
|
|
|
|
}
|
|
|
|
ast_db_freetree(orig_dbe);
|
|
|
|
ast_free(escape_buf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ast_custom_function db_keys_function = {
|
|
|
|
.name = "DB_KEYS",
|
|
|
|
.read2 = function_db_keys,
|
|
|
|
};
|
|
|
|
|
2007-01-06 00:13:33 +00:00
|
|
|
static int function_db_delete(struct ast_channel *chan, const char *cmd,
|
2006-05-25 15:40:38 +00:00
|
|
|
char *parse, char *buf, size_t len)
|
|
|
|
{
|
|
|
|
AST_DECLARE_APP_ARGS(args,
|
2008-10-30 19:18:16 +00:00
|
|
|
AST_APP_ARG(family);
|
|
|
|
AST_APP_ARG(key);
|
2006-05-25 15:40:38 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
buf[0] = '\0';
|
|
|
|
|
|
|
|
if (ast_strlen_zero(parse)) {
|
|
|
|
ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
AST_NONSTANDARD_APP_ARGS(args, parse, '/');
|
|
|
|
|
|
|
|
if (args.argc < 2) {
|
|
|
|
ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ast_db_get(args.family, args.key, buf, len - 1)) {
|
2007-06-14 19:39:12 +00:00
|
|
|
ast_debug(1, "DB_DELETE: %s/%s not found in database.\n", args.family, args.key);
|
2006-05-25 15:40:38 +00:00
|
|
|
} else {
|
|
|
|
if (ast_db_del(args.family, args.key)) {
|
2007-06-14 19:39:12 +00:00
|
|
|
ast_debug(1, "DB_DELETE: %s/%s could not be deleted from the database\n", args.family, args.key);
|
2006-05-25 15:40:38 +00:00
|
|
|
}
|
|
|
|
}
|
2008-10-30 19:18:16 +00:00
|
|
|
|
2006-05-25 15:40:38 +00:00
|
|
|
pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-12-16 19:11:51 +00:00
|
|
|
/*!
|
|
|
|
* \brief Wrapper to execute DB_DELETE from a write operation. Allows execution
|
|
|
|
* even if live_dangerously is disabled.
|
|
|
|
*/
|
|
|
|
static int function_db_delete_write(struct ast_channel *chan, const char *cmd, char *parse,
|
|
|
|
const char *value)
|
|
|
|
{
|
|
|
|
/* Throwaway to hold the result from the read */
|
|
|
|
char buf[128];
|
|
|
|
return function_db_delete(chan, cmd, parse, buf, sizeof(buf));
|
|
|
|
}
|
2006-05-25 15:40:38 +00:00
|
|
|
|
|
|
|
static struct ast_custom_function db_delete_function = {
|
|
|
|
.name = "DB_DELETE",
|
|
|
|
.read = function_db_delete,
|
2013-12-16 19:11:51 +00:00
|
|
|
.write = function_db_delete_write,
|
2006-05-25 15:40:38 +00:00
|
|
|
};
|
|
|
|
|
2006-08-21 02:11:39 +00:00
|
|
|
static int unload_module(void)
|
2006-02-11 03:14:05 +00:00
|
|
|
{
|
|
|
|
int res = 0;
|
2006-02-12 04:28:58 +00:00
|
|
|
|
2006-02-11 03:14:05 +00:00
|
|
|
res |= ast_custom_function_unregister(&db_function);
|
|
|
|
res |= ast_custom_function_unregister(&db_exists_function);
|
2006-05-25 15:40:38 +00:00
|
|
|
res |= ast_custom_function_unregister(&db_delete_function);
|
Add DB_KEYS.
Discussion on #asterisk on 2011-01-19:
(02:07:03 PM) boch: i wonder how to cycle all entries in a tree
(02:07:11 PM) leifmadsen: use While()
(02:07:17 PM) leifmadsen: you need to know the tree structure already though
(02:07:36 PM) boch: what you mean?
(02:09:02 PM) leifmadsen: you need to know the structure prior to looping, because you can't just return the structure from the dialplan
(02:09:43 PM) leifmadsen: the only way I can think of doing that is via something like writing the output of: asterisk -rx "database show" to a file, then looping through that to know the structure of the database and check everything
(02:09:59 PM) leifmadsen: but at that point you're better off just using either a relational database or an external script
(02:10:13 PM) boch: for example i need to know all entries in the tree
(02:10:15 PM) boch: got it
(02:10:20 PM) leifmadsen: exactly
(02:10:22 PM) leifmadsen: that's the problem
(02:10:22 PM) boch: thank you
(02:13:09 PM) mateu: yeah, i'm surprised there isn't something from the dialplan like 'database show family' so one can get all keys in a family to loop over.
(02:15:35 PM) leifmadsen: database shows everything
(02:16:22 PM) mateu: i mean something from the dial plan that mimics 'database show <family>'
(02:16:41 PM) leifmadsen: guess no one has found that important enough to program :)
(02:16:52 PM) leifmadsen: at that point you should probably just use a relational database...
(02:17:10 PM) mateu: i dunno
(02:17:16 PM) mateu: seems pretty basic to me.
(02:17:16 PM) leifmadsen: me either
(02:17:19 PM) leifmadsen: sure does
(02:17:24 PM) leifmadsen: no one has programmed it though
(02:17:28 PM) ***leifmadsen shrugs
(02:17:43 PM) mateu: ok, well at least we know how it currently stands. thanks leifmadsen
(02:28:52 PM) Corydon76-home: leifmadsen: something like HASHKEYS() ?
(02:30:11 PM) leifmadsen: Corydon76-home: ummm, I was thinking more like DUNDI_QUERY() and DUNDI_RESULT()
(02:30:31 PM) leifmadsen: although HASHKEYS() might work
(02:30:58 PM) leifmadsen: actually ya, looking at it, similar to HASHKEYS()
(02:31:01 PM) leifmadsen: DBKEYS() I guess?
(02:31:45 PM) Corydon76-home: So with no argument, retrieves families, with an argument, retrieves keys of that family?
(02:34:02 PM) leifmadsen: ya
(02:34:16 PM) leifmadsen: how would you iterate through layers of them?
(02:34:30 PM) leifmadsen: i.e. family/key/key/key ?
(02:34:43 PM) Corydon76-home: Essentially, yes
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@303198 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-01-21 08:13:18 +00:00
|
|
|
res |= ast_custom_function_unregister(&db_keys_function);
|
2006-02-11 03:14:05 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2006-08-21 02:11:39 +00:00
|
|
|
static int load_module(void)
|
2006-02-11 03:14:05 +00:00
|
|
|
{
|
|
|
|
int res = 0;
|
2006-02-12 04:28:58 +00:00
|
|
|
|
2014-11-20 16:35:21 +00:00
|
|
|
res |= ast_custom_function_register_escalating(&db_function, AST_CFE_BOTH);
|
2006-02-11 03:14:05 +00:00
|
|
|
res |= ast_custom_function_register(&db_exists_function);
|
2013-12-16 19:11:51 +00:00
|
|
|
res |= ast_custom_function_register_escalating(&db_delete_function, AST_CFE_READ);
|
Add DB_KEYS.
Discussion on #asterisk on 2011-01-19:
(02:07:03 PM) boch: i wonder how to cycle all entries in a tree
(02:07:11 PM) leifmadsen: use While()
(02:07:17 PM) leifmadsen: you need to know the tree structure already though
(02:07:36 PM) boch: what you mean?
(02:09:02 PM) leifmadsen: you need to know the structure prior to looping, because you can't just return the structure from the dialplan
(02:09:43 PM) leifmadsen: the only way I can think of doing that is via something like writing the output of: asterisk -rx "database show" to a file, then looping through that to know the structure of the database and check everything
(02:09:59 PM) leifmadsen: but at that point you're better off just using either a relational database or an external script
(02:10:13 PM) boch: for example i need to know all entries in the tree
(02:10:15 PM) boch: got it
(02:10:20 PM) leifmadsen: exactly
(02:10:22 PM) leifmadsen: that's the problem
(02:10:22 PM) boch: thank you
(02:13:09 PM) mateu: yeah, i'm surprised there isn't something from the dialplan like 'database show family' so one can get all keys in a family to loop over.
(02:15:35 PM) leifmadsen: database shows everything
(02:16:22 PM) mateu: i mean something from the dial plan that mimics 'database show <family>'
(02:16:41 PM) leifmadsen: guess no one has found that important enough to program :)
(02:16:52 PM) leifmadsen: at that point you should probably just use a relational database...
(02:17:10 PM) mateu: i dunno
(02:17:16 PM) mateu: seems pretty basic to me.
(02:17:16 PM) leifmadsen: me either
(02:17:19 PM) leifmadsen: sure does
(02:17:24 PM) leifmadsen: no one has programmed it though
(02:17:28 PM) ***leifmadsen shrugs
(02:17:43 PM) mateu: ok, well at least we know how it currently stands. thanks leifmadsen
(02:28:52 PM) Corydon76-home: leifmadsen: something like HASHKEYS() ?
(02:30:11 PM) leifmadsen: Corydon76-home: ummm, I was thinking more like DUNDI_QUERY() and DUNDI_RESULT()
(02:30:31 PM) leifmadsen: although HASHKEYS() might work
(02:30:58 PM) leifmadsen: actually ya, looking at it, similar to HASHKEYS()
(02:31:01 PM) leifmadsen: DBKEYS() I guess?
(02:31:45 PM) Corydon76-home: So with no argument, retrieves families, with an argument, retrieves keys of that family?
(02:34:02 PM) leifmadsen: ya
(02:34:16 PM) leifmadsen: how would you iterate through layers of them?
(02:34:30 PM) leifmadsen: i.e. family/key/key/key ?
(02:34:43 PM) Corydon76-home: Essentially, yes
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@303198 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2011-01-21 08:13:18 +00:00
|
|
|
res |= ast_custom_function_register(&db_keys_function);
|
2006-02-11 03:14:05 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2006-08-21 02:11:39 +00:00
|
|
|
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Database (astdb) related dialplan functions");
|