Asterisk - The Open Source Telephony Project  18.5.0
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 <[email protected]> 

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

Referenced by load_module().

◆ IS_SQL_LIKE_CLAUSE

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

Definition at line 796 of file res_config_sqlite3.c.

Referenced by realtime_sqlite3_helper().

Typedef Documentation

◆ callback_t

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

Definition at line 120 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 86 of file res_config_sqlite3.c.

◆ anonymous enum

anonymous enum
Enumerator
COL_CATEGORY 
COL_VAR_NAME 
COL_VAR_VAL 
COL_COLUMNS 

Definition at line 713 of file res_config_sqlite3.c.

Function Documentation

◆ __init_escape_column_buf()

static void __init_escape_column_buf ( void  )
static

Definition at line 117 of file res_config_sqlite3.c.

131 {

◆ __init_escape_table_buf()

static void __init_escape_table_buf ( void  )
static

Definition at line 116 of file res_config_sqlite3.c.

131 {

◆ __init_escape_value_buf()

static void __init_escape_value_buf ( void  )
static

Definition at line 118 of file res_config_sqlite3.c.

131 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1403 of file res_config_sqlite3.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1403 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 1152 of file res_config_sqlite3.c.

References ao2_alloc, ao2_link, ao2_ref, and NULL.

Referenced by realtime_sqlite3_require().

1153 {
1154  char *column;
1155  struct ao2_container *cnames = arg;
1156 
1157 
1158  if (!(column = ao2_alloc(strlen(values[1]) + 1, NULL))) {
1159  return -1;
1160  }
1161 
1162  strcpy(column, values[1]);
1163 
1164  ao2_link(cnames, column);
1165  ao2_ref(column, -1);
1166 
1167  return 0;
1168 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
Generic container type.
#define ao2_link(container, obj)
Definition: astobj2.h:1549

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

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

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

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1403 of file res_config_sqlite3.c.

◆ db_cmp_fn()

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

Definition at line 224 of file res_config_sqlite3.c.

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

Referenced by load_module().

224  {
225  struct realtime_sqlite3_db *db = obj, *other = arg;
226  const char *name = arg;
227 
228  return !strcasecmp(db->name, flags & OBJ_KEY ? name : other->name) ? CMP_MATCH | CMP_STOP : 0;
229 }
const ast_string_field name
#define OBJ_KEY
Definition: astobj2.h:1155
static sqlite3 * db
static const char name[]
Definition: cdr_mysql.c:74

◆ db_destructor()

static void db_destructor ( void *  obj)
static

Definition at line 231 of file res_config_sqlite3.c.

References ao2_lock, ao2_unlock, ast_debug, ast_string_field_free_memory, db, db_stop_batch(), realtime_sqlite3_db::handle, and realtime_sqlite3_db::name.

Referenced by new_realtime_sqlite3_db().

232 {
233  struct realtime_sqlite3_db *db = obj;
234 
235  ast_debug(1, "Destroying db: %s\n", db->name);
237  db_stop_batch(db);
238  if (db->handle) {
239  ao2_lock(db);
240  sqlite3_close(db->handle);
241  ao2_unlock(db);
242  }
243 }
const ast_string_field name
void db_stop_batch(struct realtime_sqlite3_db *db)
static sqlite3 * db
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ db_hash_fn()

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

Definition at line 217 of file res_config_sqlite3.c.

References ast_str_hash(), db, realtime_sqlite3_db::name, and OBJ_KEY.

Referenced by load_module().

218 {
219  const struct realtime_sqlite3_db *db = obj;
220 
221  return ast_str_hash(flags & OBJ_KEY ? (const char *) obj : db->name);
222 }
const ast_string_field name
#define OBJ_KEY
Definition: astobj2.h:1155
static sqlite3 * db
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

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

References ao2_lock, ao2_unlock, ast_log, realtime_sqlite3_db::busy_timeout, realtime_sqlite3_db::debug, realtime_sqlite3_db::filename, realtime_sqlite3_db::handle, LOG_WARNING, NULL, and trace_cb().

Referenced by parse_config(), and update_realtime_sqlite3_db().

340 {
341  ao2_lock(db);
342  if (sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
343  ast_log(LOG_WARNING, "Could not open %s: %s\n", db->filename, sqlite3_errmsg(db->handle));
344  ao2_unlock(db);
345  return -1;
346  }
347  sqlite3_busy_timeout(db->handle, db->busy_timeout);
348 
349  if (db->debug) {
350  sqlite3_trace(db->handle, trace_cb, db);
351  } else {
352  sqlite3_trace(db->handle, NULL, NULL);
353  }
354 
355  ao2_unlock(db);
356 
357  return 0;
358 }
#define LOG_WARNING
Definition: logger.h:274
static void trace_cb(void *arg, const char *sql)
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ao2_lock(a)
Definition: astobj2.h:718
const ast_string_field filename

◆ db_start_batch()

void db_start_batch ( struct realtime_sqlite3_db db)

Definition at line 366 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(), realtime_sqlite3_db::has_batch_thread, NULL, and realtime_sqlite3_db::syncthread.

Referenced by parse_config(), and update_realtime_sqlite3_db().

367 {
368  if (db->batch) {
369  ast_cond_init(&db->cond, NULL);
370  ao2_ref(db, +1);
372  }
373 }
static void * db_sync_thread(void *data)
Wrap commands in transactions increased write performance.
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ao2_ref(o, delta)
Definition: astobj2.h:464
unsigned int has_batch_thread

◆ db_stop_batch()

void db_stop_batch ( struct realtime_sqlite3_db db)

Definition at line 375 of file res_config_sqlite3.c.

References db_sync(), realtime_sqlite3_db::exiting, realtime_sqlite3_db::has_batch_thread, NULL, and realtime_sqlite3_db::syncthread.

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

376 {
377  if (db->has_batch_thread) {
378  db->has_batch_thread = 0;
379  db->exiting = 1;
380  db_sync(db);
381  pthread_join(db->syncthread, NULL);
382  }
383 }
#define NULL
Definition: resample.c:96
unsigned int has_batch_thread
static void db_sync(struct realtime_sqlite3_db *db)

◆ db_sync()

static void db_sync ( struct realtime_sqlite3_db db)
static

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

361 {
362  db->wakeup = 1;
363  ast_cond_signal(&db->cond);
364 }
#define ast_cond_signal(cond)
Definition: lock.h:201

◆ db_sync_thread()

static void* db_sync_thread ( void *  data)
static

Wrap commands in transactions increased write performance.

Definition at line 310 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, db, realtime_sqlite3_db::exiting, NULL, realtime_sqlite3_exec_query_with_handle(), unref_db(), and realtime_sqlite3_db::wakeup.

Referenced by db_start_batch().

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

◆ discover_sqlite3_caps()

static void discover_sqlite3_caps ( void  )
static

Definition at line 1339 of file res_config_sqlite3.c.

References ast_debug, and has_explicit_like_escaping.

Referenced by load_module().

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

◆ find_database()

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

Definition at line 245 of file res_config_sqlite3.c.

References ao2_find, and OBJ_KEY.

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

246 {
247  return ao2_find(databases, database, OBJ_KEY);
248 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ 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 1053 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().

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

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

References ast_log, get_sqlite_column_type(), LOG_NOTICE, LOG_WARNING, realtime_sqlite3_db::name, realtime_sqlite3_exec_update_with_handle(), REALTIME_SQLITE3_REQ_CHAR, REALTIME_SQLITE3_REQ_WARN, and realtime_sqlite3_db::requirements.

Referenced by realtime_sqlite3_require().

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

◆ 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 1082 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_exec_update_with_handle(), sqlite3_escape_column(), sqlite3_escape_table(), type, and typeof().

Referenced by realtime_sqlite3_require().

1083 {
1084  const char *column;
1085  int type, first = 1, res;
1086  size_t sz;
1087  struct ast_str *sql;
1088 
1089  if (!(sql = ast_str_create(128))) {
1090  return -1;
1091  }
1092 
1093  while ((column = va_arg(ap, typeof(column)))) {
1094  type = va_arg(ap, typeof(type));
1095  sz = va_arg(ap, typeof(sz));
1096  if (first) {
1097  ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
1099  first = 0;
1100  } else {
1101  ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
1102  }
1103  }
1104 
1105  ast_str_append(&sql, 0, ")");
1106 
1107  res = realtime_sqlite3_exec_update_with_handle(db, ast_str_buffer(sql)) < 0 ? -1 : 0;
1108  ast_free(sql);
1109 
1110  return res;
1111 }
static const char * sqlite3_escape_column(const char *param)
typedef typeof(dummy_tv_var_for_types.tv_sec) ast_time_t
static const char type[]
Definition: chan_ooh323.c:109
static const char * get_sqlite_column_type(int type)
Convert Asterisk realtime types to SQLite 3 types.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
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:1091
static char * table
Definition: cdr_odbc.c:58
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:1065
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ast_free(a)
Definition: astmm.h:182
static const char * sqlite3_escape_table(const char *param)
static int realtime_sqlite3_exec_update_with_handle(struct realtime_sqlite3_db *, const char *)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ is_dirty_cb()

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

Definition at line 276 of file res_config_sqlite3.c.

References CMP_MATCH, db, db_stop_batch(), and realtime_sqlite3_db::dirty.

Referenced by unlink_dirty_databases().

277 {
278  struct realtime_sqlite3_db *db = obj;
279  if (db->dirty) {
280  db_stop_batch(db);
281  return CMP_MATCH;
282  }
283  return 0;
284 }
void db_stop_batch(struct realtime_sqlite3_db *db)
static sqlite3 * db

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

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_config_engine_register(), ast_log, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_REALTIME_DRIVER, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, DB_BUCKETS, db_cmp_fn(), db_hash_fn(), discover_sqlite3_caps(), LOG_ERROR, NULL, parse_config(), reload(), and unload_module().

1373 {
1375 
1378  if (!databases) {
1379  return AST_MODULE_LOAD_DECLINE;
1380  }
1381 
1382  if (parse_config(0)) {
1383  ao2_ref(databases, -1);
1384  return AST_MODULE_LOAD_DECLINE;
1385  }
1386 
1388  ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
1389  ao2_ref(databases, -1);
1390  return AST_MODULE_LOAD_DECLINE;
1391  }
1392 
1393  return AST_MODULE_LOAD_SUCCESS;
1394 }
#define DB_BUCKETS
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Definition: main/config.c:2990
struct ast_config_engine sqlite3_config_engine
#define NULL
Definition: resample.c:96
static void discover_sqlite3_caps(void)
static int parse_config(int reload)
Parse the res_config_sqlite3 config file.
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int db_hash_fn(const void *obj, const int flags)
static int db_cmp_fn(void *obj, void *arg, int flags)

◆ mark_all_databases_dirty()

static void mark_all_databases_dirty ( void  )
static

Definition at line 271 of file res_config_sqlite3.c.

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

Referenced by parse_config().

272 {
274 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96
static int mark_dirty_cb(void *obj, void *arg, int flags)

◆ mark_dirty_cb()

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

Definition at line 264 of file res_config_sqlite3.c.

References CMP_MATCH, db, and realtime_sqlite3_db::dirty.

Referenced by mark_all_databases_dirty().

265 {
266  struct realtime_sqlite3_db *db = obj;
267  db->dirty = 1;
268  return CMP_MATCH;
269 }
static sqlite3 * db

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

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(), realtime_sqlite3_db::batch, realtime_sqlite3_db::busy_timeout, db, db_destructor(), realtime_sqlite3_db::debug, realtime_sqlite3_db::filename, ast_variable::lineno, LOG_WARNING, ast_variable::name, realtime_sqlite3_db::name, ast_variable::next, NULL, PARSE_DEFAULT, PARSE_INT32, 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().

389 {
390  struct ast_variable *var;
391  struct realtime_sqlite3_db *db;
392 
393  if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
394  return NULL;
395  }
396 
397  if (ast_string_field_init(db, 64)) {
398  unref_db(&db);
399  return NULL;
400  }
401 
402  /* Set defaults */
404  db->batch = 100;
405  ast_string_field_set(db, name, cat);
406  db->busy_timeout = 1000;
407 
408  for (var = ast_variable_browse(config, cat); var; var = var->next) {
409  if (!strcasecmp(var->name, "dbfile")) {
411  } else if (!strcasecmp(var->name, "requirements")) {
413  } else if (!strcasecmp(var->name, "batch")) {
415  } else if (!strcasecmp(var->name, "debug")) {
416  db->debug = ast_true(var->value);
417  } else if (!strcasecmp(var->name, "busy_timeout")) {
418  if (ast_parse_arg(var->value, PARSE_INT32|PARSE_DEFAULT, &(db->busy_timeout), 1000) != 0) {
419  ast_log(LOG_WARNING, "Invalid busy_timeout value '%s' at res_config_sqlite3.conf:%d. Using 1000 instead.\n", var->value, var->lineno);
420  }
421  }
422  }
423 
424  if (ast_strlen_zero(db->filename)) {
425  ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
426  unref_db(&db);
427  return NULL;
428  }
429 
430  return db;
431 }
struct ast_variable * next
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
static sqlite3 * db
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int str_to_requirements(const char *data)
#define ast_log
Definition: astobj2.c:42
static void unref_db(struct realtime_sqlite3_db **db)
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
Definition: main/config.c:3657
static void db_destructor(void *obj)
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:3113
const ast_string_field filename
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ parse_config()

static int parse_config ( int  reload)
static

Parse the res_config_sqlite3 config file.

Definition at line 1262 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_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, unlink_dirty_databases(), unref_db(), and update_realtime_sqlite3_db().

Referenced by load_module(), and reload().

1263 {
1264  struct ast_config *config;
1265  struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME | (reload ? CONFIG_FLAG_FILEUNCHANGED : 0) };
1266  static const char *config_filename = "res_config_sqlite3.conf";
1267 
1268  config = ast_config_load(config_filename, config_flags);
1269 
1270  if (config == CONFIG_STATUS_FILEUNCHANGED) {
1271  ast_debug(1, "%s was unchanged, skipping parsing\n", config_filename);
1272  return 0;
1273  }
1274 
1276 
1277  if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
1278  ast_log(LOG_ERROR, "%s config file '%s'\n",
1279  config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
1281  return 0;
1282  } else {
1283  const char *cat;
1284  struct realtime_sqlite3_db *db;
1285 
1287  for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
1288  if (!strcasecmp(cat, "general")) {
1289  continue;
1290  }
1291  if (!(db = find_database(cat))) {
1292  if (!(db = new_realtime_sqlite3_db(config, cat))) {
1293  ast_log(LOG_WARNING, "Could not allocate new db for '%s' - skipping.\n", cat);
1294  continue;
1295  }
1296  if (db_open(db)) {
1297  unref_db(&db);
1298  continue;
1299  }
1300  db_start_batch(db);
1301  ao2_link(databases, db);
1302  unref_db(&db);
1303  } else {
1304  if (update_realtime_sqlite3_db(db, config, cat)) {
1305  unref_db(&db);
1306  continue;
1307  }
1308  unref_db(&db);
1309  }
1310  }
1312  }
1313 
1315 
1316  ast_config_destroy(config);
1317 
1318  return 0;
1319 }
static int db_open(struct realtime_sqlite3_db *db)
Open a database and appropriately set debugging on the db handle.
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 void unlink_dirty_databases(void)
char * config
Definition: conf2ael.c:66
static sqlite3 * db
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
#define ast_mutex_lock(a)
Definition: lock.h:187
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
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.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static void unref_db(struct realtime_sqlite3_db **db)
#define ast_config_load(filename, flags)
Load a config file.
static char * config_filename
Definition: extconf.c:2121
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define CONFIG_STATUS_FILEUNCHANGED
#define LOG_ERROR
Definition: logger.h:285
void db_start_batch(struct realtime_sqlite3_db *db)
static void mark_all_databases_dirty(void)
static int reload(void)
Structure used to handle boolean flags.
Definition: utils.h:199
#define CONFIG_STATUS_FILEMISSING
static ast_mutex_t config_lock
static struct realtime_sqlite3_db * find_database(const char *database)
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define ao2_link(container, obj)
Definition: astobj2.h:1549

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

References NULL, and realtime_sqlite3_helper().

852 {
853  struct ast_variable *result_row = NULL;
854 
855  realtime_sqlite3_helper(database, table, fields, 0, &result_row);
856 
857  return result_row;
858 }
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
static char * table
Definition: cdr_odbc.c:58
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.

◆ 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 1015 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, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and ast_variable::value.

1016 {
1017  struct ast_str *sql;
1018  const struct ast_variable *field;
1019  int first = 1, res;
1020 
1021  if (ast_strlen_zero(table)) {
1022  ast_log(LOG_WARNING, "Must have a table to query!\n");
1023  return -1;
1024  }
1025 
1026  if (!(sql = ast_str_create(128))) {
1027  return -1;
1028  }
1029 
1030  for (field = fields; field; field = field->next) {
1031  if (first) {
1032  ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
1034  first = 0;
1035  } else {
1036  ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
1037  }
1038  }
1039 
1040  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
1041 
1042  ast_free(sql);
1043 
1044  return res;
1045 }
struct ast_variable * next
static const char * sqlite3_escape_column_op(const char *param)
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
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:1091
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * table
Definition: cdr_odbc.c:58
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:1065
#define ast_log
Definition: astobj2.c:42
static const char * sqlite3_escape_value(const char *param)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ast_free(a)
Definition: astmm.h:182
static int realtime_sqlite3_exec_update(const char *, const char *)
static const char * sqlite3_escape_table(const char *param)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

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

634 {
635  struct realtime_sqlite3_db *db;
636  int res;
637 
638  if (!(db = find_database(database))) {
639  ast_log(LOG_WARNING, "Could not find database: %s\n", database);
640  return -1;
641  }
642 
643  res = realtime_sqlite3_exec_query_with_handle(db, sql, callback, arg);
644  ao2_ref(db, -1);
645 
646  return res;
647 }
static sqlite3 * db
#define LOG_WARNING
Definition: logger.h:274
static int realtime_sqlite3_exec_query_with_handle(struct realtime_sqlite3_db *, const char *, callback_t, void *)
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct realtime_sqlite3_db * find_database(const char *database)

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

References ao2_lock, ao2_unlock, ast_log, realtime_sqlite3_db::handle, 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().

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

◆ realtime_sqlite3_exec_update()

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

Definition at line 695 of file res_config_sqlite3.c.

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

696 {
697  struct realtime_sqlite3_db *db;
698  int res;
699 
700  if (!(db = find_database(database))) {
701  ast_log(LOG_WARNING, "Could not find database: %s\n", database);
702  return -1;
703  }
704 
706  ao2_ref(db, -1);
707 
708  return res;
709 }
static sqlite3 * db
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct realtime_sqlite3_db * find_database(const char *database)
static int realtime_sqlite3_exec_update_with_handle(struct realtime_sqlite3_db *, const char *)

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

References ao2_lock, ao2_unlock, ast_log, db_sync(), realtime_sqlite3_db::handle, LOG_WARNING, and NULL.

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

663 {
664  int res = 0;
665  char *errmsg;
666 
667  ao2_lock(db);
668  if (sqlite3_exec(db->handle, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
669  ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
670  sqlite3_free(errmsg);
671  res = -1;
672  } else {
673  res = sqlite3_changes(db->handle);
674  }
675  ao2_unlock(db);
676 
677  db_sync(db);
678 
679  return res;
680 }
#define LOG_WARNING
Definition: logger.h:274
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ao2_lock(a)
Definition: astobj2.h:718
static void db_sync(struct realtime_sqlite3_db *db)

◆ 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 799 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, 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(), and ast_variable::value.

Referenced by realtime_sqlite3(), and realtime_sqlite3_multi().

800 {
801  struct ast_str *sql;
802  const struct ast_variable *field;
803  int first = 1;
804 
805  if (ast_strlen_zero(table)) {
806  ast_log(LOG_WARNING, "Must have a table to query!\n");
807  return -1;
808  }
809 
810  if (!(sql = ast_str_create(128))) {
811  return -1;
812  }
813 
814  for (field = fields; field; field = field->next) {
815  if (first) {
816  ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
818  first = 0;
819  } else {
820  ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name),
821  sqlite3_escape_value(field->value));
822  }
823 
825  /*
826  * The realtime framework is going to pre-escape these
827  * for us with a backslash. We just need to make sure
828  * to tell SQLite about it
829  */
830  ast_str_append(&sql, 0, " ESCAPE '\\'");
831  }
832  }
833 
834  if (!is_multi) {
835  ast_str_append(&sql, 0, "%s", " LIMIT 1");
836  }
837 
838  if (realtime_sqlite3_exec_query(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg) < 0) {
839  ast_free(sql);
840  return -1;
841  }
842 
843  ast_free(sql);
844 
845  return 0;
846 }
struct ast_variable * next
static const char * sqlite3_escape_column_op(const char *param)
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
static int has_explicit_like_escaping
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:1091
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * table
Definition: cdr_odbc.c:58
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:1065
#define ast_log
Definition: astobj2.c:42
static const char * sqlite3_escape_value(const char *param)
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 realtime_sqlite3_exec_query(const char *, const char *, callback_t, void *)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ast_free(a)
Definition: astmm.h:182
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)
static const char * sqlite3_escape_table(const char *param)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ 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 768 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, NULL, realtime_sqlite3_exec_query(), static_realtime_cb(), static_sql, and cfg_entry_args::who_asked.

769 {
770  char *sql;
771  struct cfg_entry_args args;
772 
773  if (ast_strlen_zero(table)) {
774  ast_log(LOG_WARNING, "Must have a table to query!\n");
775  return NULL;
776  }
777 
778  if (!(sql = sqlite3_mprintf(static_sql, table, configfile))) {
779  ast_log(LOG_WARNING, "Couldn't allocate query\n");
780  return NULL;
781  };
782 
783  args.cfg = config;
784  args.cat = NULL;
785  args.cat_name = NULL;
786  args.flags = flags;
787  args.who_asked = who_asked;
788 
790 
791  sqlite3_free(sql);
792 
793  return config;
794 }
char * config
Definition: conf2ael.c:66
static const char * static_sql
struct ast_flags flags
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * table
Definition: cdr_odbc.c:58
#define ast_log
Definition: astobj2.c:42
static int static_realtime_cb(void *arg, int num_columns, char **values, char **columns)
static int realtime_sqlite3_exec_query(const char *, const char *, callback_t, void *)
const char * 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 863 of file res_config_sqlite3.c.

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

864 {
865  struct ast_config *cfg;
866 
867  if (!(cfg = ast_config_new())) {
868  return NULL;
869  }
870 
871  if (realtime_sqlite3_helper(database, table, fields, 1, cfg)) {
872  ast_config_destroy(cfg);
873  return NULL;
874  }
875 
876  return cfg;
877 }
#define NULL
Definition: resample.c:96
static char * table
Definition: cdr_odbc.c:58
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: extconf.c:3276
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.

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

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(), type, typeof(), and unref_db().

1175 {
1176  const char *column;
1177  char *sql;
1178  int type;
1179  int res;
1180  size_t sz;
1181  struct ao2_container *columns;
1182  struct realtime_sqlite3_db *db;
1183 
1184  /* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
1185  * return the results as char * anyway. The only field that cannot contain text
1186  * data is an INTEGER PRIMARY KEY, which must be a 64-bit signed integer. So, for
1187  * the purposes here we really only care whether the column exists and not what its
1188  * type or length is. */
1189 
1190  if (ast_strlen_zero(table)) {
1191  ast_log(LOG_WARNING, "Must have a table to query!\n");
1192  return -1;
1193  }
1194 
1195  if (!(db = find_database(database))) {
1196  return -1;
1197  }
1198 
1201  if (!columns) {
1202  unref_db(&db);
1203  return -1;
1204  }
1205 
1206  if (!(sql = sqlite3_mprintf("PRAGMA table_info(\"%q\")", table))) {
1207  unref_db(&db);
1208  ao2_ref(columns, -1);
1209  return -1;
1210  }
1211 
1212  if ((res = realtime_sqlite3_exec_query_with_handle(db, sql, add_column_name, columns)) < 0) {
1213  unref_db(&db);
1214  ao2_ref(columns, -1);
1215  sqlite3_free(sql);
1216  return -1;
1217  } else if (res == 0) {
1218  /* Table does not exist */
1219  sqlite3_free(sql);
1220  res = handle_missing_table(db, table, ap);
1221  ao2_ref(columns, -1);
1222  unref_db(&db);
1223  return res;
1224  }
1225 
1226  sqlite3_free(sql);
1227 
1228  while ((column = va_arg(ap, typeof(column)))) {
1229  char *found;
1230  type = va_arg(ap, typeof(type));
1231  sz = va_arg(ap, typeof(sz));
1232  if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
1233  if (handle_missing_column(db, table, column, type, sz)) {
1234  unref_db(&db);
1235  ao2_ref(columns, -1);
1236  return -1;
1237  }
1238  } else {
1239  ao2_ref(found, -1);
1240  }
1241  }
1242 
1243  ao2_ref(columns, -1);
1244  unref_db(&db);
1245 
1246  return 0;
1247 }
typedef typeof(dummy_tv_var_for_types.tv_sec) ast_time_t
static const char type[]
Definition: chan_ooh323.c:109
static int str_cmp_fn(void *obj, void *arg, int flags)
#define OBJ_POINTER
Definition: astobj2.h:1154
static sqlite3 * db
#define LOG_WARNING
Definition: logger.h:274
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&#39;t have, create it.
#define NULL
Definition: resample.c:96
static int realtime_sqlite3_exec_query_with_handle(struct realtime_sqlite3_db *, const char *, callback_t, void *)
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * table
Definition: cdr_odbc.c:58
#define ast_log
Definition: astobj2.c:42
static void unref_db(struct realtime_sqlite3_db **db)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static struct columns columns
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static struct realtime_sqlite3_db * find_database(const char *database)
Generic container type.
static int str_hash_fn(const void *obj, const int flags)
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 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.

◆ 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 971 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, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column(), sqlite3_escape_table(), sqlite3_escape_value(), and ast_variable::value.

972 {
973  struct ast_str *sql, *values;
974  const struct ast_variable *field;
975  int first = 1, res;
976 
977  if (ast_strlen_zero(table)) {
978  ast_log(LOG_WARNING, "Must have a table to query!\n");
979  return -1;
980  }
981 
982  if (!(sql = ast_str_create(128))) {
983  return -1;
984  }
985 
986  if (!(values = ast_str_create(128))) {
987  ast_free(sql);
988  return -1;
989  }
990 
991  for (field = fields; field; field = field->next) {
992  if (first) {
993  ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(field->name));
994  ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(field->value));
995  first = 0;
996  } else {
997  ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(field->name));
998  ast_str_append(&values, 0, ", %s", sqlite3_escape_value(field->value));
999  }
1000  }
1001 
1002  ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));
1003 
1004  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
1005 
1006  ast_free(sql);
1007  ast_free(values);
1008 
1009  return res;
1010 }
static const char * sqlite3_escape_column(const char *param)
struct ast_variable * next
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
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:1091
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * table
Definition: cdr_odbc.c:58
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:1065
#define ast_log
Definition: astobj2.c:42
static const char * sqlite3_escape_value(const char *param)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ast_free(a)
Definition: astmm.h:182
static int realtime_sqlite3_exec_update(const char *, const char *)
static const char * sqlite3_escape_table(const char *param)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

1255 {
1256  /* We currently do no caching */
1257  return -1;
1258 }

◆ 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 882 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, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and ast_variable::value.

883 {
884  struct ast_str *sql;
885  const struct ast_variable *field;
886  int first = 1, res;
887 
888  if (ast_strlen_zero(table)) {
889  ast_log(LOG_WARNING, "Must have a table to query!\n");
890  return -1;
891  }
892 
893  if (!(sql = ast_str_create(128))) {
894  return -1;
895  }
896 
897  for (field = fields; field; field = field->next) {
898  if (first) {
899  ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
901  first = 0;
902  } else {
903  ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
904  }
905  }
906 
907  ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));
908 
909  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
910  ast_free(sql);
911 
912  return res;
913 }
static const char * sqlite3_escape_column(const char *param)
struct ast_variable * next
static const char * sqlite3_escape_column_op(const char *param)
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int entity
Definition: isdn_lib.c:259
Structure for variables, used for configurations and for channel variables.
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:1091
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * table
Definition: cdr_odbc.c:58
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:1065
#define ast_log
Definition: astobj2.c:42
static const char * sqlite3_escape_value(const char *param)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ast_free(a)
Definition: astmm.h:182
static int realtime_sqlite3_exec_update(const char *, const char *)
static const char * sqlite3_escape_table(const char *param)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ 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 918 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, ast_variable::name, ast_variable::next, realtime_sqlite3_exec_update(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and ast_variable::value.

919 {
920  struct ast_str *sql;
921  struct ast_str *where_clause;
922  const struct ast_variable *field;
923  int first = 1, res;
924 
925  if (ast_strlen_zero(table)) {
926  ast_log(LOG_WARNING, "Must have a table to query!\n");
927  return -1;
928  }
929 
930  if (!(sql = ast_str_create(128))) {
931  return -1;
932  }
933 
934  if (!(where_clause = ast_str_create(128))) {
935  ast_free(sql);
936  return -1;
937  }
938 
939  for (field = lookup_fields; field; field = field->next) {
940  if (first) {
941  ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
942  first = 0;
943  } else {
944  ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
945  }
946  }
947 
948  first = 1;
949  for (field = update_fields; field; field = field->next) {
950  if (first) {
951  ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
952  first = 0;
953  } else {
954  ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
955  }
956  }
957 
958  ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));
959 
960  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
961 
962  ast_free(sql);
963  ast_free(where_clause);
964 
965  return res;
966 }
static const char * sqlite3_escape_column(const char *param)
struct ast_variable * next
static const char * sqlite3_escape_column_op(const char *param)
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
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:1091
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * table
Definition: cdr_odbc.c:58
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:1065
#define ast_log
Definition: astobj2.c:42
static const char * sqlite3_escape_value(const char *param)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ast_free(a)
Definition: astmm.h:182
static int realtime_sqlite3_exec_update(const char *, const char *)
static const char * sqlite3_escape_table(const char *param)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ reload()

static int reload ( void  )
static

Definition at line 1321 of file res_config_sqlite3.c.

References parse_config().

Referenced by load_module().

1322 {
1323  parse_config(1);
1324  return 0;
1325 }
static int parse_config(int reload)
Parse the res_config_sqlite3 config file.

◆ row_counter_wrapper()

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

Definition at line 576 of file res_config_sqlite3.c.

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

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

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

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

Referenced by realtime_sqlite3_helper().

489 {
490  struct ast_variable **head = arg, *tail;
491  int i;
492  struct ast_variable *new;
493 
494  if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
495  return SQLITE_ABORT;
496  }
497  *head = tail = new;
498 
499  for (i = 1; i < num_columns; i++) {
500  if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
501  ast_variables_destroy(*head);
502  *head = NULL;
503  return SQLITE_ABORT;
504  }
505  tail->next = new;
506  tail = new;
507  }
508 
509  return 0;
510 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define ast_variable_new(name, value, filename)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ sqlite3_escape_column()

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

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

168 {
170 }
static struct ast_threadstorage escape_column_buf
static const char * sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)

◆ sqlite3_escape_column_op()

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

Definition at line 173 of file res_config_sqlite3.c.

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

174 {
175  size_t maxlen = strlen(param) * 2 + sizeof("\"\" =");
176  struct ast_str *buf = ast_str_thread_get(&escape_column_buf, maxlen);
177  char *tmp;
178  int space = 0;
179 
180  if (ast_str_size(buf) < maxlen) {
181  /* realloc if buf is too small */
182  ast_str_make_space(&buf, maxlen);
183  }
184  tmp = ast_str_buffer(buf);
185 
186  ast_str_reset(buf);
187  *tmp++ = '"';
188  while ((*tmp++ = *param++)) {
189  /* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
190  * available to users via an API, we will definitely need to avoid allowing special
191  * characters like ';' in the data past the space as it will be unquoted data */
192  if (space) {
193  continue;
194  }
195  if (*(tmp - 1) == ' ') {
196  *(tmp - 1) = '"';
197  *tmp++ = ' ';
198  space = 1;
199  } else if (*(tmp - 1) == '"') {
200  *tmp++ = '"';
201  }
202  }
203  if (!space) {
204  strcpy(tmp - 1, "\" =");
205  }
206 
207  ast_str_update(buf);
208 
209  return ast_str_buffer(buf);
210 }
static struct ast_threadstorage escape_column_buf
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
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:653
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:663
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:861

◆ sqlite3_escape_string_helper()

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

Definition at line 130 of file res_config_sqlite3.c.

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

131 {
132  size_t maxlen = strlen(param) * 2 + sizeof("\"\"");
133  /* It doesn't appear that sqlite3_snprintf will do more than double the
134  * length of a string with %q as an option. %Q could double and possibly
135  * add two quotes, and convert NULL pointers to the word "NULL", but we
136  * don't allow those anyway. Just going to use %q for now. */
137  struct ast_str *buf = ast_str_thread_get(ts, maxlen);
138  char q = ts == &escape_value_buf ? '\'' : '"';
139  char *tmp;
140 
141  if (ast_str_size(buf) < maxlen) {
142  /* realloc if buf is too small */
143  ast_str_make_space(&buf, maxlen);
144  }
145  tmp = ast_str_buffer(buf);
146 
147  ast_str_reset(buf);
148  *tmp++ = q; /* Initial quote */
149  while ((*tmp++ = *param++)) {
150  /* Did we just copy a quote? Then double it. */
151  if (*(tmp - 1) == q) {
152  *tmp++ = q;
153  }
154  }
155  *tmp = '\0'; /* Terminate past NULL from copy */
156  *(tmp - 1) = q; /* Replace original NULL with the quote */
157  ast_str_update(buf);
158 
159  return ast_str_buffer(buf);
160 }
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
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:653
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:663
static struct ast_threadstorage escape_value_buf
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:861

◆ sqlite3_escape_table()

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

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

163 {
165 }
static const char * sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)
static struct ast_threadstorage escape_table_buf

◆ sqlite3_escape_value()

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

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

213 {
215 }
static const char * sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)
static struct ast_threadstorage escape_value_buf

◆ static_realtime_cb()

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

Definition at line 720 of file res_config_sqlite3.c.

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

721 {
722  struct cfg_entry_args *args = arg;
723  struct ast_variable *var;
724 
725  if (!strcmp(values[COL_VAR_NAME], "#include")) {
726  struct ast_config *cfg;
727  char *val;
728 
729  val = values[COL_VAR_VAL];
730  if (!(cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked))) {
731  ast_log(LOG_WARNING, "Unable to include %s\n", val);
732  return SQLITE_ABORT;
733  } else {
734  args->cfg = cfg;
735  return 0;
736  }
737  }
738 
739  if (!args->cat_name || strcmp(args->cat_name, values[COL_CATEGORY])) {
740  args->cat = ast_category_new_dynamic(values[COL_CATEGORY]);
741  if (!args->cat) {
742  return SQLITE_ABORT;
743  }
744 
745  ast_free(args->cat_name);
746 
747  if (!(args->cat_name = ast_strdup(values[COL_CATEGORY]))) {
748  ast_category_destroy(args->cat);
749  return SQLITE_ABORT;
750  }
751 
752  ast_category_append(args->cfg, args->cat);
753  }
754 
755  if (!(var = ast_variable_new(values[COL_VAR_NAME], values[COL_VAR_VAL], ""))) {
756  ast_log(LOG_WARNING, "Unable to allocate variable\n");
757  return SQLITE_ABORT;
758  }
759 
760  ast_variable_append(args->cat, var);
761 
762  return 0;
763 }
Definition: ast_expr2.c:325
struct ast_flags flags
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
struct ast_config * cfg
char * cat_name
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * args
void ast_category_destroy(struct ast_category *cat)
Definition: extconf.c:2847
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:3112
struct ast_category * cat
#define ast_log
Definition: astobj2.c:42
#define ast_variable_new(name, value, filename)
const char * who_asked
#define ast_free(a)
Definition: astmm.h:182
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: extconf.c:1178
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Appends a category to a config.
Definition: extconf.c:2835

◆ stop_batch_cb()

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

Definition at line 256 of file res_config_sqlite3.c.

References CMP_MATCH, db, and db_stop_batch().

Referenced by unload_module().

257 {
258  struct realtime_sqlite3_db *db = obj;
259 
260  db_stop_batch(db);
261  return CMP_MATCH;
262 }
void db_stop_batch(struct realtime_sqlite3_db *db)
static sqlite3 * db

◆ str_cmp_fn()

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

Definition at line 1146 of file res_config_sqlite3.c.

Referenced by realtime_sqlite3_require().

1146  {
1147  return !strcasecmp((const char *) obj, (const char *) arg);
1148 }

◆ str_hash_fn()

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

Definition at line 1141 of file res_config_sqlite3.c.

References ast_str_hash().

Referenced by realtime_sqlite3_require().

1142 {
1143  return ast_str_hash((const char *) obj);
1144 }
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ str_to_requirements()

static int str_to_requirements ( const char *  data)
static

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

292 {
293  if (!strcasecmp(data, "createclose")) {
295  } else if (!strcasecmp(data, "createchar")) {
297  }
298  /* default */
300 }

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

References ast_debug, db, and realtime_sqlite3_db::name.

Referenced by db_open(), and update_realtime_sqlite3_db().

304 {
305  struct realtime_sqlite3_db *db = arg;
306  ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
307 }
const ast_string_field name
static sqlite3 * db
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452

◆ unlink_dirty_databases()

static void unlink_dirty_databases ( void  )
static

Definition at line 286 of file res_config_sqlite3.c.

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

Referenced by parse_config().

287 {
289 }
static int is_dirty_cb(void *obj, void *arg, int flags)
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1327 of file res_config_sqlite3.c.

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

Referenced by load_module().

1328 {
1331  ao2_ref(databases, -1);
1332  databases = NULL;
1335 
1336  return 0;
1337 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
Definition: main/config.c:3006
static int stop_batch_cb(void *obj, void *arg, int flags)
#define ast_mutex_lock(a)
Definition: lock.h:187
struct ast_config_engine sqlite3_config_engine
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static ast_mutex_t config_lock
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ unref_db()

static void unref_db ( struct realtime_sqlite3_db **  db)
static

Definition at line 250 of file res_config_sqlite3.c.

References ao2_ref, and NULL.

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

251 {
252  ao2_ref(*db, -1);
253  *db = NULL;
254 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464

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

References ast_string_field_set, realtime_sqlite3_db::batch, realtime_sqlite3_db::busy_timeout, 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(), NULL, realtime_sqlite3_db::requirements, trace_cb(), and unref_db().

Referenced by parse_config().

439 {
440  struct realtime_sqlite3_db *new;
441 
442  if (!(new = new_realtime_sqlite3_db(config, cat))) {
443  return -1;
444  }
445 
446  /* Copy fields that don't need anything special done on change */
447  db->requirements = new->requirements;
448 
449  /* Handle changes that require immediate behavior modification */
450  if (db->debug != new->debug) {
451  if (db->debug) {
452  sqlite3_trace(db->handle, NULL, NULL);
453  } else {
454  sqlite3_trace(db->handle, trace_cb, db);
455  }
456  db->debug = new->debug;
457  }
458 
459  if (strcmp(db->filename, new->filename)) {
460  sqlite3_close(db->handle);
461  ast_string_field_set(db, filename, new->filename);
462  db_open(db); /* Also handles setting appropriate debug on new handle */
463  }
464 
465  if (db->busy_timeout != new->busy_timeout) {
466  db->busy_timeout = new->busy_timeout;
467  sqlite3_busy_timeout(db->handle, db->busy_timeout);
468  }
469 
470  if (db->batch != new->batch) {
471  if (db->batch == 0) {
472  db->batch = new->batch;
473  db_start_batch(db);
474  } else if (new->batch == 0) {
475  db->batch = new->batch;
476  db_stop_batch(db);
477  }
478  db->batch = new->batch;
479  }
480 
481  db->dirty = 0;
482  unref_db(&new);
483 
484  return 0;
485 }
static int db_open(struct realtime_sqlite3_db *db)
Open a database and appropriately set debugging on the db handle.
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.
void db_stop_batch(struct realtime_sqlite3_db *db)
static void trace_cb(void *arg, const char *sql)
#define NULL
Definition: resample.c:96
static void unref_db(struct realtime_sqlite3_db **db)
void db_start_batch(struct realtime_sqlite3_db *db)
const ast_string_field filename
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 1403 of file res_config_sqlite3.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1403 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 113 of file res_config_sqlite3.c.

Referenced by parse_config(), and unload_module().

◆ databases

Definition at line 110 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 117 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 116 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 118 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 61 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 73 of file res_config_sqlite3.c.

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

Referenced by realtime_sqlite3_load().