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.

Defines

#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.
int ast_db_deltree (const char *family, const char *keytree)
 Delete one or more entries in astdb.
void ast_db_freetree (struct ast_db_entry *dbe)
 Free structure created by ast_db_gettree().
int ast_db_get (const char *family, const char *key, char *value, int valuelen)
 Get key value specified by family/key.
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.
struct ast_db_entryast_db_gettree (const char *family, const char *keytree)
 Get a list of values within the astdb tree.
int ast_db_put (const char *family, const char *key, const char *value)
 Store value addressed by family/key.
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 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_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_MUTEX_INITIALIZER , NULL, 1 }
static int doexit
static int dosync
static pthread_t syncthread


Detailed Description

ASTdb Management.

Author:
Mark Spencer <markster@digium.com>
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.


Define Documentation

#define DEFINE_SQL_STATEMENT ( stmt,
sql   ) 

Value:

static sqlite3_stmt *stmt; \
   const char stmt##_sql[] = sql;

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

#define MAX_DB_FIELD   256


Function Documentation

static int ast_db_begin_transaction ( void   )  [static]

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

References db_execute_sql(), and NULL.

Referenced by db_create_astdb(), and db_sync_thread().

00297 {
00298    return db_execute_sql("BEGIN TRANSACTION", NULL, NULL);
00299 }

static int ast_db_commit_transaction ( void   )  [static]

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

References db_execute_sql(), and NULL.

Referenced by db_create_astdb(), and db_sync_thread().

00302 {
00303    return db_execute_sql("COMMIT", NULL, NULL);
00304 }

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

Delete entry in astdb.

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

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

Referenced by __expire_registry(), ast_privacy_set(), AST_TEST_DEFINE(), auth_exec(), cache_lookup_internal(), del_exec(), destroy_all_channels(), destroy_association(), dialgroup_refreshdb(), dump_queue_members(), function_db_delete(), handle_cli_database_del(), handle_dbdel(), manager_dbdel(), mkintf(), process_clearcache(), reload_queue_members(), sorcery_astdb_delete(), stasis_app_device_state_delete(), and update_registry().

00414 {
00415    char fullkey[MAX_DB_FIELD];
00416    size_t fullkey_len;
00417    int res = 0;
00418 
00419    if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
00420       ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
00421       return -1;
00422    }
00423 
00424    fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
00425 
00426    ast_mutex_lock(&dblock);
00427    if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
00428       ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
00429       res = -1;
00430    } else if (sqlite3_step(del_stmt) != SQLITE_DONE) {
00431       ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
00432       res = -1;
00433    }
00434    sqlite3_reset(del_stmt);
00435    db_sync();
00436    ast_mutex_unlock(&dblock);
00437 
00438    return res;
00439 }

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:
-1 An error occurred
>= 0 Number of records deleted

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

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

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

00442 {
00443    sqlite3_stmt *stmt = deltree_stmt;
00444    char prefix[MAX_DB_FIELD];
00445    int res = 0;
00446 
00447    if (!ast_strlen_zero(family)) {
00448       if (!ast_strlen_zero(keytree)) {
00449          /* Family and key tree */
00450          snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
00451       } else {
00452          /* Family only */
00453          snprintf(prefix, sizeof(prefix), "/%s", family);
00454       }
00455    } else {
00456       prefix[0] = '\0';
00457       stmt = deltree_all_stmt;
00458    }
00459 
00460    ast_mutex_lock(&dblock);
00461    if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
00462       ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
00463       res = -1;
00464    } else if (sqlite3_step(stmt) != SQLITE_DONE) {
00465       ast_log(LOG_WARNING, "Couldn't execute stmt: %s\n", sqlite3_errmsg(astdb));
00466       res = -1;
00467    }
00468    res = sqlite3_changes(astdb);
00469    sqlite3_reset(stmt);
00470    db_sync();
00471    ast_mutex_unlock(&dblock);
00472 
00473    return res;
00474 }

void ast_db_freetree ( struct ast_db_entry dbe  ) 

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

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:
-1 An error occurred
0 Success

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

References db_get_common(), and NULL.

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

00407 {
00408    *out = NULL;
00409 
00410    return db_get_common(family, key, out, -1);
00411 }

struct ast_db_entry* ast_db_gettree ( const char *  family,
const char *  keytree 
) [read]

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 476 of file main/db.c.

References ast_log, ast_malloc, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero, ast_db_entry::data, dblock, ast_db_entry::key, last, LOG_WARNING, MAX_DB_FIELD, ast_db_entry::next, NULL, and prefix.

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

00477 {
00478    char prefix[MAX_DB_FIELD];
00479    sqlite3_stmt *stmt = gettree_stmt;
00480    struct ast_db_entry *cur, *last = NULL, *ret = NULL;
00481 
00482    if (!ast_strlen_zero(family)) {
00483       if (!ast_strlen_zero(keytree)) {
00484          /* Family and key tree */
00485          snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
00486       } else {
00487          /* Family only */
00488          snprintf(prefix, sizeof(prefix), "/%s", family);
00489       }
00490    } else {
00491       prefix[0] = '\0';
00492       stmt = gettree_all_stmt;
00493    }
00494 
00495    ast_mutex_lock(&dblock);
00496    if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
00497       ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
00498       sqlite3_reset(stmt);
00499       ast_mutex_unlock(&dblock);
00500       return NULL;
00501    }
00502 
00503    while (sqlite3_step(stmt) == SQLITE_ROW) {
00504       const char *key_s, *value_s;
00505       if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
00506          break;
00507       }
00508       if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
00509          break;
00510       }
00511       if (!(cur = ast_malloc(sizeof(*cur) + strlen(key_s) + strlen(value_s) + 2))) {
00512          break;
00513       }
00514       cur->next = NULL;
00515       cur->key = cur->data + strlen(value_s) + 1;
00516       strcpy(cur->data, value_s);
00517       strcpy(cur->key, key_s);
00518       if (last) {
00519          last->next = cur;
00520       } else {
00521          ret = cur;
00522       }
00523       last = cur;
00524    }
00525    sqlite3_reset(stmt);
00526    ast_mutex_unlock(&dblock);
00527 
00528    return ret;
00529 }

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

Store value addressed by family/key.

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

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

Referenced by __analog_ss_thread(), ast_privacy_set(), AST_TEST_DEFINE(), 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(), mgcp_ss(), parse_register_contact(), presence_write(), save_secret(), sorcery_astdb_create(), stasis_app_device_state_update(), and update_registry().

00312 {
00313    char fullkey[MAX_DB_FIELD];
00314    size_t fullkey_len;
00315    int res = 0;
00316 
00317    if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
00318       ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
00319       return -1;
00320    }
00321 
00322    fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
00323 
00324    ast_mutex_lock(&dblock);
00325    if (sqlite3_bind_text(put_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
00326       ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
00327       res = -1;
00328    } else if (sqlite3_bind_text(put_stmt, 2, value, -1, SQLITE_STATIC) != SQLITE_OK) {
00329       ast_log(LOG_WARNING, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
00330       res = -1;
00331    } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
00332       ast_log(LOG_WARNING, "Couldn't execute statment: %s\n", sqlite3_errmsg(astdb));
00333       res = -1;
00334    }
00335 
00336    sqlite3_reset(put_stmt);
00337    db_sync();
00338    ast_mutex_unlock(&dblock);
00339 
00340    return res;
00341 }

static int ast_db_rollback_transaction ( void   )  [static]

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

References db_execute_sql(), and NULL.

Referenced by db_create_astdb(), and db_sync_thread().

00307 {
00308    return db_execute_sql("ROLLBACK", NULL, NULL);
00309 }

static void astdb_atexit ( void   )  [static]

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

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, clean_statements(), db_sync(), dblock, and NULL.

Referenced by astdb_init().

00992 {
00993    ast_cli_unregister_multiple(cli_database, ARRAY_LEN(cli_database));
00994    ast_manager_unregister("DBGet");
00995    ast_manager_unregister("DBPut");
00996    ast_manager_unregister("DBDel");
00997    ast_manager_unregister("DBDelTree");
00998 
00999    /* Set doexit to 1 to kill thread. db_sync must be called with
01000     * mutex held. */
01001    ast_mutex_lock(&dblock);
01002    doexit = 1;
01003    db_sync();
01004    ast_mutex_unlock(&dblock);
01005 
01006    pthread_join(syncthread, NULL);
01007    ast_mutex_lock(&dblock);
01008    clean_statements();
01009    if (sqlite3_close(astdb) == SQLITE_OK) {
01010       astdb = NULL;
01011    }
01012    ast_mutex_unlock(&dblock);
01013 }

int astdb_init ( void   ) 

static void clean_statements ( void   )  [static]

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

References clean_stmt().

Referenced by astdb_atexit().

00165 {
00166    clean_stmt(&get_stmt, get_stmt_sql);
00167    clean_stmt(&del_stmt, del_stmt_sql);
00168    clean_stmt(&deltree_stmt, deltree_stmt_sql);
00169    clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql);
00170    clean_stmt(&gettree_stmt, gettree_stmt_sql);
00171    clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql);
00172    clean_stmt(&showkey_stmt, showkey_stmt_sql);
00173    clean_stmt(&put_stmt, put_stmt_sql);
00174    clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql);
00175 }

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

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

References ast_log, LOG_WARNING, and NULL.

Referenced by clean_statements().

00150 {
00151    if (sqlite3_finalize(*stmt) != SQLITE_OK) {
00152       ast_log(LOG_WARNING, "Couldn't finalize statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
00153       *stmt = NULL;
00154       return -1;
00155    }
00156    *stmt = NULL;
00157    return 0;
00158 }

static int convert_bdb_to_sqlite3 ( void   )  [static]

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

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

Referenced by db_open(), and main().

00192 {
00193    char *cmd;
00194    int res;
00195 
00196    ast_asprintf(&cmd, "%s/astdb2sqlite3 '%s'\n", ast_config_AST_SBIN_DIR, ast_config_AST_DB);
00197    res = ast_safe_system(cmd);
00198    ast_free(cmd);
00199 
00200    return res;
00201 }

static int db_create_astdb ( void   )  [static]

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

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

Referenced by db_init(), and sql_db_init().

00204 {
00205    int res = 0;
00206 
00207    if (!create_astdb_stmt) {
00208       init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql));
00209    }
00210 
00211    ast_mutex_lock(&dblock);
00212    if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
00213       ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
00214       res = -1;
00215    }
00216    sqlite3_reset(create_astdb_stmt);
00217    db_sync();
00218    ast_mutex_unlock(&dblock);
00219 
00220    return res;
00221 }

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

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

References ast_log, LOG_WARNING, and NULL.

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

00283 {
00284    char *errmsg = NULL;
00285    int res =0;
00286 
00287    if (sqlite3_exec(astdb, sql, callback, arg, &errmsg) != SQLITE_OK) {
00288       ast_log(LOG_WARNING, "Error executing SQL (%s): %s\n", sql, errmsg);
00289       sqlite3_free(errmsg);
00290       res = -1;
00291    }
00292 
00293    return res;
00294 }

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

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

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

Referenced by ast_db_get(), and ast_db_get_allocated().

00358 {
00359    const unsigned char *result;
00360    char fullkey[MAX_DB_FIELD];
00361    size_t fullkey_len;
00362    int res = 0;
00363 
00364    if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
00365       ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
00366       return -1;
00367    }
00368 
00369    fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
00370 
00371    ast_mutex_lock(&dblock);
00372    if (sqlite3_bind_text(get_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
00373       ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
00374       res = -1;
00375    } else if (sqlite3_step(get_stmt) != SQLITE_ROW) {
00376       ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family);
00377       res = -1;
00378    } else if (!(result = sqlite3_column_text(get_stmt, 0))) {
00379       ast_log(LOG_WARNING, "Couldn't get value\n");
00380       res = -1;
00381    } else {
00382       const char *value = (const char *) result;
00383 
00384       if (bufferlen == -1) {
00385          *buffer = ast_strdup(value);
00386       } else {
00387          ast_copy_string(*buffer, value, bufferlen);
00388       }
00389    }
00390    sqlite3_reset(get_stmt);
00391    ast_mutex_unlock(&dblock);
00392 
00393    return res;
00394 }

static int db_init ( void   )  [static]

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

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

Referenced by astdb_init().

00267 {
00268    if (astdb) {
00269       return 0;
00270    }
00271 
00272    if (db_open() || db_create_astdb() || init_statements()) {
00273       return -1;
00274    }
00275 
00276    return 0;
00277 }

static int db_open ( void   )  [static]

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

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

Referenced by db_init(), parse_config(), sql_db_init(), and update_realtime_sqlite3_db().

00224 {
00225    char *dbname;
00226    struct stat dont_care;
00227 
00228    if (!(dbname = ast_alloca(strlen(ast_config_AST_DB) + sizeof(".sqlite3")))) {
00229       return -1;
00230    }
00231    strcpy(dbname, ast_config_AST_DB);
00232    strcat(dbname, ".sqlite3");
00233 
00234    if (stat(dbname, &dont_care) && !stat(ast_config_AST_DB, &dont_care)) {
00235       if (convert_bdb_to_sqlite3()) {
00236          ast_log(LOG_ERROR, "*** Database conversion failed!\n");
00237          ast_log(LOG_ERROR, "*** Asterisk now uses SQLite3 for its internal\n");
00238          ast_log(LOG_ERROR, "*** database. Conversion from the old astdb\n");
00239          ast_log(LOG_ERROR, "*** failed. Most likely the astdb2sqlite3 utility\n");
00240          ast_log(LOG_ERROR, "*** was not selected for build. To convert the\n");
00241          ast_log(LOG_ERROR, "*** old astdb, please delete '%s'\n", dbname);
00242          ast_log(LOG_ERROR, "*** and re-run 'make menuselect' and select astdb2sqlite3\n");
00243          ast_log(LOG_ERROR, "*** in the Utilities section, then 'make && make install'.\n");
00244          ast_log(LOG_ERROR, "*** It is also imperative that the user under which\n");
00245          ast_log(LOG_ERROR, "*** Asterisk runs have write permission to the directory\n");
00246          ast_log(LOG_ERROR, "*** where the database resides.\n");
00247          sleep(5);
00248       } else {
00249          ast_log(LOG_NOTICE, "Database conversion succeeded!\n");
00250       }
00251    }
00252 
00253    ast_mutex_lock(&dblock);
00254    if (sqlite3_open(dbname, &astdb) != SQLITE_OK) {
00255       ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", dbname, sqlite3_errmsg(astdb));
00256       sqlite3_close(astdb);
00257       ast_mutex_unlock(&dblock);
00258       return -1;
00259    }
00260 
00261    ast_mutex_unlock(&dblock);
00262 
00263    return 0;
00264 }

static void db_sync ( void   )  [static]

static void* db_sync_thread ( void *  data  )  [static]

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

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

Referenced by astdb_init(), and db_start_batch().

00959 {
00960    ast_mutex_lock(&dblock);
00961    ast_db_begin_transaction();
00962    for (;;) {
00963       /* If dosync is set, db_sync() was called during sleep(1), 
00964        * and the pending transaction should be committed. 
00965        * Otherwise, block until db_sync() is called.
00966        */
00967       while (!dosync) {
00968          ast_cond_wait(&dbcond, &dblock);
00969       }
00970       dosync = 0;
00971       if (ast_db_commit_transaction()) {
00972          ast_db_rollback_transaction();
00973       }
00974       if (doexit) {
00975          ast_mutex_unlock(&dblock);
00976          break;
00977       }
00978       ast_db_begin_transaction();
00979       ast_mutex_unlock(&dblock);
00980       sleep(1);
00981       ast_mutex_lock(&dblock);
00982    }
00983 
00984    return NULL;
00985 }

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

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

References ast_log, ast_mutex_lock, ast_mutex_unlock, dblock, LOG_WARNING, and NULL.

00133 {
00134    ast_mutex_lock(&dblock);
00135    if (sqlite3_prepare(astdb, sql, len, stmt, NULL) != SQLITE_OK) {
00136       ast_log(LOG_WARNING, "Couldn't prepare statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
00137       ast_mutex_unlock(&dblock);
00138       return -1;
00139    }
00140    ast_mutex_unlock(&dblock);
00141 
00142    return 0;
00143 }

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

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

References a, ast_cli(), and ast_cli_args::fd.

Referenced by handle_cli_database_query().

00768 {
00769    struct ast_cli_args *a = arg;
00770    size_t x;
00771 
00772    for (x = 0; x < columns; x++) {
00773       ast_cli(a->fd, "%-5s: %-50s\n", colnames[x], values[x]);
00774    }
00775    ast_cli(a->fd, "\n");
00776 
00777    return 0;
00778 }

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

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

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_del(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

00597 {
00598    int res;
00599 
00600    switch (cmd) {
00601    case CLI_INIT:
00602       e->command = "database del";
00603       e->usage =
00604          "Usage: database del <family> <key>\n"
00605          "       Deletes an entry in the Asterisk database for a given\n"
00606          "       family and key.\n";
00607       return NULL;
00608    case CLI_GENERATE:
00609       return NULL;
00610    }
00611 
00612    if (a->argc != 4)
00613       return CLI_SHOWUSAGE;
00614    res = ast_db_del(a->argv[2], a->argv[3]);
00615    if (res) {
00616       ast_cli(a->fd, "Database entry does not exist.\n");
00617    } else {
00618       ast_cli(a->fd, "Database entry removed.\n");
00619    }
00620    return CLI_SUCCESS;
00621 }

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

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

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_deltree(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

00624 {
00625    int num_deleted;
00626 
00627    switch (cmd) {
00628    case CLI_INIT:
00629       e->command = "database deltree";
00630       e->usage =
00631          "Usage: database deltree <family> [keytree]\n"
00632          "   OR: database deltree <family>[/keytree]\n"
00633          "       Deletes a family or specific keytree within a family\n"
00634          "       in the Asterisk database.  The two arguments may be\n"
00635          "       separated by either a space or a slash.\n";
00636       return NULL;
00637    case CLI_GENERATE:
00638       return NULL;
00639    }
00640 
00641    if ((a->argc < 3) || (a->argc > 4))
00642       return CLI_SHOWUSAGE;
00643    if (a->argc == 4) {
00644       num_deleted = ast_db_deltree(a->argv[2], a->argv[3]);
00645    } else {
00646       num_deleted = ast_db_deltree(a->argv[2], NULL);
00647    }
00648    if (num_deleted < 0) {
00649       ast_cli(a->fd, "Database unavailable.\n");
00650    } else if (num_deleted == 0) {
00651       ast_cli(a->fd, "Database entries do not exist.\n");
00652    } else {
00653       ast_cli(a->fd, "%d database entries removed.\n",num_deleted);
00654    }
00655    return CLI_SUCCESS;
00656 }

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

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

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_get(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_DB_FIELD, NULL, tmp(), and ast_cli_entry::usage.

00569 {
00570    int res;
00571    char tmp[MAX_DB_FIELD];
00572 
00573    switch (cmd) {
00574    case CLI_INIT:
00575       e->command = "database get";
00576       e->usage =
00577          "Usage: database get <family> <key>\n"
00578          "       Retrieves an entry in the Asterisk database for a given\n"
00579          "       family and key.\n";
00580       return NULL;
00581    case CLI_GENERATE:
00582       return NULL;
00583    }
00584 
00585    if (a->argc != 4)
00586       return CLI_SHOWUSAGE;
00587    res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp));
00588    if (res) {
00589       ast_cli(a->fd, "Database entry not found.\n");
00590    } else {
00591       ast_cli(a->fd, "Value: %s\n", tmp);
00592    }
00593    return CLI_SUCCESS;
00594 }

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

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

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_put(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

00542 {
00543    int res;
00544 
00545    switch (cmd) {
00546    case CLI_INIT:
00547       e->command = "database put";
00548       e->usage =
00549          "Usage: database put <family> <key> <value>\n"
00550          "       Adds or updates an entry in the Asterisk database for\n"
00551          "       a given family, key, and value.\n";
00552       return NULL;
00553    case CLI_GENERATE:
00554       return NULL;
00555    }
00556 
00557    if (a->argc != 5)
00558       return CLI_SHOWUSAGE;
00559    res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]);
00560    if (res)  {
00561       ast_cli(a->fd, "Failed to update entry\n");
00562    } else {
00563       ast_cli(a->fd, "Updated database successfully\n");
00564    }
00565    return CLI_SUCCESS;
00566 }

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

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

References ast_cli_args::argc, ast_cli_args::argv, 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.

00781 {
00782 
00783    switch (cmd) {
00784    case CLI_INIT:
00785       e->command = "database query";
00786       e->usage =
00787          "Usage: database query \"<SQL Statement>\"\n"
00788          "       Run a user-specified SQL query on the database. Be careful.\n";
00789       return NULL;
00790    case CLI_GENERATE:
00791       return NULL;
00792    }
00793 
00794    if (a->argc != 3) {
00795       return CLI_SHOWUSAGE;
00796    }
00797 
00798    ast_mutex_lock(&dblock);
00799    db_execute_sql(a->argv[2], display_results, a);
00800    db_sync(); /* Go ahead and sync the db in case they write */
00801    ast_mutex_unlock(&dblock);
00802 
00803    return CLI_SUCCESS;
00804 }

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

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

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

00659 {
00660    char prefix[MAX_DB_FIELD];
00661    int counter = 0;
00662    sqlite3_stmt *stmt = gettree_stmt;
00663 
00664    switch (cmd) {
00665    case CLI_INIT:
00666       e->command = "database show";
00667       e->usage =
00668          "Usage: database show [family [keytree]]\n"
00669          "   OR: database show [family[/keytree]]\n"
00670          "       Shows Asterisk database contents, optionally restricted\n"
00671          "       to a given family, or family and keytree. The two arguments\n"
00672          "       may be separated either by a space or by a slash.\n";
00673       return NULL;
00674    case CLI_GENERATE:
00675       return NULL;
00676    }
00677 
00678    if (a->argc == 4) {
00679       /* Family and key tree */
00680       snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
00681    } else if (a->argc == 3) {
00682       /* Family only */
00683       snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
00684    } else if (a->argc == 2) {
00685       /* Neither */
00686       prefix[0] = '\0';
00687       stmt = gettree_all_stmt;
00688 
00689    } else {
00690       return CLI_SHOWUSAGE;
00691    }
00692 
00693    ast_mutex_lock(&dblock);
00694    if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
00695       ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
00696       sqlite3_reset(stmt);
00697       ast_mutex_unlock(&dblock);
00698       return NULL;
00699    }
00700 
00701    while (sqlite3_step(stmt) == SQLITE_ROW) {
00702       const char *key_s, *value_s;
00703       if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
00704          ast_log(LOG_WARNING, "Skipping invalid key!\n");
00705          continue;
00706       }
00707       if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
00708          ast_log(LOG_WARNING, "Skipping invalid value!\n");
00709          continue;
00710       }
00711       ++counter;
00712       ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
00713    }
00714 
00715    sqlite3_reset(stmt);
00716    ast_mutex_unlock(&dblock);
00717 
00718    ast_cli(a->fd, "%d results found.\n", counter);
00719    return CLI_SUCCESS;
00720 }

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

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

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dblock, ast_cli_args::fd, LOG_WARNING, NULL, and ast_cli_entry::usage.

00723 {
00724    int counter = 0;
00725 
00726    switch (cmd) {
00727    case CLI_INIT:
00728       e->command = "database showkey";
00729       e->usage =
00730          "Usage: database showkey <keytree>\n"
00731          "       Shows Asterisk database contents, restricted to a given key.\n";
00732       return NULL;
00733    case CLI_GENERATE:
00734       return NULL;
00735    }
00736 
00737    if (a->argc != 3) {
00738       return CLI_SHOWUSAGE;
00739    }
00740 
00741    ast_mutex_lock(&dblock);
00742    if (!ast_strlen_zero(a->argv[2]) && (sqlite3_bind_text(showkey_stmt, 1, a->argv[2], -1, SQLITE_STATIC) != SQLITE_OK)) {
00743       ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", a->argv[2], sqlite3_errmsg(astdb));
00744       sqlite3_reset(showkey_stmt);
00745       ast_mutex_unlock(&dblock);
00746       return NULL;
00747    }
00748 
00749    while (sqlite3_step(showkey_stmt) == SQLITE_ROW) {
00750       const char *key_s, *value_s;
00751       if (!(key_s = (const char *) sqlite3_column_text(showkey_stmt, 0))) {
00752          break;
00753       }
00754       if (!(value_s = (const char *) sqlite3_column_text(showkey_stmt, 1))) {
00755          break;
00756       }
00757       ++counter;
00758       ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
00759    }
00760    sqlite3_reset(showkey_stmt);
00761    ast_mutex_unlock(&dblock);
00762 
00763    ast_cli(a->fd, "%d results found.\n", counter);
00764    return CLI_SUCCESS;
00765 }

static int init_statements ( void   )  [static]

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

References init_stmt().

Referenced by db_init(), and sql_db_init().

00178 {
00179    /* Don't initialize create_astdb_statment here as the astdb table needs to exist
00180     * brefore these statments can be initialized */
00181    return init_stmt(&get_stmt, get_stmt_sql, sizeof(get_stmt_sql))
00182    || init_stmt(&del_stmt, del_stmt_sql, sizeof(del_stmt_sql))
00183    || init_stmt(&deltree_stmt, deltree_stmt_sql, sizeof(deltree_stmt_sql))
00184    || init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql))
00185    || init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql))
00186    || init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql))
00187    || init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql))
00188    || init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
00189 }

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

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

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

Referenced by astdb_init().

00884 {
00885    const char *family = astman_get_header(m, "Family");
00886    const char *key = astman_get_header(m, "Key");
00887    int res;
00888 
00889    if (ast_strlen_zero(family)) {
00890       astman_send_error(s, m, "No family specified.");
00891       return 0;
00892    }
00893 
00894    if (ast_strlen_zero(key)) {
00895       astman_send_error(s, m, "No key specified.");
00896       return 0;
00897    }
00898 
00899    res = ast_db_del(family, key);
00900    if (res)
00901       astman_send_error(s, m, "Database entry not found");
00902    else
00903       astman_send_ack(s, m, "Key deleted successfully");
00904 
00905    return 0;
00906 }

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

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

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

Referenced by astdb_init().

00909 {
00910    const char *family = astman_get_header(m, "Family");
00911    const char *key = astman_get_header(m, "Key");
00912    int num_deleted;
00913 
00914    if (ast_strlen_zero(family)) {
00915       astman_send_error(s, m, "No family specified.");
00916       return 0;
00917    }
00918 
00919    if (!ast_strlen_zero(key)) {
00920       num_deleted = ast_db_deltree(family, key);
00921    } else {
00922       num_deleted = ast_db_deltree(family, NULL);
00923    }
00924 
00925    if (num_deleted < 0) {
00926       astman_send_error(s, m, "Database unavailable");
00927    } else if (num_deleted == 0) {
00928       astman_send_error(s, m, "Database entry not found");
00929    } else {
00930       astman_send_ack(s, m, "Key tree deleted successfully");
00931    }
00932 
00933    return 0;
00934 }

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

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

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().

00842 {
00843    const char *id = astman_get_header(m,"ActionID");
00844    char idText[256];
00845    const char *family = astman_get_header(m, "Family");
00846    const char *key = astman_get_header(m, "Key");
00847    char tmp[MAX_DB_FIELD];
00848    int res;
00849 
00850    if (ast_strlen_zero(family)) {
00851       astman_send_error(s, m, "No family specified.");
00852       return 0;
00853    }
00854    if (ast_strlen_zero(key)) {
00855       astman_send_error(s, m, "No key specified.");
00856       return 0;
00857    }
00858 
00859    idText[0] = '\0';
00860    if (!ast_strlen_zero(id))
00861       snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
00862 
00863    res = ast_db_get(family, key, tmp, sizeof(tmp));
00864    if (res) {
00865       astman_send_error(s, m, "Database entry not found");
00866    } else {
00867       astman_send_listack(s, m, "Result will follow", "start");
00868 
00869       astman_append(s, "Event: DBGetResponse\r\n"
00870             "Family: %s\r\n"
00871             "Key: %s\r\n"
00872             "Val: %s\r\n"
00873             "%s"
00874             "\r\n",
00875             family, key, tmp, idText);
00876 
00877       astman_send_list_complete_start(s, m, "DBGetComplete", 1);
00878       astman_send_list_complete_end(s);
00879    }
00880    return 0;
00881 }

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

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

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

Referenced by astdb_init().

00817 {
00818    const char *family = astman_get_header(m, "Family");
00819    const char *key = astman_get_header(m, "Key");
00820    const char *val = astman_get_header(m, "Val");
00821    int res;
00822 
00823    if (ast_strlen_zero(family)) {
00824       astman_send_error(s, m, "No family specified");
00825       return 0;
00826    }
00827    if (ast_strlen_zero(key)) {
00828       astman_send_error(s, m, "No key specified");
00829       return 0;
00830    }
00831 
00832    res = ast_db_put(family, key, S_OR(val, ""));
00833    if (res) {
00834       astman_send_error(s, m, "Failed to update entry");
00835    } else {
00836       astman_send_ack(s, m, "Updated database successfully");
00837    }
00838    return 0;
00839 }


Variable Documentation

sqlite3* astdb [static]

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

Referenced by db_create_astdb(), db_open(), db_put_raw(), DEFINE_SQL_STATEMENT(), init_stmt(), and main().

struct ast_cli_entry cli_database[] [static]

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

ast_cond_t dbcond [static]

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

ast_mutex_t dblock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

int doexit [static]

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

Referenced by ast_monitor_change_fname().

int dosync [static]

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

pthread_t syncthread [static]

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


Generated on Thu Apr 16 06:30:36 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6