00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #include "asterisk.h"
00079 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 268934 $")
00080
00081 #include <sqlite.h>
00082
00083 #include "asterisk/logger.h"
00084 #include "asterisk/app.h"
00085 #include "asterisk/pbx.h"
00086 #include "asterisk/cdr.h"
00087 #include "asterisk/cli.h"
00088 #include "asterisk/lock.h"
00089 #include "asterisk/config.h"
00090 #include "asterisk/module.h"
00091 #include "asterisk/linkedlists.h"
00092
00093 #define MACRO_BEGIN do {
00094 #define MACRO_END } while (0)
00095
00096 #define RES_CONFIG_SQLITE_NAME "res_config_sqlite"
00097 #define RES_CONFIG_SQLITE_DRIVER "sqlite"
00098 #define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2"
00099 #define RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf"
00100
00101 enum {
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 };
00112
00113 #define SET_VAR(config, to, from) \
00114 MACRO_BEGIN \
00115 int __error; \
00116 \
00117 __error = set_var(&to, #to, from->value); \
00118 \
00119 if (__error) { \
00120 ast_config_destroy(config); \
00121 unload_config(); \
00122 return 1; \
00123 } \
00124 MACRO_END
00125
00126 AST_THREADSTORAGE(sql_buf);
00127 AST_THREADSTORAGE(where_buf);
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 #define RES_CONFIG_SQLITE_MAX_LOOPS 10
00146
00147
00148
00149
00150
00151
00152 #define RES_CONFIG_SQLITE_BEGIN \
00153 MACRO_BEGIN \
00154 int __i; \
00155 \
00156 for (__i = 0; __i < RES_CONFIG_SQLITE_MAX_LOOPS; __i++) {
00157
00158
00159
00160
00161
00162
00163 #define RES_CONFIG_SQLITE_END(error) \
00164 if (error != SQLITE_BUSY) \
00165 break; \
00166 usleep(1000); \
00167 } \
00168 MACRO_END;
00169
00170
00171
00172
00173
00174
00175 struct cfg_entry_args {
00176 struct ast_config *cfg;
00177 struct ast_category *cat;
00178 char *cat_name;
00179 struct ast_flags flags;
00180 const char *who_asked;
00181 };
00182
00183
00184
00185
00186
00187
00188 struct rt_cfg_entry_args {
00189 struct ast_variable *var;
00190 struct ast_variable *last;
00191 };
00192
00193
00194
00195
00196
00197
00198
00199 struct rt_multi_cfg_entry_args {
00200 struct ast_config *cfg;
00201 char *initfield;
00202 };
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 static int set_var(char **var, const char *name, const char *value);
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 static int load_config(void);
00225
00226
00227
00228
00229
00230 static void unload_config(void);
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 static int cdr_handler(struct ast_cdr *cdr);
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames);
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 static struct ast_config * config_handler(const char *database, const char *table, const char *file,
00280 struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked);
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 static size_t get_params(va_list ap, const char ***params_ptr,
00305 const char ***vals_ptr, int warn);
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 static int add_rt_cfg_entry(void *arg, int argc, char **argv,
00323 char **columnNames);
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 static struct ast_variable * realtime_handler(const char *database,
00343 const char *table, va_list ap);
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv,
00362 char **columnNames);
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 static struct ast_config * realtime_multi_handler(const char *database,
00380 const char *table, va_list ap);
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 static int realtime_update_handler(const char *database, const char *table,
00401 const char *keyfield, const char *entity, va_list ap);
00402 static int realtime_update2_handler(const char *database, const char *table,
00403 va_list ap);
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 static int realtime_store_handler(const char *database, const char *table,
00421 va_list ap);
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 static int realtime_destroy_handler(const char *database, const char *table,
00442 const char *keyfield, const char *entity, va_list ap);
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
00453 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
00454
00455 static int realtime_require_handler(const char *database, const char *table, va_list ap);
00456 static int realtime_unload_handler(const char *unused, const char *tablename);
00457
00458
00459 static sqlite *db;
00460
00461
00462 static int use_cdr;
00463
00464
00465 static int cdr_registered;
00466
00467
00468 static int cli_status_registered;
00469
00470
00471 static char *dbfile;
00472
00473
00474 static char *config_table;
00475
00476
00477 static char *cdr_table;
00478
00479
00480
00481
00482
00483 static struct ast_config_engine sqlite_engine =
00484 {
00485 .name = RES_CONFIG_SQLITE_DRIVER,
00486 .load_func = config_handler,
00487 .realtime_func = realtime_handler,
00488 .realtime_multi_func = realtime_multi_handler,
00489 .store_func = realtime_store_handler,
00490 .destroy_func = realtime_destroy_handler,
00491 .update_func = realtime_update_handler,
00492 .update2_func = realtime_update2_handler,
00493 .require_func = realtime_require_handler,
00494 .unload_func = realtime_unload_handler,
00495 };
00496
00497
00498
00499
00500 AST_MUTEX_DEFINE_STATIC(mutex);
00501
00502
00503
00504
00505
00506 static struct ast_cli_entry cli_status[] = {
00507 AST_CLI_DEFINE(handle_cli_show_sqlite_status, "Show status information about the SQLite 2 driver"),
00508 AST_CLI_DEFINE(handle_cli_sqlite_show_tables, "Cached table information about the SQLite 2 driver"),
00509 };
00510
00511 struct sqlite_cache_columns {
00512 char *name;
00513 char *type;
00514 unsigned char isint;
00515 AST_RWLIST_ENTRY(sqlite_cache_columns) list;
00516 };
00517
00518 struct sqlite_cache_tables {
00519 char *name;
00520 AST_RWLIST_HEAD(_columns, sqlite_cache_columns) columns;
00521 AST_RWLIST_ENTRY(sqlite_cache_tables) list;
00522 };
00523
00524 static AST_RWLIST_HEAD_STATIC(sqlite_tables, sqlite_cache_tables);
00525
00526
00527
00528
00529
00530
00531 static char *sql_create_cdr_table =
00532 "CREATE TABLE '%q' (\n"
00533 " id INTEGER,\n"
00534 " clid VARCHAR(80) NOT NULL DEFAULT '',\n"
00535 " src VARCHAR(80) NOT NULL DEFAULT '',\n"
00536 " dst VARCHAR(80) NOT NULL DEFAULT '',\n"
00537 " dcontext VARCHAR(80) NOT NULL DEFAULT '',\n"
00538 " channel VARCHAR(80) NOT NULL DEFAULT '',\n"
00539 " dstchannel VARCHAR(80) NOT NULL DEFAULT '',\n"
00540 " lastapp VARCHAR(80) NOT NULL DEFAULT '',\n"
00541 " lastdata VARCHAR(80) NOT NULL DEFAULT '',\n"
00542 " start DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00543 " answer DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00544 " end DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\n"
00545 " duration INT(11) NOT NULL DEFAULT 0,\n"
00546 " billsec INT(11) NOT NULL DEFAULT 0,\n"
00547 " disposition VARCHAR(45) NOT NULL DEFAULT '',\n"
00548 " amaflags INT(11) NOT NULL DEFAULT 0,\n"
00549 " accountcode VARCHAR(20) NOT NULL DEFAULT '',\n"
00550 " uniqueid VARCHAR(32) NOT NULL DEFAULT '',\n"
00551 " userfield VARCHAR(255) NOT NULL DEFAULT '',\n"
00552 " PRIMARY KEY (id)\n"
00553 ");";
00554
00555
00556
00557
00558 #define sql_table_structure "SELECT sql FROM sqlite_master WHERE type='table' AND tbl_name='%s'"
00559
00560
00561
00562
00563
00564
00565
00566 #define sql_get_config_table \
00567 "SELECT *" \
00568 " FROM '%q'" \
00569 " WHERE filename = '%q' AND commented = 0" \
00570 " ORDER BY cat_metric ASC, var_metric ASC;"
00571
00572 static void free_table(struct sqlite_cache_tables *tblptr)
00573 {
00574 struct sqlite_cache_columns *col;
00575
00576
00577 AST_RWLIST_WRLOCK(&(tblptr->columns));
00578 while ((col = AST_RWLIST_REMOVE_HEAD(&(tblptr->columns), list))) {
00579 ast_free(col);
00580 }
00581 AST_RWLIST_UNLOCK(&(tblptr->columns));
00582 AST_RWLIST_HEAD_DESTROY(&(tblptr->columns));
00583 ast_free(tblptr);
00584 }
00585
00586 static int find_table_cb(void *vtblptr, int argc, char **argv, char **columnNames)
00587 {
00588 struct sqlite_cache_tables *tblptr = vtblptr;
00589 char *sql = ast_strdupa(argv[0]), *start, *end, *type, *remainder;
00590 int i;
00591 AST_DECLARE_APP_ARGS(fie,
00592 AST_APP_ARG(ld)[100];
00593 );
00594 struct sqlite_cache_columns *col;
00595
00596
00597
00598
00599 if ((start = strchr(sql, '(')) && (end = strrchr(sql, ')'))) {
00600 start++;
00601 *end = '\0';
00602 } else {
00603
00604 return -1;
00605 }
00606
00607 AST_STANDARD_APP_ARGS(fie, start);
00608 for (i = 0; i < fie.argc; i++) {
00609 fie.ld[i] = ast_skip_blanks(fie.ld[i]);
00610 ast_debug(5, "Found field: %s\n", fie.ld[i]);
00611 if (strncasecmp(fie.ld[i], "PRIMARY KEY", 11) == 0 && (start = strchr(fie.ld[i], '(')) && (end = strchr(fie.ld[i], ')'))) {
00612 *end = '\0';
00613 AST_RWLIST_TRAVERSE(&(tblptr->columns), col, list) {
00614 if (strcasecmp(start + 1, col->name) == 0 && strcasestr(col->type, "INTEGER")) {
00615 col->isint = 1;
00616 }
00617 }
00618 continue;
00619 }
00620
00621 for (type = fie.ld[i]; *type > 32; type++);
00622 *type++ = '\0';
00623 type = ast_skip_blanks(type);
00624 for (remainder = type; *remainder > 32; remainder++);
00625 *remainder = '\0';
00626 if (!(col = ast_calloc(1, sizeof(*col) + strlen(fie.ld[i]) + strlen(type) + 2))) {
00627 return -1;
00628 }
00629 col->name = (char *)col + sizeof(*col);
00630 col->type = (char *)col + sizeof(*col) + strlen(fie.ld[i]) + 1;
00631 strcpy(col->name, fie.ld[i]);
00632 strcpy(col->type, type);
00633 if (strcasestr(col->type, "INTEGER") && strcasestr(col->type, "PRIMARY KEY")) {
00634 col->isint = 1;
00635 }
00636 AST_LIST_INSERT_TAIL(&(tblptr->columns), col, list);
00637 }
00638 return 0;
00639 }
00640
00641 static struct sqlite_cache_tables *find_table(const char *tablename)
00642 {
00643 struct sqlite_cache_tables *tblptr;
00644 int i, err;
00645 char *sql, *errstr = NULL;
00646
00647 AST_RWLIST_RDLOCK(&sqlite_tables);
00648
00649 for (i = 0; i < 2; i++) {
00650 AST_RWLIST_TRAVERSE(&sqlite_tables, tblptr, list) {
00651 if (strcmp(tblptr->name, tablename) == 0) {
00652 break;
00653 }
00654 }
00655 if (tblptr) {
00656 AST_RWLIST_RDLOCK(&(tblptr->columns));
00657 AST_RWLIST_UNLOCK(&sqlite_tables);
00658 return tblptr;
00659 }
00660
00661 if (i == 0) {
00662 AST_RWLIST_UNLOCK(&sqlite_tables);
00663 AST_RWLIST_WRLOCK(&sqlite_tables);
00664 }
00665 }
00666
00667
00668 if (asprintf(&sql, sql_table_structure, tablename) < 0) {
00669 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00670 sql = NULL;
00671 }
00672 if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) {
00673 AST_RWLIST_UNLOCK(&sqlite_tables);
00674 ast_log(LOG_ERROR, "Memory error. Cannot cache table '%s'\n", tablename);
00675 return NULL;
00676 }
00677 tblptr->name = (char *)tblptr + sizeof(*tblptr);
00678 strcpy(tblptr->name, tablename);
00679 AST_RWLIST_HEAD_INIT(&(tblptr->columns));
00680
00681 ast_debug(1, "About to query table structure: %s\n", sql);
00682
00683 ast_mutex_lock(&mutex);
00684 if ((err = sqlite_exec(db, sql, find_table_cb, tblptr, &errstr))) {
00685 ast_mutex_unlock(&mutex);
00686 ast_log(LOG_WARNING, "SQLite error %d: %s\n", err, errstr);
00687 ast_free(errstr);
00688 free_table(tblptr);
00689 AST_RWLIST_UNLOCK(&sqlite_tables);
00690 return NULL;
00691 }
00692 ast_mutex_unlock(&mutex);
00693
00694 if (AST_LIST_EMPTY(&(tblptr->columns))) {
00695 free_table(tblptr);
00696 AST_RWLIST_UNLOCK(&sqlite_tables);
00697 return NULL;
00698 }
00699
00700 AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list);
00701 AST_RWLIST_RDLOCK(&(tblptr->columns));
00702 AST_RWLIST_UNLOCK(&sqlite_tables);
00703 return tblptr;
00704 }
00705
00706 #define release_table(a) AST_RWLIST_UNLOCK(&((a)->columns))
00707
00708 static int set_var(char **var, const char *name, const char *value)
00709 {
00710 if (*var)
00711 ast_free(*var);
00712
00713 *var = ast_strdup(value);
00714
00715 if (!*var) {
00716 ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name);
00717 return 1;
00718 }
00719
00720 return 0;
00721 }
00722
00723 static int check_vars(void)
00724 {
00725 if (!dbfile) {
00726 ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00727 return 1;
00728 }
00729
00730 use_cdr = (cdr_table != NULL);
00731
00732 return 0;
00733 }
00734
00735 static int load_config(void)
00736 {
00737 struct ast_config *config;
00738 struct ast_variable *var;
00739 int error;
00740 struct ast_flags config_flags = { 0 };
00741
00742 config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags);
00743
00744 if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
00745 ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n");
00746 return 1;
00747 }
00748
00749 for (var = ast_variable_browse(config, "general"); var; var = var->next) {
00750 if (!strcasecmp(var->name, "dbfile"))
00751 SET_VAR(config, dbfile, var);
00752 else if (!strcasecmp(var->name, "config_table"))
00753 SET_VAR(config, config_table, var);
00754 else if (!strcasecmp(var->name, "cdr_table")) {
00755 SET_VAR(config, cdr_table, var);
00756 } else
00757 ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name);
00758 }
00759
00760 ast_config_destroy(config);
00761 error = check_vars();
00762
00763 if (error) {
00764 unload_config();
00765 return 1;
00766 }
00767
00768 return 0;
00769 }
00770
00771 static void unload_config(void)
00772 {
00773 struct sqlite_cache_tables *tbl;
00774 ast_free(dbfile);
00775 dbfile = NULL;
00776 ast_free(config_table);
00777 config_table = NULL;
00778 ast_free(cdr_table);
00779 cdr_table = NULL;
00780 AST_RWLIST_WRLOCK(&sqlite_tables);
00781 while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) {
00782 free_table(tbl);
00783 }
00784 AST_RWLIST_UNLOCK(&sqlite_tables);
00785 }
00786
00787 static int cdr_handler(struct ast_cdr *cdr)
00788 {
00789 char *errormsg = NULL, *tmp, workspace[500];
00790 int error, scannum;
00791 struct sqlite_cache_tables *tbl = find_table(cdr_table);
00792 struct sqlite_cache_columns *col;
00793 struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16);
00794 int first = 1;
00795
00796 if (!tbl) {
00797 ast_log(LOG_WARNING, "No such table: %s\n", cdr_table);
00798 return -1;
00799 }
00800
00801 ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table);
00802 ast_str_set(&sql2, 0, ") VALUES (");
00803
00804 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
00805 if (col->isint) {
00806 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1);
00807 if (!tmp) {
00808 continue;
00809 }
00810 if (sscanf(tmp, "%30d", &scannum) == 1) {
00811 ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name);
00812 ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", scannum);
00813 }
00814 } else {
00815 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0);
00816 if (!tmp) {
00817 continue;
00818 }
00819 ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name);
00820 tmp = sqlite_mprintf("%Q", tmp);
00821 ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", tmp);
00822 sqlite_freemem(tmp);
00823 }
00824 first = 0;
00825 }
00826 release_table(tbl);
00827
00828 ast_str_append(&sql1, 0, "%s)", ast_str_buffer(sql2));
00829 ast_free(sql2);
00830
00831 ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql1));
00832
00833 ast_mutex_lock(&mutex);
00834
00835 RES_CONFIG_SQLITE_BEGIN
00836 error = sqlite_exec(db, ast_str_buffer(sql1), NULL, NULL, &errormsg);
00837 RES_CONFIG_SQLITE_END(error)
00838
00839 ast_mutex_unlock(&mutex);
00840
00841 ast_free(sql1);
00842
00843 if (error) {
00844 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00845 sqlite_freemem(errormsg);
00846 return 1;
00847 }
00848 sqlite_freemem(errormsg);
00849
00850 return 0;
00851 }
00852
00853 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00854 {
00855 struct cfg_entry_args *args;
00856 struct ast_variable *var;
00857
00858 if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) {
00859 ast_log(LOG_WARNING, "Corrupt table\n");
00860 return 1;
00861 }
00862
00863 args = arg;
00864
00865 if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) {
00866 struct ast_config *cfg;
00867 char *val;
00868
00869 val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL];
00870 cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked);
00871
00872 if (!cfg) {
00873 ast_log(LOG_WARNING, "Unable to include %s\n", val);
00874 return 1;
00875 } else {
00876 args->cfg = cfg;
00877 return 0;
00878 }
00879 }
00880
00881 if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) {
00882 args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999);
00883
00884 if (!args->cat) {
00885 ast_log(LOG_WARNING, "Unable to allocate category\n");
00886 return 1;
00887 }
00888
00889 ast_free(args->cat_name);
00890 args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]);
00891
00892 if (!args->cat_name) {
00893 ast_category_destroy(args->cat);
00894 return 1;
00895 }
00896
00897 ast_category_append(args->cfg, args->cat);
00898 }
00899
00900 var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], "");
00901
00902 if (!var) {
00903 ast_log(LOG_WARNING, "Unable to allocate variable");
00904 return 1;
00905 }
00906
00907 ast_variable_append(args->cat, var);
00908
00909 return 0;
00910 }
00911
00912 static struct ast_config *config_handler(const char *database, const char *table, const char *file,
00913 struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
00914 {
00915 struct cfg_entry_args args;
00916 char *query, *errormsg = NULL;
00917 int error;
00918
00919 if (!config_table) {
00920 if (!table) {
00921 ast_log(LOG_ERROR, "Table name unspecified\n");
00922 return NULL;
00923 }
00924 } else
00925 table = config_table;
00926
00927 query = sqlite_mprintf(sql_get_config_table, table, file);
00928
00929 if (!query) {
00930 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00931 return NULL;
00932 }
00933
00934 ast_debug(1, "SQL query: %s\n", query);
00935 args.cfg = cfg;
00936 args.cat = NULL;
00937 args.cat_name = NULL;
00938 args.flags = flags;
00939 args.who_asked = who_asked;
00940
00941 ast_mutex_lock(&mutex);
00942
00943 RES_CONFIG_SQLITE_BEGIN
00944 error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg);
00945 RES_CONFIG_SQLITE_END(error)
00946
00947 ast_mutex_unlock(&mutex);
00948
00949 ast_free(args.cat_name);
00950 sqlite_freemem(query);
00951
00952 if (error) {
00953 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00954 sqlite_freemem(errormsg);
00955 return NULL;
00956 }
00957 sqlite_freemem(errormsg);
00958
00959 return cfg;
00960 }
00961
00962 static size_t get_params(va_list ap, const char ***params_ptr, const char ***vals_ptr, int warn)
00963 {
00964 const char **tmp, *param, *val, **params, **vals;
00965 size_t params_count;
00966
00967 params = NULL;
00968 vals = NULL;
00969 params_count = 0;
00970
00971 while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) {
00972 if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) {
00973 ast_free(params);
00974 ast_free(vals);
00975 return 0;
00976 }
00977 params = tmp;
00978
00979 if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) {
00980 ast_free(params);
00981 ast_free(vals);
00982 return 0;
00983 }
00984 vals = tmp;
00985
00986 params[params_count] = param;
00987 vals[params_count] = val;
00988 params_count++;
00989 }
00990
00991 if (params_count > 0) {
00992 *params_ptr = params;
00993 *vals_ptr = vals;
00994 } else if (warn) {
00995 ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n");
00996 }
00997
00998 return params_count;
00999 }
01000
01001 static int add_rt_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
01002 {
01003 struct rt_cfg_entry_args *args;
01004 struct ast_variable *var;
01005 int i;
01006
01007 args = arg;
01008
01009 for (i = 0; i < argc; i++) {
01010 if (!argv[i])
01011 continue;
01012
01013 if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
01014 return 1;
01015
01016 if (!args->var)
01017 args->var = var;
01018
01019 if (!args->last)
01020 args->last = var;
01021 else {
01022 args->last->next = var;
01023 args->last = var;
01024 }
01025 }
01026
01027 return 0;
01028 }
01029
01030 static struct ast_variable * realtime_handler(const char *database, const char *table, va_list ap)
01031 {
01032 char *query, *errormsg = NULL, *op, *tmp_str;
01033 struct rt_cfg_entry_args args;
01034 const char **params, **vals;
01035 size_t params_count;
01036 int error;
01037
01038 if (!table) {
01039 ast_log(LOG_WARNING, "Table name unspecified\n");
01040 return NULL;
01041 }
01042
01043 params_count = get_params(ap, ¶ms, &vals, 1);
01044
01045 if (params_count == 0)
01046 return NULL;
01047
01048 op = (strchr(params[0], ' ') == NULL) ? " =" : "";
01049
01050
01051 #undef QUERY
01052 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'"
01053
01054
01055 query = sqlite_mprintf(QUERY, table, !strcmp(config_table, table) ? " commented = 0 AND" : "", params[0], op, vals[0]);
01056
01057 if (!query) {
01058 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01059 ast_free(params);
01060 ast_free(vals);
01061 return NULL;
01062 }
01063
01064 if (params_count > 1) {
01065 size_t i;
01066
01067 for (i = 1; i < params_count; i++) {
01068 op = (strchr(params[i], ' ') == NULL) ? " =" : "";
01069 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01070 sqlite_freemem(query);
01071
01072 if (!tmp_str) {
01073 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01074 ast_free(params);
01075 ast_free(vals);
01076 return NULL;
01077 }
01078
01079 query = tmp_str;
01080 }
01081 }
01082
01083 ast_free(params);
01084 ast_free(vals);
01085
01086 tmp_str = sqlite_mprintf("%s LIMIT 1;", query);
01087 sqlite_freemem(query);
01088
01089 if (!tmp_str) {
01090 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01091 return NULL;
01092 }
01093
01094 query = tmp_str;
01095 ast_debug(1, "SQL query: %s\n", query);
01096 args.var = NULL;
01097 args.last = NULL;
01098
01099 ast_mutex_lock(&mutex);
01100
01101 RES_CONFIG_SQLITE_BEGIN
01102 error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg);
01103 RES_CONFIG_SQLITE_END(error)
01104
01105 ast_mutex_unlock(&mutex);
01106
01107 sqlite_freemem(query);
01108
01109 if (error) {
01110 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01111 sqlite_freemem(errormsg);
01112 ast_variables_destroy(args.var);
01113 return NULL;
01114 }
01115 sqlite_freemem(errormsg);
01116
01117 return args.var;
01118 }
01119
01120 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
01121 {
01122 struct rt_multi_cfg_entry_args *args;
01123 struct ast_category *cat;
01124 struct ast_variable *var;
01125 char *cat_name;
01126 size_t i;
01127
01128 args = arg;
01129 cat_name = NULL;
01130
01131
01132
01133
01134
01135
01136 for (i = 0; i < argc; i++) {
01137 if (!strcmp(args->initfield, columnNames[i]))
01138 cat_name = argv[i];
01139 }
01140
01141 if (!cat_name) {
01142 ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
01143 return 1;
01144 }
01145
01146 if (!(cat = ast_category_new(cat_name, "", 99999))) {
01147 ast_log(LOG_WARNING, "Unable to allocate category\n");
01148 return 1;
01149 }
01150
01151 ast_category_append(args->cfg, cat);
01152
01153 for (i = 0; i < argc; i++) {
01154 if (!argv[i] || !strcmp(args->initfield, columnNames[i]))
01155 continue;
01156
01157 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01158 ast_log(LOG_WARNING, "Unable to allocate variable\n");
01159 return 1;
01160 }
01161
01162 ast_variable_append(cat, var);
01163 }
01164
01165 return 0;
01166 }
01167
01168 static struct ast_config *realtime_multi_handler(const char *database,
01169 const char *table, va_list ap)
01170 {
01171 char *query, *errormsg = NULL, *op, *tmp_str, *initfield;
01172 struct rt_multi_cfg_entry_args args;
01173 const char **params, **vals;
01174 struct ast_config *cfg;
01175 size_t params_count;
01176 int error;
01177
01178 if (!table) {
01179 ast_log(LOG_WARNING, "Table name unspecified\n");
01180 return NULL;
01181 }
01182
01183 if (!(cfg = ast_config_new())) {
01184 ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01185 return NULL;
01186 }
01187
01188 if (!(params_count = get_params(ap, ¶ms, &vals, 1))) {
01189 ast_config_destroy(cfg);
01190 return NULL;
01191 }
01192
01193 if (!(initfield = ast_strdup(params[0]))) {
01194 ast_config_destroy(cfg);
01195 ast_free(params);
01196 ast_free(vals);
01197 return NULL;
01198 }
01199
01200 tmp_str = strchr(initfield, ' ');
01201
01202 if (tmp_str)
01203 *tmp_str = '\0';
01204
01205 op = (!strchr(params[0], ' ')) ? " =" : "";
01206
01207
01208
01209
01210
01211 tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0];
01212
01213
01214 #undef QUERY
01215 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
01216
01217
01218 if (!(query = sqlite_mprintf(QUERY, table, params[0], op, tmp_str))) {
01219 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01220 ast_config_destroy(cfg);
01221 ast_free(params);
01222 ast_free(vals);
01223 ast_free(initfield);
01224 return NULL;
01225 }
01226
01227 if (params_count > 1) {
01228 size_t i;
01229
01230 for (i = 1; i < params_count; i++) {
01231 op = (!strchr(params[i], ' ')) ? " =" : "";
01232 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01233 sqlite_freemem(query);
01234
01235 if (!tmp_str) {
01236 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01237 ast_config_destroy(cfg);
01238 ast_free(params);
01239 ast_free(vals);
01240 ast_free(initfield);
01241 return NULL;
01242 }
01243
01244 query = tmp_str;
01245 }
01246 }
01247
01248 ast_free(params);
01249 ast_free(vals);
01250
01251 if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01252 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01253 sqlite_freemem(query);
01254 ast_config_destroy(cfg);
01255 ast_free(initfield);
01256 return NULL;
01257 }
01258
01259 sqlite_freemem(query);
01260 query = tmp_str;
01261 ast_debug(1, "SQL query: %s\n", query);
01262 args.cfg = cfg;
01263 args.initfield = initfield;
01264
01265 ast_mutex_lock(&mutex);
01266
01267 RES_CONFIG_SQLITE_BEGIN
01268 error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01269 RES_CONFIG_SQLITE_END(error)
01270
01271 ast_mutex_unlock(&mutex);
01272
01273 sqlite_freemem(query);
01274 ast_free(initfield);
01275
01276 if (error) {
01277 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01278 sqlite_freemem(errormsg);
01279 ast_config_destroy(cfg);
01280 return NULL;
01281 }
01282 sqlite_freemem(errormsg);
01283
01284 return cfg;
01285 }
01286
01287 static int realtime_update_handler(const char *database, const char *table,
01288 const char *keyfield, const char *entity, va_list ap)
01289 {
01290 char *query, *errormsg = NULL, *tmp_str;
01291 const char **params, **vals;
01292 size_t params_count;
01293 int error, rows_num;
01294
01295 if (!table) {
01296 ast_log(LOG_WARNING, "Table name unspecified\n");
01297 return -1;
01298 }
01299
01300 if (!(params_count = get_params(ap, ¶ms, &vals, 1)))
01301 return -1;
01302
01303
01304 #undef QUERY
01305 #define QUERY "UPDATE '%q' SET %q = '%q'"
01306
01307
01308 if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) {
01309 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01310 ast_free(params);
01311 ast_free(vals);
01312 return -1;
01313 }
01314
01315 if (params_count > 1) {
01316 size_t i;
01317
01318 for (i = 1; i < params_count; i++) {
01319 tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]);
01320 sqlite_freemem(query);
01321
01322 if (!tmp_str) {
01323 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01324 ast_free(params);
01325 ast_free(vals);
01326 return -1;
01327 }
01328
01329 query = tmp_str;
01330 }
01331 }
01332
01333 ast_free(params);
01334 ast_free(vals);
01335
01336 if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01337 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01338 sqlite_freemem(query);
01339 return -1;
01340 }
01341
01342 sqlite_freemem(query);
01343 query = tmp_str;
01344 ast_debug(1, "SQL query: %s\n", query);
01345
01346 ast_mutex_lock(&mutex);
01347
01348 RES_CONFIG_SQLITE_BEGIN
01349 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01350 RES_CONFIG_SQLITE_END(error)
01351
01352 if (!error)
01353 rows_num = sqlite_changes(db);
01354 else
01355 rows_num = -1;
01356
01357 ast_mutex_unlock(&mutex);
01358
01359 sqlite_freemem(query);
01360
01361 if (error) {
01362 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01363 }
01364 sqlite_freemem(errormsg);
01365
01366 return rows_num;
01367 }
01368
01369 static int realtime_update2_handler(const char *database, const char *table,
01370 va_list ap)
01371 {
01372 char *errormsg = NULL, *tmp1, *tmp2;
01373 int error, rows_num, first = 1;
01374 struct ast_str *sql = ast_str_thread_get(&sql_buf, 100);
01375 struct ast_str *where = ast_str_thread_get(&where_buf, 100);
01376 const char *param, *value;
01377
01378 if (!table) {
01379 ast_log(LOG_WARNING, "Table name unspecified\n");
01380 return -1;
01381 }
01382
01383 if (!sql) {
01384 return -1;
01385 }
01386
01387 ast_str_set(&sql, 0, "UPDATE %s SET", table);
01388 ast_str_set(&where, 0, " WHERE");
01389
01390 while ((param = va_arg(ap, const char *))) {
01391 value = va_arg(ap, const char *);
01392 ast_str_append(&where, 0, "%s %s = %s",
01393 first ? "" : " AND",
01394 tmp1 = sqlite_mprintf("%q", param),
01395 tmp2 = sqlite_mprintf("%Q", value));
01396 sqlite_freemem(tmp1);
01397 sqlite_freemem(tmp2);
01398 first = 0;
01399 }
01400
01401 if (first) {
01402 ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database);
01403 return -1;
01404 }
01405
01406 first = 1;
01407 while ((param = va_arg(ap, const char *))) {
01408 value = va_arg(ap, const char *);
01409 ast_str_append(&sql, 0, "%s %s = %s",
01410 first ? "" : ",",
01411 tmp1 = sqlite_mprintf("%q", param),
01412 tmp2 = sqlite_mprintf("%Q", value));
01413 sqlite_freemem(tmp1);
01414 sqlite_freemem(tmp2);
01415 first = 0;
01416 }
01417
01418 ast_str_append(&sql, 0, " %s", ast_str_buffer(where));
01419 ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql));
01420
01421 ast_mutex_lock(&mutex);
01422
01423 RES_CONFIG_SQLITE_BEGIN
01424 error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg);
01425 RES_CONFIG_SQLITE_END(error)
01426
01427 if (!error) {
01428 rows_num = sqlite_changes(db);
01429 } else {
01430 rows_num = -1;
01431 }
01432
01433 ast_mutex_unlock(&mutex);
01434
01435 if (error) {
01436 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01437 }
01438 sqlite_freemem(errormsg);
01439
01440 return rows_num;
01441 }
01442
01443 static int realtime_store_handler(const char *database, const char *table, va_list ap)
01444 {
01445 char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01446 const char **params, **vals;
01447 size_t params_count;
01448 int error, rows_id;
01449 size_t i;
01450
01451 if (!table) {
01452 ast_log(LOG_WARNING, "Table name unspecified\n");
01453 return -1;
01454 }
01455
01456 if (!(params_count = get_params(ap, ¶ms, &vals, 1)))
01457 return -1;
01458
01459
01460 #undef QUERY
01461 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01462
01463
01464 for (i = 0; i < params_count; i++) {
01465 if ( tmp_keys2 ) {
01466 tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]);
01467 sqlite_freemem(tmp_keys2);
01468 } else {
01469 tmp_keys = sqlite_mprintf("%q", params[i]);
01470 }
01471 if (!tmp_keys) {
01472 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01473 sqlite_freemem(tmp_vals);
01474 ast_free(params);
01475 ast_free(vals);
01476 return -1;
01477 }
01478
01479 if ( tmp_vals2 ) {
01480 tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, vals[i]);
01481 sqlite_freemem(tmp_vals2);
01482 } else {
01483 tmp_vals = sqlite_mprintf("'%q'", vals[i]);
01484 }
01485 if (!tmp_vals) {
01486 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01487 sqlite_freemem(tmp_keys);
01488 ast_free(params);
01489 ast_free(vals);
01490 return -1;
01491 }
01492
01493
01494 tmp_keys2 = tmp_keys;
01495 tmp_vals2 = tmp_vals;
01496 }
01497
01498 ast_free(params);
01499 ast_free(vals);
01500
01501 if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01502 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01503 sqlite_freemem(tmp_keys);
01504 sqlite_freemem(tmp_vals);
01505 return -1;
01506 }
01507
01508 sqlite_freemem(tmp_keys);
01509 sqlite_freemem(tmp_vals);
01510
01511 ast_debug(1, "SQL query: %s\n", tmp_str);
01512
01513 ast_mutex_lock(&mutex);
01514
01515 RES_CONFIG_SQLITE_BEGIN
01516 error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01517 RES_CONFIG_SQLITE_END(error)
01518
01519 if (!error) {
01520 rows_id = sqlite_last_insert_rowid(db);
01521 } else {
01522 rows_id = -1;
01523 }
01524
01525 ast_mutex_unlock(&mutex);
01526
01527 sqlite_freemem(tmp_str);
01528
01529 if (error) {
01530 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01531 }
01532 sqlite_freemem(errormsg);
01533
01534 return rows_id;
01535 }
01536
01537 static int realtime_destroy_handler(const char *database, const char *table,
01538 const char *keyfield, const char *entity, va_list ap)
01539 {
01540 char *query, *errormsg = NULL, *tmp_str;
01541 const char **params = NULL, **vals = NULL;
01542 size_t params_count;
01543 int error, rows_num;
01544 size_t i;
01545
01546 if (!table) {
01547 ast_log(LOG_WARNING, "Table name unspecified\n");
01548 return -1;
01549 }
01550
01551 params_count = get_params(ap, ¶ms, &vals, 0);
01552
01553
01554 #undef QUERY
01555 #define QUERY "DELETE FROM '%q' WHERE"
01556
01557
01558 if (!(query = sqlite_mprintf(QUERY, table))) {
01559 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01560 ast_free(params);
01561 ast_free(vals);
01562 return -1;
01563 }
01564
01565 for (i = 0; i < params_count; i++) {
01566 tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01567 sqlite_freemem(query);
01568
01569 if (!tmp_str) {
01570 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01571 ast_free(params);
01572 ast_free(vals);
01573 return -1;
01574 }
01575
01576 query = tmp_str;
01577 }
01578
01579 ast_free(params);
01580 ast_free(vals);
01581 if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01582 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01583 sqlite_freemem(query);
01584 return -1;
01585 }
01586 sqlite_freemem(query);
01587 query = tmp_str;
01588 ast_debug(1, "SQL query: %s\n", query);
01589
01590 ast_mutex_lock(&mutex);
01591
01592 RES_CONFIG_SQLITE_BEGIN
01593 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01594 RES_CONFIG_SQLITE_END(error)
01595
01596 if (!error) {
01597 rows_num = sqlite_changes(db);
01598 } else {
01599 rows_num = -1;
01600 }
01601
01602 ast_mutex_unlock(&mutex);
01603
01604 sqlite_freemem(query);
01605
01606 if (error) {
01607 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01608 }
01609 sqlite_freemem(errormsg);
01610
01611 return rows_num;
01612 }
01613
01614 static int realtime_require_handler(const char *unused, const char *tablename, va_list ap)
01615 {
01616 struct sqlite_cache_tables *tbl = find_table(tablename);
01617 struct sqlite_cache_columns *col;
01618 char *elm;
01619 int type, size, res = 0;
01620
01621 if (!tbl) {
01622 return -1;
01623 }
01624
01625 while ((elm = va_arg(ap, char *))) {
01626 type = va_arg(ap, require_type);
01627 size = va_arg(ap, int);
01628
01629 AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01630 if (strcmp(col->name, elm) == 0) {
01631
01632
01633
01634
01635 if (col->isint && !ast_rq_is_int(type)) {
01636 ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01637 res = -1;
01638 }
01639 break;
01640 }
01641 }
01642 if (!col) {
01643 ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01644 }
01645 }
01646 AST_RWLIST_UNLOCK(&(tbl->columns));
01647 return res;
01648 }
01649
01650 static int realtime_unload_handler(const char *unused, const char *tablename)
01651 {
01652 struct sqlite_cache_tables *tbl;
01653 AST_RWLIST_WRLOCK(&sqlite_tables);
01654 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) {
01655 if (!strcasecmp(tbl->name, tablename)) {
01656 AST_RWLIST_REMOVE_CURRENT(list);
01657 free_table(tbl);
01658 }
01659 }
01660 AST_RWLIST_TRAVERSE_SAFE_END
01661 AST_RWLIST_UNLOCK(&sqlite_tables);
01662 return 0;
01663 }
01664
01665 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01666 {
01667 switch (cmd) {
01668 case CLI_INIT:
01669 e->command = "sqlite show status";
01670 e->usage =
01671 "Usage: sqlite show status\n"
01672 " Show status information about the SQLite 2 driver\n";
01673 return NULL;
01674 case CLI_GENERATE:
01675 return NULL;
01676 }
01677
01678 if (a->argc != 3)
01679 return CLI_SHOWUSAGE;
01680
01681 ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01682 ast_cli(a->fd, "config_table: ");
01683
01684 if (!config_table)
01685 ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01686 else
01687 ast_cli(a->fd, "%s\n", config_table);
01688
01689 ast_cli(a->fd, "cdr_table: ");
01690
01691 if (!cdr_table)
01692 ast_cli(a->fd, "unspecified, CDR support disabled\n");
01693 else
01694 ast_cli(a->fd, "%s\n", cdr_table);
01695
01696 return CLI_SUCCESS;
01697 }
01698
01699 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01700 {
01701 struct sqlite_cache_tables *tbl;
01702 struct sqlite_cache_columns *col;
01703 int found = 0;
01704
01705 switch (cmd) {
01706 case CLI_INIT:
01707 e->command = "sqlite show tables";
01708 e->usage =
01709 "Usage: sqlite show tables\n"
01710 " Show table information about the SQLite 2 driver\n";
01711 return NULL;
01712 case CLI_GENERATE:
01713 return NULL;
01714 }
01715
01716 if (a->argc != 3)
01717 return CLI_SHOWUSAGE;
01718
01719 AST_RWLIST_RDLOCK(&sqlite_tables);
01720 AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01721 found++;
01722 ast_cli(a->fd, "Table %s:\n", tbl->name);
01723 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01724 fprintf(stderr, "%s\n", col->name);
01725 ast_cli(a->fd, " %20.20s %-30.30s\n", col->name, col->type);
01726 }
01727 }
01728 AST_RWLIST_UNLOCK(&sqlite_tables);
01729
01730 if (!found) {
01731 ast_cli(a->fd, "No tables currently in cache\n");
01732 }
01733
01734 return CLI_SUCCESS;
01735 }
01736
01737 static int unload_module(void)
01738 {
01739 if (cli_status_registered)
01740 ast_cli_unregister_multiple(cli_status, ARRAY_LEN(cli_status));
01741
01742 if (cdr_registered)
01743 ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
01744
01745 ast_config_engine_deregister(&sqlite_engine);
01746
01747 if (db)
01748 sqlite_close(db);
01749
01750 unload_config();
01751
01752 return 0;
01753 }
01754
01755 static int load_module(void)
01756 {
01757 char *errormsg = NULL;
01758 int error;
01759
01760 db = NULL;
01761 cdr_registered = 0;
01762 cli_status_registered = 0;
01763 dbfile = NULL;
01764 config_table = NULL;
01765 cdr_table = NULL;
01766 error = load_config();
01767
01768 if (error)
01769 return AST_MODULE_LOAD_DECLINE;
01770
01771 if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01772 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01773 sqlite_freemem(errormsg);
01774 unload_module();
01775 return 1;
01776 }
01777
01778 sqlite_freemem(errormsg);
01779 errormsg = NULL;
01780 ast_config_engine_register(&sqlite_engine);
01781
01782 if (use_cdr) {
01783 char *query;
01784
01785
01786 #undef QUERY
01787 #define QUERY "SELECT COUNT(id) FROM %Q;"
01788
01789
01790 query = sqlite_mprintf(QUERY, cdr_table);
01791
01792 if (!query) {
01793 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01794 unload_module();
01795 return 1;
01796 }
01797
01798 ast_debug(1, "SQL query: %s\n", query);
01799
01800 RES_CONFIG_SQLITE_BEGIN
01801 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01802 RES_CONFIG_SQLITE_END(error)
01803
01804 sqlite_freemem(query);
01805
01806 if (error) {
01807
01808
01809
01810 if (error != SQLITE_ERROR) {
01811 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01812 sqlite_freemem(errormsg);
01813 unload_module();
01814 return 1;
01815 }
01816
01817 sqlite_freemem(errormsg);
01818 errormsg = NULL;
01819 query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01820
01821 if (!query) {
01822 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01823 unload_module();
01824 return 1;
01825 }
01826
01827 ast_debug(1, "SQL query: %s\n", query);
01828
01829 RES_CONFIG_SQLITE_BEGIN
01830 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01831 RES_CONFIG_SQLITE_END(error)
01832
01833 sqlite_freemem(query);
01834
01835 if (error) {
01836 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01837 sqlite_freemem(errormsg);
01838 unload_module();
01839 return 1;
01840 }
01841 }
01842 sqlite_freemem(errormsg);
01843 errormsg = NULL;
01844
01845 error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01846
01847 if (error) {
01848 unload_module();
01849 return 1;
01850 }
01851
01852 cdr_registered = 1;
01853 }
01854
01855 error = ast_cli_register_multiple(cli_status, ARRAY_LEN(cli_status));
01856
01857 if (error) {
01858 unload_module();
01859 return 1;
01860 }
01861
01862 cli_status_registered = 1;
01863
01864 return 0;
01865 }
01866
01867 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Realtime SQLite configuration",
01868 .load = load_module,
01869 .unload = unload_module,
01870 );