Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Macros | Functions | Variables
main/db.c File Reference

ASTdb Management. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <sqlite3.h>
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
Include dependency graph for main/db.c:

Go to the source code of this file.

Macros

#define DEFINE_SQL_STATEMENT(stmt, sql)
 
#define MAX_DB_FIELD   256
 

Functions

static int ast_db_begin_transaction (void)
 
static int ast_db_commit_transaction (void)
 
int ast_db_del (const char *family, const char *key)
 Delete entry in astdb. More...
 
int ast_db_del2 (const char *family, const char *key)
 Same as ast_db_del, but with more stringent error checking. More...
 
int ast_db_deltree (const char *family, const char *keytree)
 Delete one or more entries in astdb. More...
 
int ast_db_exists (const char *family, const char *key)
 Check if family/key exitsts. More...
 
void ast_db_freetree (struct ast_db_entry *dbe)
 Free structure created by ast_db_gettree() More...
 
int ast_db_get (const char *family, const char *key, char *value, int valuelen)
 Get key value specified by family/key. More...
 
int ast_db_get_allocated (const char *family, const char *key, char **out)
 Get key value specified by family/key as a heap allocated string. More...
 
struct ast_db_entryast_db_gettree (const char *family, const char *keytree)
 Get a list of values within the astdb tree. More...
 
struct ast_db_entryast_db_gettree_by_prefix (const char *family, const char *key_prefix)
 Get a list of values with the given key prefix. More...
 
int ast_db_put (const char *family, const char *key, const char *value)
 Store value addressed by family/key. More...
 
static int ast_db_rollback_transaction (void)
 
static void astdb_atexit (void)
 
int astdb_init (void)
 
static void clean_statements (void)
 
static int clean_stmt (sqlite3_stmt **stmt, const char *sql)
 
static int convert_bdb_to_sqlite3 (void)
 
static int db_create_astdb (void)
 
static int db_execute_sql (const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
 
static int db_get_common (const char *family, const char *key, char **buffer, int bufferlen)
 
static struct ast_db_entrydb_gettree_common (sqlite3_stmt *stmt)
 
static int db_init (void)
 
static int db_open (void)
 
static void db_sync (void)
 
static void * db_sync_thread (void *data)
 
 DEFINE_SQL_STATEMENT (put_stmt, "INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)")
 
static int display_results (void *arg, int columns, char **values, char **colnames)
 
static char * handle_cli_database_del (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_deltree (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_get (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_put (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_query (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_database_showkey (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int init_statements (void)
 
static int manager_db_tree_get (struct mansession *s, const struct message *m)
 
static int manager_dbdel (struct mansession *s, const struct message *m)
 
static int manager_dbdeltree (struct mansession *s, const struct message *m)
 
static int manager_dbget (struct mansession *s, const struct message *m)
 
static int manager_dbput (struct mansession *s, const struct message *m)
 

Variables

static sqlite3 * astdb
 
static struct ast_cli_entry cli_database []
 
static ast_cond_t dbcond
 
static ast_mutex_t dblock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static int doexit
 
static int dosync
 
static pthread_t syncthread
 

Detailed Description

ASTdb Management.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
DB3 is licensed under Sleepycat Public License and is thus incompatible with GPL. To avoid having to make another exception (and complicate licensing even further) we elect to use DB1 which is BSD licensed

Definition in file main/db.c.

Macro Definition Documentation

◆ DEFINE_SQL_STATEMENT

#define DEFINE_SQL_STATEMENT (   stmt,
  sql 
)
Value:
static sqlite3_stmt *stmt; \
const char stmt##_sql[] = sql;

Definition at line 129 of file main/db.c.

◆ MAX_DB_FIELD

#define MAX_DB_FIELD   256

Definition at line 119 of file main/db.c.

Function Documentation

◆ ast_db_begin_transaction()

static int ast_db_begin_transaction ( void  )
static

Definition at line 327 of file main/db.c.

328{
329 return db_execute_sql("BEGIN TRANSACTION", NULL, NULL);
330}
static int db_execute_sql(const char *sql, int(*callback)(void *, int, char **, char **), void *arg)
Definition: main/db.c:313
#define NULL
Definition: resample.c:96

References db_execute_sql(), and NULL.

Referenced by db_sync_thread().

◆ ast_db_commit_transaction()

static int ast_db_commit_transaction ( void  )
static

Definition at line 332 of file main/db.c.

333{
334 return db_execute_sql("COMMIT", NULL, NULL);
335}

References db_execute_sql(), and NULL.

Referenced by db_sync_thread().

◆ ast_db_del()

int ast_db_del ( const char *  family,
const char *  key 
)

Delete entry in astdb.

Definition at line 476 of file main/db.c.

477{
478 char fullkey[MAX_DB_FIELD];
479 size_t fullkey_len;
480 int res = 0;
481
482 if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
483 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
484 return -1;
485 }
486
487 fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
488
490 if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
491 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
492 res = -1;
493 } else if (sqlite3_step(del_stmt) != SQLITE_DONE) {
494 ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
495 res = -1;
496 }
497 sqlite3_reset(del_stmt);
498 db_sync();
500
501 return res;
502}
#define ast_log
Definition: astobj2.c:42
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
static void db_sync(void)
Definition: main/db.c:1154
static sqlite3 * astdb
Definition: main/db.c:122
static ast_mutex_t dblock
Definition: main/db.c:120
#define MAX_DB_FIELD
Definition: main/db.c:119

References ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_sync(), dblock, LOG_WARNING, and MAX_DB_FIELD.

Referenced by __expire_registry(), add_cert_key_to_astdb(), ast_privacy_set(), AST_TEST_DEFINE(), auth_exec(), cache_lookup_internal(), cleanup_cert_from_astdb_and_fs(), destroy_all_channels(), dialgroup_refreshdb(), do_register_expire(), dump_queue_members(), function_db_delete(), handle_dbdel(), media_cache_item_del_from_astdb(), media_cache_remove_from_astdb(), mkintf(), process_clearcache(), reload_queue_members(), sorcery_astdb_delete(), stasis_app_device_state_delete(), and update_registry().

◆ ast_db_del2()

int ast_db_del2 ( const char *  family,
const char *  key 
)

Same as ast_db_del, but with more stringent error checking.

Unlike ast_db_del, if the key does not exist in the first place, an error is emitted and -1 is returned.

Return values
-1An error occured (including key not found to begin with)
0Successfully deleted

Definition at line 504 of file main/db.c.

505{
506 char fullkey[MAX_DB_FIELD];
507 char tmp[1];
508 size_t fullkey_len;
509 int mres, res = 0;
510
511 if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
512 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
513 return -1;
514 }
515
516 fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
517
519 if (ast_db_get(family, key, tmp, sizeof(tmp))) {
520 ast_log(LOG_WARNING, "AstDB key %s does not exist\n", fullkey);
521 res = -1;
522 } else if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
523 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
524 res = -1;
525 } else if ((mres = sqlite3_step(del_stmt) != SQLITE_DONE)) {
526 ast_log(LOG_WARNING, "AstDB error (%s): %s\n", fullkey, sqlite3_errstr(mres));
527 res = -1;
528 }
529 sqlite3_reset(del_stmt);
530 db_sync();
532
533 return res;
534}
static int tmp()
Definition: bt_open.c:389
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:427

References ast_db_get(), ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_sync(), dblock, LOG_WARNING, MAX_DB_FIELD, and tmp().

Referenced by handle_cli_database_del(), and manager_dbdel().

◆ ast_db_deltree()

int ast_db_deltree ( const char *  family,
const char *  keytree 
)

Delete one or more entries in astdb.

If both parameters are NULL, the entire database will be purged. If only keytree is NULL, all entries within the family will be purged. It is an error for keytree to have a value when family is NULL.

Return values
-1An error occurred
>=0 Number of records deleted

Definition at line 536 of file main/db.c.

537{
538 sqlite3_stmt *stmt = deltree_stmt;
539 char prefix[MAX_DB_FIELD];
540 int res = 0;
541
542 if (!ast_strlen_zero(family)) {
543 if (!ast_strlen_zero(keytree)) {
544 /* Family and key tree */
545 snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
546 } else {
547 /* Family only */
548 snprintf(prefix, sizeof(prefix), "/%s", family);
549 }
550 } else {
551 prefix[0] = '\0';
552 stmt = deltree_all_stmt;
553 }
554
556 if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
557 ast_log(LOG_WARNING, "Couldn't bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
558 res = -1;
559 } else if (sqlite3_step(stmt) != SQLITE_DONE) {
560 ast_log(LOG_WARNING, "Couldn't execute stmt: %s\n", sqlite3_errmsg(astdb));
561 res = -1;
562 }
563 res = sqlite3_changes(astdb);
564 sqlite3_reset(stmt);
565 db_sync();
567
568 return res;
569}
static char prefix[MAX_PREFIX]
Definition: http.c:144
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), astdb, db_sync(), dblock, LOG_WARNING, MAX_DB_FIELD, and prefix.

Referenced by ast_privacy_reset(), AST_TEST_DEFINE(), cleanup_cert_from_astdb_and_fs(), deinitialize_sorcery(), deltree_exec(), dundi_flush(), handle_cli_database_deltree(), handle_dbdeltree(), iax_provision_reload(), manager_dbdeltree(), media_cache_item_del_from_astdb(), and media_cache_remove_from_astdb().

◆ ast_db_exists()

int ast_db_exists ( const char *  family,
const char *  key 
)

Check if family/key exitsts.

Parameters
family
key
Return values
1if family/key exists
0if family/key does not exist or an error occurred

Definition at line 444 of file main/db.c.

445{
446 int result;
447 char fullkey[MAX_DB_FIELD];
448 size_t fullkey_len;
449 int res = 0;
450
451 fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
452 if (fullkey_len >= sizeof(fullkey)) {
453 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
454 return -1;
455 }
456
458 res = sqlite3_bind_text(exists_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC);
459 if (res != SQLITE_OK) {
460 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %d:%s\n", res, sqlite3_errmsg(astdb));
461 res = 0;
462 } else if (sqlite3_step(exists_stmt) != SQLITE_ROW) {
463 res = 0;
464 } else if (!(result = sqlite3_column_int(exists_stmt, 0))) {
465 res = 0;
466 } else {
467 res = result;
468 }
469 sqlite3_reset(exists_stmt);
471
472 return res;
473}
static PGresult * result
Definition: cel_pgsql.c:84

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, dblock, LOG_WARNING, MAX_DB_FIELD, and result.

Referenced by cleanup_cert_from_astdb_and_fs(), and retrieve_cert_from_cache().

◆ ast_db_freetree()

void ast_db_freetree ( struct ast_db_entry dbe)

◆ ast_db_get()

int ast_db_get ( const char *  family,
const char *  key,
char *  value,
int  valuelen 
)

◆ ast_db_get_allocated()

int ast_db_get_allocated ( const char *  family,
const char *  key,
char **  out 
)

Get key value specified by family/key as a heap allocated string.

Given a family and key, sets out to a pointer to a heap allocated string. In the event of an error, out will be set to NULL. The string must be freed by calling ast_free().

Return values
-1An error occurred
0Success

Definition at line 437 of file main/db.c.

438{
439 *out = NULL;
440
441 return db_get_common(family, key, out, -1);
442}
FILE * out
Definition: utils/frame.c:33

References db_get_common(), NULL, and out.

Referenced by AST_TEST_DEFINE(), media_cache_item_del_from_astdb(), reload_queue_members(), and sorcery_astdb_retrieve_id().

◆ ast_db_gettree()

struct ast_db_entry * ast_db_gettree ( const char *  family,
const char *  keytree 
)

Get a list of values within the astdb tree.

If family is specified, only those keys will be returned. If keytree is specified, subkeys are expected to exist (separated from the key with a slash). If subkeys do not exist and keytree is specified, the tree will consist of either a single entry or NULL will be returned.

Resulting tree should be freed by passing the return value to ast_db_freetree() when usage is concluded.

Definition at line 610 of file main/db.c.

611{
612 char prefix[MAX_DB_FIELD];
613 sqlite3_stmt *stmt = gettree_stmt;
614 size_t res = 0;
615 struct ast_db_entry *ret;
616
617 if (!ast_strlen_zero(family)) {
618 if (!ast_strlen_zero(keytree)) {
619 /* Family and key tree */
620 res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
621 } else {
622 /* Family only */
623 res = snprintf(prefix, sizeof(prefix), "/%s", family);
624 }
625
626 if (res >= sizeof(prefix)) {
627 ast_log(LOG_WARNING, "Requested prefix is too long: %s\n", keytree);
628 return NULL;
629 }
630 } else {
631 prefix[0] = '\0';
632 stmt = gettree_all_stmt;
633 }
634
636 if (res && (sqlite3_bind_text(stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK)) {
637 ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
638 sqlite3_reset(stmt);
640 return NULL;
641 }
642
643 ret = db_gettree_common(stmt);
644 sqlite3_reset(stmt);
646
647 return ret;
648}
static struct ast_db_entry * db_gettree_common(sqlite3_stmt *stmt)
Definition: main/db.c:571

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), astdb, db_gettree_common(), dblock, LOG_WARNING, MAX_DB_FIELD, NULL, and prefix.

Referenced by AST_TEST_DEFINE(), dundi_show_cache(), dundi_show_hints(), function_db_keycount(), function_db_keys(), handle_cli_devstate_list(), handle_cli_presencestate_list(), load_module(), media_cache_item_populate_from_astdb(), media_cache_populate_from_astdb(), populate_cache(), process_clearcache(), reload_queue_members(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_regex(), and stasis_app_device_states_to_json().

◆ ast_db_gettree_by_prefix()

struct ast_db_entry * ast_db_gettree_by_prefix ( const char *  family,
const char *  key_prefix 
)

Get a list of values with the given key prefix.

Parameters
familyThe family to search under
key_prefixThe key prefix to search under
Return values
NULLAn error occurred

Definition at line 650 of file main/db.c.

651{
652 char prefix[MAX_DB_FIELD];
653 size_t res;
654 struct ast_db_entry *ret;
655
656 res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, key_prefix);
657 if (res >= sizeof(prefix)) {
658 ast_log(LOG_WARNING, "Requested key prefix is too long: %s\n", key_prefix);
659 return NULL;
660 }
661
663 if (sqlite3_bind_text(gettree_prefix_stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK) {
664 ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
665 sqlite3_reset(gettree_prefix_stmt);
667 return NULL;
668 }
669
670 ret = db_gettree_common(gettree_prefix_stmt);
671 sqlite3_reset(gettree_prefix_stmt);
673
674 return ret;
675}

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_gettree_common(), dblock, LOG_WARNING, MAX_DB_FIELD, NULL, and prefix.

Referenced by sorcery_astdb_retrieve_prefix().

◆ ast_db_put()

int ast_db_put ( const char *  family,
const char *  key,
const char *  value 
)

Store value addressed by family/key.

Definition at line 342 of file main/db.c.

343{
344 char fullkey[MAX_DB_FIELD];
345 size_t fullkey_len;
346 int res = 0;
347
348 if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
349 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
350 return -1;
351 }
352
353 fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
354
356 if (sqlite3_bind_text(put_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
357 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
358 res = -1;
359 } else if (sqlite3_bind_text(put_stmt, 2, value, -1, SQLITE_STATIC) != SQLITE_OK) {
360 ast_log(LOG_WARNING, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
361 res = -1;
362 } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
363 ast_log(LOG_WARNING, "Couldn't execute statement: %s\n", sqlite3_errmsg(astdb));
364 res = -1;
365 }
366
367 sqlite3_reset(put_stmt);
368 db_sync();
370
371 return res;
372}

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_sync(), dblock, LOG_WARNING, MAX_DB_FIELD, and value.

Referenced by __analog_ss_thread(), add_cert_expiration_to_astdb(), add_cert_key_to_astdb(), ast_privacy_set(), AST_TEST_DEFINE(), asterisk_daemon(), cache_save(), cache_save_hint(), database_increment(), devstate_write(), dialgroup_refreshdb(), dump_queue_members(), function_db_write(), handle_cli_database_put(), handle_cli_devstate_change(), handle_cli_presencestate_change(), handle_command_response(), handle_dbput(), iax_provision_build(), manager_dbput(), media_cache_item_sync_to_astdb(), metadata_sync_to_astdb(), presence_write(), save_secret(), sorcery_astdb_create(), stasis_app_device_state_update(), and update_registry().

◆ ast_db_rollback_transaction()

static int ast_db_rollback_transaction ( void  )
static

Definition at line 337 of file main/db.c.

338{
339 return db_execute_sql("ROLLBACK", NULL, NULL);
340}

References db_execute_sql(), and NULL.

Referenced by db_sync_thread().

◆ astdb_atexit()

static void astdb_atexit ( void  )
static

Definition at line 1203 of file main/db.c.

1204{
1206 ast_manager_unregister("DBGet");
1207 ast_manager_unregister("DBGetTree");
1208 ast_manager_unregister("DBPut");
1209 ast_manager_unregister("DBDel");
1210 ast_manager_unregister("DBDelTree");
1211
1212 /* Set doexit to 1 to kill thread. db_sync must be called with
1213 * mutex held. */
1215 doexit = 1;
1216 db_sync();
1218
1219 pthread_join(syncthread, NULL);
1222 if (sqlite3_close(astdb) == SQLITE_OK) {
1223 astdb = NULL;
1224 }
1226}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8041
static int doexit
Definition: main/db.c:124
static void clean_statements(void)
Definition: main/db.c:189
static struct ast_cli_entry cli_database[]
Definition: main/db.c:952
static pthread_t syncthread
Definition: main/db.c:123
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, astdb, clean_statements(), cli_database, db_sync(), dblock, doexit, NULL, and syncthread.

Referenced by astdb_init().

◆ astdb_init()

int astdb_init ( void  )

Provided by db.c

Definition at line 1228 of file main/db.c.

1229{
1231
1232 if (db_init()) {
1233 return -1;
1234 }
1235
1237 return -1;
1238 }
1239
1247 return 0;
1248}
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: clicompat.c:13
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define ast_cond_init(cond, attr)
Definition: lock.h:201
static int manager_dbdel(struct mansession *s, const struct message *m)
Definition: main/db.c:1095
static int manager_db_tree_get(struct mansession *s, const struct message *m)
Definition: main/db.c:1029
static int manager_dbdeltree(struct mansession *s, const struct message *m)
Definition: main/db.c:1120
static int manager_dbget(struct mansession *s, const struct message *m)
Definition: main/db.c:987
static int db_init(void)
Definition: main/db.c:297
static int manager_dbput(struct mansession *s, const struct message *m)
Definition: main/db.c:962
static void * db_sync_thread(void *data)
Definition: main/db.c:1170
static ast_cond_t dbcond
Definition: main/db.c:121
static void astdb_atexit(void)
Definition: main/db.c:1203
#define EVENT_FLAG_REPORTING
Definition: manager.h:84
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:202
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:592

References ARRAY_LEN, ast_cli_register_multiple, ast_cond_init, ast_manager_register_xml_core, ast_pthread_create_background, ast_register_atexit(), astdb_atexit(), cli_database, db_init(), db_sync_thread(), dbcond, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, manager_db_tree_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), NULL, and syncthread.

Referenced by asterisk_daemon().

◆ clean_statements()

static void clean_statements ( void  )
static

Definition at line 189 of file main/db.c.

190{
191 clean_stmt(&get_stmt, get_stmt_sql);
192 clean_stmt(&exists_stmt, exists_stmt_sql);
193 clean_stmt(&del_stmt, del_stmt_sql);
194 clean_stmt(&deltree_stmt, deltree_stmt_sql);
195 clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql);
196 clean_stmt(&gettree_stmt, gettree_stmt_sql);
197 clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql);
198 clean_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql);
199 clean_stmt(&showkey_stmt, showkey_stmt_sql);
200 clean_stmt(&put_stmt, put_stmt_sql);
201 clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql);
202}
static int clean_stmt(sqlite3_stmt **stmt, const char *sql)
Definition: main/db.c:174

References clean_stmt().

Referenced by astdb_atexit().

◆ clean_stmt()

static int clean_stmt ( sqlite3_stmt **  stmt,
const char *  sql 
)
static

Definition at line 174 of file main/db.c.

175{
176 if (sqlite3_finalize(*stmt) != SQLITE_OK) {
177 ast_log(LOG_WARNING, "Couldn't finalize statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
178 *stmt = NULL;
179 return -1;
180 }
181 *stmt = NULL;
182 return 0;
183}

References ast_log, astdb, LOG_WARNING, and NULL.

Referenced by clean_statements().

◆ convert_bdb_to_sqlite3()

static int convert_bdb_to_sqlite3 ( void  )
static

Definition at line 220 of file main/db.c.

221{
222 char *cmd;
223 int res;
224
225 res = ast_asprintf(&cmd, "%s/astdb2sqlite3 '%s'\n", ast_config_AST_SBIN_DIR, ast_config_AST_DB);
226 if (0 <= res) {
227 res = ast_safe_system(cmd);
228 ast_free(cmd);
229 }
230
231 return res;
232}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
const char * ast_config_AST_SBIN_DIR
Definition: options.c:163
const char * ast_config_AST_DB
Definition: options.c:165

References ast_asprintf, ast_config_AST_DB, ast_config_AST_SBIN_DIR, ast_free, and ast_safe_system().

Referenced by db_open().

◆ db_create_astdb()

static int db_create_astdb ( void  )
static

Definition at line 234 of file main/db.c.

235{
236 int res = 0;
237
238 if (!create_astdb_stmt) {
239 init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql));
240 }
241
243 if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
244 ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
245 res = -1;
246 }
247 sqlite3_reset(create_astdb_stmt);
248 db_sync();
250
251 return res;
252}
static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, db_sync(), dblock, init_stmt(), and LOG_WARNING.

Referenced by db_init().

◆ db_execute_sql()

static int db_execute_sql ( const char *  sql,
int(*)(void *, int, char **, char **)  callback,
void *  arg 
)
static

Definition at line 313 of file main/db.c.

314{
315 char *errmsg = NULL;
316 int res =0;
317
318 if (sqlite3_exec(astdb, sql, callback, arg, &errmsg) != SQLITE_OK) {
319 ast_log(LOG_WARNING, "Error executing SQL (%s): %s\n", sql, errmsg);
320 sqlite3_free(errmsg);
321 res = -1;
322 }
323
324 return res;
325}

References ast_log, astdb, LOG_WARNING, and NULL.

Referenced by ast_db_begin_transaction(), ast_db_commit_transaction(), ast_db_rollback_transaction(), and handle_cli_database_query().

◆ db_get_common()

static int db_get_common ( const char *  family,
const char *  key,
char **  buffer,
int  bufferlen 
)
static

Definition at line 388 of file main/db.c.

389{
390 const unsigned char *result;
391 char fullkey[MAX_DB_FIELD];
392 size_t fullkey_len;
393 int res = 0;
394
395 if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
396 ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
397 return -1;
398 }
399
400 fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
401
403 if (sqlite3_bind_text(get_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
404 ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
405 res = -1;
406 } else if (sqlite3_step(get_stmt) != SQLITE_ROW) {
407 ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
408 res = -1;
409 } else if (!(result = sqlite3_column_text(get_stmt, 0))) {
410 ast_log(LOG_WARNING, "Couldn't get value\n");
411 res = -1;
412 } else {
413 const char *value = (const char *) result;
414
415 if (bufferlen == -1) {
416 *buffer = ast_strdup(value);
417 } else {
418 ast_copy_string(*buffer, value, bufferlen);
419 }
420 }
421 sqlite3_reset(get_stmt);
423
424 return res;
425}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

References ast_copy_string(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strdup, astdb, dblock, LOG_WARNING, MAX_DB_FIELD, result, and value.

Referenced by ast_db_get(), and ast_db_get_allocated().

◆ db_gettree_common()

static struct ast_db_entry * db_gettree_common ( sqlite3_stmt *  stmt)
static

Definition at line 571 of file main/db.c.

572{
573 struct ast_db_entry *head = NULL, *prev = NULL, *cur;
574
575 while (sqlite3_step(stmt) == SQLITE_ROW) {
576 const char *key, *value;
577 size_t key_len, value_len;
578
579 key = (const char *) sqlite3_column_text(stmt, 0);
580 value = (const char *) sqlite3_column_text(stmt, 1);
581
582 if (!key || !value) {
583 break;
584 }
585
586 key_len = strlen(key);
587 value_len = strlen(value);
588
589 cur = ast_malloc(sizeof(*cur) + key_len + value_len + 2);
590 if (!cur) {
591 break;
592 }
593
594 cur->next = NULL;
595 cur->key = cur->data + value_len + 1;
596 memcpy(cur->data, value, value_len + 1);
597 memcpy(cur->key, key, key_len + 1);
598
599 if (prev) {
600 prev->next = cur;
601 } else {
602 head = cur;
603 }
604 prev = cur;
605 }
606
607 return head;
608}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
char * key
Definition: astdb.h:33

References ast_malloc, ast_db_entry::key, NULL, and value.

Referenced by ast_db_gettree(), and ast_db_gettree_by_prefix().

◆ db_init()

static int db_init ( void  )
static

Definition at line 297 of file main/db.c.

298{
299 if (astdb) {
300 return 0;
301 }
302
303 if (db_open() || db_create_astdb() || init_statements()) {
304 return -1;
305 }
306
307 return 0;
308}
static int db_create_astdb(void)
Definition: main/db.c:234
static int db_open(void)
Definition: main/db.c:254
static int init_statements(void)
Definition: main/db.c:204

References astdb, db_create_astdb(), db_open(), and init_statements().

Referenced by astdb_init().

◆ db_open()

static int db_open ( void  )
static

Definition at line 254 of file main/db.c.

255{
256 char *dbname;
257 struct stat dont_care;
258
259 if (!(dbname = ast_alloca(strlen(ast_config_AST_DB) + sizeof(".sqlite3")))) {
260 return -1;
261 }
262 strcpy(dbname, ast_config_AST_DB);
263 strcat(dbname, ".sqlite3");
264
265 if (stat(dbname, &dont_care) && !stat(ast_config_AST_DB, &dont_care)) {
267 ast_log(LOG_ERROR, "*** Database conversion failed!\n");
268 ast_log(LOG_ERROR, "*** Asterisk now uses SQLite3 for its internal\n");
269 ast_log(LOG_ERROR, "*** database. Conversion from the old astdb\n");
270 ast_log(LOG_ERROR, "*** failed. Most likely the astdb2sqlite3 utility\n");
271 ast_log(LOG_ERROR, "*** was not selected for build. To convert the\n");
272 ast_log(LOG_ERROR, "*** old astdb, please delete '%s'\n", dbname);
273 ast_log(LOG_ERROR, "*** and re-run 'make menuselect' and select astdb2sqlite3\n");
274 ast_log(LOG_ERROR, "*** in the Utilities section, then 'make && make install'.\n");
275 ast_log(LOG_ERROR, "*** It is also imperative that the user under which\n");
276 ast_log(LOG_ERROR, "*** Asterisk runs have write permission to the directory\n");
277 ast_log(LOG_ERROR, "*** where the database resides.\n");
278 sleep(5);
279 } else {
280 ast_log(LOG_NOTICE, "Database conversion succeeded!\n");
281 }
282 }
283
285 if (sqlite3_open(dbname, &astdb) != SQLITE_OK) {
286 ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", dbname, sqlite3_errmsg(astdb));
287 sqlite3_close(astdb);
289 return -1;
290 }
291
293
294 return 0;
295}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define LOG_ERROR
#define LOG_NOTICE
static int convert_bdb_to_sqlite3(void)
Definition: main/db.c:220
static char dbname[MAX_DB_OPTION_SIZE]

References ast_alloca, ast_config_AST_DB, ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, convert_bdb_to_sqlite3(), dblock, dbname, LOG_ERROR, LOG_NOTICE, and LOG_WARNING.

Referenced by db_init().

◆ db_sync()

static void db_sync ( void  )
static

Definition at line 1154 of file main/db.c.

1155{
1156 dosync = 1;
1158}
#define ast_cond_signal(cond)
Definition: lock.h:203
static int dosync
Definition: main/db.c:125

References ast_cond_signal, dbcond, and dosync.

Referenced by ast_db_del(), ast_db_del2(), ast_db_deltree(), ast_db_put(), astdb_atexit(), db_create_astdb(), and handle_cli_database_query().

◆ db_sync_thread()

static void * db_sync_thread ( void *  data)
static

Definition at line 1170 of file main/db.c.

1171{
1174 for (;;) {
1175 /* If dosync is set, db_sync() was called during sleep(1),
1176 * and the pending transaction should be committed.
1177 * Otherwise, block until db_sync() is called.
1178 */
1179 while (!dosync) {
1181 }
1182 dosync = 0;
1185 }
1186 if (doexit) {
1188 break;
1189 }
1192 sleep(1);
1194 }
1195
1196 return NULL;
1197}
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
static int ast_db_begin_transaction(void)
Definition: main/db.c:327
static int ast_db_commit_transaction(void)
Definition: main/db.c:332
static int ast_db_rollback_transaction(void)
Definition: main/db.c:337

References ast_cond_wait, ast_db_begin_transaction(), ast_db_commit_transaction(), ast_db_rollback_transaction(), ast_mutex_lock, ast_mutex_unlock, dbcond, dblock, doexit, dosync, and NULL.

Referenced by astdb_init().

◆ DEFINE_SQL_STATEMENT()

DEFINE_SQL_STATEMENT ( put_stmt  ,
"INSERT OR REPLACE INTO astdb (key, value) VALUES (?, ?)"   
)

Definition at line 132 of file main/db.c.

158{
160 if (sqlite3_prepare(astdb, sql, len, stmt, NULL) != SQLITE_OK) {
161 ast_log(LOG_WARNING, "Couldn't prepare statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
163 return -1;
164 }
166
167 return 0;
168}
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References ast_log, ast_mutex_lock, ast_mutex_unlock, astdb, dblock, len(), LOG_WARNING, and NULL.

◆ display_results()

static int display_results ( void *  arg,
int  columns,
char **  values,
char **  colnames 
)
static

Definition at line 913 of file main/db.c.

914{
915 struct ast_cli_args *a = arg;
916 size_t x;
917
918 for (x = 0; x < columns; x++) {
919 ast_cli(a->fd, "%-5s: %-50s\n", colnames[x], values[x]);
920 }
921 ast_cli(a->fd, "\n");
922
923 return 0;
924}
static char * columns
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static struct test_val a

References a, ast_cli(), and columns.

Referenced by handle_cli_database_query().

◆ handle_cli_database_del()

static char * handle_cli_database_del ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 742 of file main/db.c.

743{
744 int res;
745
746 switch (cmd) {
747 case CLI_INIT:
748 e->command = "database del";
749 e->usage =
750 "Usage: database del <family> <key>\n"
751 " Deletes an entry in the Asterisk database for a given\n"
752 " family and key.\n";
753 return NULL;
754 case CLI_GENERATE:
755 return NULL;
756 }
757
758 if (a->argc != 4)
759 return CLI_SHOWUSAGE;
760 res = ast_db_del2(a->argv[2], a->argv[3]);
761 if (res) {
762 ast_cli(a->fd, "Database entry could not be removed.\n");
763 } else {
764 ast_cli(a->fd, "Database entry removed.\n");
765 }
766 return CLI_SUCCESS;
767}
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
int ast_db_del2(const char *family, const char *key)
Same as ast_db_del, but with more stringent error checking.
Definition: main/db.c:504
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177

References a, ast_cli(), ast_db_del2(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

◆ handle_cli_database_deltree()

static char * handle_cli_database_deltree ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 769 of file main/db.c.

770{
771 int num_deleted;
772
773 switch (cmd) {
774 case CLI_INIT:
775 e->command = "database deltree";
776 e->usage =
777 "Usage: database deltree <family> [keytree]\n"
778 " OR: database deltree <family>[/keytree]\n"
779 " Deletes a family or specific keytree within a family\n"
780 " in the Asterisk database. The two arguments may be\n"
781 " separated by either a space or a slash.\n";
782 return NULL;
783 case CLI_GENERATE:
784 return NULL;
785 }
786
787 if ((a->argc < 3) || (a->argc > 4))
788 return CLI_SHOWUSAGE;
789 if (a->argc == 4) {
790 num_deleted = ast_db_deltree(a->argv[2], a->argv[3]);
791 } else {
792 num_deleted = ast_db_deltree(a->argv[2], NULL);
793 }
794 if (num_deleted < 0) {
795 ast_cli(a->fd, "Database unavailable.\n");
796 } else if (num_deleted == 0) {
797 ast_cli(a->fd, "Database entries do not exist.\n");
798 } else {
799 ast_cli(a->fd, "%d database entries removed.\n",num_deleted);
800 }
801 return CLI_SUCCESS;
802}
int ast_db_deltree(const char *family, const char *keytree)
Delete one or more entries in astdb.
Definition: main/db.c:536

References a, ast_cli(), ast_db_deltree(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

◆ handle_cli_database_get()

static char * handle_cli_database_get ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 714 of file main/db.c.

715{
716 int res;
717 char tmp[MAX_DB_FIELD];
718
719 switch (cmd) {
720 case CLI_INIT:
721 e->command = "database get";
722 e->usage =
723 "Usage: database get <family> <key>\n"
724 " Retrieves an entry in the Asterisk database for a given\n"
725 " family and key.\n";
726 return NULL;
727 case CLI_GENERATE:
728 return NULL;
729 }
730
731 if (a->argc != 4)
732 return CLI_SHOWUSAGE;
733 res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp));
734 if (res) {
735 ast_cli(a->fd, "Database entry not found.\n");
736 } else {
737 ast_cli(a->fd, "Value: %s\n", tmp);
738 }
739 return CLI_SUCCESS;
740}

References a, ast_cli(), ast_db_get(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, MAX_DB_FIELD, NULL, tmp(), and ast_cli_entry::usage.

◆ handle_cli_database_put()

static char * handle_cli_database_put ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 687 of file main/db.c.

688{
689 int res;
690
691 switch (cmd) {
692 case CLI_INIT:
693 e->command = "database put";
694 e->usage =
695 "Usage: database put <family> <key> <value>\n"
696 " Adds or updates an entry in the Asterisk database for\n"
697 " a given family, key, and value.\n";
698 return NULL;
699 case CLI_GENERATE:
700 return NULL;
701 }
702
703 if (a->argc != 5)
704 return CLI_SHOWUSAGE;
705 res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]);
706 if (res) {
707 ast_cli(a->fd, "Failed to update entry\n");
708 } else {
709 ast_cli(a->fd, "Updated database successfully\n");
710 }
711 return CLI_SUCCESS;
712}
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:342

References a, ast_cli(), ast_db_put(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

◆ handle_cli_database_query()

static char * handle_cli_database_query ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 926 of file main/db.c.

927{
928
929 switch (cmd) {
930 case CLI_INIT:
931 e->command = "database query";
932 e->usage =
933 "Usage: database query \"<SQL Statement>\"\n"
934 " Run a user-specified SQL query on the database. Be careful.\n";
935 return NULL;
936 case CLI_GENERATE:
937 return NULL;
938 }
939
940 if (a->argc != 3) {
941 return CLI_SHOWUSAGE;
942 }
943
945 db_execute_sql(a->argv[2], display_results, a);
946 db_sync(); /* Go ahead and sync the db in case they write */
948
949 return CLI_SUCCESS;
950}
static int display_results(void *arg, int columns, char **values, char **colnames)
Definition: main/db.c:913

References a, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, db_execute_sql(), db_sync(), dblock, display_results(), NULL, and ast_cli_entry::usage.

◆ handle_cli_database_show()

static char * handle_cli_database_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 804 of file main/db.c.

805{
806 char prefix[MAX_DB_FIELD];
807 int counter = 0;
808 sqlite3_stmt *stmt = gettree_stmt;
809
810 switch (cmd) {
811 case CLI_INIT:
812 e->command = "database show";
813 e->usage =
814 "Usage: database show [family [keytree]]\n"
815 " OR: database show [family[/keytree]]\n"
816 " Shows Asterisk database contents, optionally restricted\n"
817 " to a given family, or family and keytree. The two arguments\n"
818 " may be separated either by a space or by a slash.\n";
819 return NULL;
820 case CLI_GENERATE:
821 return NULL;
822 }
823
824 if (a->argc == 4) {
825 /* Family and key tree */
826 snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
827 } else if (a->argc == 3) {
828 /* Family only */
829 snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
830 } else if (a->argc == 2) {
831 /* Neither */
832 prefix[0] = '\0';
833 stmt = gettree_all_stmt;
834
835 } else {
836 return CLI_SHOWUSAGE;
837 }
838
840 if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
841 ast_log(LOG_WARNING, "Couldn't bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
842 sqlite3_reset(stmt);
844 return NULL;
845 }
846
847 while (sqlite3_step(stmt) == SQLITE_ROW) {
848 const char *key_s, *value_s;
849 if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
850 ast_log(LOG_WARNING, "Skipping invalid key!\n");
851 continue;
852 }
853 if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
854 ast_log(LOG_WARNING, "Skipping invalid value!\n");
855 continue;
856 }
857 ++counter;
858 ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
859 }
860
861 sqlite3_reset(stmt);
863
864 ast_cli(a->fd, "%d results found.\n", counter);
865 return CLI_SUCCESS;
866}

References a, ast_cli(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), astdb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dblock, LOG_WARNING, MAX_DB_FIELD, NULL, prefix, and ast_cli_entry::usage.

◆ handle_cli_database_showkey()

static char * handle_cli_database_showkey ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 868 of file main/db.c.

869{
870 int counter = 0;
871
872 switch (cmd) {
873 case CLI_INIT:
874 e->command = "database showkey";
875 e->usage =
876 "Usage: database showkey <keytree>\n"
877 " Shows Asterisk database contents, restricted to a given key.\n";
878 return NULL;
879 case CLI_GENERATE:
880 return NULL;
881 }
882
883 if (a->argc != 3) {
884 return CLI_SHOWUSAGE;
885 }
886
888 if (!ast_strlen_zero(a->argv[2]) && (sqlite3_bind_text(showkey_stmt, 1, a->argv[2], -1, SQLITE_STATIC) != SQLITE_OK)) {
889 ast_log(LOG_WARNING, "Couldn't bind %s to stmt: %s\n", a->argv[2], sqlite3_errmsg(astdb));
890 sqlite3_reset(showkey_stmt);
892 return NULL;
893 }
894
895 while (sqlite3_step(showkey_stmt) == SQLITE_ROW) {
896 const char *key_s, *value_s;
897 if (!(key_s = (const char *) sqlite3_column_text(showkey_stmt, 0))) {
898 break;
899 }
900 if (!(value_s = (const char *) sqlite3_column_text(showkey_stmt, 1))) {
901 break;
902 }
903 ++counter;
904 ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
905 }
906 sqlite3_reset(showkey_stmt);
908
909 ast_cli(a->fd, "%d results found.\n", counter);
910 return CLI_SUCCESS;
911}

References a, ast_cli(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), astdb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dblock, LOG_WARNING, NULL, and ast_cli_entry::usage.

◆ init_statements()

static int init_statements ( void  )
static

Definition at line 204 of file main/db.c.

205{
206 /* Don't initialize create_astdb_statement here as the astdb table needs to exist
207 * brefore these statements can be initialized */
208 return init_stmt(&get_stmt, get_stmt_sql, sizeof(get_stmt_sql))
209 || init_stmt(&exists_stmt, exists_stmt_sql, sizeof(exists_stmt_sql))
210 || init_stmt(&del_stmt, del_stmt_sql, sizeof(del_stmt_sql))
211 || init_stmt(&deltree_stmt, deltree_stmt_sql, sizeof(deltree_stmt_sql))
212 || init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql))
213 || init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql))
214 || init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql))
215 || init_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql, sizeof(gettree_prefix_stmt_sql))
216 || init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql))
217 || init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
218}

References init_stmt().

Referenced by db_init().

◆ manager_db_tree_get()

static int manager_db_tree_get ( struct mansession s,
const struct message m 
)
static

Definition at line 1029 of file main/db.c.

1030{
1031 char prefix[MAX_DB_FIELD];
1032 char idText[256];
1033 const char *id = astman_get_header(m,"ActionID");
1034 const char *family = astman_get_header(m, "Family");
1035 const char *key = astman_get_header(m, "Key");
1036 sqlite3_stmt *stmt = gettree_stmt;
1037 int count = 0;
1038
1039 if (!ast_strlen_zero(family) && !ast_strlen_zero(key)) {
1040 /* Family and key tree */
1041 snprintf(prefix, sizeof(prefix), "/%s/%s", family, key);
1042 } else if (!ast_strlen_zero(family)) {
1043 /* Family only */
1044 snprintf(prefix, sizeof(prefix), "/%s", family);
1045 } else {
1046 /* Neither */
1047 prefix[0] = '\0';
1048 stmt = gettree_all_stmt;
1049 }
1050
1051 idText[0] = '\0';
1052 if (!ast_strlen_zero(id)) {
1053 snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
1054 }
1055
1057 if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
1058 ast_log(LOG_WARNING, "Couldn't bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
1059 sqlite3_reset(stmt);
1061 astman_send_error(s, m, "Unable to search database");
1062 return 0;
1063 }
1064
1065 astman_send_listack(s, m, "Result will follow", "start");
1066
1067 while (sqlite3_step(stmt) == SQLITE_ROW) {
1068 const char *key_s, *value_s;
1069 if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
1070 ast_log(LOG_WARNING, "Skipping invalid key!\n");
1071 continue;
1072 }
1073 if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
1074 ast_log(LOG_WARNING, "Skipping invalid value!\n");
1075 continue;
1076 }
1077 astman_append(s, "Event: DBGetTreeResponse\r\n"
1078 "Key: %s\r\n"
1079 "Val: %s\r\n"
1080 "%s"
1081 "\r\n",
1082 key_s, value_s, idText);
1083 count++;
1084 }
1085
1086 sqlite3_reset(stmt);
1088
1089 astman_send_list_complete_start(s, m, "DBGetTreeComplete", count);
1091
1092 return 0;
1093}
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3423
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3381
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3459
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3042
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3467
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3302

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), astdb, astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), dblock, LOG_WARNING, MAX_DB_FIELD, and prefix.

Referenced by astdb_init().

◆ manager_dbdel()

static int manager_dbdel ( struct mansession s,
const struct message m 
)
static

Definition at line 1095 of file main/db.c.

1096{
1097 const char *family = astman_get_header(m, "Family");
1098 const char *key = astman_get_header(m, "Key");
1099 int res;
1100
1101 if (ast_strlen_zero(family)) {
1102 astman_send_error(s, m, "No family specified.");
1103 return 0;
1104 }
1105
1106 if (ast_strlen_zero(key)) {
1107 astman_send_error(s, m, "No key specified.");
1108 return 0;
1109 }
1110
1111 res = ast_db_del2(family, key);
1112 if (res)
1113 astman_send_error(s, m, "Database entry could not be deleted");
1114 else
1115 astman_send_ack(s, m, "Key deleted successfully");
1116
1117 return 0;
1118}
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3413

References ast_db_del2(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), and astman_send_error().

Referenced by astdb_init().

◆ manager_dbdeltree()

static int manager_dbdeltree ( struct mansession s,
const struct message m 
)
static

Definition at line 1120 of file main/db.c.

1121{
1122 const char *family = astman_get_header(m, "Family");
1123 const char *key = astman_get_header(m, "Key");
1124 int num_deleted;
1125
1126 if (ast_strlen_zero(family)) {
1127 astman_send_error(s, m, "No family specified.");
1128 return 0;
1129 }
1130
1131 if (!ast_strlen_zero(key)) {
1132 num_deleted = ast_db_deltree(family, key);
1133 } else {
1134 num_deleted = ast_db_deltree(family, NULL);
1135 }
1136
1137 if (num_deleted < 0) {
1138 astman_send_error(s, m, "Database unavailable");
1139 } else if (num_deleted == 0) {
1140 astman_send_error(s, m, "Database entry not found");
1141 } else {
1142 astman_send_ack(s, m, "Key tree deleted successfully");
1143 }
1144
1145 return 0;
1146}

References ast_db_deltree(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and NULL.

Referenced by astdb_init().

◆ manager_dbget()

static int manager_dbget ( struct mansession s,
const struct message m 
)
static

Definition at line 987 of file main/db.c.

988{
989 const char *id = astman_get_header(m,"ActionID");
990 char idText[256];
991 const char *family = astman_get_header(m, "Family");
992 const char *key = astman_get_header(m, "Key");
993 char tmp[MAX_DB_FIELD];
994 int res;
995
996 if (ast_strlen_zero(family)) {
997 astman_send_error(s, m, "No family specified.");
998 return 0;
999 }
1000 if (ast_strlen_zero(key)) {
1001 astman_send_error(s, m, "No key specified.");
1002 return 0;
1003 }
1004
1005 idText[0] = '\0';
1006 if (!ast_strlen_zero(id))
1007 snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
1008
1009 res = ast_db_get(family, key, tmp, sizeof(tmp));
1010 if (res) {
1011 astman_send_error(s, m, "Database entry not found");
1012 } else {
1013 astman_send_listack(s, m, "Result will follow", "start");
1014
1015 astman_append(s, "Event: DBGetResponse\r\n"
1016 "Family: %s\r\n"
1017 "Key: %s\r\n"
1018 "Val: %s\r\n"
1019 "%s"
1020 "\r\n",
1021 family, key, tmp, idText);
1022
1023 astman_send_list_complete_start(s, m, "DBGetComplete", 1);
1025 }
1026 return 0;
1027}

References ast_db_get(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), MAX_DB_FIELD, and tmp().

Referenced by astdb_init().

◆ manager_dbput()

static int manager_dbput ( struct mansession s,
const struct message m 
)
static

Definition at line 962 of file main/db.c.

963{
964 const char *family = astman_get_header(m, "Family");
965 const char *key = astman_get_header(m, "Key");
966 const char *val = astman_get_header(m, "Val");
967 int res;
968
969 if (ast_strlen_zero(family)) {
970 astman_send_error(s, m, "No family specified");
971 return 0;
972 }
973 if (ast_strlen_zero(key)) {
974 astman_send_error(s, m, "No key specified");
975 return 0;
976 }
977
978 res = ast_db_put(family, key, S_OR(val, ""));
979 if (res) {
980 astman_send_error(s, m, "Failed to update entry");
981 } else {
982 astman_send_ack(s, m, "Updated database successfully");
983 }
984 return 0;
985}
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
Definition: ast_expr2.c:325

References ast_db_put(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.

Referenced by astdb_init().

Variable Documentation

◆ astdb

sqlite3* astdb
static

◆ cli_database

struct ast_cli_entry cli_database[]
static

Definition at line 952 of file main/db.c.

Referenced by astdb_atexit(), and astdb_init().

◆ dbcond

ast_cond_t dbcond
static

Definition at line 121 of file main/db.c.

Referenced by astdb_init(), db_sync(), and db_sync_thread().

◆ dblock

ast_mutex_t dblock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

◆ doexit

int doexit
static

Definition at line 124 of file main/db.c.

Referenced by astdb_atexit(), and db_sync_thread().

◆ dosync

int dosync
static

Definition at line 125 of file main/db.c.

Referenced by db_sync(), and db_sync_thread().

◆ syncthread

pthread_t syncthread
static

Definition at line 123 of file main/db.c.

Referenced by astdb_atexit(), and astdb_init().