Sat Apr 26 2014 22:03:09

Asterisk developer's documentation


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

Defines

#define DB_BUCKETS   7

Enumerations

enum  { REALTIME_SQLITE3_REQ_WARN, REALTIME_SQLITE3_REQ_CLOSE, REALTIME_SQLITE3_REQ_CHAR }
enum  { COL_CATEGORY, COL_VAR_NAME, COL_VAR_VAL, COL_COLUMNS }

Functions

static void __init_escape_column_buf (void)
static void __init_escape_table_buf (void)
static void __init_escape_value_buf (void)
static void __reg_module (void)
static void __unreg_module (void)
static int add_column_name (void *arg, int num_columns, char **values, char **columns)
 Callback for creating a hash of column names for comparison in realtime_sqlite3_require.
static int append_row_to_cfg (void *arg, int num_columns, char **values, char **columns)
 Callback for creating an ast_config from a successive sqlite3 result rows.
static int db_cmp_fn (void *obj, void *arg, int flags)
static void db_destructor (void *obj)
static int db_hash_fn (const void *obj, const int flags)
static int db_open (struct realtime_sqlite3_db *db)
 Open a database and appropriately set debugging on the db handle.
void db_start_batch (struct realtime_sqlite3_db *db)
void db_stop_batch (struct realtime_sqlite3_db *db)
static void db_sync (struct realtime_sqlite3_db *db)
static void * db_sync_thread (void *data)
 Wrap commands in transactions increased write performance.
static struct realtime_sqlite3_dbfind_database (const char *database)
static const char * get_sqlite_column_type (int type)
 Convert Asterisk realtime types to SQLite 3 types.
static int handle_missing_column (struct realtime_sqlite3_db *db, const char *table, const char *column, int type, size_t sz)
 If ast_realtime_require sends info about a column we don't have, create it.
static int handle_missing_table (struct realtime_sqlite3_db *db, const char *table, va_list ap)
 Create a table if ast_realtime_require shows that we are configured to handle the data.
static int is_dirty_cb (void *obj, void *arg, int flags)
static int load_module (void)
static void mark_all_databases_dirty (void)
static int mark_dirty_cb (void *obj, void *arg, int flags)
static struct realtime_sqlite3_dbnew_realtime_sqlite3_db (struct ast_config *config, const char *cat)
 Create a db object based on a config category.
static int parse_config (int reload)
 Parse the res_config_sqlite3 config file.
static struct ast_variablerealtime_sqlite3 (const char *database, const char *table, va_list ap)
 Realtime callback for a single row query.
static int realtime_sqlite3_destroy (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
 Realtime callback for deleting a row.
static int realtime_sqlite3_execute (const char *database, const char *sql, int(*callback)(void *, int, char **, char **), void *arg, int sync)
static int realtime_sqlite3_execute_handle (struct realtime_sqlite3_db *db, const char *sql, int(*callback)(void *, int, char **, char **), void *arg, int sync)
static int realtime_sqlite3_helper (const char *database, const char *table, va_list ap, int is_multi, void *arg)
 Helper function for single and multi-row realtime load functions.
static struct ast_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.
static struct ast_configrealtime_sqlite3_multi (const char *database, const char *table, va_list ap)
 Realtime callback for a multi-row query.
static int realtime_sqlite3_require (const char *database, const char *table, va_list ap)
 Callback for ast_realtime_require.
static int realtime_sqlite3_store (const char *database, const char *table, va_list ap)
 Realtime callback for inserting a row.
static int realtime_sqlite3_unload (const char *database, const char *table)
 Callback for clearing any cached info.
static int realtime_sqlite3_update (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
 Realtime callback for updating a row based on a single criteria.
static int realtime_sqlite3_update2 (const char *database, const char *table, va_list ap)
 Realtime callback for updating a row based on multiple criteria.
static int reload (void)
static int row_to_varlist (void *arg, int num_columns, char **values, char **columns)
 Create a varlist from a single sqlite3 result row.
static const char * sqlite3_escape_column (const char *param)
static const char * sqlite3_escape_column_op (const char *param)
static const char * sqlite3_escape_string_helper (struct ast_threadstorage *ts, const char *param)
static const char * sqlite3_escape_table (const char *param)
static const char * sqlite3_escape_value (const char *param)
static int static_realtime_cb (void *arg, int num_columns, char **values, char **columns)
static int stop_batch_cb (void *obj, void *arg, int flags)
static int str_cmp_fn (void *obj, void *arg, int flags)
static int str_hash_fn (const void *obj, const int flags)
static int str_to_requirements (const char *data)
static void trace_cb (void *arg, const char *sql)
static void unlink_dirty_databases (void)
static int unload_module (void)
static void unref_db (struct realtime_sqlite3_db **db)
static int update_realtime_sqlite3_db (struct realtime_sqlite3_db *db, struct ast_config *config, const char *cat)
 Update an existing db object based on config data.

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "SQLite 3 realtime config engine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
static struct ast_module_infoast_module_info = &__mod_info
static ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
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 , }
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.


Define Documentation

#define DB_BUCKETS   7

Definition at line 100 of file res_config_sqlite3.c.

Referenced by load_module().


Enumeration Type Documentation

anonymous enum
Enumerator:
REALTIME_SQLITE3_REQ_WARN 
REALTIME_SQLITE3_REQ_CLOSE 
REALTIME_SQLITE3_REQ_CHAR 

Definition at line 77 of file res_config_sqlite3.c.

anonymous enum
Enumerator:
COL_CATEGORY 
COL_VAR_NAME 
COL_VAR_VAL 
COL_COLUMNS 

Definition at line 558 of file res_config_sqlite3.c.


Function Documentation

static void __init_escape_column_buf ( void  ) [static]

Definition at line 106 of file res_config_sqlite3.c.

{
static void __init_escape_table_buf ( void  ) [static]

Definition at line 105 of file res_config_sqlite3.c.

{
static void __init_escape_value_buf ( void  ) [static]

Definition at line 107 of file res_config_sqlite3.c.

{
static void __reg_module ( void  ) [static]

Definition at line 1190 of file res_config_sqlite3.c.

static void __unreg_module ( void  ) [static]

Definition at line 1190 of file res_config_sqlite3.c.

static int add_column_name ( void *  arg,
int  num_columns,
char **  values,
char **  columns 
) [static]

Callback for creating a hash of column names for comparison in realtime_sqlite3_require.

Definition at line 984 of file res_config_sqlite3.c.

References ao2_alloc, ao2_link, and ao2_ref.

Referenced by realtime_sqlite3_require().

{
   char *column;
   struct ao2_container *cnames = arg;


   if (!(column = ao2_alloc(strlen(values[1]) + 1, NULL))) {
      return -1;
   }

   strcpy(column, values[1]);

   ao2_link(cnames, column);
   ao2_ref(column, -1);

   return 0;
}
static int append_row_to_cfg ( void *  arg,
int  num_columns,
char **  values,
char **  columns 
) [static]

Callback for creating an ast_config from a successive sqlite3 result rows.

Definition at line 472 of file res_config_sqlite3.c.

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

Referenced by realtime_sqlite3_helper().

{
   struct ast_config *cfg = arg;
   struct ast_category *cat;
   int i;

   if (!(cat = ast_category_new("", "", 99999))) {
      return SQLITE_ABORT;
   }

   for (i = 0; i < num_columns; i++) {
      struct ast_variable *var;
      if (!(var = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
         ast_log(LOG_ERROR, "Could not create new variable for '%s: %s', throwing away list\n", columns[i], values[i]);
         continue;
      }
      ast_variable_append(cat, var);
   }
   ast_category_append(cfg, cat);

   return 0;
}
static int db_cmp_fn ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 195 of file res_config_sqlite3.c.

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

Referenced by load_module().

                                                      {
   struct realtime_sqlite3_db *db = obj, *other = arg;
   const char *name = arg;

   return !strcasecmp(db->name, flags & OBJ_KEY ? name : other->name) ? CMP_MATCH | CMP_STOP : 0;
}
static void db_destructor ( void *  obj) [static]

Definition at line 202 of file res_config_sqlite3.c.

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

Referenced by new_realtime_sqlite3_db().

{
   struct realtime_sqlite3_db *db = obj;

   ast_debug(1, "Destroying db: %s\n", db->name);
   ast_string_field_free_memory(db);
   db_stop_batch(db);
   if (db->handle) {
      ao2_lock(db);
      sqlite3_close(db->handle);
      ao2_unlock(db);
   }
}
static int db_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 188 of file res_config_sqlite3.c.

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

Referenced by load_module().

{
   const struct realtime_sqlite3_db *db = obj;

   return ast_str_hash(flags & OBJ_KEY ? (const char *) obj : db->name);
}
static int db_open ( struct realtime_sqlite3_db db) [static]

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

Definition at line 310 of file res_config_sqlite3.c.

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

Referenced by parse_config(), and update_realtime_sqlite3_db().

{
   ao2_lock(db);
   if (sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
      ast_log(LOG_WARNING, "Could not open %s: %s\n", db->filename, sqlite3_errmsg(db->handle));
      ao2_unlock(db);
      return -1;
   }

   if (db->debug) {
      sqlite3_trace(db->handle, trace_cb, db);
   } else {
      sqlite3_trace(db->handle, NULL, NULL);
   }

   ao2_unlock(db);

   return 0;
}
static void db_sync ( struct realtime_sqlite3_db db) [static]
static void* db_sync_thread ( void *  data) [static]

Wrap commands in transactions increased write performance.

Definition at line 281 of file res_config_sqlite3.c.

References ao2_lock, ao2_object_get_lockaddr(), ao2_unlock, ast_cond_wait, realtime_sqlite3_db::batch, realtime_sqlite3_db::cond, realtime_sqlite3_db::exiting, realtime_sqlite3_execute_handle(), unref_db(), and realtime_sqlite3_db::wakeup.

Referenced by db_start_batch().

{
   struct realtime_sqlite3_db *db = data;
   ao2_lock(db);
   realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
   for (;;) {
      if (!db->wakeup) {
         ast_cond_wait(&db->cond, ao2_object_get_lockaddr(db));
      }
      db->wakeup = 0;
      if (realtime_sqlite3_execute_handle(db, "COMMIT", NULL, NULL, 0) < 0) {
         realtime_sqlite3_execute_handle(db, "ROLLBACK", NULL, NULL, 0);
      }
      if (db->exiting) {
         ao2_unlock(db);
         break;
      }
      realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
      ao2_unlock(db);
      usleep(1000 * db->batch);
      ao2_lock(db);
   }

   unref_db(&db);

   return NULL;
}
static struct realtime_sqlite3_db* find_database ( const char *  database) [static, read]

Definition at line 216 of file res_config_sqlite3.c.

References ao2_find, and OBJ_KEY.

Referenced by parse_config(), realtime_sqlite3_execute(), and realtime_sqlite3_require().

{
   return ao2_find(databases, database, OBJ_KEY);
}
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 887 of file res_config_sqlite3.c.

References RQ_CHAR, RQ_DATE, RQ_DATETIME, RQ_FLOAT, RQ_INTEGER1, RQ_INTEGER2, RQ_INTEGER3, RQ_INTEGER4, RQ_INTEGER8, RQ_UINTEGER1, RQ_UINTEGER2, RQ_UINTEGER3, RQ_UINTEGER4, and RQ_UINTEGER8.

Referenced by handle_missing_column(), and handle_missing_table().

{
   switch(type) {
   case RQ_INTEGER1 :
   case RQ_UINTEGER1 :
   case RQ_INTEGER2 :
   case RQ_UINTEGER2 :
   case RQ_INTEGER3 :
   case RQ_UINTEGER3 :
   case RQ_INTEGER4 :
   case RQ_UINTEGER4 :
   case RQ_INTEGER8 :
      return "INTEGER";
   case RQ_UINTEGER8 : /* SQLite3 stores INTEGER as signed 8-byte */
   case RQ_CHAR :
   case RQ_DATE :
   case RQ_DATETIME :
      return "TEXT";
   case RQ_FLOAT :
      return "REAL";
   default :
      return "TEXT";
   }

   return "TEXT";
}
static int handle_missing_column ( struct realtime_sqlite3_db db,
const char *  table,
const char *  column,
int  type,
size_t  sz 
) [static]

If ast_realtime_require sends info about a column we don't have, create it.

Definition at line 947 of file res_config_sqlite3.c.

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

Referenced by realtime_sqlite3_require().

{
   char *sql;
   const char *sqltype = get_sqlite_column_type(type);
   int res;

   if (db->requirements == REALTIME_SQLITE3_REQ_WARN) {
      ast_log(LOG_WARNING, "Missing column '%s' of type '%s' in %s.%s\n", column, sqltype, db->name, table);
      return -1;
   } else if (db->requirements == REALTIME_SQLITE3_REQ_CHAR) {
      sqltype = "TEXT";
   }

   if (!(sql = sqlite3_mprintf("ALTER TABLE \"%q\" ADD COLUMN \"%q\" %s", table, column, sqltype))) {
      return -1;
   }

   if (!(res = (realtime_sqlite3_execute_handle(db, sql, NULL, NULL, 1) < 0 ? -1 : 0))) {
      ast_log(LOG_NOTICE, "Creating column '%s' type %s for table %s\n", column, sqltype, table);
   }

   sqlite3_free(sql);

   return res;
}
static int handle_missing_table ( struct realtime_sqlite3_db db,
const char *  table,
va_list  ap 
) [static]

Create a table if ast_realtime_require shows that we are configured to handle the data.

Definition at line 916 of file res_config_sqlite3.c.

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

Referenced by realtime_sqlite3_require().

{
   const char *column;
   int type, first = 1, res;
   size_t sz;
   struct ast_str *sql;

   if (!(sql = ast_str_create(128))) {
      return -1;
   }

   while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
      if (first) {
         ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
               sqlite3_escape_column(column), get_sqlite_column_type(type));
         first = 0;
      } else {
         ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
      }
   }

   ast_str_append(&sql, 0, ")");

   res = realtime_sqlite3_execute_handle(db, ast_str_buffer(sql), NULL, NULL, 1) < 0 ? -1 : 0;
   ast_free(sql);

   return res;
}
static int is_dirty_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 247 of file res_config_sqlite3.c.

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

Referenced by unlink_dirty_databases().

{
   struct realtime_sqlite3_db *db = obj;
   if (db->dirty) {
      db_stop_batch(db);
      return CMP_MATCH;
   }
   return 0;
}
static void mark_all_databases_dirty ( void  ) [static]
static int mark_dirty_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 235 of file res_config_sqlite3.c.

References CMP_MATCH, and realtime_sqlite3_db::dirty.

Referenced by mark_all_databases_dirty().

{
   struct realtime_sqlite3_db *db = obj;
   db->dirty = 1;
   return CMP_MATCH;
}
static struct realtime_sqlite3_db* new_realtime_sqlite3_db ( struct ast_config config,
const char *  cat 
) [static, read]

Create a db object based on a config category.

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

Definition at line 357 of file res_config_sqlite3.c.

References ao2_alloc, ast_app_parse_timelen(), ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variable_browse(), realtime_sqlite3_db::batch, db, db_destructor(), realtime_sqlite3_db::debug, realtime_sqlite3_db::filename, LOG_WARNING, name, ast_variable::name, ast_variable::next, REALTIME_SQLITE3_REQ_WARN, realtime_sqlite3_db::requirements, str_to_requirements(), TIMELEN_MILLISECONDS, unref_db(), ast_variable::value, and var.

Referenced by parse_config(), and update_realtime_sqlite3_db().

{
   struct ast_variable *var;
   struct realtime_sqlite3_db *db;

   if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
      return NULL;
   }

   if (ast_string_field_init(db, 64)) {
      unref_db(&db);
      return NULL;
   }

   /* Set defaults */
   db->requirements = REALTIME_SQLITE3_REQ_WARN;
   db->batch = 100;
   ast_string_field_set(db, name, cat);

   for (var = ast_variable_browse(config, cat); var; var = var->next) {
      if (!strcasecmp(var->name, "dbfile")) {
         ast_string_field_set(db, filename, var->value);
      } else if (!strcasecmp(var->name, "requirements")) {
         db->requirements = str_to_requirements(var->value);
      } else if (!strcasecmp(var->name, "batch")) {
         ast_app_parse_timelen(var->value, (int *) &db->batch, TIMELEN_MILLISECONDS);
      } else if (!strcasecmp(var->name, "debug")) {
         db->debug = ast_true(var->value);
      }
   }

   if (ast_strlen_zero(db->filename)) {
      ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
      unref_db(&db);
      return NULL;
   }

   return db;
}
static int parse_config ( int  reload) [static]

Parse the res_config_sqlite3 config file.

Definition at line 1090 of file res_config_sqlite3.c.

References ao2_link, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOREALTIME, config_lock, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, db, db_open(), db_start_batch(), find_database(), LOG_ERROR, LOG_WARNING, mark_all_databases_dirty(), new_realtime_sqlite3_db(), unlink_dirty_databases(), unref_db(), and update_realtime_sqlite3_db().

Referenced by load_module(), and reload().

{
   struct ast_config *config;
   struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME | (reload ? CONFIG_FLAG_FILEUNCHANGED : 0) };
   static const char *config_filename = "res_config_sqlite3.conf";

   config = ast_config_load(config_filename, config_flags);

   if (config == CONFIG_STATUS_FILEUNCHANGED) {
      ast_debug(1, "%s was unchanged, skipping parsing\n", config_filename);
      return 0;
   }

   ast_mutex_lock(&config_lock);

   if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
      ast_log(LOG_ERROR, "%s config file '%s'\n",
         config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
   } else {
      const char *cat;
      struct realtime_sqlite3_db *db;

      mark_all_databases_dirty();
      for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
         if (!strcasecmp(cat, "general")) {
            continue;
         }
         if (!(db = find_database(cat))) {
            if (!(db = new_realtime_sqlite3_db(config, cat))) {
               ast_log(LOG_WARNING, "Could not allocate new db for '%s' - skipping.\n", cat);
               continue;
            }
            if (db_open(db)) {
               unref_db(&db);
               continue;
            }
            db_start_batch(db);
            ao2_link(databases, db);
            unref_db(&db);
         } else  {
            if (update_realtime_sqlite3_db(db, config, cat)) {
               unref_db(&db);
               continue;
            }
            unref_db(&db);
         }
      }
      unlink_dirty_databases();
   }

   ast_mutex_unlock(&config_lock);

   ast_config_destroy(config);

   return 0;
}
static struct ast_variable * realtime_sqlite3 ( const char *  database,
const char *  table,
va_list  ap 
) [static, read]

Realtime callback for a single row query.

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

Definition at line 685 of file res_config_sqlite3.c.

References realtime_sqlite3_helper().

{
   struct ast_variable *result_row = NULL;

   realtime_sqlite3_helper(database, table, ap, 0, &result_row);

   return result_row;
}
static int realtime_sqlite3_destroy ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
va_list  ap 
) [static]

Realtime callback for deleting a row.

Returns:
Number of rows affected or -1 on error

Definition at line 849 of file res_config_sqlite3.c.

References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.

{
   struct ast_str *sql;
   const char *param, *value;
   int first = 1, res;

   if (ast_strlen_zero(table)) {
      ast_log(LOG_WARNING, "Must have a table to query!\n");
      return -1;
   }

   if (!(sql = ast_str_create(128))) {
      return -1;
   }

   while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
      if (first) {
         ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
               sqlite3_escape_column_op(param), sqlite3_escape_value(value));
         first = 0;
      } else {
         ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param), sqlite3_escape_value(value));
      }
   }

   res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);

   ast_free(sql);

   return res;
}
static int realtime_sqlite3_execute ( const char *  database,
const char *  sql,
int(*)(void *, int, char **, char **)  callback,
void *  arg,
int  sync 
) [static]

Exeute an SQL statement give the database name

Return values:
-1ERROR
>-1 Number of rows changed

Definition at line 540 of file res_config_sqlite3.c.

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

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

{
   struct realtime_sqlite3_db *db;
   int res;

   if (!(db = find_database(database))) {
      ast_log(LOG_WARNING, "Could not find database: %s\n", database);
      return -1;
   }

   res = realtime_sqlite3_execute_handle(db, sql, callback, arg, sync);
   ao2_ref(db, -1);

   return res;
}
static int realtime_sqlite3_execute_handle ( struct realtime_sqlite3_db db,
const char *  sql,
int(*)(void *, int, char **, char **)  callback,
void *  arg,
int  sync 
) [static]

Exeute an SQL statement given the database object

Return values:
-1ERROR
>-1 Number of rows changed

Definition at line 513 of file res_config_sqlite3.c.

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

Referenced by db_sync_thread(), handle_missing_column(), handle_missing_table(), realtime_sqlite3_execute(), and realtime_sqlite3_require().

{
   int res = 0;
   char *errmsg;

   ao2_lock(db);
   if (sqlite3_exec(db->handle, sql, callback, arg, &errmsg) != SQLITE_OK) {
      ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
      sqlite3_free(errmsg);
      res = -1;
   } else {
      res = sqlite3_changes(db->handle);
   }
   ao2_unlock(db);

   if (sync) {
      db_sync(db);
   }

   return res;
}
static int realtime_sqlite3_helper ( const char *  database,
const char *  table,
va_list  ap,
int  is_multi,
void *  arg 
) [static]

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

Definition at line 642 of file res_config_sqlite3.c.

References append_row_to_cfg(), ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), row_to_varlist(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.

Referenced by realtime_sqlite3(), and realtime_sqlite3_multi().

{
   struct ast_str *sql;
   const char *param, *value;
   int first = 1;

   if (ast_strlen_zero(table)) {
      ast_log(LOG_WARNING, "Must have a table to query!\n");
      return -1;
   }

   if (!(sql = ast_str_create(128))) {
      return -1;
   }

   while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
      if (first) {
         ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
               sqlite3_escape_column_op(param), sqlite3_escape_value(value));
         first = 0;
      } else {
         ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param),
               sqlite3_escape_value(value));
      }
   }

   if (!is_multi) {
      ast_str_append(&sql, 0, "%s", " LIMIT 1");
   }

   if (realtime_sqlite3_execute(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg, 0) < 0) {
      ast_free(sql);
      return -1;
   }

   ast_free(sql);

   return 0;
}
static struct ast_config * realtime_sqlite3_load ( const char *  database,
const char *  table,
const char *  configfile,
struct ast_config config,
struct ast_flags  flags,
const char *  suggested_include_file,
const char *  who_asked 
) [static, read]

Realtime callback for static realtime.

Returns:
ast_config on success, NULL on failure

Definition at line 613 of file res_config_sqlite3.c.

References ast_log(), ast_strlen_zero(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, config, cfg_entry_args::flags, LOG_WARNING, realtime_sqlite3_execute(), static_realtime_cb(), and cfg_entry_args::who_asked.

{
   char *sql;
   struct cfg_entry_args args;

   if (ast_strlen_zero(table)) {
      ast_log(LOG_WARNING, "Must have a table to query!\n");
      return NULL;
   }

   if (!(sql = sqlite3_mprintf(static_sql, table, configfile))) {
      ast_log(LOG_WARNING, "Couldn't allocate query\n");
      return NULL;
   };

   args.cfg = config;
   args.cat = NULL;
   args.cat_name = NULL;
   args.flags = flags;
   args.who_asked = who_asked;

   realtime_sqlite3_execute(database, sql, static_realtime_cb, &args, 0);

   sqlite3_free(sql);

   return config;
}
static struct ast_config * realtime_sqlite3_multi ( const char *  database,
const char *  table,
va_list  ap 
) [static, read]

Realtime callback for a multi-row query.

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

Definition at line 697 of file res_config_sqlite3.c.

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

{
   struct ast_config *cfg;

   if (!(cfg = ast_config_new())) {
      return NULL;
   }

   if (realtime_sqlite3_helper(database, table, ap, 1, cfg)) {
      ast_config_destroy(cfg);
      return NULL;
   }

   return cfg;
}
static int realtime_sqlite3_require ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Callback for ast_realtime_require.

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

Definition at line 1006 of file res_config_sqlite3.c.

References add_column_name(), ao2_container_alloc, ao2_find, ao2_ref, ast_log(), ast_strlen_zero(), columns, db, find_database(), handle_missing_column(), handle_missing_table(), LOG_WARNING, OBJ_POINTER, OBJ_UNLINK, realtime_sqlite3_execute_handle(), str_cmp_fn(), str_hash_fn(), type, typeof(), and unref_db().

{
   const char *column;
   char *sql;
   int type;
   int res;
   size_t sz;
   struct ao2_container *columns;
   struct realtime_sqlite3_db *db;

   /* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
    * return the results as char * anyway. The only field that that cannot contain text
    * data is an INTEGER PRIMARY KEY, which must be a 64-bit signed integer. So, for
    * the purposes here we really only care whether the column exists and not what its
    * type or length is. */

   if (ast_strlen_zero(table)) {
      ast_log(LOG_WARNING, "Must have a table to query!\n");
      return -1;
   }

   if (!(db = find_database(database))) {
      return -1;
   }

   if (!(columns = ao2_container_alloc(31, str_hash_fn, str_cmp_fn))) {
      unref_db(&db);
      return -1;
   }

   if (!(sql = sqlite3_mprintf("PRAGMA table_info(\"%q\")", table))) {
      unref_db(&db);
      ao2_ref(columns, -1);
      return -1;
   }

   if ((res = realtime_sqlite3_execute_handle(db, sql, add_column_name, columns, 0)) < 0) {
      unref_db(&db);
      ao2_ref(columns, -1);
      sqlite3_free(sql);
      return -1;
   } else if (res == 0) {
      /* Table does not exist */
      sqlite3_free(sql);
      res = handle_missing_table(db, table, ap);
      ao2_ref(columns, -1);
      unref_db(&db);
      return res;
   }

   sqlite3_free(sql);

   while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
      char *found;
      if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
         if (handle_missing_column(db, table, column, type, sz)) {
            unref_db(&db);
            ao2_ref(columns, -1);
            return -1;
         }
      } else {
         ao2_ref(found, -1);
      }
   }

   ao2_ref(columns, -1);
   unref_db(&db);

   return 0;
}
static int realtime_sqlite3_store ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Realtime callback for inserting a row.

Returns:
Number of rows affected or -1 on error

Definition at line 805 of file res_config_sqlite3.c.

References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column(), sqlite3_escape_table(), sqlite3_escape_value(), and value.

{
   struct ast_str *sql, *values;
   const char *column, *value;
   int first = 1, res;

   if (ast_strlen_zero(table)) {
      ast_log(LOG_WARNING, "Must have a table to query!\n");
      return -1;
   }

   if (!(sql = ast_str_create(128))) {
      return -1;
   }

   if (!(values = ast_str_create(128))) {
      ast_free(sql);
      return -1;
   }

   while ((column = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
      if (first) {
         ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(column));
         ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(value));
         first = 0;
      } else {
         ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(column));
         ast_str_append(&values, 0, ", %s", sqlite3_escape_value(value));
      }
   }

   ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));

   res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);

   ast_free(sql);
   ast_free(values);

   return res;
}
static int realtime_sqlite3_unload ( const char *  database,
const char *  table 
) [static]

Callback for clearing any cached info.

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

Definition at line 1082 of file res_config_sqlite3.c.

{
   /* We currently do no caching */
   return -1;
}
static int realtime_sqlite3_update ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  entity,
va_list  ap 
) [static]

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

Returns:
Number of rows affected or -1 on error

Definition at line 716 of file res_config_sqlite3.c.

References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.

{
   struct ast_str *sql;
   const char *key, *value;
   int first = 1, res;

   if (ast_strlen_zero(table)) {
      ast_log(LOG_WARNING, "Must have a table to query!\n");
      return -1;
   }

   if (!(sql = ast_str_create(128))) {
      return -1;
   }

   while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
      if (first) {
         ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
               sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
         first = 0;
      } else {
         ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
      }
   }

   ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));

   res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
   ast_free(sql);

   return res;
}
static int realtime_sqlite3_update2 ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Realtime callback for updating a row based on multiple criteria.

Returns:
Number of rows affected or -1 on error

Definition at line 752 of file res_config_sqlite3.c.

References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), first, LOG_WARNING, realtime_sqlite3_execute(), sqlite3_escape_column(), sqlite3_escape_column_op(), sqlite3_escape_table(), sqlite3_escape_value(), and value.

{
   struct ast_str *sql;
   struct ast_str *where_clause;
   const char *key, *value;
   int first = 1, res;

   if (ast_strlen_zero(table)) {
      ast_log(LOG_WARNING, "Must have a table to query!\n");
      return -1;
   }

   if (!(sql = ast_str_create(128))) {
      return -1;
   }

   if (!(where_clause = ast_str_create(128))) {
      ast_free(sql);
      return -1;
   }

   while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
      if (first) {
         ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
         first = 0;
      } else {
         ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
      }
   }

   first = 1;
   while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
      if (first) {
         ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
         first = 0;
      } else {
         ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
      }
   }

   ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));

   res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);

   ast_free(sql);
   ast_free(where_clause);

   return res;
}
static int reload ( void  ) [static]

Definition at line 1147 of file res_config_sqlite3.c.

References parse_config().

{
   parse_config(1);
   return 0;
}
static int row_to_varlist ( void *  arg,
int  num_columns,
char **  values,
char **  columns 
) [static]

Create a varlist from a single sqlite3 result row.

Definition at line 447 of file res_config_sqlite3.c.

References ast_variable_new(), ast_variables_destroy(), ast_variable::next, and S_OR.

Referenced by realtime_sqlite3_helper().

{
   struct ast_variable **head = arg, *tail;
   int i;
   struct ast_variable *new;

   if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
      return SQLITE_ABORT;
   }
   *head = tail = new;

   for (i = 1; i < num_columns; i++) {
      if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
         ast_variables_destroy(*head);
         *head = NULL;
         return SQLITE_ABORT;
      }
      tail->next = new;
      tail = new;
   }

   return 0;
}
static const char* sqlite3_escape_column ( const char *  param) [inline, static]
static const char* sqlite3_escape_column_op ( const char *  param) [static]

Definition at line 150 of file res_config_sqlite3.c.

References ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), ast_str_update(), and escape_column_buf.

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

{
   size_t maxlen = strlen(param) * 2 + sizeof("\"\" =");
   struct ast_str *buf = ast_str_thread_get(&escape_column_buf, maxlen);
   char *tmp = ast_str_buffer(buf);
   int space = 0;

   ast_str_reset(buf);
   *tmp++ = '"';
   while ((*tmp++ = *param++)) {
      /* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
       * available to users via an API, we will definitely need to avoid allowing special
       * characters like ';' in the data past the space as it will be unquoted data */
      if (space) {
         continue;
      }
      if (*(tmp - 1) == ' ') {
         *(tmp - 1) = '"';
         *tmp++ = ' ';
         space = 1;
      } else if (*(tmp - 1) == '"') {
         *tmp++ = '"';
      }
   }
   if (!space) {
      strcpy(tmp - 1, "\" =");
   }

   ast_str_update(buf);

   return ast_str_buffer(buf);
}
static const char* sqlite3_escape_string_helper ( struct ast_threadstorage ts,
const char *  param 
) [inline, static]

Definition at line 113 of file res_config_sqlite3.c.

References ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), ast_str_update(), and escape_value_buf.

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

{
   size_t maxlen = strlen(param) * 2 + sizeof("\"\"");
   /* It doesn't appear that sqlite3_snprintf will do more than double the
    * length of a string with %q as an option. %Q could double and possibly
    * add two quotes, and convert NULL pointers to the word "NULL", but we
    * don't allow those anyway. Just going to use %q for now. */
   struct ast_str *buf = ast_str_thread_get(ts, maxlen);
   char *tmp = ast_str_buffer(buf);
   char q = ts == &escape_value_buf ? '\'' : '"';

   ast_str_reset(buf);
   *tmp++ = q; /* Initial quote */
   while ((*tmp++ = *param++)) {
      /* Did we just copy a quote? Then double it. */
      if (*(tmp - 1) == q) {
         *tmp++ = q;
      }
   }
   *tmp = '\0'; /* Terminate past NULL from copy */
   *(tmp - 1) = q; /* Replace original NULL with the quote */
   ast_str_update(buf);

   return ast_str_buffer(buf);
}
static int static_realtime_cb ( void *  arg,
int  num_columns,
char **  values,
char **  columns 
) [static]

Definition at line 565 of file res_config_sqlite3.c.

References args, ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_internal_load(), ast_free, ast_log(), ast_strdup, ast_variable_append(), ast_variable_new(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, COL_CATEGORY, COL_VAR_NAME, COL_VAR_VAL, cfg_entry_args::flags, LOG_WARNING, var, and cfg_entry_args::who_asked.

Referenced by realtime_sqlite3_load().

{
   struct cfg_entry_args *args = arg;
   struct ast_variable *var;

   if (!strcmp(values[COL_VAR_NAME], "#include")) {
      struct ast_config *cfg;
      char *val;

      val = values[COL_VAR_VAL];
      if (!(cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked))) {
         ast_log(LOG_WARNING, "Unable to include %s\n", val);
         return SQLITE_ABORT;
      } else {
         args->cfg = cfg;
         return 0;
      }
   }

   if (!args->cat_name || strcmp(args->cat_name, values[COL_CATEGORY])) {
      if (!(args->cat = ast_category_new(values[COL_CATEGORY], "", 99999))) {
         ast_log(LOG_WARNING, "Unable to allocate category\n");
         return SQLITE_ABORT;
      }

      ast_free(args->cat_name);

      if (!(args->cat_name = ast_strdup(values[COL_CATEGORY]))) {
         ast_category_destroy(args->cat);
         return SQLITE_ABORT;
      }

      ast_category_append(args->cfg, args->cat);
   }

   if (!(var = ast_variable_new(values[COL_VAR_NAME], values[COL_VAR_VAL], ""))) {
      ast_log(LOG_WARNING, "Unable to allocate variable\n");
      return SQLITE_ABORT;
   }

   ast_variable_append(args->cat, var);

   return 0;
}
static int stop_batch_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 227 of file res_config_sqlite3.c.

References CMP_MATCH, and db_stop_batch().

Referenced by unload_module().

{
   struct realtime_sqlite3_db *db = obj;

   db_stop_batch(db);
   return CMP_MATCH;
}
static int str_cmp_fn ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 978 of file res_config_sqlite3.c.

Referenced by realtime_sqlite3_require().

                                                       {
   return !strcasecmp((const char *) obj, (const char *) arg);
}
static int str_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 973 of file res_config_sqlite3.c.

References ast_str_hash().

Referenced by realtime_sqlite3_require().

{
   return ast_str_hash((const char *) obj);
}
static int str_to_requirements ( const char *  data) [static]

Definition at line 262 of file res_config_sqlite3.c.

References REALTIME_SQLITE3_REQ_CHAR, REALTIME_SQLITE3_REQ_CLOSE, and REALTIME_SQLITE3_REQ_WARN.

Referenced by new_realtime_sqlite3_db().

{
   if (!strcasecmp(data, "createclose")) {
      return REALTIME_SQLITE3_REQ_CLOSE;
   } else if (!strcasecmp(data, "createchar")) {
      return REALTIME_SQLITE3_REQ_CHAR;
   }
   /* default */
   return REALTIME_SQLITE3_REQ_WARN;
}
static void trace_cb ( void *  arg,
const char *  sql 
) [static]
Note:
Since this is called while a query is executing, we should already hold the db lock

Definition at line 274 of file res_config_sqlite3.c.

References ast_debug, and realtime_sqlite3_db::name.

Referenced by db_open(), and update_realtime_sqlite3_db().

{
   struct realtime_sqlite3_db *db = arg;
   ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
}
static void unlink_dirty_databases ( void  ) [static]
static void unref_db ( struct realtime_sqlite3_db **  db) [static]

Definition at line 221 of file res_config_sqlite3.c.

References ao2_ref.

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

{
   ao2_ref(*db, -1);
   *db = NULL;
}
static int update_realtime_sqlite3_db ( struct realtime_sqlite3_db db,
struct ast_config config,
const char *  cat 
) [static]

Update an existing db object based on config data.

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

References ast_string_field_set, realtime_sqlite3_db::batch, db_open(), db_start_batch(), db_stop_batch(), realtime_sqlite3_db::debug, realtime_sqlite3_db::dirty, realtime_sqlite3_db::filename, realtime_sqlite3_db::handle, new_realtime_sqlite3_db(), realtime_sqlite3_db::requirements, trace_cb(), and unref_db().

Referenced by parse_config().

{
   struct realtime_sqlite3_db *new;

   if (!(new = new_realtime_sqlite3_db(config, cat))) {
      return -1;
   }

   /* Copy fields that don't need anything special done on change */
   db->requirements = new->requirements;

   /* Handle changes that require immediate behavior modification */
   if (db->debug != new->debug) {
      if (db->debug) {
         sqlite3_trace(db->handle, NULL, NULL);
      } else {
         sqlite3_trace(db->handle, trace_cb, db);
      }
      db->debug = new->debug;
   }

   if (strcmp(db->filename, new->filename)) {
      sqlite3_close(db->handle);
      ast_string_field_set(db, filename, new->filename);
      db_open(db); /* Also handles setting appropriate debug on new handle */
   }

   if (db->batch != new->batch) {
      if (db->batch == 0) {
         db->batch = new->batch;
         db_start_batch(db);
      } else if (new->batch == 0) {
         db->batch = new->batch;
         db_stop_batch(db);
      }
      db->batch = new->batch;
   }

   db->dirty = 0;
   unref_db(&new);

   return 0;
}

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "SQLite 3 realtime config engine" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, } [static]

Definition at line 1190 of file res_config_sqlite3.c.

Definition at line 1190 of file res_config_sqlite3.c.

ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 102 of file res_config_sqlite3.c.

Referenced by parse_config(), and unload_module().

Definition at line 99 of file res_config_sqlite3.c.

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

Definition at line 106 of file res_config_sqlite3.c.

Referenced by sqlite3_escape_column(), and sqlite3_escape_column_op().

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

Definition at line 105 of file res_config_sqlite3.c.

Referenced by sqlite3_escape_table().

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

Definition at line 107 of file res_config_sqlite3.c.

Referenced by sqlite3_escape_string_helper(), and sqlite3_escape_value().

Definition at line 64 of file res_config_sqlite3.c.

const char* static_sql = "SELECT category, var_name, var_val FROM \"%q\" WHERE filename = %Q AND commented = 0 ORDER BY cat_metric ASC, var_metric ASC" [static]
Note:
It is important that the COL_* enum matches the order of the columns selected in static_sql

Definition at line 557 of file res_config_sqlite3.c.