Mon Sep 20 2010 00:23:38

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