Sat Apr 26 2014 22:01:40

Asterisk developer's documentation


res_config_sqlite3.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2011, Terry Wilson
00005  *
00006  * Terry Wilson <twilson@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  *
00018  * Please follow coding guidelines
00019  * http://svn.digium.com/view/asterisk/trunk/doc/CODING-GUIDELINES
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief SQLite 3 configuration engine
00025  *
00026  * \author\verbatim Terry Wilson <twilson@digium.com> \endverbatim
00027  *
00028  * This is a realtime configuration engine for the SQLite 3 Database
00029  * \ingroup resources
00030  */
00031 
00032 /*** MODULEINFO
00033    <depend>sqlite3</depend>
00034    <support_level>core</support_level>
00035  ***/
00036 
00037 #include "asterisk.h"
00038 
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 362307 $")
00040 
00041 #include <sqlite3.h>
00042 
00043 #include "asterisk/module.h"
00044 #include "asterisk/config.h"
00045 #include "asterisk/paths.h"
00046 #include "asterisk/astobj2.h"
00047 #include "asterisk/lock.h"
00048 #include "asterisk/utils.h"
00049 #include "asterisk/app.h"
00050 
00051 /*** DOCUMENTATION
00052  ***/
00053 
00054 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);
00055 static struct ast_variable *realtime_sqlite3(const char *database, const char *table, va_list ap);
00056 static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, va_list ap);
00057 static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
00058 static int realtime_sqlite3_update2(const char *database, const char *table, va_list ap);
00059 static int realtime_sqlite3_store(const char *database, const char *table, va_list ap);
00060 static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
00061 static int realtime_sqlite3_require(const char *database, const char *table, va_list ap);
00062 static int realtime_sqlite3_unload(const char *database, const char *table);
00063 
00064 struct ast_config_engine sqlite3_config_engine = {
00065    .name = "sqlite3",
00066    .load_func = realtime_sqlite3_load,
00067    .realtime_func = realtime_sqlite3,
00068    .realtime_multi_func = realtime_sqlite3_multi,
00069    .update_func = realtime_sqlite3_update,
00070    .update2_func = realtime_sqlite3_update2,
00071    .store_func = realtime_sqlite3_store,
00072    .destroy_func = realtime_sqlite3_destroy,
00073    .require_func = realtime_sqlite3_require,
00074    .unload_func = realtime_sqlite3_unload,
00075 };
00076 
00077 enum {
00078    REALTIME_SQLITE3_REQ_WARN,
00079    REALTIME_SQLITE3_REQ_CLOSE,
00080    REALTIME_SQLITE3_REQ_CHAR,
00081 };
00082 
00083 struct realtime_sqlite3_db {
00084    AST_DECLARE_STRING_FIELDS(
00085       AST_STRING_FIELD(name);
00086       AST_STRING_FIELD(filename);
00087    );
00088    sqlite3 *handle;
00089    pthread_t syncthread;
00090    ast_cond_t cond;
00091    unsigned int requirements:2;
00092    unsigned int dirty:1;
00093    unsigned int debug:1;
00094    unsigned int exiting:1;
00095    unsigned int wakeup:1;
00096    unsigned int batch;
00097 };
00098 
00099 struct ao2_container *databases;
00100 #define DB_BUCKETS 7
00101 
00102 AST_MUTEX_DEFINE_STATIC(config_lock);
00103 
00104 /* We need a separate buffer for each field we might use concurrently */
00105 AST_THREADSTORAGE(escape_table_buf);
00106 AST_THREADSTORAGE(escape_column_buf);
00107 AST_THREADSTORAGE(escape_value_buf);
00108 
00109 static int realtime_sqlite3_execute_handle(struct realtime_sqlite3_db *db, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync);
00110 void db_start_batch(struct realtime_sqlite3_db *db);
00111 void db_stop_batch(struct realtime_sqlite3_db *db);
00112 
00113 static inline const char *sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)
00114 {
00115    size_t maxlen = strlen(param) * 2 + sizeof("\"\"");
00116    /* It doesn't appear that sqlite3_snprintf will do more than double the
00117     * length of a string with %q as an option. %Q could double and possibly
00118     * add two quotes, and convert NULL pointers to the word "NULL", but we
00119     * don't allow those anyway. Just going to use %q for now. */
00120    struct ast_str *buf = ast_str_thread_get(ts, maxlen);
00121    char *tmp = ast_str_buffer(buf);
00122    char q = ts == &escape_value_buf ? '\'' : '"';
00123 
00124    ast_str_reset(buf);
00125    *tmp++ = q; /* Initial quote */
00126    while ((*tmp++ = *param++)) {
00127       /* Did we just copy a quote? Then double it. */
00128       if (*(tmp - 1) == q) {
00129          *tmp++ = q;
00130       }
00131    }
00132    *tmp = '\0'; /* Terminate past NULL from copy */
00133    *(tmp - 1) = q; /* Replace original NULL with the quote */
00134    ast_str_update(buf);
00135 
00136    return ast_str_buffer(buf);
00137 }
00138 
00139 static inline const char *sqlite3_escape_table(const char *param)
00140 {
00141    return sqlite3_escape_string_helper(&escape_table_buf, param);
00142 }
00143 
00144 static inline const char *sqlite3_escape_column(const char *param)
00145 {
00146    return sqlite3_escape_string_helper(&escape_column_buf, param);
00147 }
00148 
00149 /* Not inlining this function because it uses strdupa and I don't know if the compiler would be dumb */
00150 static const char *sqlite3_escape_column_op(const char *param)
00151 {
00152    size_t maxlen = strlen(param) * 2 + sizeof("\"\" =");
00153    struct ast_str *buf = ast_str_thread_get(&escape_column_buf, maxlen);
00154    char *tmp = ast_str_buffer(buf);
00155    int space = 0;
00156 
00157    ast_str_reset(buf);
00158    *tmp++ = '"';
00159    while ((*tmp++ = *param++)) {
00160       /* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
00161        * available to users via an API, we will definitely need to avoid allowing special
00162        * characters like ';' in the data past the space as it will be unquoted data */
00163       if (space) {
00164          continue;
00165       }
00166       if (*(tmp - 1) == ' ') {
00167          *(tmp - 1) = '"';
00168          *tmp++ = ' ';
00169          space = 1;
00170       } else if (*(tmp - 1) == '"') {
00171          *tmp++ = '"';
00172       }
00173    }
00174    if (!space) {
00175       strcpy(tmp - 1, "\" =");
00176    }
00177 
00178    ast_str_update(buf);
00179 
00180    return ast_str_buffer(buf);
00181 }
00182 
00183 static inline const char *sqlite3_escape_value(const char *param)
00184 {
00185    return sqlite3_escape_string_helper(&escape_value_buf, param);
00186 }
00187 
00188 static int db_hash_fn(const void *obj, const int flags)
00189 {
00190    const struct realtime_sqlite3_db *db = obj;
00191 
00192    return ast_str_hash(flags & OBJ_KEY ? (const char *) obj : db->name);
00193 }
00194 
00195 static int db_cmp_fn(void *obj, void *arg, int flags) {
00196    struct realtime_sqlite3_db *db = obj, *other = arg;
00197    const char *name = arg;
00198 
00199    return !strcasecmp(db->name, flags & OBJ_KEY ? name : other->name) ? CMP_MATCH | CMP_STOP : 0;
00200 }
00201 
00202 static void db_destructor(void *obj)
00203 {
00204    struct realtime_sqlite3_db *db = obj;
00205 
00206    ast_debug(1, "Destroying db: %s\n", db->name);
00207    ast_string_field_free_memory(db);
00208    db_stop_batch(db);
00209    if (db->handle) {
00210       ao2_lock(db);
00211       sqlite3_close(db->handle);
00212       ao2_unlock(db);
00213    }
00214 }
00215 
00216 static struct realtime_sqlite3_db *find_database(const char *database)
00217 {
00218    return ao2_find(databases, database, OBJ_KEY);
00219 }
00220 
00221 static void unref_db(struct realtime_sqlite3_db **db)
00222 {
00223    ao2_ref(*db, -1);
00224    *db = NULL;
00225 }
00226 
00227 static int stop_batch_cb(void *obj, void *arg, int flags)
00228 {
00229    struct realtime_sqlite3_db *db = obj;
00230 
00231    db_stop_batch(db);
00232    return CMP_MATCH;
00233 }
00234 
00235 static int mark_dirty_cb(void *obj, void *arg, int flags)
00236 {
00237    struct realtime_sqlite3_db *db = obj;
00238    db->dirty = 1;
00239    return CMP_MATCH;
00240 }
00241 
00242 static void mark_all_databases_dirty(void)
00243 {
00244    ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA, mark_dirty_cb, NULL);
00245 }
00246 
00247 static int is_dirty_cb(void *obj, void *arg, int flags)
00248 {
00249    struct realtime_sqlite3_db *db = obj;
00250    if (db->dirty) {
00251       db_stop_batch(db);
00252       return CMP_MATCH;
00253    }
00254    return 0;
00255 }
00256 
00257 static void unlink_dirty_databases(void)
00258 {
00259    ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, is_dirty_cb, NULL);
00260 }
00261 
00262 static int str_to_requirements(const char *data)
00263 {
00264    if (!strcasecmp(data, "createclose")) {
00265       return REALTIME_SQLITE3_REQ_CLOSE;
00266    } else if (!strcasecmp(data, "createchar")) {
00267       return REALTIME_SQLITE3_REQ_CHAR;
00268    }
00269    /* default */
00270    return REALTIME_SQLITE3_REQ_WARN;
00271 }
00272 
00273 /*! \note Since this is called while a query is executing, we should already hold the db lock */
00274 static void trace_cb(void *arg, const char *sql)
00275 {
00276    struct realtime_sqlite3_db *db = arg;
00277    ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
00278 }
00279 
00280 /*! \brief Wrap commands in transactions increased write performance */
00281 static void *db_sync_thread(void *data)
00282 {
00283    struct realtime_sqlite3_db *db = data;
00284    ao2_lock(db);
00285    realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
00286    for (;;) {
00287       if (!db->wakeup) {
00288          ast_cond_wait(&db->cond, ao2_object_get_lockaddr(db));
00289       }
00290       db->wakeup = 0;
00291       if (realtime_sqlite3_execute_handle(db, "COMMIT", NULL, NULL, 0) < 0) {
00292          realtime_sqlite3_execute_handle(db, "ROLLBACK", NULL, NULL, 0);
00293       }
00294       if (db->exiting) {
00295          ao2_unlock(db);
00296          break;
00297       }
00298       realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
00299       ao2_unlock(db);
00300       usleep(1000 * db->batch);
00301       ao2_lock(db);
00302    }
00303 
00304    unref_db(&db);
00305 
00306    return NULL;
00307 }
00308 
00309 /*! \brief Open a database and appropriately set debugging on the db handle */
00310 static int db_open(struct realtime_sqlite3_db *db)
00311 {
00312    ao2_lock(db);
00313    if (sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
00314       ast_log(LOG_WARNING, "Could not open %s: %s\n", db->filename, sqlite3_errmsg(db->handle));
00315       ao2_unlock(db);
00316       return -1;
00317    }
00318 
00319    if (db->debug) {
00320       sqlite3_trace(db->handle, trace_cb, db);
00321    } else {
00322       sqlite3_trace(db->handle, NULL, NULL);
00323    }
00324 
00325    ao2_unlock(db);
00326 
00327    return 0;
00328 }
00329 
00330 static void db_sync(struct realtime_sqlite3_db *db)
00331 {
00332    db->wakeup = 1;
00333    ast_cond_signal(&db->cond);
00334 }
00335 
00336 void db_start_batch(struct realtime_sqlite3_db *db)
00337 {
00338    if (db->batch) {
00339       ast_cond_init(&db->cond, NULL);
00340       ao2_ref(db, +1);
00341       ast_pthread_create_background(&db->syncthread, NULL, db_sync_thread, db);
00342    }
00343 }
00344 
00345 void db_stop_batch(struct realtime_sqlite3_db *db)
00346 {
00347    if (db->batch) {
00348       db->exiting = 1;
00349       db_sync(db);
00350       pthread_join(db->syncthread, NULL);
00351    }
00352 }
00353 
00354 /*! \brief Create a db object based on a config category
00355  * \note Opening the db handle and linking to databases must be handled outside of this function
00356  */
00357 static struct realtime_sqlite3_db *new_realtime_sqlite3_db(struct ast_config *config, const char *cat)
00358 {
00359    struct ast_variable *var;
00360    struct realtime_sqlite3_db *db;
00361 
00362    if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
00363       return NULL;
00364    }
00365 
00366    if (ast_string_field_init(db, 64)) {
00367       unref_db(&db);
00368       return NULL;
00369    }
00370 
00371    /* Set defaults */
00372    db->requirements = REALTIME_SQLITE3_REQ_WARN;
00373    db->batch = 100;
00374    ast_string_field_set(db, name, cat);
00375 
00376    for (var = ast_variable_browse(config, cat); var; var = var->next) {
00377       if (!strcasecmp(var->name, "dbfile")) {
00378          ast_string_field_set(db, filename, var->value);
00379       } else if (!strcasecmp(var->name, "requirements")) {
00380          db->requirements = str_to_requirements(var->value);
00381       } else if (!strcasecmp(var->name, "batch")) {
00382          ast_app_parse_timelen(var->value, (int *) &db->batch, TIMELEN_MILLISECONDS);
00383       } else if (!strcasecmp(var->name, "debug")) {
00384          db->debug = ast_true(var->value);
00385       }
00386    }
00387 
00388    if (ast_strlen_zero(db->filename)) {
00389       ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
00390       unref_db(&db);
00391       return NULL;
00392    }
00393 
00394    return db;
00395 }
00396 
00397 /*! \brief Update an existing db object based on config data
00398  * \param db The database object to update
00399  * \param config The configuration data with which to update the db
00400  * \param cat The config category (which becomes db->name)
00401  */
00402 static int update_realtime_sqlite3_db(struct realtime_sqlite3_db *db, struct ast_config *config, const char *cat)
00403 {
00404    struct realtime_sqlite3_db *new;
00405 
00406    if (!(new = new_realtime_sqlite3_db(config, cat))) {
00407       return -1;
00408    }
00409 
00410    /* Copy fields that don't need anything special done on change */
00411    db->requirements = new->requirements;
00412 
00413    /* Handle changes that require immediate behavior modification */
00414    if (db->debug != new->debug) {
00415       if (db->debug) {
00416          sqlite3_trace(db->handle, NULL, NULL);
00417       } else {
00418          sqlite3_trace(db->handle, trace_cb, db);
00419       }
00420       db->debug = new->debug;
00421    }
00422 
00423    if (strcmp(db->filename, new->filename)) {
00424       sqlite3_close(db->handle);
00425       ast_string_field_set(db, filename, new->filename);
00426       db_open(db); /* Also handles setting appropriate debug on new handle */
00427    }
00428 
00429    if (db->batch != new->batch) {
00430       if (db->batch == 0) {
00431          db->batch = new->batch;
00432          db_start_batch(db);
00433       } else if (new->batch == 0) {
00434          db->batch = new->batch;
00435          db_stop_batch(db);
00436       }
00437       db->batch = new->batch;
00438    }
00439 
00440    db->dirty = 0;
00441    unref_db(&new);
00442 
00443    return 0;
00444 }
00445 
00446 /*! \brief Create a varlist from a single sqlite3 result row */
00447 static int row_to_varlist(void *arg, int num_columns, char **values, char **columns)
00448 {
00449    struct ast_variable **head = arg, *tail;
00450    int i;
00451    struct ast_variable *new;
00452 
00453    if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
00454       return SQLITE_ABORT;
00455    }
00456    *head = tail = new;
00457 
00458    for (i = 1; i < num_columns; i++) {
00459       if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
00460          ast_variables_destroy(*head);
00461          *head = NULL;
00462          return SQLITE_ABORT;
00463       }
00464       tail->next = new;
00465       tail = new;
00466    }
00467 
00468    return 0;
00469 }
00470 
00471 /*! \brief Callback for creating an ast_config from a successive sqlite3 result rows */
00472 static int append_row_to_cfg(void *arg, int num_columns, char **values, char **columns)
00473 {
00474    struct ast_config *cfg = arg;
00475    struct ast_category *cat;
00476    int i;
00477 
00478    if (!(cat = ast_category_new("", "", 99999))) {
00479       return SQLITE_ABORT;
00480    }
00481 
00482    for (i = 0; i < num_columns; i++) {
00483       struct ast_variable *var;
00484       if (!(var = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
00485          ast_log(LOG_ERROR, "Could not create new variable for '%s: %s', throwing away list\n", columns[i], values[i]);
00486          continue;
00487       }
00488       ast_variable_append(cat, var);
00489    }
00490    ast_category_append(cfg, cat);
00491 
00492    return 0;
00493 }
00494 
00495 /*!
00496  * Structure sent to the SQLite 3 callback function for static configuration.
00497  *
00498  * \see static_realtime_cb()
00499  */
00500 struct cfg_entry_args {
00501    struct ast_config *cfg;
00502    struct ast_category *cat;
00503    char *cat_name;
00504    struct ast_flags flags;
00505    const char *who_asked;
00506 };
00507 
00508 /*! Exeute an SQL statement given the database object
00509  *
00510  * \retval -1 ERROR
00511  * \retval > -1 Number of rows changed
00512  */
00513 static int realtime_sqlite3_execute_handle(struct realtime_sqlite3_db *db, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync)
00514 {
00515    int res = 0;
00516    char *errmsg;
00517 
00518    ao2_lock(db);
00519    if (sqlite3_exec(db->handle, sql, callback, arg, &errmsg) != SQLITE_OK) {
00520       ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
00521       sqlite3_free(errmsg);
00522       res = -1;
00523    } else {
00524       res = sqlite3_changes(db->handle);
00525    }
00526    ao2_unlock(db);
00527 
00528    if (sync) {
00529       db_sync(db);
00530    }
00531 
00532    return res;
00533 }
00534 
00535 /*! Exeute an SQL statement give the database name
00536  *
00537  * \retval -1 ERROR
00538  * \retval > -1 Number of rows changed
00539  */
00540 static int realtime_sqlite3_execute(const char *database, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync)
00541 {
00542    struct realtime_sqlite3_db *db;
00543    int res;
00544 
00545    if (!(db = find_database(database))) {
00546       ast_log(LOG_WARNING, "Could not find database: %s\n", database);
00547       return -1;
00548    }
00549 
00550    res = realtime_sqlite3_execute_handle(db, sql, callback, arg, sync);
00551    ao2_ref(db, -1);
00552 
00553    return res;
00554 }
00555 
00556 /*! \note It is important that the COL_* enum matches the order of the columns selected in static_sql */
00557 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";
00558 enum {
00559    COL_CATEGORY,
00560    COL_VAR_NAME,
00561    COL_VAR_VAL,
00562    COL_COLUMNS,
00563 };
00564 
00565 static int static_realtime_cb(void *arg, int num_columns, char **values, char **columns)
00566 {
00567    struct cfg_entry_args *args = arg;
00568    struct ast_variable *var;
00569 
00570    if (!strcmp(values[COL_VAR_NAME], "#include")) {
00571       struct ast_config *cfg;
00572       char *val;
00573 
00574       val = values[COL_VAR_VAL];
00575       if (!(cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked))) {
00576          ast_log(LOG_WARNING, "Unable to include %s\n", val);
00577          return SQLITE_ABORT;
00578       } else {
00579          args->cfg = cfg;
00580          return 0;
00581       }
00582    }
00583 
00584    if (!args->cat_name || strcmp(args->cat_name, values[COL_CATEGORY])) {
00585       if (!(args->cat = ast_category_new(values[COL_CATEGORY], "", 99999))) {
00586          ast_log(LOG_WARNING, "Unable to allocate category\n");
00587          return SQLITE_ABORT;
00588       }
00589 
00590       ast_free(args->cat_name);
00591 
00592       if (!(args->cat_name = ast_strdup(values[COL_CATEGORY]))) {
00593          ast_category_destroy(args->cat);
00594          return SQLITE_ABORT;
00595       }
00596 
00597       ast_category_append(args->cfg, args->cat);
00598    }
00599 
00600    if (!(var = ast_variable_new(values[COL_VAR_NAME], values[COL_VAR_VAL], ""))) {
00601       ast_log(LOG_WARNING, "Unable to allocate variable\n");
00602       return SQLITE_ABORT;
00603    }
00604 
00605    ast_variable_append(args->cat, var);
00606 
00607    return 0;
00608 }
00609 
00610 /*! \brief Realtime callback for static realtime
00611  * \return ast_config on success, NULL on failure
00612  */
00613 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)
00614 {
00615    char *sql;
00616    struct cfg_entry_args args;
00617 
00618    if (ast_strlen_zero(table)) {
00619       ast_log(LOG_WARNING, "Must have a table to query!\n");
00620       return NULL;
00621    }
00622 
00623    if (!(sql = sqlite3_mprintf(static_sql, table, configfile))) {
00624       ast_log(LOG_WARNING, "Couldn't allocate query\n");
00625       return NULL;
00626    };
00627 
00628    args.cfg = config;
00629    args.cat = NULL;
00630    args.cat_name = NULL;
00631    args.flags = flags;
00632    args.who_asked = who_asked;
00633 
00634    realtime_sqlite3_execute(database, sql, static_realtime_cb, &args, 0);
00635 
00636    sqlite3_free(sql);
00637 
00638    return config;
00639 }
00640 
00641 /*! \brief Helper function for single and multi-row realtime load functions */
00642 static int realtime_sqlite3_helper(const char *database, const char *table, va_list ap, int is_multi, void *arg)
00643 {
00644    struct ast_str *sql;
00645    const char *param, *value;
00646    int first = 1;
00647 
00648    if (ast_strlen_zero(table)) {
00649       ast_log(LOG_WARNING, "Must have a table to query!\n");
00650       return -1;
00651    }
00652 
00653    if (!(sql = ast_str_create(128))) {
00654       return -1;
00655    }
00656 
00657    while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00658       if (first) {
00659          ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
00660                sqlite3_escape_column_op(param), sqlite3_escape_value(value));
00661          first = 0;
00662       } else {
00663          ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param),
00664                sqlite3_escape_value(value));
00665       }
00666    }
00667 
00668    if (!is_multi) {
00669       ast_str_append(&sql, 0, "%s", " LIMIT 1");
00670    }
00671 
00672    if (realtime_sqlite3_execute(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg, 0) < 0) {
00673       ast_free(sql);
00674       return -1;
00675    }
00676 
00677    ast_free(sql);
00678 
00679    return 0;
00680 }
00681 
00682 /*! \brief Realtime callback for a single row query
00683  * \return ast_variable list for single result on success, NULL on empty/failure
00684  */
00685 static struct ast_variable *realtime_sqlite3(const char *database, const char *table, va_list ap)
00686 {
00687    struct ast_variable *result_row = NULL;
00688 
00689    realtime_sqlite3_helper(database, table, ap, 0, &result_row);
00690 
00691    return result_row;
00692 }
00693 
00694 /*! \brief Realtime callback for a multi-row query
00695  * \return ast_config containing possibly many results on success, NULL on empty/failure
00696  */
00697 static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, va_list ap)
00698 {
00699    struct ast_config *cfg;
00700 
00701    if (!(cfg = ast_config_new())) {
00702       return NULL;
00703    }
00704 
00705    if (realtime_sqlite3_helper(database, table, ap, 1, cfg)) {
00706       ast_config_destroy(cfg);
00707       return NULL;
00708    }
00709 
00710    return cfg;
00711 }
00712 
00713 /*! \brief Realtime callback for updating a row based on a single criteria
00714  * \return Number of rows affected or -1 on error
00715  */
00716 static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
00717 {
00718    struct ast_str *sql;
00719    const char *key, *value;
00720    int first = 1, res;
00721 
00722    if (ast_strlen_zero(table)) {
00723       ast_log(LOG_WARNING, "Must have a table to query!\n");
00724       return -1;
00725    }
00726 
00727    if (!(sql = ast_str_create(128))) {
00728       return -1;
00729    }
00730 
00731    while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00732       if (first) {
00733          ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
00734                sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
00735          first = 0;
00736       } else {
00737          ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
00738       }
00739    }
00740 
00741    ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));
00742 
00743    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00744    ast_free(sql);
00745 
00746    return res;
00747 }
00748 
00749 /*! \brief Realtime callback for updating a row based on multiple criteria
00750  * \return Number of rows affected or -1 on error
00751  */
00752 static int realtime_sqlite3_update2(const char *database, const char *table, va_list ap)
00753 {
00754    struct ast_str *sql;
00755    struct ast_str *where_clause;
00756    const char *key, *value;
00757    int first = 1, res;
00758 
00759    if (ast_strlen_zero(table)) {
00760       ast_log(LOG_WARNING, "Must have a table to query!\n");
00761       return -1;
00762    }
00763 
00764    if (!(sql = ast_str_create(128))) {
00765       return -1;
00766    }
00767 
00768    if (!(where_clause = ast_str_create(128))) {
00769       ast_free(sql);
00770       return -1;
00771    }
00772 
00773    while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00774       if (first) {
00775          ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
00776          first = 0;
00777       } else {
00778          ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
00779       }
00780    }
00781 
00782    first = 1;
00783    while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00784       if (first) {
00785          ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
00786          first = 0;
00787       } else {
00788          ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
00789       }
00790    }
00791 
00792    ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));
00793 
00794    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00795 
00796    ast_free(sql);
00797    ast_free(where_clause);
00798 
00799    return res;
00800 }
00801 
00802 /*! \brief Realtime callback for inserting a row
00803  * \return Number of rows affected or -1 on error
00804  */
00805 static int realtime_sqlite3_store(const char *database, const char *table, va_list ap)
00806 {
00807    struct ast_str *sql, *values;
00808    const char *column, *value;
00809    int first = 1, res;
00810 
00811    if (ast_strlen_zero(table)) {
00812       ast_log(LOG_WARNING, "Must have a table to query!\n");
00813       return -1;
00814    }
00815 
00816    if (!(sql = ast_str_create(128))) {
00817       return -1;
00818    }
00819 
00820    if (!(values = ast_str_create(128))) {
00821       ast_free(sql);
00822       return -1;
00823    }
00824 
00825    while ((column = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00826       if (first) {
00827          ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(column));
00828          ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(value));
00829          first = 0;
00830       } else {
00831          ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(column));
00832          ast_str_append(&values, 0, ", %s", sqlite3_escape_value(value));
00833       }
00834    }
00835 
00836    ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));
00837 
00838    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00839 
00840    ast_free(sql);
00841    ast_free(values);
00842 
00843    return res;
00844 }
00845 
00846 /*! \brief Realtime callback for deleting a row
00847  * \return Number of rows affected or -1 on error
00848  */
00849 static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
00850 {
00851    struct ast_str *sql;
00852    const char *param, *value;
00853    int first = 1, res;
00854 
00855    if (ast_strlen_zero(table)) {
00856       ast_log(LOG_WARNING, "Must have a table to query!\n");
00857       return -1;
00858    }
00859 
00860    if (!(sql = ast_str_create(128))) {
00861       return -1;
00862    }
00863 
00864    while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00865       if (first) {
00866          ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
00867                sqlite3_escape_column_op(param), sqlite3_escape_value(value));
00868          first = 0;
00869       } else {
00870          ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param), sqlite3_escape_value(value));
00871       }
00872    }
00873 
00874    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00875 
00876    ast_free(sql);
00877 
00878    return res;
00879 }
00880 
00881 /*! \brief Convert Asterisk realtime types to SQLite 3 types
00882  * \note SQLite 3 has NULL, INTEGER, REAL, TEXT, and BLOB types. Any column other than
00883  * an INTEGER PRIMARY KEY will actually store any kind of data due to its dynamic
00884  * typing. When we create columns, we'll go ahead and use these base types instead
00885  * of messing with column widths, etc. */
00886 
00887 static const char *get_sqlite_column_type(int type)
00888 {
00889    switch(type) {
00890    case RQ_INTEGER1 :
00891    case RQ_UINTEGER1 :
00892    case RQ_INTEGER2 :
00893    case RQ_UINTEGER2 :
00894    case RQ_INTEGER3 :
00895    case RQ_UINTEGER3 :
00896    case RQ_INTEGER4 :
00897    case RQ_UINTEGER4 :
00898    case RQ_INTEGER8 :
00899       return "INTEGER";
00900    case RQ_UINTEGER8 : /* SQLite3 stores INTEGER as signed 8-byte */
00901    case RQ_CHAR :
00902    case RQ_DATE :
00903    case RQ_DATETIME :
00904       return "TEXT";
00905    case RQ_FLOAT :
00906       return "REAL";
00907    default :
00908       return "TEXT";
00909    }
00910 
00911    return "TEXT";
00912 }
00913 
00914 /*! \brief Create a table if ast_realtime_require shows that we are configured to handle the data
00915  */
00916 static int handle_missing_table(struct realtime_sqlite3_db *db, const char *table, va_list ap)
00917 {
00918    const char *column;
00919    int type, first = 1, res;
00920    size_t sz;
00921    struct ast_str *sql;
00922 
00923    if (!(sql = ast_str_create(128))) {
00924       return -1;
00925    }
00926 
00927    while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
00928       if (first) {
00929          ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
00930                sqlite3_escape_column(column), get_sqlite_column_type(type));
00931          first = 0;
00932       } else {
00933          ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
00934       }
00935    }
00936 
00937    ast_str_append(&sql, 0, ")");
00938 
00939    res = realtime_sqlite3_execute_handle(db, ast_str_buffer(sql), NULL, NULL, 1) < 0 ? -1 : 0;
00940    ast_free(sql);
00941 
00942    return res;
00943 }
00944 
00945 /*! \brief If ast_realtime_require sends info about a column we don't have, create it
00946  */
00947 static int handle_missing_column(struct realtime_sqlite3_db *db, const char *table, const char *column, int type, size_t sz)
00948 {
00949    char *sql;
00950    const char *sqltype = get_sqlite_column_type(type);
00951    int res;
00952 
00953    if (db->requirements == REALTIME_SQLITE3_REQ_WARN) {
00954       ast_log(LOG_WARNING, "Missing column '%s' of type '%s' in %s.%s\n", column, sqltype, db->name, table);
00955       return -1;
00956    } else if (db->requirements == REALTIME_SQLITE3_REQ_CHAR) {
00957       sqltype = "TEXT";
00958    }
00959 
00960    if (!(sql = sqlite3_mprintf("ALTER TABLE \"%q\" ADD COLUMN \"%q\" %s", table, column, sqltype))) {
00961       return -1;
00962    }
00963 
00964    if (!(res = (realtime_sqlite3_execute_handle(db, sql, NULL, NULL, 1) < 0 ? -1 : 0))) {
00965       ast_log(LOG_NOTICE, "Creating column '%s' type %s for table %s\n", column, sqltype, table);
00966    }
00967 
00968    sqlite3_free(sql);
00969 
00970    return res;
00971 }
00972 
00973 static int str_hash_fn(const void *obj, const int flags)
00974 {
00975    return ast_str_hash((const char *) obj);
00976 }
00977 
00978 static int str_cmp_fn(void *obj, void *arg, int flags) {
00979    return !strcasecmp((const char *) obj, (const char *) arg);
00980 }
00981 
00982 /*! \brief Callback for creating a hash of column names for comparison in realtime_sqlite3_require
00983  */
00984 static int add_column_name(void *arg, int num_columns, char **values, char **columns)
00985 {
00986    char *column;
00987    struct ao2_container *cnames = arg;
00988 
00989 
00990    if (!(column = ao2_alloc(strlen(values[1]) + 1, NULL))) {
00991       return -1;
00992    }
00993 
00994    strcpy(column, values[1]);
00995 
00996    ao2_link(cnames, column);
00997    ao2_ref(column, -1);
00998 
00999    return 0;
01000 }
01001 
01002 /*! \brief Callback for ast_realtime_require
01003  * \retval 0 Required fields met specified standards
01004  * \retval -1 One or more fields was missing or insufficient
01005  */
01006 static int realtime_sqlite3_require(const char *database, const char *table, va_list ap)
01007 {
01008    const char *column;
01009    char *sql;
01010    int type;
01011    int res;
01012    size_t sz;
01013    struct ao2_container *columns;
01014    struct realtime_sqlite3_db *db;
01015 
01016    /* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
01017     * return the results as char * anyway. The only field that that cannot contain text
01018     * data is an INTEGER PRIMARY KEY, which must be a 64-bit signed integer. So, for
01019     * the purposes here we really only care whether the column exists and not what its
01020     * type or length is. */
01021 
01022    if (ast_strlen_zero(table)) {
01023       ast_log(LOG_WARNING, "Must have a table to query!\n");
01024       return -1;
01025    }
01026 
01027    if (!(db = find_database(database))) {
01028       return -1;
01029    }
01030 
01031    if (!(columns = ao2_container_alloc(31, str_hash_fn, str_cmp_fn))) {
01032       unref_db(&db);
01033       return -1;
01034    }
01035 
01036    if (!(sql = sqlite3_mprintf("PRAGMA table_info(\"%q\")", table))) {
01037       unref_db(&db);
01038       ao2_ref(columns, -1);
01039       return -1;
01040    }
01041 
01042    if ((res = realtime_sqlite3_execute_handle(db, sql, add_column_name, columns, 0)) < 0) {
01043       unref_db(&db);
01044       ao2_ref(columns, -1);
01045       sqlite3_free(sql);
01046       return -1;
01047    } else if (res == 0) {
01048       /* Table does not exist */
01049       sqlite3_free(sql);
01050       res = handle_missing_table(db, table, ap);
01051       ao2_ref(columns, -1);
01052       unref_db(&db);
01053       return res;
01054    }
01055 
01056    sqlite3_free(sql);
01057 
01058    while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
01059       char *found;
01060       if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
01061          if (handle_missing_column(db, table, column, type, sz)) {
01062             unref_db(&db);
01063             ao2_ref(columns, -1);
01064             return -1;
01065          }
01066       } else {
01067          ao2_ref(found, -1);
01068       }
01069    }
01070 
01071    ao2_ref(columns, -1);
01072    unref_db(&db);
01073 
01074    return 0;
01075 }
01076 
01077 /*! \brief Callback for clearing any cached info
01078  * \note We don't currently cache anything
01079  * \retval 0 If any cache was purged
01080  * \retval -1 If no cache was found
01081  */
01082 static int realtime_sqlite3_unload(const char *database, const char *table)
01083 {
01084    /* We currently do no caching */
01085    return -1;
01086 }
01087 
01088 /*! \brief Parse the res_config_sqlite3 config file
01089  */
01090 static int parse_config(int reload)
01091 {
01092    struct ast_config *config;
01093    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME | (reload ? CONFIG_FLAG_FILEUNCHANGED : 0) };
01094    static const char *config_filename = "res_config_sqlite3.conf";
01095 
01096    config = ast_config_load(config_filename, config_flags);
01097 
01098    if (config == CONFIG_STATUS_FILEUNCHANGED) {
01099       ast_debug(1, "%s was unchanged, skipping parsing\n", config_filename);
01100       return 0;
01101    }
01102 
01103    ast_mutex_lock(&config_lock);
01104 
01105    if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
01106       ast_log(LOG_ERROR, "%s config file '%s'\n",
01107          config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
01108    } else {
01109       const char *cat;
01110       struct realtime_sqlite3_db *db;
01111 
01112       mark_all_databases_dirty();
01113       for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
01114          if (!strcasecmp(cat, "general")) {
01115             continue;
01116          }
01117          if (!(db = find_database(cat))) {
01118             if (!(db = new_realtime_sqlite3_db(config, cat))) {
01119                ast_log(LOG_WARNING, "Could not allocate new db for '%s' - skipping.\n", cat);
01120                continue;
01121             }
01122             if (db_open(db)) {
01123                unref_db(&db);
01124                continue;
01125             }
01126             db_start_batch(db);
01127             ao2_link(databases, db);
01128             unref_db(&db);
01129          } else  {
01130             if (update_realtime_sqlite3_db(db, config, cat)) {
01131                unref_db(&db);
01132                continue;
01133             }
01134             unref_db(&db);
01135          }
01136       }
01137       unlink_dirty_databases();
01138    }
01139 
01140    ast_mutex_unlock(&config_lock);
01141 
01142    ast_config_destroy(config);
01143 
01144    return 0;
01145 }
01146 
01147 static int reload(void)
01148 {
01149    parse_config(1);
01150    return 0;
01151 }
01152 
01153 static int unload_module(void)
01154 {
01155    ast_mutex_lock(&config_lock);
01156    ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, stop_batch_cb, NULL);
01157    ao2_ref(databases, -1);
01158    databases = NULL;
01159    ast_config_engine_deregister(&sqlite3_config_engine);
01160    ast_mutex_unlock(&config_lock);
01161 
01162    return 0;
01163 }
01164 
01165 static int load_module(void)
01166 {
01167    if (!((databases = ao2_container_alloc(DB_BUCKETS, db_hash_fn, db_cmp_fn)))) {
01168       return AST_MODULE_LOAD_FAILURE;
01169    }
01170 
01171    if (parse_config(0)) {
01172       ao2_ref(databases, -1);
01173       return AST_MODULE_LOAD_FAILURE;
01174    }
01175 
01176    if (!(ast_config_engine_register(&sqlite3_config_engine))) {
01177       ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
01178       ao2_ref(databases, -1);
01179       return AST_MODULE_LOAD_FAILURE;
01180    }
01181 
01182    return AST_MODULE_LOAD_SUCCESS;
01183 }
01184 
01185 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SQLite 3 realtime config engine",
01186    .load = load_module,
01187    .unload = unload_module,
01188    .reload = reload,
01189    .load_pri = AST_MODPRI_REALTIME_DRIVER,
01190 );