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