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: 328209 $")
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, !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] || !strcmp(args->initfield, columnNames[i]))
01158 continue;
01159
01160 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01161 ast_log(LOG_WARNING, "Unable to allocate variable\n");
01162 return 1;
01163 }
01164
01165 ast_variable_append(cat, var);
01166 }
01167
01168 return 0;
01169 }
01170
01171 static struct ast_config *realtime_multi_handler(const char *database,
01172 const char *table, va_list ap)
01173 {
01174 char *query, *errormsg = NULL, *op, *tmp_str, *initfield;
01175 struct rt_multi_cfg_entry_args args;
01176 const char **params, **vals;
01177 struct ast_config *cfg;
01178 size_t params_count;
01179 int error;
01180
01181 if (!table) {
01182 ast_log(LOG_WARNING, "Table name unspecified\n");
01183 return NULL;
01184 }
01185
01186 if (!(cfg = ast_config_new())) {
01187 ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01188 return NULL;
01189 }
01190
01191 if (!(params_count = get_params(ap, ¶ms, &vals, 1))) {
01192 ast_config_destroy(cfg);
01193 return NULL;
01194 }
01195
01196 if (!(initfield = ast_strdup(params[0]))) {
01197 ast_config_destroy(cfg);
01198 ast_free(params);
01199 ast_free(vals);
01200 return NULL;
01201 }
01202
01203 tmp_str = strchr(initfield, ' ');
01204
01205 if (tmp_str)
01206 *tmp_str = '\0';
01207
01208 op = (!strchr(params[0], ' ')) ? " =" : "";
01209
01210
01211
01212
01213
01214 tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0];
01215
01216
01217 #undef QUERY
01218 #define QUERY "SELECT * FROM '%q' WHERE commented = 0 AND %q%s '%q'"
01219
01220
01221 if (!(query = sqlite_mprintf(QUERY, table, params[0], op, tmp_str))) {
01222 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01223 ast_config_destroy(cfg);
01224 ast_free(params);
01225 ast_free(vals);
01226 ast_free(initfield);
01227 return NULL;
01228 }
01229
01230 if (params_count > 1) {
01231 size_t i;
01232
01233 for (i = 1; i < params_count; i++) {
01234 op = (!strchr(params[i], ' ')) ? " =" : "";
01235 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01236 sqlite_freemem(query);
01237
01238 if (!tmp_str) {
01239 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01240 ast_config_destroy(cfg);
01241 ast_free(params);
01242 ast_free(vals);
01243 ast_free(initfield);
01244 return NULL;
01245 }
01246
01247 query = tmp_str;
01248 }
01249 }
01250
01251 ast_free(params);
01252 ast_free(vals);
01253
01254 if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01255 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01256 sqlite_freemem(query);
01257 ast_config_destroy(cfg);
01258 ast_free(initfield);
01259 return NULL;
01260 }
01261
01262 sqlite_freemem(query);
01263 query = tmp_str;
01264 ast_debug(1, "SQL query: %s\n", query);
01265 args.cfg = cfg;
01266 args.initfield = initfield;
01267
01268 ast_mutex_lock(&mutex);
01269
01270 RES_CONFIG_SQLITE_BEGIN
01271 error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01272 RES_CONFIG_SQLITE_END(error)
01273
01274 ast_mutex_unlock(&mutex);
01275
01276 sqlite_freemem(query);
01277 ast_free(initfield);
01278
01279 if (error) {
01280 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01281 sqlite_freemem(errormsg);
01282 ast_config_destroy(cfg);
01283 return NULL;
01284 }
01285 sqlite_freemem(errormsg);
01286
01287 return cfg;
01288 }
01289
01290 static int realtime_update_handler(const char *database, const char *table,
01291 const char *keyfield, const char *entity, va_list ap)
01292 {
01293 char *query, *errormsg = NULL, *tmp_str;
01294 const char **params, **vals;
01295 size_t params_count;
01296 int error, rows_num;
01297
01298 if (!table) {
01299 ast_log(LOG_WARNING, "Table name unspecified\n");
01300 return -1;
01301 }
01302
01303 if (!(params_count = get_params(ap, ¶ms, &vals, 1)))
01304 return -1;
01305
01306
01307 #undef QUERY
01308 #define QUERY "UPDATE '%q' SET %q = '%q'"
01309
01310
01311 if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) {
01312 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01313 ast_free(params);
01314 ast_free(vals);
01315 return -1;
01316 }
01317
01318 if (params_count > 1) {
01319 size_t i;
01320
01321 for (i = 1; i < params_count; i++) {
01322 tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]);
01323 sqlite_freemem(query);
01324
01325 if (!tmp_str) {
01326 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01327 ast_free(params);
01328 ast_free(vals);
01329 return -1;
01330 }
01331
01332 query = tmp_str;
01333 }
01334 }
01335
01336 ast_free(params);
01337 ast_free(vals);
01338
01339 if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01340 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01341 sqlite_freemem(query);
01342 return -1;
01343 }
01344
01345 sqlite_freemem(query);
01346 query = tmp_str;
01347 ast_debug(1, "SQL query: %s\n", query);
01348
01349 ast_mutex_lock(&mutex);
01350
01351 RES_CONFIG_SQLITE_BEGIN
01352 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01353 RES_CONFIG_SQLITE_END(error)
01354
01355 if (!error)
01356 rows_num = sqlite_changes(db);
01357 else
01358 rows_num = -1;
01359
01360 ast_mutex_unlock(&mutex);
01361
01362 sqlite_freemem(query);
01363
01364 if (error) {
01365 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01366 }
01367 sqlite_freemem(errormsg);
01368
01369 return rows_num;
01370 }
01371
01372 static int realtime_update2_handler(const char *database, const char *table,
01373 va_list ap)
01374 {
01375 char *errormsg = NULL, *tmp1, *tmp2;
01376 int error, rows_num, first = 1;
01377 struct ast_str *sql = ast_str_thread_get(&sql_buf, 100);
01378 struct ast_str *where = ast_str_thread_get(&where_buf, 100);
01379 const char *param, *value;
01380
01381 if (!table) {
01382 ast_log(LOG_WARNING, "Table name unspecified\n");
01383 return -1;
01384 }
01385
01386 if (!sql) {
01387 return -1;
01388 }
01389
01390 ast_str_set(&sql, 0, "UPDATE %s SET", table);
01391 ast_str_set(&where, 0, " WHERE");
01392
01393 while ((param = va_arg(ap, const char *))) {
01394 value = va_arg(ap, const char *);
01395 ast_str_append(&where, 0, "%s %s = %s",
01396 first ? "" : " AND",
01397 tmp1 = sqlite_mprintf("%q", param),
01398 tmp2 = sqlite_mprintf("%Q", value));
01399 sqlite_freemem(tmp1);
01400 sqlite_freemem(tmp2);
01401 first = 0;
01402 }
01403
01404 if (first) {
01405 ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database);
01406 return -1;
01407 }
01408
01409 first = 1;
01410 while ((param = va_arg(ap, const char *))) {
01411 value = va_arg(ap, const char *);
01412 ast_str_append(&sql, 0, "%s %s = %s",
01413 first ? "" : ",",
01414 tmp1 = sqlite_mprintf("%q", param),
01415 tmp2 = sqlite_mprintf("%Q", value));
01416 sqlite_freemem(tmp1);
01417 sqlite_freemem(tmp2);
01418 first = 0;
01419 }
01420
01421 ast_str_append(&sql, 0, " %s", ast_str_buffer(where));
01422 ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql));
01423
01424 ast_mutex_lock(&mutex);
01425
01426 RES_CONFIG_SQLITE_BEGIN
01427 error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg);
01428 RES_CONFIG_SQLITE_END(error)
01429
01430 if (!error) {
01431 rows_num = sqlite_changes(db);
01432 } else {
01433 rows_num = -1;
01434 }
01435
01436 ast_mutex_unlock(&mutex);
01437
01438 if (error) {
01439 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01440 }
01441 sqlite_freemem(errormsg);
01442
01443 return rows_num;
01444 }
01445
01446 static int realtime_store_handler(const char *database, const char *table, va_list ap)
01447 {
01448 char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01449 const char **params, **vals;
01450 size_t params_count;
01451 int error, rows_id;
01452 size_t i;
01453
01454 if (!table) {
01455 ast_log(LOG_WARNING, "Table name unspecified\n");
01456 return -1;
01457 }
01458
01459 if (!(params_count = get_params(ap, ¶ms, &vals, 1)))
01460 return -1;
01461
01462
01463 #undef QUERY
01464 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01465
01466
01467 for (i = 0; i < params_count; i++) {
01468 if ( tmp_keys2 ) {
01469 tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]);
01470 sqlite_freemem(tmp_keys2);
01471 } else {
01472 tmp_keys = sqlite_mprintf("%q", params[i]);
01473 }
01474 if (!tmp_keys) {
01475 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01476 sqlite_freemem(tmp_vals);
01477 ast_free(params);
01478 ast_free(vals);
01479 return -1;
01480 }
01481
01482 if ( tmp_vals2 ) {
01483 tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, vals[i]);
01484 sqlite_freemem(tmp_vals2);
01485 } else {
01486 tmp_vals = sqlite_mprintf("'%q'", vals[i]);
01487 }
01488 if (!tmp_vals) {
01489 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01490 sqlite_freemem(tmp_keys);
01491 ast_free(params);
01492 ast_free(vals);
01493 return -1;
01494 }
01495
01496
01497 tmp_keys2 = tmp_keys;
01498 tmp_vals2 = tmp_vals;
01499 }
01500
01501 ast_free(params);
01502 ast_free(vals);
01503
01504 if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01505 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01506 sqlite_freemem(tmp_keys);
01507 sqlite_freemem(tmp_vals);
01508 return -1;
01509 }
01510
01511 sqlite_freemem(tmp_keys);
01512 sqlite_freemem(tmp_vals);
01513
01514 ast_debug(1, "SQL query: %s\n", tmp_str);
01515
01516 ast_mutex_lock(&mutex);
01517
01518 RES_CONFIG_SQLITE_BEGIN
01519 error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01520 RES_CONFIG_SQLITE_END(error)
01521
01522 if (!error) {
01523 rows_id = sqlite_last_insert_rowid(db);
01524 } else {
01525 rows_id = -1;
01526 }
01527
01528 ast_mutex_unlock(&mutex);
01529
01530 sqlite_freemem(tmp_str);
01531
01532 if (error) {
01533 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01534 }
01535 sqlite_freemem(errormsg);
01536
01537 return rows_id;
01538 }
01539
01540 static int realtime_destroy_handler(const char *database, const char *table,
01541 const char *keyfield, const char *entity, va_list ap)
01542 {
01543 char *query, *errormsg = NULL, *tmp_str;
01544 const char **params = NULL, **vals = NULL;
01545 size_t params_count;
01546 int error, rows_num;
01547 size_t i;
01548
01549 if (!table) {
01550 ast_log(LOG_WARNING, "Table name unspecified\n");
01551 return -1;
01552 }
01553
01554 params_count = get_params(ap, ¶ms, &vals, 0);
01555
01556
01557 #undef QUERY
01558 #define QUERY "DELETE FROM '%q' WHERE"
01559
01560
01561 if (!(query = sqlite_mprintf(QUERY, table))) {
01562 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01563 ast_free(params);
01564 ast_free(vals);
01565 return -1;
01566 }
01567
01568 for (i = 0; i < params_count; i++) {
01569 tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01570 sqlite_freemem(query);
01571
01572 if (!tmp_str) {
01573 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01574 ast_free(params);
01575 ast_free(vals);
01576 return -1;
01577 }
01578
01579 query = tmp_str;
01580 }
01581
01582 ast_free(params);
01583 ast_free(vals);
01584 if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01585 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01586 sqlite_freemem(query);
01587 return -1;
01588 }
01589 sqlite_freemem(query);
01590 query = tmp_str;
01591 ast_debug(1, "SQL query: %s\n", query);
01592
01593 ast_mutex_lock(&mutex);
01594
01595 RES_CONFIG_SQLITE_BEGIN
01596 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01597 RES_CONFIG_SQLITE_END(error)
01598
01599 if (!error) {
01600 rows_num = sqlite_changes(db);
01601 } else {
01602 rows_num = -1;
01603 }
01604
01605 ast_mutex_unlock(&mutex);
01606
01607 sqlite_freemem(query);
01608
01609 if (error) {
01610 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01611 }
01612 sqlite_freemem(errormsg);
01613
01614 return rows_num;
01615 }
01616
01617 static int realtime_require_handler(const char *unused, const char *tablename, va_list ap)
01618 {
01619 struct sqlite_cache_tables *tbl = find_table(tablename);
01620 struct sqlite_cache_columns *col;
01621 char *elm;
01622 int type, res = 0;
01623
01624 if (!tbl) {
01625 return -1;
01626 }
01627
01628 while ((elm = va_arg(ap, char *))) {
01629 type = va_arg(ap, require_type);
01630 va_arg(ap, int);
01631
01632 AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01633 if (strcmp(col->name, elm) == 0) {
01634
01635
01636
01637
01638 if (col->isint && !ast_rq_is_int(type)) {
01639 ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01640 res = -1;
01641 }
01642 break;
01643 }
01644 }
01645 if (!col) {
01646 ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01647 }
01648 }
01649 AST_RWLIST_UNLOCK(&(tbl->columns));
01650 return res;
01651 }
01652
01653 static int realtime_unload_handler(const char *unused, const char *tablename)
01654 {
01655 struct sqlite_cache_tables *tbl;
01656 AST_RWLIST_WRLOCK(&sqlite_tables);
01657 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) {
01658 if (!strcasecmp(tbl->name, tablename)) {
01659 AST_RWLIST_REMOVE_CURRENT(list);
01660 free_table(tbl);
01661 }
01662 }
01663 AST_RWLIST_TRAVERSE_SAFE_END
01664 AST_RWLIST_UNLOCK(&sqlite_tables);
01665 return 0;
01666 }
01667
01668 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01669 {
01670 switch (cmd) {
01671 case CLI_INIT:
01672 e->command = "sqlite show status";
01673 e->usage =
01674 "Usage: sqlite show status\n"
01675 " Show status information about the SQLite 2 driver\n";
01676 return NULL;
01677 case CLI_GENERATE:
01678 return NULL;
01679 }
01680
01681 if (a->argc != 3)
01682 return CLI_SHOWUSAGE;
01683
01684 ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01685 ast_cli(a->fd, "config_table: ");
01686
01687 if (!config_table)
01688 ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01689 else
01690 ast_cli(a->fd, "%s\n", config_table);
01691
01692 ast_cli(a->fd, "cdr_table: ");
01693
01694 if (!cdr_table)
01695 ast_cli(a->fd, "unspecified, CDR support disabled\n");
01696 else
01697 ast_cli(a->fd, "%s\n", cdr_table);
01698
01699 return CLI_SUCCESS;
01700 }
01701
01702 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01703 {
01704 struct sqlite_cache_tables *tbl;
01705 struct sqlite_cache_columns *col;
01706 int found = 0;
01707
01708 switch (cmd) {
01709 case CLI_INIT:
01710 e->command = "sqlite show tables";
01711 e->usage =
01712 "Usage: sqlite show tables\n"
01713 " Show table information about the SQLite 2 driver\n";
01714 return NULL;
01715 case CLI_GENERATE:
01716 return NULL;
01717 }
01718
01719 if (a->argc != 3)
01720 return CLI_SHOWUSAGE;
01721
01722 AST_RWLIST_RDLOCK(&sqlite_tables);
01723 AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01724 found++;
01725 ast_cli(a->fd, "Table %s:\n", tbl->name);
01726 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01727 fprintf(stderr, "%s\n", col->name);
01728 ast_cli(a->fd, " %20.20s %-30.30s\n", col->name, col->type);
01729 }
01730 }
01731 AST_RWLIST_UNLOCK(&sqlite_tables);
01732
01733 if (!found) {
01734 ast_cli(a->fd, "No tables currently in cache\n");
01735 }
01736
01737 return CLI_SUCCESS;
01738 }
01739
01740 static int unload_module(void)
01741 {
01742 if (cli_status_registered)
01743 ast_cli_unregister_multiple(cli_status, ARRAY_LEN(cli_status));
01744
01745 if (cdr_registered)
01746 ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
01747
01748 ast_config_engine_deregister(&sqlite_engine);
01749
01750 if (db)
01751 sqlite_close(db);
01752
01753 unload_config();
01754
01755 return 0;
01756 }
01757
01758 static int load_module(void)
01759 {
01760 char *errormsg = NULL;
01761 int error;
01762
01763 db = NULL;
01764 cdr_registered = 0;
01765 cli_status_registered = 0;
01766 dbfile = NULL;
01767 config_table = NULL;
01768 cdr_table = NULL;
01769 error = load_config();
01770
01771 if (error)
01772 return AST_MODULE_LOAD_DECLINE;
01773
01774 if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01775 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01776 sqlite_freemem(errormsg);
01777 unload_module();
01778 return 1;
01779 }
01780
01781 sqlite_freemem(errormsg);
01782 errormsg = NULL;
01783 ast_config_engine_register(&sqlite_engine);
01784
01785 if (use_cdr) {
01786 char *query;
01787
01788
01789 #undef QUERY
01790 #define QUERY "SELECT COUNT(id) FROM %Q;"
01791
01792
01793 query = sqlite_mprintf(QUERY, cdr_table);
01794
01795 if (!query) {
01796 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01797 unload_module();
01798 return 1;
01799 }
01800
01801 ast_debug(1, "SQL query: %s\n", query);
01802
01803 RES_CONFIG_SQLITE_BEGIN
01804 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01805 RES_CONFIG_SQLITE_END(error)
01806
01807 sqlite_freemem(query);
01808
01809 if (error) {
01810
01811
01812
01813 if (error != SQLITE_ERROR) {
01814 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01815 sqlite_freemem(errormsg);
01816 unload_module();
01817 return 1;
01818 }
01819
01820 sqlite_freemem(errormsg);
01821 errormsg = NULL;
01822 query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01823
01824 if (!query) {
01825 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01826 unload_module();
01827 return 1;
01828 }
01829
01830 ast_debug(1, "SQL query: %s\n", query);
01831
01832 RES_CONFIG_SQLITE_BEGIN
01833 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01834 RES_CONFIG_SQLITE_END(error)
01835
01836 sqlite_freemem(query);
01837
01838 if (error) {
01839 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01840 sqlite_freemem(errormsg);
01841 unload_module();
01842 return 1;
01843 }
01844 }
01845 sqlite_freemem(errormsg);
01846 errormsg = NULL;
01847
01848 error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01849
01850 if (error) {
01851 unload_module();
01852 return 1;
01853 }
01854
01855 cdr_registered = 1;
01856 }
01857
01858 error = ast_cli_register_multiple(cli_status, ARRAY_LEN(cli_status));
01859
01860 if (error) {
01861 unload_module();
01862 return 1;
01863 }
01864
01865 cli_status_registered = 1;
01866
01867 return 0;
01868 }
01869
01870 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Realtime SQLite configuration",
01871 .load = load_module,
01872 .unload = unload_module,
01873 .load_pri = AST_MODPRI_REALTIME_DRIVER,
01874 );