Wed Jan 27 20:02:47 2016

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  _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_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
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 94 of file res_config_sqlite.c.

#define MACRO_END   } while (0)

Definition at line 95 of file res_config_sqlite.c.

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

Definition at line 711 of file res_config_sqlite.c.

#define RES_CONFIG_SQLITE_BEGIN
#define RES_CONFIG_SQLITE_CONF_FILE   "res_config_sqlite.conf"

Definition at line 100 of file res_config_sqlite.c.

Referenced by load_config().

#define RES_CONFIG_SQLITE_DESCRIPTION   "Resource Module for SQLite 2"

Definition at line 99 of file res_config_sqlite.c.

Referenced by load_module().

#define RES_CONFIG_SQLITE_DRIVER   "sqlite"

Definition at line 98 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 164 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 146 of file res_config_sqlite.c.

#define RES_CONFIG_SQLITE_NAME   "res_config_sqlite"

Definition at line 97 of file res_config_sqlite.c.

Referenced by load_module(), and unload_module().

#define SET_VAR ( config,
to,
from   ) 

Definition at line 114 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 569 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 561 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 102 of file res_config_sqlite.c.


Function Documentation

static void __init_sql_buf ( void   )  [static]

Definition at line 127 of file res_config_sqlite.c.

00157 {

static void __init_where_buf ( void   )  [static]

Definition at line 128 of file res_config_sqlite.c.

00157 {

static void __reg_module ( void   )  [static]

Definition at line 1877 of file res_config_sqlite.c.

static void __unreg_module ( void   )  [static]

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

References args, 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().

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

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

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

Referenced by realtime_handler().

01007 {
01008    struct rt_cfg_entry_args *args;
01009    struct ast_variable *var;
01010    int i;
01011 
01012    args = arg;
01013 
01014    for (i = 0; i < argc; i++) {
01015       if (!argv[i])
01016          continue;
01017 
01018       if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
01019          return 1;
01020 
01021       if (!args->var)
01022          args->var = var;
01023 
01024       if (!args->last)
01025          args->last = var;
01026       else {
01027          args->last->next = var;
01028          args->last = var;
01029       }
01030    }
01031 
01032    return 0;
01033 }

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

References args, 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().

01126 {
01127    struct rt_multi_cfg_entry_args *args;
01128    struct ast_category *cat;
01129    struct ast_variable *var;
01130    char *cat_name;
01131    size_t i;
01132 
01133    args = arg;
01134    cat_name = NULL;
01135 
01136    /*
01137     * cat_name should always be set here, since initfield is forged from
01138     * params[0] in realtime_multi_handler(), which is a search parameter
01139     * of the SQL query.
01140     */
01141    for (i = 0; i < argc; i++) {
01142       if (!strcmp(args->initfield, columnNames[i]))
01143          cat_name = argv[i];
01144    }
01145 
01146    if (!cat_name) {
01147       ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
01148       return 1;
01149    }
01150 
01151    if (!(cat = ast_category_new(cat_name, "", 99999))) {
01152       ast_log(LOG_WARNING, "Unable to allocate category\n");
01153       return 1;
01154    }
01155 
01156    ast_category_append(args->cfg, cat);
01157 
01158    for (i = 0; i < argc; i++) {
01159       if (!argv[i]) {
01160          continue;
01161       }
01162 
01163       if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01164          ast_log(LOG_WARNING, "Unable to allocate variable\n");
01165          return 1;
01166       }
01167 
01168       ast_variable_append(cat, var);
01169    }
01170 
01171    return 0;
01172 }

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

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

static int check_vars ( void   )  [static]

Definition at line 728 of file res_config_sqlite.c.

References ast_log(), and LOG_ERROR.

Referenced by load_config().

00729 {
00730    if (!dbfile) {
00731       ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00732       return 1;
00733    }
00734 
00735    use_cdr = (cdr_table != NULL);
00736 
00737    return 0;
00738 }

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.
who_asked 
Return values:
cfg object
NULL if an error occurred
See also:
add_cfg_entry()

Definition at line 917 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.

00919 {
00920    struct cfg_entry_args args;
00921    char *query, *errormsg = NULL;
00922    int error;
00923 
00924    if (!config_table) {
00925       if (!table) {
00926          ast_log(LOG_ERROR, "Table name unspecified\n");
00927          return NULL;
00928       }
00929    } else
00930       table = config_table;
00931 
00932    query = sqlite_mprintf(sql_get_config_table, table, file);
00933 
00934    if (!query) {
00935       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00936       return NULL;
00937    }
00938 
00939    ast_debug(1, "SQL query: %s\n", query);
00940    args.cfg = cfg;
00941    args.cat = NULL;
00942    args.cat_name = NULL;
00943    args.flags = flags;
00944    args.who_asked = who_asked;
00945 
00946    ast_mutex_lock(&mutex);
00947 
00948    RES_CONFIG_SQLITE_BEGIN
00949       error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg);
00950    RES_CONFIG_SQLITE_END(error)
00951 
00952    ast_mutex_unlock(&mutex);
00953 
00954    ast_free(args.cat_name);
00955    sqlite_freemem(query);
00956 
00957    if (error) {
00958       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00959       sqlite_freemem(errormsg);
00960       return NULL;
00961    }
00962    sqlite_freemem(errormsg);
00963 
00964    return cfg;
00965 }

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

Definition at line 644 of file res_config_sqlite.c.

References ast_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, 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().

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

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

Definition at line 589 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, ast_strdupa, sqlite_cache_tables::columns, sqlite_cache_columns::isint, sqlite_cache_columns::name, and sqlite_cache_columns::type.

Referenced by find_table().

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

static void free_table ( struct sqlite_cache_tables tblptr  )  [static]

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

00576 {
00577    struct sqlite_cache_columns *col;
00578 
00579    /* Obtain a write lock to ensure there are no read locks outstanding */
00580    AST_RWLIST_WRLOCK(&(tblptr->columns));
00581    while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) {
00582       ast_free(col);
00583    }
00584    AST_RWLIST_UNLOCK(&(tblptr->columns));
00585    AST_RWLIST_HEAD_DESTROY(&(tblptr->columns));
00586    ast_free(tblptr);
00587 }

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
warn 
Return values:
the number of elements in the arrays (which have the same size).
0 if an error occurred.

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

00968 {
00969    const char **tmp, *param, *val, **params, **vals;
00970    size_t params_count;
00971 
00972    params = NULL;
00973    vals = NULL;
00974    params_count = 0;
00975 
00976    while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) {
00977       if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) {
00978          ast_free(params);
00979          ast_free(vals);
00980          return 0;
00981       }
00982       params = tmp;
00983 
00984       if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) {
00985          ast_free(params);
00986          ast_free(vals);
00987          return 0;
00988       }
00989       vals = tmp;
00990 
00991       params[params_count] = param;
00992       vals[params_count] = val;
00993       params_count++;
00994    }
00995 
00996    if (params_count > 0) {
00997       *params_ptr = params;
00998       *vals_ptr = vals;
00999    } else if (warn) {
01000       ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n");
01001    }
01002 
01003    return params_count;
01004 }

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

01672 {
01673    switch (cmd) {
01674    case CLI_INIT:
01675       e->command = "sqlite show status";
01676       e->usage =
01677          "Usage: sqlite show status\n"
01678          "       Show status information about the SQLite 2 driver\n";
01679       return NULL;
01680    case CLI_GENERATE:
01681       return NULL;
01682    }
01683 
01684    if (a->argc != 3)
01685       return CLI_SHOWUSAGE;
01686 
01687    ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01688    ast_cli(a->fd, "config_table: ");
01689 
01690    if (!config_table)
01691       ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01692    else
01693       ast_cli(a->fd, "%s\n", config_table);
01694 
01695    ast_cli(a->fd, "cdr_table: ");
01696 
01697    if (!cdr_table)
01698       ast_cli(a->fd, "unspecified, CDR support disabled\n");
01699    else
01700       ast_cli(a->fd, "%s\n", cdr_table);
01701 
01702    return CLI_SUCCESS;
01703 }

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

Definition at line 1705 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.

01706 {
01707    struct sqlite_cache_tables *tbl;
01708    struct sqlite_cache_columns *col;
01709    int found = 0;
01710 
01711    switch (cmd) {
01712    case CLI_INIT:
01713       e->command = "sqlite show tables";
01714       e->usage =
01715          "Usage: sqlite show tables\n"
01716          "       Show table information about the SQLite 2 driver\n";
01717       return NULL;
01718    case CLI_GENERATE:
01719       return NULL;
01720    }
01721 
01722    if (a->argc != 3)
01723       return CLI_SHOWUSAGE;
01724 
01725    AST_RWLIST_RDLOCK(&sqlite_tables);
01726    AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01727       found++;
01728       ast_cli(a->fd, "Table %s:\n", tbl->name);
01729       AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01730          fprintf(stderr, "%s\n", col->name);
01731          ast_cli(a->fd, "  %20.20s  %-30.30s\n", col->name, col->type);
01732       }
01733    }
01734    AST_RWLIST_UNLOCK(&sqlite_tables);
01735 
01736    if (!found) {
01737       ast_cli(a->fd, "No tables currently in cache\n");
01738    }
01739 
01740    return CLI_SUCCESS;
01741 }

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

00741 {
00742    struct ast_config *config;
00743    struct ast_variable *var;
00744    int error;
00745    struct ast_flags config_flags = { 0 };
00746 
00747    config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags);
00748 
00749    if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
00750       ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n");
00751       return 1;
00752    }
00753 
00754    for (var = ast_variable_browse(config, "general"); var; var = var->next) {
00755       if (!strcasecmp(var->name, "dbfile"))
00756          SET_VAR(config, dbfile, var);
00757       else if (!strcasecmp(var->name, "config_table"))
00758          SET_VAR(config, config_table, var);
00759       else if (!strcasecmp(var->name, "cdr_table")) {
00760          SET_VAR(config, cdr_table, var);
00761       } else
00762          ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name);
00763    }
00764 
00765    ast_config_destroy(config);
00766    error = check_vars();
00767 
00768    if (error) {
00769       unload_config();
00770       return 1;
00771    }
00772 
00773    return 0;
00774 }

static int load_module ( void   )  [static]

Definition at line 1761 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.

01762 {
01763    char *errormsg = NULL;
01764    int error;
01765 
01766    db = NULL;
01767    cdr_registered = 0;
01768    cli_status_registered = 0;
01769    dbfile = NULL;
01770    config_table = NULL;
01771    cdr_table = NULL;
01772    error = load_config();
01773 
01774    if (error)
01775       return AST_MODULE_LOAD_DECLINE;
01776 
01777    if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01778       ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01779       sqlite_freemem(errormsg);
01780       unload_module();
01781       return 1;
01782    }
01783 
01784    sqlite_freemem(errormsg);
01785    errormsg = NULL;
01786    ast_config_engine_register(&sqlite_engine);
01787 
01788    if (use_cdr) {
01789       char *query;
01790 
01791 /* \cond DOXYGEN_CAN_PARSE_THIS */
01792 #undef QUERY
01793 #define QUERY "SELECT COUNT(id) FROM %Q;"
01794 /* \endcond */
01795 
01796       query = sqlite_mprintf(QUERY, cdr_table);
01797 
01798       if (!query) {
01799          ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01800          unload_module();
01801          return 1;
01802       }
01803 
01804       ast_debug(1, "SQL query: %s\n", query);
01805 
01806       RES_CONFIG_SQLITE_BEGIN
01807          error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01808       RES_CONFIG_SQLITE_END(error)
01809 
01810       sqlite_freemem(query);
01811 
01812       if (error) {
01813          /*
01814           * Unexpected error.
01815           */
01816          if (error != SQLITE_ERROR) {
01817             ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01818             sqlite_freemem(errormsg);
01819             unload_module();
01820             return 1;
01821          }
01822 
01823          sqlite_freemem(errormsg);
01824          errormsg = NULL;
01825          query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01826 
01827          if (!query) {
01828             ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01829             unload_module();
01830             return 1;
01831          }
01832 
01833          ast_debug(1, "SQL query: %s\n", query);
01834 
01835          RES_CONFIG_SQLITE_BEGIN
01836             error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01837          RES_CONFIG_SQLITE_END(error)
01838 
01839          sqlite_freemem(query);
01840 
01841          if (error) {
01842             ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01843             sqlite_freemem(errormsg);
01844             unload_module();
01845             return 1;
01846          }
01847       }
01848       sqlite_freemem(errormsg);
01849       errormsg = NULL;
01850 
01851       error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01852 
01853       if (error) {
01854          unload_module();
01855          return 1;
01856       }
01857 
01858       cdr_registered = 1;
01859    }
01860 
01861    error = ast_cli_register_multiple(cli_status, ARRAY_LEN(cli_status));
01862 
01863    if (error) {
01864       unload_module();
01865       return 1;
01866    }
01867 
01868    cli_status_registered = 1;
01869 
01870    return 0;
01871 }

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

01545 {
01546    char *query, *errormsg = NULL, *tmp_str;
01547    const char **params = NULL, **vals = NULL;
01548    size_t params_count;
01549    int error, rows_num;
01550    size_t i;
01551 
01552    if (!table) {
01553       ast_log(LOG_WARNING, "Table name unspecified\n");
01554       return -1;
01555    }
01556 
01557    params_count = get_params(ap, &params, &vals, 0);
01558 
01559 /* \cond DOXYGEN_CAN_PARSE_THIS */
01560 #undef QUERY
01561 #define QUERY "DELETE FROM '%q' WHERE"
01562 /* \endcond */
01563 
01564    if (!(query = sqlite_mprintf(QUERY, table))) {
01565       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01566       ast_free(params);
01567       ast_free(vals);
01568       return -1;
01569    }
01570 
01571    for (i = 0; i < params_count; i++) {
01572       tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01573       sqlite_freemem(query);
01574 
01575       if (!tmp_str) {
01576          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01577          ast_free(params);
01578          ast_free(vals);
01579          return -1;
01580       }
01581 
01582       query = tmp_str;
01583    }
01584 
01585    ast_free(params);
01586    ast_free(vals);
01587    if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01588       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01589       sqlite_freemem(query);
01590       return -1;
01591    }
01592    sqlite_freemem(query);
01593    query = tmp_str;
01594    ast_debug(1, "SQL query: %s\n", query);
01595 
01596    ast_mutex_lock(&mutex);
01597 
01598    RES_CONFIG_SQLITE_BEGIN
01599       error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01600    RES_CONFIG_SQLITE_END(error)
01601 
01602    if (!error) {
01603       rows_num = sqlite_changes(db);
01604    } else {
01605       rows_num = -1;
01606    }
01607 
01608    ast_mutex_unlock(&mutex);
01609 
01610    sqlite_freemem(query);
01611 
01612    if (error) {
01613       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01614    }
01615    sqlite_freemem(errormsg);
01616 
01617    return rows_num;
01618 }

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

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

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

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

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

Definition at line 1620 of file res_config_sqlite.c.

References ast_log(), 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.

01621 {
01622    struct sqlite_cache_tables *tbl = find_table(tablename);
01623    struct sqlite_cache_columns *col;
01624    char *elm;
01625    int type, res = 0;
01626 
01627    if (!tbl) {
01628       return -1;
01629    }
01630 
01631    while ((elm = va_arg(ap, char *))) {
01632       type = va_arg(ap, require_type);
01633       va_arg(ap, int);
01634       /* Check if the field matches the criteria */
01635       AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01636          if (strcmp(col->name, elm) == 0) {
01637             /* SQLite only has two types - the 32-bit integer field that
01638              * is the key column, and everything else (everything else
01639              * being a string).
01640              */
01641             if (col->isint && !ast_rq_is_int(type)) {
01642                ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01643                res = -1;
01644             }
01645             break;
01646          }
01647       }
01648       if (!col) {
01649          ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01650       }
01651    }
01652    AST_RWLIST_UNLOCK(&(tbl->columns));
01653    return res;
01654 }

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

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

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 1375 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, value, and where_buf.

01377 {
01378    char *errormsg = NULL, *tmp1, *tmp2;
01379    int error, rows_num, first = 1;
01380    struct ast_str *sql = ast_str_thread_get(&sql_buf, 100);
01381    struct ast_str *where = ast_str_thread_get(&where_buf, 100);
01382    const char *param, *value;
01383 
01384    if (!table) {
01385       ast_log(LOG_WARNING, "Table name unspecified\n");
01386       return -1;
01387    }
01388 
01389    if (!sql) {
01390       return -1;
01391    }
01392 
01393    ast_str_set(&sql, 0, "UPDATE %s SET", table);
01394    ast_str_set(&where, 0, " WHERE");
01395 
01396    while ((param = va_arg(ap, const char *))) {
01397       value = va_arg(ap, const char *);
01398       ast_str_append(&where, 0, "%s %s = %s",
01399          first ? "" : " AND",
01400          tmp1 = sqlite_mprintf("%q", param),
01401          tmp2 = sqlite_mprintf("%Q", value));
01402       sqlite_freemem(tmp1);
01403       sqlite_freemem(tmp2);
01404       first = 0;
01405    }
01406 
01407    if (first) {
01408       ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database);
01409       return -1;
01410    }
01411 
01412    first = 1;
01413    while ((param = va_arg(ap, const char *))) {
01414       value = va_arg(ap, const char *);
01415       ast_str_append(&sql, 0, "%s %s = %s",
01416          first ? "" : ",",
01417          tmp1 = sqlite_mprintf("%q", param),
01418          tmp2 = sqlite_mprintf("%Q", value));
01419       sqlite_freemem(tmp1);
01420       sqlite_freemem(tmp2);
01421       first = 0;
01422    }
01423 
01424    ast_str_append(&sql, 0, " %s", ast_str_buffer(where));
01425    ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql));
01426 
01427    ast_mutex_lock(&mutex);
01428 
01429    RES_CONFIG_SQLITE_BEGIN
01430       error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg);
01431    RES_CONFIG_SQLITE_END(error)
01432 
01433    if (!error) {
01434       rows_num = sqlite_changes(db);
01435    } else {
01436       rows_num = -1;
01437    }
01438 
01439    ast_mutex_unlock(&mutex);
01440 
01441    if (error) {
01442       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01443    }
01444    sqlite_freemem(errormsg);
01445 
01446    return rows_num;
01447 }

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

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

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

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

00714 {
00715    if (*var)
00716       ast_free(*var);
00717 
00718    *var = ast_strdup(value);
00719 
00720    if (!*var) {
00721       ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name);
00722       return 1;
00723    }
00724 
00725    return 0;
00726 }

static void unload_config ( void   )  [static]

Free resources related to configuration.

See also:
load_config()

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

00777 {
00778    struct sqlite_cache_tables *tbl;
00779    ast_free(dbfile);
00780    dbfile = NULL;
00781    ast_free(config_table);
00782    config_table = NULL;
00783    ast_free(cdr_table);
00784    cdr_table = NULL;
00785    AST_RWLIST_WRLOCK(&sqlite_tables);
00786    while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) {
00787       free_table(tbl);
00788    }
00789    AST_RWLIST_UNLOCK(&sqlite_tables);
00790 }

static int unload_module ( void   )  [static]

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, } [static]

Definition at line 1877 of file res_config_sqlite.c.

Definition at line 1877 of file res_config_sqlite.c.

int cdr_registered [static]

Set to 1 if the CDR callback function was registered.

Definition at line 468 of file res_config_sqlite.c.

char* cdr_table [static]

The name of the table used to store CDR entries.

Definition at line 480 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 509 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 471 of file res_config_sqlite.c.

char* config_table [static]

The name of the static configuration table.

Definition at line 477 of file res_config_sqlite.c.

sqlite* db [static]

The SQLite database object.

Definition at line 462 of file res_config_sqlite.c.

char* dbfile [static]

The path of the database file.

Definition at line 474 of file res_config_sqlite.c.

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

Definition at line 127 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 534 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 486 of file res_config_sqlite.c.

int use_cdr [static]

Set to 1 if CDR support is enabled.

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

Referenced by realtime_update2_handler().


Generated on 27 Jan 2016 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1