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