Asterisk - The Open Source Telephony Project  21.4.1
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"

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.
 
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.
 
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.
 
void db_start_batch (struct realtime_sqlite3_db *db)
 
void db_stop_batch (struct realtime_sqlite3_db *db)
 
static void db_sync (struct realtime_sqlite3_db *db)
 
static void * db_sync_thread (void *data)
 Wrap commands in transactions increased write performance.
 
static 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.
 
static int handle_missing_table (struct realtime_sqlite3_db *db, const char *table, va_list ap)
 Create a table if ast_realtime_require shows that we are configured to handle the data.
 
static int is_dirty_cb (void *obj, void *arg, int flags)
 
static int load_module (void)
 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.
 
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.
 
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.
 
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 = "da6642af068ee5e6490c5b1d2cc1d238" , .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.

Function Documentation

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.

Referenced by handle_missing_column(), and handle_missing_table().

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

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_config_engine_register(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and parse_config().

1370 {
1371  discover_sqlite3_caps();
1372 
1374  db_hash_fn, NULL, db_cmp_fn);
1375  if (!databases) {
1376  return AST_MODULE_LOAD_DECLINE;
1377  }
1378 
1379  if (parse_config(0)) {
1380  ao2_ref(databases, -1);
1381  return AST_MODULE_LOAD_DECLINE;
1382  }
1383 
1384  if (!(ast_config_engine_register(&sqlite3_config_engine))) {
1385  ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
1386  ao2_ref(databases, -1);
1387  return AST_MODULE_LOAD_DECLINE;
1388  }
1389 
1390  return AST_MODULE_LOAD_SUCCESS;
1391 }
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Definition: main/config.c:3157
static int parse_config(int reload)
Parse the res_config_sqlite3 config file.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#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
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
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.

References ast_app_parse_timelen(), ast_parse_arg(), ast_string_field_init, ast_string_field_set, ast_true(), ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by parse_config(), and update_realtime_sqlite3_db().

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;
402  ast_string_field_set(db, name, cat);
403  db->busy_timeout = 1000;
404 
405  for (var = ast_variable_browse(config, cat); var; var = var->next) {
406  if (!strcasecmp(var->name, "dbfile")) {
407  ast_string_field_set(db, filename, var->value);
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 }
struct ast_variable * next
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Definition: main/config.c:3827
Structure for variables, used for configurations and for channel variables.
#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". 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: utils.c:2199
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:3273
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
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.

References realtime_sqlite3_helper().

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 }
Structure for variables, used for configurations and for channel variables.
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.
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.

References ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_variable::name, ast_variable::next, and ast_variable::value.

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),
1030  sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
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 }
struct ast_variable * next
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:1139
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
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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 
786  realtime_sqlite3_exec_query(database, sql, static_realtime_cb, &args);
787 
788  sqlite3_free(sql);
789 
790  return config;
791 }
static const char * static_sql
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.

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

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)) {
869  ast_config_destroy(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
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.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
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.

References add_column_name(), AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, columns, handle_missing_column(), handle_missing_table(), OBJ_POINTER, and OBJ_UNLINK.

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 
1197  str_hash_fn, NULL, str_cmp_fn);
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 
1209  if ((res = realtime_sqlite3_exec_query_with_handle(db, sql, add_column_name, columns)) < 0) {
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
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.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#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
static char * columns
Generic container type.
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.
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.

References ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_variable::name, ast_variable::next, and ast_variable::value.

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);
1004  ast_free(values);
1005 
1006  return res;
1007 }
struct ast_variable * next
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:1139
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
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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 }
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.

References ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_variable::name, ast_variable::next, and ast_variable::value.

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",
897  sqlite3_escape_table(table), sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
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 }
struct ast_variable * next
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:1139
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
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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.

References ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_variable::name, ast_variable::next, and ast_variable::value.

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 }
struct ast_variable * next
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:1139
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
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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.

References ast_debug.

Referenced by db_open(), and update_realtime_sqlite3_db().

301 {
302  struct realtime_sqlite3_db *db = arg;
303  ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
304 }
#define ast_debug(level,...)
Log a DEBUG message.
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.

References ast_string_field_set, db_open(), new_realtime_sqlite3_db(), and trace_cb().

Referenced by parse_config().

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;
470  db_start_batch(db);
471  } else if (new->batch == 0) {
472  db->batch = new->batch;
473  db_stop_batch(db);
474  }
475  db->batch = new->batch;
476  }
477 
478  db->dirty = 0;
479  unref_db(&new);
480 
481  return 0;
482 }
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 trace_cb(void *arg, const char *sql)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521

Variable Documentation

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.