Sat Jul 12 2014 17:18:36

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: 416337 $")
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    sqlite3_busy_timeout(db->handle, 1000);
00319 
00320    if (db->debug) {
00321       sqlite3_trace(db->handle, trace_cb, db);
00322    } else {
00323       sqlite3_trace(db->handle, NULL, NULL);
00324    }
00325 
00326    ao2_unlock(db);
00327 
00328    return 0;
00329 }
00330 
00331 static void db_sync(struct realtime_sqlite3_db *db)
00332 {
00333    db->wakeup = 1;
00334    ast_cond_signal(&db->cond);
00335 }
00336 
00337 void db_start_batch(struct realtime_sqlite3_db *db)
00338 {
00339    if (db->batch) {
00340       ast_cond_init(&db->cond, NULL);
00341       ao2_ref(db, +1);
00342       ast_pthread_create_background(&db->syncthread, NULL, db_sync_thread, db);
00343    }
00344 }
00345 
00346 void db_stop_batch(struct realtime_sqlite3_db *db)
00347 {
00348    if (db->batch) {
00349       db->exiting = 1;
00350       db_sync(db);
00351       pthread_join(db->syncthread, NULL);
00352    }
00353 }
00354 
00355 /*! \brief Create a db object based on a config category
00356  * \note Opening the db handle and linking to databases must be handled outside of this function
00357  */
00358 static struct realtime_sqlite3_db *new_realtime_sqlite3_db(struct ast_config *config, const char *cat)
00359 {
00360    struct ast_variable *var;
00361    struct realtime_sqlite3_db *db;
00362 
00363    if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
00364       return NULL;
00365    }
00366 
00367    if (ast_string_field_init(db, 64)) {
00368       unref_db(&db);
00369       return NULL;
00370    }
00371 
00372    /* Set defaults */
00373    db->requirements = REALTIME_SQLITE3_REQ_WARN;
00374    db->batch = 100;
00375    ast_string_field_set(db, name, cat);
00376 
00377    for (var = ast_variable_browse(config, cat); var; var = var->next) {
00378       if (!strcasecmp(var->name, "dbfile")) {
00379          ast_string_field_set(db, filename, var->value);
00380       } else if (!strcasecmp(var->name, "requirements")) {
00381          db->requirements = str_to_requirements(var->value);
00382       } else if (!strcasecmp(var->name, "batch")) {
00383          ast_app_parse_timelen(var->value, (int *) &db->batch, TIMELEN_MILLISECONDS);
00384       } else if (!strcasecmp(var->name, "debug")) {
00385          db->debug = ast_true(var->value);
00386       }
00387    }
00388 
00389    if (ast_strlen_zero(db->filename)) {
00390       ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
00391       unref_db(&db);
00392       return NULL;
00393    }
00394 
00395    return db;
00396 }
00397 
00398 /*! \brief Update an existing db object based on config data
00399  * \param db The database object to update
00400  * \param config The configuration data with which to update the db
00401  * \param cat The config category (which becomes db->name)
00402  */
00403 static int update_realtime_sqlite3_db(struct realtime_sqlite3_db *db, struct ast_config *config, const char *cat)
00404 {
00405    struct realtime_sqlite3_db *new;
00406 
00407    if (!(new = new_realtime_sqlite3_db(config, cat))) {
00408       return -1;
00409    }
00410 
00411    /* Copy fields that don't need anything special done on change */
00412    db->requirements = new->requirements;
00413 
00414    /* Handle changes that require immediate behavior modification */
00415    if (db->debug != new->debug) {
00416       if (db->debug) {
00417          sqlite3_trace(db->handle, NULL, NULL);
00418       } else {
00419          sqlite3_trace(db->handle, trace_cb, db);
00420       }
00421       db->debug = new->debug;
00422    }
00423 
00424    if (strcmp(db->filename, new->filename)) {
00425       sqlite3_close(db->handle);
00426       ast_string_field_set(db, filename, new->filename);
00427       db_open(db); /* Also handles setting appropriate debug on new handle */
00428    }
00429 
00430    if (db->batch != new->batch) {
00431       if (db->batch == 0) {
00432          db->batch = new->batch;
00433          db_start_batch(db);
00434       } else if (new->batch == 0) {
00435          db->batch = new->batch;
00436          db_stop_batch(db);
00437       }
00438       db->batch = new->batch;
00439    }
00440 
00441    db->dirty = 0;
00442    unref_db(&new);
00443 
00444    return 0;
00445 }
00446 
00447 /*! \brief Create a varlist from a single sqlite3 result row */
00448 static int row_to_varlist(void *arg, int num_columns, char **values, char **columns)
00449 {
00450    struct ast_variable **head = arg, *tail;
00451    int i;
00452    struct ast_variable *new;
00453 
00454    if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
00455       return SQLITE_ABORT;
00456    }
00457    *head = tail = new;
00458 
00459    for (i = 1; i < num_columns; i++) {
00460       if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
00461          ast_variables_destroy(*head);
00462          *head = NULL;
00463          return SQLITE_ABORT;
00464       }
00465       tail->next = new;
00466       tail = new;
00467    }
00468 
00469    return 0;
00470 }
00471 
00472 /*! \brief Callback for creating an ast_config from a successive sqlite3 result rows */
00473 static int append_row_to_cfg(void *arg, int num_columns, char **values, char **columns)
00474 {
00475    struct ast_config *cfg = arg;
00476    struct ast_category *cat;
00477    int i;
00478 
00479    if (!(cat = ast_category_new("", "", 99999))) {
00480       return SQLITE_ABORT;
00481    }
00482 
00483    for (i = 0; i < num_columns; i++) {
00484       struct ast_variable *var;
00485       if (!(var = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
00486          ast_log(LOG_ERROR, "Could not create new variable for '%s: %s', throwing away list\n", columns[i], values[i]);
00487          continue;
00488       }
00489       ast_variable_append(cat, var);
00490    }
00491    ast_category_append(cfg, cat);
00492 
00493    return 0;
00494 }
00495 
00496 /*!
00497  * Structure sent to the SQLite 3 callback function for static configuration.
00498  *
00499  * \see static_realtime_cb()
00500  */
00501 struct cfg_entry_args {
00502    struct ast_config *cfg;
00503    struct ast_category *cat;
00504    char *cat_name;
00505    struct ast_flags flags;
00506    const char *who_asked;
00507 };
00508 
00509 /*! Exeute an SQL statement given the database object
00510  *
00511  * \retval -1 ERROR
00512  * \retval > -1 Number of rows changed
00513  */
00514 static int realtime_sqlite3_execute_handle(struct realtime_sqlite3_db *db, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync)
00515 {
00516    int res = 0;
00517    char *errmsg;
00518 
00519    ao2_lock(db);
00520    if (sqlite3_exec(db->handle, sql, callback, arg, &errmsg) != SQLITE_OK) {
00521       ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
00522       sqlite3_free(errmsg);
00523       res = -1;
00524    } else {
00525       res = sqlite3_changes(db->handle);
00526    }
00527    ao2_unlock(db);
00528 
00529    if (sync) {
00530       db_sync(db);
00531    }
00532 
00533    return res;
00534 }
00535 
00536 /*! Exeute an SQL statement give the database name
00537  *
00538  * \retval -1 ERROR
00539  * \retval > -1 Number of rows changed
00540  */
00541 static int realtime_sqlite3_execute(const char *database, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync)
00542 {
00543    struct realtime_sqlite3_db *db;
00544    int res;
00545 
00546    if (!(db = find_database(database))) {
00547       ast_log(LOG_WARNING, "Could not find database: %s\n", database);
00548       return -1;
00549    }
00550 
00551    res = realtime_sqlite3_execute_handle(db, sql, callback, arg, sync);
00552    ao2_ref(db, -1);
00553 
00554    return res;
00555 }
00556 
00557 /*! \note It is important that the COL_* enum matches the order of the columns selected in static_sql */
00558 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";
00559 enum {
00560    COL_CATEGORY,
00561    COL_VAR_NAME,
00562    COL_VAR_VAL,
00563    COL_COLUMNS,
00564 };
00565 
00566 static int static_realtime_cb(void *arg, int num_columns, char **values, char **columns)
00567 {
00568    struct cfg_entry_args *args = arg;
00569    struct ast_variable *var;
00570 
00571    if (!strcmp(values[COL_VAR_NAME], "#include")) {
00572       struct ast_config *cfg;
00573       char *val;
00574 
00575       val = values[COL_VAR_VAL];
00576       if (!(cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked))) {
00577          ast_log(LOG_WARNING, "Unable to include %s\n", val);
00578          return SQLITE_ABORT;
00579       } else {
00580          args->cfg = cfg;
00581          return 0;
00582       }
00583    }
00584 
00585    if (!args->cat_name || strcmp(args->cat_name, values[COL_CATEGORY])) {
00586       if (!(args->cat = ast_category_new(values[COL_CATEGORY], "", 99999))) {
00587          ast_log(LOG_WARNING, "Unable to allocate category\n");
00588          return SQLITE_ABORT;
00589       }
00590 
00591       ast_free(args->cat_name);
00592 
00593       if (!(args->cat_name = ast_strdup(values[COL_CATEGORY]))) {
00594          ast_category_destroy(args->cat);
00595          return SQLITE_ABORT;
00596       }
00597 
00598       ast_category_append(args->cfg, args->cat);
00599    }
00600 
00601    if (!(var = ast_variable_new(values[COL_VAR_NAME], values[COL_VAR_VAL], ""))) {
00602       ast_log(LOG_WARNING, "Unable to allocate variable\n");
00603       return SQLITE_ABORT;
00604    }
00605 
00606    ast_variable_append(args->cat, var);
00607 
00608    return 0;
00609 }
00610 
00611 /*! \brief Realtime callback for static realtime
00612  * \return ast_config on success, NULL on failure
00613  */
00614 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)
00615 {
00616    char *sql;
00617    struct cfg_entry_args args;
00618 
00619    if (ast_strlen_zero(table)) {
00620       ast_log(LOG_WARNING, "Must have a table to query!\n");
00621       return NULL;
00622    }
00623 
00624    if (!(sql = sqlite3_mprintf(static_sql, table, configfile))) {
00625       ast_log(LOG_WARNING, "Couldn't allocate query\n");
00626       return NULL;
00627    };
00628 
00629    args.cfg = config;
00630    args.cat = NULL;
00631    args.cat_name = NULL;
00632    args.flags = flags;
00633    args.who_asked = who_asked;
00634 
00635    realtime_sqlite3_execute(database, sql, static_realtime_cb, &args, 0);
00636 
00637    sqlite3_free(sql);
00638 
00639    return config;
00640 }
00641 
00642 /*! \brief Helper function for single and multi-row realtime load functions */
00643 static int realtime_sqlite3_helper(const char *database, const char *table, va_list ap, int is_multi, void *arg)
00644 {
00645    struct ast_str *sql;
00646    const char *param, *value;
00647    int first = 1;
00648 
00649    if (ast_strlen_zero(table)) {
00650       ast_log(LOG_WARNING, "Must have a table to query!\n");
00651       return -1;
00652    }
00653 
00654    if (!(sql = ast_str_create(128))) {
00655       return -1;
00656    }
00657 
00658    while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00659       if (first) {
00660          ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
00661                sqlite3_escape_column_op(param), sqlite3_escape_value(value));
00662          first = 0;
00663       } else {
00664          ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param),
00665                sqlite3_escape_value(value));
00666       }
00667    }
00668 
00669    if (!is_multi) {
00670       ast_str_append(&sql, 0, "%s", " LIMIT 1");
00671    }
00672 
00673    if (realtime_sqlite3_execute(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg, 0) < 0) {
00674       ast_free(sql);
00675       return -1;
00676    }
00677 
00678    ast_free(sql);
00679 
00680    return 0;
00681 }
00682 
00683 /*! \brief Realtime callback for a single row query
00684  * \return ast_variable list for single result on success, NULL on empty/failure
00685  */
00686 static struct ast_variable *realtime_sqlite3(const char *database, const char *table, va_list ap)
00687 {
00688    struct ast_variable *result_row = NULL;
00689 
00690    realtime_sqlite3_helper(database, table, ap, 0, &result_row);
00691 
00692    return result_row;
00693 }
00694 
00695 /*! \brief Realtime callback for a multi-row query
00696  * \return ast_config containing possibly many results on success, NULL on empty/failure
00697  */
00698 static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, va_list ap)
00699 {
00700    struct ast_config *cfg;
00701 
00702    if (!(cfg = ast_config_new())) {
00703       return NULL;
00704    }
00705 
00706    if (realtime_sqlite3_helper(database, table, ap, 1, cfg)) {
00707       ast_config_destroy(cfg);
00708       return NULL;
00709    }
00710 
00711    return cfg;
00712 }
00713 
00714 /*! \brief Realtime callback for updating a row based on a single criteria
00715  * \return Number of rows affected or -1 on error
00716  */
00717 static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
00718 {
00719    struct ast_str *sql;
00720    const char *key, *value;
00721    int first = 1, res;
00722 
00723    if (ast_strlen_zero(table)) {
00724       ast_log(LOG_WARNING, "Must have a table to query!\n");
00725       return -1;
00726    }
00727 
00728    if (!(sql = ast_str_create(128))) {
00729       return -1;
00730    }
00731 
00732    while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00733       if (first) {
00734          ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
00735                sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
00736          first = 0;
00737       } else {
00738          ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
00739       }
00740    }
00741 
00742    ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));
00743 
00744    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00745    ast_free(sql);
00746 
00747    return res;
00748 }
00749 
00750 /*! \brief Realtime callback for updating a row based on multiple criteria
00751  * \return Number of rows affected or -1 on error
00752  */
00753 static int realtime_sqlite3_update2(const char *database, const char *table, va_list ap)
00754 {
00755    struct ast_str *sql;
00756    struct ast_str *where_clause;
00757    const char *key, *value;
00758    int first = 1, res;
00759 
00760    if (ast_strlen_zero(table)) {
00761       ast_log(LOG_WARNING, "Must have a table to query!\n");
00762       return -1;
00763    }
00764 
00765    if (!(sql = ast_str_create(128))) {
00766       return -1;
00767    }
00768 
00769    if (!(where_clause = ast_str_create(128))) {
00770       ast_free(sql);
00771       return -1;
00772    }
00773 
00774    while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00775       if (first) {
00776          ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
00777          first = 0;
00778       } else {
00779          ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
00780       }
00781    }
00782 
00783    first = 1;
00784    while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00785       if (first) {
00786          ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
00787          first = 0;
00788       } else {
00789          ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
00790       }
00791    }
00792 
00793    ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));
00794 
00795    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00796 
00797    ast_free(sql);
00798    ast_free(where_clause);
00799 
00800    return res;
00801 }
00802 
00803 /*! \brief Realtime callback for inserting a row
00804  * \return Number of rows affected or -1 on error
00805  */
00806 static int realtime_sqlite3_store(const char *database, const char *table, va_list ap)
00807 {
00808    struct ast_str *sql, *values;
00809    const char *column, *value;
00810    int first = 1, res;
00811 
00812    if (ast_strlen_zero(table)) {
00813       ast_log(LOG_WARNING, "Must have a table to query!\n");
00814       return -1;
00815    }
00816 
00817    if (!(sql = ast_str_create(128))) {
00818       return -1;
00819    }
00820 
00821    if (!(values = ast_str_create(128))) {
00822       ast_free(sql);
00823       return -1;
00824    }
00825 
00826    while ((column = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00827       if (first) {
00828          ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(column));
00829          ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(value));
00830          first = 0;
00831       } else {
00832          ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(column));
00833          ast_str_append(&values, 0, ", %s", sqlite3_escape_value(value));
00834       }
00835    }
00836 
00837    ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));
00838 
00839    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00840 
00841    ast_free(sql);
00842    ast_free(values);
00843 
00844    return res;
00845 }
00846 
00847 /*! \brief Realtime callback for deleting a row
00848  * \return Number of rows affected or -1 on error
00849  */
00850 static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
00851 {
00852    struct ast_str *sql;
00853    const char *param, *value;
00854    int first = 1, res;
00855 
00856    if (ast_strlen_zero(table)) {
00857       ast_log(LOG_WARNING, "Must have a table to query!\n");
00858       return -1;
00859    }
00860 
00861    if (!(sql = ast_str_create(128))) {
00862       return -1;
00863    }
00864 
00865    while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
00866       if (first) {
00867          ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
00868                sqlite3_escape_column_op(param), sqlite3_escape_value(value));
00869          first = 0;
00870       } else {
00871          ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param), sqlite3_escape_value(value));
00872       }
00873    }
00874 
00875    res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
00876 
00877    ast_free(sql);
00878 
00879    return res;
00880 }
00881 
00882 /*! \brief Convert Asterisk realtime types to SQLite 3 types
00883  * \note SQLite 3 has NULL, INTEGER, REAL, TEXT, and BLOB types. Any column other than
00884  * an INTEGER PRIMARY KEY will actually store any kind of data due to its dynamic
00885  * typing. When we create columns, we'll go ahead and use these base types instead
00886  * of messing with column widths, etc. */
00887 
00888 static const char *get_sqlite_column_type(int type)
00889 {
00890    switch(type) {
00891    case RQ_INTEGER1 :
00892    case RQ_UINTEGER1 :
00893    case RQ_INTEGER2 :
00894    case RQ_UINTEGER2 :
00895    case RQ_INTEGER3 :
00896    case RQ_UINTEGER3 :
00897    case RQ_INTEGER4 :
00898    case RQ_UINTEGER4 :
00899    case RQ_INTEGER8 :
00900       return "INTEGER";
00901    case RQ_UINTEGER8 : /* SQLite3 stores INTEGER as signed 8-byte */
00902    case RQ_CHAR :
00903    case RQ_DATE :
00904    case RQ_DATETIME :
00905       return "TEXT";
00906    case RQ_FLOAT :
00907       return "REAL";
00908    default :
00909       return "TEXT";
00910    }
00911 
00912    return "TEXT";
00913 }
00914 
00915 /*! \brief Create a table if ast_realtime_require shows that we are configured to handle the data
00916  */
00917 static int handle_missing_table(struct realtime_sqlite3_db *db, const char *table, va_list ap)
00918 {
00919    const char *column;
00920    int type, first = 1, res;
00921    size_t sz;
00922    struct ast_str *sql;
00923 
00924    if (!(sql = ast_str_create(128))) {
00925       return -1;
00926    }
00927 
00928    while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
00929       if (first) {
00930          ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
00931                sqlite3_escape_column(column), get_sqlite_column_type(type));
00932          first = 0;
00933       } else {
00934          ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
00935       }
00936    }
00937 
00938    ast_str_append(&sql, 0, ")");
00939 
00940    res = realtime_sqlite3_execute_handle(db, ast_str_buffer(sql), NULL, NULL, 1) < 0 ? -1 : 0;
00941    ast_free(sql);
00942 
00943    return res;
00944 }
00945 
00946 /*! \brief If ast_realtime_require sends info about a column we don't have, create it
00947  */
00948 static int handle_missing_column(struct realtime_sqlite3_db *db, const char *table, const char *column, int type, size_t sz)
00949 {
00950    char *sql;
00951    const char *sqltype = get_sqlite_column_type(type);
00952    int res;
00953 
00954    if (db->requirements == REALTIME_SQLITE3_REQ_WARN) {
00955       ast_log(LOG_WARNING, "Missing column '%s' of type '%s' in %s.%s\n", column, sqltype, db->name, table);
00956       return -1;
00957    } else if (db->requirements == REALTIME_SQLITE3_REQ_CHAR) {
00958       sqltype = "TEXT";
00959    }
00960 
00961    if (!(sql = sqlite3_mprintf("ALTER TABLE \"%q\" ADD COLUMN \"%q\" %s", table, column, sqltype))) {
00962       return -1;
00963    }
00964 
00965    if (!(res = (realtime_sqlite3_execute_handle(db, sql, NULL, NULL, 1) < 0 ? -1 : 0))) {
00966       ast_log(LOG_NOTICE, "Creating column '%s' type %s for table %s\n", column, sqltype, table);
00967    }
00968 
00969    sqlite3_free(sql);
00970 
00971    return res;
00972 }
00973 
00974 static int str_hash_fn(const void *obj, const int flags)
00975 {
00976    return ast_str_hash((const char *) obj);
00977 }
00978 
00979 static int str_cmp_fn(void *obj, void *arg, int flags) {
00980    return !strcasecmp((const char *) obj, (const char *) arg);
00981 }
00982 
00983 /*! \brief Callback for creating a hash of column names for comparison in realtime_sqlite3_require
00984  */
00985 static int add_column_name(void *arg, int num_columns, char **values, char **columns)
00986 {
00987    char *column;
00988    struct ao2_container *cnames = arg;
00989 
00990 
00991    if (!(column = ao2_alloc(strlen(values[1]) + 1, NULL))) {
00992       return -1;
00993    }
00994 
00995    strcpy(column, values[1]);
00996 
00997    ao2_link(cnames, column);
00998    ao2_ref(column, -1);
00999 
01000    return 0;
01001 }
01002 
01003 /*! \brief Callback for ast_realtime_require
01004  * \retval 0 Required fields met specified standards
01005  * \retval -1 One or more fields was missing or insufficient
01006  */
01007 static int realtime_sqlite3_require(const char *database, const char *table, va_list ap)
01008 {
01009    const char *column;
01010    char *sql;
01011    int type;
01012    int res;
01013    size_t sz;
01014    struct ao2_container *columns;
01015    struct realtime_sqlite3_db *db;
01016 
01017    /* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
01018     * return the results as char * anyway. The only field that that cannot contain text
01019     * data is an INTEGER PRIMARY KEY, which must be a 64-bit signed integer. So, for
01020     * the purposes here we really only care whether the column exists and not what its
01021     * type or length is. */
01022 
01023    if (ast_strlen_zero(table)) {
01024       ast_log(LOG_WARNING, "Must have a table to query!\n");
01025       return -1;
01026    }
01027 
01028    if (!(db = find_database(database))) {
01029       return -1;
01030    }
01031 
01032    if (!(columns = ao2_container_alloc(31, str_hash_fn, str_cmp_fn))) {
01033       unref_db(&db);
01034       return -1;
01035    }
01036 
01037    if (!(sql = sqlite3_mprintf("PRAGMA table_info(\"%q\")", table))) {
01038       unref_db(&db);
01039       ao2_ref(columns, -1);
01040       return -1;
01041    }
01042 
01043    if ((res = realtime_sqlite3_execute_handle(db, sql, add_column_name, columns, 0)) < 0) {
01044       unref_db(&db);
01045       ao2_ref(columns, -1);
01046       sqlite3_free(sql);
01047       return -1;
01048    } else if (res == 0) {
01049       /* Table does not exist */
01050       sqlite3_free(sql);
01051       res = handle_missing_table(db, table, ap);
01052       ao2_ref(columns, -1);
01053       unref_db(&db);
01054       return res;
01055    }
01056 
01057    sqlite3_free(sql);
01058 
01059    while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
01060       char *found;
01061       if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
01062          if (handle_missing_column(db, table, column, type, sz)) {
01063             unref_db(&db);
01064             ao2_ref(columns, -1);
01065             return -1;
01066          }
01067       } else {
01068          ao2_ref(found, -1);
01069       }
01070    }
01071 
01072    ao2_ref(columns, -1);
01073    unref_db(&db);
01074 
01075    return 0;
01076 }
01077 
01078 /*! \brief Callback for clearing any cached info
01079  * \note We don't currently cache anything
01080  * \retval 0 If any cache was purged
01081  * \retval -1 If no cache was found
01082  */
01083 static int realtime_sqlite3_unload(const char *database, const char *table)
01084 {
01085    /* We currently do no caching */
01086    return -1;
01087 }
01088 
01089 /*! \brief Parse the res_config_sqlite3 config file
01090  */
01091 static int parse_config(int reload)
01092 {
01093    struct ast_config *config;
01094    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME | (reload ? CONFIG_FLAG_FILEUNCHANGED : 0) };
01095    static const char *config_filename = "res_config_sqlite3.conf";
01096 
01097    config = ast_config_load(config_filename, config_flags);
01098 
01099    if (config == CONFIG_STATUS_FILEUNCHANGED) {
01100       ast_debug(1, "%s was unchanged, skipping parsing\n", config_filename);
01101       return 0;
01102    }
01103 
01104    ast_mutex_lock(&config_lock);
01105 
01106    if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
01107       ast_log(LOG_ERROR, "%s config file '%s'\n",
01108          config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
01109    } else {
01110       const char *cat;
01111       struct realtime_sqlite3_db *db;
01112 
01113       mark_all_databases_dirty();
01114       for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
01115          if (!strcasecmp(cat, "general")) {
01116             continue;
01117          }
01118          if (!(db = find_database(cat))) {
01119             if (!(db = new_realtime_sqlite3_db(config, cat))) {
01120                ast_log(LOG_WARNING, "Could not allocate new db for '%s' - skipping.\n", cat);
01121                continue;
01122             }
01123             if (db_open(db)) {
01124                unref_db(&db);
01125                continue;
01126             }
01127             db_start_batch(db);
01128             ao2_link(databases, db);
01129             unref_db(&db);
01130          } else  {
01131             if (update_realtime_sqlite3_db(db, config, cat)) {
01132                unref_db(&db);
01133                continue;
01134             }
01135             unref_db(&db);
01136          }
01137       }
01138       unlink_dirty_databases();
01139    }
01140 
01141    ast_mutex_unlock(&config_lock);
01142 
01143    ast_config_destroy(config);
01144 
01145    return 0;
01146 }
01147 
01148 static int reload(void)
01149 {
01150    parse_config(1);
01151    return 0;
01152 }
01153 
01154 static int unload_module(void)
01155 {
01156    ast_mutex_lock(&config_lock);
01157    ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, stop_batch_cb, NULL);
01158    ao2_ref(databases, -1);
01159    databases = NULL;
01160    ast_config_engine_deregister(&sqlite3_config_engine);
01161    ast_mutex_unlock(&config_lock);
01162 
01163    return 0;
01164 }
01165 
01166 static int load_module(void)
01167 {
01168    if (!((databases = ao2_container_alloc(DB_BUCKETS, db_hash_fn, db_cmp_fn)))) {
01169       return AST_MODULE_LOAD_FAILURE;
01170    }
01171 
01172    if (parse_config(0)) {
01173       ao2_ref(databases, -1);
01174       return AST_MODULE_LOAD_FAILURE;
01175    }
01176 
01177    if (!(ast_config_engine_register(&sqlite3_config_engine))) {
01178       ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
01179       ao2_ref(databases, -1);
01180       return AST_MODULE_LOAD_FAILURE;
01181    }
01182 
01183    return AST_MODULE_LOAD_SUCCESS;
01184 }
01185 
01186 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SQLite 3 realtime config engine",
01187    .load = load_module,
01188    .unload = unload_module,
01189    .reload = reload,
01190    .load_pri = AST_MODPRI_REALTIME_DRIVER,
01191 );