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 | sqlite_cache_tables::_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 | __fini_sqlite_tables (void) |
static void | __init_sqlite_tables (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. | |
AST_THREADSTORAGE_CUSTOM_SCOPE (where_buf, NULL, ast_free_ptr, static) | |
AST_THREADSTORAGE_CUSTOM_SCOPE (sql_buf, NULL, ast_free_ptr, static) | |
static int | cdr_handler (struct ast_cdr *cdr) |
Asterisk callback function for CDR support. | |
static int | check_vars (void) |
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) |
Asterisk callback function for static configuration. | |
static struct sqlite_cache_tables * | find_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_variable * | realtime_handler (const char *database, const char *table, va_list ap) |
Asterisk callback function for RealTime configuration. | |
static struct ast_config * | realtime_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 __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime SQLite configuration" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | cdr_registered |
static char * | cdr_table |
static struct ast_cli_entry | cli_status [] |
static int | cli_status_registered |
static char * | config_table |
static sqlite * | db |
static char * | dbfile |
static ast_mutex_t | mutex = AST_MUTEX_INIT_VALUE |
static char * | sql_create_cdr_table = ");" |
static struct ast_config_engine | sqlite_engine |
static struct sqlite_tables | sqlite_tables |
static int | use_cdr |
res_config_sqlite module.
Definition in file res_config_sqlite.c.
#define MACRO_BEGIN do { |
Definition at line 93 of file res_config_sqlite.c.
#define MACRO_END } while (0) |
Definition at line 94 of file res_config_sqlite.c.
#define release_table | ( | a | ) | AST_RWLIST_UNLOCK(&((a)->columns)) |
Definition at line 706 of file res_config_sqlite.c.
Referenced by cdr_handler().
#define RES_CONFIG_SQLITE_BEGIN |
MACRO_BEGIN \ int __i; \ \ for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++) {
Macro used before executing a query.
Definition at line 152 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_CONF_FILE "res_config_sqlite.conf" |
Definition at line 99 of file res_config_sqlite.c.
Referenced by load_config().
#define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2" |
Definition at line 98 of file res_config_sqlite.c.
Referenced by load_module().
#define RES_CONFIG_SQLITE_DRIVER "sqlite" |
Definition at line 97 of file res_config_sqlite.c.
#define RES_CONFIG_SQLITE_END | ( | error | ) |
if (error != SQLITE_BUSY) \ break; \ usleep(1000); \ } \ MACRO_END;
Macro used after executing a query.
Definition at line 163 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), load_module(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), realtime_update2_handler(), and realtime_update_handler().
#define RES_CONFIG_SQLITE_MAX_LOOPS 10 |
Maximum number of loops before giving up executing a query. Calls to sqlite_xxx() functions which can return SQLITE_BUSY are enclosed by RES_CONFIG_SQLITE_BEGIN and RES_CONFIG_SQLITE_END, e.g.
char *errormsg; int error;
RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error)
if (error) ...;
Definition at line 145 of file res_config_sqlite.c.
#define RES_CONFIG_SQLITE_NAME "res_config_sqlite" |
Definition at line 96 of file res_config_sqlite.c.
Referenced by load_module(), and unload_module().
#define SET_VAR | ( | config, | |
to, | |||
from | |||
) |
Definition at line 113 of file res_config_sqlite.c.
Referenced by load_config().
#define sql_get_config_table |
"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.
Definition at line 566 of file res_config_sqlite.c.
Referenced by config_handler().
SQL query format to describe the table structure
Definition at line 558 of file res_config_sqlite.c.
Referenced by find_table().
anonymous enum |
Definition at line 101 of file res_config_sqlite.c.
{ 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, };
static void __fini_sqlite_tables | ( | void | ) | [static] |
Definition at line 524 of file res_config_sqlite.c.
:00:00',\n"
static void __init_sqlite_tables | ( | void | ) | [static] |
Definition at line 524 of file res_config_sqlite.c.
:00:00',\n"
static void __reg_module | ( | void | ) | [static] |
Definition at line 1870 of file res_config_sqlite.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1870 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.
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 |
0 | on success |
1 | if an error occurred |
Definition at line 853 of file res_config_sqlite.c.
References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_internal_load(), ast_free, ast_log(), ast_strdup, ast_variable_append(), ast_variable_new(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, cfg_entry_args::flags, LOG_WARNING, RES_CONFIG_SQLITE_CONFIG_CATEGORY, RES_CONFIG_SQLITE_CONFIG_COLUMNS, RES_CONFIG_SQLITE_CONFIG_VAR_NAME, RES_CONFIG_SQLITE_CONFIG_VAR_VAL, val, var, and cfg_entry_args::who_asked.
Referenced by config_handler().
{ struct cfg_entry_args *args; struct ast_variable *var; if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) { ast_log(LOG_WARNING, "Corrupt table\n"); return 1; } args = arg; if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) { struct ast_config *cfg; char *val; val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL]; cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked); if (!cfg) { ast_log(LOG_WARNING, "Unable to include %s\n", val); return 1; } else { args->cfg = cfg; return 0; } } if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) { args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999); if (!args->cat) { ast_log(LOG_WARNING, "Unable to allocate category\n"); return 1; } ast_free(args->cat_name); args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]); if (!args->cat_name) { ast_category_destroy(args->cat); return 1; } ast_category_append(args->cfg, args->cat); } var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], ""); if (!var) { ast_log(LOG_WARNING, "Unable to allocate variable"); return 1; } ast_variable_append(args->cat, var); return 0; }
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.
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 |
0 | on success. |
1 | if an error occurred. |
Definition at line 1001 of file res_config_sqlite.c.
References ast_variable_new(), rt_cfg_entry_args::last, ast_variable::next, rt_cfg_entry_args::var, and var.
Referenced by realtime_handler().
{ struct rt_cfg_entry_args *args; struct ast_variable *var; int i; args = arg; for (i = 0; i < argc; i++) { if (!argv[i]) continue; if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) return 1; if (!args->var) args->var = var; if (!args->last) args->last = var; else { args->last->next = var; args->last = var; } } return 0; }
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.
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 |
0 | on success. |
1 | if an error occurred. |
Definition at line 1120 of file res_config_sqlite.c.
References ast_category_append(), ast_category_new(), ast_log(), ast_variable_append(), ast_variable_new(), rt_multi_cfg_entry_args::cfg, rt_multi_cfg_entry_args::initfield, LOG_ERROR, LOG_WARNING, and var.
Referenced by realtime_multi_handler().
{ struct rt_multi_cfg_entry_args *args; struct ast_category *cat; struct ast_variable *var; char *cat_name; size_t i; args = arg; cat_name = NULL; /* * cat_name should always be set here, since initfield is forged from * params[0] in realtime_multi_handler(), which is a search parameter * of the SQL query. */ for (i = 0; i < argc; i++) { if (!strcmp(args->initfield, columnNames[i])) cat_name = argv[i]; } if (!cat_name) { ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n"); return 1; } if (!(cat = ast_category_new(cat_name, "", 99999))) { ast_log(LOG_WARNING, "Unable to allocate category\n"); return 1; } ast_category_append(args->cfg, cat); for (i = 0; i < argc; i++) { if (!argv[i] || !strcmp(args->initfield, columnNames[i])) continue; if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) { ast_log(LOG_WARNING, "Unable to allocate variable\n"); return 1; } ast_variable_append(cat, var); } return 0; }
AST_THREADSTORAGE_CUSTOM_SCOPE | ( | where_buf | , |
NULL | , | ||
ast_free_ptr | , | ||
static | |||
) |
AST_THREADSTORAGE_CUSTOM_SCOPE | ( | sql_buf | , |
NULL | , | ||
ast_free_ptr | , | ||
static | |||
) |
static int cdr_handler | ( | struct ast_cdr * | cdr | ) | [static] |
Asterisk callback function for CDR support.
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.
0 | on success |
1 | if an error occurred |
Definition at line 787 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().
{ char *errormsg = NULL, *tmp, workspace[500]; int error, scannum; struct sqlite_cache_tables *tbl = find_table(cdr_table); struct sqlite_cache_columns *col; struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16); int first = 1; if (!tbl) { ast_log(LOG_WARNING, "No such table: %s\n", cdr_table); return -1; } ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table); ast_str_set(&sql2, 0, ") VALUES ("); AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) { if (col->isint) { ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1); if (!tmp) { continue; } if (sscanf(tmp, "%30d", &scannum) == 1) { ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name); ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", scannum); } } else { ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0); if (!tmp) { continue; } ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name); tmp = sqlite_mprintf("%Q", tmp); ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", tmp); sqlite_freemem(tmp); } first = 0; } release_table(tbl); ast_str_append(&sql1, 0, "%s)", ast_str_buffer(sql2)); ast_free(sql2); ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql1)); ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, ast_str_buffer(sql1), NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error) ast_mutex_unlock(&mutex); ast_free(sql1); if (error) { ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); sqlite_freemem(errormsg); return 1; } sqlite_freemem(errormsg); return 0; }
static int check_vars | ( | void | ) | [static] |
Definition at line 723 of file res_config_sqlite.c.
References ast_log(), and LOG_ERROR.
Referenced by load_config().
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.
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. |
cfg | object |
NULL | if an error occurred |
Definition at line 912 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, config_table, 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.
{ struct cfg_entry_args args; char *query, *errormsg = NULL; int error; if (!config_table) { if (!table) { ast_log(LOG_ERROR, "Table name unspecified\n"); return NULL; } } else table = config_table; query = sqlite_mprintf(sql_get_config_table, table, file); if (!query) { ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); return NULL; } ast_debug(1, "SQL query: %s\n", query); args.cfg = cfg; args.cat = NULL; args.cat_name = NULL; args.flags = flags; args.who_asked = who_asked; ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg); RES_CONFIG_SQLITE_END(error) ast_mutex_unlock(&mutex); ast_free(args.cat_name); sqlite_freemem(query); if (error) { ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); sqlite_freemem(errormsg); return NULL; } sqlite_freemem(errormsg); return cfg; }
static struct sqlite_cache_tables* find_table | ( | const char * | tablename | ) | [static, read] |
Definition at line 641 of file res_config_sqlite.c.
References asprintf, ast_calloc, ast_debug, ast_free, AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_HEAD_INIT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, sqlite_cache_tables::columns, errno, find_table_cb(), free_table(), LOG_ERROR, LOG_WARNING, mutex, sqlite_cache_tables::name, and sql_table_structure.
Referenced by cdr_handler(), and realtime_require_handler().
{ struct sqlite_cache_tables *tblptr; int i, err; char *sql, *errstr = NULL; AST_RWLIST_RDLOCK(&sqlite_tables); for (i = 0; i < 2; i++) { AST_RWLIST_TRAVERSE(&sqlite_tables, tblptr, list) { if (strcmp(tblptr->name, tablename) == 0) { break; } } if (tblptr) { AST_RWLIST_RDLOCK(&(tblptr->columns)); AST_RWLIST_UNLOCK(&sqlite_tables); return tblptr; } if (i == 0) { AST_RWLIST_UNLOCK(&sqlite_tables); AST_RWLIST_WRLOCK(&sqlite_tables); } } /* Table structure not cached; build the structure now */ if (asprintf(&sql, sql_table_structure, tablename) < 0) { ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); sql = NULL; } if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) { AST_RWLIST_UNLOCK(&sqlite_tables); ast_log(LOG_ERROR, "Memory error. Cannot cache table '%s'\n", tablename); return NULL; } tblptr->name = (char *)tblptr + sizeof(*tblptr); strcpy(tblptr->name, tablename); /* SAFE */ AST_RWLIST_HEAD_INIT(&(tblptr->columns)); ast_debug(1, "About to query table structure: %s\n", sql); ast_mutex_lock(&mutex); if ((err = sqlite_exec(db, sql, find_table_cb, tblptr, &errstr))) { ast_mutex_unlock(&mutex); ast_log(LOG_WARNING, "SQLite error %d: %s\n", err, errstr); ast_free(errstr); free_table(tblptr); AST_RWLIST_UNLOCK(&sqlite_tables); return NULL; } ast_mutex_unlock(&mutex); if (AST_LIST_EMPTY(&(tblptr->columns))) { free_table(tblptr); AST_RWLIST_UNLOCK(&sqlite_tables); return NULL; } AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list); AST_RWLIST_RDLOCK(&(tblptr->columns)); AST_RWLIST_UNLOCK(&sqlite_tables); return tblptr; }
static int find_table_cb | ( | void * | vtblptr, |
int | argc, | ||
char ** | argv, | ||
char ** | columnNames | ||
) | [static] |
Definition at line 586 of file res_config_sqlite.c.
References AST_APP_ARG, ast_calloc, ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdupa, sqlite_cache_tables::columns, sqlite_cache_columns::isint, sqlite_cache_columns::name, strcasestr(), and sqlite_cache_columns::type.
Referenced by find_table().
{ struct sqlite_cache_tables *tblptr = vtblptr; char *sql = ast_strdupa(argv[0]), *start, *end, *type, *remainder; int i; AST_DECLARE_APP_ARGS(fie, AST_APP_ARG(ld)[100]; /* This means we support up to 100 columns per table */ ); struct sqlite_cache_columns *col; /* This is really fun. We get to parse an SQL statement to figure out * what columns are in the table. */ if ((start = strchr(sql, '(')) && (end = strrchr(sql, ')'))) { start++; *end = '\0'; } else { /* Abort */ return -1; } AST_STANDARD_APP_ARGS(fie, start); for (i = 0; i < fie.argc; i++) { fie.ld[i] = ast_skip_blanks(fie.ld[i]); ast_debug(5, "Found field: %s\n", fie.ld[i]); if (strncasecmp(fie.ld[i], "PRIMARY KEY", 11) == 0 && (start = strchr(fie.ld[i], '(')) && (end = strchr(fie.ld[i], ')'))) { *end = '\0'; AST_RWLIST_TRAVERSE(&(tblptr->columns), col, list) { if (strcasecmp(start + 1, col->name) == 0 && strcasestr(col->type, "INTEGER")) { col->isint = 1; } } continue; } /* type delimiter could be any space character */ for (type = fie.ld[i]; *type > 32; type++); *type++ = '\0'; type = ast_skip_blanks(type); for (remainder = type; *remainder > 32; remainder++); *remainder = '\0'; if (!(col = ast_calloc(1, sizeof(*col) + strlen(fie.ld[i]) + strlen(type) + 2))) { return -1; } col->name = (char *)col + sizeof(*col); col->type = (char *)col + sizeof(*col) + strlen(fie.ld[i]) + 1; strcpy(col->name, fie.ld[i]); /* SAFE */ strcpy(col->type, type); /* SAFE */ if (strcasestr(col->type, "INTEGER") && strcasestr(col->type, "PRIMARY KEY")) { col->isint = 1; } AST_LIST_INSERT_TAIL(&(tblptr->columns), col, list); } return 0; }
static void free_table | ( | struct sqlite_cache_tables * | tblptr | ) | [static] |
Definition at line 572 of file res_config_sqlite.c.
References ast_free, AST_RWLIST_HEAD_DESTROY, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and sqlite_cache_tables::columns.
Referenced by find_table(), realtime_unload_handler(), and unload_config().
{ struct sqlite_cache_columns *col; /* Obtain a write lock to ensure there are no read locks outstanding */ AST_RWLIST_WRLOCK(&(tblptr->columns)); while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) { ast_free(col); } AST_RWLIST_UNLOCK(&(tblptr->columns)); AST_RWLIST_HEAD_DESTROY(&(tblptr->columns)); ast_free(tblptr); }
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:
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.
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 |
the | number of elements in the arrays (which have the same size). |
0 | if an error occurred. |
Definition at line 962 of file res_config_sqlite.c.
References ast_free, ast_log(), ast_realloc, LOG_WARNING, and val.
Referenced by realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), and realtime_update_handler().
{ const char **tmp, *param, *val, **params, **vals; size_t params_count; params = NULL; vals = NULL; params_count = 0; while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) { if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) { ast_free(params); ast_free(vals); return 0; } params = tmp; if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) { ast_free(params); ast_free(vals); return 0; } vals = tmp; params[params_count] = param; vals[params_count] = val; params_count++; } if (params_count > 0) { *params_ptr = params; *vals_ptr = vals; } else if (warn) { ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n"); } return params_count; }
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.
e | CLI command |
cmd | |
a | CLI argument list |
Definition at line 1665 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.
{ switch (cmd) { case CLI_INIT: e->command = "sqlite show status"; e->usage = "Usage: sqlite show status\n" " Show status information about the SQLite 2 driver\n"; return NULL; case CLI_GENERATE: return NULL; } if (a->argc != 3) return CLI_SHOWUSAGE; ast_cli(a->fd, "SQLite database path: %s\n", dbfile); ast_cli(a->fd, "config_table: "); if (!config_table) ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n"); else ast_cli(a->fd, "%s\n", config_table); ast_cli(a->fd, "cdr_table: "); if (!cdr_table) ast_cli(a->fd, "unspecified, CDR support disabled\n"); else ast_cli(a->fd, "%s\n", cdr_table); return CLI_SUCCESS; }
static char * handle_cli_sqlite_show_tables | ( | struct ast_cli_entry * | e, |
int | cmd, | ||
struct ast_cli_args * | a | ||
) | [static] |
Definition at line 1699 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.
{ struct sqlite_cache_tables *tbl; struct sqlite_cache_columns *col; int found = 0; switch (cmd) { case CLI_INIT: e->command = "sqlite show tables"; e->usage = "Usage: sqlite show tables\n" " Show table information about the SQLite 2 driver\n"; return NULL; case CLI_GENERATE: return NULL; } if (a->argc != 3) return CLI_SHOWUSAGE; AST_RWLIST_RDLOCK(&sqlite_tables); AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) { found++; ast_cli(a->fd, "Table %s:\n", tbl->name); AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) { fprintf(stderr, "%s\n", col->name); ast_cli(a->fd, " %20.20s %-30.30s\n", col->name, col->type); } } AST_RWLIST_UNLOCK(&sqlite_tables); if (!found) { ast_cli(a->fd, "No tables currently in cache\n"); } return CLI_SUCCESS; }
static int load_config | ( | void | ) | [static] |
Load the configuration file.
This function sets dbfile, config_table, and cdr_table. It calls check_vars() before returning, and unload_config() if an error occurred.
0 | on success |
1 | if an error occurred |
Definition at line 735 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().
{ struct ast_config *config; struct ast_variable *var; int error; struct ast_flags config_flags = { 0 }; config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags); if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) { ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n"); return 1; } for (var = ast_variable_browse(config, "general"); var; var = var->next) { if (!strcasecmp(var->name, "dbfile")) SET_VAR(config, dbfile, var); else if (!strcasecmp(var->name, "config_table")) SET_VAR(config, config_table, var); else if (!strcasecmp(var->name, "cdr_table")) { SET_VAR(config, cdr_table, var); } else ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name); } ast_config_destroy(config); error = check_vars(); if (error) { unload_config(); return 1; } return 0; }
static int load_module | ( | void | ) | [static] |
Definition at line 1755 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().
{ char *errormsg = NULL; int error; db = NULL; cdr_registered = 0; cli_status_registered = 0; dbfile = NULL; config_table = NULL; cdr_table = NULL; error = load_config(); if (error) return AST_MODULE_LOAD_DECLINE; if (!(db = sqlite_open(dbfile, 0660, &errormsg))) { ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); sqlite_freemem(errormsg); unload_module(); return 1; } sqlite_freemem(errormsg); errormsg = NULL; ast_config_engine_register(&sqlite_engine); if (use_cdr) { char *query; /* \cond DOXYGEN_CAN_PARSE_THIS */ #undef QUERY #define QUERY "SELECT COUNT(id) FROM %Q;" /* \endcond */ query = sqlite_mprintf(QUERY, cdr_table); if (!query) { ast_log(LOG_ERROR, "Unable to allocate SQL query\n"); unload_module(); return 1; } ast_debug(1, "SQL query: %s\n", query); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error) sqlite_freemem(query); if (error) { /* * Unexpected error. */ if (error != SQLITE_ERROR) { ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); sqlite_freemem(errormsg); unload_module(); return 1; } sqlite_freemem(errormsg); errormsg = NULL; query = sqlite_mprintf(sql_create_cdr_table, cdr_table); if (!query) { ast_log(LOG_ERROR, "Unable to allocate SQL query\n"); unload_module(); return 1; } ast_debug(1, "SQL query: %s\n", query); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error) sqlite_freemem(query); if (error) { ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); sqlite_freemem(errormsg); unload_module(); return 1; } } sqlite_freemem(errormsg); errormsg = NULL; error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler); if (error) { unload_module(); return 1; } cdr_registered = 1; } error = ast_cli_register_multiple(cli_status, ARRAY_LEN(cli_status)); if (error) { unload_module(); return 1; } cli_status_registered = 1; return 0; }
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.
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 |
the | number of affected rows. |
-1 | if an error occurred. |
Definition at line 1537 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.
{ char *query, *errormsg = NULL, *tmp_str; const char **params = NULL, **vals = NULL; size_t params_count; int error, rows_num; size_t i; if (!table) { ast_log(LOG_WARNING, "Table name unspecified\n"); return -1; } params_count = get_params(ap, ¶ms, &vals, 0); /* \cond DOXYGEN_CAN_PARSE_THIS */ #undef QUERY #define QUERY "DELETE FROM '%q' WHERE" /* \endcond */ if (!(query = sqlite_mprintf(QUERY, table))) { ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); ast_free(params); ast_free(vals); return -1; } for (i = 0; i < params_count; i++) { tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]); sqlite_freemem(query); if (!tmp_str) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); ast_free(params); ast_free(vals); return -1; } query = tmp_str; } ast_free(params); ast_free(vals); if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); sqlite_freemem(query); return -1; } sqlite_freemem(query); query = tmp_str; ast_debug(1, "SQL query: %s\n", query); ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error) if (!error) { rows_num = sqlite_changes(db); } else { rows_num = -1; } ast_mutex_unlock(&mutex); sqlite_freemem(query); if (error) { ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); } sqlite_freemem(errormsg); return rows_num; }
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';
.
database | the database to use (ignored) |
table | the table to use |
ap | list of parameters and values to match |
a | linked list of struct ast_variable objects |
NULL | if an error occurred |
Definition at line 1030 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.
{ char *query, *errormsg = NULL, *op, *tmp_str; struct rt_cfg_entry_args args; const char **params, **vals; size_t params_count; int error; if (!table) { ast_log(LOG_WARNING, "Table name unspecified\n"); return NULL; } params_count = get_params(ap, ¶ms, &vals, 1); if (params_count == 0) return NULL; op = (strchr(params[0], ' ') == NULL) ? " =" : ""; /* \cond DOXYGEN_CAN_PARSE_THIS */ #undef QUERY #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'" /* \endcond */ query = sqlite_mprintf(QUERY, table, !strcmp(config_table, table) ? " commented = 0 AND" : "", params[0], op, vals[0]); if (!query) { ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); ast_free(params); ast_free(vals); return NULL; } if (params_count > 1) { size_t i; for (i = 1; i < params_count; i++) { op = (strchr(params[i], ' ') == NULL) ? " =" : ""; tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]); sqlite_freemem(query); if (!tmp_str) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); ast_free(params); ast_free(vals); return NULL; } query = tmp_str; } } ast_free(params); ast_free(vals); tmp_str = sqlite_mprintf("%s LIMIT 1;", query); sqlite_freemem(query); if (!tmp_str) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); return NULL; } query = tmp_str; ast_debug(1, "SQL query: %s\n", query); args.var = NULL; args.last = NULL; ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg); RES_CONFIG_SQLITE_END(error) ast_mutex_unlock(&mutex); sqlite_freemem(query); if (error) { ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); sqlite_freemem(errormsg); ast_variables_destroy(args.var); return NULL; } sqlite_freemem(errormsg); return args.var; }
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.
database | the database to use (ignored) |
table | the table to use |
ap | list of parameters and values to match |
a | struct ast_config object storing categories and variables. |
NULL | if an error occurred. |
Definition at line 1168 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.
{ char *query, *errormsg = NULL, *op, *tmp_str, *initfield; struct rt_multi_cfg_entry_args args; const char **params, **vals; struct ast_config *cfg; size_t params_count; int error; if (!table) { ast_log(LOG_WARNING, "Table name unspecified\n"); return NULL; } if (!(cfg = ast_config_new())) { ast_log(LOG_WARNING, "Unable to allocate configuration structure\n"); return NULL; } if (!(params_count = get_params(ap, ¶ms, &vals, 1))) { ast_config_destroy(cfg); return NULL; } if (!(initfield = ast_strdup(params[0]))) { ast_config_destroy(cfg); ast_free(params); ast_free(vals); return NULL; } tmp_str = strchr(initfield, ' '); if (tmp_str) *tmp_str = '\0'; op = (!strchr(params[0], ' ')) ? " =" : ""; /* * Asterisk sends us an already escaped string when searching for * "exten LIKE" (uh!). Handle it separately. */ tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0]; /* \cond DOXYGEN_CAN_PARSE_THIS */ #undef QUERY #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'" /* \endcond */ if (!(query = sqlite_mprintf(QUERY, table, params[0], op, tmp_str))) { ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); ast_config_destroy(cfg); ast_free(params); ast_free(vals); ast_free(initfield); return NULL; } if (params_count > 1) { size_t i; for (i = 1; i < params_count; i++) { op = (!strchr(params[i], ' ')) ? " =" : ""; tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]); sqlite_freemem(query); if (!tmp_str) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); ast_config_destroy(cfg); ast_free(params); ast_free(vals); ast_free(initfield); return NULL; } query = tmp_str; } } ast_free(params); ast_free(vals); if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); sqlite_freemem(query); ast_config_destroy(cfg); ast_free(initfield); return NULL; } sqlite_freemem(query); query = tmp_str; ast_debug(1, "SQL query: %s\n", query); args.cfg = cfg; args.initfield = initfield; ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg); RES_CONFIG_SQLITE_END(error) ast_mutex_unlock(&mutex); sqlite_freemem(query); ast_free(initfield); if (error) { ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); sqlite_freemem(errormsg); ast_config_destroy(cfg); return NULL; } sqlite_freemem(errormsg); return cfg; }
static int realtime_require_handler | ( | const char * | database, |
const char * | table, | ||
va_list | ap | ||
) | [static] |
Definition at line 1614 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.
{ struct sqlite_cache_tables *tbl = find_table(tablename); struct sqlite_cache_columns *col; char *elm; int type, size, res = 0; if (!tbl) { return -1; } while ((elm = va_arg(ap, char *))) { type = va_arg(ap, require_type); size = va_arg(ap, int); /* Check if the field matches the criteria */ AST_RWLIST_TRAVERSE(&tbl->columns, col, list) { if (strcmp(col->name, elm) == 0) { /* SQLite only has two types - the 32-bit integer field that * is the key column, and everything else (everything else * being a string). */ if (col->isint && !ast_rq_is_int(type)) { ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name); res = -1; } break; } } if (!col) { ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm); } } AST_RWLIST_UNLOCK(&(tbl->columns)); return res; }
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.
database | the database to use (ignored) |
table | the table to use |
ap | list of parameters and new values to insert into the database |
the | rowid of inserted row. |
-1 | if an error occurred. |
Definition at line 1443 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.
{ char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL; const char **params, **vals; size_t params_count; int error, rows_id; size_t i; if (!table) { ast_log(LOG_WARNING, "Table name unspecified\n"); return -1; } if (!(params_count = get_params(ap, ¶ms, &vals, 1))) return -1; /* \cond DOXYGEN_CAN_PARSE_THIS */ #undef QUERY #define QUERY "INSERT into '%q' (%s) VALUES (%s);" /* \endcond */ for (i = 0; i < params_count; i++) { if ( tmp_keys2 ) { tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]); sqlite_freemem(tmp_keys2); } else { tmp_keys = sqlite_mprintf("%q", params[i]); } if (!tmp_keys) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); sqlite_freemem(tmp_vals); ast_free(params); ast_free(vals); return -1; } if ( tmp_vals2 ) { tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, vals[i]); sqlite_freemem(tmp_vals2); } else { tmp_vals = sqlite_mprintf("'%q'", vals[i]); } if (!tmp_vals) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); sqlite_freemem(tmp_keys); ast_free(params); ast_free(vals); return -1; } tmp_keys2 = tmp_keys; tmp_vals2 = tmp_vals; } ast_free(params); ast_free(vals); if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); sqlite_freemem(tmp_keys); sqlite_freemem(tmp_vals); return -1; } sqlite_freemem(tmp_keys); sqlite_freemem(tmp_vals); ast_debug(1, "SQL query: %s\n", tmp_str); ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error) if (!error) { rows_id = sqlite_last_insert_rowid(db); } else { rows_id = -1; } ast_mutex_unlock(&mutex); sqlite_freemem(tmp_str); if (error) { ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); } sqlite_freemem(errormsg); return rows_id; }
static int realtime_unload_handler | ( | const char * | unused, |
const char * | tablename | ||
) | [static] |
Definition at line 1650 of file res_config_sqlite.c.
References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_table(), and sqlite_cache_tables::name.
{ struct sqlite_cache_tables *tbl; AST_RWLIST_WRLOCK(&sqlite_tables); AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) { if (!strcasecmp(tbl->name, tablename)) { AST_RWLIST_REMOVE_CURRENT(list); free_table(tbl); } } AST_RWLIST_TRAVERSE_SAFE_END AST_RWLIST_UNLOCK(&sqlite_tables); return 0; }
static int realtime_update2_handler | ( | const char * | database, |
const char * | table, | ||
va_list | ap | ||
) | [static] |
Definition at line 1369 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, and S_OR.
{ char *errormsg = NULL, *tmp1, *tmp2; int error, rows_num, first = 1; struct ast_str *sql = ast_str_thread_get(&sql_buf, 100); struct ast_str *where = ast_str_thread_get(&where_buf, 100); const char *param, *value; if (!table) { ast_log(LOG_WARNING, "Table name unspecified\n"); return -1; } if (!sql) { return -1; } ast_str_set(&sql, 0, "UPDATE %s SET", table); ast_str_set(&where, 0, " WHERE"); while ((param = va_arg(ap, const char *))) { value = va_arg(ap, const char *); ast_str_append(&where, 0, "%s %s = %s", first ? "" : " AND", tmp1 = sqlite_mprintf("%q", param), tmp2 = sqlite_mprintf("%Q", value)); sqlite_freemem(tmp1); sqlite_freemem(tmp2); first = 0; } if (first) { ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database); return -1; } first = 1; while ((param = va_arg(ap, const char *))) { value = va_arg(ap, const char *); ast_str_append(&sql, 0, "%s %s = %s", first ? "" : ",", tmp1 = sqlite_mprintf("%q", param), tmp2 = sqlite_mprintf("%Q", value)); sqlite_freemem(tmp1); sqlite_freemem(tmp2); first = 0; } ast_str_append(&sql, 0, " %s", ast_str_buffer(where)); ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql)); ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error) if (!error) { rows_num = sqlite_changes(db); } else { rows_num = -1; } ast_mutex_unlock(&mutex); if (error) { ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); } sqlite_freemem(errormsg); return rows_num; }
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.
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 |
the | number of affected rows. |
-1 | if an error occurred. |
Definition at line 1287 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.
{ char *query, *errormsg = NULL, *tmp_str; const char **params, **vals; size_t params_count; int error, rows_num; if (!table) { ast_log(LOG_WARNING, "Table name unspecified\n"); return -1; } if (!(params_count = get_params(ap, ¶ms, &vals, 1))) return -1; /* \cond DOXYGEN_CAN_PARSE_THIS */ #undef QUERY #define QUERY "UPDATE '%q' SET %q = '%q'" /* \endcond */ if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) { ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); ast_free(params); ast_free(vals); return -1; } if (params_count > 1) { size_t i; for (i = 1; i < params_count; i++) { tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]); sqlite_freemem(query); if (!tmp_str) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); ast_free(params); ast_free(vals); return -1; } query = tmp_str; } } ast_free(params); ast_free(vals); if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) { ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); sqlite_freemem(query); return -1; } sqlite_freemem(query); query = tmp_str; ast_debug(1, "SQL query: %s\n", query); ast_mutex_lock(&mutex); RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error) if (!error) rows_num = sqlite_changes(db); else rows_num = -1; ast_mutex_unlock(&mutex); sqlite_freemem(query); if (error) { ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); } sqlite_freemem(errormsg); return rows_num; }
static int set_var | ( | char ** | var, |
const char * | name, | ||
const char * | value | ||
) | [static] |
Allocate a variable.
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 |
0 | on success |
1 | if an allocation error occurred |
Definition at line 708 of file res_config_sqlite.c.
References ast_free, ast_log(), ast_strdup, and LOG_WARNING.
{ if (*var) ast_free(*var); *var = ast_strdup(value); if (!*var) { ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name); return 1; } return 0; }
static void unload_config | ( | void | ) | [static] |
Free resources related to configuration.
Definition at line 771 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().
{ struct sqlite_cache_tables *tbl; ast_free(dbfile); dbfile = NULL; ast_free(config_table); config_table = NULL; ast_free(cdr_table); cdr_table = NULL; AST_RWLIST_WRLOCK(&sqlite_tables); while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) { free_table(tbl); } AST_RWLIST_UNLOCK(&sqlite_tables); }
static int unload_module | ( | void | ) | [static] |
Definition at line 1737 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().
Referenced by load_module().
{ if (cli_status_registered) ast_cli_unregister_multiple(cli_status, ARRAY_LEN(cli_status)); if (cdr_registered) ast_cdr_unregister(RES_CONFIG_SQLITE_NAME); ast_config_engine_deregister(&sqlite_engine); if (db) sqlite_close(db); unload_config(); return 0; }
struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime SQLite configuration" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 1870 of file res_config_sqlite.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1870 of file res_config_sqlite.c.
int cdr_registered [static] |
Set to 1 if the CDR callback function was registered.
Definition at line 465 of file res_config_sqlite.c.
char* cdr_table [static] |
The name of the table used to store CDR entries.
Definition at line 477 of file res_config_sqlite.c.
struct ast_cli_entry cli_status[] [static] |
{ AST_CLI_DEFINE(handle_cli_show_sqlite_status, "Show status information about the SQLite 2 driver"), AST_CLI_DEFINE(handle_cli_sqlite_show_tables, "Cached table information about the SQLite 2 driver"), }
Structure containing details and callback functions for the CLI status command.
Definition at line 506 of file res_config_sqlite.c.
int cli_status_registered [static] |
Set to 1 if the CLI status command callback function was registered.
Definition at line 468 of file res_config_sqlite.c.
char* config_table [static] |
The name of the static configuration table.
Definition at line 474 of file res_config_sqlite.c.
Referenced by config_handler().
sqlite* db [static] |
The SQLite database object.
Definition at line 459 of file res_config_sqlite.c.
char* dbfile [static] |
The path of the database file.
Definition at line 471 of file res_config_sqlite.c.
ast_mutex_t mutex = AST_MUTEX_INIT_VALUE [static] |
The mutex used to prevent simultaneous access to the SQLite database.
Definition at line 500 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), find_table(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), realtime_update2_handler(), and realtime_update_handler().
char* sql_create_cdr_table = ");" [static] |
SQL query format to create the CDR table if non existent.
Definition at line 531 of file res_config_sqlite.c.
Referenced by load_module().
struct ast_config_engine sqlite_engine [static] |
The structure specifying all callback functions used by Asterisk for static and RealTime configuration.
Definition at line 483 of file res_config_sqlite.c.
struct sqlite_tables sqlite_tables [static] |
int use_cdr [static] |
Set to 1 if CDR support is enabled.
Definition at line 462 of file res_config_sqlite.c.