Fri Nov 12 12:08:03 2010

Asterisk developer's documentation


res_config_sqlite.c File Reference

res_config_sqlite module. More...

#include "asterisk.h"
#include <sqlite.h>
#include "asterisk/logger.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/cdr.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/linkedlists.h"
Include dependency graph for res_config_sqlite.c:

Go to the source code of this file.

Data Structures

struct  _columns
struct  cfg_entry_args
struct  rt_cfg_entry_args
struct  rt_multi_cfg_entry_args
struct  sqlite_cache_columns
struct  sqlite_cache_tables
struct  sqlite_tables

Defines

#define MACRO_BEGIN   do {
#define MACRO_END   } while (0)
#define release_table(a)   AST_RWLIST_UNLOCK(&((a)->columns))
#define RES_CONFIG_SQLITE_BEGIN
#define RES_CONFIG_SQLITE_CONF_FILE   "res_config_sqlite.conf"
#define RES_CONFIG_SQLITE_DESCRIPTION   "Resource Module for SQLite 2"
#define RES_CONFIG_SQLITE_DRIVER   "sqlite"
#define RES_CONFIG_SQLITE_END(error)
#define RES_CONFIG_SQLITE_MAX_LOOPS   10
#define RES_CONFIG_SQLITE_NAME   "res_config_sqlite"
#define SET_VAR(config, to, from)
#define sql_get_config_table
#define sql_table_structure   "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'"

Enumerations

enum  {
  RES_CONFIG_SQLITE_CONFIG_ID, RES_CONFIG_SQLITE_CONFIG_CAT_METRIC, RES_CONFIG_SQLITE_CONFIG_VAR_METRIC, RES_CONFIG_SQLITE_CONFIG_COMMENTED,
  RES_CONFIG_SQLITE_CONFIG_FILENAME, RES_CONFIG_SQLITE_CONFIG_CATEGORY, RES_CONFIG_SQLITE_CONFIG_VAR_NAME, RES_CONFIG_SQLITE_CONFIG_VAR_VAL,
  RES_CONFIG_SQLITE_CONFIG_COLUMNS
}

Functions

static void __init_sql_buf (void)
static void __init_where_buf (void)
static void __reg_module (void)
static void __unreg_module (void)
static int add_cfg_entry (void *arg, int argc, char **argv, char **columnNames)
 SQLite callback function for static configuration.
static int add_rt_cfg_entry (void *arg, int argc, char **argv, char **columnNames)
 SQLite callback function for RealTime configuration.
static int add_rt_multi_cfg_entry (void *arg, int argc, char **argv, char **columnNames)
 SQLite callback function for RealTime configuration.
static int cdr_handler (struct ast_cdr *cdr)
 Asterisk callback function for CDR support.
static int check_vars (void)
static struct ast_configconfig_handler (const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
 Asterisk callback function for static configuration.
static struct sqlite_cache_tablesfind_table (const char *tablename)
static int find_table_cb (void *vtblptr, int argc, char **argv, char **columnNames)
static void free_table (struct sqlite_cache_tables *tblptr)
static size_t get_params (va_list ap, const char ***params_ptr, const char ***vals_ptr, int warn)
 Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values.
static char * handle_cli_show_sqlite_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Asterisk callback function for the CLI status command.
static char * handle_cli_sqlite_show_tables (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int load_config (void)
 Load the configuration file.
static int load_module (void)
static int realtime_destroy_handler (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
 Asterisk callback function for RealTime configuration (destroys variable).
static struct ast_variablerealtime_handler (const char *database, const char *table, va_list ap)
 Asterisk callback function for RealTime configuration.
static struct ast_configrealtime_multi_handler (const char *database, const char *table, va_list ap)
 Asterisk callback function for RealTime configuration.
static int realtime_require_handler (const char *database, const char *table, va_list ap)
static int realtime_store_handler (const char *database, const char *table, va_list ap)
 Asterisk callback function for RealTime configuration (variable create/store).
static int realtime_unload_handler (const char *unused, const char *tablename)
static int realtime_update2_handler (const char *database, const char *table, va_list ap)
static int realtime_update_handler (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
 Asterisk callback function for RealTime configuration (variable update).
static int set_var (char **var, const char *name, const char *value)
 Allocate a variable.
static void unload_config (void)
 Free resources related to configuration.
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime SQLite configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static int cdr_registered
static char * cdr_table
static struct ast_cli_entry cli_status []
static int cli_status_registered
static char * config_table
static sqlite * db
static char * dbfile
static ast_mutex_t mutex = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
static struct ast_threadstorage sql_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql_buf , .custom_init = NULL , }
static char * sql_create_cdr_table
static struct ast_config_engine sqlite_engine
static int use_cdr
static struct ast_threadstorage where_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_where_buf , .custom_init = NULL , }

Detailed Description

res_config_sqlite module.

Definition in file res_config_sqlite.c.


Define Documentation

#define MACRO_BEGIN   do {

Definition at line 93 of file res_config_sqlite.c.

#define MACRO_END   } while (0)

Definition at line 94 of file res_config_sqlite.c.

#define release_table (  )     AST_RWLIST_UNLOCK(&((a)->columns))

Definition at line 704 of file res_config_sqlite.c.

#define RES_CONFIG_SQLITE_BEGIN
#define RES_CONFIG_SQLITE_CONF_FILE   "res_config_sqlite.conf"

Definition at line 99 of file res_config_sqlite.c.

Referenced by load_config().

#define RES_CONFIG_SQLITE_DESCRIPTION   "Resource Module for SQLite 2"

Definition at line 98 of file res_config_sqlite.c.

Referenced by load_module().

#define RES_CONFIG_SQLITE_DRIVER   "sqlite"

Definition at line 97 of file res_config_sqlite.c.

#define RES_CONFIG_SQLITE_END ( error   ) 
Value:
if (error != SQLITE_BUSY)  \
         break;                  \
      usleep(1000);                 \
   }                       \
MACRO_END;

Macro used after executing a query.

See also:
RES_CONFIG_SQLITE_MAX_LOOPS.

Definition at line 163 of file res_config_sqlite.c.

Referenced by cdr_handler(), config_handler(), load_module(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), realtime_update2_handler(), and realtime_update_handler().

#define RES_CONFIG_SQLITE_MAX_LOOPS   10

Maximum number of loops before giving up executing a query. Calls to sqlite_xxx() functions which can return SQLITE_BUSY are enclosed by RES_CONFIG_SQLITE_BEGIN and RES_CONFIG_SQLITE_END, e.g.

 char *errormsg;
 int error;
 RES_CONFIG_SQLITE_BEGIN
	 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
 RES_CONFIG_SQLITE_END(error)
 if (error)
	 ...;
 

Definition at line 145 of file res_config_sqlite.c.

#define RES_CONFIG_SQLITE_NAME   "res_config_sqlite"

Definition at line 96 of file res_config_sqlite.c.

Referenced by load_module(), and unload_module().

#define SET_VAR ( config,
to,
from   ) 

Definition at line 113 of file res_config_sqlite.c.

Referenced by load_config().

#define sql_get_config_table
Value:
"SELECT *" \
   "  FROM '%q'" \
   "  WHERE filename = '%q' AND commented = 0" \
   "  ORDER BY cat_metric ASC, var_metric ASC;"

SQL query format to fetch the static configuration of a file. Rows must be sorted by category.

See also:
add_cfg_entry()

Definition at line 566 of file res_config_sqlite.c.

Referenced by config_handler().

#define sql_table_structure   "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'"

SQL query format to describe the table structure

Definition at line 558 of file res_config_sqlite.c.

Referenced by find_table().


Enumeration Type Documentation

anonymous enum
Enumerator:
RES_CONFIG_SQLITE_CONFIG_ID 
RES_CONFIG_SQLITE_CONFIG_CAT_METRIC 
RES_CONFIG_SQLITE_CONFIG_VAR_METRIC 
RES_CONFIG_SQLITE_CONFIG_COMMENTED 
RES_CONFIG_SQLITE_CONFIG_FILENAME 
RES_CONFIG_SQLITE_CONFIG_CATEGORY 
RES_CONFIG_SQLITE_CONFIG_VAR_NAME 
RES_CONFIG_SQLITE_CONFIG_VAR_VAL 
RES_CONFIG_SQLITE_CONFIG_COLUMNS 

Definition at line 101 of file res_config_sqlite.c.


Function Documentation

static void __init_sql_buf ( void   )  [static]

Definition at line 126 of file res_config_sqlite.c.

00156 {

static void __init_where_buf ( void   )  [static]

Definition at line 127 of file res_config_sqlite.c.

00156 {

static void __reg_module ( void   )  [static]

Definition at line 1868 of file res_config_sqlite.c.

static void __unreg_module ( void   )  [static]

Definition at line 1868 of file res_config_sqlite.c.

static int add_cfg_entry ( void *  arg,
int  argc,
char **  argv,
char **  columnNames 
) [static]

SQLite callback function for static configuration.

This function is passed to the SQLite engine as a callback function to parse a row and store it in a struct ast_config object. It relies on resulting rows being sorted by category.

Parameters:
arg a pointer to a struct cfg_entry_args object
argc number of columns
argv values in the row
columnNames names and types of the columns
Return values:
0 on success
1 if an error occurred
See also:
cfg_entry_args
sql_get_config_table
config_handler()

Definition at line 851 of file res_config_sqlite.c.

References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_internal_load(), ast_free, ast_log(), ast_strdup, ast_variable_append(), ast_variable_new(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, cfg_entry_args::flags, LOG_WARNING, RES_CONFIG_SQLITE_CONFIG_CATEGORY, RES_CONFIG_SQLITE_CONFIG_COLUMNS, RES_CONFIG_SQLITE_CONFIG_VAR_NAME, RES_CONFIG_SQLITE_CONFIG_VAR_VAL, var, and cfg_entry_args::who_asked.

Referenced by config_handler().

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 }

static int add_rt_cfg_entry ( void *  arg,
int  argc,
char **  argv,
char **  columnNames 
) [static]

SQLite callback function for RealTime configuration.

This function is passed to the SQLite engine as a callback function to parse a row and store it in a linked list of struct ast_variable objects.

Parameters:
arg a pointer to a struct rt_cfg_entry_args object
argc number of columns
argv values in the row
columnNames names and types of the columns
Return values:
0 on success.
1 if an error occurred.
See also:
rt_cfg_entry_args
realtime_handler()

Definition at line 999 of file res_config_sqlite.c.

References ast_variable_new(), rt_cfg_entry_args::last, ast_variable::next, rt_cfg_entry_args::var, and var.

Referenced by realtime_handler().

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 }

static int add_rt_multi_cfg_entry ( void *  arg,
int  argc,
char **  argv,
char **  columnNames 
) [static]

SQLite callback function for RealTime configuration.

This function performs the same actions as add_rt_cfg_entry() except that the rt_multi_cfg_entry_args structure is designed to store categories in addition to variables.

Parameters:
arg a pointer to a struct rt_multi_cfg_entry_args object
argc number of columns
argv values in the row
columnNames names and types of the columns
Return values:
0 on success.
1 if an error occurred.
See also:
rt_multi_cfg_entry_args
realtime_multi_handler()

Definition at line 1118 of file res_config_sqlite.c.

References ast_category_append(), ast_category_new(), ast_log(), ast_variable_append(), ast_variable_new(), rt_multi_cfg_entry_args::cfg, rt_multi_cfg_entry_args::initfield, LOG_ERROR, LOG_WARNING, and var.

Referenced by realtime_multi_handler().

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 }

static int cdr_handler ( struct ast_cdr cdr  )  [static]

Asterisk callback function for CDR support.

Parameters:
cdr the CDR entry Asterisk sends us.

Asterisk will call this function each time a CDR entry must be logged if CDR support is enabled.

Return values:
0 on success
1 if an error occurred

Definition at line 785 of file res_config_sqlite.c.

References ast_cdr_getvar(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_TRAVERSE, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), sqlite_cache_tables::columns, find_table(), first, sqlite_cache_columns::isint, LOG_ERROR, LOG_WARNING, mutex, sqlite_cache_columns::name, release_table, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.

Referenced by load_module().

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 }

static int check_vars ( void   )  [static]

Definition at line 721 of file res_config_sqlite.c.

References ast_log(), and LOG_ERROR.

Referenced by load_config().

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 }

static struct ast_config * config_handler ( const char *  database,
const char *  table,
const char *  file,
struct ast_config cfg,
struct ast_flags  flags,
const char *  suggested_incl,
const char *  who_asked 
) [static, read]

Asterisk callback function for static configuration.

Asterisk will call this function when it loads its static configuration, which usually happens at startup and reload.

Parameters:
database the database to use (ignored)
table the table to use
file the file to load from the database
cfg the struct ast_config object to use when storing variables
flags Optional flags. Not used.
suggested_incl suggest include.
Return values:
cfg object
NULL if an error occurred
See also:
add_cfg_entry()

Definition at line 910 of file res_config_sqlite.c.

References add_cfg_entry(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, cfg_entry_args::flags, LOG_ERROR, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, sql_get_config_table, and cfg_entry_args::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 }

static struct sqlite_cache_tables* find_table ( const char *  tablename  )  [static, read]

Definition at line 641 of file res_config_sqlite.c.

References asprintf, ast_calloc, ast_debug, ast_free, AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_HEAD_INIT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, sqlite_cache_tables::columns, errno, find_table_cb(), free_table(), LOG_ERROR, LOG_WARNING, mutex, sqlite_cache_tables::name, and sql_table_structure.

Referenced by cdr_handler(), and realtime_require_handler().

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 }

static int find_table_cb ( void *  vtblptr,
int  argc,
char **  argv,
char **  columnNames 
) [static]

Definition at line 586 of file res_config_sqlite.c.

References AST_APP_ARG, ast_calloc, ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, ast_skip_blanks(), AST_STANDARD_APP_ARGS, sqlite_cache_tables::columns, sqlite_cache_columns::isint, sqlite_cache_columns::name, and sqlite_cache_columns::type.

Referenced by find_table().

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 }

static void free_table ( struct sqlite_cache_tables tblptr  )  [static]

Definition at line 572 of file res_config_sqlite.c.

References ast_free, AST_RWLIST_HEAD_DESTROY, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and sqlite_cache_tables::columns.

Referenced by find_table(), realtime_unload_handler(), and unload_config().

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 }

static size_t get_params ( va_list  ap,
const char ***  params_ptr,
const char ***  vals_ptr,
int  warn 
) [static]

Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values.

ap must have the following format : param1 val1 param2 val2 param3 val3 ... arguments will be extracted to create 2 arrays:

  • params : param1 param2 param3 ...
  • vals : val1 val2 val3 ...

The address of these arrays are stored in params_ptr and vals_ptr. It is the responsibility of the caller to release the memory of these arrays. It is considered an error that va_list has a null or odd number of strings.

Parameters:
ap the va_list object to parse
params_ptr where the address of the params array is stored
vals_ptr where the address of the vals array is stored
Return values:
the number of elements in the arrays (which have the same size).
0 if an error occurred.

Definition at line 960 of file res_config_sqlite.c.

References ast_free, ast_log(), ast_realloc, and LOG_WARNING.

Referenced by realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), and realtime_update_handler().

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 }

static char * handle_cli_show_sqlite_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Asterisk callback function for the CLI status command.

Parameters:
e CLI command
cmd 
a CLI argument list
Returns:
RESULT_SUCCESS

Definition at line 1663 of file res_config_sqlite.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

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 }

static char * handle_cli_sqlite_show_tables ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1697 of file res_config_sqlite.c.

References ast_cli_args::argc, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, sqlite_cache_tables::columns, ast_cli_entry::command, ast_cli_args::fd, sqlite_cache_columns::name, sqlite_cache_tables::name, sqlite_cache_columns::type, and ast_cli_entry::usage.

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 }

static int load_config ( void   )  [static]

Load the configuration file.

See also:
unload_config()

This function sets dbfile, config_table, and cdr_table. It calls check_vars() before returning, and unload_config() if an error occurred.

Return values:
0 on success
1 if an error occurred

Definition at line 733 of file res_config_sqlite.c.

References ast_config_destroy(), ast_config_load, ast_log(), ast_variable_browse(), check_vars(), config, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, RES_CONFIG_SQLITE_CONF_FILE, SET_VAR, unload_config(), and var.

Referenced by load_module().

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 }

static int load_module ( void   )  [static]

Definition at line 1753 of file res_config_sqlite.c.

References ARRAY_LEN, ast_cdr_register(), ast_cli_register_multiple(), ast_config_engine_register(), ast_debug, ast_log(), AST_MODULE_LOAD_DECLINE, cdr_handler(), load_config(), LOG_ERROR, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_DESCRIPTION, RES_CONFIG_SQLITE_END, RES_CONFIG_SQLITE_NAME, S_OR, sql_create_cdr_table, and unload_module.

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 }

static int realtime_destroy_handler ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
va_list  ap 
) [static]

Asterisk callback function for RealTime configuration (destroys variable).

Asterisk will call this function each time a variable has been destroyed internally and must be removed from the backend engine. keyfield and entity are used to find the row to delete, e.g. DELETE FROM table WHERE keyfield = 'entity';. ap is a list of parameters and values with the same format as the other realtime functions.

Parameters:
database the database to use (ignored)
table the table to use
keyfield the column of the matching cell
entity the value of the matching cell
ap list of additional parameters for cell matching
Return values:
the number of affected rows.
-1 if an error occurred.

Definition at line 1535 of file res_config_sqlite.c.

References ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.

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 }

static struct ast_variable * realtime_handler ( const char *  database,
const char *  table,
va_list  ap 
) [static, read]

Asterisk callback function for RealTime configuration.

Asterisk will call this function each time it requires a variable through the RealTime architecture. ap is a list of parameters and values used to find a specific row, e.g one parameter "name" and one value "123" so that the SQL query becomes SELECT * FROM table WHERE name = '123';.

Parameters:
database the database to use (ignored)
table the table to use
ap list of parameters and values to match
Return values:
a linked list of struct ast_variable objects
NULL if an error occurred
See also:
add_rt_cfg_entry()

Definition at line 1028 of file res_config_sqlite.c.

References add_rt_cfg_entry(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variables_destroy(), get_params(), rt_cfg_entry_args::last, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and rt_cfg_entry_args::var.

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 }

static struct ast_config * realtime_multi_handler ( const char *  database,
const char *  table,
va_list  ap 
) [static, read]

Asterisk callback function for RealTime configuration.

This function performs the same actions as realtime_handler() except that it can store variables per category, and can return several categories.

Parameters:
database the database to use (ignored)
table the table to use
ap list of parameters and values to match
Return values:
a struct ast_config object storing categories and variables.
NULL if an error occurred.
See also:
add_rt_multi_cfg_entry()

Definition at line 1166 of file res_config_sqlite.c.

References add_rt_multi_cfg_entry(), ast_config_destroy(), ast_config_new(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, rt_multi_cfg_entry_args::cfg, get_params(), rt_multi_cfg_entry_args::initfield, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.

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 }

static int realtime_require_handler ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Definition at line 1612 of file res_config_sqlite.c.

References ast_log(), ast_rq_is_int(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, sqlite_cache_tables::columns, find_table(), sqlite_cache_columns::isint, LOG_WARNING, sqlite_cache_columns::name, and sqlite_cache_columns::type.

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 }

static int realtime_store_handler ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Asterisk callback function for RealTime configuration (variable create/store).

Asterisk will call this function each time a variable has been created internally and must be stored in the backend engine. are used to find the row to update, e.g. ap is a list of parameters and values with the same format as the other realtime functions.

Parameters:
database the database to use (ignored)
table the table to use
ap list of parameters and new values to insert into the database
Return values:
the rowid of inserted row.
-1 if an error occurred.

Definition at line 1441 of file res_config_sqlite.c.

References ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.

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 }

static int realtime_unload_handler ( const char *  unused,
const char *  tablename 
) [static]
static int realtime_update2_handler ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Definition at line 1367 of file res_config_sqlite.c.

References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), first, LOG_ERROR, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, sql_buf, and where_buf.

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 }

static int realtime_update_handler ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
va_list  ap 
) [static]

Asterisk callback function for RealTime configuration (variable update).

Asterisk will call this function each time a variable has been modified internally and must be updated in the backend engine. keyfield and entity are used to find the row to update, e.g. UPDATE table SET ... WHERE keyfield = 'entity';. ap is a list of parameters and values with the same format as the other realtime functions.

Parameters:
database the database to use (ignored)
table the table to use
keyfield the column of the matching cell
entity the value of the matching cell
ap list of parameters and new values to update in the database
Return values:
the number of affected rows.
-1 if an error occurred.

Definition at line 1285 of file res_config_sqlite.c.

References ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.

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 }

static int set_var ( char **  var,
const char *  name,
const char *  value 
) [static]

Allocate a variable.

Parameters:
var the address of the variable to set (it will be allocated)
name the name of the variable (for error handling)
value the value to store in var
Return values:
0 on success
1 if an allocation error occurred

Definition at line 706 of file res_config_sqlite.c.

References ast_free, ast_log(), ast_strdup, and LOG_WARNING.

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 }

static void unload_config ( void   )  [static]

Free resources related to configuration.

See also:
load_config()

Definition at line 769 of file res_config_sqlite.c.

References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and free_table().

Referenced by load_config(), and unload_module().

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 }

static int unload_module ( void   )  [static]

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime SQLite configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 1868 of file res_config_sqlite.c.

Definition at line 1868 of file res_config_sqlite.c.

int cdr_registered [static]

Set to 1 if the CDR callback function was registered.

Definition at line 465 of file res_config_sqlite.c.

char* cdr_table [static]

The name of the table used to store CDR entries.

Definition at line 477 of file res_config_sqlite.c.

struct ast_cli_entry cli_status[] [static]
Initial value:
 {
   AST_CLI_DEFINE(handle_cli_show_sqlite_status, "Show status information about the SQLite 2 driver"),
   AST_CLI_DEFINE(handle_cli_sqlite_show_tables, "Cached table information about the SQLite 2 driver"),
}

Structure containing details and callback functions for the CLI status command.

Definition at line 506 of file res_config_sqlite.c.

int cli_status_registered [static]

Set to 1 if the CLI status command callback function was registered.

Definition at line 468 of file res_config_sqlite.c.

char* config_table [static]

The name of the static configuration table.

Definition at line 474 of file res_config_sqlite.c.

sqlite* db [static]

The SQLite database object.

Definition at line 459 of file res_config_sqlite.c.

char* dbfile [static]

The path of the database file.

Definition at line 471 of file res_config_sqlite.c.

ast_mutex_t mutex = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]
struct ast_threadstorage sql_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql_buf , .custom_init = NULL , } [static]

Definition at line 126 of file res_config_sqlite.c.

Referenced by realtime_update2_handler().

char* sql_create_cdr_table [static]

SQL query format to create the CDR table if non existent.

Definition at line 531 of file res_config_sqlite.c.

Referenced by load_module().

The structure specifying all callback functions used by Asterisk for static and RealTime configuration.

Definition at line 483 of file res_config_sqlite.c.

int use_cdr [static]

Set to 1 if CDR support is enabled.

Definition at line 462 of file res_config_sqlite.c.

struct ast_threadstorage where_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_where_buf , .custom_init = NULL , } [static]

Definition at line 127 of file res_config_sqlite.c.

Referenced by realtime_update2_handler().


Generated by  doxygen 1.6.2