Wed May 16 06:33:33 2012

Asterisk developer's documentation


func_db.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2005-2006, Russell Bryant <russelb@clemson.edu> 
00005  *
00006  * func_db.c adapted from the old app_db.c, copyright by the following people 
00007  * Copyright (C) 2005, Mark Spencer <markster@digium.com>
00008  * Copyright (C) 2003, Jefferson Noxon <jeff@debian.org>
00009  *
00010  * See http://www.asterisk.org for more information about
00011  * the Asterisk project. Please do not directly contact
00012  * any of the maintainers of this project for assistance;
00013  * the project provides a web site, mailing lists and IRC
00014  * channels for your use.
00015  *
00016  * This program is free software, distributed under the terms of
00017  * the GNU General Public License Version 2. See the LICENSE file
00018  * at the top of the source tree.
00019  */
00020 
00021 /*! \file
00022  *
00023  * \brief Functions for interaction with the Asterisk database
00024  *
00025  * \author Russell Bryant <russelb@clemson.edu>
00026  *
00027  * \ingroup functions
00028  */
00029 
00030 /*** MODULEINFO
00031    <support_level>core</support_level>
00032  ***/
00033 
00034 #include "asterisk.h"
00035 
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328259 $")
00037 
00038 #include <regex.h>
00039 
00040 #include "asterisk/module.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/pbx.h"
00043 #include "asterisk/utils.h"
00044 #include "asterisk/app.h"
00045 #include "asterisk/astdb.h"
00046 
00047 /*** DOCUMENTATION
00048    <function name="DB" language="en_US">
00049       <synopsis>
00050          Read from or write to the Asterisk database.
00051       </synopsis>
00052       <syntax argsep="/">
00053          <parameter name="family" required="true" />
00054          <parameter name="key" required="true" />
00055       </syntax>
00056       <description>
00057          <para>This function will read from or write a value to the Asterisk database.  On a
00058          read, this function returns the corresponding value from the database, or blank
00059          if it does not exist.  Reading a database value will also set the variable
00060          DB_RESULT.  If you wish to find out if an entry exists, use the DB_EXISTS
00061          function.</para>
00062       </description>
00063       <see-also>
00064          <ref type="application">DBdel</ref>
00065          <ref type="function">DB_DELETE</ref>
00066          <ref type="application">DBdeltree</ref>
00067          <ref type="function">DB_EXISTS</ref>
00068       </see-also>
00069    </function>
00070    <function name="DB_EXISTS" language="en_US">
00071       <synopsis>
00072          Check to see if a key exists in the Asterisk database.
00073       </synopsis>
00074       <syntax argsep="/">
00075          <parameter name="family" required="true" />
00076          <parameter name="key" required="true" />
00077       </syntax>
00078       <description>
00079          <para>This function will check to see if a key exists in the Asterisk
00080          database. If it exists, the function will return <literal>1</literal>. If not,
00081          it will return <literal>0</literal>.  Checking for existence of a database key will
00082          also set the variable DB_RESULT to the key's value if it exists.</para>
00083       </description>
00084       <see-also>
00085          <ref type="function">DB</ref>
00086       </see-also>
00087    </function>
00088    <function name="DB_KEYS" language="en_US">
00089       <synopsis>
00090          Obtain a list of keys within the Asterisk database.
00091       </synopsis>
00092       <syntax>
00093          <parameter name="prefix" />
00094       </syntax>
00095       <description>
00096          <para>This function will return a comma-separated list of keys existing
00097          at the prefix specified within the Asterisk database.  If no argument is
00098          provided, then a list of key families will be returned.</para>
00099       </description>
00100    </function>
00101    <function name="DB_DELETE" language="en_US">
00102       <synopsis>
00103          Return a value from the database and delete it.
00104       </synopsis>
00105       <syntax argsep="/">
00106          <parameter name="family" required="true" />
00107          <parameter name="key" required="true" />
00108       </syntax>
00109       <description>
00110          <para>This function will retrieve a value from the Asterisk database
00111          and then remove that key from the database. <variable>DB_RESULT</variable>
00112          will be set to the key's value if it exists.</para>
00113       </description>
00114       <see-also>
00115          <ref type="application">DBdel</ref>
00116          <ref type="function">DB</ref>
00117          <ref type="application">DBdeltree</ref>
00118       </see-also>
00119    </function>
00120  ***/
00121 
00122 static int function_db_read(struct ast_channel *chan, const char *cmd,
00123              char *parse, char *buf, size_t len)
00124 {
00125    AST_DECLARE_APP_ARGS(args,
00126       AST_APP_ARG(family);
00127       AST_APP_ARG(key);
00128    );
00129 
00130    buf[0] = '\0';
00131 
00132    if (ast_strlen_zero(parse)) {
00133       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
00134       return -1;
00135    }
00136 
00137    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00138 
00139    if (args.argc < 2) {
00140       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
00141       return -1;
00142    }
00143 
00144    if (ast_db_get(args.family, args.key, buf, len - 1)) {
00145       ast_debug(1, "DB: %s/%s not found in database.\n", args.family, args.key);
00146    } else {
00147       pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
00148    }
00149 
00150    return 0;
00151 }
00152 
00153 static int function_db_write(struct ast_channel *chan, const char *cmd, char *parse,
00154               const char *value)
00155 {
00156    AST_DECLARE_APP_ARGS(args,
00157       AST_APP_ARG(family);
00158       AST_APP_ARG(key);
00159    );
00160 
00161    if (ast_strlen_zero(parse)) {
00162       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=<value>\n");
00163       return -1;
00164    }
00165 
00166    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00167 
00168    if (args.argc < 2) {
00169       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=value\n");
00170       return -1;
00171    }
00172 
00173    if (ast_db_put(args.family, args.key, value)) {
00174       ast_log(LOG_WARNING, "DB: Error writing value to database.\n");
00175    }
00176 
00177    return 0;
00178 }
00179 
00180 static struct ast_custom_function db_function = {
00181    .name = "DB",
00182    .read = function_db_read,
00183    .write = function_db_write,
00184 };
00185 
00186 static int function_db_exists(struct ast_channel *chan, const char *cmd,
00187                char *parse, char *buf, size_t len)
00188 {
00189    AST_DECLARE_APP_ARGS(args,
00190       AST_APP_ARG(family);
00191       AST_APP_ARG(key);
00192    );
00193 
00194    buf[0] = '\0';
00195 
00196    if (ast_strlen_zero(parse)) {
00197       ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
00198       return -1;
00199    }
00200 
00201    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00202 
00203    if (args.argc < 2) {
00204       ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
00205       return -1;
00206    }
00207 
00208    if (ast_db_get(args.family, args.key, buf, len - 1)) {
00209       strcpy(buf, "0");
00210    } else {
00211       pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
00212       strcpy(buf, "1");
00213    }
00214 
00215    return 0;
00216 }
00217 
00218 static struct ast_custom_function db_exists_function = {
00219    .name = "DB_EXISTS",
00220    .read = function_db_exists,
00221    .read_max = 2,
00222 };
00223 
00224 static int function_db_keys(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **result, ssize_t maxlen)
00225 {
00226    size_t parselen = strlen(parse);
00227    struct ast_db_entry *dbe, *orig_dbe;
00228    struct ast_str *escape_buf = NULL;
00229    const char *last = "";
00230 
00231    /* Remove leading and trailing slashes */
00232    while (parse[0] == '/') {
00233       parse++;
00234       parselen--;
00235    }
00236    while (parse[parselen - 1] == '/') {
00237       parse[--parselen] = '\0';
00238    }
00239 
00240    ast_str_reset(*result);
00241 
00242    /* Nothing within the database at that prefix? */
00243    if (!(orig_dbe = dbe = ast_db_gettree(parse, NULL))) {
00244       return 0;
00245    }
00246 
00247    for (; dbe; dbe = dbe->next) {
00248       /* Find the current component */
00249       char *curkey = &dbe->key[parselen + 1], *slash;
00250       if (*curkey == '/') {
00251          curkey++;
00252       }
00253       /* Remove everything after the current component */
00254       if ((slash = strchr(curkey, '/'))) {
00255          *slash = '\0';
00256       }
00257 
00258       /* Skip duplicates */
00259       if (!strcasecmp(last, curkey)) {
00260          continue;
00261       }
00262       last = curkey;
00263 
00264       if (orig_dbe != dbe) {
00265          ast_str_append(result, maxlen, ",");
00266       }
00267       ast_str_append_escapecommas(result, maxlen, curkey, strlen(curkey));
00268    }
00269    ast_db_freetree(orig_dbe);
00270    ast_free(escape_buf);
00271    return 0;
00272 }
00273 
00274 static struct ast_custom_function db_keys_function = {
00275    .name = "DB_KEYS",
00276    .read2 = function_db_keys,
00277 };
00278 
00279 static int function_db_delete(struct ast_channel *chan, const char *cmd,
00280                char *parse, char *buf, size_t len)
00281 {
00282    AST_DECLARE_APP_ARGS(args,
00283       AST_APP_ARG(family);
00284       AST_APP_ARG(key);
00285    );
00286 
00287    buf[0] = '\0';
00288 
00289    if (ast_strlen_zero(parse)) {
00290       ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
00291       return -1;
00292    }
00293 
00294    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00295 
00296    if (args.argc < 2) {
00297       ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
00298       return -1;
00299    }
00300 
00301    if (ast_db_get(args.family, args.key, buf, len - 1)) {
00302       ast_debug(1, "DB_DELETE: %s/%s not found in database.\n", args.family, args.key);
00303    } else {
00304       if (ast_db_del(args.family, args.key)) {
00305          ast_debug(1, "DB_DELETE: %s/%s could not be deleted from the database\n", args.family, args.key);
00306       }
00307    }
00308 
00309    pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
00310 
00311    return 0;
00312 }
00313 
00314 
00315 static struct ast_custom_function db_delete_function = {
00316    .name = "DB_DELETE",
00317    .read = function_db_delete,
00318 };
00319 
00320 static int unload_module(void)
00321 {
00322    int res = 0;
00323 
00324    res |= ast_custom_function_unregister(&db_function);
00325    res |= ast_custom_function_unregister(&db_exists_function);
00326    res |= ast_custom_function_unregister(&db_delete_function);
00327    res |= ast_custom_function_unregister(&db_keys_function);
00328 
00329    return res;
00330 }
00331 
00332 static int load_module(void)
00333 {
00334    int res = 0;
00335 
00336    res |= ast_custom_function_register(&db_function);
00337    res |= ast_custom_function_register(&db_exists_function);
00338    res |= ast_custom_function_register(&db_delete_function);
00339    res |= ast_custom_function_register(&db_keys_function);
00340 
00341    return res;
00342 }
00343 
00344 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Database (astdb) related dialplan functions");

Generated on Wed May 16 06:33:33 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6