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: 371590 $")
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 (ast_asprintf(&sql, sql_table_structure, tablename) < 0) {
00672 sql = NULL;
00673 }
00674 if (!(tblptr = ast_calloc(1, sizeof(*tblptr) + strlen(tablename) + 1))) {
00675 AST_RWLIST_UNLOCK(&sqlite_tables);
00676 ast_log(LOG_ERROR, "Memory error. Cannot cache table '%s'\n", tablename);
00677 ast_free(sql);
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 ast_free(sql);
00694 return NULL;
00695 }
00696 ast_mutex_unlock(&mutex);
00697 ast_free(sql);
00698
00699 if (AST_LIST_EMPTY(&(tblptr->columns))) {
00700 free_table(tblptr);
00701 AST_RWLIST_UNLOCK(&sqlite_tables);
00702 return NULL;
00703 }
00704
00705 AST_RWLIST_INSERT_TAIL(&sqlite_tables, tblptr, list);
00706 AST_RWLIST_RDLOCK(&(tblptr->columns));
00707 AST_RWLIST_UNLOCK(&sqlite_tables);
00708 return tblptr;
00709 }
00710
00711 #define release_table(a) AST_RWLIST_UNLOCK(&((a)->columns))
00712
00713 static int set_var(char **var, const char *name, const char *value)
00714 {
00715 if (*var)
00716 ast_free(*var);
00717
00718 *var = ast_strdup(value);
00719
00720 if (!*var) {
00721 ast_log(LOG_WARNING, "Unable to allocate variable %s\n", name);
00722 return 1;
00723 }
00724
00725 return 0;
00726 }
00727
00728 static int check_vars(void)
00729 {
00730 if (!dbfile) {
00731 ast_log(LOG_ERROR, "Required parameter undefined: dbfile\n");
00732 return 1;
00733 }
00734
00735 use_cdr = (cdr_table != NULL);
00736
00737 return 0;
00738 }
00739
00740 static int load_config(void)
00741 {
00742 struct ast_config *config;
00743 struct ast_variable *var;
00744 int error;
00745 struct ast_flags config_flags = { 0 };
00746
00747 config = ast_config_load(RES_CONFIG_SQLITE_CONF_FILE, config_flags);
00748
00749 if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
00750 ast_log(LOG_ERROR, "Unable to load " RES_CONFIG_SQLITE_CONF_FILE "\n");
00751 return 1;
00752 }
00753
00754 for (var = ast_variable_browse(config, "general"); var; var = var->next) {
00755 if (!strcasecmp(var->name, "dbfile"))
00756 SET_VAR(config, dbfile, var);
00757 else if (!strcasecmp(var->name, "config_table"))
00758 SET_VAR(config, config_table, var);
00759 else if (!strcasecmp(var->name, "cdr_table")) {
00760 SET_VAR(config, cdr_table, var);
00761 } else
00762 ast_log(LOG_WARNING, "Unknown parameter : %s\n", var->name);
00763 }
00764
00765 ast_config_destroy(config);
00766 error = check_vars();
00767
00768 if (error) {
00769 unload_config();
00770 return 1;
00771 }
00772
00773 return 0;
00774 }
00775
00776 static void unload_config(void)
00777 {
00778 struct sqlite_cache_tables *tbl;
00779 ast_free(dbfile);
00780 dbfile = NULL;
00781 ast_free(config_table);
00782 config_table = NULL;
00783 ast_free(cdr_table);
00784 cdr_table = NULL;
00785 AST_RWLIST_WRLOCK(&sqlite_tables);
00786 while ((tbl = AST_RWLIST_REMOVE_HEAD(&sqlite_tables, list))) {
00787 free_table(tbl);
00788 }
00789 AST_RWLIST_UNLOCK(&sqlite_tables);
00790 }
00791
00792 static int cdr_handler(struct ast_cdr *cdr)
00793 {
00794 char *errormsg = NULL, *tmp, workspace[500];
00795 int error, scannum;
00796 struct sqlite_cache_tables *tbl = find_table(cdr_table);
00797 struct sqlite_cache_columns *col;
00798 struct ast_str *sql1 = ast_str_create(160), *sql2 = ast_str_create(16);
00799 int first = 1;
00800
00801 if (!tbl) {
00802 ast_log(LOG_WARNING, "No such table: %s\n", cdr_table);
00803 return -1;
00804 }
00805
00806 ast_str_set(&sql1, 0, "INSERT INTO %s (", cdr_table);
00807 ast_str_set(&sql2, 0, ") VALUES (");
00808
00809 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
00810 if (col->isint) {
00811 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 1);
00812 if (!tmp) {
00813 continue;
00814 }
00815 if (sscanf(tmp, "%30d", &scannum) == 1) {
00816 ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name);
00817 ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", scannum);
00818 }
00819 } else {
00820 ast_cdr_getvar(cdr, col->name, &tmp, workspace, sizeof(workspace), 0, 0);
00821 if (!tmp) {
00822 continue;
00823 }
00824 ast_str_append(&sql1, 0, "%s%s", first ? "" : ",", col->name);
00825 tmp = sqlite_mprintf("%Q", tmp);
00826 ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", tmp);
00827 sqlite_freemem(tmp);
00828 }
00829 first = 0;
00830 }
00831 release_table(tbl);
00832
00833 ast_str_append(&sql1, 0, "%s)", ast_str_buffer(sql2));
00834 ast_free(sql2);
00835
00836 ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql1));
00837
00838 ast_mutex_lock(&mutex);
00839
00840 RES_CONFIG_SQLITE_BEGIN
00841 error = sqlite_exec(db, ast_str_buffer(sql1), NULL, NULL, &errormsg);
00842 RES_CONFIG_SQLITE_END(error)
00843
00844 ast_mutex_unlock(&mutex);
00845
00846 ast_free(sql1);
00847
00848 if (error) {
00849 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00850 sqlite_freemem(errormsg);
00851 return 1;
00852 }
00853 sqlite_freemem(errormsg);
00854
00855 return 0;
00856 }
00857
00858 static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
00859 {
00860 struct cfg_entry_args *args;
00861 struct ast_variable *var;
00862
00863 if (argc != RES_CONFIG_SQLITE_CONFIG_COLUMNS) {
00864 ast_log(LOG_WARNING, "Corrupt table\n");
00865 return 1;
00866 }
00867
00868 args = arg;
00869
00870 if (!strcmp(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], "#include")) {
00871 struct ast_config *cfg;
00872 char *val;
00873
00874 val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL];
00875 cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked);
00876
00877 if (!cfg) {
00878 ast_log(LOG_WARNING, "Unable to include %s\n", val);
00879 return 1;
00880 } else {
00881 args->cfg = cfg;
00882 return 0;
00883 }
00884 }
00885
00886 if (!args->cat_name || strcmp(args->cat_name, argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY])) {
00887 args->cat = ast_category_new(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY], "", 99999);
00888
00889 if (!args->cat) {
00890 ast_log(LOG_WARNING, "Unable to allocate category\n");
00891 return 1;
00892 }
00893
00894 ast_free(args->cat_name);
00895 args->cat_name = ast_strdup(argv[RES_CONFIG_SQLITE_CONFIG_CATEGORY]);
00896
00897 if (!args->cat_name) {
00898 ast_category_destroy(args->cat);
00899 return 1;
00900 }
00901
00902 ast_category_append(args->cfg, args->cat);
00903 }
00904
00905 var = ast_variable_new(argv[RES_CONFIG_SQLITE_CONFIG_VAR_NAME], argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL], "");
00906
00907 if (!var) {
00908 ast_log(LOG_WARNING, "Unable to allocate variable\n");
00909 return 1;
00910 }
00911
00912 ast_variable_append(args->cat, var);
00913
00914 return 0;
00915 }
00916
00917 static struct ast_config *config_handler(const char *database, const char *table, const char *file,
00918 struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
00919 {
00920 struct cfg_entry_args args;
00921 char *query, *errormsg = NULL;
00922 int error;
00923
00924 if (!config_table) {
00925 if (!table) {
00926 ast_log(LOG_ERROR, "Table name unspecified\n");
00927 return NULL;
00928 }
00929 } else
00930 table = config_table;
00931
00932 query = sqlite_mprintf(sql_get_config_table, table, file);
00933
00934 if (!query) {
00935 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
00936 return NULL;
00937 }
00938
00939 ast_debug(1, "SQL query: %s\n", query);
00940 args.cfg = cfg;
00941 args.cat = NULL;
00942 args.cat_name = NULL;
00943 args.flags = flags;
00944 args.who_asked = who_asked;
00945
00946 ast_mutex_lock(&mutex);
00947
00948 RES_CONFIG_SQLITE_BEGIN
00949 error = sqlite_exec(db, query, add_cfg_entry, &args, &errormsg);
00950 RES_CONFIG_SQLITE_END(error)
00951
00952 ast_mutex_unlock(&mutex);
00953
00954 ast_free(args.cat_name);
00955 sqlite_freemem(query);
00956
00957 if (error) {
00958 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
00959 sqlite_freemem(errormsg);
00960 return NULL;
00961 }
00962 sqlite_freemem(errormsg);
00963
00964 return cfg;
00965 }
00966
00967 static size_t get_params(va_list ap, const char ***params_ptr, const char ***vals_ptr, int warn)
00968 {
00969 const char **tmp, *param, *val, **params, **vals;
00970 size_t params_count;
00971
00972 params = NULL;
00973 vals = NULL;
00974 params_count = 0;
00975
00976 while ((param = va_arg(ap, const char *)) && (val = va_arg(ap, const char *))) {
00977 if (!(tmp = ast_realloc(params, (params_count + 1) * sizeof(char *)))) {
00978 ast_free(params);
00979 ast_free(vals);
00980 return 0;
00981 }
00982 params = tmp;
00983
00984 if (!(tmp = ast_realloc(vals, (params_count + 1) * sizeof(char *)))) {
00985 ast_free(params);
00986 ast_free(vals);
00987 return 0;
00988 }
00989 vals = tmp;
00990
00991 params[params_count] = param;
00992 vals[params_count] = val;
00993 params_count++;
00994 }
00995
00996 if (params_count > 0) {
00997 *params_ptr = params;
00998 *vals_ptr = vals;
00999 } else if (warn) {
01000 ast_log(LOG_WARNING, "1 parameter and 1 value at least required\n");
01001 }
01002
01003 return params_count;
01004 }
01005
01006 static int add_rt_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
01007 {
01008 struct rt_cfg_entry_args *args;
01009 struct ast_variable *var;
01010 int i;
01011
01012 args = arg;
01013
01014 for (i = 0; i < argc; i++) {
01015 if (!argv[i])
01016 continue;
01017
01018 if (!(var = ast_variable_new(columnNames[i], argv[i], "")))
01019 return 1;
01020
01021 if (!args->var)
01022 args->var = var;
01023
01024 if (!args->last)
01025 args->last = var;
01026 else {
01027 args->last->next = var;
01028 args->last = var;
01029 }
01030 }
01031
01032 return 0;
01033 }
01034
01035 static struct ast_variable * realtime_handler(const char *database, const char *table, va_list ap)
01036 {
01037 char *query, *errormsg = NULL, *op, *tmp_str;
01038 struct rt_cfg_entry_args args;
01039 const char **params, **vals;
01040 size_t params_count;
01041 int error;
01042
01043 if (!table) {
01044 ast_log(LOG_WARNING, "Table name unspecified\n");
01045 return NULL;
01046 }
01047
01048 params_count = get_params(ap, ¶ms, &vals, 1);
01049
01050 if (params_count == 0)
01051 return NULL;
01052
01053 op = (strchr(params[0], ' ') == NULL) ? " =" : "";
01054
01055
01056 #undef QUERY
01057 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'"
01058
01059
01060 query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", params[0], op, vals[0]);
01061
01062 if (!query) {
01063 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01064 ast_free(params);
01065 ast_free(vals);
01066 return NULL;
01067 }
01068
01069 if (params_count > 1) {
01070 size_t i;
01071
01072 for (i = 1; i < params_count; i++) {
01073 op = (strchr(params[i], ' ') == NULL) ? " =" : "";
01074 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01075 sqlite_freemem(query);
01076
01077 if (!tmp_str) {
01078 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01079 ast_free(params);
01080 ast_free(vals);
01081 return NULL;
01082 }
01083
01084 query = tmp_str;
01085 }
01086 }
01087
01088 ast_free(params);
01089 ast_free(vals);
01090
01091 tmp_str = sqlite_mprintf("%s LIMIT 1;", query);
01092 sqlite_freemem(query);
01093
01094 if (!tmp_str) {
01095 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01096 return NULL;
01097 }
01098
01099 query = tmp_str;
01100 ast_debug(1, "SQL query: %s\n", query);
01101 args.var = NULL;
01102 args.last = NULL;
01103
01104 ast_mutex_lock(&mutex);
01105
01106 RES_CONFIG_SQLITE_BEGIN
01107 error = sqlite_exec(db, query, add_rt_cfg_entry, &args, &errormsg);
01108 RES_CONFIG_SQLITE_END(error)
01109
01110 ast_mutex_unlock(&mutex);
01111
01112 sqlite_freemem(query);
01113
01114 if (error) {
01115 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01116 sqlite_freemem(errormsg);
01117 ast_variables_destroy(args.var);
01118 return NULL;
01119 }
01120 sqlite_freemem(errormsg);
01121
01122 return args.var;
01123 }
01124
01125 static int add_rt_multi_cfg_entry(void *arg, int argc, char **argv, char **columnNames)
01126 {
01127 struct rt_multi_cfg_entry_args *args;
01128 struct ast_category *cat;
01129 struct ast_variable *var;
01130 char *cat_name;
01131 size_t i;
01132
01133 args = arg;
01134 cat_name = NULL;
01135
01136
01137
01138
01139
01140
01141 for (i = 0; i < argc; i++) {
01142 if (!strcmp(args->initfield, columnNames[i]))
01143 cat_name = argv[i];
01144 }
01145
01146 if (!cat_name) {
01147 ast_log(LOG_ERROR, "Bogus SQL results, cat_name is NULL !\n");
01148 return 1;
01149 }
01150
01151 if (!(cat = ast_category_new(cat_name, "", 99999))) {
01152 ast_log(LOG_WARNING, "Unable to allocate category\n");
01153 return 1;
01154 }
01155
01156 ast_category_append(args->cfg, cat);
01157
01158 for (i = 0; i < argc; i++) {
01159 if (!argv[i]) {
01160 continue;
01161 }
01162
01163 if (!(var = ast_variable_new(columnNames[i], argv[i], ""))) {
01164 ast_log(LOG_WARNING, "Unable to allocate variable\n");
01165 return 1;
01166 }
01167
01168 ast_variable_append(cat, var);
01169 }
01170
01171 return 0;
01172 }
01173
01174 static struct ast_config *realtime_multi_handler(const char *database,
01175 const char *table, va_list ap)
01176 {
01177 char *query, *errormsg = NULL, *op, *tmp_str, *initfield;
01178 struct rt_multi_cfg_entry_args args;
01179 const char **params, **vals;
01180 struct ast_config *cfg;
01181 size_t params_count;
01182 int error;
01183
01184 if (!table) {
01185 ast_log(LOG_WARNING, "Table name unspecified\n");
01186 return NULL;
01187 }
01188
01189 if (!(cfg = ast_config_new())) {
01190 ast_log(LOG_WARNING, "Unable to allocate configuration structure\n");
01191 return NULL;
01192 }
01193
01194 if (!(params_count = get_params(ap, ¶ms, &vals, 1))) {
01195 ast_config_destroy(cfg);
01196 return NULL;
01197 }
01198
01199 if (!(initfield = ast_strdup(params[0]))) {
01200 ast_config_destroy(cfg);
01201 ast_free(params);
01202 ast_free(vals);
01203 return NULL;
01204 }
01205
01206 tmp_str = strchr(initfield, ' ');
01207
01208 if (tmp_str)
01209 *tmp_str = '\0';
01210
01211 op = (!strchr(params[0], ' ')) ? " =" : "";
01212
01213
01214
01215
01216
01217 tmp_str = (!strcmp(vals[0], "\\_%")) ? "_%" : (char *)vals[0];
01218
01219
01220 #undef QUERY
01221 #define QUERY "SELECT * FROM '%q' WHERE%s %q%s '%q'"
01222
01223
01224 if (!(query = sqlite_mprintf(QUERY, table, (config_table && !strcmp(config_table, table)) ? " commented = 0 AND" : "", params[0], op, tmp_str))) {
01225 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01226 ast_config_destroy(cfg);
01227 ast_free(params);
01228 ast_free(vals);
01229 ast_free(initfield);
01230 return NULL;
01231 }
01232
01233 if (params_count > 1) {
01234 size_t i;
01235
01236 for (i = 1; i < params_count; i++) {
01237 op = (!strchr(params[i], ' ')) ? " =" : "";
01238 tmp_str = sqlite_mprintf("%s AND %q%s '%q'", query, params[i], op, vals[i]);
01239 sqlite_freemem(query);
01240
01241 if (!tmp_str) {
01242 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01243 ast_config_destroy(cfg);
01244 ast_free(params);
01245 ast_free(vals);
01246 ast_free(initfield);
01247 return NULL;
01248 }
01249
01250 query = tmp_str;
01251 }
01252 }
01253
01254 ast_free(params);
01255 ast_free(vals);
01256
01257 if (!(tmp_str = sqlite_mprintf("%s ORDER BY %q;", query, initfield))) {
01258 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01259 sqlite_freemem(query);
01260 ast_config_destroy(cfg);
01261 ast_free(initfield);
01262 return NULL;
01263 }
01264
01265 sqlite_freemem(query);
01266 query = tmp_str;
01267 ast_debug(1, "SQL query: %s\n", query);
01268 args.cfg = cfg;
01269 args.initfield = initfield;
01270
01271 ast_mutex_lock(&mutex);
01272
01273 RES_CONFIG_SQLITE_BEGIN
01274 error = sqlite_exec(db, query, add_rt_multi_cfg_entry, &args, &errormsg);
01275 RES_CONFIG_SQLITE_END(error)
01276
01277 ast_mutex_unlock(&mutex);
01278
01279 sqlite_freemem(query);
01280 ast_free(initfield);
01281
01282 if (error) {
01283 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01284 sqlite_freemem(errormsg);
01285 ast_config_destroy(cfg);
01286 return NULL;
01287 }
01288 sqlite_freemem(errormsg);
01289
01290 return cfg;
01291 }
01292
01293 static int realtime_update_handler(const char *database, const char *table,
01294 const char *keyfield, const char *entity, va_list ap)
01295 {
01296 char *query, *errormsg = NULL, *tmp_str;
01297 const char **params, **vals;
01298 size_t params_count;
01299 int error, rows_num;
01300
01301 if (!table) {
01302 ast_log(LOG_WARNING, "Table name unspecified\n");
01303 return -1;
01304 }
01305
01306 if (!(params_count = get_params(ap, ¶ms, &vals, 1)))
01307 return -1;
01308
01309
01310 #undef QUERY
01311 #define QUERY "UPDATE '%q' SET %q = '%q'"
01312
01313
01314 if (!(query = sqlite_mprintf(QUERY, table, params[0], vals[0]))) {
01315 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01316 ast_free(params);
01317 ast_free(vals);
01318 return -1;
01319 }
01320
01321 if (params_count > 1) {
01322 size_t i;
01323
01324 for (i = 1; i < params_count; i++) {
01325 tmp_str = sqlite_mprintf("%s, %q = '%q'", query, params[i], vals[i]);
01326 sqlite_freemem(query);
01327
01328 if (!tmp_str) {
01329 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01330 ast_free(params);
01331 ast_free(vals);
01332 return -1;
01333 }
01334
01335 query = tmp_str;
01336 }
01337 }
01338
01339 ast_free(params);
01340 ast_free(vals);
01341
01342 if (!(tmp_str = sqlite_mprintf("%s WHERE %q = '%q';", query, keyfield, entity))) {
01343 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01344 sqlite_freemem(query);
01345 return -1;
01346 }
01347
01348 sqlite_freemem(query);
01349 query = tmp_str;
01350 ast_debug(1, "SQL query: %s\n", query);
01351
01352 ast_mutex_lock(&mutex);
01353
01354 RES_CONFIG_SQLITE_BEGIN
01355 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01356 RES_CONFIG_SQLITE_END(error)
01357
01358 if (!error)
01359 rows_num = sqlite_changes(db);
01360 else
01361 rows_num = -1;
01362
01363 ast_mutex_unlock(&mutex);
01364
01365 sqlite_freemem(query);
01366
01367 if (error) {
01368 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01369 }
01370 sqlite_freemem(errormsg);
01371
01372 return rows_num;
01373 }
01374
01375 static int realtime_update2_handler(const char *database, const char *table,
01376 va_list ap)
01377 {
01378 char *errormsg = NULL, *tmp1, *tmp2;
01379 int error, rows_num, first = 1;
01380 struct ast_str *sql = ast_str_thread_get(&sql_buf, 100);
01381 struct ast_str *where = ast_str_thread_get(&where_buf, 100);
01382 const char *param, *value;
01383
01384 if (!table) {
01385 ast_log(LOG_WARNING, "Table name unspecified\n");
01386 return -1;
01387 }
01388
01389 if (!sql) {
01390 return -1;
01391 }
01392
01393 ast_str_set(&sql, 0, "UPDATE %s SET", table);
01394 ast_str_set(&where, 0, " WHERE");
01395
01396 while ((param = va_arg(ap, const char *))) {
01397 value = va_arg(ap, const char *);
01398 ast_str_append(&where, 0, "%s %s = %s",
01399 first ? "" : " AND",
01400 tmp1 = sqlite_mprintf("%q", param),
01401 tmp2 = sqlite_mprintf("%Q", value));
01402 sqlite_freemem(tmp1);
01403 sqlite_freemem(tmp2);
01404 first = 0;
01405 }
01406
01407 if (first) {
01408 ast_log(LOG_ERROR, "No criteria specified on update to '%s@%s'!\n", table, database);
01409 return -1;
01410 }
01411
01412 first = 1;
01413 while ((param = va_arg(ap, const char *))) {
01414 value = va_arg(ap, const char *);
01415 ast_str_append(&sql, 0, "%s %s = %s",
01416 first ? "" : ",",
01417 tmp1 = sqlite_mprintf("%q", param),
01418 tmp2 = sqlite_mprintf("%Q", value));
01419 sqlite_freemem(tmp1);
01420 sqlite_freemem(tmp2);
01421 first = 0;
01422 }
01423
01424 ast_str_append(&sql, 0, " %s", ast_str_buffer(where));
01425 ast_debug(1, "SQL query: %s\n", ast_str_buffer(sql));
01426
01427 ast_mutex_lock(&mutex);
01428
01429 RES_CONFIG_SQLITE_BEGIN
01430 error = sqlite_exec(db, ast_str_buffer(sql), NULL, NULL, &errormsg);
01431 RES_CONFIG_SQLITE_END(error)
01432
01433 if (!error) {
01434 rows_num = sqlite_changes(db);
01435 } else {
01436 rows_num = -1;
01437 }
01438
01439 ast_mutex_unlock(&mutex);
01440
01441 if (error) {
01442 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01443 }
01444 sqlite_freemem(errormsg);
01445
01446 return rows_num;
01447 }
01448
01449 static int realtime_store_handler(const char *database, const char *table, va_list ap)
01450 {
01451 char *errormsg = NULL, *tmp_str, *tmp_keys = NULL, *tmp_keys2 = NULL, *tmp_vals = NULL, *tmp_vals2 = NULL;
01452 const char **params, **vals;
01453 size_t params_count;
01454 int error, rows_id;
01455 size_t i;
01456
01457 if (!table) {
01458 ast_log(LOG_WARNING, "Table name unspecified\n");
01459 return -1;
01460 }
01461
01462 if (!(params_count = get_params(ap, ¶ms, &vals, 1)))
01463 return -1;
01464
01465
01466 #undef QUERY
01467 #define QUERY "INSERT into '%q' (%s) VALUES (%s);"
01468
01469
01470 for (i = 0; i < params_count; i++) {
01471 if ( tmp_keys2 ) {
01472 tmp_keys = sqlite_mprintf("%s, %q", tmp_keys2, params[i]);
01473 sqlite_freemem(tmp_keys2);
01474 } else {
01475 tmp_keys = sqlite_mprintf("%q", params[i]);
01476 }
01477 if (!tmp_keys) {
01478 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01479 sqlite_freemem(tmp_vals);
01480 ast_free(params);
01481 ast_free(vals);
01482 return -1;
01483 }
01484
01485 if ( tmp_vals2 ) {
01486 tmp_vals = sqlite_mprintf("%s, '%q'", tmp_vals2, vals[i]);
01487 sqlite_freemem(tmp_vals2);
01488 } else {
01489 tmp_vals = sqlite_mprintf("'%q'", vals[i]);
01490 }
01491 if (!tmp_vals) {
01492 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01493 sqlite_freemem(tmp_keys);
01494 ast_free(params);
01495 ast_free(vals);
01496 return -1;
01497 }
01498
01499
01500 tmp_keys2 = tmp_keys;
01501 tmp_vals2 = tmp_vals;
01502 }
01503
01504 ast_free(params);
01505 ast_free(vals);
01506
01507 if (!(tmp_str = sqlite_mprintf(QUERY, table, tmp_keys, tmp_vals))) {
01508 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01509 sqlite_freemem(tmp_keys);
01510 sqlite_freemem(tmp_vals);
01511 return -1;
01512 }
01513
01514 sqlite_freemem(tmp_keys);
01515 sqlite_freemem(tmp_vals);
01516
01517 ast_debug(1, "SQL query: %s\n", tmp_str);
01518
01519 ast_mutex_lock(&mutex);
01520
01521 RES_CONFIG_SQLITE_BEGIN
01522 error = sqlite_exec(db, tmp_str, NULL, NULL, &errormsg);
01523 RES_CONFIG_SQLITE_END(error)
01524
01525 if (!error) {
01526 rows_id = sqlite_last_insert_rowid(db);
01527 } else {
01528 rows_id = -1;
01529 }
01530
01531 ast_mutex_unlock(&mutex);
01532
01533 sqlite_freemem(tmp_str);
01534
01535 if (error) {
01536 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01537 }
01538 sqlite_freemem(errormsg);
01539
01540 return rows_id;
01541 }
01542
01543 static int realtime_destroy_handler(const char *database, const char *table,
01544 const char *keyfield, const char *entity, va_list ap)
01545 {
01546 char *query, *errormsg = NULL, *tmp_str;
01547 const char **params = NULL, **vals = NULL;
01548 size_t params_count;
01549 int error, rows_num;
01550 size_t i;
01551
01552 if (!table) {
01553 ast_log(LOG_WARNING, "Table name unspecified\n");
01554 return -1;
01555 }
01556
01557 params_count = get_params(ap, ¶ms, &vals, 0);
01558
01559
01560 #undef QUERY
01561 #define QUERY "DELETE FROM '%q' WHERE"
01562
01563
01564 if (!(query = sqlite_mprintf(QUERY, table))) {
01565 ast_log(LOG_WARNING, "Unable to allocate SQL query\n");
01566 ast_free(params);
01567 ast_free(vals);
01568 return -1;
01569 }
01570
01571 for (i = 0; i < params_count; i++) {
01572 tmp_str = sqlite_mprintf("%s %q = '%q' AND", query, params[i], vals[i]);
01573 sqlite_freemem(query);
01574
01575 if (!tmp_str) {
01576 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01577 ast_free(params);
01578 ast_free(vals);
01579 return -1;
01580 }
01581
01582 query = tmp_str;
01583 }
01584
01585 ast_free(params);
01586 ast_free(vals);
01587 if (!(tmp_str = sqlite_mprintf("%s %q = '%q';", query, keyfield, entity))) {
01588 ast_log(LOG_WARNING, "Unable to reallocate SQL query\n");
01589 sqlite_freemem(query);
01590 return -1;
01591 }
01592 sqlite_freemem(query);
01593 query = tmp_str;
01594 ast_debug(1, "SQL query: %s\n", query);
01595
01596 ast_mutex_lock(&mutex);
01597
01598 RES_CONFIG_SQLITE_BEGIN
01599 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01600 RES_CONFIG_SQLITE_END(error)
01601
01602 if (!error) {
01603 rows_num = sqlite_changes(db);
01604 } else {
01605 rows_num = -1;
01606 }
01607
01608 ast_mutex_unlock(&mutex);
01609
01610 sqlite_freemem(query);
01611
01612 if (error) {
01613 ast_log(LOG_WARNING, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01614 }
01615 sqlite_freemem(errormsg);
01616
01617 return rows_num;
01618 }
01619
01620 static int realtime_require_handler(const char *unused, const char *tablename, va_list ap)
01621 {
01622 struct sqlite_cache_tables *tbl = find_table(tablename);
01623 struct sqlite_cache_columns *col;
01624 char *elm;
01625 int type, res = 0;
01626
01627 if (!tbl) {
01628 return -1;
01629 }
01630
01631 while ((elm = va_arg(ap, char *))) {
01632 type = va_arg(ap, require_type);
01633 va_arg(ap, int);
01634
01635 AST_RWLIST_TRAVERSE(&tbl->columns, col, list) {
01636 if (strcmp(col->name, elm) == 0) {
01637
01638
01639
01640
01641 if (col->isint && !ast_rq_is_int(type)) {
01642 ast_log(LOG_WARNING, "Realtime table %s: column '%s' is an integer field, but Asterisk requires that it not be!\n", tablename, col->name);
01643 res = -1;
01644 }
01645 break;
01646 }
01647 }
01648 if (!col) {
01649 ast_log(LOG_WARNING, "Realtime table %s requires column '%s', but that column does not exist!\n", tablename, elm);
01650 }
01651 }
01652 AST_RWLIST_UNLOCK(&(tbl->columns));
01653 return res;
01654 }
01655
01656 static int realtime_unload_handler(const char *unused, const char *tablename)
01657 {
01658 struct sqlite_cache_tables *tbl;
01659 AST_RWLIST_WRLOCK(&sqlite_tables);
01660 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&sqlite_tables, tbl, list) {
01661 if (!strcasecmp(tbl->name, tablename)) {
01662 AST_RWLIST_REMOVE_CURRENT(list);
01663 free_table(tbl);
01664 }
01665 }
01666 AST_RWLIST_TRAVERSE_SAFE_END
01667 AST_RWLIST_UNLOCK(&sqlite_tables);
01668 return 0;
01669 }
01670
01671 static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01672 {
01673 switch (cmd) {
01674 case CLI_INIT:
01675 e->command = "sqlite show status";
01676 e->usage =
01677 "Usage: sqlite show status\n"
01678 " Show status information about the SQLite 2 driver\n";
01679 return NULL;
01680 case CLI_GENERATE:
01681 return NULL;
01682 }
01683
01684 if (a->argc != 3)
01685 return CLI_SHOWUSAGE;
01686
01687 ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
01688 ast_cli(a->fd, "config_table: ");
01689
01690 if (!config_table)
01691 ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
01692 else
01693 ast_cli(a->fd, "%s\n", config_table);
01694
01695 ast_cli(a->fd, "cdr_table: ");
01696
01697 if (!cdr_table)
01698 ast_cli(a->fd, "unspecified, CDR support disabled\n");
01699 else
01700 ast_cli(a->fd, "%s\n", cdr_table);
01701
01702 return CLI_SUCCESS;
01703 }
01704
01705 static char *handle_cli_sqlite_show_tables(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01706 {
01707 struct sqlite_cache_tables *tbl;
01708 struct sqlite_cache_columns *col;
01709 int found = 0;
01710
01711 switch (cmd) {
01712 case CLI_INIT:
01713 e->command = "sqlite show tables";
01714 e->usage =
01715 "Usage: sqlite show tables\n"
01716 " Show table information about the SQLite 2 driver\n";
01717 return NULL;
01718 case CLI_GENERATE:
01719 return NULL;
01720 }
01721
01722 if (a->argc != 3)
01723 return CLI_SHOWUSAGE;
01724
01725 AST_RWLIST_RDLOCK(&sqlite_tables);
01726 AST_RWLIST_TRAVERSE(&sqlite_tables, tbl, list) {
01727 found++;
01728 ast_cli(a->fd, "Table %s:\n", tbl->name);
01729 AST_RWLIST_TRAVERSE(&(tbl->columns), col, list) {
01730 fprintf(stderr, "%s\n", col->name);
01731 ast_cli(a->fd, " %20.20s %-30.30s\n", col->name, col->type);
01732 }
01733 }
01734 AST_RWLIST_UNLOCK(&sqlite_tables);
01735
01736 if (!found) {
01737 ast_cli(a->fd, "No tables currently in cache\n");
01738 }
01739
01740 return CLI_SUCCESS;
01741 }
01742
01743 static int unload_module(void)
01744 {
01745 if (cli_status_registered)
01746 ast_cli_unregister_multiple(cli_status, ARRAY_LEN(cli_status));
01747
01748 if (cdr_registered)
01749 ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
01750
01751 ast_config_engine_deregister(&sqlite_engine);
01752
01753 if (db)
01754 sqlite_close(db);
01755
01756 unload_config();
01757
01758 return 0;
01759 }
01760
01761 static int load_module(void)
01762 {
01763 char *errormsg = NULL;
01764 int error;
01765
01766 db = NULL;
01767 cdr_registered = 0;
01768 cli_status_registered = 0;
01769 dbfile = NULL;
01770 config_table = NULL;
01771 cdr_table = NULL;
01772 error = load_config();
01773
01774 if (error)
01775 return AST_MODULE_LOAD_DECLINE;
01776
01777 if (!(db = sqlite_open(dbfile, 0660, &errormsg))) {
01778 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01779 sqlite_freemem(errormsg);
01780 unload_module();
01781 return 1;
01782 }
01783
01784 sqlite_freemem(errormsg);
01785 errormsg = NULL;
01786 ast_config_engine_register(&sqlite_engine);
01787
01788 if (use_cdr) {
01789 char *query;
01790
01791
01792 #undef QUERY
01793 #define QUERY "SELECT COUNT(id) FROM %Q;"
01794
01795
01796 query = sqlite_mprintf(QUERY, cdr_table);
01797
01798 if (!query) {
01799 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01800 unload_module();
01801 return 1;
01802 }
01803
01804 ast_debug(1, "SQL query: %s\n", query);
01805
01806 RES_CONFIG_SQLITE_BEGIN
01807 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01808 RES_CONFIG_SQLITE_END(error)
01809
01810 sqlite_freemem(query);
01811
01812 if (error) {
01813
01814
01815
01816 if (error != SQLITE_ERROR) {
01817 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01818 sqlite_freemem(errormsg);
01819 unload_module();
01820 return 1;
01821 }
01822
01823 sqlite_freemem(errormsg);
01824 errormsg = NULL;
01825 query = sqlite_mprintf(sql_create_cdr_table, cdr_table);
01826
01827 if (!query) {
01828 ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
01829 unload_module();
01830 return 1;
01831 }
01832
01833 ast_debug(1, "SQL query: %s\n", query);
01834
01835 RES_CONFIG_SQLITE_BEGIN
01836 error = sqlite_exec(db, query, NULL, NULL, &errormsg);
01837 RES_CONFIG_SQLITE_END(error)
01838
01839 sqlite_freemem(query);
01840
01841 if (error) {
01842 ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
01843 sqlite_freemem(errormsg);
01844 unload_module();
01845 return 1;
01846 }
01847 }
01848 sqlite_freemem(errormsg);
01849 errormsg = NULL;
01850
01851 error = ast_cdr_register(RES_CONFIG_SQLITE_NAME, RES_CONFIG_SQLITE_DESCRIPTION, cdr_handler);
01852
01853 if (error) {
01854 unload_module();
01855 return 1;
01856 }
01857
01858 cdr_registered = 1;
01859 }
01860
01861 error = ast_cli_register_multiple(cli_status, ARRAY_LEN(cli_status));
01862
01863 if (error) {
01864 unload_module();
01865 return 1;
01866 }
01867
01868 cli_status_registered = 1;
01869
01870 return 0;
01871 }
01872
01873 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Realtime SQLite configuration",
01874 .load = load_module,
01875 .unload = unload_module,
01876 .load_pri = AST_MODPRI_REALTIME_DRIVER,
01877 );