Mon Oct 8 12:39:04 2012

Asterisk developer's documentation


res_config_sqlite.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2006, Proformatique
00005  *
00006  * Written by Richard Braun <rbraun@proformatique.com>
00007  *
00008  * Based on res_sqlite3 by Anthony Minessale II,
00009  * and res_config_mysql by Matthew Boehm
00010  *
00011  * See http://www.asterisk.org for more information about
00012  * the Asterisk project. Please do not directly contact
00013  * any of the maintainers of this project for assistance;
00014  * the project provides a web site, mailing lists and IRC
00015  * channels for your use.
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*!
00023  * \page res_config_sqlite
00024  *
00025  * \section intro_sec Presentation
00026  *
00027  * res_config_sqlite is a module for the Asterisk Open Source PBX to
00028  * support SQLite 2 databases. It can be used to fetch configuration
00029  * from a database (static configuration files and/or using the Asterisk
00030  * RealTime Architecture - ARA).  It can also be used to log CDR entries. 
00031  * Note that Asterisk already comes with a module named cdr_sqlite.
00032  * There are two reasons for including it in res_config_sqlite:
00033  * the first is that rewriting it was a training to learn how to write a
00034  * simple module for Asterisk, the other is to have the same database open for
00035  * all kinds of operations, which improves reliability and performance.
00036  *
00037  * \section conf_sec Configuration
00038  *
00039  * The main configuration file is res_config_sqlite.conf. It must be readable or
00040  * res_config_sqlite will fail to start. It is suggested to use the sample file
00041  * in this package as a starting point. The file has only one section
00042  * named <code>general</code>. Here are the supported parameters :
00043  *
00044  * <dl>
00045  * <dt><code>dbfile</code></dt>
00046  * <dd>The absolute path to the SQLite database (the file can be non existent,
00047  *       res_config_sqlite will create it if it has the appropriate rights)</dd>
00048  * <dt><code>config_table</code></dt>
00049  * <dd>The table used for static configuration</dd>
00050  * <dt><code>cdr_table</code></dt>
00051  * <dd>The table used to store CDR entries (if ommitted, CDR support is
00052  *       disabled)</dd>
00053  * </dl>
00054  *
00055  * To use res_config_sqlite for static and/or RealTime configuration, refer to the
00056  * Asterisk documentation. The file tables.sql can be used to create the
00057  * needed tables.
00058  *
00059  * \section status_sec Driver status
00060  *
00061  * The CLI command <code>show sqlite status</code> returns status information
00062  * about the running driver.
00063  *
00064  * \section credits_sec Credits
00065  *
00066  * res_config_sqlite was developed by Richard Braun at the Proformatique company.
00067  */
00068 
00069 /*!
00070  * \file
00071  * \brief res_config_sqlite module.
00072  */
00073 
00074 /*** MODULEINFO
00075    <depend>sqlite</depend>
00076    <support_level>extended</support_level>
00077  ***/
00078 
00079 #include "asterisk.h"
00080 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 361471 $")
00081 
00082 #include <sqlite.h>
00083 
00084 #include "asterisk/logger.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/pbx.h"
00087 #include "asterisk/cdr.h"
00088 #include "asterisk/cli.h"
00089 #include "asterisk/lock.h"
00090 #include "asterisk/config.h"
00091 #include "asterisk/module.h"
00092 #include "asterisk/linkedlists.h"
00093 
00094 #define MACRO_BEGIN  do {
00095 #define MACRO_END } while (0)
00096 
00097 #define RES_CONFIG_SQLITE_NAME "res_config_sqlite"
00098 #define RES_CONFIG_SQLITE_DRIVER "sqlite"
00099 #define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2"
00100 #define RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf"
00101 
00102 enum {
00103    RES_CONFIG_SQLITE_CONFIG_ID,
00104    RES_CONFIG_SQLITE_CONFIG_CAT_METRIC,
00105    RES_CONFIG_SQLITE_CONFIG_VAR_METRIC,
00106    RES_CONFIG_SQLITE_CONFIG_COMMENTED,
00107    RES_CONFIG_SQLITE_CONFIG_FILENAME,
00108    RES_CONFIG_SQLITE_CONFIG_CATEGORY,
00109    RES_CONFIG_SQLITE_CONFIG_VAR_NAME,
00110    RES_CONFIG_SQLITE_CONFIG_VAR_VAL,
00111    RES_CONFIG_SQLITE_CONFIG_COLUMNS,
00112 };
00113 
00114 #define SET_VAR(config, to, from)         \
00115 MACRO_BEGIN                \
00116    int __error;               \
00117                      \
00118    __error = set_var(&to, #to, from->value); \
00119                      \
00120    if (__error) {             \
00121       ast_config_destroy(config);      \
00122       unload_config();        \
00123       return 1;            \
00124    }                 \
00125 MACRO_END
00126 
00127 AST_THREADSTORAGE(sql_buf);
00128 AST_THREADSTORAGE(where_buf);
00129 
00130 /*!
00131  * Maximum number of loops before giving up executing a query. Calls to
00132  * sqlite_xxx() functions which can return SQLITE_BUSY
00133  * are enclosed by RES_CONFIG_SQLITE_BEGIN and RES_CONFIG_SQLITE_END, e.g.
00134  * <pre>
00135  * char *errormsg;
00136  * int error;
00137  *
00138  * RES_CONFIG_SQLITE_BEGIN
00139  *  error = sqlite_exec(db, query, NULL, NULL, &errormsg);
00140  * RES_CONFIG_SQLITE_END(error)
00141  *
00142  * if (error)
00143  *  ...;
00144  * </pre>
00145  */
00146 #define RES_CONFIG_SQLITE_MAX_LOOPS 10
00147 
00148 /*!
00149  * Macro used before executing a query.
00150  *
00151  * \see RES_CONFIG_SQLITE_MAX_LOOPS.
00152  */
00153 #define RES_CONFIG_SQLITE_BEGIN                 \
00154 MACRO_BEGIN                      \
00155    int __i;                   \
00156                            \
00157    for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++)  {
00158 
00159 /*!
00160  * Macro used after executing a query.
00161  *
00162  * \see RES_CONFIG_SQLITE_MAX_LOOPS.
00163  */
00164 #define RES_CONFIG_SQLITE_END(error)               \
00165       if (error != SQLITE_BUSY)  \
00166          break;                  \
00167       usleep(1000);                 \
00168    }                       \
00169 MACRO_END;
00170 
00171 /*!
00172  * Structure sent to the SQLite callback function for static configuration.
00173  *
00174  * \see add_cfg_entry()
00175  */
00176 struct cfg_entry_args {
00177    struct ast_config *cfg;
00178    struct ast_category *cat;
00179    char *cat_name;
00180    struct ast_flags flags;
00181    const char *who_asked;
00182 };
00183 
00184 /*!
00185  * Structure sent to the SQLite callback function for RealTime configuration.
00186  *
00187  * \see add_rt_cfg_entry()
00188  */
00189 struct rt_cfg_entry_args {
00190    struct ast_variable *var;
00191    struct ast_variable *last;
00192 };
00193 
00194 /*!
00195  * Structure sent to the SQLite callback function for RealTime configuration
00196  * (realtime_multi_handler()).
00197  *
00198  * \see add_rt_multi_cfg_entry()
00199  */
00200 struct rt_multi_cfg_entry_args {
00201    struct ast_config *cfg;
00202    char *initfield;
00203 };
00204 
00205 /*!
00206  * \brief Allocate a variable.
00207  * \param var the address of the variable to set (it will be allocated)
00208  * \param name the name of the variable (for error handling)
00209  * \param value the value to store in var
00210  * \retval 0 on success
00211  * \retval 1 if an allocation error occurred
00212  */
00213 static int set_var(char **var, const char *name, const char *value);
00214 
00215 /*!
00216  * \brief Load the configuration file.
00217  * \see unload_config()
00218  *
00219  * This function sets dbfile, config_table, and cdr_table. It calls
00220  * check_vars() before returning, and unload_config() if an error occurred.
00221  *
00222  * \retval 0 on success
00223  * \retval 1 if an error occurred
00224  */
00225 static int load_config(void);
00226 
00227 /*!
00228  * \brief Free resources related to configuration.
00229  * \see load_config()
00230  */
00231 static void unload_config(void);
00232 
00233 /*!
00234  * \brief Asterisk callback function for CDR support.
00235  * \param cdr the CDR entry Asterisk sends us.
00236  *
00237  * Asterisk will call this function each time a CDR entry must be logged if
00238  * CDR support is enabled.
00239  *
00240  * \retval 0 on success
00241  * \retval 1 if an error occurred
00242  */
00243 static int cdr_handler(struct ast_cdr *cdr);
00244 
00245 /*!
00246  * \brief SQLite callback function for static configuration.
00247  *
00248  * This function is passed to the SQLite engine as a callback function to
00249  * parse a row and store it in a struct ast_config object. It relies on
00250  * resulting rows being sorted by category.
00251  *
00252  * \param arg a pointer to a struct cfg_entry_args object
00253  * \param argc number of columns
00254  * \param argv values in the row
00255  * \param columnNames names and types of the columns
00256  * \retval 0 on success
00257  * \retval 1 if an error occurred
00258  * \see cfg_entry_args
00259  * \see sql_get_config_table
00260  * \see config_handler()
00261  */
00262 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames);
00263 
00264 /*!
00265  * \brief Asterisk callback function for static configuration.
00266  *
00267  * Asterisk will call this function when it loads its static configuration,
00268  * which usually happens at startup and reload.
00269  *
00270  * \param database the database to use (ignored)
00271  * \param table the table to use
00272  * \param file the file to load from the database
00273  * \param cfg the struct ast_config object to use when storing variables
00274  * \param flags Optional flags.  Not used.
00275  * \param suggested_incl suggest include.
00276  * \param who_asked
00277  * \retval cfg object
00278  * \retval NULL if an error occurred
00279  * \see add_cfg_entry()
00280  */
00281 static struct ast_config * config_handler(const char *database, const char *table, const char *file,
00282    struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked);
00283 
00284 /*!
00285  * \brief Helper function to parse a va_list object into 2 dynamic arrays of
00286  * strings, parameters and values.
00287  *
00288  * ap must have the following format : param1 val1 param2 val2 param3 val3 ...
00289  * arguments will be extracted to create 2 arrays:
00290  *
00291  * <ul>
00292  * <li>params : param1 param2 param3 ...</li>
00293  * <li>vals : val1 val2 val3 ...</li>
00294  * </ul>
00295  *
00296  * The address of these arrays are stored in params_ptr and vals_ptr. It
00297  * is the responsibility of the caller to release the memory of these arrays.
00298  * It is considered an error that va_list has a null or odd number of strings.
00299  *
00300  * \param ap the va_list object to parse
00301  * \param params_ptr where the address of the params array is stored
00302  * \param vals_ptr where the address of the vals array is stored
00303  * \param warn
00304  * \retval the number of elements in the arrays (which have the same size).
00305  * \retval 0 if an error occurred.
00306  */
00307 static size_t get_params(va_list ap, const char ***params_ptr,
00308    const char ***vals_ptr, int warn);
00309 
00310 /*!
00311  * \brief SQLite callback function for RealTime configuration.
00312  *
00313  * This function is passed to the SQLite engine as a callback function to
00314  * parse a row and store it in a linked list of struct ast_variable objects.
00315  *
00316  * \param arg a pointer to a struct rt_cfg_entry_args object
00317  * \param argc number of columns
00318  * \param argv values in the row
00319  * \param columnNames names and types of the columns
00320  * \retval 0 on success.
00321  * \retval 1 if an error occurred.
00322  * \see rt_cfg_entry_args
00323  * \see realtime_handler()
00324  */
00325 static int add_rt_cfg_entry(void *arg, int argc, char **argv,
00326    char **columnNames);
00327 
00328 /*!
00329  * \brief Asterisk callback function for RealTime configuration.
00330  *
00331  * Asterisk will call this function each time it requires a variable
00332  * through the RealTime architecture. ap is a list of parameters and
00333  * values used to find a specific row, e.g one parameter "name" and
00334  * one value "123" so that the SQL query becomes <code>SELECT * FROM
00335  * table WHERE name = '123';</code>.
00336  *
00337  * \param database the database to use (ignored)
00338  * \param table the table to use
00339  * \param ap list of parameters and values to match
00340  *
00341  * \retval a linked list of struct ast_variable objects
00342  * \retval NULL if an error occurred
00343  * \see add_rt_cfg_entry()
00344  */
00345 static struct ast_variable * realtime_handler(const char *database,
00346    const char *table, va_list ap);
00347 
00348 /*!
00349  * \brief SQLite callback function for RealTime configuration.
00350  *
00351  * This function performs the same actions as add_rt_cfg_entry() except
00352  * that the rt_multi_cfg_entry_args structure is designed to store
00353  * categories in addition to variables.
00354  *
00355  * \param arg a pointer to a struct rt_multi_cfg_entry_args object
00356  * \param argc number of columns
00357  * \param argv values in the row
00358  * \param columnNames names and types of the columns
00359  * \retval 0 on success.
00360  * \retval 1 if an error occurred.
00361  * \see rt_multi_cfg_entry_args
00362  * \see realtime_multi_handler()
00363  */
00364 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv,
00365    char **columnNames);
00366 
00367 /*!
00368  * \brief Asterisk callback function for RealTime configuration.
00369  *
00370  * This function performs the same actions as realtime_handler() except
00371  * that it can store variables per category, and can return several
00372  * categories.
00373  *
00374  * \param database the database to use (ignored)
00375  * \param table the table to use
00376  * \param ap list of parameters and values to match
00377  * \retval a struct ast_config object storing categories and variables.
00378  * \retval NULL if an error occurred.
00379  *
00380  * \see add_rt_multi_cfg_entry()
00381  */
00382 static struct ast_config * realtime_multi_handler(const char *database,
00383    const char *table, va_list ap);
00384 
00385 /*!
00386  * \brief Asterisk callback function for RealTime configuration (variable
00387  * update).
00388  *
00389  * Asterisk will call this function each time a variable has been modified
00390  * internally and must be updated in the backend engine. keyfield and entity
00391  * are used to find the row to update, e.g. <code>UPDATE table SET ... WHERE
00392  * keyfield = 'entity';</code>. ap is a list of parameters and values with the
00393  * same format as the other realtime functions.
00394  *
00395  * \param database the database to use (ignored)
00396  * \param table the table to use
00397  * \param keyfield the column of the matching cell
00398  * \param entity the value of the matching cell
00399  * \param ap list of parameters and new values to update in the database
00400  * \retval the number of affected rows.
00401  * \retval -1 if an error occurred.
00402  */
00403 static int realtime_update_handler(const char *database, const char *table,
00404    const char *keyfield, const char *entity, va_list ap);
00405 static int realtime_update2_handler(const char *database, const char *table,
00406    va_list ap);
00407 
00408 /*!
00409  * \brief Asterisk callback function for RealTime configuration (variable
00410  * create/store).
00411  *
00412  * Asterisk will call this function each time a variable has been created
00413  * internally and must be stored in the backend engine.
00414  * are used to find the row to update, e.g. ap is a list of parameters and
00415  * values with the same format as the other realtime functions.
00416  *
00417  * \param database the database to use (ignored)
00418  * \param table the table to use
00419  * \param ap list of parameters and new values to insert into the database
00420  * \retval the rowid of inserted row.
00421  * \retval -1 if an error occurred.
00422  */
00423 static int realtime_store_handler(const char *database, const char *table,
00424    va_list ap);
00425 
00426 /*!
00427  * \brief Asterisk callback function for RealTime configuration (destroys
00428  * variable).
00429  *
00430  * Asterisk will call this function each time a variable has been destroyed
00431  * internally and must be removed from the backend engine. keyfield and entity
00432  * are used to find the row to delete, e.g. <code>DELETE FROM table WHERE
00433  * keyfield = 'entity';</code>. ap is a list of parameters and values with the
00434  * same format as the other realtime functions.
00435  *
00436  * \param database the database to use (ignored)
00437  * \param table the table to use
00438  * \param keyfield the column of the matching cell
00439  * \param entity the value of the matching cell
00440  * \param ap list of additional parameters for cell matching
00441  * \retval the number of affected rows.
00442  * \retval -1 if an error occurred.
00443  */
00444 static int realtime_destroy_handler(const char *database, const char *table,
00445    const char *keyfield, const char *entity, va_list ap);
00446 
00447 /*!
00448  * \brief Asterisk callback function for the CLI status command.
00449  *
00450  * \param e CLI command
00451  * \param cmd 
00452  * \param a CLI argument list
00453  * \return RESULT_SUCCESS
00454  */
00455 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
00456 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
00457 
00458 static int realtime_require_handler(const char *database, const char *table, va_list ap);
00459 static int realtime_unload_handler(const char *unused, const char *tablename);
00460 
00461 /*! The SQLite database object. */
00462 static sqlite *db;
00463 
00464 /*! Set to 1 if CDR support is enabled. */
00465 static int use_cdr;
00466 
00467 /*! Set to 1 if the CDR callback function was registered. */
00468 static int cdr_registered;
00469 
00470 /*! Set to 1 if the CLI status command callback function was registered. */
00471 static int cli_status_registered;
00472 
00473 /*! The path of the database file. */
00474 static char *dbfile;
00475 
00476 /*! The name of the static configuration table. */
00477 static char *config_table;
00478 
00479 /*! The name of the table used to store CDR entries. */
00480 static char *cdr_table;
00481 
00482 /*!
00483  * The structure specifying all callback functions used by Asterisk for static
00484  * and RealTime configuration.
00485  */
00486 static struct ast_config_engine sqlite_engine =
00487 {
00488    .name = RES_CONFIG_SQLITE_DRIVER,
00489    .load_func = config_handler,
00490    .realtime_func = realtime_handler,
00491    .realtime_multi_func = realtime_multi_handler,
00492    .store_func = realtime_store_handler,
00493    .destroy_func = realtime_destroy_handler,
00494    .update_func = realtime_update_handler,
00495    .update2_func = realtime_update2_handler,
00496    .require_func = realtime_require_handler,
00497    .unload_func = realtime_unload_handler,
00498 };
00499 
00500 /*!
00501  * The mutex used to prevent simultaneous access to the SQLite database.
00502  */
00503 AST_MUTEX_DEFINE_STATIC(mutex);
00504 
00505 /*!
00506  * Structure containing details and callback functions for the CLI status
00507  * command.
00508  */
00509 static struct ast_cli_entry cli_status[] = {
00510    AST_CLI_DEFINE(handle_cli_show_sqlite_status, "Show status information about the SQLite 2 driver"),
00511    AST_CLI_DEFINE(handle_cli_sqlite_show_tables, "Cached table information about the SQLite 2 driver"),
00512 };
00513 
00514 struct sqlite_cache_columns {
00515    char *name;
00516    char *type;
00517    unsigned char isint;    /*!< By definition, only INTEGER PRIMARY KEY is an integer; everything else is a string. */
00518    AST_RWLIST_ENTRY(sqlite_cache_columns) list;
00519 };
00520 
00521 struct sqlite_cache_tables {
00522    char *name;
00523    AST_RWLIST_HEAD(_columns, sqlite_cache_columns) columns;
00524    AST_RWLIST_ENTRY(sqlite_cache_tables) list;
00525 };
00526 
00527 static AST_RWLIST_HEAD_STATIC(sqlite_tables, sqlite_cache_tables);
00528 
00529 /*
00530  * Taken from Asterisk 1.2 cdr_sqlite.so.
00531  */
00532 
00533 /*! SQL query format to create the CDR table if non existent. */
00534 static char *sql_create_cdr_table =
00535 "CREATE TABLE '%q' (\n"
00536 "  id    INTEGER,\n"
00537 "  clid     VARCHAR(80) NOT NULL DEFAULT '',\n"
00538 "  src      VARCHAR(80) NOT NULL DEFAULT '',\n"
00539 "  dst      VARCHAR(80) NOT NULL DEFAULT '',\n"
00540 "  dcontext VARCHAR(80) NOT NULL DEFAULT '',\n"
00541 "  channel     VARCHAR(80) NOT NULL DEFAULT '',\n"
00542 "  dstchannel  VARCHAR(80) NOT NULL DEFAULT '',\n"
00543 "  lastapp     VARCHAR(80) NOT NULL DEFAULT '',\n"
00544 "  lastdata VARCHAR(80) NOT NULL DEFAULT '',\n"
00545 "  start    DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00546 "  answer      DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00547 "  end      DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00548 "  duration INT(11)     NOT NULL DEFAULT 0,\n"
00549 "  billsec     INT(11)     NOT NULL DEFAULT 0,\n"
00550 "  disposition VARCHAR(45) NOT NULL DEFAULT '',\n"
00551 "  amaflags INT(11)     NOT NULL DEFAULT 0,\n"
00552 "  accountcode VARCHAR(20) NOT NULL DEFAULT '',\n"
00553 "  uniqueid VARCHAR(32) NOT NULL DEFAULT '',\n"
00554 "  userfield   VARCHAR(255)   NOT NULL DEFAULT '',\n"
00555 "  PRIMARY KEY (id)\n"
00556 ");";
00557 
00558 /*!
00559  * SQL query format to describe the table structure
00560  */
00561 #define sql_table_structure "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'"
00562 
00563 /*!
00564  * SQL query format to fetch the static configuration of a file.
00565  * Rows must be sorted by category.
00566  *
00567  * \see add_cfg_entry()
00568  */
00569 #define sql_get_config_table \
00570    "SELECT *" \
00571    "  FROM '%q'" \
00572    "  WHERE filename = '%q' AND commented = 0" \
00573    "  ORDER BY cat_metric ASC, var_metric ASC;"
00574 
00575 static void free_table(struct sqlite_cache_tables *tblptr)
00576 {
00577    struct sqlite_cache_columns *col;
00578 
00579    /* Obtain a write lock to ensure there are no read locks outstanding */
00580    AST_RWLIST_WRLOCK(&(tblptr->columns));
00581    while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) {
00582       ast_free(col);
00583    }
00584    AST_RWLIST_UNLOCK(&(tblptr->columns));
00585    AST_RWLIST_HEAD_DESTROY(&(tblptr->columns));
00586    ast_free(tblptr);
00587 }
00588 
00589 static int find_table_cb(void *vtblptr, int argc, char **argv, char **columnNames)
00590 {
00591    struct sqlite_cache_tables *tblptr = vtblptr;
00592    char *sql = ast_strdupa(argv[0]), *start, *end, *type, *remainder;
00593    int i;
00594    AST_DECLARE_APP_ARGS(fie,
00595       AST_APP_ARG(ld)[100]; /* This means we support up to 100 columns per table */
00596    );
00597    struct sqlite_cache_columns *col;
00598 
00599    /* This is really fun.  We get to parse an SQL statement to figure out
00600     * what columns are in the table.
00601     */
00602    if ((start = strchr(sql, '(')) && (end = strrchr(sql, ')'))) {
00603       start++;
00604       *end = '\0';
00605    } else {
00606       /* Abort */
00607       return -1;
00608    }
00609 
00610    AST_STANDARD_APP_ARGS(fie, start);
00611    for (i = 0; i < fie.argc; i++) {
00612       fie.ld[i] = ast_skip_blanks(fie.ld[i]);
00613       ast_debug(5, "Found field: %s\n", fie.ld[i]);
00614       if (strncasecmp(fie.ld[i], "PRIMARY KEY", 11) == 0 && (start = strchr(fie.ld[i], '(')) && (end = strchr(fie.ld[i], ')'))) {
00615          *end = '\0';
00616          AST_RWLIST_TRAVERSE(&(tblptr->columns), col, list) {
00617             if (strcasecmp(start + 1, col->name) == 0 && strcasestr(col->type, "INTEGER")) {
00618                col->isint = 1;
00619             }
00620          }
00621          continue;
00622       }
00623       /* type delimiter could be any space character */
00624       for (type = fie.ld[i]; *type > 32; type++);
00625       *type++ = '\0';
00626       type = ast_skip_blanks(type);
00627       for (remainder = type; *remainder > 32; remainder++);
00628       *remainder = '\0';
00629       if (!(col = ast_calloc(1, sizeof(*col) + strlen(fie.ld[i]) + strlen(type) + 2))) {
00630          return -1;
00631       }
00632       col->name = (char *)col + sizeof(*col);
00633       col->type = (char *)col + sizeof(*col) + strlen(fie.ld[i]) + 1;
00634       strcpy(col->name, fie.ld[i]); /* SAFE */
00635       strcpy(col->type, type); /* SAFE */
00636       if (strcasestr(col->type, "INTEGER") && strcasestr(col->type, "PRIMARY KEY")) {
00637          col->isint = 1;
00638       }
00639       AST_LIST_INSERT_TAIL(&(tblptr->columns), col, list);
00640    }
00641    return 0;
00642 }
00643 
00644 static struct sqlite_cache_tables *find_table(const char *tablename)
00645 {
00646    struct sqlite_cache_tables *tblptr;
00647    int i, err;
00648    char *sql, *errstr = NULL;
00649 
00650    AST_RWLIST_RDLOCK(&sqlite_tables);
00651 
00652    for (i = 0; i < 2; i++) {
00653       AST_RWLIST_TRAVERSE(&sqlite_tables, tblptr, list) {
00654          if (strcmp(tblptr->name, tablename) == 0) {
00655             break;
00656          }
00657       }
00658       if (tblptr) {
00659          AST_RWLIST_RDLOCK(&(tblptr->columns));
00660          AST_RWLIST_UNLOCK(&sqlite_tables);
00661          return tblptr;
00662       }
00663 
00664       if (i == 0) {
00665          AST_RWLIST_UNLOCK(&sqlite_tables);
00666          AST_RWLIST_WRLOCK(&sqlite_tables);
00667       }
00668    }
00669 
00670    /* Table structure not cached; build the structure now */
00671    if (asprintf(&sql, sql_table_structure, tablename) < 0) {
00672       ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00673       sql = NULL;
00674    }
00675    if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) {
00676       AST_RWLIST_UNLOCK(&sqlite_tables);
00677       ast_log(LOG_ERROR, "Memory error.  Cannot cache table '%s'\n", tablename);
00678       return NULL;
00679    }
00680    tblptr->name = (char *)tblptr + sizeof(*tblptr);
00681    strcpy(tblptr->name, tablename); /* SAFE */
00682    AST_RWLIST_HEAD_INIT(&(tblptr->columns));
00683 
00684    ast_debug(1, "About to query table structure: %s\n", sql);
00685 
00686    ast_mutex_lock(&mutex);
00687    if ((err = sqlite_exec(db, sql, find_table_cb, tblptr, &errstr))) {
00688       ast_mutex_unlock(&mutex);
00689       ast_log(LOG_WARNING, "SQLite error %d: %s\n", err, errstr);
00690       ast_free(errstr);
00691       free_table(tblptr);
00692       AST_RWLIST_UNLOCK(&sqlite_tables);
00693       return NULL;
00694    }
00695    ast_mutex_unlock(&mutex);
00696 
00697    if (AST_LIST_EMPTY(&(tblptr->columns))) {
00698       free_table(tblptr);
00699       AST_RWLIST_UNLOCK(&sqlite_tables);
00700       return NULL;
00701    }
00702 
00703    AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list);
00704    AST_RWLIST_RDLOCK(&(tblptr->columns));
00705    AST_RWLIST_UNLOCK(&sqlite_tables);
00706    return tblptr;
00707 }
00708 
00709 #define release_table(a)   AST_RWLIST_UNLOCK(&((a)->columns))
00710 
00711 static int set_var(char **var, const char *name, const char *value)
00712 {
00713    if (*var)
00714       ast_free(*var);
00715 
00716    *var = ast_strdup(value);
00717 
00718    if (!*var) {
00719       ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name);
00720       return 1;
00721    }
00722 
00723    return 0;
00724 }
00725 
00726 static int check_vars(void)
00727 {
00728    if (!dbfile) {
00729       ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00730       return 1;
00731    }
00732 
00733    use_cdr = (cdr_table != NULL);
00734 
00735    return 0;
00736 }
00737 
00738 static int load_config(void)
00739 {
00740    struct ast_config *config;
00741    struct ast_variable *var;
00742    int error;
00743    struct ast_flags config_flags = { 0 };
00744 
00745    config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags);
00746 
00747    if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
00748       ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n");
00749       return 1;
00750    }
00751 
00752    for (var = ast_variable_browse(config, "general"); var; var = var->next) {
00753       if (!strcasecmp(var->name, "dbfile"))
00754          SET_VAR(config, dbfile, var);
00755       else if (!strcasecmp(var->name, "config_table"))
00756          SET_VAR(config, config_table, var);
00757       else if (!strcasecmp(var->name, "cdr_table")) {
00758          SET_VAR(config, cdr_table, var);
00759       } else
00760          ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name);
00761    }
00762 
00763    ast_config_destroy(config);
00764    error = check_vars();
00765 
00766    if (error) {
00767       unload_config();
00768       return 1;
00769    }
00770 
00771    return 0;
00772 }
00773 
00774 static void unload_config(void)
00775 {
00776    struct sqlite_cache_tables *tbl;
00777    ast_free(dbfile);
00778    dbfile = NULL;
00779    ast_free(config_table);
00780    config_table = NULL;
00781    ast_free(cdr_table);
00782    cdr_table = NULL;
00783    AST_RWLIST_WRLOCK(&sqlite_tables);
00784    while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) {
00785       free_table(tbl);
00786    }
00787    AST_RWLIST_UNLOCK(&sqlite_tables);
00788 }
00789 
00790 static int cdr_handler(struct ast_cdr *cdr)
00791 {
00792    char *errormsg = NULL, *tmp, workspace[500];
00793    int error, scannum;
00794    struct sqlite_cache_tables *tbl = find_table(cdr_table);
00795    struct sqlite_cache_columns *col;
00796    struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16);
00797    int first = 1;
00798 
00799    if (!tbl) {
00800       ast_log(LOG_WARNING, "No such table: %s\n", cdr_table);
00801       return -1;
00802    }
00803 
00804    ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table);
00805    ast_str_set(&sql2, 0, ") VALUES (");
00806 
00807    AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
00808       if (col->isint) {
00809          ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1);
00810          if (!tmp) {
00811             continue;
00812          }
00813          if (sscanf(tmp, "%30d", &scannum) == 1) {
00814             ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name);
00815             ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", scannum);
00816          }
00817       } else {
00818          ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0);
00819          if (!tmp) {
00820             continue;
00821          }
00822          ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name);
00823          tmp = sqlite_mprintf("%Q", tmp);
00824          ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", tmp);
00825          sqlite_freemem(tmp);
00826       }
00827       first = 0;
00828    }
00829    release_table(tbl);
00830 
00831    ast_str_append(&sql1, 0, "%s)", ast_str_buffer(sql2));
00832    ast_free(sql2);
00833 
00834    ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql1));
00835 
00836    ast_mutex_lock(&mutex);
00837 
00838    RES_CONFIG_SQLITE_BEGIN
00839       error = sqlite_exec(db, ast_str_buffer(sql1), NULL, NULL, &errormsg);
00840    RES_CONFIG_SQLITE_END(error)
00841 
00842    ast_mutex_unlock(&mutex);
00843 
00844    ast_free(sql1);
00845 
00846    if (error) {
00847       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00848       sqlite_freemem(errormsg);
00849       return 1;
00850    }
00851    sqlite_freemem(errormsg);
00852 
00853    return 0;
00854 }
00855 
00856 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00857 {
00858    struct cfg_entry_args *args;
00859    struct ast_variable *var;
00860 
00861    if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) {
00862       ast_log(LOG_WARNING, "Corrupt table\n");
00863       return 1;
00864    }
00865 
00866    args = arg;
00867 
00868    if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) {
00869       struct ast_config *cfg;
00870       char *val;
00871 
00872       val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL];
00873       cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked);
00874 
00875       if (!cfg) {
00876          ast_log(LOG_WARNING, "Unable to include %s\n", val);
00877          return 1;
00878       } else {
00879          args->cfg = cfg;
00880          return 0;
00881       }
00882    }
00883 
00884    if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) {
00885       args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999);
00886 
00887       if (!args->cat) {
00888          ast_log(LOG_WARNING, "Unable to allocate category\n");
00889          return 1;
00890       }
00891 
00892       ast_free(args->cat_name);
00893       args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]);
00894 
00895       if (!args->cat_name) {
00896          ast_category_destroy(args->cat);
00897          return 1;
00898       }
00899 
00900       ast_category_append(args->cfg, args->cat);
00901    }
00902 
00903    var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], "");
00904 
00905    if (!var) {
00906       ast_log(LOG_WARNING, "Unable to allocate variable\n");
00907       return 1;
00908    }
00909 
00910    ast_variable_append(args->cat, var);
00911 
00912    return 0;
00913 }
00914 
00915 static struct ast_config *config_handler(const char *database, const char *table, const char *file,
00916    struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
00917 {
00918    struct cfg_entry_args args;
00919    char *query, *errormsg = NULL;
00920    int error;
00921 
00922    if (!config_table) {
00923       if (!table) {
00924          ast_log(LOG_ERROR, "Table name unspecified\n");
00925          return NULL;
00926       }
00927    } else
00928       table = config_table;
00929 
00930    query = sqlite_mprintf(sql_get_config_table, table, file);
00931 
00932    if (!query) {
00933       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00934       return NULL;
00935    }
00936 
00937    ast_debug(1, "SQL query: %s\n", query);
00938    args.cfg = cfg;
00939    args.cat = NULL;
00940    args.cat_name = NULL;
00941    args.flags = flags;
00942    args.who_asked = who_asked;
00943 
00944    ast_mutex_lock(&mutex);
00945 
00946    RES_CONFIG_SQLITE_BEGIN
00947       error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg);
00948    RES_CONFIG_SQLITE_END(error)
00949 
00950    ast_mutex_unlock(&mutex);
00951 
00952    ast_free(args.cat_name);
00953    sqlite_freemem(query);
00954 
00955    if (error) {
00956       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00957       sqlite_freemem(errormsg);
00958       return NULL;
00959    }
00960    sqlite_freemem(errormsg);
00961 
00962    return cfg;
00963 }
00964 
00965 static size_t get_params(va_list ap, const char ***params_ptr, const char ***vals_ptr, int warn)
00966 {
00967    const char **tmp, *param, *val, **params, **vals;
00968    size_t params_count;
00969 
00970    params = NULL;
00971    vals = NULL;
00972    params_count = 0;
00973 
00974    while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) {
00975       if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) {
00976          ast_free(params);
00977          ast_free(vals);
00978          return 0;
00979       }
00980       params = tmp;
00981 
00982       if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) {
00983          ast_free(params);
00984          ast_free(vals);
00985          return 0;
00986       }
00987       vals = tmp;
00988 
00989       params[params_count] = param;
00990       vals[params_count] = val;
00991       params_count++;
00992    }
00993 
00994    if (params_count > 0) {
00995       *params_ptr = params;
00996       *vals_ptr = vals;
00997    } else if (warn) {
00998       ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n");
00999    }
01000 
01001    return params_count;
01002 }
01003 
01004 static int add_rt_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
01005 {
01006    struct rt_cfg_entry_args *args;
01007    struct ast_variable *var;
01008    int i;
01009 
01010    args = arg;
01011 
01012    for (i = 0; i < argc; i++) {
01013       if (!argv[i])
01014          continue;
01015 
01016       if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
01017          return 1;
01018 
01019       if (!args->var)
01020          args->var = var;
01021 
01022       if (!args->last)
01023          args->last = var;
01024       else {
01025          args->last->next = var;
01026          args->last = var;
01027       }
01028    }
01029 
01030    return 0;
01031 }
01032 
01033 static struct ast_variable * realtime_handler(const char *database, const char *table, va_list ap)
01034 {
01035    char *query, *errormsg = NULL, *op, *tmp_str;
01036    struct rt_cfg_entry_args args;
01037    const char **params, **vals;
01038    size_t params_count;
01039    int error;
01040 
01041    if (!table) {
01042       ast_log(LOG_WARNING, "Table name unspecified\n");
01043       return NULL;
01044    }
01045 
01046    params_count = get_params(ap, &params, &vals, 1);
01047 
01048    if (params_count == 0)
01049       return NULL;
01050 
01051    op = (strchr(params[0], ' ') == NULL) ? " =" : "";
01052 
01053 /* \cond DOXYGEN_CAN_PARSE_THIS */
01054 #undef QUERY
01055 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'"
01056 /* \endcond */
01057 
01058    query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", params[0], op, vals[0]);
01059 
01060    if (!query) {
01061       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01062       ast_free(params);
01063       ast_free(vals);
01064       return NULL;
01065    }
01066 
01067    if (params_count > 1) {
01068       size_t i;
01069 
01070       for (i = 1; i < params_count; i++) {
01071          op = (strchr(params[i], ' ') == NULL) ? " =" : "";
01072          tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01073          sqlite_freemem(query);
01074 
01075          if (!tmp_str) {
01076             ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01077             ast_free(params);
01078             ast_free(vals);
01079             return NULL;
01080          }
01081 
01082          query = tmp_str;
01083       }
01084    }
01085 
01086    ast_free(params);
01087    ast_free(vals);
01088 
01089    tmp_str = sqlite_mprintf("%s LIMIT 1;", query);
01090    sqlite_freemem(query);
01091 
01092    if (!tmp_str) {
01093       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01094       return NULL;
01095    }
01096 
01097    query = tmp_str;
01098    ast_debug(1, "SQL query: %s\n", query);
01099    args.var = NULL;
01100    args.last = NULL;
01101 
01102    ast_mutex_lock(&mutex);
01103 
01104    RES_CONFIG_SQLITE_BEGIN
01105       error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg);
01106    RES_CONFIG_SQLITE_END(error)
01107 
01108    ast_mutex_unlock(&mutex);
01109 
01110    sqlite_freemem(query);
01111 
01112    if (error) {
01113       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01114       sqlite_freemem(errormsg);
01115       ast_variables_destroy(args.var);
01116       return NULL;
01117    }
01118    sqlite_freemem(errormsg);
01119 
01120    return args.var;
01121 }
01122 
01123 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
01124 {
01125    struct rt_multi_cfg_entry_args *args;
01126    struct ast_category *cat;
01127    struct ast_variable *var;
01128    char *cat_name;
01129    size_t i;
01130 
01131    args = arg;
01132    cat_name = NULL;
01133 
01134    /*
01135     * cat_name should always be set here, since initfield is forged from
01136     * params[0] in realtime_multi_handler(), which is a search parameter
01137     * of the SQL query.
01138     */
01139    for (i = 0; i < argc; i++) {
01140       if (!strcmp(args->initfield, columnNames[i]))
01141          cat_name = argv[i];
01142    }
01143 
01144    if (!cat_name) {
01145       ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
01146       return 1;
01147    }
01148 
01149    if (!(cat = ast_category_new(cat_name, "", 99999))) {
01150       ast_log(LOG_WARNING, "Unable to allocate category\n");
01151       return 1;
01152    }
01153 
01154    ast_category_append(args->cfg, cat);
01155 
01156    for (i = 0; i < argc; i++) {
01157       if (!argv[i]) {
01158          continue;
01159       }
01160 
01161       if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01162          ast_log(LOG_WARNING, "Unable to allocate variable\n");
01163          return 1;
01164       }
01165 
01166       ast_variable_append(cat, var);
01167    }
01168 
01169    return 0;
01170 }
01171 
01172 static struct ast_config *realtime_multi_handler(const char *database,
01173    const char *table, va_list ap)
01174 {
01175    char *query, *errormsg = NULL, *op, *tmp_str, *initfield;
01176    struct rt_multi_cfg_entry_args args;
01177    const char **params, **vals;
01178    struct ast_config *cfg;
01179    size_t params_count;
01180    int error;
01181 
01182    if (!table) {
01183       ast_log(LOG_WARNING, "Table name unspecified\n");
01184       return NULL;
01185    }
01186 
01187    if (!(cfg = ast_config_new())) {
01188       ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01189       return NULL;
01190    }
01191 
01192    if (!(params_count = get_params(ap, &params, &vals, 1))) {
01193       ast_config_destroy(cfg);
01194       return NULL;
01195    }
01196 
01197    if (!(initfield = ast_strdup(params[0]))) {
01198       ast_config_destroy(cfg);
01199       ast_free(params);
01200       ast_free(vals);
01201       return NULL;
01202    }
01203 
01204    tmp_str = strchr(initfield, ' ');
01205 
01206    if (tmp_str)
01207       *tmp_str = '\0';
01208 
01209    op = (!strchr(params[0], ' ')) ? " =" : "";
01210 
01211    /*
01212     * Asterisk sends us an already escaped string when searching for
01213     * "exten LIKE" (uh!). Handle it separately.
01214     */
01215    tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0];
01216 
01217 /* \cond DOXYGEN_CAN_PARSE_THIS */
01218 #undef QUERY
01219 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'"
01220 /* \endcond */
01221 
01222    if (!(query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", params[0], op, tmp_str))) {
01223       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01224       ast_config_destroy(cfg);
01225       ast_free(params);
01226       ast_free(vals);
01227       ast_free(initfield);
01228       return NULL;
01229    }
01230 
01231    if (params_count > 1) {
01232       size_t i;
01233 
01234       for (i = 1; i < params_count; i++) {
01235          op = (!strchr(params[i], ' ')) ? " =" : "";
01236          tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01237          sqlite_freemem(query);
01238 
01239          if (!tmp_str) {
01240             ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01241             ast_config_destroy(cfg);
01242             ast_free(params);
01243             ast_free(vals);
01244             ast_free(initfield);
01245             return NULL;
01246          }
01247 
01248          query = tmp_str;
01249       }
01250    }
01251 
01252    ast_free(params);
01253    ast_free(vals);
01254 
01255    if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01256       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01257       sqlite_freemem(query);
01258       ast_config_destroy(cfg);
01259       ast_free(initfield);
01260       return NULL;
01261    }
01262 
01263    sqlite_freemem(query);
01264    query = tmp_str;
01265    ast_debug(1, "SQL query: %s\n", query);
01266    args.cfg = cfg;
01267    args.initfield = initfield;
01268 
01269    ast_mutex_lock(&mutex);
01270 
01271    RES_CONFIG_SQLITE_BEGIN
01272       error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01273    RES_CONFIG_SQLITE_END(error)
01274 
01275    ast_mutex_unlock(&mutex);
01276 
01277    sqlite_freemem(query);
01278    ast_free(initfield);
01279 
01280    if (error) {
01281       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01282       sqlite_freemem(errormsg);
01283       ast_config_destroy(cfg);
01284       return NULL;
01285    }
01286    sqlite_freemem(errormsg);
01287 
01288    return cfg;
01289 }
01290 
01291 static int realtime_update_handler(const char *database, const char *table,
01292    const char *keyfield, const char *entity, va_list ap)
01293 {
01294    char *query, *errormsg = NULL, *tmp_str;
01295    const char **params, **vals;
01296    size_t params_count;
01297    int error, rows_num;
01298 
01299    if (!table) {
01300       ast_log(LOG_WARNING, "Table name unspecified\n");
01301       return -1;
01302    }
01303 
01304    if (!(params_count = get_params(ap, &params, &vals, 1)))
01305       return -1;
01306 
01307 /* \cond DOXYGEN_CAN_PARSE_THIS */
01308 #undef QUERY
01309 #define QUERY "UPDATE '%q' SET %q = '%q'"
01310 /* \endcond */
01311 
01312    if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) {
01313       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01314       ast_free(params);
01315       ast_free(vals);
01316       return -1;
01317    }
01318 
01319    if (params_count > 1) {
01320       size_t i;
01321 
01322       for (i = 1; i < params_count; i++) {
01323          tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]);
01324          sqlite_freemem(query);
01325 
01326          if (!tmp_str) {
01327             ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01328             ast_free(params);
01329             ast_free(vals);
01330             return -1;
01331          }
01332 
01333          query = tmp_str;
01334       }
01335    }
01336 
01337    ast_free(params);
01338    ast_free(vals);
01339 
01340    if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01341       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01342       sqlite_freemem(query);
01343       return -1;
01344    }
01345 
01346    sqlite_freemem(query);
01347    query = tmp_str;
01348    ast_debug(1, "SQL query: %s\n", query);
01349 
01350    ast_mutex_lock(&mutex);
01351 
01352    RES_CONFIG_SQLITE_BEGIN
01353       error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01354    RES_CONFIG_SQLITE_END(error)
01355 
01356    if (!error)
01357       rows_num = sqlite_changes(db);
01358    else
01359       rows_num = -1;
01360 
01361    ast_mutex_unlock(&mutex);
01362 
01363    sqlite_freemem(query);
01364 
01365    if (error) {
01366       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01367    }
01368    sqlite_freemem(errormsg);
01369 
01370    return rows_num;
01371 }
01372 
01373 static int realtime_update2_handler(const char *database, const char *table,
01374    va_list ap)
01375 {
01376    char *errormsg = NULL, *tmp1, *tmp2;
01377    int error, rows_num, first = 1;
01378    struct ast_str *sql = ast_str_thread_get(&sql_buf, 100);
01379    struct ast_str *where = ast_str_thread_get(&where_buf, 100);
01380    const char *param, *value;
01381 
01382    if (!table) {
01383       ast_log(LOG_WARNING, "Table name unspecified\n");
01384       return -1;
01385    }
01386 
01387    if (!sql) {
01388       return -1;
01389    }
01390 
01391    ast_str_set(&sql, 0, "UPDATE %s SET", table);
01392    ast_str_set(&where, 0, " WHERE");
01393 
01394    while ((param = va_arg(ap, const char *))) {
01395       value = va_arg(ap, const char *);
01396       ast_str_append(&where, 0, "%s %s = %s",
01397          first ? "" : " AND",
01398          tmp1 = sqlite_mprintf("%q", param),
01399          tmp2 = sqlite_mprintf("%Q", value));
01400       sqlite_freemem(tmp1);
01401       sqlite_freemem(tmp2);
01402       first = 0;
01403    }
01404 
01405    if (first) {
01406       ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database);
01407       return -1;
01408    }
01409 
01410    first = 1;
01411    while ((param = va_arg(ap, const char *))) {
01412       value = va_arg(ap, const char *);
01413       ast_str_append(&sql, 0, "%s %s = %s",
01414          first ? "" : ",",
01415          tmp1 = sqlite_mprintf("%q", param),
01416          tmp2 = sqlite_mprintf("%Q", value));
01417       sqlite_freemem(tmp1);
01418       sqlite_freemem(tmp2);
01419       first = 0;
01420    }
01421 
01422    ast_str_append(&sql, 0, " %s", ast_str_buffer(where));
01423    ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql));
01424 
01425    ast_mutex_lock(&mutex);
01426 
01427    RES_CONFIG_SQLITE_BEGIN
01428       error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg);
01429    RES_CONFIG_SQLITE_END(error)
01430 
01431    if (!error) {
01432       rows_num = sqlite_changes(db);
01433    } else {
01434       rows_num = -1;
01435    }
01436 
01437    ast_mutex_unlock(&mutex);
01438 
01439    if (error) {
01440       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01441    }
01442    sqlite_freemem(errormsg);
01443 
01444    return rows_num;
01445 }
01446 
01447 static int realtime_store_handler(const char *database, const char *table, va_list ap)
01448 {
01449    char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01450    const char **params, **vals;
01451    size_t params_count;
01452    int error, rows_id;
01453    size_t i;
01454 
01455    if (!table) {
01456       ast_log(LOG_WARNING, "Table name unspecified\n");
01457       return -1;
01458    }
01459 
01460    if (!(params_count = get_params(ap, &params, &vals, 1)))
01461       return -1;
01462 
01463 /* \cond DOXYGEN_CAN_PARSE_THIS */
01464 #undef QUERY
01465 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01466 /* \endcond */
01467 
01468    for (i = 0; i < params_count; i++) {
01469       if ( tmp_keys2 ) {
01470          tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]);
01471          sqlite_freemem(tmp_keys2);
01472       } else {
01473          tmp_keys = sqlite_mprintf("%q", params[i]);
01474       }
01475       if (!tmp_keys) {
01476          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01477          sqlite_freemem(tmp_vals);
01478          ast_free(params);
01479          ast_free(vals);
01480          return -1;
01481       }
01482 
01483       if ( tmp_vals2 ) {
01484          tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, vals[i]);
01485          sqlite_freemem(tmp_vals2);
01486       } else {
01487          tmp_vals = sqlite_mprintf("'%q'", vals[i]);
01488       }
01489       if (!tmp_vals) {
01490          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01491          sqlite_freemem(tmp_keys);
01492          ast_free(params);
01493          ast_free(vals);
01494          return -1;
01495       }
01496 
01497 
01498       tmp_keys2 = tmp_keys;
01499       tmp_vals2 = tmp_vals;
01500    }
01501 
01502    ast_free(params);
01503    ast_free(vals);
01504 
01505    if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01506       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01507       sqlite_freemem(tmp_keys);
01508       sqlite_freemem(tmp_vals);
01509       return -1;
01510    }
01511 
01512    sqlite_freemem(tmp_keys);
01513    sqlite_freemem(tmp_vals);
01514 
01515    ast_debug(1, "SQL query: %s\n", tmp_str);
01516 
01517    ast_mutex_lock(&mutex);
01518 
01519    RES_CONFIG_SQLITE_BEGIN
01520       error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01521    RES_CONFIG_SQLITE_END(error)
01522 
01523    if (!error) {
01524       rows_id = sqlite_last_insert_rowid(db);
01525    } else {
01526       rows_id = -1;
01527    }
01528 
01529    ast_mutex_unlock(&mutex);
01530 
01531    sqlite_freemem(tmp_str);
01532 
01533    if (error) {
01534       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01535    }
01536    sqlite_freemem(errormsg);
01537 
01538    return rows_id;
01539 }
01540 
01541 static int realtime_destroy_handler(const char *database, const char *table,
01542    const char *keyfield, const char *entity, va_list ap)
01543 {
01544    char *query, *errormsg = NULL, *tmp_str;
01545    const char **params = NULL, **vals = NULL;
01546    size_t params_count;
01547    int error, rows_num;
01548    size_t i;
01549 
01550    if (!table) {
01551       ast_log(LOG_WARNING, "Table name unspecified\n");
01552       return -1;
01553    }
01554 
01555    params_count = get_params(ap, &params, &vals, 0);
01556 
01557 /* \cond DOXYGEN_CAN_PARSE_THIS */
01558 #undef QUERY
01559 #define QUERY "DELETE FROM '%q' WHERE"
01560 /* \endcond */
01561 
01562    if (!(query = sqlite_mprintf(QUERY, table))) {
01563       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01564       ast_free(params);
01565       ast_free(vals);
01566       return -1;
01567    }
01568 
01569    for (i = 0; i < params_count; i++) {
01570       tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01571       sqlite_freemem(query);
01572 
01573       if (!tmp_str) {
01574          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01575          ast_free(params);
01576          ast_free(vals);
01577          return -1;
01578       }
01579 
01580       query = tmp_str;
01581    }
01582 
01583    ast_free(params);
01584    ast_free(vals);
01585    if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01586       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01587       sqlite_freemem(query);
01588       return -1;
01589    }
01590    sqlite_freemem(query);
01591    query = tmp_str;
01592    ast_debug(1, "SQL query: %s\n", query);
01593 
01594    ast_mutex_lock(&mutex);
01595 
01596    RES_CONFIG_SQLITE_BEGIN
01597       error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01598    RES_CONFIG_SQLITE_END(error)
01599 
01600    if (!error) {
01601       rows_num = sqlite_changes(db);
01602    } else {
01603       rows_num = -1;
01604    }
01605 
01606    ast_mutex_unlock(&mutex);
01607 
01608    sqlite_freemem(query);
01609 
01610    if (error) {
01611       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01612    }
01613    sqlite_freemem(errormsg);
01614 
01615    return rows_num;
01616 }
01617 
01618 static int realtime_require_handler(const char *unused, const char *tablename, va_list ap)
01619 {
01620    struct sqlite_cache_tables *tbl = find_table(tablename);
01621    struct sqlite_cache_columns *col;
01622    char *elm;
01623    int type, res = 0;
01624 
01625    if (!tbl) {
01626       return -1;
01627    }
01628 
01629    while ((elm = va_arg(ap, char *))) {
01630       type = va_arg(ap, require_type);
01631       va_arg(ap, int);
01632       /* Check if the field matches the criteria */
01633       AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01634          if (strcmp(col->name, elm) == 0) {
01635             /* SQLite only has two types - the 32-bit integer field that
01636              * is the key column, and everything else (everything else
01637              * being a string).
01638              */
01639             if (col->isint && !ast_rq_is_int(type)) {
01640                ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01641                res = -1;
01642             }
01643             break;
01644          }
01645       }
01646       if (!col) {
01647          ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01648       }
01649    }
01650    AST_RWLIST_UNLOCK(&(tbl->columns));
01651    return res;
01652 }
01653 
01654 static int realtime_unload_handler(const char *unused, const char *tablename)
01655 {
01656    struct sqlite_cache_tables *tbl;
01657    AST_RWLIST_WRLOCK(&sqlite_tables);
01658    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) {
01659       if (!strcasecmp(tbl->name, tablename)) {
01660          AST_RWLIST_REMOVE_CURRENT(list);
01661          free_table(tbl);
01662       }
01663    }
01664    AST_RWLIST_TRAVERSE_SAFE_END
01665    AST_RWLIST_UNLOCK(&sqlite_tables);
01666    return 0;
01667 }
01668 
01669 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01670 {
01671    switch (cmd) {
01672    case CLI_INIT:
01673       e->command = "sqlite show status";
01674       e->usage =
01675          "Usage: sqlite show status\n"
01676          "       Show status information about the SQLite 2 driver\n";
01677       return NULL;
01678    case CLI_GENERATE:
01679       return NULL;
01680    }
01681 
01682    if (a->argc != 3)
01683       return CLI_SHOWUSAGE;
01684 
01685    ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01686    ast_cli(a->fd, "config_table: ");
01687 
01688    if (!config_table)
01689       ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01690    else
01691       ast_cli(a->fd, "%s\n", config_table);
01692 
01693    ast_cli(a->fd, "cdr_table: ");
01694 
01695    if (!cdr_table)
01696       ast_cli(a->fd, "unspecified, CDR support disabled\n");
01697    else
01698       ast_cli(a->fd, "%s\n", cdr_table);
01699 
01700    return CLI_SUCCESS;
01701 }
01702 
01703 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01704 {
01705    struct sqlite_cache_tables *tbl;
01706    struct sqlite_cache_columns *col;
01707    int found = 0;
01708 
01709    switch (cmd) {
01710    case CLI_INIT:
01711       e->command = "sqlite show tables";
01712       e->usage =
01713          "Usage: sqlite show tables\n"
01714          "       Show table information about the SQLite 2 driver\n";
01715       return NULL;
01716    case CLI_GENERATE:
01717       return NULL;
01718    }
01719 
01720    if (a->argc != 3)
01721       return CLI_SHOWUSAGE;
01722 
01723    AST_RWLIST_RDLOCK(&sqlite_tables);
01724    AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01725       found++;
01726       ast_cli(a->fd, "Table %s:\n", tbl->name);
01727       AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01728          fprintf(stderr, "%s\n", col->name);
01729          ast_cli(a->fd, "  %20.20s  %-30.30s\n", col->name, col->type);
01730       }
01731    }
01732    AST_RWLIST_UNLOCK(&sqlite_tables);
01733 
01734    if (!found) {
01735       ast_cli(a->fd, "No tables currently in cache\n");
01736    }
01737 
01738    return CLI_SUCCESS;
01739 }
01740 
01741 static int unload_module(void)
01742 {
01743    if (cli_status_registered)
01744       ast_cli_unregister_multiple(cli_status, ARRAY_LEN(cli_status));
01745 
01746    if (cdr_registered)
01747       ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
01748 
01749    ast_config_engine_deregister(&sqlite_engine);
01750 
01751    if (db)
01752       sqlite_close(db);
01753 
01754    unload_config();
01755 
01756    return 0;
01757 }
01758 
01759 static int load_module(void)
01760 {
01761    char *errormsg = NULL;
01762    int error;
01763 
01764    db = NULL;
01765    cdr_registered = 0;
01766    cli_status_registered = 0;
01767    dbfile = NULL;
01768    config_table = NULL;
01769    cdr_table = NULL;
01770    error = load_config();
01771 
01772    if (error)
01773       return AST_MODULE_LOAD_DECLINE;
01774 
01775    if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01776       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01777       sqlite_freemem(errormsg);
01778       unload_module();
01779       return 1;
01780    }
01781 
01782    sqlite_freemem(errormsg);
01783    errormsg = NULL;
01784    ast_config_engine_register(&sqlite_engine);
01785 
01786    if (use_cdr) {
01787       char *query;
01788 
01789 /* \cond DOXYGEN_CAN_PARSE_THIS */
01790 #undef QUERY
01791 #define QUERY "SELECT COUNT(id) FROM %Q;"
01792 /* \endcond */
01793 
01794       query = sqlite_mprintf(QUERY, cdr_table);
01795 
01796       if (!query) {
01797          ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01798          unload_module();
01799          return 1;
01800       }
01801 
01802       ast_debug(1, "SQL query: %s\n", query);
01803 
01804       RES_CONFIG_SQLITE_BEGIN
01805          error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01806       RES_CONFIG_SQLITE_END(error)
01807 
01808       sqlite_freemem(query);
01809 
01810       if (error) {
01811          /*
01812           * Unexpected error.
01813           */
01814          if (error != SQLITE_ERROR) {
01815             ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01816             sqlite_freemem(errormsg);
01817             unload_module();
01818             return 1;
01819          }
01820 
01821          sqlite_freemem(errormsg);
01822          errormsg = NULL;
01823          query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01824 
01825          if (!query) {
01826             ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01827             unload_module();
01828             return 1;
01829          }
01830 
01831          ast_debug(1, "SQL query: %s\n", query);
01832 
01833          RES_CONFIG_SQLITE_BEGIN
01834             error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01835          RES_CONFIG_SQLITE_END(error)
01836 
01837          sqlite_freemem(query);
01838 
01839          if (error) {
01840             ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01841             sqlite_freemem(errormsg);
01842             unload_module();
01843             return 1;
01844          }
01845       }
01846       sqlite_freemem(errormsg);
01847       errormsg = NULL;
01848 
01849       error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01850 
01851       if (error) {
01852          unload_module();
01853          return 1;
01854       }
01855 
01856       cdr_registered = 1;
01857    }
01858 
01859    error = ast_cli_register_multiple(cli_status, ARRAY_LEN(cli_status));
01860 
01861    if (error) {
01862       unload_module();
01863       return 1;
01864    }
01865 
01866    cli_status_registered = 1;
01867 
01868    return 0;
01869 }
01870 
01871 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Realtime SQLite configuration",
01872       .load = load_module,
01873       .unload = unload_module,
01874       .load_pri = AST_MODPRI_REALTIME_DRIVER,
01875 );

Generated on Mon Oct 8 12:39:04 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7