res_config_sqlite.c File Reference

res_config_sqlite module. More...

#include "asterisk.h"
#include <sqlite.h>
#include "asterisk/logger.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/cdr.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/linkedlists.h"

Include dependency graph for res_config_sqlite.c:

Go to the source code of this file.

Data Structures

struct  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 __fini_sqlite_tables (void)
static void __init_sql_buf (void)
static void __init_sqlite_tables (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 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)
 Load the module.
static int realtime_destroy_handler (const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
 Asterisk callback function for RealTime configuration (destroys variable).
static struct ast_variablerealtime_handler (const char *database, const char *table, const struct ast_variable *fields)
 Asterisk callback function for RealTime configuration.
static struct ast_configrealtime_multi_handler (const char *database, const char *table, const struct ast_variable *fields)
 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, const struct ast_variable *fields)
 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, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
static int realtime_update_handler (const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
 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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .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_MUTEX_INITIALIZER , 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 103 of file res_config_sqlite.c.

#define MACRO_END   } while (0)

Definition at line 104 of file res_config_sqlite.c.

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

Definition at line 694 of file res_config_sqlite.c.

#define RES_CONFIG_SQLITE_BEGIN

#define RES_CONFIG_SQLITE_CONF_FILE   "res_config_sqlite.conf"

Definition at line 109 of file res_config_sqlite.c.

Referenced by load_config().

#define RES_CONFIG_SQLITE_DESCRIPTION   "Resource Module for SQLite 2"

Definition at line 108 of file res_config_sqlite.c.

Referenced by load_module().

#define RES_CONFIG_SQLITE_DRIVER   "sqlite"

Definition at line 107 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 173 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 155 of file res_config_sqlite.c.

#define RES_CONFIG_SQLITE_NAME   "res_config_sqlite"

Definition at line 106 of file res_config_sqlite.c.

Referenced by load_module(), and unload_module().

#define SET_VAR ( config,
to,
from   ) 

Definition at line 123 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 552 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 544 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 111 of file res_config_sqlite.c.


Function Documentation

static void __fini_sqlite_tables ( void   )  [static]

Definition at line 510 of file res_config_sqlite.c.

00528 :00:00',\n"

static void __init_sql_buf ( void   )  [static]

Definition at line 136 of file res_config_sqlite.c.

00166 {

static void __init_sqlite_tables ( void   )  [static]

Definition at line 510 of file res_config_sqlite.c.

00528 :00:00',\n"

static void __init_where_buf ( void   )  [static]

Definition at line 137 of file res_config_sqlite.c.

00166 {

static void __reg_module ( void   )  [static]

Definition at line 1775 of file res_config_sqlite.c.

static void __unreg_module ( void   )  [static]

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

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

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

00951 {
00952    struct rt_cfg_entry_args *args;
00953    struct ast_variable *var;
00954    int i;
00955 
00956    args = arg;
00957 
00958    for (i = 0; i < argc; i++) {
00959       if (!argv[i])
00960          continue;
00961 
00962       if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
00963          return 1;
00964 
00965       if (!args->var)
00966          args->var = var;
00967 
00968       if (!args->last)
00969          args->last = var;
00970       else {
00971          args->last->next = var;
00972          args->last = var;
00973       }
00974    }
00975 
00976    return 0;
00977 }

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 1056 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, NULL, and var.

Referenced by realtime_multi_handler().

01057 {
01058    struct rt_multi_cfg_entry_args *args;
01059    struct ast_category *cat;
01060    struct ast_variable *var;
01061    char *cat_name;
01062    size_t i;
01063 
01064    args = arg;
01065    cat_name = NULL;
01066 
01067    /*
01068     * cat_name should always be set here, since initfield is forged from
01069     * params[0] in realtime_multi_handler(), which is a search parameter
01070     * of the SQL query.
01071     */
01072    for (i = 0; i < argc; i++) {
01073       if (!strcmp(args->initfield, columnNames[i]))
01074          cat_name = argv[i];
01075    }
01076 
01077    if (!cat_name) {
01078       ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
01079       return 1;
01080    }
01081 
01082    if (!(cat = ast_category_new(cat_name, "", 99999))) {
01083       ast_log(LOG_WARNING, "Unable to allocate category\n");
01084       return 1;
01085    }
01086 
01087    ast_category_append(args->cfg, cat);
01088 
01089    for (i = 0; i < argc; i++) {
01090       if (!argv[i]) {
01091          continue;
01092       }
01093 
01094       if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01095          ast_log(LOG_WARNING, "Unable to allocate variable\n");
01096          return 1;
01097       }
01098 
01099       ast_variable_append(cat, var);
01100    }
01101 
01102    return 0;
01103 }

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

References ast_cdr_format_var(), 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, error(), find_table(), first, sqlite_cache_columns::isint, LOG_ERROR, LOG_WARNING, mutex, sqlite_cache_columns::name, NULL, release_table, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and tmp().

Referenced by load_module().

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

static int check_vars ( void   )  [static]

Definition at line 711 of file res_config_sqlite.c.

References ast_log, LOG_ERROR, and NULL.

Referenced by load_config().

00712 {
00713    if (!dbfile) {
00714       ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00715       return 1;
00716    }
00717 
00718    use_cdr = (cdr_table != NULL);
00719 
00720    return 0;
00721 }

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 900 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, error(), cfg_entry_args::flags, LOG_ERROR, LOG_WARNING, mutex, NULL, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, sql_get_config_table, and cfg_entry_args::who_asked.

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

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

Definition at line 627 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, NULL, and sql_table_structure.

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

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

Definition at line 572 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, end, sqlite_cache_columns::isint, sqlite_cache_columns::name, strcasestr(), and sqlite_cache_columns::type.

Referenced by find_table().

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

static void free_table ( struct sqlite_cache_tables tblptr  )  [static]

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

00559 {
00560    struct sqlite_cache_columns *col;
00561 
00562    /* Obtain a write lock to ensure there are no read locks outstanding */
00563    AST_RWLIST_WRLOCK(&(tblptr->columns));
00564    while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) {
00565       ast_free(col);
00566    }
00567    AST_RWLIST_UNLOCK(&(tblptr->columns));
00568    AST_RWLIST_HEAD_DESTROY(&(tblptr->columns));
00569    ast_free(tblptr);
00570 }

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 1556 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, NULL, and ast_cli_entry::usage.

01557 {
01558    switch (cmd) {
01559    case CLI_INIT:
01560       e->command = "sqlite show status";
01561       e->usage =
01562          "Usage: sqlite show status\n"
01563          "       Show status information about the SQLite 2 driver\n";
01564       return NULL;
01565    case CLI_GENERATE:
01566       return NULL;
01567    }
01568 
01569    if (a->argc != 3)
01570       return CLI_SHOWUSAGE;
01571 
01572    ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01573    ast_cli(a->fd, "config_table: ");
01574 
01575    if (!config_table)
01576       ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01577    else
01578       ast_cli(a->fd, "%s\n", config_table);
01579 
01580    ast_cli(a->fd, "cdr_table: ");
01581 
01582    if (!cdr_table)
01583       ast_cli(a->fd, "unspecified, CDR support disabled\n");
01584    else
01585       ast_cli(a->fd, "%s\n", cdr_table);
01586 
01587    return CLI_SUCCESS;
01588 }

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

Definition at line 1590 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, NULL, sqlite_cache_columns::type, and ast_cli_entry::usage.

01591 {
01592    struct sqlite_cache_tables *tbl;
01593    struct sqlite_cache_columns *col;
01594    int found = 0;
01595 
01596    switch (cmd) {
01597    case CLI_INIT:
01598       e->command = "sqlite show tables";
01599       e->usage =
01600          "Usage: sqlite show tables\n"
01601          "       Show table information about the SQLite 2 driver\n";
01602       return NULL;
01603    case CLI_GENERATE:
01604       return NULL;
01605    }
01606 
01607    if (a->argc != 3)
01608       return CLI_SHOWUSAGE;
01609 
01610    AST_RWLIST_RDLOCK(&sqlite_tables);
01611    AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01612       found++;
01613       ast_cli(a->fd, "Table %s:\n", tbl->name);
01614       AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01615          fprintf(stderr, "%s\n", col->name);
01616          ast_cli(a->fd, "  %20.20s  %-30.30s\n", col->name, col->type);
01617       }
01618    }
01619    AST_RWLIST_UNLOCK(&sqlite_tables);
01620 
01621    if (!found) {
01622       ast_cli(a->fd, "No tables currently in cache\n");
01623    }
01624 
01625    return CLI_SUCCESS;
01626 }

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 723 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, error(), LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, RES_CONFIG_SQLITE_CONF_FILE, SET_VAR, unload_config(), and var.

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

static int load_module ( void   )  [static]

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 1658 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(), error(), load_config(), LOG_ERROR, NULL, 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.

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

static int realtime_destroy_handler ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
const struct ast_variable fields 
) [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
fields list of additional parameters for cell matching
Return values:
the number of affected rows.
-1 if an error occurred.

Definition at line 1438 of file res_config_sqlite.c.

References ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, error(), LOG_WARNING, mutex, ast_variable::name, ast_variable::next, NULL, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and ast_variable::value.

01440 {
01441    char *query, *errormsg = NULL, *tmp_str;
01442    const struct ast_variable *field;
01443    int error, rows_num;
01444 
01445    if (!table) {
01446       ast_log(LOG_WARNING, "Table name unspecified\n");
01447       return -1;
01448    }
01449 
01450 /* \cond DOXYGEN_CAN_PARSE_THIS */
01451 #undef QUERY
01452 #define QUERY "DELETE FROM '%q' WHERE"
01453 /* \endcond */
01454 
01455    if (!(query = sqlite_mprintf(QUERY, table))) {
01456       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01457       return -1;
01458    }
01459 
01460    for (field = fields; field; field = field->next) {
01461       tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, field->name, field->value);
01462       sqlite_freemem(query);
01463 
01464       if (!tmp_str) {
01465          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01466          return -1;
01467       }
01468 
01469       query = tmp_str;
01470    }
01471 
01472    if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01473       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01474       sqlite_freemem(query);
01475       return -1;
01476    }
01477    sqlite_freemem(query);
01478    query = tmp_str;
01479    ast_debug(1, "SQL query: %s\n", query);
01480 
01481    ast_mutex_lock(&mutex);
01482 
01483    RES_CONFIG_SQLITE_BEGIN
01484       error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01485    RES_CONFIG_SQLITE_END(error)
01486 
01487    if (!error) {
01488       rows_num = sqlite_changes(db);
01489    } else {
01490       rows_num = -1;
01491    }
01492 
01493    ast_mutex_unlock(&mutex);
01494 
01495    sqlite_freemem(query);
01496 
01497    if (error) {
01498       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01499    }
01500    sqlite_freemem(errormsg);
01501 
01502    return rows_num;
01503 }

static struct ast_variable * realtime_handler ( const char *  database,
const char *  table,
const struct ast_variable fields 
) [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
fields 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 979 of file res_config_sqlite.c.

References add_rt_cfg_entry(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_variables_destroy(), error(), rt_cfg_entry_args::last, LOG_WARNING, mutex, ast_variable::name, ast_variable::next, NULL, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, ast_variable::value, and rt_cfg_entry_args::var.

00980 {
00981    char *query, *errormsg = NULL, *op, *tmp_str;
00982    struct rt_cfg_entry_args args;
00983    const struct ast_variable *field = fields;
00984    int error;
00985 
00986    if (!table) {
00987       ast_log(LOG_WARNING, "Table name unspecified\n");
00988       return NULL;
00989    }
00990 
00991    if (!fields) {
00992       return NULL;
00993    }
00994 
00995    op = (strchr(field->name, ' ') == NULL) ? " =" : "";
00996 
00997 /* \cond DOXYGEN_CAN_PARSE_THIS */
00998 #undef QUERY
00999 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'"
01000 /* \endcond */
01001 
01002    query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", field->name, op, field->value);
01003 
01004    if (!query) {
01005       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01006       return NULL;
01007    }
01008 
01009    while ((field = field->next)) {
01010       op = (strchr(field->name, ' ') == NULL) ? " =" : "";
01011       tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, field->name, op, field->value);
01012       sqlite_freemem(query);
01013 
01014       if (!tmp_str) {
01015          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01016          return NULL;
01017       }
01018 
01019       query = tmp_str;
01020    }
01021 
01022    tmp_str = sqlite_mprintf("%s LIMIT 1;", query);
01023    sqlite_freemem(query);
01024 
01025    if (!tmp_str) {
01026       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01027       return NULL;
01028    }
01029 
01030    query = tmp_str;
01031    ast_debug(1, "SQL query: %s\n", query);
01032    args.var = NULL;
01033    args.last = NULL;
01034 
01035    ast_mutex_lock(&mutex);
01036 
01037    RES_CONFIG_SQLITE_BEGIN
01038       error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg);
01039    RES_CONFIG_SQLITE_END(error)
01040 
01041    ast_mutex_unlock(&mutex);
01042 
01043    sqlite_freemem(query);
01044 
01045    if (error) {
01046       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01047       sqlite_freemem(errormsg);
01048       ast_variables_destroy(args.var);
01049       return NULL;
01050    }
01051    sqlite_freemem(errormsg);
01052 
01053    return args.var;
01054 }

static struct ast_config * realtime_multi_handler ( const char *  database,
const char *  table,
const struct ast_variable fields 
) [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
fields 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 1105 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, error(), rt_multi_cfg_entry_args::initfield, LOG_WARNING, mutex, ast_variable::name, ast_variable::next, NULL, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and ast_variable::value.

01107 {
01108    char *query, *errormsg = NULL, *op, *tmp_str, *initfield;
01109    struct rt_multi_cfg_entry_args args;
01110    const struct ast_variable *field = fields;
01111    struct ast_config *cfg;
01112    int error;
01113 
01114    if (!table) {
01115       ast_log(LOG_WARNING, "Table name unspecified\n");
01116       return NULL;
01117    }
01118 
01119    if (!fields) {
01120       return NULL;
01121    }
01122 
01123    if (!(cfg = ast_config_new())) {
01124       ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01125       return NULL;
01126    }
01127 
01128    if (!(initfield = ast_strdup(field->name))) {
01129       ast_config_destroy(cfg);
01130       return NULL;
01131    }
01132 
01133    tmp_str = strchr(initfield, ' ');
01134 
01135    if (tmp_str)
01136       *tmp_str = '\0';
01137 
01138    op = (!strchr(field->name, ' ')) ? " =" : "";
01139 
01140    /*
01141     * Asterisk sends us an already escaped string when searching for
01142     * "exten LIKE" (uh!). Handle it separately.
01143     */
01144    tmp_str = (!strcmp(field->value, "\\_%")) ? "_%" : (char *)field->value;
01145 
01146 /* \cond DOXYGEN_CAN_PARSE_THIS */
01147 #undef QUERY
01148 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'"
01149 /* \endcond */
01150 
01151    if (!(query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", field->name, op, tmp_str))) {
01152       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01153       ast_config_destroy(cfg);
01154       ast_free(initfield);
01155       return NULL;
01156    }
01157 
01158    while ((field = field->next)) {
01159       op = (!strchr(field->name, ' ')) ? " =" : "";
01160       tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, field->name, op, field->value);
01161       sqlite_freemem(query);
01162 
01163       if (!tmp_str) {
01164          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01165          ast_config_destroy(cfg);
01166          ast_free(initfield);
01167          return NULL;
01168       }
01169 
01170       query = tmp_str;
01171    }
01172 
01173    if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01174       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01175       sqlite_freemem(query);
01176       ast_config_destroy(cfg);
01177       ast_free(initfield);
01178       return NULL;
01179    }
01180 
01181    sqlite_freemem(query);
01182    query = tmp_str;
01183    ast_debug(1, "SQL query: %s\n", query);
01184    args.cfg = cfg;
01185    args.initfield = initfield;
01186 
01187    ast_mutex_lock(&mutex);
01188 
01189    RES_CONFIG_SQLITE_BEGIN
01190       error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01191    RES_CONFIG_SQLITE_END(error)
01192 
01193    ast_mutex_unlock(&mutex);
01194 
01195    sqlite_freemem(query);
01196    ast_free(initfield);
01197 
01198    if (error) {
01199       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01200       sqlite_freemem(errormsg);
01201       ast_config_destroy(cfg);
01202       return NULL;
01203    }
01204    sqlite_freemem(errormsg);
01205 
01206    return cfg;
01207 }

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

Definition at line 1505 of file res_config_sqlite.c.

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

01506 {
01507    struct sqlite_cache_tables *tbl = find_table(tablename);
01508    struct sqlite_cache_columns *col;
01509    char *elm;
01510    int type, res = 0;
01511 
01512    if (!tbl) {
01513       return -1;
01514    }
01515 
01516    while ((elm = va_arg(ap, char *))) {
01517       type = va_arg(ap, require_type);
01518       va_arg(ap, int);
01519       /* Check if the field matches the criteria */
01520       AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01521          if (strcmp(col->name, elm) == 0) {
01522             /* SQLite only has two types - the 32-bit integer field that
01523              * is the key column, and everything else (everything else
01524              * being a string).
01525              */
01526             if (col->isint && !ast_rq_is_int(type)) {
01527                ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01528                res = -1;
01529             }
01530             break;
01531          }
01532       }
01533       if (!col) {
01534          ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01535       }
01536    }
01537    AST_RWLIST_UNLOCK(&(tbl->columns));
01538    return res;
01539 }

static int realtime_store_handler ( const char *  database,
const char *  table,
const struct ast_variable fields 
) [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
fields 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 1352 of file res_config_sqlite.c.

References ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, error(), LOG_WARNING, mutex, ast_variable::name, ast_variable::next, NULL, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and ast_variable::value.

01353 {
01354    char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01355    const struct ast_variable *field = fields;
01356    int error, rows_id;
01357 
01358    if (!table) {
01359       ast_log(LOG_WARNING, "Table name unspecified\n");
01360       return -1;
01361    }
01362 
01363    if (!fields) {
01364       return -1;
01365    }
01366 
01367 /* \cond DOXYGEN_CAN_PARSE_THIS */
01368 #undef QUERY
01369 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01370 /* \endcond */
01371 
01372    do {
01373       if ( tmp_keys2 ) {
01374          tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, field->name);
01375          sqlite_freemem(tmp_keys2);
01376       } else {
01377          tmp_keys = sqlite_mprintf("%q", field->name);
01378       }
01379       if (!tmp_keys) {
01380          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01381          sqlite_freemem(tmp_vals);
01382          return -1;
01383       }
01384 
01385       if ( tmp_vals2 ) {
01386          tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, field->value);
01387          sqlite_freemem(tmp_vals2);
01388       } else {
01389          tmp_vals = sqlite_mprintf("'%q'", field->value);
01390       }
01391       if (!tmp_vals) {
01392          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01393          sqlite_freemem(tmp_keys);
01394          return -1;
01395       }
01396 
01397 
01398       tmp_keys2 = tmp_keys;
01399       tmp_vals2 = tmp_vals;
01400    } while ((field = field->next));
01401 
01402    if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01403       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01404       sqlite_freemem(tmp_keys);
01405       sqlite_freemem(tmp_vals);
01406       return -1;
01407    }
01408 
01409    sqlite_freemem(tmp_keys);
01410    sqlite_freemem(tmp_vals);
01411 
01412    ast_debug(1, "SQL query: %s\n", tmp_str);
01413 
01414    ast_mutex_lock(&mutex);
01415 
01416    RES_CONFIG_SQLITE_BEGIN
01417       error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01418    RES_CONFIG_SQLITE_END(error)
01419 
01420    if (!error) {
01421       rows_id = sqlite_last_insert_rowid(db);
01422    } else {
01423       rows_id = -1;
01424    }
01425 
01426    ast_mutex_unlock(&mutex);
01427 
01428    sqlite_freemem(tmp_str);
01429 
01430    if (error) {
01431       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01432    }
01433    sqlite_freemem(errormsg);
01434 
01435    return rows_id;
01436 }

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

static int realtime_update2_handler ( const char *  database,
const char *  table,
const struct ast_variable lookup_fields,
const struct ast_variable update_fields 
) [static]

Definition at line 1280 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(), error(), first, LOG_ERROR, LOG_WARNING, mutex, ast_variable::name, ast_variable::next, NULL, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, sql_buf, ast_variable::value, and where_buf.

01282 {
01283    char *errormsg = NULL, *tmp1, *tmp2;
01284    int error, rows_num, first = 1;
01285    struct ast_str *sql = ast_str_thread_get(&sql_buf, 100);
01286    struct ast_str *where = ast_str_thread_get(&where_buf, 100);
01287    const struct ast_variable *field;
01288 
01289    if (!table) {
01290       ast_log(LOG_WARNING, "Table name unspecified\n");
01291       return -1;
01292    }
01293 
01294    if (!sql) {
01295       return -1;
01296    }
01297 
01298    ast_str_set(&sql, 0, "UPDATE %s SET", table);
01299    ast_str_set(&where, 0, " WHERE");
01300 
01301    for (field = lookup_fields; field; field = field->next) {
01302       ast_str_append(&where, 0, "%s %s = %s",
01303          first ? "" : " AND",
01304          tmp1 = sqlite_mprintf("%q", field->name),
01305          tmp2 = sqlite_mprintf("%Q", field->value));
01306       sqlite_freemem(tmp1);
01307       sqlite_freemem(tmp2);
01308       first = 0;
01309    }
01310 
01311    if (first) {
01312       ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database);
01313       return -1;
01314    }
01315 
01316    first = 1;
01317    for (field = update_fields; field; field = field->next) {
01318       ast_str_append(&sql, 0, "%s %s = %s",
01319          first ? "" : ",",
01320          tmp1 = sqlite_mprintf("%q", field->name),
01321          tmp2 = sqlite_mprintf("%Q", field->value));
01322       sqlite_freemem(tmp1);
01323       sqlite_freemem(tmp2);
01324       first = 0;
01325    }
01326 
01327    ast_str_append(&sql, 0, " %s", ast_str_buffer(where));
01328    ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql));
01329 
01330    ast_mutex_lock(&mutex);
01331 
01332    RES_CONFIG_SQLITE_BEGIN
01333       error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg);
01334    RES_CONFIG_SQLITE_END(error)
01335 
01336    if (!error) {
01337       rows_num = sqlite_changes(db);
01338    } else {
01339       rows_num = -1;
01340    }
01341 
01342    ast_mutex_unlock(&mutex);
01343 
01344    if (error) {
01345       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01346    }
01347    sqlite_freemem(errormsg);
01348 
01349    return rows_num;
01350 }

static int realtime_update_handler ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
const struct ast_variable fields 
) [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
fields 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 1209 of file res_config_sqlite.c.

References ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, error(), LOG_WARNING, mutex, ast_variable::name, ast_variable::next, NULL, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and ast_variable::value.

01211 {
01212    char *query, *errormsg = NULL, *tmp_str;
01213    const struct ast_variable *field = fields;
01214    int error, rows_num;
01215 
01216    if (!table) {
01217       ast_log(LOG_WARNING, "Table name unspecified\n");
01218       return -1;
01219    }
01220 
01221    if (!field) {
01222       return -1;
01223    }
01224 
01225 /* \cond DOXYGEN_CAN_PARSE_THIS */
01226 #undef QUERY
01227 #define QUERY "UPDATE '%q' SET %q = '%q'"
01228 /* \endcond */
01229 
01230    if (!(query = sqlite_mprintf(QUERY, table, field->name, field->value))) {
01231       ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01232       return -1;
01233    }
01234 
01235    while ((field = field->next)) {
01236       tmp_str = sqlite_mprintf("%s, %q = '%q'", query, field->name, field->value);
01237       sqlite_freemem(query);
01238 
01239       if (!tmp_str) {
01240          ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01241          return -1;
01242       }
01243 
01244       query = tmp_str;
01245    }
01246 
01247    if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01248       ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01249       sqlite_freemem(query);
01250       return -1;
01251    }
01252 
01253    sqlite_freemem(query);
01254    query = tmp_str;
01255    ast_debug(1, "SQL query: %s\n", query);
01256 
01257    ast_mutex_lock(&mutex);
01258 
01259    RES_CONFIG_SQLITE_BEGIN
01260       error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01261    RES_CONFIG_SQLITE_END(error)
01262 
01263    if (!error)
01264       rows_num = sqlite_changes(db);
01265    else
01266       rows_num = -1;
01267 
01268    ast_mutex_unlock(&mutex);
01269 
01270    sqlite_freemem(query);
01271 
01272    if (error) {
01273       ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01274    }
01275    sqlite_freemem(errormsg);
01276 
01277    return rows_num;
01278 }

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

References ast_free, ast_log, ast_strdup, and LOG_WARNING.

Referenced by main().

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

static void unload_config ( void   )  [static]

Free resources related to configuration.

See also:
load_config()

Definition at line 759 of file res_config_sqlite.c.

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

Referenced by load_config(), and unload_module().

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

static int unload_module ( void   )  [static]

Definition at line 1628 of file res_config_sqlite.c.

References ARRAY_LEN, ast_cdr_unregister(), ast_cli_unregister_multiple(), ast_config_engine_deregister(), RES_CONFIG_SQLITE_NAME, and unload_config().

01629 {
01630    if (cdr_registered && ast_cdr_unregister(RES_CONFIG_SQLITE_NAME)) {
01631       return -1;
01632    }
01633 
01634    if (cli_status_registered) {
01635       ast_cli_unregister_multiple(cli_status, ARRAY_LEN(cli_status));
01636    }
01637 
01638    ast_config_engine_deregister(&sqlite_engine);
01639 
01640    if (db)
01641       sqlite_close(db);
01642 
01643    unload_config();
01644 
01645    return 0;
01646 }


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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DRIVER, } [static]

Definition at line 1775 of file res_config_sqlite.c.

Definition at line 1775 of file res_config_sqlite.c.

int cdr_registered [static]

Set to 1 if the CDR callback function was registered.

Definition at line 451 of file res_config_sqlite.c.

char* cdr_table [static]

The name of the table used to store CDR entries.

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

char* config_table [static]

The name of the static configuration table.

Definition at line 460 of file res_config_sqlite.c.

sqlite* db [static]

The SQLite database object.

Definition at line 445 of file res_config_sqlite.c.

char* dbfile [static]

The path of the database file.

Definition at line 457 of file res_config_sqlite.c.

ast_mutex_t mutex = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

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

Definition at line 136 of file res_config_sqlite.c.

char* sql_create_cdr_table [static]

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

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

int use_cdr [static]

Set to 1 if CDR support is enabled.

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


Generated on Thu Apr 16 06:32:47 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6