#include "asterisk.h"
#include <sqlite.h>
#include "asterisk/logger.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/cdr.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/linkedlists.h"
Go to the source code of this file.
Data Structures | |
struct | cfg_entry_args |
struct | rt_cfg_entry_args |
struct | rt_multi_cfg_entry_args |
struct | sqlite_cache_columns |
struct | sqlite_cache_tables |
struct | sqlite_cache_tables::_columns |
struct | sqlite_tables |
Defines | |
#define | MACRO_BEGIN do { |
#define | MACRO_END } while (0) |
#define | release_table(a) AST_RWLIST_UNLOCK(&((a)->columns)) |
#define | RES_CONFIG_SQLITE_BEGIN |
#define | RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf" |
#define | RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2" |
#define | RES_CONFIG_SQLITE_DRIVER "sqlite" |
#define | RES_CONFIG_SQLITE_END(error) |
#define | RES_CONFIG_SQLITE_MAX_LOOPS 10 |
#define | RES_CONFIG_SQLITE_NAME "res_config_sqlite" |
#define | SET_VAR(config, to, from) |
#define | sql_get_config_table |
#define | sql_table_structure "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'" |
Enumerations | |
enum | { RES_CONFIG_SQLITE_CONFIG_ID, RES_CONFIG_SQLITE_CONFIG_CAT_METRIC, RES_CONFIG_SQLITE_CONFIG_VAR_METRIC, RES_CONFIG_SQLITE_CONFIG_COMMENTED, RES_CONFIG_SQLITE_CONFIG_FILENAME, RES_CONFIG_SQLITE_CONFIG_CATEGORY, RES_CONFIG_SQLITE_CONFIG_VAR_NAME, RES_CONFIG_SQLITE_CONFIG_VAR_VAL, RES_CONFIG_SQLITE_CONFIG_COLUMNS } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | add_cfg_entry (void *arg, int argc, char **argv, char **columnNames) |
SQLite callback function for static configuration. | |
static int | add_rt_cfg_entry (void *arg, int argc, char **argv, char **columnNames) |
SQLite callback function for RealTime configuration. | |
static int | add_rt_multi_cfg_entry (void *arg, int argc, char **argv, char **columnNames) |
SQLite callback function for RealTime configuration. | |
static int | cdr_handler (struct ast_cdr *cdr) |
Asterisk callback function for CDR support. | |
static int | check_vars (void) |
static struct ast_config * | config_handler (const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked) |
Asterisk callback function for static configuration. | |
static struct sqlite_cache_tables * | find_table (const char *tablename) |
static int | find_table_cb (void *vtblptr, int argc, char **argv, char **columnNames) |
static void | free_table (struct sqlite_cache_tables *tblptr) |
static size_t | get_params (va_list ap, const char ***params_ptr, const char ***vals_ptr) |
Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values. | |
static char * | handle_cli_show_sqlite_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Asterisk callback function for the CLI status command. | |
static char * | handle_cli_sqlite_show_tables (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | load_config (void) |
Load the configuration file. | |
static int | load_module (void) |
static int | realtime_destroy_handler (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap) |
Asterisk callback function for RealTime configuration (destroys variable). | |
static struct ast_variable * | realtime_handler (const char *database, const char *table, va_list ap) |
Asterisk callback function for RealTime configuration. | |
static struct ast_config * | realtime_multi_handler (const char *database, const char *table, va_list ap) |
Asterisk callback function for RealTime configuration. | |
static int | realtime_require_handler (const char *database, const char *table, va_list ap) |
static int | realtime_store_handler (const char *database, const char *table, va_list ap) |
Asterisk callback function for RealTime configuration (variable create/store). | |
static int | realtime_unload_handler (const char *unused, const char *tablename) |
static int | realtime_update_handler (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap) |
Asterisk callback function for RealTime configuration (variable update). | |
static int | set_var (char **var, const char *name, const char *value) |
Allocate a variable. | |
static void | unload_config (void) |
Free resources related to configuration. | |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime SQLite configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | cdr_registered |
static char * | cdr_table |
static struct ast_cli_entry | cli_status [] |
static int | cli_status_registered |
static char * | config_table |
static sqlite * | db |
static char * | dbfile |
static ast_mutex_t | mutex = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static char * | sql_create_cdr_table |
static struct ast_config_engine | sqlite_engine |
static int | use_cdr |
Definition in file res_config_sqlite.c.
#define MACRO_BEGIN do { |
Definition at line 93 of file res_config_sqlite.c.
#define MACRO_END } while (0) |
Definition at line 94 of file res_config_sqlite.c.
#define release_table | ( | a | ) | AST_RWLIST_UNLOCK(&((a)->columns)) |
#define RES_CONFIG_SQLITE_BEGIN |
Value:
MACRO_BEGIN \ int __i; \ \ for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++) {
Definition at line 149 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), load_module(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), and realtime_update_handler().
#define RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf" |
#define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2" |
#define RES_CONFIG_SQLITE_DRIVER "sqlite" |
Definition at line 97 of file res_config_sqlite.c.
#define RES_CONFIG_SQLITE_END | ( | error | ) |
Value:
if (error != SQLITE_BUSY) \ break; \ usleep(1000); \ } \ MACRO_END;
Definition at line 160 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), load_module(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), and realtime_update_handler().
#define RES_CONFIG_SQLITE_MAX_LOOPS 10 |
Maximum number of loops before giving up executing a query. Calls to sqlite_xxx() functions which can return SQLITE_BUSY are enclosed by RES_CONFIG_SQLITE_BEGIN and RES_CONFIG_SQLITE_END, e.g.
char *errormsg; int error;
RES_CONFIG_SQLITE_BEGIN error = sqlite_exec(db, query, NULL, NULL, &errormsg); RES_CONFIG_SQLITE_END(error)
if (error) ...;
Definition at line 142 of file res_config_sqlite.c.
#define RES_CONFIG_SQLITE_NAME "res_config_sqlite" |
Definition at line 96 of file res_config_sqlite.c.
Referenced by load_module(), and unload_module().
#define SET_VAR | ( | config, | |||
to, | |||||
from | ) |
#define sql_get_config_table |
Value:
"SELECT *" \ " FROM '%q'" \ " WHERE filename = '%q' AND commented = 0" \ " ORDER BY cat_metric ASC, var_metric ASC;"
Definition at line 560 of file res_config_sqlite.c.
Referenced by config_handler().
SQL query format to describe the table structure
Definition at line 552 of file res_config_sqlite.c.
anonymous enum |
Definition at line 101 of file res_config_sqlite.c.
00101 { 00102 RES_CONFIG_SQLITE_CONFIG_ID, 00103 RES_CONFIG_SQLITE_CONFIG_CAT_METRIC, 00104 RES_CONFIG_SQLITE_CONFIG_VAR_METRIC, 00105 RES_CONFIG_SQLITE_CONFIG_COMMENTED, 00106 RES_CONFIG_SQLITE_CONFIG_FILENAME, 00107 RES_CONFIG_SQLITE_CONFIG_CATEGORY, 00108 RES_CONFIG_SQLITE_CONFIG_VAR_NAME, 00109 RES_CONFIG_SQLITE_CONFIG_VAR_VAL, 00110 RES_CONFIG_SQLITE_CONFIG_COLUMNS, 00111 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 1787 of file res_config_sqlite.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1787 of file res_config_sqlite.c.
static int add_cfg_entry | ( | void * | arg, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
SQLite callback function for static configuration.
This function is passed to the SQLite engine as a callback function to parse a row and store it in a struct ast_config object. It relies on resulting rows being sorted by category.
arg | a pointer to a struct cfg_entry_args object | |
argc | number of columns | |
argv | values in the row | |
columnNames | names and types of the columns |
0 | on success | |
1 | if an error occurred |
Definition at line 845 of file res_config_sqlite.c.
References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_internal_load(), ast_free, ast_log(), ast_strdup, ast_variable_append(), ast_variable_new(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, cfg_entry_args::flags, LOG_WARNING, RES_CONFIG_SQLITE_CONFIG_CATEGORY, RES_CONFIG_SQLITE_CONFIG_COLUMNS, RES_CONFIG_SQLITE_CONFIG_VAR_NAME, RES_CONFIG_SQLITE_CONFIG_VAR_VAL, var, and cfg_entry_args::who_asked.
Referenced by config_handler().
00846 { 00847 struct cfg_entry_args *args; 00848 struct ast_variable *var; 00849 00850 if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) { 00851 ast_log(LOG_WARNING, "Corrupt table\n"); 00852 return 1; 00853 } 00854 00855 args = arg; 00856 00857 if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) { 00858 struct ast_config *cfg; 00859 char *val; 00860 00861 val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL]; 00862 cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked); 00863 00864 if (!cfg) { 00865 ast_log(LOG_WARNING, "Unable to include %s\n", val); 00866 return 1; 00867 } else { 00868 args->cfg = cfg; 00869 return 0; 00870 } 00871 } 00872 00873 if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) { 00874 args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999); 00875 00876 if (!args->cat) { 00877 ast_log(LOG_WARNING, "Unable to allocate category\n"); 00878 return 1; 00879 } 00880 00881 ast_free(args->cat_name); 00882 args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]); 00883 00884 if (!args->cat_name) { 00885 ast_category_destroy(args->cat); 00886 return 1; 00887 } 00888 00889 ast_category_append(args->cfg, args->cat); 00890 } 00891 00892 var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], ""); 00893 00894 if (!var) { 00895 ast_log(LOG_WARNING, "Unable to allocate variable"); 00896 return 1; 00897 } 00898 00899 ast_variable_append(args->cat, var); 00900 00901 return 0; 00902 }
static int add_rt_cfg_entry | ( | void * | arg, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
SQLite callback function for RealTime configuration.
This function is passed to the SQLite engine as a callback function to parse a row and store it in a linked list of struct ast_variable objects.
arg | a pointer to a struct rt_cfg_entry_args object | |
argc | number of columns | |
argv | values in the row | |
columnNames | names and types of the columns |
0 | on success. | |
1 | if an error occurred. |
Definition at line 992 of file res_config_sqlite.c.
References ast_variable_new(), rt_cfg_entry_args::last, ast_variable::next, rt_cfg_entry_args::var, and var.
Referenced by realtime_handler().
00993 { 00994 struct rt_cfg_entry_args *args; 00995 struct ast_variable *var; 00996 int i; 00997 00998 args = arg; 00999 01000 for (i = 0; i < argc; i++) { 01001 if (!argv[i]) 01002 continue; 01003 01004 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) 01005 return 1; 01006 01007 if (!args->var) 01008 args->var = var; 01009 01010 if (!args->last) 01011 args->last = var; 01012 else { 01013 args->last->next = var; 01014 args->last = var; 01015 } 01016 } 01017 01018 return 0; 01019 }
static int add_rt_multi_cfg_entry | ( | void * | arg, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
SQLite callback function for RealTime configuration.
This function performs the same actions as add_rt_cfg_entry() except that the rt_multi_cfg_entry_args structure is designed to store categories in addition to variables.
arg | a pointer to a struct rt_multi_cfg_entry_args object | |
argc | number of columns | |
argv | values in the row | |
columnNames | names and types of the columns |
0 | on success. | |
1 | if an error occurred. |
Definition at line 1111 of file res_config_sqlite.c.
References ast_category_append(), ast_category_new(), ast_log(), ast_variable_append(), ast_variable_new(), rt_multi_cfg_entry_args::cfg, rt_multi_cfg_entry_args::initfield, LOG_ERROR, LOG_WARNING, and var.
Referenced by realtime_multi_handler().
01112 { 01113 struct rt_multi_cfg_entry_args *args; 01114 struct ast_category *cat; 01115 struct ast_variable *var; 01116 char *cat_name; 01117 size_t i; 01118 01119 args = arg; 01120 cat_name = NULL; 01121 01122 /* 01123 * cat_name should always be set here, since initfield is forged from 01124 * params[0] in realtime_multi_handler(), which is a search parameter 01125 * of the SQL query. 01126 */ 01127 for (i = 0; i < argc; i++) { 01128 if (!strcmp(args->initfield, columnNames[i])) 01129 cat_name = argv[i]; 01130 } 01131 01132 if (!cat_name) { 01133 ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n"); 01134 return 1; 01135 } 01136 01137 if (!(cat = ast_category_new(cat_name, "", 99999))) { 01138 ast_log(LOG_WARNING, "Unable to allocate category\n"); 01139 return 1; 01140 } 01141 01142 ast_category_append(args->cfg, cat); 01143 01144 for (i = 0; i < argc; i++) { 01145 if (!argv[i] || !strcmp(args->initfield, columnNames[i])) 01146 continue; 01147 01148 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) { 01149 ast_log(LOG_WARNING, "Unable to allocate variable\n"); 01150 return 1; 01151 } 01152 01153 ast_variable_append(cat, var); 01154 } 01155 01156 return 0; 01157 }
static int cdr_handler | ( | struct ast_cdr * | cdr | ) | [static] |
Asterisk callback function for CDR support.
cdr | the CDR entry Asterisk sends us. |
0 | on success | |
1 | if an error occurred |
Definition at line 779 of file res_config_sqlite.c.
References ast_cdr_getvar(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_TRAVERSE, ast_str_append(), ast_str_create(), ast_str_set(), sqlite_cache_tables::columns, find_table(), sqlite_cache_columns::isint, LOG_ERROR, LOG_WARNING, mutex, sqlite_cache_columns::name, release_table, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, ast_str::str, and ast_str::used.
Referenced by load_module().
00780 { 00781 char *errormsg = NULL, *tmp, workspace[500]; 00782 int error, scannum; 00783 struct sqlite_cache_tables *tbl = find_table(cdr_table); 00784 struct sqlite_cache_columns *col; 00785 struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16); 00786 00787 if (!tbl) { 00788 ast_log(LOG_WARNING, "No such table: %s\n", cdr_table); 00789 return -1; 00790 } 00791 00792 ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table); 00793 ast_str_set(&sql2, 0, ") VALUES ("); 00794 00795 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) { 00796 if (col->isint) { 00797 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1); 00798 if (!tmp) { 00799 continue; 00800 } 00801 if (sscanf(tmp, "%d", &scannum) == 1) { 00802 ast_str_append(&sql1, 0, "%s,", col->name); 00803 ast_str_append(&sql2, 0, "%d,", scannum); 00804 } 00805 } else { 00806 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0); 00807 if (!tmp) { 00808 continue; 00809 } 00810 ast_str_append(&sql1, 0, "%s,", col->name); 00811 tmp = sqlite_mprintf("%Q", tmp); 00812 ast_str_append(&sql2, 0, "%s,", tmp); 00813 sqlite_freemem(tmp); 00814 } 00815 } 00816 release_table(tbl); 00817 00818 sql1->str[--sql1->used] = '\0'; 00819 sql2->str[--sql2->used] = '\0'; 00820 ast_str_append(&sql1, 0, "%s)", sql2->str); 00821 ast_free(sql2); 00822 00823 ast_debug(1, "SQL query: %s\n", sql1->str); 00824 00825 ast_mutex_lock(&mutex); 00826 00827 RES_CONFIG_SQLITE_BEGIN 00828 error = sqlite_exec(db, sql1->str, NULL, NULL, &errormsg); 00829 RES_CONFIG_SQLITE_END(error) 00830 00831 ast_mutex_unlock(&mutex); 00832 00833 ast_free(sql1); 00834 00835 if (error) { 00836 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 00837 sqlite_freemem(errormsg); 00838 return 1; 00839 } 00840 sqlite_freemem(errormsg); 00841 00842 return 0; 00843 }
static int check_vars | ( | void | ) | [static] |
static struct ast_config * config_handler | ( | const char * | database, | |
const char * | table, | |||
const char * | file, | |||
struct ast_config * | cfg, | |||
struct ast_flags | flags, | |||
const char * | suggested_incl, | |||
const char * | who_asked | |||
) | [static] |
Asterisk callback function for static configuration.
Asterisk will call this function when it loads its static configuration, which usually happens at startup and reload.
database | the database to use (ignored) | |
table | the table to use | |
file | the file to load from the database | |
cfg | the struct ast_config object to use when storing variables | |
flags | Optional flags. Not used. | |
suggested_incl | suggest include. |
cfg | object | |
NULL | if an error occurred |
Definition at line 904 of file res_config_sqlite.c.
References add_cfg_entry(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), cfg_entry_args::cat, cfg_entry_args::cat_name, cfg_entry_args::cfg, cfg_entry_args::flags, LOG_ERROR, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, sql_get_config_table, and cfg_entry_args::who_asked.
00906 { 00907 struct cfg_entry_args args; 00908 char *query, *errormsg = NULL; 00909 int error; 00910 00911 if (!config_table) { 00912 if (!table) { 00913 ast_log(LOG_ERROR, "Table name unspecified\n"); 00914 return NULL; 00915 } 00916 } else 00917 table = config_table; 00918 00919 query = sqlite_mprintf(sql_get_config_table, table, file); 00920 00921 if (!query) { 00922 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 00923 return NULL; 00924 } 00925 00926 ast_debug(1, "SQL query: %s\n", query); 00927 args.cfg = cfg; 00928 args.cat = NULL; 00929 args.cat_name = NULL; 00930 args.flags = flags; 00931 args.who_asked = who_asked; 00932 00933 ast_mutex_lock(&mutex); 00934 00935 RES_CONFIG_SQLITE_BEGIN 00936 error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg); 00937 RES_CONFIG_SQLITE_END(error) 00938 00939 ast_mutex_unlock(&mutex); 00940 00941 ast_free(args.cat_name); 00942 sqlite_freemem(query); 00943 00944 if (error) { 00945 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 00946 sqlite_freemem(errormsg); 00947 return NULL; 00948 } 00949 sqlite_freemem(errormsg); 00950 00951 return cfg; 00952 }
static struct sqlite_cache_tables* find_table | ( | const char * | tablename | ) | [static] |
Definition at line 635 of file res_config_sqlite.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, sqlite_cache_tables::list, and sqlite_cache_tables::name.
00636 { 00637 struct sqlite_cache_tables *tblptr; 00638 int i, err; 00639 char *sql, *errstr = NULL; 00640 00641 AST_RWLIST_RDLOCK(&sqlite_tables); 00642 00643 for (i = 0; i < 2; i++) { 00644 AST_RWLIST_TRAVERSE(&sqlite_tables, tblptr, list) { 00645 if (strcmp(tblptr->name, tablename) == 0) { 00646 break; 00647 } 00648 } 00649 if (tblptr) { 00650 AST_RWLIST_RDLOCK(&(tblptr->columns)); 00651 AST_RWLIST_UNLOCK(&sqlite_tables); 00652 return tblptr; 00653 } 00654 00655 if (i == 0) { 00656 AST_RWLIST_UNLOCK(&sqlite_tables); 00657 AST_RWLIST_WRLOCK(&sqlite_tables); 00658 } 00659 } 00660 00661 /* Table structure not cached; build the structure now */ 00662 if (asprintf(&sql, sql_table_structure, tablename) < 0) { 00663 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00664 sql = NULL; 00665 } 00666 if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) { 00667 AST_RWLIST_UNLOCK(&sqlite_tables); 00668 ast_log(LOG_ERROR, "Memory error. Cannot cache table '%s'\n", tablename); 00669 return NULL; 00670 } 00671 tblptr->name = (char *)tblptr + sizeof(*tblptr); 00672 strcpy(tblptr->name, tablename); /* SAFE */ 00673 AST_RWLIST_HEAD_INIT(&(tblptr->columns)); 00674 00675 ast_debug(1, "About to query table structure: %s\n", sql); 00676 00677 ast_mutex_lock(&mutex); 00678 if ((err = sqlite_exec(db, sql, find_table_cb, tblptr, &errstr))) { 00679 ast_mutex_unlock(&mutex); 00680 ast_log(LOG_WARNING, "SQLite error %d: %s\n", err, errstr); 00681 ast_free(errstr); 00682 free_table(tblptr); 00683 return NULL; 00684 } 00685 ast_mutex_unlock(&mutex); 00686 00687 if (AST_LIST_EMPTY(&(tblptr->columns))) { 00688 free_table(tblptr); 00689 return NULL; 00690 } 00691 00692 AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list); 00693 AST_RWLIST_RDLOCK(&(tblptr->columns)); 00694 AST_RWLIST_UNLOCK(&sqlite_tables); 00695 return tblptr; 00696 }
static int find_table_cb | ( | void * | vtblptr, | |
int | argc, | |||
char ** | argv, | |||
char ** | columnNames | |||
) | [static] |
Definition at line 580 of file res_config_sqlite.c.
References AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, AST_RWLIST_TRAVERSE, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdupa, sqlite_cache_tables::columns, sqlite_cache_columns::isint, sqlite_cache_columns::name, strcasestr(), and sqlite_cache_columns::type.
00581 { 00582 struct sqlite_cache_tables *tblptr = vtblptr; 00583 char *sql = ast_strdupa(argv[0]), *start, *end, *type, *remainder; 00584 int i; 00585 AST_DECLARE_APP_ARGS(fie, 00586 AST_APP_ARG(ld)[100]; /* This means we support up to 100 columns per table */ 00587 ); 00588 struct sqlite_cache_columns *col; 00589 00590 /* This is really fun. We get to parse an SQL statement to figure out 00591 * what columns are in the table. 00592 */ 00593 if ((start = strchr(sql, '(')) && (end = strrchr(sql, ')'))) { 00594 start++; 00595 *end = '\0'; 00596 } else { 00597 /* Abort */ 00598 return -1; 00599 } 00600 00601 AST_STANDARD_APP_ARGS(fie, start); 00602 for (i = 0; i < fie.argc; i++) { 00603 fie.ld[i] = ast_skip_blanks(fie.ld[i]); 00604 ast_debug(5, "Found field: %s\n", fie.ld[i]); 00605 if (strncasecmp(fie.ld[i], "PRIMARY KEY", 11) == 0 && (start = strchr(fie.ld[i], '(')) && (end = strchr(fie.ld[i], ')'))) { 00606 *end = '\0'; 00607 AST_RWLIST_TRAVERSE(&(tblptr->columns), col, list) { 00608 if (strcasecmp(start + 1, col->name) == 0 && strcasestr(col->type, "INTEGER")) { 00609 col->isint = 1; 00610 } 00611 } 00612 continue; 00613 } 00614 /* type delimiter could be any space character */ 00615 for (type = fie.ld[i]; *type > 32; type++); 00616 *type++ = '\0'; 00617 type = ast_skip_blanks(type); 00618 for (remainder = type; *remainder > 32; remainder++); 00619 *remainder = '\0'; 00620 if (!(col = ast_calloc(1, sizeof(*col) + strlen(fie.ld[i]) + strlen(type) + 2))) { 00621 return -1; 00622 } 00623 col->name = (char *)col + sizeof(*col); 00624 col->type = (char *)col + sizeof(*col) + strlen(fie.ld[i]) + 1; 00625 strcpy(col->name, fie.ld[i]); /* SAFE */ 00626 strcpy(col->type, type); /* SAFE */ 00627 if (strcasestr(col->type, "INTEGER") && strcasestr(col->type, "PRIMARY KEY")) { 00628 col->isint = 1; 00629 } 00630 AST_LIST_INSERT_TAIL(&(tblptr->columns), col, list); 00631 } 00632 return 0; 00633 }
static void free_table | ( | struct sqlite_cache_tables * | tblptr | ) | [static] |
Definition at line 566 of file res_config_sqlite.c.
References ast_free, AST_RWLIST_HEAD_DESTROY, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and sqlite_cache_tables::columns.
Referenced by realtime_unload_handler(), and unload_config().
00567 { 00568 struct sqlite_cache_columns *col; 00569 00570 /* Obtain a write lock to ensure there are no read locks outstanding */ 00571 AST_RWLIST_WRLOCK(&(tblptr->columns)); 00572 while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) { 00573 ast_free(col); 00574 } 00575 AST_RWLIST_UNLOCK(&(tblptr->columns)); 00576 AST_RWLIST_HEAD_DESTROY(&(tblptr->columns)); 00577 ast_free(tblptr); 00578 }
static size_t get_params | ( | va_list | ap, | |
const char *** | params_ptr, | |||
const char *** | vals_ptr | |||
) | [static] |
Helper function to parse a va_list object into 2 dynamic arrays of strings, parameters and values.
ap must have the following format : param1 val1 param2 val2 param3 val3 ... arguments will be extracted to create 2 arrays:
The address of these arrays are stored in params_ptr and vals_ptr. It is the responsibility of the caller to release the memory of these arrays. It is considered an error that va_list has a null or odd number of strings.
ap | the va_list object to parse | |
params_ptr | where the address of the params array is stored | |
vals_ptr | where the address of the vals array is stored |
the | number of elements in the arrays (which have the same size). | |
0 | if an error occurred. |
Definition at line 954 of file res_config_sqlite.c.
References ast_free, ast_log(), ast_realloc, and LOG_WARNING.
Referenced by realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), and realtime_update_handler().
00955 { 00956 const char **tmp, *param, *val, **params, **vals; 00957 size_t params_count; 00958 00959 params = NULL; 00960 vals = NULL; 00961 params_count = 0; 00962 00963 while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) { 00964 if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) { 00965 ast_free(params); 00966 ast_free(vals); 00967 return 0; 00968 } 00969 params = tmp; 00970 00971 if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) { 00972 ast_free(params); 00973 ast_free(vals); 00974 return 0; 00975 } 00976 vals = tmp; 00977 00978 params[params_count] = param; 00979 vals[params_count] = val; 00980 params_count++; 00981 } 00982 00983 if (params_count > 0) { 00984 *params_ptr = params; 00985 *vals_ptr = vals; 00986 } else 00987 ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n"); 00988 00989 return params_count; 00990 }
static char * handle_cli_show_sqlite_status | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Asterisk callback function for the CLI status command.
e | CLI command | |
cmd | ||
a | CLI argument list |
Definition at line 1582 of file res_config_sqlite.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
01583 { 01584 switch (cmd) { 01585 case CLI_INIT: 01586 e->command = "sqlite show status"; 01587 e->usage = 01588 "Usage: sqlite show status\n" 01589 " Show status information about the SQLite 2 driver\n"; 01590 return NULL; 01591 case CLI_GENERATE: 01592 return NULL; 01593 } 01594 01595 if (a->argc != 3) 01596 return CLI_SHOWUSAGE; 01597 01598 ast_cli(a->fd, "SQLite database path: %s\n", dbfile); 01599 ast_cli(a->fd, "config_table: "); 01600 01601 if (!config_table) 01602 ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n"); 01603 else 01604 ast_cli(a->fd, "%s\n", config_table); 01605 01606 ast_cli(a->fd, "cdr_table: "); 01607 01608 if (!cdr_table) 01609 ast_cli(a->fd, "unspecified, CDR support disabled\n"); 01610 else 01611 ast_cli(a->fd, "%s\n", cdr_table); 01612 01613 return CLI_SUCCESS; 01614 }
static char * handle_cli_sqlite_show_tables | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1616 of file res_config_sqlite.c.
References ast_cli_args::argc, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, sqlite_cache_tables::columns, ast_cli_entry::command, ast_cli_args::fd, sqlite_cache_columns::list, sqlite_cache_columns::name, sqlite_cache_tables::name, sqlite_cache_columns::type, and ast_cli_entry::usage.
01617 { 01618 struct sqlite_cache_tables *tbl; 01619 struct sqlite_cache_columns *col; 01620 int found = 0; 01621 01622 switch (cmd) { 01623 case CLI_INIT: 01624 e->command = "sqlite show tables"; 01625 e->usage = 01626 "Usage: sqlite show tables\n" 01627 " Show table information about the SQLite 2 driver\n"; 01628 return NULL; 01629 case CLI_GENERATE: 01630 return NULL; 01631 } 01632 01633 if (a->argc != 3) 01634 return CLI_SHOWUSAGE; 01635 01636 AST_RWLIST_RDLOCK(&sqlite_tables); 01637 AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) { 01638 found++; 01639 ast_cli(a->fd, "Table %s:\n", tbl->name); 01640 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) { 01641 fprintf(stderr, "%s\n", col->name); 01642 ast_cli(a->fd, " %20.20s %-30.30s\n", col->name, col->type); 01643 } 01644 } 01645 AST_RWLIST_UNLOCK(&sqlite_tables); 01646 01647 if (!found) { 01648 ast_cli(a->fd, "No tables currently in cache\n"); 01649 } 01650 01651 return CLI_SUCCESS; 01652 }
static int load_config | ( | void | ) | [static] |
Load the configuration file.
0 | on success | |
1 | if an error occurred |
Definition at line 727 of file res_config_sqlite.c.
References ast_config_load, ast_log(), ast_variable_browse(), config, config_flags, LOG_ERROR, LOG_WARNING, RES_CONFIG_SQLITE_CONF_FILE, SET_VAR, and var.
00728 { 00729 struct ast_config *config; 00730 struct ast_variable *var; 00731 int error; 00732 struct ast_flags config_flags = { 0 }; 00733 00734 config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags); 00735 00736 if (!config) { 00737 ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n"); 00738 return 1; 00739 } 00740 00741 for (var = ast_variable_browse(config, "general"); var; var = var->next) { 00742 if (!strcasecmp(var->name, "dbfile")) 00743 SET_VAR(config, dbfile, var); 00744 else if (!strcasecmp(var->name, "config_table")) 00745 SET_VAR(config, config_table, var); 00746 else if (!strcasecmp(var->name, "cdr_table")) { 00747 SET_VAR(config, cdr_table, var); 00748 } else 00749 ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name); 00750 } 00751 00752 ast_config_destroy(config); 00753 error = check_vars(); 00754 00755 if (error) { 00756 unload_config(); 00757 return 1; 00758 } 00759 00760 return 0; 00761 }
static int load_module | ( | void | ) | [static] |
Definition at line 1672 of file res_config_sqlite.c.
References ast_cdr_register(), ast_cli_register_multiple(), ast_config_engine_register(), ast_debug, ast_log(), AST_MODULE_LOAD_DECLINE, cdr_handler(), cli_status, load_config(), LOG_ERROR, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_DESCRIPTION, RES_CONFIG_SQLITE_END, RES_CONFIG_SQLITE_NAME, S_OR, sql_create_cdr_table, sqlite_engine, and unload_module().
01673 { 01674 char *errormsg = NULL; 01675 int error; 01676 01677 db = NULL; 01678 cdr_registered = 0; 01679 cli_status_registered = 0; 01680 dbfile = NULL; 01681 config_table = NULL; 01682 cdr_table = NULL; 01683 error = load_config(); 01684 01685 if (error) 01686 return AST_MODULE_LOAD_DECLINE; 01687 01688 if (!(db = sqlite_open(dbfile, 0660, &errormsg))) { 01689 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01690 sqlite_freemem(errormsg); 01691 unload_module(); 01692 return 1; 01693 } 01694 01695 sqlite_freemem(errormsg); 01696 errormsg = NULL; 01697 ast_config_engine_register(&sqlite_engine); 01698 01699 if (use_cdr) { 01700 char *query; 01701 01702 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01703 #undef QUERY 01704 #define QUERY "SELECT COUNT(id) FROM %Q;" 01705 /* \endcond */ 01706 01707 query = sqlite_mprintf(QUERY, cdr_table); 01708 01709 if (!query) { 01710 ast_log(LOG_ERROR, "Unable to allocate SQL query\n"); 01711 unload_module(); 01712 return 1; 01713 } 01714 01715 ast_debug(1, "SQL query: %s\n", query); 01716 01717 RES_CONFIG_SQLITE_BEGIN 01718 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01719 RES_CONFIG_SQLITE_END(error) 01720 01721 sqlite_freemem(query); 01722 01723 if (error) { 01724 /* 01725 * Unexpected error. 01726 */ 01727 if (error != SQLITE_ERROR) { 01728 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01729 sqlite_freemem(errormsg); 01730 unload_module(); 01731 return 1; 01732 } 01733 01734 sqlite_freemem(errormsg); 01735 errormsg = NULL; 01736 query = sqlite_mprintf(sql_create_cdr_table, cdr_table); 01737 01738 if (!query) { 01739 ast_log(LOG_ERROR, "Unable to allocate SQL query\n"); 01740 unload_module(); 01741 return 1; 01742 } 01743 01744 ast_debug(1, "SQL query: %s\n", query); 01745 01746 RES_CONFIG_SQLITE_BEGIN 01747 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01748 RES_CONFIG_SQLITE_END(error) 01749 01750 sqlite_freemem(query); 01751 01752 if (error) { 01753 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01754 sqlite_freemem(errormsg); 01755 unload_module(); 01756 return 1; 01757 } 01758 } 01759 sqlite_freemem(errormsg); 01760 errormsg = NULL; 01761 01762 error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler); 01763 01764 if (error) { 01765 unload_module(); 01766 return 1; 01767 } 01768 01769 cdr_registered = 1; 01770 } 01771 01772 error = ast_cli_register_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry)); 01773 01774 if (error) { 01775 unload_module(); 01776 return 1; 01777 } 01778 01779 cli_status_registered = 1; 01780 01781 return 0; 01782 }
static int realtime_destroy_handler | ( | const char * | database, | |
const char * | table, | |||
const char * | keyfield, | |||
const char * | entity, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration (destroys variable).
Asterisk will call this function each time a variable has been destroyed internally and must be removed from the backend engine. keyfield and entity are used to find the row to delete, e.g. DELETE FROM table WHERE keyfield = 'entity';
. ap is a list of parameters and values with the same format as the other realtime functions.
database | the database to use (ignored) | |
table | the table to use | |
keyfield | the column of the matching cell | |
entity | the value of the matching cell | |
ap | list of additional parameters for cell matching |
the | number of affected rows. | |
-1 | if an error occurred. |
Definition at line 1454 of file res_config_sqlite.c.
References ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01456 { 01457 char *query, *errormsg = NULL, *tmp_str; 01458 const char **params, **vals; 01459 size_t params_count; 01460 int error, rows_num; 01461 size_t i; 01462 01463 if (!table) { 01464 ast_log(LOG_WARNING, "Table name unspecified\n"); 01465 return -1; 01466 } 01467 01468 if (!(params_count = get_params(ap, ¶ms, &vals))) 01469 return -1; 01470 01471 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01472 #undef QUERY 01473 #define QUERY "DELETE FROM '%q' WHERE" 01474 /* \endcond */ 01475 01476 if (!(query = sqlite_mprintf(QUERY, table))) { 01477 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01478 ast_free(params); 01479 ast_free(vals); 01480 return -1; 01481 } 01482 01483 for (i = 0; i < params_count; i++) { 01484 tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]); 01485 sqlite_freemem(query); 01486 01487 if (!tmp_str) { 01488 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01489 ast_free(params); 01490 ast_free(vals); 01491 return -1; 01492 } 01493 01494 query = tmp_str; 01495 } 01496 01497 ast_free(params); 01498 ast_free(vals); 01499 if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) { 01500 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01501 sqlite_freemem(query); 01502 return -1; 01503 } 01504 sqlite_freemem(query); 01505 query = tmp_str; 01506 ast_debug(1, "SQL query: %s\n", query); 01507 01508 ast_mutex_lock(&mutex); 01509 01510 RES_CONFIG_SQLITE_BEGIN 01511 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01512 RES_CONFIG_SQLITE_END(error) 01513 01514 if (!error) 01515 rows_num = sqlite_changes(db); 01516 else 01517 rows_num = -1; 01518 01519 ast_mutex_unlock(&mutex); 01520 01521 sqlite_freemem(query); 01522 01523 if (error) { 01524 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01525 } 01526 sqlite_freemem(errormsg); 01527 01528 return rows_num; 01529 }
static struct ast_variable * realtime_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration.
Asterisk will call this function each time it requires a variable through the RealTime architecture. ap is a list of parameters and values used to find a specific row, e.g one parameter "name" and one value "123" so that the SQL query becomes SELECT * FROM table WHERE name = '123';
.
database | the database to use (ignored) | |
table | the table to use | |
ap | list of parameters and values to match |
a | linked list of struct ast_variable objects | |
NULL | if an error occurred |
Definition at line 1021 of file res_config_sqlite.c.
References add_rt_cfg_entry(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variables_destroy(), get_params(), rt_cfg_entry_args::last, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, S_OR, and rt_cfg_entry_args::var.
01022 { 01023 char *query, *errormsg = NULL, *op, *tmp_str; 01024 struct rt_cfg_entry_args args; 01025 const char **params, **vals; 01026 size_t params_count; 01027 int error; 01028 01029 if (!table) { 01030 ast_log(LOG_WARNING, "Table name unspecified\n"); 01031 return NULL; 01032 } 01033 01034 params_count = get_params(ap, ¶ms, &vals); 01035 01036 if (params_count == 0) 01037 return NULL; 01038 01039 op = (strchr(params[0], ' ') == NULL) ? " =" : ""; 01040 01041 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01042 #undef QUERY 01043 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'" 01044 /* \endcond */ 01045 01046 query = sqlite_mprintf(QUERY, table, params[0], op, vals[0]); 01047 01048 if (!query) { 01049 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01050 ast_free(params); 01051 ast_free(vals); 01052 return NULL; 01053 } 01054 01055 if (params_count > 1) { 01056 size_t i; 01057 01058 for (i = 1; i < params_count; i++) { 01059 op = (strchr(params[i], ' ') == NULL) ? " =" : ""; 01060 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]); 01061 sqlite_freemem(query); 01062 01063 if (!tmp_str) { 01064 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01065 ast_free(params); 01066 ast_free(vals); 01067 return NULL; 01068 } 01069 01070 query = tmp_str; 01071 } 01072 } 01073 01074 ast_free(params); 01075 ast_free(vals); 01076 01077 tmp_str = sqlite_mprintf("%s LIMIT 1;", query); 01078 sqlite_freemem(query); 01079 01080 if (!tmp_str) { 01081 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01082 return NULL; 01083 } 01084 01085 query = tmp_str; 01086 ast_debug(1, "SQL query: %s\n", query); 01087 args.var = NULL; 01088 args.last = NULL; 01089 01090 ast_mutex_lock(&mutex); 01091 01092 RES_CONFIG_SQLITE_BEGIN 01093 error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg); 01094 RES_CONFIG_SQLITE_END(error) 01095 01096 ast_mutex_unlock(&mutex); 01097 01098 sqlite_freemem(query); 01099 01100 if (error) { 01101 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01102 sqlite_freemem(errormsg); 01103 ast_variables_destroy(args.var); 01104 return NULL; 01105 } 01106 sqlite_freemem(errormsg); 01107 01108 return args.var; 01109 }
static struct ast_config * realtime_multi_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration.
This function performs the same actions as realtime_handler() except that it can store variables per category, and can return several categories.
database | the database to use (ignored) | |
table | the table to use | |
ap | list of parameters and values to match |
a | struct ast_config object storing categories and variables. | |
NULL | if an error occurred. |
Definition at line 1159 of file res_config_sqlite.c.
References add_rt_multi_cfg_entry(), ast_config_destroy(), ast_config_new(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, rt_multi_cfg_entry_args::cfg, get_params(), rt_multi_cfg_entry_args::initfield, LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01161 { 01162 char *query, *errormsg = NULL, *op, *tmp_str, *initfield; 01163 struct rt_multi_cfg_entry_args args; 01164 const char **params, **vals; 01165 struct ast_config *cfg; 01166 size_t params_count; 01167 int error; 01168 01169 if (!table) { 01170 ast_log(LOG_WARNING, "Table name unspecified\n"); 01171 return NULL; 01172 } 01173 01174 if (!(cfg = ast_config_new())) { 01175 ast_log(LOG_WARNING, "Unable to allocate configuration structure\n"); 01176 return NULL; 01177 } 01178 01179 if (!(params_count = get_params(ap, ¶ms, &vals))) { 01180 ast_config_destroy(cfg); 01181 return NULL; 01182 } 01183 01184 if (!(initfield = ast_strdup(params[0]))) { 01185 ast_config_destroy(cfg); 01186 ast_free(params); 01187 ast_free(vals); 01188 return NULL; 01189 } 01190 01191 tmp_str = strchr(initfield, ' '); 01192 01193 if (tmp_str) 01194 *tmp_str = '\0'; 01195 01196 op = (!strchr(params[0], ' ')) ? " =" : ""; 01197 01198 /* 01199 * Asterisk sends us an already escaped string when searching for 01200 * "exten LIKE" (uh!). Handle it separately. 01201 */ 01202 tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0]; 01203 01204 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01205 #undef QUERY 01206 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'" 01207 /* \endcond */ 01208 01209 if (!(query = sqlite_mprintf(QUERY, table, params[0], op, tmp_str))) { 01210 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01211 ast_config_destroy(cfg); 01212 ast_free(params); 01213 ast_free(vals); 01214 ast_free(initfield); 01215 return NULL; 01216 } 01217 01218 if (params_count > 1) { 01219 size_t i; 01220 01221 for (i = 1; i < params_count; i++) { 01222 op = (!strchr(params[i], ' ')) ? " =" : ""; 01223 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]); 01224 sqlite_freemem(query); 01225 01226 if (!tmp_str) { 01227 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01228 ast_config_destroy(cfg); 01229 ast_free(params); 01230 ast_free(vals); 01231 ast_free(initfield); 01232 return NULL; 01233 } 01234 01235 query = tmp_str; 01236 } 01237 } 01238 01239 ast_free(params); 01240 ast_free(vals); 01241 01242 if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) { 01243 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01244 sqlite_freemem(query); 01245 ast_config_destroy(cfg); 01246 ast_free(initfield); 01247 return NULL; 01248 } 01249 01250 sqlite_freemem(query); 01251 query = tmp_str; 01252 ast_debug(1, "SQL query: %s\n", query); 01253 args.cfg = cfg; 01254 args.initfield = initfield; 01255 01256 ast_mutex_lock(&mutex); 01257 01258 RES_CONFIG_SQLITE_BEGIN 01259 error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg); 01260 RES_CONFIG_SQLITE_END(error) 01261 01262 ast_mutex_unlock(&mutex); 01263 01264 sqlite_freemem(query); 01265 ast_free(initfield); 01266 01267 if (error) { 01268 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01269 sqlite_freemem(errormsg); 01270 ast_config_destroy(cfg); 01271 return NULL; 01272 } 01273 sqlite_freemem(errormsg); 01274 01275 return cfg; 01276 }
static int realtime_require_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Definition at line 1531 of file res_config_sqlite.c.
References ast_log(), ast_rq_is_int(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, sqlite_cache_tables::columns, find_table(), sqlite_cache_columns::isint, sqlite_cache_columns::list, LOG_WARNING, sqlite_cache_columns::name, and type.
01532 { 01533 struct sqlite_cache_tables *tbl = find_table(tablename); 01534 struct sqlite_cache_columns *col; 01535 char *elm; 01536 int type, size, res = 0; 01537 01538 if (!tbl) { 01539 return -1; 01540 } 01541 01542 while ((elm = va_arg(ap, char *))) { 01543 type = va_arg(ap, require_type); 01544 size = va_arg(ap, int); 01545 /* Check if the field matches the criteria */ 01546 AST_RWLIST_TRAVERSE(&tbl->columns, col, list) { 01547 if (strcmp(col->name, elm) == 0) { 01548 /* SQLite only has two types - the 32-bit integer field that 01549 * is the key column, and everything else (everything else 01550 * being a string). 01551 */ 01552 if (col->isint && !ast_rq_is_int(type)) { 01553 ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name); 01554 res = -1; 01555 } 01556 break; 01557 } 01558 } 01559 if (!col) { 01560 ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm); 01561 } 01562 } 01563 AST_RWLIST_UNLOCK(&(tbl->columns)); 01564 return res; 01565 }
static int realtime_store_handler | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration (variable create/store).
Asterisk will call this function each time a variable has been created internally and must be stored in the backend engine. are used to find the row to update, e.g. ap is a list of parameters and values with the same format as the other realtime functions.
database | the database to use (ignored) | |
table | the table to use | |
ap | list of parameters and new values to insert into the database |
the | rowid of inserted row. | |
-1 | if an error occurred. |
Definition at line 1360 of file res_config_sqlite.c.
References ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01361 { 01362 char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL; 01363 const char **params, **vals; 01364 size_t params_count; 01365 int error, rows_id; 01366 size_t i; 01367 01368 if (!table) { 01369 ast_log(LOG_WARNING, "Table name unspecified\n"); 01370 return -1; 01371 } 01372 01373 if (!(params_count = get_params(ap, ¶ms, &vals))) 01374 return -1; 01375 01376 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01377 #undef QUERY 01378 #define QUERY "INSERT into '%q' (%s) VALUES (%s);" 01379 /* \endcond */ 01380 01381 for (i = 0; i < params_count; i++) { 01382 if ( tmp_keys2 ) { 01383 tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]); 01384 sqlite_freemem(tmp_keys2); 01385 } else { 01386 tmp_keys = sqlite_mprintf("%q", params[i]); 01387 } 01388 if (!tmp_keys) { 01389 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01390 sqlite_freemem(tmp_vals); 01391 ast_free(params); 01392 ast_free(vals); 01393 return -1; 01394 } 01395 01396 if ( tmp_vals2 ) { 01397 tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, params[i]); 01398 sqlite_freemem(tmp_vals2); 01399 } else { 01400 tmp_vals = sqlite_mprintf("'%q'", params[i]); 01401 } 01402 if (!tmp_vals) { 01403 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01404 sqlite_freemem(tmp_keys); 01405 ast_free(params); 01406 ast_free(vals); 01407 return -1; 01408 } 01409 01410 01411 tmp_keys2 = tmp_keys; 01412 tmp_vals2 = tmp_vals; 01413 } 01414 01415 ast_free(params); 01416 ast_free(vals); 01417 01418 if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) { 01419 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01420 sqlite_freemem(tmp_keys); 01421 sqlite_freemem(tmp_vals); 01422 return -1; 01423 } 01424 01425 sqlite_freemem(tmp_keys); 01426 sqlite_freemem(tmp_vals); 01427 01428 ast_debug(1, "SQL query: %s\n", tmp_str); 01429 01430 ast_mutex_lock(&mutex); 01431 01432 RES_CONFIG_SQLITE_BEGIN 01433 error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg); 01434 RES_CONFIG_SQLITE_END(error) 01435 01436 if (!error) { 01437 rows_id = sqlite_last_insert_rowid(db); 01438 } else { 01439 rows_id = -1; 01440 } 01441 01442 ast_mutex_unlock(&mutex); 01443 01444 sqlite_freemem(tmp_str); 01445 01446 if (error) { 01447 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01448 } 01449 sqlite_freemem(errormsg); 01450 01451 return rows_id; 01452 }
static int realtime_unload_handler | ( | const char * | unused, | |
const char * | tablename | |||
) | [static] |
Definition at line 1567 of file res_config_sqlite.c.
References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_table(), sqlite_cache_tables::list, and sqlite_cache_tables::name.
01568 { 01569 struct sqlite_cache_tables *tbl; 01570 AST_RWLIST_WRLOCK(&sqlite_tables); 01571 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) { 01572 if (!strcasecmp(tbl->name, tablename)) { 01573 AST_RWLIST_REMOVE_CURRENT(list); 01574 free_table(tbl); 01575 } 01576 } 01577 AST_RWLIST_TRAVERSE_SAFE_END 01578 AST_RWLIST_UNLOCK(&sqlite_tables); 01579 return 0; 01580 }
static int realtime_update_handler | ( | const char * | database, | |
const char * | table, | |||
const char * | keyfield, | |||
const char * | entity, | |||
va_list | ap | |||
) | [static] |
Asterisk callback function for RealTime configuration (variable update).
Asterisk will call this function each time a variable has been modified internally and must be updated in the backend engine. keyfield and entity are used to find the row to update, e.g. UPDATE table SET ... WHERE keyfield = 'entity';
. ap is a list of parameters and values with the same format as the other realtime functions.
database | the database to use (ignored) | |
table | the table to use | |
keyfield | the column of the matching cell | |
entity | the value of the matching cell | |
ap | list of parameters and new values to update in the database |
the | number of affected rows. | |
-1 | if an error occurred. |
Definition at line 1278 of file res_config_sqlite.c.
References ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), get_params(), LOG_WARNING, mutex, RES_CONFIG_SQLITE_BEGIN, RES_CONFIG_SQLITE_END, and S_OR.
01280 { 01281 char *query, *errormsg = NULL, *tmp_str; 01282 const char **params, **vals; 01283 size_t params_count; 01284 int error, rows_num; 01285 01286 if (!table) { 01287 ast_log(LOG_WARNING, "Table name unspecified\n"); 01288 return -1; 01289 } 01290 01291 if (!(params_count = get_params(ap, ¶ms, &vals))) 01292 return -1; 01293 01294 /* \cond DOXYGEN_CAN_PARSE_THIS */ 01295 #undef QUERY 01296 #define QUERY "UPDATE '%q' SET %q = '%q'" 01297 /* \endcond */ 01298 01299 if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) { 01300 ast_log(LOG_WARNING, "Unable to allocate SQL query\n"); 01301 ast_free(params); 01302 ast_free(vals); 01303 return -1; 01304 } 01305 01306 if (params_count > 1) { 01307 size_t i; 01308 01309 for (i = 1; i < params_count; i++) { 01310 tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]); 01311 sqlite_freemem(query); 01312 01313 if (!tmp_str) { 01314 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01315 ast_free(params); 01316 ast_free(vals); 01317 return -1; 01318 } 01319 01320 query = tmp_str; 01321 } 01322 } 01323 01324 ast_free(params); 01325 ast_free(vals); 01326 01327 if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) { 01328 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n"); 01329 sqlite_freemem(query); 01330 return -1; 01331 } 01332 01333 sqlite_freemem(query); 01334 query = tmp_str; 01335 ast_debug(1, "SQL query: %s\n", query); 01336 01337 ast_mutex_lock(&mutex); 01338 01339 RES_CONFIG_SQLITE_BEGIN 01340 error = sqlite_exec(db, query, NULL, NULL, &errormsg); 01341 RES_CONFIG_SQLITE_END(error) 01342 01343 if (!error) 01344 rows_num = sqlite_changes(db); 01345 else 01346 rows_num = -1; 01347 01348 ast_mutex_unlock(&mutex); 01349 01350 sqlite_freemem(query); 01351 01352 if (error) { 01353 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error))); 01354 } 01355 sqlite_freemem(errormsg); 01356 01357 return rows_num; 01358 }
static int set_var | ( | char ** | var, | |
const char * | name, | |||
const char * | value | |||
) | [static] |
Allocate a variable.
var | the address of the variable to set (it will be allocated) | |
name | the name of the variable (for error handling) | |
value | the value to store in var |
0 | on success | |
1 | if an allocation error occurred |
Definition at line 700 of file res_config_sqlite.c.
References ast_free, ast_log(), ast_strdup, and LOG_WARNING.
00701 { 00702 if (*var) 00703 ast_free(*var); 00704 00705 *var = ast_strdup(value); 00706 00707 if (!*var) { 00708 ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name); 00709 return 1; 00710 } 00711 00712 return 0; 00713 }
static void unload_config | ( | void | ) | [static] |
Free resources related to configuration.
Definition at line 763 of file res_config_sqlite.c.
References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_table(), and sqlite_cache_tables::list.
Referenced by unload_module().
00764 { 00765 struct sqlite_cache_tables *tbl; 00766 ast_free(dbfile); 00767 dbfile = NULL; 00768 ast_free(config_table); 00769 config_table = NULL; 00770 ast_free(cdr_table); 00771 cdr_table = NULL; 00772 AST_RWLIST_WRLOCK(&sqlite_tables); 00773 while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) { 00774 free_table(tbl); 00775 } 00776 AST_RWLIST_UNLOCK(&sqlite_tables); 00777 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1654 of file res_config_sqlite.c.
References ast_cdr_unregister(), ast_cli_unregister_multiple(), ast_config_engine_deregister(), cli_status, RES_CONFIG_SQLITE_NAME, sqlite_engine, and unload_config().
01655 { 01656 if (cli_status_registered) 01657 ast_cli_unregister_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry)); 01658 01659 if (cdr_registered) 01660 ast_cdr_unregister(RES_CONFIG_SQLITE_NAME); 01661 01662 ast_config_engine_deregister(&sqlite_engine); 01663 01664 if (db) 01665 sqlite_close(db); 01666 01667 unload_config(); 01668 01669 return 0; 01670 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime SQLite configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 1787 of file res_config_sqlite.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1787 of file res_config_sqlite.c.
int cdr_registered [static] |
Set to 1 if the CDR callback function was registered.
Definition at line 460 of file res_config_sqlite.c.
char* cdr_table [static] |
The name of the table used to store CDR entries.
Definition at line 472 of file res_config_sqlite.c.
struct ast_cli_entry cli_status[] [static] |
Initial value:
{ { .handler = handle_cli_show_sqlite_status , .summary = "Show status information about the SQLite 2 driver" ,__VA_ARGS__ }, { .handler = handle_cli_sqlite_show_tables , .summary = "Cached table information about the SQLite 2 driver" ,__VA_ARGS__ }, }
Definition at line 500 of file res_config_sqlite.c.
int cli_status_registered [static] |
Set to 1 if the CLI status command callback function was registered.
Definition at line 463 of file res_config_sqlite.c.
char* config_table [static] |
The name of the static configuration table.
Definition at line 469 of file res_config_sqlite.c.
sqlite* db [static] |
The SQLite database object.
Definition at line 454 of file res_config_sqlite.c.
char* dbfile [static] |
The path of the database file.
Definition at line 466 of file res_config_sqlite.c.
ast_mutex_t mutex = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
The mutex used to prevent simultaneous access to the SQLite database.
Definition at line 494 of file res_config_sqlite.c.
Referenced by cdr_handler(), config_handler(), realtime_destroy_handler(), realtime_handler(), realtime_multi_handler(), realtime_store_handler(), and realtime_update_handler().
char* sql_create_cdr_table [static] |
SQL query format to create the CDR table if non existent.
Definition at line 525 of file res_config_sqlite.c.
Referenced by load_module().
struct ast_config_engine sqlite_engine [static] |
The structure specifying all callback functions used by Asterisk for static and RealTime configuration.
Definition at line 478 of file res_config_sqlite.c.
Referenced by load_module(), and unload_module().
int use_cdr [static] |
Set to 1 if CDR support is enabled.
Definition at line 457 of file res_config_sqlite.c.