Wed Aug 18 22:34:31 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"

Go to the source code of this file.

Data Structures

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_cache_tables::_columns
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 __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)
 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_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 = "a9c98e5d177805051735cb5b0b16b0a0" , .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 char * sql_create_cdr_table
static struct ast_config_engine sqlite_engine
static int use_cdr


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 698 of file res_config_sqlite.c.

Referenced by cdr_handler().

#define RES_CONFIG_SQLITE_BEGIN

Value:

MACRO_BEGIN                      \
   int __i;                   \
                           \
   for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++)  {
Macro used before executing a query.

See also:
RES_CONFIG_SQLITE_MAX_LOOPS.

Definition at line 149 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(), and realtime_update_handler().

#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 160 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(), 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 142 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 560 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 552 of file res_config_sqlite.c.


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 __reg_module ( void   )  [static]

Definition at line 1787 of file res_config_sqlite.c.

static void __unreg_module ( void   )  [static]

Definition at line 1787 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 845 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().

00846 {
00847    struct cfg_entry_args *args;
00848    struct ast_variable *var;
00849 
00850    if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) {
00851       ast_log(LOG_WARNING, "Corrupt table\n");
00852       return 1;
00853    }
00854 
00855    args = arg;
00856 
00857    if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) {
00858       struct ast_config *cfg;
00859       char *val;
00860 
00861       val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL];
00862       cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked);
00863 
00864       if (!cfg) {
00865          ast_log(LOG_WARNING, "Unable to include %s\n", val);
00866          return 1;
00867       } else {
00868          args->cfg = cfg;
00869          return 0;
00870       }
00871    }
00872 
00873    if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) {
00874       args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999);
00875 
00876       if (!args->cat) {
00877          ast_log(LOG_WARNING, "Unable to allocate category\n");
00878          return 1;
00879       }
00880 
00881       ast_free(args->cat_name);
00882       args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]);
00883 
00884       if (!args->cat_name) {
00885          ast_category_destroy(args->cat);
00886          return 1;
00887       }
00888 
00889       ast_category_append(args->cfg, args->cat);
00890    }
00891 
00892    var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], "");
00893 
00894    if (!var) {
00895       ast_log(LOG_WARNING, "Unable to allocate variable");
00896       return 1;
00897    }
00898 
00899    ast_variable_append(args->cat, var);
00900 
00901    return 0;
00902 }

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 992 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().

00993 {
00994    struct rt_cfg_entry_args *args;
00995    struct ast_variable *var;
00996    int i;
00997 
00998    args = arg;
00999 
01000    for (i = 0; i < argc; i++) {
01001       if (!argv[i])
01002          continue;
01003 
01004       if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
01005          return 1;
01006 
01007       if (!args->var)
01008          args->var = var;
01009 
01010       if (!args->last)
01011          args->last = var;
01012       else {
01013          args->last->next = var;
01014          args->last = var;
01015       }
01016    }
01017 
01018    return 0;
01019 }

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 1111 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().

01112 {
01113    struct rt_multi_cfg_entry_args *args;
01114    struct ast_category *cat;
01115    struct ast_variable *var;
01116    char *cat_name;
01117    size_t i;
01118 
01119    args = arg;
01120    cat_name = NULL;
01121 
01122    /*
01123     * cat_name should always be set here, since initfield is forged from
01124     * params[0] in realtime_multi_handler(), which is a search parameter
01125     * of the SQL query.
01126     */
01127    for (i = 0; i < argc; i++) {
01128       if (!strcmp(args->initfield, columnNames[i]))
01129          cat_name = argv[i];
01130    }
01131 
01132    if (!cat_name) {
01133       ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
01134       return 1;
01135    }
01136 
01137    if (!(cat = ast_category_new(cat_name, "", 99999))) {
01138       ast_log(LOG_WARNING, "Unable to allocate category\n");
01139       return 1;
01140    }
01141 
01142    ast_category_append(args->cfg, cat);
01143 
01144    for (i = 0; i < argc; i++) {
01145       if (!argv[i] || !strcmp(args->initfield, columnNames[i]))
01146          continue;
01147 
01148       if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01149          ast_log(LOG_WARNING, "Unable to allocate variable\n");
01150          return 1;
01151       }
01152 
01153       ast_variable_append(cat, var);
01154    }
01155 
01156    return 0;
01157 }

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 779 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_create(), ast_str_set(), sqlite_cache_tables::columns, find_table(), sqlite_cache_columns::isint, LOG_ERROR, LOG_WARNING, mutex, sqlite_cache_columns::name, release_table, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, ast_str::str, and ast_str::used.

Referenced by load_module().

00780 {
00781    char *errormsg = NULL, *tmp, workspace[500];
00782    int error, scannum;
00783    struct sqlite_cache_tables *tbl = find_table(cdr_table);
00784    struct sqlite_cache_columns *col;
00785    struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16);
00786 
00787    if (!tbl) {
00788       ast_log(LOG_WARNING, "No such table: %s\n", cdr_table);
00789       return -1;
00790    }
00791 
00792    ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table);
00793    ast_str_set(&sql2, 0, ") VALUES (");
00794 
00795    AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
00796       if (col->isint) {
00797          ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1);
00798          if (!tmp) {
00799             continue;
00800          }
00801          if (sscanf(tmp, "%30d", &scannum) == 1) {
00802             ast_str_append(&sql1, 0, "%s,", col->name);
00803             ast_str_append(&sql2, 0, "%d,", scannum);
00804          }
00805       } else {
00806          ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0);
00807          if (!tmp) {
00808             continue;
00809          }
00810          ast_str_append(&sql1, 0, "%s,", col->name);
00811          tmp = sqlite_mprintf("%Q", tmp);
00812          ast_str_append(&sql2, 0, "%s,", tmp);
00813          sqlite_freemem(tmp);
00814       }
00815    }
00816    release_table(tbl);
00817 
00818    sql1->str[--sql1->used] = '\0';
00819    sql2->str[--sql2->used] = '\0';
00820    ast_str_append(&sql1, 0, "%s)", sql2->str);
00821    ast_free(sql2);
00822 
00823    ast_debug(1, "SQL query: %s\n", sql1->str);
00824 
00825    ast_mutex_lock(&mutex);
00826 
00827    RES_CONFIG_SQLITE_BEGIN
00828       error = sqlite_exec(db, sql1->str, NULL, NULL, &errormsg);
00829    RES_CONFIG_SQLITE_END(error)
00830 
00831    ast_mutex_unlock(&mutex);
00832 
00833    ast_free(sql1);
00834 
00835    if (error) {
00836       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00837       sqlite_freemem(errormsg);
00838       return 1;
00839    }
00840    sqlite_freemem(errormsg);
00841 
00842    return 0;
00843 }

static int check_vars ( void   )  [static]

Definition at line 715 of file res_config_sqlite.c.

References ast_log(), and LOG_ERROR.

00716 {
00717    if (!dbfile) {
00718       ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00719       return 1;
00720    }
00721 
00722    use_cdr = (cdr_table != NULL);
00723 
00724    return 0;
00725 }

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]

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 904 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.

00906 {
00907    struct cfg_entry_args args;
00908    char *query, *errormsg = NULL;
00909    int error;
00910 
00911    if (!config_table) {
00912       if (!table) {
00913          ast_log(LOG_ERROR, "Table name unspecified\n");
00914          return NULL;
00915       }
00916    } else
00917       table = config_table;
00918 
00919    query = sqlite_mprintf(sql_get_config_table, table, file);
00920 
00921    if (!query) {
00922       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00923       return NULL;
00924    }
00925 
00926    ast_debug(1, "SQL query: %s\n", query);
00927    args.cfg = cfg;
00928    args.cat = NULL;
00929    args.cat_name = NULL;
00930    args.flags = flags;
00931    args.who_asked = who_asked;
00932 
00933    ast_mutex_lock(&mutex);
00934 
00935    RES_CONFIG_SQLITE_BEGIN
00936       error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg);
00937    RES_CONFIG_SQLITE_END(error)
00938 
00939    ast_mutex_unlock(&mutex);
00940 
00941    ast_free(args.cat_name);
00942    sqlite_freemem(query);
00943 
00944    if (error) {
00945       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00946       sqlite_freemem(errormsg);
00947       return NULL;
00948    }
00949    sqlite_freemem(errormsg);
00950 
00951    return cfg;
00952 }

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

Definition at line 635 of file res_config_sqlite.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, sqlite_cache_tables::list, and sqlite_cache_tables::name.

00636 {
00637    struct sqlite_cache_tables *tblptr;
00638    int i, err;
00639    char *sql, *errstr = NULL;
00640 
00641    AST_RWLIST_RDLOCK(&sqlite_tables);
00642 
00643    for (i = 0; i < 2; i++) {
00644       AST_RWLIST_TRAVERSE(&sqlite_tables, tblptr, list) {
00645          if (strcmp(tblptr->name, tablename) == 0) {
00646             break;
00647          }
00648       }
00649       if (tblptr) {
00650          AST_RWLIST_RDLOCK(&(tblptr->columns));
00651          AST_RWLIST_UNLOCK(&sqlite_tables);
00652          return tblptr;
00653       }
00654 
00655       if (i == 0) {
00656          AST_RWLIST_UNLOCK(&sqlite_tables);
00657          AST_RWLIST_WRLOCK(&sqlite_tables);
00658       }
00659    }
00660 
00661    /* Table structure not cached; build the structure now */
00662    if (asprintf(&sql, sql_table_structure, tablename) < 0) {
00663       ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00664       sql = NULL;
00665    }
00666    if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) {
00667       AST_RWLIST_UNLOCK(&sqlite_tables);
00668       ast_log(LOG_ERROR, "Memory error.  Cannot cache table '%s'\n", tablename);
00669       return NULL;
00670    }
00671    tblptr->name = (char *)tblptr + sizeof(*tblptr);
00672    strcpy(tblptr->name, tablename); /* SAFE */
00673    AST_RWLIST_HEAD_INIT(&(tblptr->columns));
00674 
00675    ast_debug(1, "About to query table structure: %s\n", sql);
00676 
00677    ast_mutex_lock(&mutex);
00678    if ((err = sqlite_exec(db, sql, find_table_cb, tblptr, &errstr))) {
00679       ast_mutex_unlock(&mutex);
00680       ast_log(LOG_WARNING, "SQLite error %d: %s\n", err, errstr);
00681       ast_free(errstr);
00682       free_table(tblptr);
00683       return NULL;
00684    }
00685    ast_mutex_unlock(&mutex);
00686 
00687    if (AST_LIST_EMPTY(&(tblptr->columns))) {
00688       free_table(tblptr);
00689       return NULL;
00690    }
00691 
00692    AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list);
00693    AST_RWLIST_RDLOCK(&(tblptr->columns));
00694    AST_RWLIST_UNLOCK(&sqlite_tables);
00695    return tblptr;
00696 }

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

Definition at line 580 of file res_config_sqlite.c.

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

00581 {
00582    struct sqlite_cache_tables *tblptr = vtblptr;
00583    char *sql = ast_strdupa(argv[0]), *start, *end, *type, *remainder;
00584    int i;
00585    AST_DECLARE_APP_ARGS(fie,
00586       AST_APP_ARG(ld)[100]; /* This means we support up to 100 columns per table */
00587    );
00588    struct sqlite_cache_columns *col;
00589 
00590    /* This is really fun.  We get to parse an SQL statement to figure out
00591     * what columns are in the table.
00592     */
00593    if ((start = strchr(sql, '(')) && (end = strrchr(sql, ')'))) {
00594       start++;
00595       *end = '\0';
00596    } else {
00597       /* Abort */
00598       return -1;
00599    }
00600 
00601    AST_STANDARD_APP_ARGS(fie, start);
00602    for (i = 0; i < fie.argc; i++) {
00603       fie.ld[i] = ast_skip_blanks(fie.ld[i]);
00604       ast_debug(5, "Found field: %s\n", fie.ld[i]);
00605       if (strncasecmp(fie.ld[i], "PRIMARY KEY", 11) == 0 && (start = strchr(fie.ld[i], '(')) && (end = strchr(fie.ld[i], ')'))) {
00606          *end = '\0';
00607          AST_RWLIST_TRAVERSE(&(tblptr->columns), col, list) {
00608             if (strcasecmp(start + 1, col->name) == 0 && strcasestr(col->type, "INTEGER")) {
00609                col->isint = 1;
00610             }
00611          }
00612          continue;
00613       }
00614       /* type delimiter could be any space character */
00615       for (type = fie.ld[i]; *type > 32; type++);
00616       *type++ = '\0';
00617       type = ast_skip_blanks(type);
00618       for (remainder = type; *remainder > 32; remainder++);
00619       *remainder = '\0';
00620       if (!(col = ast_calloc(1, sizeof(*col) + strlen(fie.ld[i]) + strlen(type) + 2))) {
00621          return -1;
00622       }
00623       col->name = (char *)col + sizeof(*col);
00624       col->type = (char *)col + sizeof(*col) + strlen(fie.ld[i]) + 1;
00625       strcpy(col->name, fie.ld[i]); /* SAFE */
00626       strcpy(col->type, type); /* SAFE */
00627       if (strcasestr(col->type, "INTEGER") && strcasestr(col->type, "PRIMARY KEY")) {
00628          col->isint = 1;
00629       }
00630       AST_LIST_INSERT_TAIL(&(tblptr->columns), col, list);
00631    }
00632    return 0;
00633 }

static void free_table ( struct sqlite_cache_tables tblptr  )  [static]

Definition at line 566 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 realtime_unload_handler(), and unload_config().

00567 {
00568    struct sqlite_cache_columns *col;
00569 
00570    /* Obtain a write lock to ensure there are no read locks outstanding */
00571    AST_RWLIST_WRLOCK(&(tblptr->columns));
00572    while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) {
00573       ast_free(col);
00574    }
00575    AST_RWLIST_UNLOCK(&(tblptr->columns));
00576    AST_RWLIST_HEAD_DESTROY(&(tblptr->columns));
00577    ast_free(tblptr);
00578 }

static size_t get_params ( va_list  ap,
const char ***  params_ptr,
const char ***  vals_ptr 
) [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:

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 954 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().

00955 {
00956    const char **tmp, *param, *val, **params, **vals;
00957    size_t params_count;
00958 
00959    params = NULL;
00960    vals = NULL;
00961    params_count = 0;
00962 
00963    while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) {
00964       if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) {
00965          ast_free(params);
00966          ast_free(vals);
00967          return 0;
00968       }
00969       params = tmp;
00970 
00971       if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) {
00972          ast_free(params);
00973          ast_free(vals);
00974          return 0;
00975       }
00976       vals = tmp;
00977 
00978       params[params_count] = param;
00979       vals[params_count] = val;
00980       params_count++;
00981    }
00982 
00983    if (params_count > 0) {
00984       *params_ptr = params;
00985       *vals_ptr = vals;
00986    } else
00987       ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n");
00988 
00989    return params_count;
00990 }

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 1582 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.

01583 {
01584    switch (cmd) {
01585    case CLI_INIT:
01586       e->command = "sqlite show status";
01587       e->usage =
01588          "Usage: sqlite show status\n"
01589          "       Show status information about the SQLite 2 driver\n";
01590       return NULL;
01591    case CLI_GENERATE:
01592       return NULL;
01593    }
01594 
01595    if (a->argc != 3)
01596       return CLI_SHOWUSAGE;
01597 
01598    ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01599    ast_cli(a->fd, "config_table: ");
01600 
01601    if (!config_table)
01602       ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01603    else
01604       ast_cli(a->fd, "%s\n", config_table);
01605 
01606    ast_cli(a->fd, "cdr_table: ");
01607 
01608    if (!cdr_table)
01609       ast_cli(a->fd, "unspecified, CDR support disabled\n");
01610    else
01611       ast_cli(a->fd, "%s\n", cdr_table);
01612 
01613    return CLI_SUCCESS;
01614 }

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

Definition at line 1616 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::list, sqlite_cache_columns::name, sqlite_cache_tables::name, sqlite_cache_columns::type, and ast_cli_entry::usage.

01617 {
01618    struct sqlite_cache_tables *tbl;
01619    struct sqlite_cache_columns *col;
01620    int found = 0;
01621 
01622    switch (cmd) {
01623    case CLI_INIT:
01624       e->command = "sqlite show tables";
01625       e->usage =
01626          "Usage: sqlite show tables\n"
01627          "       Show table information about the SQLite 2 driver\n";
01628       return NULL;
01629    case CLI_GENERATE:
01630       return NULL;
01631    }
01632 
01633    if (a->argc != 3)
01634       return CLI_SHOWUSAGE;
01635 
01636    AST_RWLIST_RDLOCK(&sqlite_tables);
01637    AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01638       found++;
01639       ast_cli(a->fd, "Table %s:\n", tbl->name);
01640       AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01641          fprintf(stderr, "%s\n", col->name);
01642          ast_cli(a->fd, "  %20.20s  %-30.30s\n", col->name, col->type);
01643       }
01644    }
01645    AST_RWLIST_UNLOCK(&sqlite_tables);
01646 
01647    if (!found) {
01648       ast_cli(a->fd, "No tables currently in cache\n");
01649    }
01650 
01651    return CLI_SUCCESS;
01652 }

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 727 of file res_config_sqlite.c.

References ast_config_load, ast_log(), ast_variable_browse(), config, config_flags, LOG_ERROR, LOG_WARNING, RES_CONFIG_SQLITE_CONF_FILE, SET_VAR, and var.

00728 {
00729    struct ast_config *config;
00730    struct ast_variable *var;
00731    int error;
00732    struct ast_flags config_flags = { 0 };
00733 
00734    config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags);
00735 
00736    if (!config) {
00737       ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n");
00738       return 1;
00739    }
00740 
00741    for (var = ast_variable_browse(config, "general"); var; var = var->next) {
00742       if (!strcasecmp(var->name, "dbfile"))
00743          SET_VAR(config, dbfile, var);
00744       else if (!strcasecmp(var->name, "config_table"))
00745          SET_VAR(config, config_table, var);
00746       else if (!strcasecmp(var->name, "cdr_table")) {
00747          SET_VAR(config, cdr_table, var);
00748       } else
00749          ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name);
00750    }
00751 
00752    ast_config_destroy(config);
00753    error = check_vars();
00754 
00755    if (error) {
00756       unload_config();
00757       return 1;
00758    }
00759 
00760    return 0;
00761 }

static int load_module ( void   )  [static]

Definition at line 1672 of file res_config_sqlite.c.

References ast_cdr_register(), ast_cli_register_multiple(), ast_config_engine_register(), ast_debug, ast_log(), AST_MODULE_LOAD_DECLINE, cdr_handler(), cli_status, 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, sqlite_engine, and unload_module().

01673 {
01674    char *errormsg = NULL;
01675    int error;
01676 
01677    db = NULL;
01678    cdr_registered = 0;
01679    cli_status_registered = 0;
01680    dbfile = NULL;
01681    config_table = NULL;
01682    cdr_table = NULL;
01683    error = load_config();
01684 
01685    if (error)
01686       return AST_MODULE_LOAD_DECLINE;
01687 
01688    if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01689       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01690       sqlite_freemem(errormsg);
01691       unload_module();
01692       return 1;
01693    }
01694 
01695    sqlite_freemem(errormsg);
01696    errormsg = NULL;
01697    ast_config_engine_register(&sqlite_engine);
01698 
01699    if (use_cdr) {
01700       char *query;
01701 
01702 /* \cond DOXYGEN_CAN_PARSE_THIS */
01703 #undef QUERY
01704 #define QUERY "SELECT COUNT(id) FROM %Q;"
01705 /* \endcond */
01706 
01707       query = sqlite_mprintf(QUERY, cdr_table);
01708 
01709       if (!query) {
01710          ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01711          unload_module();
01712          return 1;
01713       }
01714 
01715       ast_debug(1, "SQL query: %s\n", query);
01716 
01717       RES_CONFIG_SQLITE_BEGIN
01718          error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01719       RES_CONFIG_SQLITE_END(error)
01720 
01721       sqlite_freemem(query);
01722 
01723       if (error) {
01724          /*
01725           * Unexpected error.
01726           */
01727          if (error != SQLITE_ERROR) {
01728             ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01729             sqlite_freemem(errormsg);
01730             unload_module();
01731             return 1;
01732          }
01733 
01734          sqlite_freemem(errormsg);
01735          errormsg = NULL;
01736          query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01737 
01738          if (!query) {
01739             ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01740             unload_module();
01741             return 1;
01742          }
01743 
01744          ast_debug(1, "SQL query: %s\n", query);
01745 
01746          RES_CONFIG_SQLITE_BEGIN
01747             error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01748          RES_CONFIG_SQLITE_END(error)
01749 
01750          sqlite_freemem(query);
01751 
01752          if (error) {
01753             ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01754             sqlite_freemem(errormsg);
01755             unload_module();
01756             return 1;
01757          }
01758       }
01759       sqlite_freemem(errormsg);
01760       errormsg = NULL;
01761 
01762       error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01763 
01764       if (error) {
01765          unload_module();
01766          return 1;
01767       }
01768 
01769       cdr_registered = 1;
01770    }
01771 
01772    error = ast_cli_register_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
01773 
01774    if (error) {
01775       unload_module();
01776       return 1;
01777    }
01778 
01779    cli_status_registered = 1;
01780 
01781    return 0;
01782 }

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 1454 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.

01456 {
01457    char *query, *errormsg = NULL, *tmp_str;
01458    const char **params, **vals;
01459    size_t params_count;
01460    int error, rows_num;
01461    size_t i;
01462 
01463    if (!table) {
01464       ast_log(LOG_WARNING, "Table name unspecified\n");
01465       return -1;
01466    }
01467 
01468    if (!(params_count = get_params(ap, &params, &vals)))
01469       return -1;
01470 
01471 /* \cond DOXYGEN_CAN_PARSE_THIS */
01472 #undef QUERY
01473 #define QUERY "DELETE FROM '%q' WHERE"
01474 /* \endcond */
01475 
01476    if (!(query = sqlite_mprintf(QUERY, table))) {
01477       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01478       ast_free(params);
01479       ast_free(vals);
01480       return -1;
01481    }
01482 
01483    for (i = 0; i < params_count; i++) {
01484       tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01485       sqlite_freemem(query);
01486 
01487       if (!tmp_str) {
01488          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01489          ast_free(params);
01490          ast_free(vals);
01491          return -1;
01492       }
01493 
01494       query = tmp_str;
01495    }
01496 
01497    ast_free(params);
01498    ast_free(vals);
01499    if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01500       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01501       sqlite_freemem(query);
01502       return -1;
01503    }
01504    sqlite_freemem(query);
01505    query = tmp_str;
01506    ast_debug(1, "SQL query: %s\n", query);
01507 
01508    ast_mutex_lock(&mutex);
01509 
01510    RES_CONFIG_SQLITE_BEGIN
01511       error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01512    RES_CONFIG_SQLITE_END(error)
01513 
01514    if (!error)
01515       rows_num = sqlite_changes(db);
01516    else
01517       rows_num = -1;
01518 
01519    ast_mutex_unlock(&mutex);
01520 
01521    sqlite_freemem(query);
01522 
01523    if (error) {
01524       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01525    }
01526    sqlite_freemem(errormsg);
01527 
01528    return rows_num;
01529 }

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

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 1021 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.

01022 {
01023    char *query, *errormsg = NULL, *op, *tmp_str;
01024    struct rt_cfg_entry_args args;
01025    const char **params, **vals;
01026    size_t params_count;
01027    int error;
01028 
01029    if (!table) {
01030       ast_log(LOG_WARNING, "Table name unspecified\n");
01031       return NULL;
01032    }
01033 
01034    params_count = get_params(ap, &params, &vals);
01035 
01036    if (params_count == 0)
01037       return NULL;
01038 
01039    op = (strchr(params[0], ' ') == NULL) ? " =" : "";
01040 
01041 /* \cond DOXYGEN_CAN_PARSE_THIS */
01042 #undef QUERY
01043 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
01044 /* \endcond */
01045 
01046    query = sqlite_mprintf(QUERY, table, params[0], op, vals[0]);
01047 
01048    if (!query) {
01049       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01050       ast_free(params);
01051       ast_free(vals);
01052       return NULL;
01053    }
01054 
01055    if (params_count > 1) {
01056       size_t i;
01057 
01058       for (i = 1; i < params_count; i++) {
01059          op = (strchr(params[i], ' ') == NULL) ? " =" : "";
01060          tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01061          sqlite_freemem(query);
01062 
01063          if (!tmp_str) {
01064             ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01065             ast_free(params);
01066             ast_free(vals);
01067             return NULL;
01068          }
01069 
01070          query = tmp_str;
01071       }
01072    }
01073 
01074    ast_free(params);
01075    ast_free(vals);
01076 
01077    tmp_str = sqlite_mprintf("%s LIMIT 1;", query);
01078    sqlite_freemem(query);
01079 
01080    if (!tmp_str) {
01081       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01082       return NULL;
01083    }
01084 
01085    query = tmp_str;
01086    ast_debug(1, "SQL query: %s\n", query);
01087    args.var = NULL;
01088    args.last = NULL;
01089 
01090    ast_mutex_lock(&mutex);
01091 
01092    RES_CONFIG_SQLITE_BEGIN
01093       error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg);
01094    RES_CONFIG_SQLITE_END(error)
01095 
01096    ast_mutex_unlock(&mutex);
01097 
01098    sqlite_freemem(query);
01099 
01100    if (error) {
01101       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01102       sqlite_freemem(errormsg);
01103       ast_variables_destroy(args.var);
01104       return NULL;
01105    }
01106    sqlite_freemem(errormsg);
01107 
01108    return args.var;
01109 }

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

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 1159 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.

01161 {
01162    char *query, *errormsg = NULL, *op, *tmp_str, *initfield;
01163    struct rt_multi_cfg_entry_args args;
01164    const char **params, **vals;
01165    struct ast_config *cfg;
01166    size_t params_count;
01167    int error;
01168 
01169    if (!table) {
01170       ast_log(LOG_WARNING, "Table name unspecified\n");
01171       return NULL;
01172    }
01173 
01174    if (!(cfg = ast_config_new())) {
01175       ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01176       return NULL;
01177    }
01178 
01179    if (!(params_count = get_params(ap, &params, &vals))) {
01180       ast_config_destroy(cfg);
01181       return NULL;
01182    }
01183 
01184    if (!(initfield = ast_strdup(params[0]))) {
01185       ast_config_destroy(cfg);
01186       ast_free(params);
01187       ast_free(vals);
01188       return NULL;
01189    }
01190 
01191    tmp_str = strchr(initfield, ' ');
01192 
01193    if (tmp_str)
01194       *tmp_str = '\0';
01195 
01196    op = (!strchr(params[0], ' ')) ? " =" : "";
01197 
01198    /*
01199     * Asterisk sends us an already escaped string when searching for
01200     * "exten LIKE" (uh!). Handle it separately.
01201     */
01202    tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0];
01203 
01204 /* \cond DOXYGEN_CAN_PARSE_THIS */
01205 #undef QUERY
01206 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
01207 /* \endcond */
01208 
01209    if (!(query = sqlite_mprintf(QUERY, table, params[0], op, tmp_str))) {
01210       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01211       ast_config_destroy(cfg);
01212       ast_free(params);
01213       ast_free(vals);
01214       ast_free(initfield);
01215       return NULL;
01216    }
01217 
01218    if (params_count > 1) {
01219       size_t i;
01220 
01221       for (i = 1; i < params_count; i++) {
01222          op = (!strchr(params[i], ' ')) ? " =" : "";
01223          tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01224          sqlite_freemem(query);
01225 
01226          if (!tmp_str) {
01227             ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01228             ast_config_destroy(cfg);
01229             ast_free(params);
01230             ast_free(vals);
01231             ast_free(initfield);
01232             return NULL;
01233          }
01234 
01235          query = tmp_str;
01236       }
01237    }
01238 
01239    ast_free(params);
01240    ast_free(vals);
01241 
01242    if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01243       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01244       sqlite_freemem(query);
01245       ast_config_destroy(cfg);
01246       ast_free(initfield);
01247       return NULL;
01248    }
01249 
01250    sqlite_freemem(query);
01251    query = tmp_str;
01252    ast_debug(1, "SQL query: %s\n", query);
01253    args.cfg = cfg;
01254    args.initfield = initfield;
01255 
01256    ast_mutex_lock(&mutex);
01257 
01258    RES_CONFIG_SQLITE_BEGIN
01259       error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01260    RES_CONFIG_SQLITE_END(error)
01261 
01262    ast_mutex_unlock(&mutex);
01263 
01264    sqlite_freemem(query);
01265    ast_free(initfield);
01266 
01267    if (error) {
01268       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01269       sqlite_freemem(errormsg);
01270       ast_config_destroy(cfg);
01271       return NULL;
01272    }
01273    sqlite_freemem(errormsg);
01274 
01275    return cfg;
01276 }

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

Definition at line 1531 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, sqlite_cache_columns::list, LOG_WARNING, sqlite_cache_columns::name, and type.

01532 {
01533    struct sqlite_cache_tables *tbl = find_table(tablename);
01534    struct sqlite_cache_columns *col;
01535    char *elm;
01536    int type, size, res = 0;
01537 
01538    if (!tbl) {
01539       return -1;
01540    }
01541 
01542    while ((elm = va_arg(ap, char *))) {
01543       type = va_arg(ap, require_type);
01544       size = va_arg(ap, int);
01545       /* Check if the field matches the criteria */
01546       AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01547          if (strcmp(col->name, elm) == 0) {
01548             /* SQLite only has two types - the 32-bit integer field that
01549              * is the key column, and everything else (everything else
01550              * being a string).
01551              */
01552             if (col->isint && !ast_rq_is_int(type)) {
01553                ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01554                res = -1;
01555             }
01556             break;
01557          }
01558       }
01559       if (!col) {
01560          ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01561       }
01562    }
01563    AST_RWLIST_UNLOCK(&(tbl->columns));
01564    return res;
01565 }

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 1360 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.

01361 {
01362    char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01363    const char **params, **vals;
01364    size_t params_count;
01365    int error, rows_id;
01366    size_t i;
01367 
01368    if (!table) {
01369       ast_log(LOG_WARNING, "Table name unspecified\n");
01370       return -1;
01371    }
01372 
01373    if (!(params_count = get_params(ap, &params, &vals)))
01374       return -1;
01375 
01376 /* \cond DOXYGEN_CAN_PARSE_THIS */
01377 #undef QUERY
01378 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01379 /* \endcond */
01380 
01381    for (i = 0; i < params_count; i++) {
01382       if ( tmp_keys2 ) {
01383          tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]);
01384          sqlite_freemem(tmp_keys2);
01385       } else {
01386          tmp_keys = sqlite_mprintf("%q", params[i]);
01387       }
01388       if (!tmp_keys) {
01389          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01390          sqlite_freemem(tmp_vals);
01391          ast_free(params);
01392          ast_free(vals);
01393          return -1;
01394       }
01395 
01396       if ( tmp_vals2 ) {
01397          tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, params[i]);
01398          sqlite_freemem(tmp_vals2);
01399       } else {
01400          tmp_vals = sqlite_mprintf("'%q'", params[i]);
01401       }
01402       if (!tmp_vals) {
01403          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01404          sqlite_freemem(tmp_keys);
01405          ast_free(params);
01406          ast_free(vals);
01407          return -1;
01408       }
01409 
01410 
01411       tmp_keys2 = tmp_keys;
01412       tmp_vals2 = tmp_vals;
01413    }
01414 
01415    ast_free(params);
01416    ast_free(vals);
01417 
01418    if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01419       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01420       sqlite_freemem(tmp_keys);
01421       sqlite_freemem(tmp_vals);
01422       return -1;
01423    }
01424 
01425    sqlite_freemem(tmp_keys);
01426    sqlite_freemem(tmp_vals);
01427 
01428    ast_debug(1, "SQL query: %s\n", tmp_str);
01429 
01430    ast_mutex_lock(&mutex);
01431 
01432    RES_CONFIG_SQLITE_BEGIN
01433       error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01434    RES_CONFIG_SQLITE_END(error)
01435 
01436    if (!error) {
01437       rows_id = sqlite_last_insert_rowid(db);
01438    } else {
01439       rows_id = -1;
01440    }
01441 
01442    ast_mutex_unlock(&mutex);
01443 
01444    sqlite_freemem(tmp_str);
01445 
01446    if (error) {
01447       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01448    }
01449    sqlite_freemem(errormsg);
01450 
01451    return rows_id;
01452 }

static int realtime_unload_handler ( const char *  unused,
const char *  tablename 
) [static]

Definition at line 1567 of file res_config_sqlite.c.

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_table(), sqlite_cache_tables::list, and sqlite_cache_tables::name.

01568 {
01569    struct sqlite_cache_tables *tbl;
01570    AST_RWLIST_WRLOCK(&sqlite_tables);
01571    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) {
01572       if (!strcasecmp(tbl->name, tablename)) {
01573          AST_RWLIST_REMOVE_CURRENT(list);
01574          free_table(tbl);
01575       }
01576    }
01577    AST_RWLIST_TRAVERSE_SAFE_END
01578    AST_RWLIST_UNLOCK(&sqlite_tables);
01579    return 0;
01580 }

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 1278 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.

01280 {
01281    char *query, *errormsg = NULL, *tmp_str;
01282    const char **params, **vals;
01283    size_t params_count;
01284    int error, rows_num;
01285 
01286    if (!table) {
01287       ast_log(LOG_WARNING, "Table name unspecified\n");
01288       return -1;
01289    }
01290 
01291    if (!(params_count = get_params(ap, &params, &vals)))
01292       return -1;
01293 
01294 /* \cond DOXYGEN_CAN_PARSE_THIS */
01295 #undef QUERY
01296 #define QUERY "UPDATE '%q' SET %q = '%q'"
01297 /* \endcond */
01298 
01299    if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) {
01300       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01301       ast_free(params);
01302       ast_free(vals);
01303       return -1;
01304    }
01305 
01306    if (params_count > 1) {
01307       size_t i;
01308 
01309       for (i = 1; i < params_count; i++) {
01310          tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]);
01311          sqlite_freemem(query);
01312 
01313          if (!tmp_str) {
01314             ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01315             ast_free(params);
01316             ast_free(vals);
01317             return -1;
01318          }
01319 
01320          query = tmp_str;
01321       }
01322    }
01323 
01324    ast_free(params);
01325    ast_free(vals);
01326 
01327    if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01328       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01329       sqlite_freemem(query);
01330       return -1;
01331    }
01332 
01333    sqlite_freemem(query);
01334    query = tmp_str;
01335    ast_debug(1, "SQL query: %s\n", query);
01336 
01337    ast_mutex_lock(&mutex);
01338 
01339    RES_CONFIG_SQLITE_BEGIN
01340       error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01341    RES_CONFIG_SQLITE_END(error)
01342 
01343    if (!error)
01344       rows_num = sqlite_changes(db);
01345    else
01346       rows_num = -1;
01347 
01348    ast_mutex_unlock(&mutex);
01349 
01350    sqlite_freemem(query);
01351 
01352    if (error) {
01353       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01354    }
01355    sqlite_freemem(errormsg);
01356 
01357    return rows_num;
01358 }

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 700 of file res_config_sqlite.c.

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

00701 {
00702    if (*var)
00703       ast_free(*var);
00704 
00705    *var = ast_strdup(value);
00706 
00707    if (!*var) {
00708       ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name);
00709       return 1;
00710    }
00711 
00712    return 0;
00713 }

static void unload_config ( void   )  [static]

Free resources related to configuration.

See also:
load_config()

Definition at line 763 of file res_config_sqlite.c.

References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_table(), and sqlite_cache_tables::list.

Referenced by unload_module().

00764 {
00765    struct sqlite_cache_tables *tbl;
00766    ast_free(dbfile);
00767    dbfile = NULL;
00768    ast_free(config_table);
00769    config_table = NULL;
00770    ast_free(cdr_table);
00771    cdr_table = NULL;
00772    AST_RWLIST_WRLOCK(&sqlite_tables);
00773    while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) {
00774       free_table(tbl);
00775    }
00776    AST_RWLIST_UNLOCK(&sqlite_tables);
00777 }

static int unload_module ( void   )  [static]

Definition at line 1654 of file res_config_sqlite.c.

References ast_cdr_unregister(), ast_cli_unregister_multiple(), ast_config_engine_deregister(), cli_status, RES_CONFIG_SQLITE_NAME, sqlite_engine, and unload_config().

01655 {
01656    if (cli_status_registered)
01657       ast_cli_unregister_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
01658 
01659    if (cdr_registered)
01660       ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
01661 
01662    ast_config_engine_deregister(&sqlite_engine);
01663 
01664    if (db)
01665       sqlite_close(db);
01666 
01667    unload_config();
01668 
01669    return 0;
01670 }


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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static]

Definition at line 1787 of file res_config_sqlite.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1787 of file res_config_sqlite.c.

int cdr_registered [static]

Set to 1 if the CDR callback function was registered.

Definition at line 460 of file res_config_sqlite.c.

char* cdr_table [static]

The name of the table used to store CDR entries.

Definition at line 472 of file res_config_sqlite.c.

struct ast_cli_entry cli_status[] [static]

Initial value:

 {
   { .handler =  handle_cli_show_sqlite_status , .summary =  "Show status information about the SQLite 2 driver" ,__VA_ARGS__ },
   { .handler =  handle_cli_sqlite_show_tables , .summary =  "Cached table information about the SQLite 2 driver" ,__VA_ARGS__ },
}
Structure containing details and callback functions for the CLI status command.

Definition at line 500 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 463 of file res_config_sqlite.c.

char* config_table [static]

The name of the static configuration table.

Definition at line 469 of file res_config_sqlite.c.

sqlite* db [static]

The SQLite database object.

Definition at line 454 of file res_config_sqlite.c.

char* dbfile [static]

The path of the database file.

Definition at line 466 of file res_config_sqlite.c.

ast_mutex_t mutex = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

The mutex used to prevent simultaneous access to the SQLite database.

Definition at line 494 of file res_config_sqlite.c.

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

char* sql_create_cdr_table [static]

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

Definition at line 525 of file res_config_sqlite.c.

Referenced by load_module().

struct ast_config_engine sqlite_engine [static]

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

Definition at line 478 of file res_config_sqlite.c.

Referenced by load_module(), and unload_module().

int use_cdr [static]

Set to 1 if CDR support is enabled.

Definition at line 457 of file res_config_sqlite.c.


Generated on Wed Aug 18 22:34:31 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7