We have faced situation when using CDR and CEL by sqlite3 modules. With system having...
[asterisk/asterisk.git] / main / db.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief ASTdb Management
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \note DB3 is licensed under Sleepycat Public License and is thus incompatible
26  * with GPL.  To avoid having to make another exception (and complicate
27  * licensing even further) we elect to use DB1 which is BSD licensed
28  */
29
30 /*** MODULEINFO
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
37
38 #include "asterisk/_private.h"
39 #include "asterisk/paths.h"     /* use ast_config_AST_DB */
40 #include <sys/time.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #include <signal.h>
45 #include <dirent.h>
46 #include <sqlite3.h>
47
48 #include "asterisk/channel.h"
49 #include "asterisk/file.h"
50 #include "asterisk/app.h"
51 #include "asterisk/dsp.h"
52 #include "asterisk/astdb.h"
53 #include "asterisk/cli.h"
54 #include "asterisk/utils.h"
55 #include "asterisk/manager.h"
56
57 /*** DOCUMENTATION
58         <manager name="DBGet" language="en_US">
59                 <synopsis>
60                         Get DB Entry.
61                 </synopsis>
62                 <syntax>
63                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
64                         <parameter name="Family" required="true" />
65                         <parameter name="Key" required="true" />
66                 </syntax>
67                 <description>
68                 </description>
69         </manager>
70         <manager name="DBPut" language="en_US">
71                 <synopsis>
72                         Put DB entry.
73                 </synopsis>
74                 <syntax>
75                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
76                         <parameter name="Family" required="true" />
77                         <parameter name="Key" required="true" />
78                         <parameter name="Val" />
79                 </syntax>
80                 <description>
81                 </description>
82         </manager>
83         <manager name="DBDel" language="en_US">
84                 <synopsis>
85                         Delete DB entry.
86                 </synopsis>
87                 <syntax>
88                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
89                         <parameter name="Family" required="true" />
90                         <parameter name="Key" required="true" />
91                 </syntax>
92                 <description>
93                 </description>
94         </manager>
95         <manager name="DBDelTree" language="en_US">
96                 <synopsis>
97                         Delete DB Tree.
98                 </synopsis>
99                 <syntax>
100                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
101                         <parameter name="Family" required="true" />
102                         <parameter name="Key" />
103                 </syntax>
104                 <description>
105                 </description>
106         </manager>
107  ***/
108
109 #define MAX_DB_FIELD 256
110 AST_MUTEX_DEFINE_STATIC(dblock);
111 static ast_cond_t dbcond;
112 static sqlite3 *astdb;
113 static pthread_t syncthread;
114 static int doexit;
115 static int dosync;
116
117 static void db_sync(void);
118
119 #define DEFINE_SQL_STATEMENT(stmt,sql) static sqlite3_stmt *stmt; \
120         const char stmt##_sql[] = sql;
121
122 DEFINE_SQL_STATEMENT(put_stmt, "INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)")
123 DEFINE_SQL_STATEMENT(get_stmt, "SELECT value FROM astdb WHERE key=?")
124 DEFINE_SQL_STATEMENT(del_stmt, "DELETE FROM astdb WHERE key=?")
125 DEFINE_SQL_STATEMENT(deltree_stmt, "DELETE FROM astdb WHERE key || '/' LIKE ? || '/' || '%'")
126 DEFINE_SQL_STATEMENT(deltree_all_stmt, "DELETE FROM astdb")
127 DEFINE_SQL_STATEMENT(gettree_stmt, "SELECT key, value FROM astdb WHERE key || '/' LIKE ? || '/' || '%' ORDER BY key")
128 DEFINE_SQL_STATEMENT(gettree_all_stmt, "SELECT key, value FROM astdb ORDER BY key")
129 DEFINE_SQL_STATEMENT(showkey_stmt, "SELECT key, value FROM astdb WHERE key LIKE '%' || '/' || ? ORDER BY key")
130 DEFINE_SQL_STATEMENT(create_astdb_stmt, "CREATE TABLE IF NOT EXISTS astdb(key VARCHAR(256), value VARCHAR(256), PRIMARY KEY(key))")
131
132 static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
133 {
134         ast_mutex_lock(&dblock);
135         if (sqlite3_prepare(astdb, sql, len, stmt, NULL) != SQLITE_OK) {
136                 ast_log(LOG_WARNING, "Couldn't prepare statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
137                 ast_mutex_unlock(&dblock);
138                 return -1;
139         }
140         ast_mutex_unlock(&dblock);
141
142         return 0;
143 }
144
145 /*! \internal
146  * \brief Clean up the prepared SQLite3 statement
147  * \note dblock should already be locked prior to calling this method
148  */
149 static int clean_stmt(sqlite3_stmt **stmt, const char *sql)
150 {
151         if (sqlite3_finalize(*stmt) != SQLITE_OK) {
152                 ast_log(LOG_WARNING, "Couldn't finalize statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
153                 *stmt = NULL;
154                 return -1;
155         }
156         *stmt = NULL;
157         return 0;
158 }
159
160 /*! \internal
161  * \brief Clean up all prepared SQLite3 statements
162  * \note dblock should already be locked prior to calling this method
163  */
164 static void clean_statements(void)
165 {
166         clean_stmt(&get_stmt, get_stmt_sql);
167         clean_stmt(&del_stmt, del_stmt_sql);
168         clean_stmt(&deltree_stmt, deltree_stmt_sql);
169         clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql);
170         clean_stmt(&gettree_stmt, gettree_stmt_sql);
171         clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql);
172         clean_stmt(&showkey_stmt, showkey_stmt_sql);
173         clean_stmt(&put_stmt, put_stmt_sql);
174         clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql);
175 }
176
177 static int init_statements(void)
178 {
179         /* Don't initialize create_astdb_statment here as the astdb table needs to exist
180          * brefore these statments can be initialized */
181         return init_stmt(&get_stmt, get_stmt_sql, sizeof(get_stmt_sql))
182         || init_stmt(&del_stmt, del_stmt_sql, sizeof(del_stmt_sql))
183         || init_stmt(&deltree_stmt, deltree_stmt_sql, sizeof(deltree_stmt_sql))
184         || init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql))
185         || init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql))
186         || init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql))
187         || init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql))
188         || init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
189 }
190
191 static int convert_bdb_to_sqlite3(void)
192 {
193         char *cmd;
194         int res;
195
196         ast_asprintf(&cmd, "%s/astdb2sqlite3 '%s'\n", ast_config_AST_SBIN_DIR, ast_config_AST_DB);
197         res = ast_safe_system(cmd);
198         ast_free(cmd);
199
200         return res;
201 }
202
203 static int db_create_astdb(void)
204 {
205         int res = 0;
206
207         if (!create_astdb_stmt) {
208                 init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql));
209         }
210
211         ast_mutex_lock(&dblock);
212         if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
213                 ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
214                 res = -1;
215         }
216         sqlite3_reset(create_astdb_stmt);
217         db_sync();
218         ast_mutex_unlock(&dblock);
219
220         return res;
221 }
222
223 static int db_open(void)
224 {
225         char *dbname;
226         struct stat dont_care;
227
228         if (!(dbname = ast_alloca(strlen(ast_config_AST_DB) + sizeof(".sqlite3")))) {
229                 return -1;
230         }
231         strcpy(dbname, ast_config_AST_DB);
232         strcat(dbname, ".sqlite3");
233
234         if (stat(dbname, &dont_care) && !stat(ast_config_AST_DB, &dont_care)) {
235                 if (convert_bdb_to_sqlite3()) {
236                         ast_log(LOG_ERROR, "*** Database conversion failed!\n");
237                         ast_log(LOG_ERROR, "*** Asterisk now uses SQLite3 for its internal\n");
238                         ast_log(LOG_ERROR, "*** database. Conversion from the old astdb\n");
239                         ast_log(LOG_ERROR, "*** failed. Most likely the astdb2sqlite3 utility\n");
240                         ast_log(LOG_ERROR, "*** was not selected for build. To convert the\n");
241                         ast_log(LOG_ERROR, "*** old astdb, please delete '%s'\n", dbname);
242                         ast_log(LOG_ERROR, "*** and re-run 'make menuselect' and select astdb2sqlite3\n");
243                         ast_log(LOG_ERROR, "*** in the Utilities section, then 'make && make install'.\n");
244                         ast_log(LOG_ERROR, "*** It is also imperative that the user under which\n");
245                         ast_log(LOG_ERROR, "*** Asterisk runs have write permission to the directory\n");
246                         ast_log(LOG_ERROR, "*** where the database resides.\n");
247                         sleep(5);
248                 } else {
249                         ast_log(LOG_NOTICE, "Database conversion succeeded!\n");
250                 }
251         }
252
253         ast_mutex_lock(&dblock);
254         if (sqlite3_open(dbname, &astdb) != SQLITE_OK) {
255                 ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", dbname, sqlite3_errmsg(astdb));
256                 sqlite3_close(astdb);
257                 ast_mutex_unlock(&dblock);
258                 return -1;
259         }
260
261         ast_mutex_unlock(&dblock);
262
263         return 0;
264 }
265
266 static int db_init(void)
267 {
268         if (astdb) {
269                 return 0;
270         }
271
272         if (db_open() || db_create_astdb() || init_statements()) {
273                 return -1;
274         }
275
276         return 0;
277 }
278
279 /* We purposely don't lock around the sqlite3 call because the transaction
280  * calls will be called with the database lock held. For any other use, make
281  * sure to take the dblock yourself. */
282 static int db_execute_sql(const char *sql, int (*callback)(void *, int, char **, char **), void *arg)
283 {
284         char *errmsg = NULL;
285         int res =0;
286
287         if (sqlite3_exec(astdb, sql, callback, arg, &errmsg) != SQLITE_OK) {
288                 ast_log(LOG_WARNING, "Error executing SQL (%s): %s\n", sql, errmsg);
289                 sqlite3_free(errmsg);
290                 res = -1;
291         }
292
293         return res;
294 }
295
296 static int ast_db_begin_transaction(void)
297 {
298         return db_execute_sql("BEGIN TRANSACTION", NULL, NULL);
299 }
300
301 static int ast_db_commit_transaction(void)
302 {
303         return db_execute_sql("COMMIT", NULL, NULL);
304 }
305
306 static int ast_db_rollback_transaction(void)
307 {
308         return db_execute_sql("ROLLBACK", NULL, NULL);
309 }
310
311 int ast_db_put(const char *family, const char *key, const char *value)
312 {
313         char fullkey[MAX_DB_FIELD];
314         size_t fullkey_len;
315         int res = 0;
316
317         if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
318                 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
319                 return -1;
320         }
321
322         fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
323
324         ast_mutex_lock(&dblock);
325         if (sqlite3_bind_text(put_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
326                 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
327                 res = -1;
328         } else if (sqlite3_bind_text(put_stmt, 2, value, -1, SQLITE_STATIC) != SQLITE_OK) {
329                 ast_log(LOG_WARNING, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
330                 res = -1;
331         } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
332                 ast_log(LOG_WARNING, "Couldn't execute statment: %s\n", sqlite3_errmsg(astdb));
333                 res = -1;
334         }
335
336         sqlite3_reset(put_stmt);
337         db_sync();
338         ast_mutex_unlock(&dblock);
339
340         return res;
341 }
342
343 /*!
344  * \internal
345  * \brief Get key value specified by family/key.
346  *
347  * Gets the value associated with the specified \a family and \a key, and
348  * stores it, either into the fixed sized buffer specified by \a buffer
349  * and \a bufferlen, or as a heap allocated string if \a bufferlen is -1.
350  *
351  * \note If \a bufferlen is -1, \a buffer points to heap allocated memory
352  *       and must be freed by calling ast_free().
353  *
354  * \retval -1 An error occurred
355  * \retval 0 Success
356  */
357 static int db_get_common(const char *family, const char *key, char **buffer, int bufferlen)
358 {
359         const unsigned char *result;
360         char fullkey[MAX_DB_FIELD];
361         size_t fullkey_len;
362         int res = 0;
363
364         if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
365                 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
366                 return -1;
367         }
368
369         fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
370
371         ast_mutex_lock(&dblock);
372         if (sqlite3_bind_text(get_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
373                 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
374                 res = -1;
375         } else if (sqlite3_step(get_stmt) != SQLITE_ROW) {
376                 ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
377                 res = -1;
378         } else if (!(result = sqlite3_column_text(get_stmt, 0))) {
379                 ast_log(LOG_WARNING, "Couldn't get value\n");
380                 res = -1;
381         } else {
382                 const char *value = (const char *) result;
383
384                 if (bufferlen == -1) {
385                         *buffer = ast_strdup(value);
386                 } else {
387                         ast_copy_string(*buffer, value, bufferlen);
388                 }
389         }
390         sqlite3_reset(get_stmt);
391         ast_mutex_unlock(&dblock);
392
393         return res;
394 }
395
396 int ast_db_get(const char *family, const char *key, char *value, int valuelen)
397 {
398         ast_assert(value != NULL);
399
400         /* Make sure we initialize */
401         value[0] = 0;
402
403         return db_get_common(family, key, &value, valuelen);
404 }
405
406 int ast_db_get_allocated(const char *family, const char *key, char **out)
407 {
408         *out = NULL;
409
410         return db_get_common(family, key, out, -1);
411 }
412
413 int ast_db_del(const char *family, const char *key)
414 {
415         char fullkey[MAX_DB_FIELD];
416         size_t fullkey_len;
417         int res = 0;
418
419         if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
420                 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
421                 return -1;
422         }
423
424         fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
425
426         ast_mutex_lock(&dblock);
427         if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
428                 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
429                 res = -1;
430         } else if (sqlite3_step(del_stmt) != SQLITE_DONE) {
431                 ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
432                 res = -1;
433         }
434         sqlite3_reset(del_stmt);
435         db_sync();
436         ast_mutex_unlock(&dblock);
437
438         return res;
439 }
440
441 int ast_db_deltree(const char *family, const char *keytree)
442 {
443         sqlite3_stmt *stmt = deltree_stmt;
444         char prefix[MAX_DB_FIELD];
445         int res = 0;
446
447         if (!ast_strlen_zero(family)) {
448                 if (!ast_strlen_zero(keytree)) {
449                         /* Family and key tree */
450                         snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
451                 } else {
452                         /* Family only */
453                         snprintf(prefix, sizeof(prefix), "/%s", family);
454                 }
455         } else {
456                 prefix[0] = '\0';
457                 stmt = deltree_all_stmt;
458         }
459
460         ast_mutex_lock(&dblock);
461         if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
462                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
463                 res = -1;
464         } else if (sqlite3_step(stmt) != SQLITE_DONE) {
465                 ast_log(LOG_WARNING, "Couldn't execute stmt: %s\n", sqlite3_errmsg(astdb));
466                 res = -1;
467         }
468         res = sqlite3_changes(astdb);
469         sqlite3_reset(stmt);
470         db_sync();
471         ast_mutex_unlock(&dblock);
472
473         return res;
474 }
475
476 struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
477 {
478         char prefix[MAX_DB_FIELD];
479         sqlite3_stmt *stmt = gettree_stmt;
480         struct ast_db_entry *cur, *last = NULL, *ret = NULL;
481
482         if (!ast_strlen_zero(family)) {
483                 if (!ast_strlen_zero(keytree)) {
484                         /* Family and key tree */
485                         snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
486                 } else {
487                         /* Family only */
488                         snprintf(prefix, sizeof(prefix), "/%s", family);
489                 }
490         } else {
491                 prefix[0] = '\0';
492                 stmt = gettree_all_stmt;
493         }
494
495         ast_mutex_lock(&dblock);
496         if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
497                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
498                 sqlite3_reset(stmt);
499                 ast_mutex_unlock(&dblock);
500                 return NULL;
501         }
502
503         while (sqlite3_step(stmt) == SQLITE_ROW) {
504                 const char *key_s, *value_s;
505                 if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
506                         break;
507                 }
508                 if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
509                         break;
510                 }
511                 if (!(cur = ast_malloc(sizeof(*cur) + strlen(key_s) + strlen(value_s) + 2))) {
512                         break;
513                 }
514                 cur->next = NULL;
515                 cur->key = cur->data + strlen(value_s) + 1;
516                 strcpy(cur->data, value_s);
517                 strcpy(cur->key, key_s);
518                 if (last) {
519                         last->next = cur;
520                 } else {
521                         ret = cur;
522                 }
523                 last = cur;
524         }
525         sqlite3_reset(stmt);
526         ast_mutex_unlock(&dblock);
527
528         return ret;
529 }
530
531 void ast_db_freetree(struct ast_db_entry *dbe)
532 {
533         struct ast_db_entry *last;
534         while (dbe) {
535                 last = dbe;
536                 dbe = dbe->next;
537                 ast_free(last);
538         }
539 }
540
541 static char *handle_cli_database_put(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
542 {
543         int res;
544
545         switch (cmd) {
546         case CLI_INIT:
547                 e->command = "database put";
548                 e->usage =
549                         "Usage: database put <family> <key> <value>\n"
550                         "       Adds or updates an entry in the Asterisk database for\n"
551                         "       a given family, key, and value.\n";
552                 return NULL;
553         case CLI_GENERATE:
554                 return NULL;
555         }
556
557         if (a->argc != 5)
558                 return CLI_SHOWUSAGE;
559         res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]);
560         if (res)  {
561                 ast_cli(a->fd, "Failed to update entry\n");
562         } else {
563                 ast_cli(a->fd, "Updated database successfully\n");
564         }
565         return CLI_SUCCESS;
566 }
567
568 static char *handle_cli_database_get(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
569 {
570         int res;
571         char tmp[MAX_DB_FIELD];
572
573         switch (cmd) {
574         case CLI_INIT:
575                 e->command = "database get";
576                 e->usage =
577                         "Usage: database get <family> <key>\n"
578                         "       Retrieves an entry in the Asterisk database for a given\n"
579                         "       family and key.\n";
580                 return NULL;
581         case CLI_GENERATE:
582                 return NULL;
583         }
584
585         if (a->argc != 4)
586                 return CLI_SHOWUSAGE;
587         res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp));
588         if (res) {
589                 ast_cli(a->fd, "Database entry not found.\n");
590         } else {
591                 ast_cli(a->fd, "Value: %s\n", tmp);
592         }
593         return CLI_SUCCESS;
594 }
595
596 static char *handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
597 {
598         int res;
599
600         switch (cmd) {
601         case CLI_INIT:
602                 e->command = "database del";
603                 e->usage =
604                         "Usage: database del <family> <key>\n"
605                         "       Deletes an entry in the Asterisk database for a given\n"
606                         "       family and key.\n";
607                 return NULL;
608         case CLI_GENERATE:
609                 return NULL;
610         }
611
612         if (a->argc != 4)
613                 return CLI_SHOWUSAGE;
614         res = ast_db_del(a->argv[2], a->argv[3]);
615         if (res) {
616                 ast_cli(a->fd, "Database entry does not exist.\n");
617         } else {
618                 ast_cli(a->fd, "Database entry removed.\n");
619         }
620         return CLI_SUCCESS;
621 }
622
623 static char *handle_cli_database_deltree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
624 {
625         int num_deleted;
626
627         switch (cmd) {
628         case CLI_INIT:
629                 e->command = "database deltree";
630                 e->usage =
631                         "Usage: database deltree <family> [keytree]\n"
632                         "   OR: database deltree <family>[/keytree]\n"
633                         "       Deletes a family or specific keytree within a family\n"
634                         "       in the Asterisk database.  The two arguments may be\n"
635                         "       separated by either a space or a slash.\n";
636                 return NULL;
637         case CLI_GENERATE:
638                 return NULL;
639         }
640
641         if ((a->argc < 3) || (a->argc > 4))
642                 return CLI_SHOWUSAGE;
643         if (a->argc == 4) {
644                 num_deleted = ast_db_deltree(a->argv[2], a->argv[3]);
645         } else {
646                 num_deleted = ast_db_deltree(a->argv[2], NULL);
647         }
648         if (num_deleted < 0) {
649                 ast_cli(a->fd, "Database unavailable.\n");
650         } else if (num_deleted == 0) {
651                 ast_cli(a->fd, "Database entries do not exist.\n");
652         } else {
653                 ast_cli(a->fd, "%d database entries removed.\n",num_deleted);
654         }
655         return CLI_SUCCESS;
656 }
657
658 static char *handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
659 {
660         char prefix[MAX_DB_FIELD];
661         int counter = 0;
662         sqlite3_stmt *stmt = gettree_stmt;
663
664         switch (cmd) {
665         case CLI_INIT:
666                 e->command = "database show";
667                 e->usage =
668                         "Usage: database show [family [keytree]]\n"
669                         "   OR: database show [family[/keytree]]\n"
670                         "       Shows Asterisk database contents, optionally restricted\n"
671                         "       to a given family, or family and keytree. The two arguments\n"
672                         "       may be separated either by a space or by a slash.\n";
673                 return NULL;
674         case CLI_GENERATE:
675                 return NULL;
676         }
677
678         if (a->argc == 4) {
679                 /* Family and key tree */
680                 snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
681         } else if (a->argc == 3) {
682                 /* Family only */
683                 snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
684         } else if (a->argc == 2) {
685                 /* Neither */
686                 prefix[0] = '\0';
687                 stmt = gettree_all_stmt;
688
689         } else {
690                 return CLI_SHOWUSAGE;
691         }
692
693         ast_mutex_lock(&dblock);
694         if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
695                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
696                 sqlite3_reset(stmt);
697                 ast_mutex_unlock(&dblock);
698                 return NULL;
699         }
700
701         while (sqlite3_step(stmt) == SQLITE_ROW) {
702                 const char *key_s, *value_s;
703                 if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
704                         ast_log(LOG_WARNING, "Skipping invalid key!\n");
705                         continue;
706                 }
707                 if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
708                         ast_log(LOG_WARNING, "Skipping invalid value!\n");
709                         continue;
710                 }
711                 ++counter;
712                 ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
713         }
714
715         sqlite3_reset(stmt);
716         ast_mutex_unlock(&dblock);
717
718         ast_cli(a->fd, "%d results found.\n", counter);
719         return CLI_SUCCESS;
720 }
721
722 static char *handle_cli_database_showkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
723 {
724         int counter = 0;
725
726         switch (cmd) {
727         case CLI_INIT:
728                 e->command = "database showkey";
729                 e->usage =
730                         "Usage: database showkey <keytree>\n"
731                         "       Shows Asterisk database contents, restricted to a given key.\n";
732                 return NULL;
733         case CLI_GENERATE:
734                 return NULL;
735         }
736
737         if (a->argc != 3) {
738                 return CLI_SHOWUSAGE;
739         }
740
741         ast_mutex_lock(&dblock);
742         if (!ast_strlen_zero(a->argv[2]) && (sqlite3_bind_text(showkey_stmt, 1, a->argv[2], -1, SQLITE_STATIC) != SQLITE_OK)) {
743                 ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", a->argv[2], sqlite3_errmsg(astdb));
744                 sqlite3_reset(showkey_stmt);
745                 ast_mutex_unlock(&dblock);
746                 return NULL;
747         }
748
749         while (sqlite3_step(showkey_stmt) == SQLITE_ROW) {
750                 const char *key_s, *value_s;
751                 if (!(key_s = (const char *) sqlite3_column_text(showkey_stmt, 0))) {
752                         break;
753                 }
754                 if (!(value_s = (const char *) sqlite3_column_text(showkey_stmt, 1))) {
755                         break;
756                 }
757                 ++counter;
758                 ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
759         }
760         sqlite3_reset(showkey_stmt);
761         ast_mutex_unlock(&dblock);
762
763         ast_cli(a->fd, "%d results found.\n", counter);
764         return CLI_SUCCESS;
765 }
766
767 static int display_results(void *arg, int columns, char **values, char **colnames)
768 {
769         struct ast_cli_args *a = arg;
770         size_t x;
771
772         for (x = 0; x < columns; x++) {
773                 ast_cli(a->fd, "%-5s: %-50s\n", colnames[x], values[x]);
774         }
775         ast_cli(a->fd, "\n");
776
777         return 0;
778 }
779
780 static char *handle_cli_database_query(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
781 {
782
783         switch (cmd) {
784         case CLI_INIT:
785                 e->command = "database query";
786                 e->usage =
787                         "Usage: database query \"<SQL Statement>\"\n"
788                         "       Run a user-specified SQL query on the database. Be careful.\n";
789                 return NULL;
790         case CLI_GENERATE:
791                 return NULL;
792         }
793
794         if (a->argc != 3) {
795                 return CLI_SHOWUSAGE;
796         }
797
798         ast_mutex_lock(&dblock);
799         db_execute_sql(a->argv[2], display_results, a);
800         db_sync(); /* Go ahead and sync the db in case they write */
801         ast_mutex_unlock(&dblock);
802
803         return CLI_SUCCESS;
804 }
805
806 static struct ast_cli_entry cli_database[] = {
807         AST_CLI_DEFINE(handle_cli_database_show,    "Shows database contents"),
808         AST_CLI_DEFINE(handle_cli_database_showkey, "Shows database contents"),
809         AST_CLI_DEFINE(handle_cli_database_get,     "Gets database value"),
810         AST_CLI_DEFINE(handle_cli_database_put,     "Adds/updates database value"),
811         AST_CLI_DEFINE(handle_cli_database_del,     "Removes database key/value"),
812         AST_CLI_DEFINE(handle_cli_database_deltree, "Removes database keytree/values"),
813         AST_CLI_DEFINE(handle_cli_database_query,   "Run a user-specified query on the astdb"),
814 };
815
816 static int manager_dbput(struct mansession *s, const struct message *m)
817 {
818         const char *family = astman_get_header(m, "Family");
819         const char *key = astman_get_header(m, "Key");
820         const char *val = astman_get_header(m, "Val");
821         int res;
822
823         if (ast_strlen_zero(family)) {
824                 astman_send_error(s, m, "No family specified");
825                 return 0;
826         }
827         if (ast_strlen_zero(key)) {
828                 astman_send_error(s, m, "No key specified");
829                 return 0;
830         }
831
832         res = ast_db_put(family, key, S_OR(val, ""));
833         if (res) {
834                 astman_send_error(s, m, "Failed to update entry");
835         } else {
836                 astman_send_ack(s, m, "Updated database successfully");
837         }
838         return 0;
839 }
840
841 static int manager_dbget(struct mansession *s, const struct message *m)
842 {
843         const char *id = astman_get_header(m,"ActionID");
844         char idText[256] = "";
845         const char *family = astman_get_header(m, "Family");
846         const char *key = astman_get_header(m, "Key");
847         char tmp[MAX_DB_FIELD];
848         int res;
849
850         if (ast_strlen_zero(family)) {
851                 astman_send_error(s, m, "No family specified.");
852                 return 0;
853         }
854         if (ast_strlen_zero(key)) {
855                 astman_send_error(s, m, "No key specified.");
856                 return 0;
857         }
858
859         if (!ast_strlen_zero(id))
860                 snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
861
862         res = ast_db_get(family, key, tmp, sizeof(tmp));
863         if (res) {
864                 astman_send_error(s, m, "Database entry not found");
865         } else {
866                 astman_send_ack(s, m, "Result will follow");
867                 astman_append(s, "Event: DBGetResponse\r\n"
868                                 "Family: %s\r\n"
869                                 "Key: %s\r\n"
870                                 "Val: %s\r\n"
871                                 "%s"
872                                 "\r\n",
873                                 family, key, tmp, idText);
874                 astman_append(s, "Event: DBGetComplete\r\n"
875                                 "%s"
876                                 "\r\n",
877                                 idText);
878         }
879         return 0;
880 }
881
882 static int manager_dbdel(struct mansession *s, const struct message *m)
883 {
884         const char *family = astman_get_header(m, "Family");
885         const char *key = astman_get_header(m, "Key");
886         int res;
887
888         if (ast_strlen_zero(family)) {
889                 astman_send_error(s, m, "No family specified.");
890                 return 0;
891         }
892
893         if (ast_strlen_zero(key)) {
894                 astman_send_error(s, m, "No key specified.");
895                 return 0;
896         }
897
898         res = ast_db_del(family, key);
899         if (res)
900                 astman_send_error(s, m, "Database entry not found");
901         else
902                 astman_send_ack(s, m, "Key deleted successfully");
903
904         return 0;
905 }
906
907 static int manager_dbdeltree(struct mansession *s, const struct message *m)
908 {
909         const char *family = astman_get_header(m, "Family");
910         const char *key = astman_get_header(m, "Key");
911         int num_deleted;
912
913         if (ast_strlen_zero(family)) {
914                 astman_send_error(s, m, "No family specified.");
915                 return 0;
916         }
917
918         if (!ast_strlen_zero(key)) {
919                 num_deleted = ast_db_deltree(family, key);
920         } else {
921                 num_deleted = ast_db_deltree(family, NULL);
922         }
923
924         if (num_deleted < 0) {
925                 astman_send_error(s, m, "Database unavailable");
926         } else if (num_deleted == 0) {
927                 astman_send_error(s, m, "Database entry not found");
928         } else {
929                 astman_send_ack(s, m, "Key tree deleted successfully");
930         }
931
932         return 0;
933 }
934
935 /*!
936  * \internal
937  * \brief Signal the astdb sync thread to do its thing.
938  *
939  * \note dblock is assumed to be held when calling this function.
940  */
941 static void db_sync(void)
942 {
943         dosync = 1;
944         ast_cond_signal(&dbcond);
945 }
946
947 /*!
948  * \internal
949  * \brief astdb sync thread
950  *
951  * This thread is in charge of syncing astdb to disk after a change.
952  * By pushing it off to this thread to take care of, this I/O bound operation
953  * will not block other threads from performing other critical processing.
954  * If changes happen rapidly, this thread will also ensure that the sync
955  * operations are rate limited.
956  */
957 static void *db_sync_thread(void *data)
958 {
959         ast_mutex_lock(&dblock);
960         ast_db_begin_transaction();
961         for (;;) {
962                 /* If dosync is set, db_sync() was called during sleep(1), 
963                  * and the pending transaction should be committed. 
964                  * Otherwise, block until db_sync() is called.
965                  */
966                 while (!dosync) {
967                         ast_cond_wait(&dbcond, &dblock);
968                 }
969                 dosync = 0;
970                 if (ast_db_commit_transaction()) {
971                         ast_db_rollback_transaction();
972                 }
973                 if (doexit) {
974                         ast_mutex_unlock(&dblock);
975                         break;
976                 }
977                 ast_db_begin_transaction();
978                 ast_mutex_unlock(&dblock);
979                 sleep(1);
980                 ast_mutex_lock(&dblock);
981         }
982
983         return NULL;
984 }
985
986 /*!
987  * \internal
988  * \brief Clean up resources on Asterisk shutdown
989  */
990 static void astdb_atexit(void)
991 {
992         ast_cli_unregister_multiple(cli_database, ARRAY_LEN(cli_database));
993         ast_manager_unregister("DBGet");
994         ast_manager_unregister("DBPut");
995         ast_manager_unregister("DBDel");
996         ast_manager_unregister("DBDelTree");
997
998         /* Set doexit to 1 to kill thread. db_sync must be called with
999          * mutex held. */
1000         ast_mutex_lock(&dblock);
1001         doexit = 1;
1002         db_sync();
1003         ast_mutex_unlock(&dblock);
1004
1005         pthread_join(syncthread, NULL);
1006         ast_mutex_lock(&dblock);
1007         clean_statements();
1008         if (sqlite3_close(astdb) == SQLITE_OK) {
1009                 astdb = NULL;
1010         }
1011         ast_mutex_unlock(&dblock);
1012 }
1013
1014 int astdb_init(void)
1015 {
1016         if (db_init()) {
1017                 return -1;
1018         }
1019
1020         ast_cond_init(&dbcond, NULL);
1021         if (ast_pthread_create_background(&syncthread, NULL, db_sync_thread, NULL)) {
1022                 return -1;
1023         }
1024
1025         ast_register_atexit(astdb_atexit);
1026         ast_cli_register_multiple(cli_database, ARRAY_LEN(cli_database));
1027         ast_manager_register_xml_core("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget);
1028         ast_manager_register_xml_core("DBPut", EVENT_FLAG_SYSTEM, manager_dbput);
1029         ast_manager_register_xml_core("DBDel", EVENT_FLAG_SYSTEM, manager_dbdel);
1030         ast_manager_register_xml_core("DBDelTree", EVENT_FLAG_SYSTEM, manager_dbdeltree);
1031         return 0;
1032 }