SQLite 3 configuration engine. More...
#include "asterisk.h"#include <sqlite3.h>#include "asterisk/module.h"#include "asterisk/config.h"#include "asterisk/paths.h"#include "asterisk/astobj2.h"#include "asterisk/lock.h"#include "asterisk/utils.h"#include "asterisk/app.h"
Go to the source code of this file.
Data Structures | |
| struct | cfg_entry_args |
| struct | realtime_sqlite3_db |
Defines | |
| #define | DB_BUCKETS 7 |
Enumerations | |
| enum | { REALTIME_SQLITE3_REQ_WARN, REALTIME_SQLITE3_REQ_CLOSE, REALTIME_SQLITE3_REQ_CHAR } |
| enum | { COL_CATEGORY, COL_VAR_NAME, COL_VAR_VAL, COL_COLUMNS } |
Functions | |
| static void | __init_escape_column_buf (void) |
| static void | __init_escape_table_buf (void) |
| static void | __init_escape_value_buf (void) |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | add_column_name (void *arg, int num_columns, char **values, char **columns) |
| Callback for creating a hash of column names for comparison in realtime_sqlite3_require. | |
| static int | append_row_to_cfg (void *arg, int num_columns, char **values, char **columns) |
| Callback for creating an ast_config from a successive sqlite3 result rows. | |
| static int | db_cmp_fn (void *obj, void *arg, int flags) |
| static void | db_destructor (void *obj) |
| static int | db_hash_fn (const void *obj, const int flags) |
| static int | db_open (struct realtime_sqlite3_db *db) |
| Open a database and appropriately set debugging on the db handle. | |
| void | db_start_batch (struct realtime_sqlite3_db *db) |
| void | db_stop_batch (struct realtime_sqlite3_db *db) |
| static void | db_sync (struct realtime_sqlite3_db *db) |
| static void * | db_sync_thread (void *data) |
| Wrap commands in transactions increased write performance. | |
| static struct realtime_sqlite3_db * | find_database (const char *database) |
| static const char * | get_sqlite_column_type (int type) |
| Convert Asterisk realtime types to SQLite 3 types. | |
| static int | handle_missing_column (struct realtime_sqlite3_db *db, const char *table, const char *column, int type, size_t sz) |
| If ast_realtime_require sends info about a column we don't have, create it. | |
| static int | handle_missing_table (struct realtime_sqlite3_db *db, const char *table, va_list ap) |
| Create a table if ast_realtime_require shows that we are configured to handle the data. | |
| static int | is_dirty_cb (void *obj, void *arg, int flags) |
| static int | load_module (void) |
| static void | mark_all_databases_dirty (void) |
| static int | mark_dirty_cb (void *obj, void *arg, int flags) |
| static struct realtime_sqlite3_db * | new_realtime_sqlite3_db (struct ast_config *config, const char *cat) |
| Create a db object based on a config category. | |
| static int | parse_config (int reload) |
| Parse the res_config_sqlite3 config file. | |
| static struct ast_variable * | realtime_sqlite3 (const char *database, const char *table, va_list ap) |
| Realtime callback for a single row query. | |
| static int | realtime_sqlite3_destroy (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap) |
| Realtime callback for deleting a row. | |
| static int | realtime_sqlite3_execute (const char *database, const char *sql, int(*callback)(void *, int, char **, char **), void *arg, int sync) |
| static int | realtime_sqlite3_execute_handle (struct realtime_sqlite3_db *db, const char *sql, int(*callback)(void *, int, char **, char **), void *arg, int sync) |
| static int | realtime_sqlite3_helper (const char *database, const char *table, va_list ap, int is_multi, void *arg) |
| Helper function for single and multi-row realtime load functions. | |
| static struct ast_config * | realtime_sqlite3_load (const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) |
| Realtime callback for static realtime. | |
| static struct ast_config * | realtime_sqlite3_multi (const char *database, const char *table, va_list ap) |
| Realtime callback for a multi-row query. | |
| static int | realtime_sqlite3_require (const char *database, const char *table, va_list ap) |
| Callback for ast_realtime_require. | |
| static int | realtime_sqlite3_store (const char *database, const char *table, va_list ap) |
| Realtime callback for inserting a row. | |
| static int | realtime_sqlite3_unload (const char *database, const char *table) |
| Callback for clearing any cached info. | |
| static int | realtime_sqlite3_update (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap) |
| Realtime callback for updating a row based on a single criteria. | |
| static int | realtime_sqlite3_update2 (const char *database, const char *table, va_list ap) |
| Realtime callback for updating a row based on multiple criteria. | |
| static int | reload (void) |
| static int | row_to_varlist (void *arg, int num_columns, char **values, char **columns) |
| Create a varlist from a single sqlite3 result row. | |
| static const char * | sqlite3_escape_column (const char *param) |
| static const char * | sqlite3_escape_column_op (const char *param) |
| static const char * | sqlite3_escape_string_helper (struct ast_threadstorage *ts, const char *param) |
| static const char * | sqlite3_escape_table (const char *param) |
| static const char * | sqlite3_escape_value (const char *param) |
| static int | static_realtime_cb (void *arg, int num_columns, char **values, char **columns) |
| static int | stop_batch_cb (void *obj, void *arg, int flags) |
| static int | str_cmp_fn (void *obj, void *arg, int flags) |
| static int | str_hash_fn (const void *obj, const int flags) |
| static int | str_to_requirements (const char *data) |
| static void | trace_cb (void *arg, const char *sql) |
| static void | unlink_dirty_databases (void) |
| static int | unload_module (void) |
| static void | unref_db (struct realtime_sqlite3_db **db) |
| static int | update_realtime_sqlite3_db (struct realtime_sqlite3_db *db, struct ast_config *config, const char *cat) |
| Update an existing db object based on config data. | |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "SQLite 3 realtime config engine" , .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, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static ast_mutex_t | config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| struct ao2_container * | databases |
| static struct ast_threadstorage | escape_column_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_column_buf , .custom_init = NULL , } |
| static struct ast_threadstorage | escape_table_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_table_buf , .custom_init = NULL , } |
| static struct ast_threadstorage | escape_value_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_value_buf , .custom_init = NULL , } |
| struct ast_config_engine | sqlite3_config_engine |
| static const char * | static_sql = "SELECT category, var_name, var_val FROM \"%q\" WHERE filename = %Q AND commented = 0 ORDER BY cat_metric ASC, var_metric ASC" |
SQLite 3 configuration engine.
This is a realtime configuration engine for the SQLite 3 Database
Definition in file res_config_sqlite3.c.
| #define DB_BUCKETS 7 |
Definition at line 100 of file res_config_sqlite3.c.
Referenced by load_module().
| anonymous enum |
Definition at line 77 of file res_config_sqlite3.c.
| anonymous enum |
Definition at line 558 of file res_config_sqlite3.c.
{
COL_CATEGORY,
COL_VAR_NAME,
COL_VAR_VAL,
COL_COLUMNS,
};
| static void __init_escape_column_buf | ( | void | ) | [static] |
Definition at line 106 of file res_config_sqlite3.c.
{
| static void __init_escape_table_buf | ( | void | ) | [static] |
Definition at line 105 of file res_config_sqlite3.c.
{
| static void __init_escape_value_buf | ( | void | ) | [static] |
Definition at line 107 of file res_config_sqlite3.c.
{
| static void __reg_module | ( | void | ) | [static] |
Definition at line 1190 of file res_config_sqlite3.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1190 of file res_config_sqlite3.c.
| static int add_column_name | ( | void * | arg, |
| int | num_columns, | ||
| char ** | values, | ||
| char ** | columns | ||
| ) | [static] |
Callback for creating a hash of column names for comparison in realtime_sqlite3_require.
Definition at line 984 of file res_config_sqlite3.c.
References ao2_alloc, ao2_link, and ao2_ref.
Referenced by realtime_sqlite3_require().
| static int append_row_to_cfg | ( | void * | arg, |
| int | num_columns, | ||
| char ** | values, | ||
| char ** | columns | ||
| ) | [static] |
Callback for creating an ast_config from a successive sqlite3 result rows.
Definition at line 472 of file res_config_sqlite3.c.
References ast_category_append(), ast_category_new(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, S_OR, and var.
Referenced by realtime_sqlite3_helper().
{
struct ast_config *cfg = arg;
struct ast_category *cat;
int i;
if (!(cat = ast_category_new("", "", 99999))) {
return SQLITE_ABORT;
}
for (i = 0; i < num_columns; i++) {
struct ast_variable *var;
if (!(var = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
ast_log(LOG_ERROR, "Could not create new variable for '%s: %s', throwing away list\n", columns[i], values[i]);
continue;
}
ast_variable_append(cat, var);
}
ast_category_append(cfg, cat);
return 0;
}
| static int db_cmp_fn | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 195 of file res_config_sqlite3.c.
References CMP_MATCH, CMP_STOP, name, realtime_sqlite3_db::name, and OBJ_KEY.
Referenced by load_module().
| static void db_destructor | ( | void * | obj | ) | [static] |
Definition at line 202 of file res_config_sqlite3.c.
References ao2_lock, ao2_unlock, ast_debug, ast_string_field_free_memory, db_stop_batch(), realtime_sqlite3_db::handle, and realtime_sqlite3_db::name.
Referenced by new_realtime_sqlite3_db().
{
struct realtime_sqlite3_db *db = obj;
ast_debug(1, "Destroying db: %s\n", db->name);
ast_string_field_free_memory(db);
db_stop_batch(db);
if (db->handle) {
ao2_lock(db);
sqlite3_close(db->handle);
ao2_unlock(db);
}
}
| static int db_hash_fn | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 188 of file res_config_sqlite3.c.
References ast_str_hash(), realtime_sqlite3_db::name, and OBJ_KEY.
Referenced by load_module().
{
const struct realtime_sqlite3_db *db = obj;
return ast_str_hash(flags & OBJ_KEY ? (const char *) obj : db->name);
}
| static int db_open | ( | struct realtime_sqlite3_db * | db | ) | [static] |
Open a database and appropriately set debugging on the db handle.
Definition at line 310 of file res_config_sqlite3.c.
References ao2_lock, ao2_unlock, ast_log(), realtime_sqlite3_db::debug, realtime_sqlite3_db::filename, realtime_sqlite3_db::handle, LOG_WARNING, and trace_cb().
Referenced by parse_config(), and update_realtime_sqlite3_db().
{
ao2_lock(db);
if (sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
ast_log(LOG_WARNING, "Could not open %s: %s\n", db->filename, sqlite3_errmsg(db->handle));
ao2_unlock(db);
return -1;
}
if (db->debug) {
sqlite3_trace(db->handle, trace_cb, db);
} else {
sqlite3_trace(db->handle, NULL, NULL);
}
ao2_unlock(db);
return 0;
}
| void db_start_batch | ( | struct realtime_sqlite3_db * | db | ) |
Definition at line 336 of file res_config_sqlite3.c.
References ao2_ref, ast_cond_init, ast_pthread_create_background, realtime_sqlite3_db::batch, realtime_sqlite3_db::cond, db_sync_thread(), and realtime_sqlite3_db::syncthread.
Referenced by parse_config(), and update_realtime_sqlite3_db().
{
if (db->batch) {
ast_cond_init(&db->cond, NULL);
ao2_ref(db, +1);
ast_pthread_create_background(&db->syncthread, NULL, db_sync_thread, db);
}
}
| void db_stop_batch | ( | struct realtime_sqlite3_db * | db | ) |
Definition at line 345 of file res_config_sqlite3.c.
References realtime_sqlite3_db::batch, db_sync(), realtime_sqlite3_db::exiting, and realtime_sqlite3_db::syncthread.
Referenced by db_destructor(), is_dirty_cb(), stop_batch_cb(), and update_realtime_sqlite3_db().
{
if (db->batch) {
db->exiting = 1;
db_sync(db);
pthread_join(db->syncthread, NULL);
}
}
| static void db_sync | ( | struct realtime_sqlite3_db * | db | ) | [static] |
Definition at line 330 of file res_config_sqlite3.c.
References ast_cond_signal, realtime_sqlite3_db::cond, and realtime_sqlite3_db::wakeup.
Referenced by db_stop_batch(), and realtime_sqlite3_execute_handle().
{
db->wakeup = 1;
ast_cond_signal(&db->cond);
}
| static void* db_sync_thread | ( | void * | data | ) | [static] |
Wrap commands in transactions increased write performance.
Definition at line 281 of file res_config_sqlite3.c.
References ao2_lock, ao2_object_get_lockaddr(), ao2_unlock, ast_cond_wait, realtime_sqlite3_db::batch, realtime_sqlite3_db::cond, realtime_sqlite3_db::exiting, realtime_sqlite3_execute_handle(), unref_db(), and realtime_sqlite3_db::wakeup.
Referenced by db_start_batch().
{
struct realtime_sqlite3_db *db = data;
ao2_lock(db);
realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
for (;;) {
if (!db->wakeup) {
ast_cond_wait(&db->cond, ao2_object_get_lockaddr(db));
}
db->wakeup = 0;
if (realtime_sqlite3_execute_handle(db, "COMMIT", NULL, NULL, 0) < 0) {
realtime_sqlite3_execute_handle(db, "ROLLBACK", NULL, NULL, 0);
}
if (db->exiting) {
ao2_unlock(db);
break;
}
realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
ao2_unlock(db);
usleep(1000 * db->batch);
ao2_lock(db);
}
unref_db(&db);
return NULL;
}
| static struct realtime_sqlite3_db* find_database | ( | const char * | database | ) | [static, read] |
Definition at line 216 of file res_config_sqlite3.c.
References ao2_find, and OBJ_KEY.
Referenced by parse_config(), realtime_sqlite3_execute(), and realtime_sqlite3_require().
| static const char* get_sqlite_column_type | ( | int | type | ) | [static] |
Convert Asterisk realtime types to SQLite 3 types.
Definition at line 887 of file res_config_sqlite3.c.
References RQ_CHAR, RQ_DATE, RQ_DATETIME, RQ_FLOAT, RQ_INTEGER1, RQ_INTEGER2, RQ_INTEGER3, RQ_INTEGER4, RQ_INTEGER8, RQ_UINTEGER1, RQ_UINTEGER2, RQ_UINTEGER3, RQ_UINTEGER4, and RQ_UINTEGER8.
Referenced by handle_missing_column(), and handle_missing_table().
{
switch(type) {
case RQ_INTEGER1 :
case RQ_UINTEGER1 :
case RQ_INTEGER2 :
case RQ_UINTEGER2 :
case RQ_INTEGER3 :
case RQ_UINTEGER3 :
case RQ_INTEGER4 :
case RQ_UINTEGER4 :
case RQ_INTEGER8 :
return "INTEGER";
case RQ_UINTEGER8 : /* SQLite3 stores INTEGER as signed 8-byte */
case RQ_CHAR :
case RQ_DATE :
case RQ_DATETIME :
return "TEXT";
case RQ_FLOAT :
return "REAL";
default :
return "TEXT";
}
return "TEXT";
}
| static int handle_missing_column | ( | struct realtime_sqlite3_db * | db, |
| const char * | table, | ||
| const char * | column, | ||
| int | type, | ||
| size_t | sz | ||
| ) | [static] |
If ast_realtime_require sends info about a column we don't have, create it.
Definition at line 947 of file res_config_sqlite3.c.
References ast_log(), get_sqlite_column_type(), LOG_NOTICE, LOG_WARNING, realtime_sqlite3_db::name, realtime_sqlite3_execute_handle(), REALTIME_SQLITE3_REQ_CHAR, REALTIME_SQLITE3_REQ_WARN, and realtime_sqlite3_db::requirements.
Referenced by realtime_sqlite3_require().
{
char *sql;
const char *sqltype = get_sqlite_column_type(type);
int res;
if (db->requirements == REALTIME_SQLITE3_REQ_WARN) {
ast_log(LOG_WARNING, "Missing column '%s' of type '%s' in %s.%s\n", column, sqltype, db->name, table);
return -1;
} else if (db->requirements == REALTIME_SQLITE3_REQ_CHAR) {
sqltype = "TEXT";
}
if (!(sql = sqlite3_mprintf("ALTER TABLE \"%q\" ADD COLUMN \"%q\" %s", table, column, sqltype))) {
return -1;
}
if (!(res = (realtime_sqlite3_execute_handle(db, sql, NULL, NULL, 1) < 0 ? -1 : 0))) {
ast_log(LOG_NOTICE, "Creating column '%s' type %s for table %s\n", column, sqltype, table);
}
sqlite3_free(sql);
return res;
}
| static int handle_missing_table | ( | struct realtime_sqlite3_db * | db, |
| const char * | table, | ||
| va_list | ap | ||
| ) | [static] |
Create a table if ast_realtime_require shows that we are configured to handle the data.
Definition at line 916 of file res_config_sqlite3.c.
References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), first, get_sqlite_column_type(), realtime_sqlite3_execute_handle(), sqlite3_escape_column(), sqlite3_escape_table(), type, and typeof().
Referenced by realtime_sqlite3_require().
{
const char *column;
int type, first = 1, res;
size_t sz;
struct ast_str *sql;
if (!(sql = ast_str_create(128))) {
return -1;
}
while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
if (first) {
ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
sqlite3_escape_column(column), get_sqlite_column_type(type));
first = 0;
} else {
ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
}
}
ast_str_append(&sql, 0, ")");
res = realtime_sqlite3_execute_handle(db, ast_str_buffer(sql), NULL, NULL, 1) < 0 ? -1 : 0;
ast_free(sql);
return res;
}
| static int is_dirty_cb | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 247 of file res_config_sqlite3.c.
References CMP_MATCH, db_stop_batch(), and realtime_sqlite3_db::dirty.
Referenced by unlink_dirty_databases().
{
struct realtime_sqlite3_db *db = obj;
if (db->dirty) {
db_stop_batch(db);
return CMP_MATCH;
}
return 0;
}
| static int load_module | ( | void | ) | [static] |
Definition at line 1165 of file res_config_sqlite3.c.
References ao2_container_alloc, ao2_ref, ast_config_engine_register(), ast_log(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, DB_BUCKETS, db_cmp_fn(), db_hash_fn(), LOG_ERROR, and parse_config().
{
if (!((databases = ao2_container_alloc(DB_BUCKETS, db_hash_fn, db_cmp_fn)))) {
return AST_MODULE_LOAD_FAILURE;
}
if (parse_config(0)) {
ao2_ref(databases, -1);
return AST_MODULE_LOAD_FAILURE;
}
if (!(ast_config_engine_register(&sqlite3_config_engine))) {
ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
ao2_ref(databases, -1);
return AST_MODULE_LOAD_FAILURE;
}
return AST_MODULE_LOAD_SUCCESS;
}
| static void mark_all_databases_dirty | ( | void | ) | [static] |
Definition at line 242 of file res_config_sqlite3.c.
References ao2_callback, mark_dirty_cb(), OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by parse_config().
{
ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA, mark_dirty_cb, NULL);
}
| static int mark_dirty_cb | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 235 of file res_config_sqlite3.c.
References CMP_MATCH, and realtime_sqlite3_db::dirty.
Referenced by mark_all_databases_dirty().
{
struct realtime_sqlite3_db *db = obj;
db->dirty = 1;
return CMP_MATCH;
}
| static struct realtime_sqlite3_db* new_realtime_sqlite3_db | ( | struct ast_config * | config, |
| const char * | cat | ||
| ) | [static, read] |
Create a db object based on a config category.
Definition at line 357 of file res_config_sqlite3.c.
References ao2_alloc, ast_app_parse_timelen(), ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variable_browse(), realtime_sqlite3_db::batch, db, db_destructor(), realtime_sqlite3_db::debug, realtime_sqlite3_db::filename, LOG_WARNING, name, ast_variable::name, ast_variable::next, REALTIME_SQLITE3_REQ_WARN, realtime_sqlite3_db::requirements, str_to_requirements(), TIMELEN_MILLISECONDS, unref_db(), ast_variable::value, and var.
Referenced by parse_config(), and update_realtime_sqlite3_db().
{
struct ast_variable *var;
struct realtime_sqlite3_db *db;
if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
return NULL;
}
if (ast_string_field_init(db, 64)) {
unref_db(&db);
return NULL;
}
/* Set defaults */
db->requirements = REALTIME_SQLITE3_REQ_WARN;
db->batch = 100;
ast_string_field_set(db, name, cat);
for (var = ast_variable_browse(config, cat); var; var = var->next) {
if (!strcasecmp(var->name, "dbfile")) {
ast_string_field_set(db, filename, var->value);
} else if (!strcasecmp(var->name, "requirements")) {
db->requirements = str_to_requirements(var->value);
} else if (!strcasecmp(var->name, "batch")) {
ast_app_parse_timelen(var->value, (int *) &db->batch, TIMELEN_MILLISECONDS);
} else if (!strcasecmp(var->name, "debug")) {
db->debug = ast_true(var->value);
}
}
if (ast_strlen_zero(db->filename)) {
ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
unref_db(&db);
return NULL;
}
return db;
}
| static int parse_config | ( | int | reload | ) | [static] |
Parse the res_config_sqlite3 config file.
Definition at line 1090 of file res_config_sqlite3.c.
References ao2_link, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOREALTIME, config_lock, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, db, db_open(), db_start_batch(), find_database(), LOG_ERROR, LOG_WARNING, mark_all_databases_dirty(), new_realtime_sqlite3_db(), unlink_dirty_databases(), unref_db(), and update_realtime_sqlite3_db().
Referenced by load_module(), and reload().
{
struct ast_config *config;
struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME | (reload ? CONFIG_FLAG_FILEUNCHANGED : 0) };
static const char *config_filename = "res_config_sqlite3.conf";
config = ast_config_load(config_filename, config_flags);
if (config == CONFIG_STATUS_FILEUNCHANGED) {
ast_debug(1, "%s was unchanged, skipping parsing\n", config_filename);
return 0;
}
ast_mutex_lock(&config_lock);
if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "%s config file '%s'\n",
config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
} else {
const char *cat;
struct realtime_sqlite3_db *db;
mark_all_databases_dirty();
for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
if (!strcasecmp(cat, "general")) {
continue;
}
if (!(db = find_database(cat))) {
if (!(db = new_realtime_sqlite3_db(config, cat))) {
ast_log(LOG_WARNING, "Could not allocate new db for '%s' - skipping.\n", cat);
continue;
}
if (db_open(db)) {
unref_db(&db);
continue;
}
db_start_batch(db);
ao2_link(databases, db);
unref_db(&db);
} else {
if (update_realtime_sqlite3_db(db, config, cat)) {
unref_db(&db);
continue;
}
unref_db(&db);
}
}
unlink_dirty_databases();
}
ast_mutex_unlock(&config_lock);
ast_config_destroy(config);
return 0;
}
| static struct ast_variable * realtime_sqlite3 | ( | const char * | database, |
| const char * | table, | ||
| va_list | ap | ||
| ) | [static, read] |
Realtime callback for a single row query.
Definition at line 685 of file res_config_sqlite3.c.
References realtime_sqlite3_helper().
{
struct ast_variable *result_row = NULL;
realtime_sqlite3_helper(database, table, ap, 0, &result_row);
return result_row;
}
| static int realtime_sqlite3_destroy | ( | const char * | database, |
| const char * | table, | ||
| const char * | keyfield, | ||
| const char * | entity, | ||
| va_list | ap | ||
| ) | [static] |
Realtime callback for deleting a row.
Definition at line 849 of file res_config_sqlite3.c.
References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.
{
struct ast_str *sql;
const char *param, *value;
int first = 1, res;
if (ast_strlen_zero(table)) {
ast_log(LOG_WARNING, "Must have a table to query!\n");
return -1;
}
if (!(sql = ast_str_create(128))) {
return -1;
}
while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
sqlite3_escape_column_op(param), sqlite3_escape_value(value));
first = 0;
} else {
ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param), sqlite3_escape_value(value));
}
}
res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
return res;
}
| static int realtime_sqlite3_execute | ( | const char * | database, |
| const char * | sql, | ||
| int(*)(void *, int, char **, char **) | callback, | ||
| void * | arg, | ||
| int | sync | ||
| ) | [static] |
Exeute an SQL statement give the database name
| -1 | ERROR |
| > | -1 Number of rows changed |
Definition at line 540 of file res_config_sqlite3.c.
References ao2_ref, ast_log(), db, find_database(), LOG_WARNING, and realtime_sqlite3_execute_handle().
Referenced by realtime_sqlite3_destroy(), realtime_sqlite3_helper(), realtime_sqlite3_load(), realtime_sqlite3_store(), realtime_sqlite3_update(), and realtime_sqlite3_update2().
{
struct realtime_sqlite3_db *db;
int res;
if (!(db = find_database(database))) {
ast_log(LOG_WARNING, "Could not find database: %s\n", database);
return -1;
}
res = realtime_sqlite3_execute_handle(db, sql, callback, arg, sync);
ao2_ref(db, -1);
return res;
}
| static int realtime_sqlite3_execute_handle | ( | struct realtime_sqlite3_db * | db, |
| const char * | sql, | ||
| int(*)(void *, int, char **, char **) | callback, | ||
| void * | arg, | ||
| int | sync | ||
| ) | [static] |
Exeute an SQL statement given the database object
| -1 | ERROR |
| > | -1 Number of rows changed |
Definition at line 513 of file res_config_sqlite3.c.
References ao2_lock, ao2_unlock, ast_log(), db_sync(), realtime_sqlite3_db::handle, and LOG_WARNING.
Referenced by db_sync_thread(), handle_missing_column(), handle_missing_table(), realtime_sqlite3_execute(), and realtime_sqlite3_require().
{
int res = 0;
char *errmsg;
ao2_lock(db);
if (sqlite3_exec(db->handle, sql, callback, arg, &errmsg) != SQLITE_OK) {
ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
sqlite3_free(errmsg);
res = -1;
} else {
res = sqlite3_changes(db->handle);
}
ao2_unlock(db);
if (sync) {
db_sync(db);
}
return res;
}
| static int realtime_sqlite3_helper | ( | const char * | database, |
| const char * | table, | ||
| va_list | ap, | ||
| int | is_multi, | ||
| void * | arg | ||
| ) | [static] |
Helper function for single and multi-row realtime load functions.
Definition at line 642 of file res_config_sqlite3.c.
References append_row_to_cfg(), ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), row_to_varlist(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.
Referenced by realtime_sqlite3(), and realtime_sqlite3_multi().
{
struct ast_str *sql;
const char *param, *value;
int first = 1;
if (ast_strlen_zero(table)) {
ast_log(LOG_WARNING, "Must have a table to query!\n");
return -1;
}
if (!(sql = ast_str_create(128))) {
return -1;
}
while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
sqlite3_escape_column_op(param), sqlite3_escape_value(value));
first = 0;
} else {
ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param),
sqlite3_escape_value(value));
}
}
if (!is_multi) {
ast_str_append(&sql, 0, "%s", " LIMIT 1");
}
if (realtime_sqlite3_execute(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg, 0) < 0) {
ast_free(sql);
return -1;
}
ast_free(sql);
return 0;
}
| static struct ast_config * realtime_sqlite3_load | ( | const char * | database, |
| const char * | table, | ||
| const char * | configfile, | ||
| struct ast_config * | config, | ||
| struct ast_flags | flags, | ||
| const char * | suggested_include_file, | ||
| const char * | who_asked | ||
| ) | [static, read] |
Realtime callback for static realtime.
Definition at line 613 of file res_config_sqlite3.c.
References ast_log(), ast_strlen_zero(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, config, cfg_entry_args::flags, LOG_WARNING, realtime_sqlite3_execute(), static_realtime_cb(), and cfg_entry_args::who_asked.
{
char *sql;
struct cfg_entry_args args;
if (ast_strlen_zero(table)) {
ast_log(LOG_WARNING, "Must have a table to query!\n");
return NULL;
}
if (!(sql = sqlite3_mprintf(static_sql, table, configfile))) {
ast_log(LOG_WARNING, "Couldn't allocate query\n");
return NULL;
};
args.cfg = config;
args.cat = NULL;
args.cat_name = NULL;
args.flags = flags;
args.who_asked = who_asked;
realtime_sqlite3_execute(database, sql, static_realtime_cb, &args, 0);
sqlite3_free(sql);
return config;
}
| static struct ast_config * realtime_sqlite3_multi | ( | const char * | database, |
| const char * | table, | ||
| va_list | ap | ||
| ) | [static, read] |
Realtime callback for a multi-row query.
Definition at line 697 of file res_config_sqlite3.c.
References ast_config_destroy(), ast_config_new(), and realtime_sqlite3_helper().
{
struct ast_config *cfg;
if (!(cfg = ast_config_new())) {
return NULL;
}
if (realtime_sqlite3_helper(database, table, ap, 1, cfg)) {
ast_config_destroy(cfg);
return NULL;
}
return cfg;
}
| static int realtime_sqlite3_require | ( | const char * | database, |
| const char * | table, | ||
| va_list | ap | ||
| ) | [static] |
Callback for ast_realtime_require.
| 0 | Required fields met specified standards |
| -1 | One or more fields was missing or insufficient |
Definition at line 1006 of file res_config_sqlite3.c.
References add_column_name(), ao2_container_alloc, ao2_find, ao2_ref, ast_log(), ast_strlen_zero(), columns, db, find_database(), handle_missing_column(), handle_missing_table(), LOG_WARNING, OBJ_POINTER, OBJ_UNLINK, realtime_sqlite3_execute_handle(), str_cmp_fn(), str_hash_fn(), type, typeof(), and unref_db().
{
const char *column;
char *sql;
int type;
int res;
size_t sz;
struct ao2_container *columns;
struct realtime_sqlite3_db *db;
/* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
* return the results as char * anyway. The only field that that cannot contain text
* data is an INTEGER PRIMARY KEY, which must be a 64-bit signed integer. So, for
* the purposes here we really only care whether the column exists and not what its
* type or length is. */
if (ast_strlen_zero(table)) {
ast_log(LOG_WARNING, "Must have a table to query!\n");
return -1;
}
if (!(db = find_database(database))) {
return -1;
}
if (!(columns = ao2_container_alloc(31, str_hash_fn, str_cmp_fn))) {
unref_db(&db);
return -1;
}
if (!(sql = sqlite3_mprintf("PRAGMA table_info(\"%q\")", table))) {
unref_db(&db);
ao2_ref(columns, -1);
return -1;
}
if ((res = realtime_sqlite3_execute_handle(db, sql, add_column_name, columns, 0)) < 0) {
unref_db(&db);
ao2_ref(columns, -1);
sqlite3_free(sql);
return -1;
} else if (res == 0) {
/* Table does not exist */
sqlite3_free(sql);
res = handle_missing_table(db, table, ap);
ao2_ref(columns, -1);
unref_db(&db);
return res;
}
sqlite3_free(sql);
while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
char *found;
if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
if (handle_missing_column(db, table, column, type, sz)) {
unref_db(&db);
ao2_ref(columns, -1);
return -1;
}
} else {
ao2_ref(found, -1);
}
}
ao2_ref(columns, -1);
unref_db(&db);
return 0;
}
| static int realtime_sqlite3_store | ( | const char * | database, |
| const char * | table, | ||
| va_list | ap | ||
| ) | [static] |
Realtime callback for inserting a row.
Definition at line 805 of file res_config_sqlite3.c.
References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column(), sqlite3_escape_table(), sqlite3_escape_value(), and value.
{
struct ast_str *sql, *values;
const char *column, *value;
int first = 1, res;
if (ast_strlen_zero(table)) {
ast_log(LOG_WARNING, "Must have a table to query!\n");
return -1;
}
if (!(sql = ast_str_create(128))) {
return -1;
}
if (!(values = ast_str_create(128))) {
ast_free(sql);
return -1;
}
while ((column = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(column));
ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(value));
first = 0;
} else {
ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(column));
ast_str_append(&values, 0, ", %s", sqlite3_escape_value(value));
}
}
ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));
res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
ast_free(values);
return res;
}
| static int realtime_sqlite3_unload | ( | const char * | database, |
| const char * | table | ||
| ) | [static] |
Callback for clearing any cached info.
| 0 | If any cache was purged |
| -1 | If no cache was found |
Definition at line 1082 of file res_config_sqlite3.c.
{
/* We currently do no caching */
return -1;
}
| static int realtime_sqlite3_update | ( | const char * | database, |
| const char * | table, | ||
| const char * | keyfield, | ||
| const char * | entity, | ||
| va_list | ap | ||
| ) | [static] |
Realtime callback for updating a row based on a single criteria.
Definition at line 716 of file res_config_sqlite3.c.
References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.
{
struct ast_str *sql;
const char *key, *value;
int first = 1, res;
if (ast_strlen_zero(table)) {
ast_log(LOG_WARNING, "Must have a table to query!\n");
return -1;
}
if (!(sql = ast_str_create(128))) {
return -1;
}
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
first = 0;
} else {
ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
}
}
ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));
res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
return res;
}
| static int realtime_sqlite3_update2 | ( | const char * | database, |
| const char * | table, | ||
| va_list | ap | ||
| ) | [static] |
Realtime callback for updating a row based on multiple criteria.
Definition at line 752 of file res_config_sqlite3.c.
References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.
{
struct ast_str *sql;
struct ast_str *where_clause;
const char *key, *value;
int first = 1, res;
if (ast_strlen_zero(table)) {
ast_log(LOG_WARNING, "Must have a table to query!\n");
return -1;
}
if (!(sql = ast_str_create(128))) {
return -1;
}
if (!(where_clause = ast_str_create(128))) {
ast_free(sql);
return -1;
}
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
first = 0;
} else {
ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
}
}
first = 1;
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
first = 0;
} else {
ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
}
}
ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));
res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
ast_free(where_clause);
return res;
}
| static int reload | ( | void | ) | [static] |
Definition at line 1147 of file res_config_sqlite3.c.
References parse_config().
{
parse_config(1);
return 0;
}
| static int row_to_varlist | ( | void * | arg, |
| int | num_columns, | ||
| char ** | values, | ||
| char ** | columns | ||
| ) | [static] |
Create a varlist from a single sqlite3 result row.
Definition at line 447 of file res_config_sqlite3.c.
References ast_variable_new(), ast_variables_destroy(), ast_variable::next, and S_OR.
Referenced by realtime_sqlite3_helper().
{
struct ast_variable **head = arg, *tail;
int i;
struct ast_variable *new;
if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
return SQLITE_ABORT;
}
*head = tail = new;
for (i = 1; i < num_columns; i++) {
if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
ast_variables_destroy(*head);
*head = NULL;
return SQLITE_ABORT;
}
tail->next = new;
tail = new;
}
return 0;
}
| static const char* sqlite3_escape_column | ( | const char * | param | ) | [inline, static] |
Definition at line 144 of file res_config_sqlite3.c.
References escape_column_buf, and sqlite3_escape_string_helper().
Referenced by handle_missing_table(), realtime_sqlite3_store(), realtime_sqlite3_update(), and realtime_sqlite3_update2().
{
return sqlite3_escape_string_helper(&escape_column_buf, param);
}
| static const char* sqlite3_escape_column_op | ( | const char * | param | ) | [static] |
Definition at line 150 of file res_config_sqlite3.c.
References ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), ast_str_update(), and escape_column_buf.
Referenced by realtime_sqlite3_destroy(), realtime_sqlite3_helper(), realtime_sqlite3_update(), and realtime_sqlite3_update2().
{
size_t maxlen = strlen(param) * 2 + sizeof("\"\" =");
struct ast_str *buf = ast_str_thread_get(&escape_column_buf, maxlen);
char *tmp = ast_str_buffer(buf);
int space = 0;
ast_str_reset(buf);
*tmp++ = '"';
while ((*tmp++ = *param++)) {
/* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
* available to users via an API, we will definitely need to avoid allowing special
* characters like ';' in the data past the space as it will be unquoted data */
if (space) {
continue;
}
if (*(tmp - 1) == ' ') {
*(tmp - 1) = '"';
*tmp++ = ' ';
space = 1;
} else if (*(tmp - 1) == '"') {
*tmp++ = '"';
}
}
if (!space) {
strcpy(tmp - 1, "\" =");
}
ast_str_update(buf);
return ast_str_buffer(buf);
}
| static const char* sqlite3_escape_string_helper | ( | struct ast_threadstorage * | ts, |
| const char * | param | ||
| ) | [inline, static] |
Definition at line 113 of file res_config_sqlite3.c.
References ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), ast_str_update(), and escape_value_buf.
Referenced by sqlite3_escape_column(), sqlite3_escape_table(), and sqlite3_escape_value().
{
size_t maxlen = strlen(param) * 2 + sizeof("\"\"");
/* It doesn't appear that sqlite3_snprintf will do more than double the
* length of a string with %q as an option. %Q could double and possibly
* add two quotes, and convert NULL pointers to the word "NULL", but we
* don't allow those anyway. Just going to use %q for now. */
struct ast_str *buf = ast_str_thread_get(ts, maxlen);
char *tmp = ast_str_buffer(buf);
char q = ts == &escape_value_buf ? '\'' : '"';
ast_str_reset(buf);
*tmp++ = q; /* Initial quote */
while ((*tmp++ = *param++)) {
/* Did we just copy a quote? Then double it. */
if (*(tmp - 1) == q) {
*tmp++ = q;
}
}
*tmp = '\0'; /* Terminate past NULL from copy */
*(tmp - 1) = q; /* Replace original NULL with the quote */
ast_str_update(buf);
return ast_str_buffer(buf);
}
| static const char* sqlite3_escape_table | ( | const char * | param | ) | [inline, static] |
Definition at line 139 of file res_config_sqlite3.c.
References escape_table_buf, and sqlite3_escape_string_helper().
Referenced by handle_missing_table(), realtime_sqlite3_destroy(), realtime_sqlite3_helper(), realtime_sqlite3_store(), realtime_sqlite3_update(), and realtime_sqlite3_update2().
{
return sqlite3_escape_string_helper(&escape_table_buf, param);
}
| static const char* sqlite3_escape_value | ( | const char * | param | ) | [inline, static] |
Definition at line 183 of file res_config_sqlite3.c.
References escape_value_buf, and sqlite3_escape_string_helper().
Referenced by realtime_sqlite3_destroy(), realtime_sqlite3_helper(), realtime_sqlite3_store(), realtime_sqlite3_update(), and realtime_sqlite3_update2().
{
return sqlite3_escape_string_helper(&escape_value_buf, param);
}
| static int static_realtime_cb | ( | void * | arg, |
| int | num_columns, | ||
| char ** | values, | ||
| char ** | columns | ||
| ) | [static] |
Definition at line 565 of file res_config_sqlite3.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, COL_CATEGORY, COL_VAR_NAME, COL_VAR_VAL, cfg_entry_args::flags, LOG_WARNING, var, and cfg_entry_args::who_asked.
Referenced by realtime_sqlite3_load().
{
struct cfg_entry_args *args = arg;
struct ast_variable *var;
if (!strcmp(values[COL_VAR_NAME], "#include")) {
struct ast_config *cfg;
char *val;
val = values[COL_VAR_VAL];
if (!(cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked))) {
ast_log(LOG_WARNING, "Unable to include %s\n", val);
return SQLITE_ABORT;
} else {
args->cfg = cfg;
return 0;
}
}
if (!args->cat_name || strcmp(args->cat_name, values[COL_CATEGORY])) {
if (!(args->cat = ast_category_new(values[COL_CATEGORY], "", 99999))) {
ast_log(LOG_WARNING, "Unable to allocate category\n");
return SQLITE_ABORT;
}
ast_free(args->cat_name);
if (!(args->cat_name = ast_strdup(values[COL_CATEGORY]))) {
ast_category_destroy(args->cat);
return SQLITE_ABORT;
}
ast_category_append(args->cfg, args->cat);
}
if (!(var = ast_variable_new(values[COL_VAR_NAME], values[COL_VAR_VAL], ""))) {
ast_log(LOG_WARNING, "Unable to allocate variable\n");
return SQLITE_ABORT;
}
ast_variable_append(args->cat, var);
return 0;
}
| static int stop_batch_cb | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 227 of file res_config_sqlite3.c.
References CMP_MATCH, and db_stop_batch().
Referenced by unload_module().
{
struct realtime_sqlite3_db *db = obj;
db_stop_batch(db);
return CMP_MATCH;
}
| static int str_cmp_fn | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 978 of file res_config_sqlite3.c.
Referenced by realtime_sqlite3_require().
{
return !strcasecmp((const char *) obj, (const char *) arg);
}
| static int str_hash_fn | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 973 of file res_config_sqlite3.c.
References ast_str_hash().
Referenced by realtime_sqlite3_require().
{
return ast_str_hash((const char *) obj);
}
| static int str_to_requirements | ( | const char * | data | ) | [static] |
Definition at line 262 of file res_config_sqlite3.c.
References REALTIME_SQLITE3_REQ_CHAR, REALTIME_SQLITE3_REQ_CLOSE, and REALTIME_SQLITE3_REQ_WARN.
Referenced by new_realtime_sqlite3_db().
{
if (!strcasecmp(data, "createclose")) {
return REALTIME_SQLITE3_REQ_CLOSE;
} else if (!strcasecmp(data, "createchar")) {
return REALTIME_SQLITE3_REQ_CHAR;
}
/* default */
return REALTIME_SQLITE3_REQ_WARN;
}
| static void trace_cb | ( | void * | arg, |
| const char * | sql | ||
| ) | [static] |
Definition at line 274 of file res_config_sqlite3.c.
References ast_debug, and realtime_sqlite3_db::name.
Referenced by db_open(), and update_realtime_sqlite3_db().
{
struct realtime_sqlite3_db *db = arg;
ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
}
| static void unlink_dirty_databases | ( | void | ) | [static] |
Definition at line 257 of file res_config_sqlite3.c.
References ao2_callback, is_dirty_cb(), OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.
Referenced by parse_config().
{
ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, is_dirty_cb, NULL);
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 1153 of file res_config_sqlite3.c.
References ao2_callback, ao2_ref, ast_config_engine_deregister(), ast_mutex_lock, ast_mutex_unlock, config_lock, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and stop_batch_cb().
{
ast_mutex_lock(&config_lock);
ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, stop_batch_cb, NULL);
ao2_ref(databases, -1);
databases = NULL;
ast_config_engine_deregister(&sqlite3_config_engine);
ast_mutex_unlock(&config_lock);
return 0;
}
| static void unref_db | ( | struct realtime_sqlite3_db ** | db | ) | [static] |
Definition at line 221 of file res_config_sqlite3.c.
References ao2_ref.
Referenced by db_sync_thread(), new_realtime_sqlite3_db(), parse_config(), realtime_sqlite3_require(), and update_realtime_sqlite3_db().
{
ao2_ref(*db, -1);
*db = NULL;
}
| static int update_realtime_sqlite3_db | ( | struct realtime_sqlite3_db * | db, |
| struct ast_config * | config, | ||
| const char * | cat | ||
| ) | [static] |
Update an existing db object based on config data.
| db | The database object to update |
| config | The configuration data with which to update the db |
| cat | The config category (which becomes db->name) |
Definition at line 402 of file res_config_sqlite3.c.
References ast_string_field_set, realtime_sqlite3_db::batch, db_open(), db_start_batch(), db_stop_batch(), realtime_sqlite3_db::debug, realtime_sqlite3_db::dirty, realtime_sqlite3_db::filename, realtime_sqlite3_db::handle, new_realtime_sqlite3_db(), realtime_sqlite3_db::requirements, trace_cb(), and unref_db().
Referenced by parse_config().
{
struct realtime_sqlite3_db *new;
if (!(new = new_realtime_sqlite3_db(config, cat))) {
return -1;
}
/* Copy fields that don't need anything special done on change */
db->requirements = new->requirements;
/* Handle changes that require immediate behavior modification */
if (db->debug != new->debug) {
if (db->debug) {
sqlite3_trace(db->handle, NULL, NULL);
} else {
sqlite3_trace(db->handle, trace_cb, db);
}
db->debug = new->debug;
}
if (strcmp(db->filename, new->filename)) {
sqlite3_close(db->handle);
ast_string_field_set(db, filename, new->filename);
db_open(db); /* Also handles setting appropriate debug on new handle */
}
if (db->batch != new->batch) {
if (db->batch == 0) {
db->batch = new->batch;
db_start_batch(db);
} else if (new->batch == 0) {
db->batch = new->batch;
db_stop_batch(db);
}
db->batch = new->batch;
}
db->dirty = 0;
unref_db(&new);
return 0;
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "SQLite 3 realtime config engine" , .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, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, } [static] |
Definition at line 1190 of file res_config_sqlite3.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1190 of file res_config_sqlite3.c.
ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 102 of file res_config_sqlite3.c.
Referenced by parse_config(), and unload_module().
| struct ao2_container* databases |
Definition at line 99 of file res_config_sqlite3.c.
struct ast_threadstorage escape_column_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_column_buf , .custom_init = NULL , } [static] |
Definition at line 106 of file res_config_sqlite3.c.
Referenced by sqlite3_escape_column(), and sqlite3_escape_column_op().
struct ast_threadstorage escape_table_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_table_buf , .custom_init = NULL , } [static] |
Definition at line 105 of file res_config_sqlite3.c.
Referenced by sqlite3_escape_table().
struct ast_threadstorage escape_value_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_value_buf , .custom_init = NULL , } [static] |
Definition at line 107 of file res_config_sqlite3.c.
Referenced by sqlite3_escape_string_helper(), and sqlite3_escape_value().
Definition at line 64 of file res_config_sqlite3.c.
const char* static_sql = "SELECT category, var_name, var_val FROM \"%q\" WHERE filename = %Q AND commented = 0 ORDER BY cat_metric ASC, var_metric ASC" [static] |
Definition at line 557 of file res_config_sqlite3.c.