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