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