Asterisk - The Open Source Telephony Project  18.5.0
res_config_sqlite3.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2011, Terry Wilson
5  *
6  * Terry Wilson <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  *
18  * Please follow coding guidelines
19  * http://svn.digium.com/view/asterisk/trunk/doc/CODING-GUIDELINES
20  */
21 
22 /*! \file
23  *
24  * \brief SQLite 3 configuration engine
25  *
26  * \author\verbatim Terry Wilson <[email protected]> \endverbatim
27  *
28  * This is a realtime configuration engine for the SQLite 3 Database
29  * \ingroup resources
30  */
31 
32 /*! \li \ref res_config_sqlite3.c uses the configuration file \ref res_config_sqlite3.conf
33  * \addtogroup configuration_file Configuration Files
34  */
35 
36 /*!
37  * \page res_config_sqlite3.conf res_config_sqlite3.conf
38  * \verbinclude res_config_sqlite3.conf.sample
39  */
40 
41 /*** MODULEINFO
42  <depend>sqlite3</depend>
43  <support_level>core</support_level>
44  ***/
45 
46 #include "asterisk.h"
47 
48 #include <sqlite3.h>
49 
50 #include "asterisk/module.h"
51 #include "asterisk/config.h"
52 #include "asterisk/paths.h"
53 #include "asterisk/astobj2.h"
54 #include "asterisk/lock.h"
55 #include "asterisk/utils.h"
56 #include "asterisk/app.h"
57 
58 /*** DOCUMENTATION
59  ***/
60 
62 
63 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);
64 static struct ast_variable *realtime_sqlite3(const char *database, const char *table, const struct ast_variable *fields);
65 static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, const struct ast_variable *fields);
66 static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
67 static int realtime_sqlite3_update2(const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields);
68 static int realtime_sqlite3_store(const char *database, const char *table, const struct ast_variable *fields);
69 static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
70 static int realtime_sqlite3_require(const char *database, const char *table, va_list ap);
71 static int realtime_sqlite3_unload(const char *database, const char *table);
72 
74  .name = "sqlite3",
75  .load_func = realtime_sqlite3_load,
76  .realtime_func = realtime_sqlite3,
77  .realtime_multi_func = realtime_sqlite3_multi,
78  .update_func = realtime_sqlite3_update,
79  .update2_func = realtime_sqlite3_update2,
80  .store_func = realtime_sqlite3_store,
81  .destroy_func = realtime_sqlite3_destroy,
82  .require_func = realtime_sqlite3_require,
83  .unload_func = realtime_sqlite3_unload,
84 };
85 
86 enum {
90 };
91 
96  );
97  sqlite3 *handle;
98  pthread_t syncthread;
100  unsigned int requirements:2;
101  unsigned int dirty:1;
102  unsigned int debug:1;
103  unsigned int exiting:1;
104  unsigned int wakeup:1;
105  unsigned int has_batch_thread:1;
106  unsigned int batch;
108 };
109 
111 #define DB_BUCKETS 7
112 
114 
115 /* We need a separate buffer for each field we might use concurrently */
119 
120 typedef int (*callback_t)(void*, int, char **, char **);
121 
122 static int realtime_sqlite3_exec_query_with_handle(struct realtime_sqlite3_db *, const char *, callback_t, void *);
123 static int realtime_sqlite3_exec_query(const char *, const char *, callback_t, void *);
124 static int realtime_sqlite3_exec_update_with_handle(struct realtime_sqlite3_db *, const char *);
125 static int realtime_sqlite3_exec_update(const char *, const char *);
126 
128 void db_stop_batch(struct realtime_sqlite3_db *db);
129 
130 static inline const char *sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)
131 {
132  size_t maxlen = strlen(param) * 2 + sizeof("\"\"");
133  /* It doesn't appear that sqlite3_snprintf will do more than double the
134  * length of a string with %q as an option. %Q could double and possibly
135  * add two quotes, and convert NULL pointers to the word "NULL", but we
136  * don't allow those anyway. Just going to use %q for now. */
137  struct ast_str *buf = ast_str_thread_get(ts, maxlen);
138  char q = ts == &escape_value_buf ? '\'' : '"';
139  char *tmp;
140 
141  if (ast_str_size(buf) < maxlen) {
142  /* realloc if buf is too small */
143  ast_str_make_space(&buf, maxlen);
144  }
145  tmp = ast_str_buffer(buf);
146 
147  ast_str_reset(buf);
148  *tmp++ = q; /* Initial quote */
149  while ((*tmp++ = *param++)) {
150  /* Did we just copy a quote? Then double it. */
151  if (*(tmp - 1) == q) {
152  *tmp++ = q;
153  }
154  }
155  *tmp = '\0'; /* Terminate past NULL from copy */
156  *(tmp - 1) = q; /* Replace original NULL with the quote */
157  ast_str_update(buf);
158 
159  return ast_str_buffer(buf);
160 }
161 
162 static inline const char *sqlite3_escape_table(const char *param)
163 {
165 }
166 
167 static inline const char *sqlite3_escape_column(const char *param)
168 {
170 }
171 
172 /* Not inlining this function because it uses strdupa and I don't know if the compiler would be dumb */
173 static const char *sqlite3_escape_column_op(const char *param)
174 {
175  size_t maxlen = strlen(param) * 2 + sizeof("\"\" =");
176  struct ast_str *buf = ast_str_thread_get(&escape_column_buf, maxlen);
177  char *tmp;
178  int space = 0;
179 
180  if (ast_str_size(buf) < maxlen) {
181  /* realloc if buf is too small */
182  ast_str_make_space(&buf, maxlen);
183  }
184  tmp = ast_str_buffer(buf);
185 
186  ast_str_reset(buf);
187  *tmp++ = '"';
188  while ((*tmp++ = *param++)) {
189  /* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
190  * available to users via an API, we will definitely need to avoid allowing special
191  * characters like ';' in the data past the space as it will be unquoted data */
192  if (space) {
193  continue;
194  }
195  if (*(tmp - 1) == ' ') {
196  *(tmp - 1) = '"';
197  *tmp++ = ' ';
198  space = 1;
199  } else if (*(tmp - 1) == '"') {
200  *tmp++ = '"';
201  }
202  }
203  if (!space) {
204  strcpy(tmp - 1, "\" =");
205  }
206 
207  ast_str_update(buf);
208 
209  return ast_str_buffer(buf);
210 }
211 
212 static inline const char *sqlite3_escape_value(const char *param)
213 {
215 }
216 
217 static int db_hash_fn(const void *obj, const int flags)
218 {
219  const struct realtime_sqlite3_db *db = obj;
220 
221  return ast_str_hash(flags & OBJ_KEY ? (const char *) obj : db->name);
222 }
223 
224 static int db_cmp_fn(void *obj, void *arg, int flags) {
225  struct realtime_sqlite3_db *db = obj, *other = arg;
226  const char *name = arg;
227 
228  return !strcasecmp(db->name, flags & OBJ_KEY ? name : other->name) ? CMP_MATCH | CMP_STOP : 0;
229 }
230 
231 static void db_destructor(void *obj)
232 {
233  struct realtime_sqlite3_db *db = obj;
234 
235  ast_debug(1, "Destroying db: %s\n", db->name);
237  db_stop_batch(db);
238  if (db->handle) {
239  ao2_lock(db);
240  sqlite3_close(db->handle);
241  ao2_unlock(db);
242  }
243 }
244 
245 static struct realtime_sqlite3_db *find_database(const char *database)
246 {
247  return ao2_find(databases, database, OBJ_KEY);
248 }
249 
250 static void unref_db(struct realtime_sqlite3_db **db)
251 {
252  ao2_ref(*db, -1);
253  *db = NULL;
254 }
255 
256 static int stop_batch_cb(void *obj, void *arg, int flags)
257 {
258  struct realtime_sqlite3_db *db = obj;
259 
260  db_stop_batch(db);
261  return CMP_MATCH;
262 }
263 
264 static int mark_dirty_cb(void *obj, void *arg, int flags)
265 {
266  struct realtime_sqlite3_db *db = obj;
267  db->dirty = 1;
268  return CMP_MATCH;
269 }
270 
271 static void mark_all_databases_dirty(void)
272 {
274 }
275 
276 static int is_dirty_cb(void *obj, void *arg, int flags)
277 {
278  struct realtime_sqlite3_db *db = obj;
279  if (db->dirty) {
280  db_stop_batch(db);
281  return CMP_MATCH;
282  }
283  return 0;
284 }
285 
286 static void unlink_dirty_databases(void)
287 {
289 }
290 
291 static int str_to_requirements(const char *data)
292 {
293  if (!strcasecmp(data, "createclose")) {
295  } else if (!strcasecmp(data, "createchar")) {
297  }
298  /* default */
300 }
301 
302 /*! \note Since this is called while a query is executing, we should already hold the db lock */
303 static void trace_cb(void *arg, const char *sql)
304 {
305  struct realtime_sqlite3_db *db = arg;
306  ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
307 }
308 
309 /*! \brief Wrap commands in transactions increased write performance */
310 static void *db_sync_thread(void *data)
311 {
312  struct realtime_sqlite3_db *db = data;
313  ao2_lock(db);
314  realtime_sqlite3_exec_query_with_handle(db, "BEGIN TRANSACTION", NULL, NULL);
315  for (;;) {
316  if (!db->wakeup) {
318  }
319  db->wakeup = 0;
320  if (realtime_sqlite3_exec_query_with_handle(db, "COMMIT", NULL, NULL) < 0) {
322  }
323  if (db->exiting) {
324  ao2_unlock(db);
325  break;
326  }
327  realtime_sqlite3_exec_query_with_handle(db, "BEGIN TRANSACTION", NULL, NULL);
328  ao2_unlock(db);
329  usleep(1000 * db->batch);
330  ao2_lock(db);
331  }
332 
333  unref_db(&db);
334 
335  return NULL;
336 }
337 
338 /*! \brief Open a database and appropriately set debugging on the db handle */
339 static int db_open(struct realtime_sqlite3_db *db)
340 {
341  ao2_lock(db);
342  if (sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
343  ast_log(LOG_WARNING, "Could not open %s: %s\n", db->filename, sqlite3_errmsg(db->handle));
344  ao2_unlock(db);
345  return -1;
346  }
347  sqlite3_busy_timeout(db->handle, db->busy_timeout);
348 
349  if (db->debug) {
350  sqlite3_trace(db->handle, trace_cb, db);
351  } else {
352  sqlite3_trace(db->handle, NULL, NULL);
353  }
354 
355  ao2_unlock(db);
356 
357  return 0;
358 }
359 
360 static void db_sync(struct realtime_sqlite3_db *db)
361 {
362  db->wakeup = 1;
363  ast_cond_signal(&db->cond);
364 }
365 
367 {
368  if (db->batch) {
369  ast_cond_init(&db->cond, NULL);
370  ao2_ref(db, +1);
372  }
373 }
374 
376 {
377  if (db->has_batch_thread) {
378  db->has_batch_thread = 0;
379  db->exiting = 1;
380  db_sync(db);
381  pthread_join(db->syncthread, NULL);
382  }
383 }
384 
385 /*! \brief Create a db object based on a config category
386  * \note Opening the db handle and linking to databases must be handled outside of this function
387  */
388 static struct realtime_sqlite3_db *new_realtime_sqlite3_db(struct ast_config *config, const char *cat)
389 {
390  struct ast_variable *var;
391  struct realtime_sqlite3_db *db;
392 
393  if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
394  return NULL;
395  }
396 
397  if (ast_string_field_init(db, 64)) {
398  unref_db(&db);
399  return NULL;
400  }
401 
402  /* Set defaults */
404  db->batch = 100;
405  ast_string_field_set(db, name, cat);
406  db->busy_timeout = 1000;
407 
408  for (var = ast_variable_browse(config, cat); var; var = var->next) {
409  if (!strcasecmp(var->name, "dbfile")) {
411  } else if (!strcasecmp(var->name, "requirements")) {
413  } else if (!strcasecmp(var->name, "batch")) {
415  } else if (!strcasecmp(var->name, "debug")) {
416  db->debug = ast_true(var->value);
417  } else if (!strcasecmp(var->name, "busy_timeout")) {
418  if (ast_parse_arg(var->value, PARSE_INT32|PARSE_DEFAULT, &(db->busy_timeout), 1000) != 0) {
419  ast_log(LOG_WARNING, "Invalid busy_timeout value '%s' at res_config_sqlite3.conf:%d. Using 1000 instead.\n", var->value, var->lineno);
420  }
421  }
422  }
423 
424  if (ast_strlen_zero(db->filename)) {
425  ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
426  unref_db(&db);
427  return NULL;
428  }
429 
430  return db;
431 }
432 
433 /*! \brief Update an existing db object based on config data
434  * \param db The database object to update
435  * \param config The configuration data with which to update the db
436  * \param cat The config category (which becomes db->name)
437  */
438 static int update_realtime_sqlite3_db(struct realtime_sqlite3_db *db, struct ast_config *config, const char *cat)
439 {
440  struct realtime_sqlite3_db *new;
441 
442  if (!(new = new_realtime_sqlite3_db(config, cat))) {
443  return -1;
444  }
445 
446  /* Copy fields that don't need anything special done on change */
447  db->requirements = new->requirements;
448 
449  /* Handle changes that require immediate behavior modification */
450  if (db->debug != new->debug) {
451  if (db->debug) {
452  sqlite3_trace(db->handle, NULL, NULL);
453  } else {
454  sqlite3_trace(db->handle, trace_cb, db);
455  }
456  db->debug = new->debug;
457  }
458 
459  if (strcmp(db->filename, new->filename)) {
460  sqlite3_close(db->handle);
461  ast_string_field_set(db, filename, new->filename);
462  db_open(db); /* Also handles setting appropriate debug on new handle */
463  }
464 
465  if (db->busy_timeout != new->busy_timeout) {
466  db->busy_timeout = new->busy_timeout;
467  sqlite3_busy_timeout(db->handle, db->busy_timeout);
468  }
469 
470  if (db->batch != new->batch) {
471  if (db->batch == 0) {
472  db->batch = new->batch;
473  db_start_batch(db);
474  } else if (new->batch == 0) {
475  db->batch = new->batch;
476  db_stop_batch(db);
477  }
478  db->batch = new->batch;
479  }
480 
481  db->dirty = 0;
482  unref_db(&new);
483 
484  return 0;
485 }
486 
487 /*! \brief Create a varlist from a single sqlite3 result row */
488 static int row_to_varlist(void *arg, int num_columns, char **values, char **columns)
489 {
490  struct ast_variable **head = arg, *tail;
491  int i;
492  struct ast_variable *new;
493 
494  if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
495  return SQLITE_ABORT;
496  }
497  *head = tail = new;
498 
499  for (i = 1; i < num_columns; i++) {
500  if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
501  ast_variables_destroy(*head);
502  *head = NULL;
503  return SQLITE_ABORT;
504  }
505  tail->next = new;
506  tail = new;
507  }
508 
509  return 0;
510 }
511 
512 /*! \brief Callback for creating an ast_config from a successive sqlite3 result rows */
513 static int append_row_to_cfg(void *arg, int num_columns, char **values, char **columns)
514 {
515  struct ast_config *cfg = arg;
516  struct ast_category *cat;
517  int i;
518 
520  if (!cat) {
521  return SQLITE_ABORT;
522  }
523 
524  for (i = 0; i < num_columns; i++) {
525  struct ast_variable *var;
526  if (!(var = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
527  ast_log(LOG_ERROR, "Could not create new variable for '%s: %s', throwing away list\n", columns[i], values[i]);
528  continue;
529  }
530  ast_variable_append(cat, var);
531  }
532  ast_category_append(cfg, cat);
533 
534  return 0;
535 }
536 
537 /*!
538  * Structure sent to the SQLite 3 callback function for static configuration.
539  *
540  * \see static_realtime_cb()
541  */
542 struct cfg_entry_args {
543  struct ast_config *cfg;
544  struct ast_category *cat;
545  char *cat_name;
546  struct ast_flags flags;
547  const char *who_asked;
548 };
549 
550 /*!
551  * Structure passed to row counting SQLite callback.
552  */
555  void *wrapped_arg;
557 };
558 
559 /*!
560  * \internal
561  * \brief SQLite3 callback that counts rows of a result set.
562  *
563  * \details
564  * This is used to decorate existing callbacks so that we can count the number
565  * of rows returned from a SELECT statement and still process each row
566  * independently.
567  *
568  * \param data user data pointer passed in via sqlite3_exec()
569  * \param num_columns number of columns in the result
570  * \param values array of pointers to column values
571  * \param columns array of pointers of to column names
572  *
573  * \return the return value of the wrapped callback, or 0 if no wrapped callback
574  * is provided.
575  */
576 static int row_counter_wrapper(void *arg, int num_columns, char **values, char **columns)
577 {
578  struct row_counter_args *wrapped = arg;
579  wrapped->row_count++;
580  if (wrapped->wrapped_callback) {
581  return wrapped->wrapped_callback(wrapped->wrapped_arg, num_columns, values, columns);
582  }
583  return 0;
584 }
585 
586 /*!
587  * \internal
588  * \brief Execute a SQL SELECT statement using a database handle
589  *
590  * \param db the database handle to use for the query
591  * \param sql the SQL statement to execute
592  * \param callback a user defined callback that will be called for each row of
593  * the result set
594  * \param arg data to be passed to the user defined callback
595  *
596  * \return if successful, the number of rows returned from the provided SELECT
597  * statement. -1 on failure.
598  */
599 static int realtime_sqlite3_exec_query_with_handle(struct realtime_sqlite3_db *db, const char *sql, callback_t callback, void *arg)
600 {
601  int res = 0;
602  char *errmsg;
603  struct row_counter_args wrapper = {
604  .wrapped_callback = callback,
605  .wrapped_arg = arg,
606  .row_count = 0,
607  };
608 
609  ao2_lock(db);
610  if (sqlite3_exec(db->handle, sql, row_counter_wrapper, &wrapper, &errmsg) != SQLITE_OK) {
611  ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
612  sqlite3_free(errmsg);
613  res = -1;
614  }
615  ao2_unlock(db);
616 
617  return res == 0 ? wrapper.row_count : res;
618 }
619 
620 /*!
621  * \internal
622  * \brief Execute a SQL SELECT statement on the specified database
623  *
624  * \param database the name of the database to query
625  * \param sql the SQL statement to execute
626  * \param callback a user defined callback that will be called for each row of
627  * the result set
628  * \param arg data to be passed to the user defined callback
629  *
630  * \return if successful, the number of rows returned from the provided SELECT
631  * statement. -1 on failure.
632  */
633 static int realtime_sqlite3_exec_query(const char *database, const char *sql, callback_t callback, void *arg)
634 {
635  struct realtime_sqlite3_db *db;
636  int res;
637 
638  if (!(db = find_database(database))) {
639  ast_log(LOG_WARNING, "Could not find database: %s\n", database);
640  return -1;
641  }
642 
643  res = realtime_sqlite3_exec_query_with_handle(db, sql, callback, arg);
644  ao2_ref(db, -1);
645 
646  return res;
647 }
648 
649 /*!
650  * \internal
651  * \brief Execute a SQL INSERT/UPDATE/DELETE statement using a database handle
652  *
653  * \note A database sync operation is always performed after a statement
654  * is executed.
655  *
656  * \param db the database handle to use for the query
657  * \param sql the SQL statement to execute
658  *
659  * \return if successful, the number of rows modified by the provided SQL
660  * statement. -1 on failure.
661  */
663 {
664  int res = 0;
665  char *errmsg;
666 
667  ao2_lock(db);
668  if (sqlite3_exec(db->handle, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
669  ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
670  sqlite3_free(errmsg);
671  res = -1;
672  } else {
673  res = sqlite3_changes(db->handle);
674  }
675  ao2_unlock(db);
676 
677  db_sync(db);
678 
679  return res;
680 }
681 
682 /*!
683  * \internal
684  * \brief Execute a SQL INSERT/UPDATE/DELETE statement using a database handle
685  *
686  * \note A database sync operation is always performed after a statement
687  * is executed.
688  *
689  * \param database the name of the database to query
690  * \param sql the SQL statement to execute
691  *
692  * \return if successful, the number of rows modified by the provided SQL
693  * statement. -1 on failure.
694  */
695 static int realtime_sqlite3_exec_update(const char *database, const char *sql)
696 {
697  struct realtime_sqlite3_db *db;
698  int res;
699 
700  if (!(db = find_database(database))) {
701  ast_log(LOG_WARNING, "Could not find database: %s\n", database);
702  return -1;
703  }
704 
706  ao2_ref(db, -1);
707 
708  return res;
709 }
710 
711 /*! \note It is important that the COL_* enum matches the order of the columns selected in static_sql */
712 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";
713 enum {
718 };
719 
720 static int static_realtime_cb(void *arg, int num_columns, char **values, char **columns)
721 {
722  struct cfg_entry_args *args = arg;
723  struct ast_variable *var;
724 
725  if (!strcmp(values[COL_VAR_NAME], "#include")) {
726  struct ast_config *cfg;
727  char *val;
728 
729  val = values[COL_VAR_VAL];
730  if (!(cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked))) {
731  ast_log(LOG_WARNING, "Unable to include %s\n", val);
732  return SQLITE_ABORT;
733  } else {
734  args->cfg = cfg;
735  return 0;
736  }
737  }
738 
739  if (!args->cat_name || strcmp(args->cat_name, values[COL_CATEGORY])) {
740  args->cat = ast_category_new_dynamic(values[COL_CATEGORY]);
741  if (!args->cat) {
742  return SQLITE_ABORT;
743  }
744 
745  ast_free(args->cat_name);
746 
747  if (!(args->cat_name = ast_strdup(values[COL_CATEGORY]))) {
748  ast_category_destroy(args->cat);
749  return SQLITE_ABORT;
750  }
751 
752  ast_category_append(args->cfg, args->cat);
753  }
754 
755  if (!(var = ast_variable_new(values[COL_VAR_NAME], values[COL_VAR_VAL], ""))) {
756  ast_log(LOG_WARNING, "Unable to allocate variable\n");
757  return SQLITE_ABORT;
758  }
759 
760  ast_variable_append(args->cat, var);
761 
762  return 0;
763 }
764 
765 /*! \brief Realtime callback for static realtime
766  * \return ast_config on success, NULL on failure
767  */
768 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)
769 {
770  char *sql;
771  struct cfg_entry_args args;
772 
773  if (ast_strlen_zero(table)) {
774  ast_log(LOG_WARNING, "Must have a table to query!\n");
775  return NULL;
776  }
777 
778  if (!(sql = sqlite3_mprintf(static_sql, table, configfile))) {
779  ast_log(LOG_WARNING, "Couldn't allocate query\n");
780  return NULL;
781  };
782 
783  args.cfg = config;
784  args.cat = NULL;
785  args.cat_name = NULL;
786  args.flags = flags;
787  args.who_asked = who_asked;
788 
789  realtime_sqlite3_exec_query(database, sql, static_realtime_cb, &args);
790 
791  sqlite3_free(sql);
792 
793  return config;
794 }
795 
796 #define IS_SQL_LIKE_CLAUSE(x) ((x) && ast_ends_with(x, " LIKE"))
797 
798 /*! \brief Helper function for single and multi-row realtime load functions */
799 static int realtime_sqlite3_helper(const char *database, const char *table, const struct ast_variable *fields, int is_multi, void *arg)
800 {
801  struct ast_str *sql;
802  const struct ast_variable *field;
803  int first = 1;
804 
805  if (ast_strlen_zero(table)) {
806  ast_log(LOG_WARNING, "Must have a table to query!\n");
807  return -1;
808  }
809 
810  if (!(sql = ast_str_create(128))) {
811  return -1;
812  }
813 
814  for (field = fields; field; field = field->next) {
815  if (first) {
816  ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
818  first = 0;
819  } else {
820  ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name),
821  sqlite3_escape_value(field->value));
822  }
823 
825  /*
826  * The realtime framework is going to pre-escape these
827  * for us with a backslash. We just need to make sure
828  * to tell SQLite about it
829  */
830  ast_str_append(&sql, 0, " ESCAPE '\\'");
831  }
832  }
833 
834  if (!is_multi) {
835  ast_str_append(&sql, 0, "%s", " LIMIT 1");
836  }
837 
838  if (realtime_sqlite3_exec_query(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg) < 0) {
839  ast_free(sql);
840  return -1;
841  }
842 
843  ast_free(sql);
844 
845  return 0;
846 }
847 
848 /*! \brief Realtime callback for a single row query
849  * \return ast_variable list for single result on success, NULL on empty/failure
850  */
851 static struct ast_variable *realtime_sqlite3(const char *database, const char *table, const struct ast_variable *fields)
852 {
853  struct ast_variable *result_row = NULL;
854 
855  realtime_sqlite3_helper(database, table, fields, 0, &result_row);
856 
857  return result_row;
858 }
859 
860 /*! \brief Realtime callback for a multi-row query
861  * \return ast_config containing possibly many results on success, NULL on empty/failure
862  */
863 static struct ast_config *realtime_sqlite3_multi(const char *database, const char *table, const struct ast_variable *fields)
864 {
865  struct ast_config *cfg;
866 
867  if (!(cfg = ast_config_new())) {
868  return NULL;
869  }
870 
871  if (realtime_sqlite3_helper(database, table, fields, 1, cfg)) {
872  ast_config_destroy(cfg);
873  return NULL;
874  }
875 
876  return cfg;
877 }
878 
879 /*! \brief Realtime callback for updating a row based on a single criteria
880  * \return Number of rows affected or -1 on error
881  */
882 static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
883 {
884  struct ast_str *sql;
885  const struct ast_variable *field;
886  int first = 1, res;
887 
888  if (ast_strlen_zero(table)) {
889  ast_log(LOG_WARNING, "Must have a table to query!\n");
890  return -1;
891  }
892 
893  if (!(sql = ast_str_create(128))) {
894  return -1;
895  }
896 
897  for (field = fields; field; field = field->next) {
898  if (first) {
899  ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
901  first = 0;
902  } else {
903  ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
904  }
905  }
906 
907  ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));
908 
909  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
910  ast_free(sql);
911 
912  return res;
913 }
914 
915 /*! \brief Realtime callback for updating a row based on multiple criteria
916  * \return Number of rows affected or -1 on error
917  */
918 static int realtime_sqlite3_update2(const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
919 {
920  struct ast_str *sql;
921  struct ast_str *where_clause;
922  const struct ast_variable *field;
923  int first = 1, res;
924 
925  if (ast_strlen_zero(table)) {
926  ast_log(LOG_WARNING, "Must have a table to query!\n");
927  return -1;
928  }
929 
930  if (!(sql = ast_str_create(128))) {
931  return -1;
932  }
933 
934  if (!(where_clause = ast_str_create(128))) {
935  ast_free(sql);
936  return -1;
937  }
938 
939  for (field = lookup_fields; field; field = field->next) {
940  if (first) {
941  ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
942  first = 0;
943  } else {
944  ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
945  }
946  }
947 
948  first = 1;
949  for (field = update_fields; field; field = field->next) {
950  if (first) {
951  ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
952  first = 0;
953  } else {
954  ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(field->name), sqlite3_escape_value(field->value));
955  }
956  }
957 
958  ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));
959 
960  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
961 
962  ast_free(sql);
963  ast_free(where_clause);
964 
965  return res;
966 }
967 
968 /*! \brief Realtime callback for inserting a row
969  * \return Number of rows affected or -1 on error
970  */
971 static int realtime_sqlite3_store(const char *database, const char *table, const struct ast_variable *fields)
972 {
973  struct ast_str *sql, *values;
974  const struct ast_variable *field;
975  int first = 1, res;
976 
977  if (ast_strlen_zero(table)) {
978  ast_log(LOG_WARNING, "Must have a table to query!\n");
979  return -1;
980  }
981 
982  if (!(sql = ast_str_create(128))) {
983  return -1;
984  }
985 
986  if (!(values = ast_str_create(128))) {
987  ast_free(sql);
988  return -1;
989  }
990 
991  for (field = fields; field; field = field->next) {
992  if (first) {
993  ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(field->name));
994  ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(field->value));
995  first = 0;
996  } else {
997  ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(field->name));
998  ast_str_append(&values, 0, ", %s", sqlite3_escape_value(field->value));
999  }
1000  }
1001 
1002  ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));
1003 
1004  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
1005 
1006  ast_free(sql);
1007  ast_free(values);
1008 
1009  return res;
1010 }
1011 
1012 /*! \brief Realtime callback for deleting a row
1013  * \return Number of rows affected or -1 on error
1014  */
1015 static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
1016 {
1017  struct ast_str *sql;
1018  const struct ast_variable *field;
1019  int first = 1, res;
1020 
1021  if (ast_strlen_zero(table)) {
1022  ast_log(LOG_WARNING, "Must have a table to query!\n");
1023  return -1;
1024  }
1025 
1026  if (!(sql = ast_str_create(128))) {
1027  return -1;
1028  }
1029 
1030  for (field = fields; field; field = field->next) {
1031  if (first) {
1032  ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
1034  first = 0;
1035  } else {
1036  ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(field->name), sqlite3_escape_value(field->value));
1037  }
1038  }
1039 
1040  res = realtime_sqlite3_exec_update(database, ast_str_buffer(sql));
1041 
1042  ast_free(sql);
1043 
1044  return res;
1045 }
1046 
1047 /*! \brief Convert Asterisk realtime types to SQLite 3 types
1048  * \note SQLite 3 has NULL, INTEGER, REAL, TEXT, and BLOB types. Any column other than
1049  * an INTEGER PRIMARY KEY will actually store any kind of data due to its dynamic
1050  * typing. When we create columns, we'll go ahead and use these base types instead
1051  * of messing with column widths, etc. */
1052 
1053 static const char *get_sqlite_column_type(int type)
1054 {
1055  switch(type) {
1056  case RQ_INTEGER1 :
1057  case RQ_UINTEGER1 :
1058  case RQ_INTEGER2 :
1059  case RQ_UINTEGER2 :
1060  case RQ_INTEGER3 :
1061  case RQ_UINTEGER3 :
1062  case RQ_INTEGER4 :
1063  case RQ_UINTEGER4 :
1064  case RQ_INTEGER8 :
1065  return "INTEGER";
1066  case RQ_UINTEGER8 : /* SQLite3 stores INTEGER as signed 8-byte */
1067  case RQ_CHAR :
1068  case RQ_DATE :
1069  case RQ_DATETIME :
1070  return "TEXT";
1071  case RQ_FLOAT :
1072  return "REAL";
1073  default :
1074  return "TEXT";
1075  }
1076 
1077  return "TEXT";
1078 }
1079 
1080 /*! \brief Create a table if ast_realtime_require shows that we are configured to handle the data
1081  */
1082 static int handle_missing_table(struct realtime_sqlite3_db *db, const char *table, va_list ap)
1083 {
1084  const char *column;
1085  int type, first = 1, res;
1086  size_t sz;
1087  struct ast_str *sql;
1088 
1089  if (!(sql = ast_str_create(128))) {
1090  return -1;
1091  }
1092 
1093  while ((column = va_arg(ap, typeof(column)))) {
1094  type = va_arg(ap, typeof(type));
1095  sz = va_arg(ap, typeof(sz));
1096  if (first) {
1097  ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
1099  first = 0;
1100  } else {
1101  ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
1102  }
1103  }
1104 
1105  ast_str_append(&sql, 0, ")");
1106 
1107  res = realtime_sqlite3_exec_update_with_handle(db, ast_str_buffer(sql)) < 0 ? -1 : 0;
1108  ast_free(sql);
1109 
1110  return res;
1111 }
1112 
1113 /*! \brief If ast_realtime_require sends info about a column we don't have, create it
1114  */
1115 static int handle_missing_column(struct realtime_sqlite3_db *db, const char *table, const char *column, int type, size_t sz)
1116 {
1117  char *sql;
1118  const char *sqltype = get_sqlite_column_type(type);
1119  int res;
1120 
1122  ast_log(LOG_WARNING, "Missing column '%s' of type '%s' in %s.%s\n", column, sqltype, db->name, table);
1123  return -1;
1124  } else if (db->requirements == REALTIME_SQLITE3_REQ_CHAR) {
1125  sqltype = "TEXT";
1126  }
1127 
1128  if (!(sql = sqlite3_mprintf("ALTER TABLE \"%q\" ADD COLUMN \"%q\" %s", table, column, sqltype))) {
1129  return -1;
1130  }
1131 
1132  if (!(res = (realtime_sqlite3_exec_update_with_handle(db, sql) < 0 ? -1 : 0))) {
1133  ast_log(LOG_NOTICE, "Creating column '%s' type %s for table %s\n", column, sqltype, table);
1134  }
1135 
1136  sqlite3_free(sql);
1137 
1138  return res;
1139 }
1140 
1141 static int str_hash_fn(const void *obj, const int flags)
1142 {
1143  return ast_str_hash((const char *) obj);
1144 }
1145 
1146 static int str_cmp_fn(void *obj, void *arg, int flags) {
1147  return !strcasecmp((const char *) obj, (const char *) arg);
1148 }
1149 
1150 /*! \brief Callback for creating a hash of column names for comparison in realtime_sqlite3_require
1151  */
1152 static int add_column_name(void *arg, int num_columns, char **values, char **columns)
1153 {
1154  char *column;
1155  struct ao2_container *cnames = arg;
1156 
1157 
1158  if (!(column = ao2_alloc(strlen(values[1]) + 1, NULL))) {
1159  return -1;
1160  }
1161 
1162  strcpy(column, values[1]);
1163 
1164  ao2_link(cnames, column);
1165  ao2_ref(column, -1);
1166 
1167  return 0;
1168 }
1169 
1170 /*! \brief Callback for ast_realtime_require
1171  * \retval 0 Required fields met specified standards
1172  * \retval -1 One or more fields was missing or insufficient
1173  */
1174 static int realtime_sqlite3_require(const char *database, const char *table, va_list ap)
1175 {
1176  const char *column;
1177  char *sql;
1178  int type;
1179  int res;
1180  size_t sz;
1181  struct ao2_container *columns;
1182  struct realtime_sqlite3_db *db;
1183 
1184  /* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
1185  * return the results as char * anyway. The only field that cannot contain text
1186  * data is an INTEGER PRIMARY KEY, which must be a 64-bit signed integer. So, for
1187  * the purposes here we really only care whether the column exists and not what its
1188  * type or length is. */
1189 
1190  if (ast_strlen_zero(table)) {
1191  ast_log(LOG_WARNING, "Must have a table to query!\n");
1192  return -1;
1193  }
1194 
1195  if (!(db = find_database(database))) {
1196  return -1;
1197  }
1198 
1201  if (!columns) {
1202  unref_db(&db);
1203  return -1;
1204  }
1205 
1206  if (!(sql = sqlite3_mprintf("PRAGMA table_info(\"%q\")", table))) {
1207  unref_db(&db);
1208  ao2_ref(columns, -1);
1209  return -1;
1210  }
1211 
1212  if ((res = realtime_sqlite3_exec_query_with_handle(db, sql, add_column_name, columns)) < 0) {
1213  unref_db(&db);
1214  ao2_ref(columns, -1);
1215  sqlite3_free(sql);
1216  return -1;
1217  } else if (res == 0) {
1218  /* Table does not exist */
1219  sqlite3_free(sql);
1220  res = handle_missing_table(db, table, ap);
1221  ao2_ref(columns, -1);
1222  unref_db(&db);
1223  return res;
1224  }
1225 
1226  sqlite3_free(sql);
1227 
1228  while ((column = va_arg(ap, typeof(column)))) {
1229  char *found;
1230  type = va_arg(ap, typeof(type));
1231  sz = va_arg(ap, typeof(sz));
1232  if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
1233  if (handle_missing_column(db, table, column, type, sz)) {
1234  unref_db(&db);
1235  ao2_ref(columns, -1);
1236  return -1;
1237  }
1238  } else {
1239  ao2_ref(found, -1);
1240  }
1241  }
1242 
1243  ao2_ref(columns, -1);
1244  unref_db(&db);
1245 
1246  return 0;
1247 }
1248 
1249 /*! \brief Callback for clearing any cached info
1250  * \note We don't currently cache anything
1251  * \retval 0 If any cache was purged
1252  * \retval -1 If no cache was found
1253  */
1254 static int realtime_sqlite3_unload(const char *database, const char *table)
1255 {
1256  /* We currently do no caching */
1257  return -1;
1258 }
1259 
1260 /*! \brief Parse the res_config_sqlite3 config file
1261  */
1262 static int parse_config(int reload)
1263 {
1264  struct ast_config *config;
1265  struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME | (reload ? CONFIG_FLAG_FILEUNCHANGED : 0) };
1266  static const char *config_filename = "res_config_sqlite3.conf";
1267 
1268  config = ast_config_load(config_filename, config_flags);
1269 
1270  if (config == CONFIG_STATUS_FILEUNCHANGED) {
1271  ast_debug(1, "%s was unchanged, skipping parsing\n", config_filename);
1272  return 0;
1273  }
1274 
1276 
1277  if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
1278  ast_log(LOG_ERROR, "%s config file '%s'\n",
1279  config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
1281  return 0;
1282  } else {
1283  const char *cat;
1284  struct realtime_sqlite3_db *db;
1285 
1287  for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
1288  if (!strcasecmp(cat, "general")) {
1289  continue;
1290  }
1291  if (!(db = find_database(cat))) {
1292  if (!(db = new_realtime_sqlite3_db(config, cat))) {
1293  ast_log(LOG_WARNING, "Could not allocate new db for '%s' - skipping.\n", cat);
1294  continue;
1295  }
1296  if (db_open(db)) {
1297  unref_db(&db);
1298  continue;
1299  }
1300  db_start_batch(db);
1301  ao2_link(databases, db);
1302  unref_db(&db);
1303  } else {
1304  if (update_realtime_sqlite3_db(db, config, cat)) {
1305  unref_db(&db);
1306  continue;
1307  }
1308  unref_db(&db);
1309  }
1310  }
1312  }
1313 
1315 
1316  ast_config_destroy(config);
1317 
1318  return 0;
1319 }
1320 
1321 static int reload(void)
1322 {
1323  parse_config(1);
1324  return 0;
1325 }
1326 
1327 static int unload_module(void)
1328 {
1331  ao2_ref(databases, -1);
1332  databases = NULL;
1333  ast_config_engine_deregister(&sqlite3_config_engine);
1335 
1336  return 0;
1337 }
1338 
1339 static void discover_sqlite3_caps(void)
1340 {
1341  /*
1342  * So we cheat a little bit here. SQLite3 added support for the
1343  * 'ESCAPE' keyword in 3.1.0. They added SQLITE_VERSION_NUMBER
1344  * in 3.1.2. So if we run into 3.1.0 or 3.1.1 in the wild, we
1345  * just treat it like < 3.1.0.
1346  *
1347  * For reference: 3.1.0, 3.1.1, and 3.1.2 were all released
1348  * within 30 days of each other in Jan/Feb 2005, so I don't
1349  * imagine we'll be finding something pre-3.1.2 that often in
1350  * practice.
1351  */
1352 #if defined(SQLITE_VERSION_NUMBER)
1354 #else
1356 #endif
1357 
1358  ast_debug(3, "SQLite3 has 'LIKE ... ESCAPE ...' support? %s\n",
1359  has_explicit_like_escaping ? "Yes" : "No");
1360 }
1361 
1362 /*!
1363  * \brief Load the module
1364  *
1365  * Module loading including tests for configuration or dependencies.
1366  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
1367  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
1368  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
1369  * configuration file or other non-critical problem return
1370  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
1371  */
1372 static int load_module(void)
1373 {
1375 
1378  if (!databases) {
1379  return AST_MODULE_LOAD_DECLINE;
1380  }
1381 
1382  if (parse_config(0)) {
1383  ao2_ref(databases, -1);
1384  return AST_MODULE_LOAD_DECLINE;
1385  }
1386 
1387  if (!(ast_config_engine_register(&sqlite3_config_engine))) {
1388  ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
1389  ao2_ref(databases, -1);
1390  return AST_MODULE_LOAD_DECLINE;
1391  }
1392 
1393  return AST_MODULE_LOAD_SUCCESS;
1394 }
1395 
1396 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SQLite 3 realtime config engine",
1397  .support_level = AST_MODULE_SUPPORT_CORE,
1398  .load = load_module,
1399  .unload = unload_module,
1400  .reload = reload,
1401  .load_pri = AST_MODPRI_REALTIME_DRIVER,
1402  .requires = "extconfig",
1403 );
static const char * sqlite3_escape_column(const char *param)
static int db_open(struct realtime_sqlite3_db *db)
Open a database and appropriately set debugging on the db handle.
static struct realtime_sqlite3_db * new_realtime_sqlite3_db(struct ast_config *config, const char *cat)
Create a db object based on a config category.
struct ast_variable * next
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Definition: threadstorage.h:84
typedef typeof(dummy_tv_var_for_types.tv_sec) ast_time_t
static const char type[]
Definition: chan_ooh323.c:109
static int realtime_sqlite3_update2(const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
Realtime callback for updating a row based on multiple criteria.
static struct ast_threadstorage escape_column_buf
static const char * sqlite3_escape_column_op(const char *param)
const ast_string_field name
static const char * sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static int row_counter_wrapper(void *arg, int num_columns, char **values, char **columns)
void db_stop_batch(struct realtime_sqlite3_db *db)
static void unlink_dirty_databases(void)
static void * db_sync_thread(void *data)
Wrap commands in transactions increased write performance.
int(* callback_t)(void *, int, char **, char **)
static const char * get_sqlite_column_type(int type)
Convert Asterisk realtime types to SQLite 3 types.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Definition: ast_expr2.c:325
char * config
Definition: conf2ael.c:66
callback_t wrapped_callback
static const char * static_sql
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
#define OBJ_KEY
Definition: astobj2.h:1155
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int str_cmp_fn(void *obj, void *arg, int flags)
struct ast_flags flags
#define OBJ_POINTER
Definition: astobj2.h:1154
#define DB_BUCKETS
static sqlite3 * db
#define LOG_WARNING
Definition: logger.h:274
static int is_dirty_cb(void *obj, void *arg, int flags)
static struct ast_config * realtime_sqlite3_multi(const char *database, const char *table, const struct ast_variable *fields)
Realtime callback for a multi-row query.
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define CONFIG_STATUS_FILEINVALID
static void trace_cb(void *arg, const char *sql)
static int handle_missing_column(struct realtime_sqlite3_db *db, const char *table, const char *column, int type, size_t sz)
If ast_realtime_require sends info about a column we don&#39;t have, create it.
static int entity
Definition: isdn_lib.c:259
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
data for a thread locally stored variable
Definition: threadstorage.h:56
#define var
Definition: ast_expr2f.c:614
static int has_explicit_like_escaping
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
Definition: main/config.c:3006
struct ast_config * cfg
static int realtime_sqlite3_store(const char *database, const char *table, const struct ast_variable *fields)
Realtime callback for inserting a row.
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
char * cat_name
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Definition: main/config.c:2990
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_cond_init(cond, attr)
Definition: lock.h:199
static int stop_batch_cb(void *obj, void *arg, int flags)
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:337
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
const char * args
struct ast_config_engine sqlite3_config_engine
#define NULL
Definition: resample.c:96
static int realtime_sqlite3_exec_query_with_handle(struct realtime_sqlite3_db *, const char *, callback_t, void *)
static int realtime_sqlite3_unload(const char *database, const char *table)
Callback for clearing any cached info.
static void discover_sqlite3_caps(void)
void ast_category_destroy(struct ast_category *cat)
Definition: extconf.c:2847
#define ast_cond_signal(cond)
Definition: lock.h:201
struct ast_config * ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
Definition: main/config.c:3112
Configuration engine structure, used to define realtime drivers.
Utility functions.
pthread_cond_t ast_cond_t
Definition: lock.h:176
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int str_to_requirements(const char *data)
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
static char * table
Definition: cdr_odbc.c:58
static int parse_config(int reload)
Parse the res_config_sqlite3 config file.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
Configuration File Parser.
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.
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)
Realtime callback for static realtime.
struct ast_category * cat
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static void unref_db(struct realtime_sqlite3_db **db)
#define ast_config_load(filename, flags)
Load a config file.
static char * config_filename
Definition: extconf.c:2121
Asterisk file paths, configured in asterisk.conf.
struct ao2_container * databases
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:299
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int realtime_sqlite3_destroy(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
Realtime callback for deleting a row.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define ao2_lock(a)
Definition: astobj2.h:718
unsigned int has_batch_thread
static const char * sqlite3_escape_value(const char *param)
#define ast_variable_new(name, value, filename)
static int append_row_to_cfg(void *arg, int num_columns, char **values, char **columns)
Callback for creating an ast_config from a successive sqlite3 result rows.
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: extconf.c:3276
static int static_realtime_cb(void *arg, int num_columns, char **values, char **columns)
static int realtime_sqlite3_exec_query(const char *, const char *, callback_t, void *)
#define CONFIG_STATUS_FILEUNCHANGED
const char * who_asked
static void db_sync(struct realtime_sqlite3_db *db)
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void db_start_batch(struct realtime_sqlite3_db *db)
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define LOG_NOTICE
Definition: logger.h:263
static struct columns columns
#define ast_free(a)
Definition: astmm.h:182
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
Definition: main/config.c:3657
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int realtime_sqlite3_helper(const char *database, const char *table, const struct ast_variable *fields, int is_multi, void *arg)
Helper function for single and multi-row realtime load functions.
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static int row_to_varlist(void *arg, int num_columns, char **values, char **columns)
Create a varlist from a single sqlite3 result row.
static int db_hash_fn(const void *obj, const int flags)
static int realtime_sqlite3_update(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields)
Realtime callback for updating a row based on a single criteria.
static void mark_all_databases_dirty(void)
static int reload(void)
Structure used to handle boolean flags.
Definition: utils.h:199
static int realtime_sqlite3_exec_update(const char *, const char *)
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static int unload_module(void)
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: extconf.c:1178
#define CONFIG_STATUS_FILEMISSING
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Appends a category to a config.
Definition: extconf.c:2835
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
#define IS_SQL_LIKE_CLAUSE(x)
static void db_destructor(void *obj)
static int realtime_sqlite3_require(const char *database, const char *table, va_list ap)
Callback for ast_realtime_require.
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:663
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static const char * sqlite3_escape_table(const char *param)
static int mark_dirty_cb(void *obj, void *arg, int flags)
static struct ast_threadstorage escape_value_buf
static ast_mutex_t config_lock
static struct realtime_sqlite3_db * find_database(const char *database)
Generic container type.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
static int str_hash_fn(const void *obj, const int flags)
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
Definition: main/app.c:3113
static int handle_missing_table(struct realtime_sqlite3_db *db, const char *table, va_list ap)
Create a table if ast_realtime_require shows that we are configured to handle the data...
static int add_column_name(void *arg, int num_columns, char **values, char **columns)
Callback for creating a hash of column names for comparison in realtime_sqlite3_require.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
static struct ast_threadstorage escape_table_buf
static int realtime_sqlite3_exec_update_with_handle(struct realtime_sqlite3_db *, const char *)
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static struct ast_variable * realtime_sqlite3(const char *database, const char *table, const struct ast_variable *fields)
Realtime callback for a single row query.
static int db_cmp_fn(void *obj, void *arg, int flags)
static int load_module(void)
Load the module.
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition: lock.h:518
const ast_string_field filename
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549