Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
res_config_sqlite3.c File Reference

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"
Include dependency graph for res_config_sqlite3.c:

Go to the source code of this file.

Data Structures

struct  cfg_entry_args
 
struct  realtime_sqlite3_db
 
struct  row_counter_args
 

Macros

#define DB_BUCKETS   7
 
#define IS_SQL_LIKE_CLAUSE(x)   ((x) && ast_ends_with(x, " LIKE"))
 

Typedefs

typedef int(* callback_t) (void *, int, char **, char **)
 

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. More...
 
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. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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. More...
 
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. More...
 
static void discover_sqlite3_caps (void)
 
static struct realtime_sqlite3_dbfind_database (const char *database)
 
static const char * get_sqlite_column_type (int type)
 Convert Asterisk realtime types to SQLite 3 types. More...
 
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. More...
 
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. More...
 
static int is_dirty_cb (void *obj, void *arg, int flags)
 
static int load_module (void)
 Load the module. More...
 
static void mark_all_databases_dirty (void)
 
static int mark_dirty_cb (void *obj, void *arg, int flags)
 
static struct realtime_sqlite3_dbnew_realtime_sqlite3_db (struct ast_config *config, const char *cat)
 Create a db object based on a config category. More...
 
static int parse_config (int reload)
 Parse the res_config_sqlite3 config file. More...
 
static struct ast_variablerealtime_sqlite3 (const char *database, const char *table, const struct ast_variable *fields)
 Realtime callback for a single row query. More...
 
static int realtime_sqlite3_destroy (const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
 Realtime callback for deleting a row. More...
 
static int realtime_sqlite3_exec_query (const char *, const char *, callback_t, void *)
 
static int realtime_sqlite3_exec_query_with_handle (struct realtime_sqlite3_db *, const char *, callback_t, void *)
 
static int realtime_sqlite3_exec_update (const char *, const char *)
 
static int realtime_sqlite3_exec_update_with_handle (struct realtime_sqlite3_db *, const char *)
 
static int realtime_sqlite3_helper (const char *database, const char *table, const struct ast_variable *fields, int is_multi, void *arg)
 Helper function for single and multi-row realtime load functions. More...
 
static struct ast_configrealtime_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. More...
 
static struct ast_configrealtime_sqlite3_multi (const char *database, const char *table, const struct ast_variable *fields)
 Realtime callback for a multi-row query. More...
 
static int realtime_sqlite3_require (const char *database, const char *table, va_list ap)
 Callback for ast_realtime_require. More...
 
static int realtime_sqlite3_store (const char *database, const char *table, const struct ast_variable *fields)
 Realtime callback for inserting a row. More...
 
static int realtime_sqlite3_unload (const char *database, const char *table)
 Callback for clearing any cached info. More...
 
static int realtime_sqlite3_update (const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
 Realtime callback for updating a row based on a single criteria. More...
 
static int realtime_sqlite3_update2 (const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
 Realtime callback for updating a row based on multiple criteria. More...
 
static int reload (void)
 
static int row_counter_wrapper (void *arg, int num_columns, char **values, char **columns)
 
static int row_to_varlist (void *arg, int num_columns, char **values, char **columns)
 Create a varlist from a single sqlite3 result row. More...
 
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. More...
 

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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, .requires = "extconfig", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
struct ao2_containerdatabases
 
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 , }
 
static int has_explicit_like_escaping
 
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"
 

Detailed Description

SQLite 3 configuration engine.

Author
Terry Wilson <twilson@digium.com> 

This is a realtime configuration engine for the SQLite 3 Database

Definition in file res_config_sqlite3.c.

Macro Definition Documentation

◆ DB_BUCKETS

#define DB_BUCKETS   7

Definition at line 108 of file res_config_sqlite3.c.

◆ IS_SQL_LIKE_CLAUSE

#define IS_SQL_LIKE_CLAUSE (   x)    ((x) && ast_ends_with(x, " LIKE"))

Definition at line 793 of file res_config_sqlite3.c.

Typedef Documentation

◆ callback_t

typedef int(* callback_t) (void *, int, char **, char **)

Definition at line 117 of file res_config_sqlite3.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
REALTIME_SQLITE3_REQ_WARN 
REALTIME_SQLITE3_REQ_CLOSE 
REALTIME_SQLITE3_REQ_CHAR 

Definition at line 83 of file res_config_sqlite3.c.

◆ anonymous enum

anonymous enum
Enumerator
COL_CATEGORY 
COL_VAR_NAME 
COL_VAR_VAL 
COL_COLUMNS 

Definition at line 710 of file res_config_sqlite3.c.

710 {
715};
@ COL_COLUMNS
@ COL_VAR_VAL
@ COL_CATEGORY
@ COL_VAR_NAME

Function Documentation

◆ __init_escape_column_buf()

static void __init_escape_column_buf ( void  )
static

Definition at line 114 of file res_config_sqlite3.c.

128{

◆ __init_escape_table_buf()

static void __init_escape_table_buf ( void  )
static

Definition at line 113 of file res_config_sqlite3.c.

128{

◆ __init_escape_value_buf()

static void __init_escape_value_buf ( void  )
static

Definition at line 115 of file res_config_sqlite3.c.

128{

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1400 of file res_config_sqlite3.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1400 of file res_config_sqlite3.c.

◆ add_column_name()

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 1149 of file res_config_sqlite3.c.

1150{
1151 char *column;
1152 struct ao2_container *cnames = arg;
1153
1154
1155 if (!(column = ao2_alloc(strlen(values[1]) + 1, NULL))) {
1156 return -1;
1157 }
1158
1159 strcpy(column, values[1]);
1160
1161 ao2_link(cnames, column);
1162 ao2_ref(column, -1);
1163
1164 return 0;
1165}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define NULL
Definition: resample.c:96
Generic container type.

References ao2_alloc, ao2_link, ao2_ref, and NULL.

Referenced by realtime_sqlite3_require().

◆ append_row_to_cfg()

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 510 of file res_config_sqlite3.c.

511{
512 struct ast_config *cfg = arg;
513 struct ast_category *cat;
514 int i;
515
517 if (!cat) {
518 return SQLITE_ABORT;
519 }
520
521 for (i = 0; i < num_columns; i++) {
522 struct ast_variable *var;
523 if (!(var = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
524 ast_log(LOG_ERROR, "Could not create new variable for '%s: %s', throwing away list\n", columns[i], values[i]);
525 continue;
526 }
528 }
529 ast_category_append(cfg, cat);
530
531 return 0;
532}
#define var
Definition: ast_expr2f.c:605
#define ast_log
Definition: astobj2.c:42
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
Definition: extconf.c:2833
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: extconf.c:1177
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
#define ast_variable_new(name, value, filename)
#define LOG_ERROR
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
Structure for variables, used for configurations and for channel variables.

References ast_category_append(), ast_category_new_anonymous, ast_log, ast_variable_append(), ast_variable_new, LOG_ERROR, S_OR, and var.

Referenced by realtime_sqlite3_helper().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1400 of file res_config_sqlite3.c.

◆ db_cmp_fn()

static int db_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 221 of file res_config_sqlite3.c.

221 {
222 struct realtime_sqlite3_db *db = obj, *other = arg;
223 const char *name = arg;
224
225 return !strcasecmp(db->name, flags & OBJ_KEY ? name : other->name) ? CMP_MATCH | CMP_STOP : 0;
226}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
#define OBJ_KEY
Definition: astobj2.h:1151
static sqlite3 * db
static const char name[]
Definition: format_mp3.c:68

References CMP_MATCH, CMP_STOP, db, name, and OBJ_KEY.

Referenced by load_module().

◆ db_destructor()

static void db_destructor ( void *  obj)
static

Definition at line 228 of file res_config_sqlite3.c.

229{
230 struct realtime_sqlite3_db *db = obj;
231
232 ast_debug(1, "Destroying db: %s\n", db->name);
235 if (db->handle) {
236 ao2_lock(db);
237 sqlite3_close(db->handle);
238 ao2_unlock(db);
239 }
240}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ast_debug(level,...)
Log a DEBUG message.
void db_stop_batch(struct realtime_sqlite3_db *db)
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ao2_lock, ao2_unlock, ast_debug, ast_string_field_free_memory, db, and db_stop_batch().

Referenced by new_realtime_sqlite3_db().

◆ db_hash_fn()

static int db_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 214 of file res_config_sqlite3.c.

215{
216 const struct realtime_sqlite3_db *db = obj;
217
218 return ast_str_hash(flags & OBJ_KEY ? (const char *) obj : db->name);
219}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

References ast_str_hash(), db, and OBJ_KEY.

Referenced by load_module().

◆ db_open()

static int db_open ( struct realtime_sqlite3_db db)
static

Open a database and appropriately set debugging on the db handle.

Definition at line 336 of file res_config_sqlite3.c.

337{
338 ao2_lock(db);
339 if (sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
340 ast_log(LOG_WARNING, "Could not open %s: %s\n", db->filename, sqlite3_errmsg(db->handle));
341 ao2_unlock(db);
342 return -1;
343 }
344 sqlite3_busy_timeout(db->handle, db->busy_timeout);
345
346 if (db->debug) {
347 sqlite3_trace(db->handle, trace_cb, db);
348 } else {
349 sqlite3_trace(db->handle, NULL, NULL);
350 }
351
352 ao2_unlock(db);
353
354 return 0;
355}
#define LOG_WARNING
static void trace_cb(void *arg, const char *sql)

References ao2_lock, ao2_unlock, ast_log, db, LOG_WARNING, NULL, and trace_cb().

Referenced by parse_config(), and update_realtime_sqlite3_db().

◆ db_start_batch()

void db_start_batch ( struct realtime_sqlite3_db db)

Definition at line 363 of file res_config_sqlite3.c.

364{
365 if (db->batch) {
366 ast_cond_init(&db->cond, NULL);
367 ao2_ref(db, +1);
368 db->has_batch_thread = !ast_pthread_create_background(&db->syncthread, NULL, db_sync_thread, db);
369 }
370}
#define ast_cond_init(cond, attr)
Definition: lock.h:201
static void * db_sync_thread(void *data)
Wrap commands in transactions increased write performance.
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:592

References ao2_ref, ast_cond_init, ast_pthread_create_background, db, db_sync_thread(), and NULL.

Referenced by parse_config(), and update_realtime_sqlite3_db().

◆ db_stop_batch()

void db_stop_batch ( struct realtime_sqlite3_db db)

Definition at line 372 of file res_config_sqlite3.c.

373{
374 if (db->has_batch_thread) {
375 db->has_batch_thread = 0;
376 db->exiting = 1;
377 db_sync(db);
378 pthread_join(db->syncthread, NULL);
379 }
380}
static void db_sync(struct realtime_sqlite3_db *db)

References db, db_sync(), and NULL.

Referenced by db_destructor(), is_dirty_cb(), stop_batch_cb(), and update_realtime_sqlite3_db().

◆ db_sync()

static void db_sync ( struct realtime_sqlite3_db db)
static

Definition at line 357 of file res_config_sqlite3.c.

358{
359 db->wakeup = 1;
360 ast_cond_signal(&db->cond);
361}
#define ast_cond_signal(cond)
Definition: lock.h:203

References ast_cond_signal, and db.

Referenced by db_stop_batch(), and realtime_sqlite3_exec_update_with_handle().

◆ db_sync_thread()

static void * db_sync_thread ( void *  data)
static

Wrap commands in transactions increased write performance.

Definition at line 307 of file res_config_sqlite3.c.

308{
309 struct realtime_sqlite3_db *db = data;
310 ao2_lock(db);
311 realtime_sqlite3_exec_query_with_handle(db, "BEGIN TRANSACTION", NULL, NULL);
312 for (;;) {
313 if (!db->wakeup) {
315 }
316 db->wakeup = 0;
319 }
320 if (db->exiting) {
321 ao2_unlock(db);
322 break;
323 }
324 realtime_sqlite3_exec_query_with_handle(db, "BEGIN TRANSACTION", NULL, NULL);
325 ao2_unlock(db);
326 usleep(1000 * db->batch);
327 ao2_lock(db);
328 }
329
330 unref_db(&db);
331
332 return NULL;
333}
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
static int realtime_sqlite3_exec_query_with_handle(struct realtime_sqlite3_db *, const char *, callback_t, void *)
static void unref_db(struct realtime_sqlite3_db **db)

References ao2_lock, ao2_object_get_lockaddr(), ao2_unlock, ast_cond_wait, db, NULL, realtime_sqlite3_exec_query_with_handle(), and unref_db().

Referenced by db_start_batch().

◆ discover_sqlite3_caps()

static void discover_sqlite3_caps ( void  )
static

Definition at line 1336 of file res_config_sqlite3.c.

1337{
1338 /*
1339 * So we cheat a little bit here. SQLite3 added support for the
1340 * 'ESCAPE' keyword in 3.1.0. They added SQLITE_VERSION_NUMBER
1341 * in 3.1.2. So if we run into 3.1.0 or 3.1.1 in the wild, we
1342 * just treat it like < 3.1.0.
1343 *
1344 * For reference: 3.1.0, 3.1.1, and 3.1.2 were all released
1345 * within 30 days of each other in Jan/Feb 2005, so I don't
1346 * imagine we'll be finding something pre-3.1.2 that often in
1347 * practice.
1348 */
1349#if defined(SQLITE_VERSION_NUMBER)
1351#else
1353#endif
1354
1355 ast_debug(3, "SQLite3 has 'LIKE ... ESCAPE ...' support? %s\n",
1356 has_explicit_like_escaping ? "Yes" : "No");
1357}
static int has_explicit_like_escaping

References ast_debug, and has_explicit_like_escaping.

Referenced by load_module().

◆ find_database()

static struct realtime_sqlite3_db * find_database ( const char *  database)
static

Definition at line 242 of file res_config_sqlite3.c.

243{
244 return ao2_find(databases, database, OBJ_KEY);
245}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, and OBJ_KEY.

Referenced by parse_config(), realtime_sqlite3_exec_query(), realtime_sqlite3_exec_update(), and realtime_sqlite3_require().

◆ get_sqlite_column_type()

static const char * get_sqlite_column_type ( int  type)
static

Convert Asterisk realtime types to SQLite 3 types.

Note
SQLite 3 has NULL, INTEGER, REAL, TEXT, and BLOB types. Any column other than an INTEGER PRIMARY KEY will actually store any kind of data due to its dynamic typing. When we create columns, we'll go ahead and use these base types instead of messing with column widths, etc.

Definition at line 1050 of file res_config_sqlite3.c.

1051{
1052 switch(type) {
1053 case RQ_INTEGER1 :
1054 case RQ_UINTEGER1 :
1055 case RQ_INTEGER2 :
1056 case RQ_UINTEGER2 :
1057 case RQ_INTEGER3 :
1058 case RQ_UINTEGER3 :
1059 case RQ_INTEGER4 :
1060 case RQ_UINTEGER4 :
1061 case RQ_INTEGER8 :
1062 return "INTEGER";
1063 case RQ_UINTEGER8 : /* SQLite3 stores INTEGER as signed 8-byte */
1064 case RQ_CHAR :
1065 case RQ_DATE :
1066 case RQ_DATETIME :
1067 return "TEXT";
1068 case RQ_FLOAT :
1069 return "REAL";
1070 default :
1071 return "TEXT";
1072 }
1073
1074 return "TEXT";
1075}
static const char type[]
Definition: chan_ooh323.c:109

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, RQ_UINTEGER8, and type.

Referenced by handle_missing_column(), and handle_missing_table().

◆ handle_missing_column()

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 1112 of file res_config_sqlite3.c.

1113{
1114 char *sql;
1115 const char *sqltype = get_sqlite_column_type(type);
1116 int res;
1117
1118 if (db->requirements == REALTIME_SQLITE3_REQ_WARN) {
1119 ast_log(LOG_WARNING, "Missing column '%s' of type '%s' in %s.%s\n", column, sqltype, db->name, table);
1120 return -1;
1121 } else if (db->requirements == REALTIME_SQLITE3_REQ_CHAR) {
1122 sqltype = "TEXT";
1123 }
1124
1125 if (!(sql = sqlite3_mprintf("ALTER TABLE \"%q\" ADD COLUMN \"%q\" %s", table, column, sqltype))) {
1126 return -1;
1127 }
1128
1129 if (!(res = (realtime_sqlite3_exec_update_with_handle(db, sql) < 0 ? -1 : 0))) {
1130 ast_log(LOG_NOTICE, "Creating column '%s' type %s for table %s\n", column, sqltype, table);
1131 }
1132
1133 sqlite3_free(sql);
1134
1135 return res;
1136}
static char * table
Definition: cdr_odbc.c:55
#define LOG_NOTICE
static const char * get_sqlite_column_type(int type)
Convert Asterisk realtime types to SQLite 3 types.
static int realtime_sqlite3_exec_update_with_handle(struct realtime_sqlite3_db *, const char *)

References ast_log, db, get_sqlite_column_type(), LOG_NOTICE, LOG_WARNING, realtime_sqlite3_exec_update_with_handle(), REALTIME_SQLITE3_REQ_CHAR, REALTIME_SQLITE3_REQ_WARN, table, and type.

Referenced by realtime_sqlite3_require().

◆ handle_missing_table()

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 1079 of file res_config_sqlite3.c.

1080{
1081 const char *column;
1082 int type, first = 1, res;
1083 size_t sz;
1084 struct ast_str *sql;
1085
1086 if (!(sql = ast_str_create(128))) {
1087 return -1;
1088 }
1089
1090 while ((column = va_arg(ap, typeof(column)))) {
1091 type = va_arg(ap, typeof(type));
1092 sz = va_arg(ap, typeof(sz));
1093 if (first) {
1094 ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
1096 first = 0;
1097 } else {
1098 ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
1099 }
1100 }
1101
1102 ast_str_append(&sql, 0, ")");
1103
1105 ast_free(sql);
1106
1107 return res;
1108}
struct sla_ringing_trunk * first
Definition: app_sla.c:332
#define ast_free(a)
Definition: astmm.h:180
static const char * sqlite3_escape_table(const char *param)
static const char * sqlite3_escape_column(const char *param)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
Support for dynamic strings.
Definition: strings.h:623
typedef typeof(dummy_tv_var_for_types.tv_sec) ast_time_t

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), db, first, get_sqlite_column_type(), realtime_sqlite3_exec_update_with_handle(), sqlite3_escape_column(), sqlite3_escape_table(), table, type, and typeof().

Referenced by realtime_sqlite3_require().

◆ is_dirty_cb()

static int is_dirty_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 273 of file res_config_sqlite3.c.

274{
275 struct realtime_sqlite3_db *db = obj;
276 if (db->dirty) {
278 return CMP_MATCH;
279 }
280 return 0;
281}

References CMP_MATCH, db, and db_stop_batch().

Referenced by unlink_dirty_databases().

◆ load_module()

static int load_module ( void  )
static

Load the module.

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

Definition at line 1369 of file res_config_sqlite3.c.

1370{
1372
1375 if (!databases) {
1377 }
1378
1379 if (parse_config(0)) {
1380 ao2_ref(databases, -1);
1382 }
1383
1385 ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
1386 ao2_ref(databases, -1);
1388 }
1389
1391}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Definition: main/config.c:3157
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int db_cmp_fn(void *obj, void *arg, int flags)
static int parse_config(int reload)
Parse the res_config_sqlite3 config file.
static int db_hash_fn(const void *obj, const int flags)
#define DB_BUCKETS
struct ast_config_engine sqlite3_config_engine
static void discover_sqlite3_caps(void)

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_config_engine_register(), ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, DB_BUCKETS, db_cmp_fn(), db_hash_fn(), discover_sqlite3_caps(), LOG_ERROR, NULL, parse_config(), and sqlite3_config_engine.

◆ mark_all_databases_dirty()

static void mark_all_databases_dirty ( void  )
static

Definition at line 268 of file res_config_sqlite3.c.

269{
271}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
static int mark_dirty_cb(void *obj, void *arg, int flags)

References ao2_callback, mark_dirty_cb(), NULL, OBJ_MULTIPLE, and OBJ_NODATA.

Referenced by parse_config().

◆ mark_dirty_cb()

static int mark_dirty_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 261 of file res_config_sqlite3.c.

262{
263 struct realtime_sqlite3_db *db = obj;
264 db->dirty = 1;
265 return CMP_MATCH;
266}

References CMP_MATCH, and db.

Referenced by mark_all_databases_dirty().

◆ new_realtime_sqlite3_db()

static struct realtime_sqlite3_db * new_realtime_sqlite3_db ( struct ast_config config,
const char *  cat 
)
static

Create a db object based on a config category.

Note
Opening the db handle and linking to databases must be handled outside of this function

Definition at line 385 of file res_config_sqlite3.c.

386{
387 struct ast_variable *var;
388 struct realtime_sqlite3_db *db;
389
390 if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
391 return NULL;
392 }
393
394 if (ast_string_field_init(db, 64)) {
395 unref_db(&db);
396 return NULL;
397 }
398
399 /* Set defaults */
400 db->requirements = REALTIME_SQLITE3_REQ_WARN;
401 db->batch = 100;
403 db->busy_timeout = 1000;
404
405 for (var = ast_variable_browse(config, cat); var; var = var->next) {
406 if (!strcasecmp(var->name, "dbfile")) {
408 } else if (!strcasecmp(var->name, "requirements")) {
409 db->requirements = str_to_requirements(var->value);
410 } else if (!strcasecmp(var->name, "batch")) {
411 ast_app_parse_timelen(var->value, (int *) &db->batch, TIMELEN_MILLISECONDS);
412 } else if (!strcasecmp(var->name, "debug")) {
413 db->debug = ast_true(var->value);
414 } else if (!strcasecmp(var->name, "busy_timeout")) {
415 if (ast_parse_arg(var->value, PARSE_INT32|PARSE_DEFAULT, &(db->busy_timeout), 1000) != 0) {
416 ast_log(LOG_WARNING, "Invalid busy_timeout value '%s' at res_config_sqlite3.conf:%d. Using 1000 instead.\n", var->value, var->lineno);
417 }
418 }
419 }
420
421 if (ast_strlen_zero(db->filename)) {
422 ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
423 unref_db(&db);
424 return NULL;
425 }
426
427 return db;
428}
static const char config[]
Definition: chan_ooh323.c:111
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
Definition: main/app.c:3263
@ TIMELEN_MILLISECONDS
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Definition: main/config.c:3827
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
static void db_destructor(void *obj)
static int str_to_requirements(const char *data)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
const ast_string_field filename

References ao2_alloc, ast_app_parse_timelen(), ast_log, ast_parse_arg(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variable_browse(), config, db, db_destructor(), realtime_sqlite3_db::filename, LOG_WARNING, name, NULL, PARSE_DEFAULT, PARSE_INT32, REALTIME_SQLITE3_REQ_WARN, str_to_requirements(), TIMELEN_MILLISECONDS, unref_db(), and var.

Referenced by parse_config(), and update_realtime_sqlite3_db().

◆ parse_config()

static int parse_config ( int  reload)
static

Parse the res_config_sqlite3 config file.

Definition at line 1259 of file res_config_sqlite3.c.

1260{
1261 struct ast_config *config;
1262 struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME | (reload ? CONFIG_FLAG_FILEUNCHANGED : 0) };
1263 static const char *config_filename = "res_config_sqlite3.conf";
1264
1265 config = ast_config_load(config_filename, config_flags);
1266
1268 ast_debug(1, "%s was unchanged, skipping parsing\n", config_filename);
1269 return 0;
1270 }
1271
1273
1275 ast_log(LOG_ERROR, "%s config file '%s'\n",
1276 config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
1278 return 0;
1279 } else {
1280 const char *cat;
1281 struct realtime_sqlite3_db *db;
1282
1284 for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
1285 if (!strcasecmp(cat, "general")) {
1286 continue;
1287 }
1288 if (!(db = find_database(cat))) {
1289 if (!(db = new_realtime_sqlite3_db(config, cat))) {
1290 ast_log(LOG_WARNING, "Could not allocate new db for '%s' - skipping.\n", cat);
1291 continue;
1292 }
1293 if (db_open(db)) {
1294 unref_db(&db);
1295 continue;
1296 }
1299 unref_db(&db);
1300 } else {
1302 unref_db(&db);
1303 continue;
1304 }
1305 unref_db(&db);
1306 }
1307 }
1309 }
1310
1312
1314
1315 return 0;
1316}
static char * config_filename
Definition: extconf.c:2120
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
@ CONFIG_FLAG_NOREALTIME
@ CONFIG_FLAG_FILEUNCHANGED
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
static ast_mutex_t config_lock
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.
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 struct realtime_sqlite3_db * find_database(const char *database)
static void mark_all_databases_dirty(void)
static int db_open(struct realtime_sqlite3_db *db)
Open a database and appropriately set debugging on the db handle.
static int reload(void)
static void unlink_dirty_databases(void)
void db_start_batch(struct realtime_sqlite3_db *db)
Structure used to handle boolean flags.
Definition: utils.h:199

References ao2_link, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, config, config_filename, 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(), NULL, reload(), unlink_dirty_databases(), unref_db(), and update_realtime_sqlite3_db().

Referenced by load_module(), and reload().

◆ realtime_sqlite3()

static struct ast_variable * realtime_sqlite3 ( const char *  database,
const char *  table,
const struct ast_variable fields 
)
static

Realtime callback for a single row query.

Returns
ast_variable list for single result on success, NULL on empty/failure

Definition at line 848 of file res_config_sqlite3.c.

849{
850 struct ast_variable *result_row = NULL;
851
852 realtime_sqlite3_helper(database, table, fields, 0, &result_row);
853
854 return result_row;
855}
static int realtime_sqlite3_helper(const char *database, const char *table, const struct ast_variable *fields, int is_multi, void *arg)
Helper function for single and multi-row realtime load functions.

References NULL, realtime_sqlite3_helper(), and table.

◆ realtime_sqlite3_destroy()

static int realtime_sqlite3_destroy ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
const struct ast_variable fields 
)
static

Realtime callback for deleting a row.

Returns
Number of rows affected or -1 on error

Definition at line 1012 of file res_config_sqlite3.c.

1013{
1014 struct ast_str *sql;
1015 const struct ast_variable *field;
1016 int first = 1, res;
1017
1018 if (ast_strlen_zero(table)) {
1019 ast_log(LOG_WARNING, "Must have a table to query!\n");
1020 return -1;
1021 }
1022
1023 if (!(sql = ast_str_create(128))) {
1024 return -1;
1025 }
1026
1027 for (field = fields; field; field = field->next) {
1028 if (first) {
1029 ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
1031 first = 0;
1032 } else {
1033 ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
1034 }
1035 }
1036
1037 res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
1038
1039 ast_free(sql);
1040
1041 return res;
1042}
static int realtime_sqlite3_exec_update(const char *, const char *)
static const char * sqlite3_escape_value(const char *param)
static const char * sqlite3_escape_column_op(const char *param)
struct ast_variable * next

References ast_free, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), table, and ast_variable::value.

◆ realtime_sqlite3_exec_query()

static int realtime_sqlite3_exec_query ( const char *  database,
const char *  sql,
callback_t  callback,
void *  arg 
)
static

Definition at line 630 of file res_config_sqlite3.c.

631{
632 struct realtime_sqlite3_db *db;
633 int res;
634
635 if (!(db = find_database(database))) {
636 ast_log(LOG_WARNING, "Could not find database: %s\n", database);
637 return -1;
638 }
639
640 res = realtime_sqlite3_exec_query_with_handle(db, sql, callback, arg);
641 ao2_ref(db, -1);
642
643 return res;
644}

References ao2_ref, ast_log, db, find_database(), LOG_WARNING, and realtime_sqlite3_exec_query_with_handle().

Referenced by realtime_sqlite3_helper(), and realtime_sqlite3_load().

◆ realtime_sqlite3_exec_query_with_handle()

static int realtime_sqlite3_exec_query_with_handle ( struct realtime_sqlite3_db db,
const char *  sql,
callback_t  callback,
void *  arg 
)
static

Definition at line 596 of file res_config_sqlite3.c.

597{
598 int res = 0;
599 char *errmsg;
600 struct row_counter_args wrapper = {
601 .wrapped_callback = callback,
602 .wrapped_arg = arg,
603 .row_count = 0,
604 };
605
606 ao2_lock(db);
607 if (sqlite3_exec(db->handle, sql, row_counter_wrapper, &wrapper, &errmsg) != SQLITE_OK) {
608 ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
609 sqlite3_free(errmsg);
610 res = -1;
611 }
612 ao2_unlock(db);
613
614 return res == 0 ? wrapper.row_count : res;
615}
static int row_counter_wrapper(void *arg, int num_columns, char **values, char **columns)
callback_t wrapped_callback

References ao2_lock, ao2_unlock, ast_log, db, LOG_WARNING, row_counter_args::row_count, row_counter_wrapper(), and row_counter_args::wrapped_callback.

Referenced by db_sync_thread(), realtime_sqlite3_exec_query(), and realtime_sqlite3_require().

◆ realtime_sqlite3_exec_update()

static int realtime_sqlite3_exec_update ( const char *  database,
const char *  sql 
)
static

Definition at line 692 of file res_config_sqlite3.c.

693{
694 struct realtime_sqlite3_db *db;
695 int res;
696
697 if (!(db = find_database(database))) {
698 ast_log(LOG_WARNING, "Could not find database: %s\n", database);
699 return -1;
700 }
701
703 ao2_ref(db, -1);
704
705 return res;
706}

References ao2_ref, ast_log, db, find_database(), LOG_WARNING, and realtime_sqlite3_exec_update_with_handle().

Referenced by realtime_sqlite3_destroy(), realtime_sqlite3_store(), realtime_sqlite3_update(), and realtime_sqlite3_update2().

◆ realtime_sqlite3_exec_update_with_handle()

static int realtime_sqlite3_exec_update_with_handle ( struct realtime_sqlite3_db db,
const char *  sql 
)
static

Definition at line 659 of file res_config_sqlite3.c.

660{
661 int res = 0;
662 char *errmsg;
663
664 ao2_lock(db);
665 if (sqlite3_exec(db->handle, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
666 ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
667 sqlite3_free(errmsg);
668 res = -1;
669 } else {
670 res = sqlite3_changes(db->handle);
671 }
672 ao2_unlock(db);
673
674 db_sync(db);
675
676 return res;
677}

References ao2_lock, ao2_unlock, ast_log, db, db_sync(), LOG_WARNING, and NULL.

Referenced by handle_missing_column(), handle_missing_table(), and realtime_sqlite3_exec_update().

◆ realtime_sqlite3_helper()

static int realtime_sqlite3_helper ( const char *  database,
const char *  table,
const struct ast_variable fields,
int  is_multi,
void *  arg 
)
static

Helper function for single and multi-row realtime load functions.

Definition at line 796 of file res_config_sqlite3.c.

797{
798 struct ast_str *sql;
799 const struct ast_variable *field;
800 int first = 1;
801
802 if (ast_strlen_zero(table)) {
803 ast_log(LOG_WARNING, "Must have a table to query!\n");
804 return -1;
805 }
806
807 if (!(sql = ast_str_create(128))) {
808 return -1;
809 }
810
811 for (field = fields; field; field = field->next) {
812 if (first) {
813 ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
815 first = 0;
816 } else {
817 ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name),
819 }
820
822 /*
823 * The realtime framework is going to pre-escape these
824 * for us with a backslash. We just need to make sure
825 * to tell SQLite about it
826 */
827 ast_str_append(&sql, 0, " ESCAPE '\\'");
828 }
829 }
830
831 if (!is_multi) {
832 ast_str_append(&sql, 0, "%s", " LIMIT 1");
833 }
834
835 if (realtime_sqlite3_exec_query(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg) < 0) {
836 ast_free(sql);
837 return -1;
838 }
839
840 ast_free(sql);
841
842 return 0;
843}
static int realtime_sqlite3_exec_query(const char *, const char *, callback_t, void *)
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 row_to_varlist(void *arg, int num_columns, char **values, char **columns)
Create a varlist from a single sqlite3 result row.
#define IS_SQL_LIKE_CLAUSE(x)

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, has_explicit_like_escaping, IS_SQL_LIKE_CLAUSE, LOG_WARNING, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_query(), row_to_varlist(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), table, and ast_variable::value.

Referenced by realtime_sqlite3(), and realtime_sqlite3_multi().

◆ realtime_sqlite3_load()

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

Realtime callback for static realtime.

Returns
ast_config on success, NULL on failure

Definition at line 765 of file res_config_sqlite3.c.

766{
767 char *sql;
768 struct cfg_entry_args args;
769
770 if (ast_strlen_zero(table)) {
771 ast_log(LOG_WARNING, "Must have a table to query!\n");
772 return NULL;
773 }
774
775 if (!(sql = sqlite3_mprintf(static_sql, table, configfile))) {
776 ast_log(LOG_WARNING, "Couldn't allocate query\n");
777 return NULL;
778 };
779
780 args.cfg = config;
781 args.cat = NULL;
782 args.cat_name = NULL;
783 args.flags = flags;
784 args.who_asked = who_asked;
785
787
788 sqlite3_free(sql);
789
790 return config;
791}
static int static_realtime_cb(void *arg, int num_columns, char **values, char **columns)
static const char * static_sql
const char * who_asked
struct ast_flags flags
const char * args

References args, ast_log, ast_strlen_zero(), config, cfg_entry_args::flags, LOG_WARNING, NULL, realtime_sqlite3_exec_query(), static_realtime_cb(), static_sql, table, and cfg_entry_args::who_asked.

◆ realtime_sqlite3_multi()

static struct ast_config * realtime_sqlite3_multi ( const char *  database,
const char *  table,
const struct ast_variable fields 
)
static

Realtime callback for a multi-row query.

Returns
ast_config containing possibly many results on success, NULL on empty/failure

Definition at line 860 of file res_config_sqlite3.c.

861{
862 struct ast_config *cfg;
863
864 if (!(cfg = ast_config_new())) {
865 return NULL;
866 }
867
868 if (realtime_sqlite3_helper(database, table, fields, 1, cfg)) {
870 return NULL;
871 }
872
873 return cfg;
874}
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: extconf.c:3274

References ast_config_destroy(), ast_config_new(), NULL, realtime_sqlite3_helper(), and table.

◆ realtime_sqlite3_require()

static int realtime_sqlite3_require ( const char *  database,
const char *  table,
va_list  ap 
)
static

Callback for ast_realtime_require.

Return values
0Required fields met specified standards
-1One or more fields was missing or insufficient

Definition at line 1171 of file res_config_sqlite3.c.

1172{
1173 const char *column;
1174 char *sql;
1175 int type;
1176 int res;
1177 size_t sz;
1178 struct ao2_container *columns;
1179 struct realtime_sqlite3_db *db;
1180
1181 /* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
1182 * return the results as char * anyway. The only field that cannot contain text
1183 * data is an INTEGER PRIMARY KEY, which must be a 64-bit signed integer. So, for
1184 * the purposes here we really only care whether the column exists and not what its
1185 * type or length is. */
1186
1187 if (ast_strlen_zero(table)) {
1188 ast_log(LOG_WARNING, "Must have a table to query!\n");
1189 return -1;
1190 }
1191
1192 if (!(db = find_database(database))) {
1193 return -1;
1194 }
1195
1198 if (!columns) {
1199 unref_db(&db);
1200 return -1;
1201 }
1202
1203 if (!(sql = sqlite3_mprintf("PRAGMA table_info(\"%q\")", table))) {
1204 unref_db(&db);
1205 ao2_ref(columns, -1);
1206 return -1;
1207 }
1208
1210 unref_db(&db);
1211 ao2_ref(columns, -1);
1212 sqlite3_free(sql);
1213 return -1;
1214 } else if (res == 0) {
1215 /* Table does not exist */
1216 sqlite3_free(sql);
1217 res = handle_missing_table(db, table, ap);
1218 ao2_ref(columns, -1);
1219 unref_db(&db);
1220 return res;
1221 }
1222
1223 sqlite3_free(sql);
1224
1225 while ((column = va_arg(ap, typeof(column)))) {
1226 char *found;
1227 type = va_arg(ap, typeof(type));
1228 sz = va_arg(ap, typeof(sz));
1229 if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
1230 if (handle_missing_column(db, table, column, type, sz)) {
1231 unref_db(&db);
1232 ao2_ref(columns, -1);
1233 return -1;
1234 }
1235 } else {
1236 ao2_ref(found, -1);
1237 }
1238 }
1239
1240 ao2_ref(columns, -1);
1241 unref_db(&db);
1242
1243 return 0;
1244}
#define OBJ_POINTER
Definition: astobj2.h:1150
@ OBJ_UNLINK
Definition: astobj2.h:1039
static char * columns
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 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 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 str_hash_fn(const void *obj, const int flags)
static int str_cmp_fn(void *obj, void *arg, int flags)

References add_column_name(), AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_find, ao2_ref, ast_log, ast_strlen_zero(), columns, db, find_database(), handle_missing_column(), handle_missing_table(), LOG_WARNING, NULL, OBJ_POINTER, OBJ_UNLINK, realtime_sqlite3_exec_query_with_handle(), str_cmp_fn(), str_hash_fn(), table, type, typeof(), and unref_db().

◆ realtime_sqlite3_store()

static int realtime_sqlite3_store ( const char *  database,
const char *  table,
const struct ast_variable fields 
)
static

Realtime callback for inserting a row.

Returns
Number of rows affected or -1 on error

Definition at line 968 of file res_config_sqlite3.c.

969{
970 struct ast_str *sql, *values;
971 const struct ast_variable *field;
972 int first = 1, res;
973
974 if (ast_strlen_zero(table)) {
975 ast_log(LOG_WARNING, "Must have a table to query!\n");
976 return -1;
977 }
978
979 if (!(sql = ast_str_create(128))) {
980 return -1;
981 }
982
983 if (!(values = ast_str_create(128))) {
984 ast_free(sql);
985 return -1;
986 }
987
988 for (field = fields; field; field = field->next) {
989 if (first) {
990 ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(field->name));
991 ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(field->value));
992 first = 0;
993 } else {
994 ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(field->name));
995 ast_str_append(&values, 0, ", %s", sqlite3_escape_value(field->value));
996 }
997 }
998
999 ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));
1000
1001 res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
1002
1003 ast_free(sql);
1005
1006 return res;
1007}

References ast_free, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column(), sqlite3_escape_table(), sqlite3_escape_value(), table, and ast_variable::value.

◆ realtime_sqlite3_unload()

static int realtime_sqlite3_unload ( const char *  database,
const char *  table 
)
static

Callback for clearing any cached info.

Note
We don't currently cache anything
Return values
0If any cache was purged
-1If no cache was found

Definition at line 1251 of file res_config_sqlite3.c.

1252{
1253 /* We currently do no caching */
1254 return -1;
1255}

◆ realtime_sqlite3_update()

static int realtime_sqlite3_update ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
const struct ast_variable fields 
)
static

Realtime callback for updating a row based on a single criteria.

Returns
Number of rows affected or -1 on error

Definition at line 879 of file res_config_sqlite3.c.

880{
881 struct ast_str *sql;
882 const struct ast_variable *field;
883 int first = 1, res;
884
885 if (ast_strlen_zero(table)) {
886 ast_log(LOG_WARNING, "Must have a table to query!\n");
887 return -1;
888 }
889
890 if (!(sql = ast_str_create(128))) {
891 return -1;
892 }
893
894 for (field = fields; field; field = field->next) {
895 if (first) {
896 ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
898 first = 0;
899 } else {
900 ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
901 }
902 }
903
904 ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));
905
906 res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
907 ast_free(sql);
908
909 return res;
910}

References ast_free, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), table, and ast_variable::value.

◆ realtime_sqlite3_update2()

static int realtime_sqlite3_update2 ( const char *  database,
const char *  table,
const struct ast_variable lookup_fields,
const struct ast_variable update_fields 
)
static

Realtime callback for updating a row based on multiple criteria.

Returns
Number of rows affected or -1 on error

Definition at line 915 of file res_config_sqlite3.c.

916{
917 struct ast_str *sql;
918 struct ast_str *where_clause;
919 const struct ast_variable *field;
920 int first = 1, res;
921
922 if (ast_strlen_zero(table)) {
923 ast_log(LOG_WARNING, "Must have a table to query!\n");
924 return -1;
925 }
926
927 if (!(sql = ast_str_create(128))) {
928 return -1;
929 }
930
931 if (!(where_clause = ast_str_create(128))) {
932 ast_free(sql);
933 return -1;
934 }
935
936 for (field = lookup_fields; field; field = field->next) {
937 if (first) {
938 ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
939 first = 0;
940 } else {
941 ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
942 }
943 }
944
945 first = 1;
946 for (field = update_fields; field; field = field->next) {
947 if (first) {
948 ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
949 first = 0;
950 } else {
951 ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
952 }
953 }
954
955 ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));
956
957 res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
958
959 ast_free(sql);
960 ast_free(where_clause);
961
962 return res;
963}

References ast_free, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), table, and ast_variable::value.

◆ reload()

static int reload ( void  )
static

Definition at line 1318 of file res_config_sqlite3.c.

1319{
1320 parse_config(1);
1321 return 0;
1322}

References parse_config().

Referenced by parse_config().

◆ row_counter_wrapper()

static int row_counter_wrapper ( void *  arg,
int  num_columns,
char **  values,
char **  columns 
)
static

Definition at line 573 of file res_config_sqlite3.c.

574{
575 struct row_counter_args *wrapped = arg;
576 wrapped->row_count++;
577 if (wrapped->wrapped_callback) {
578 return wrapped->wrapped_callback(wrapped->wrapped_arg, num_columns, values, columns);
579 }
580 return 0;
581}

References row_counter_args::row_count, row_counter_args::wrapped_arg, and row_counter_args::wrapped_callback.

Referenced by realtime_sqlite3_exec_query_with_handle().

◆ row_to_varlist()

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 485 of file res_config_sqlite3.c.

486{
487 struct ast_variable **head = arg, *tail;
488 int i;
489 struct ast_variable *new;
490
491 if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
492 return SQLITE_ABORT;
493 }
494 *head = tail = new;
495
496 for (i = 1; i < num_columns; i++) {
497 if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
499 *head = NULL;
500 return SQLITE_ABORT;
501 }
502 tail->next = new;
503 tail = new;
504 }
505
506 return 0;
507}
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262

References ast_variable_new, ast_variables_destroy(), NULL, and S_OR.

Referenced by realtime_sqlite3_helper().

◆ sqlite3_escape_column()

static const char * sqlite3_escape_column ( const char *  param)
inlinestatic

Definition at line 164 of file res_config_sqlite3.c.

165{
167}
static const char * sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)
static struct ast_threadstorage escape_column_buf

References escape_column_buf, and sqlite3_escape_string_helper().

Referenced by handle_missing_table(), realtime_sqlite3_store(), realtime_sqlite3_update(), and realtime_sqlite3_update2().

◆ sqlite3_escape_column_op()

static const char * sqlite3_escape_column_op ( const char *  param)
static

Definition at line 170 of file res_config_sqlite3.c.

171{
172 size_t maxlen = strlen(param) * 2 + sizeof("\"\" =");
174 char *tmp;
175 int space = 0;
176
177 if (ast_str_size(buf) < maxlen) {
178 /* realloc if buf is too small */
179 ast_str_make_space(&buf, maxlen);
180 }
182
184 *tmp++ = '"';
185 while ((*tmp++ = *param++)) {
186 /* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
187 * available to users via an API, we will definitely need to avoid allowing special
188 * characters like ';' in the data past the space as it will be unquoted data */
189 if (space) {
190 continue;
191 }
192 if (*(tmp - 1) == ' ') {
193 *(tmp - 1) = '"';
194 *tmp++ = ' ';
195 space = 1;
196 } else if (*(tmp - 1) == '"') {
197 *tmp++ = '"';
198 }
199 }
200 if (!space) {
201 strcpy(tmp - 1, "\" =");
202 }
203
205
206 return ast_str_buffer(buf);
207}
static int tmp()
Definition: bt_open.c:389
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
#define ast_str_make_space(buf, new_len)
Definition: strings.h:828
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:703
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:742
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:909

References ast_str_buffer(), ast_str_make_space, ast_str_reset(), ast_str_size(), ast_str_thread_get(), ast_str_update(), buf, escape_column_buf, and tmp().

Referenced by realtime_sqlite3_destroy(), realtime_sqlite3_helper(), realtime_sqlite3_update(), and realtime_sqlite3_update2().

◆ sqlite3_escape_string_helper()

static const char * sqlite3_escape_string_helper ( struct ast_threadstorage ts,
const char *  param 
)
inlinestatic

Definition at line 127 of file res_config_sqlite3.c.

128{
129 size_t maxlen = strlen(param) * 2 + sizeof("\"\"");
130 /* It doesn't appear that sqlite3_snprintf will do more than double the
131 * length of a string with %q as an option. %Q could double and possibly
132 * add two quotes, and convert NULL pointers to the word "NULL", but we
133 * don't allow those anyway. Just going to use %q for now. */
134 struct ast_str *buf = ast_str_thread_get(ts, maxlen);
135 char q = ts == &escape_value_buf ? '\'' : '"';
136 char *tmp;
137
138 if (ast_str_size(buf) < maxlen) {
139 /* realloc if buf is too small */
140 ast_str_make_space(&buf, maxlen);
141 }
143
145 *tmp++ = q; /* Initial quote */
146 while ((*tmp++ = *param++)) {
147 /* Did we just copy a quote? Then double it. */
148 if (*(tmp - 1) == q) {
149 *tmp++ = q;
150 }
151 }
152 *tmp = '\0'; /* Terminate past NULL from copy */
153 *(tmp - 1) = q; /* Replace original NULL with the quote */
155
156 return ast_str_buffer(buf);
157}
static struct ast_threadstorage escape_value_buf

References ast_str_buffer(), ast_str_make_space, ast_str_reset(), ast_str_size(), ast_str_thread_get(), ast_str_update(), buf, escape_value_buf, and tmp().

Referenced by sqlite3_escape_column(), sqlite3_escape_table(), and sqlite3_escape_value().

◆ sqlite3_escape_table()

static const char * sqlite3_escape_table ( const char *  param)
inlinestatic

◆ sqlite3_escape_value()

static const char * sqlite3_escape_value ( const char *  param)
inlinestatic

◆ static_realtime_cb()

static int static_realtime_cb ( void *  arg,
int  num_columns,
char **  values,
char **  columns 
)
static

Definition at line 717 of file res_config_sqlite3.c.

718{
719 struct cfg_entry_args *args = arg;
720 struct ast_variable *var;
721
722 if (!strcmp(values[COL_VAR_NAME], "#include")) {
723 struct ast_config *cfg;
724 char *val;
725
727 if (!(cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked))) {
728 ast_log(LOG_WARNING, "Unable to include %s\n", val);
729 return SQLITE_ABORT;
730 } else {
731 args->cfg = cfg;
732 return 0;
733 }
734 }
735
736 if (!args->cat_name || strcmp(args->cat_name, values[COL_CATEGORY])) {
738 if (!args->cat) {
739 return SQLITE_ABORT;
740 }
741
742 ast_free(args->cat_name);
743
744 if (!(args->cat_name = ast_strdup(values[COL_CATEGORY]))) {
746 return SQLITE_ABORT;
747 }
748
749 ast_category_append(args->cfg, args->cat);
750 }
751
753 ast_log(LOG_WARNING, "Unable to allocate variable\n");
754 return SQLITE_ABORT;
755 }
756
758
759 return 0;
760}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_category_destroy(struct ast_category *cat)
Definition: extconf.c:2845
struct ast_config * ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
Definition: main/config.c:3279
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
Definition: ast_expr2.c:325

References args, ast_category_append(), ast_category_destroy(), ast_category_new_dynamic, ast_config_internal_load(), ast_free, ast_log, ast_strdup, ast_variable_append(), ast_variable_new, COL_CATEGORY, COL_VAR_NAME, COL_VAR_VAL, LOG_WARNING, and var.

Referenced by realtime_sqlite3_load().

◆ stop_batch_cb()

static int stop_batch_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 253 of file res_config_sqlite3.c.

254{
255 struct realtime_sqlite3_db *db = obj;
256
258 return CMP_MATCH;
259}

References CMP_MATCH, db, and db_stop_batch().

Referenced by unload_module().

◆ str_cmp_fn()

static int str_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1143 of file res_config_sqlite3.c.

1143 {
1144 return !strcasecmp((const char *) obj, (const char *) arg);
1145}

Referenced by realtime_sqlite3_require().

◆ str_hash_fn()

static int str_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 1138 of file res_config_sqlite3.c.

1139{
1140 return ast_str_hash((const char *) obj);
1141}

References ast_str_hash().

Referenced by realtime_sqlite3_require().

◆ str_to_requirements()

static int str_to_requirements ( const char *  data)
static

Definition at line 288 of file res_config_sqlite3.c.

289{
290 if (!strcasecmp(data, "createclose")) {
292 } else if (!strcasecmp(data, "createchar")) {
294 }
295 /* default */
297}

References REALTIME_SQLITE3_REQ_CHAR, REALTIME_SQLITE3_REQ_CLOSE, and REALTIME_SQLITE3_REQ_WARN.

Referenced by new_realtime_sqlite3_db().

◆ trace_cb()

static void trace_cb ( void *  arg,
const char *  sql 
)
static
Note
Since this is called while a query is executing, we should already hold the db lock

Definition at line 300 of file res_config_sqlite3.c.

301{
302 struct realtime_sqlite3_db *db = arg;
303 ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
304}

References ast_debug, and db.

Referenced by db_open(), and update_realtime_sqlite3_db().

◆ unlink_dirty_databases()

static void unlink_dirty_databases ( void  )
static

Definition at line 283 of file res_config_sqlite3.c.

284{
286}
static int is_dirty_cb(void *obj, void *arg, int flags)

References ao2_callback, is_dirty_cb(), NULL, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by parse_config().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1324 of file res_config_sqlite3.c.

1325{
1328 ao2_ref(databases, -1);
1329 databases = NULL;
1332
1333 return 0;
1334}
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
Definition: main/config.c:3173
static int stop_batch_cb(void *obj, void *arg, int flags)

References ao2_callback, ao2_ref, ast_config_engine_deregister(), ast_mutex_lock, ast_mutex_unlock, config_lock, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sqlite3_config_engine, and stop_batch_cb().

◆ unref_db()

static void unref_db ( struct realtime_sqlite3_db **  db)
static

Definition at line 247 of file res_config_sqlite3.c.

248{
249 ao2_ref(*db, -1);
250 *db = NULL;
251}

References ao2_ref, db, and NULL.

Referenced by db_sync_thread(), new_realtime_sqlite3_db(), parse_config(), realtime_sqlite3_require(), and update_realtime_sqlite3_db().

◆ update_realtime_sqlite3_db()

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.

Parameters
dbThe database object to update
configThe configuration data with which to update the db
catThe config category (which becomes db->name)

Definition at line 435 of file res_config_sqlite3.c.

436{
437 struct realtime_sqlite3_db *new;
438
439 if (!(new = new_realtime_sqlite3_db(config, cat))) {
440 return -1;
441 }
442
443 /* Copy fields that don't need anything special done on change */
444 db->requirements = new->requirements;
445
446 /* Handle changes that require immediate behavior modification */
447 if (db->debug != new->debug) {
448 if (db->debug) {
449 sqlite3_trace(db->handle, NULL, NULL);
450 } else {
451 sqlite3_trace(db->handle, trace_cb, db);
452 }
453 db->debug = new->debug;
454 }
455
456 if (strcmp(db->filename, new->filename)) {
457 sqlite3_close(db->handle);
458 ast_string_field_set(db, filename, new->filename);
459 db_open(db); /* Also handles setting appropriate debug on new handle */
460 }
461
462 if (db->busy_timeout != new->busy_timeout) {
463 db->busy_timeout = new->busy_timeout;
464 sqlite3_busy_timeout(db->handle, db->busy_timeout);
465 }
466
467 if (db->batch != new->batch) {
468 if (db->batch == 0) {
469 db->batch = new->batch;
471 } else if (new->batch == 0) {
472 db->batch = new->batch;
474 }
475 db->batch = new->batch;
476 }
477
478 db->dirty = 0;
479 unref_db(&new);
480
481 return 0;
482}

References ast_string_field_set, config, db, db_open(), db_start_batch(), db_stop_batch(), realtime_sqlite3_db::filename, new_realtime_sqlite3_db(), NULL, trace_cb(), and unref_db().

Referenced by parse_config().

Variable Documentation

◆ __mod_info

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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, .requires = "extconfig", }
static

Definition at line 1400 of file res_config_sqlite3.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1400 of file res_config_sqlite3.c.

◆ config_lock

ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 110 of file res_config_sqlite3.c.

Referenced by parse_config(), and unload_module().

◆ databases

Definition at line 107 of file res_config_sqlite3.c.

◆ escape_column_buf

struct ast_threadstorage escape_column_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_column_buf , .custom_init = NULL , }
static

Definition at line 114 of file res_config_sqlite3.c.

Referenced by sqlite3_escape_column(), and sqlite3_escape_column_op().

◆ escape_table_buf

struct ast_threadstorage escape_table_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_table_buf , .custom_init = NULL , }
static

Definition at line 113 of file res_config_sqlite3.c.

Referenced by sqlite3_escape_table().

◆ escape_value_buf

struct ast_threadstorage escape_value_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escape_value_buf , .custom_init = NULL , }
static

Definition at line 115 of file res_config_sqlite3.c.

Referenced by sqlite3_escape_string_helper(), and sqlite3_escape_value().

◆ has_explicit_like_escaping

int has_explicit_like_escaping
static

Definition at line 58 of file res_config_sqlite3.c.

Referenced by discover_sqlite3_caps(), and realtime_sqlite3_helper().

◆ sqlite3_config_engine

struct ast_config_engine sqlite3_config_engine

Definition at line 70 of file res_config_sqlite3.c.

Referenced by load_module(), and unload_module().

◆ static_sql

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
Note
It is important that the COL_* enum matches the order of the columns selected in static_sql

Definition at line 709 of file res_config_sqlite3.c.

Referenced by realtime_sqlite3_load().