[asterisk-commits] twilson: branch twilson/sqlite_astdb r323320 - /team/twilson/sqlite_astdb/main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jun 13 22:06:13 CDT 2011
Author: twilson
Date: Mon Jun 13 22:06:11 2011
New Revision: 323320
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=323320
Log:
Add database conversion routine for old Berkeley databases
Also fix some issues with the syncing
Modified:
team/twilson/sqlite_astdb/main/db.c
Modified: team/twilson/sqlite_astdb/main/db.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sqlite_astdb/main/db.c?view=diff&rev=323320&r1=323319&r2=323320
==============================================================================
--- team/twilson/sqlite_astdb/main/db.c (original)
+++ team/twilson/sqlite_astdb/main/db.c Mon Jun 13 22:06:11 2011
@@ -20,11 +20,11 @@
*
* \brief ASTdb Management
*
- * \author Mark Spencer <markster at digium.com>
+ * \author Mark Spencer <markster at 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
+ * with GPL. To avoid having to make another exception (and complicate
+ * licensing even further) we elect to use DB1 which is BSD licensed
*/
#include "asterisk.h"
@@ -34,6 +34,9 @@
#include "asterisk/_private.h"
#include "asterisk/paths.h" /* use ast_config_AST_DB */
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <signal.h>
#include <dirent.h>
@@ -46,6 +49,7 @@
#include "asterisk/utils.h"
#include "asterisk/manager.h"
#include <sqlite3.h>
+#include "db1-ast/include/db.h"
/*** DOCUMENTATION
<manager name="DBGet" language="en_US">
@@ -134,6 +138,8 @@
static int init_statements(void)
{
+ /* Don't initialize create_astdb_statment here as the astdb table needs to exist
+ * brefore these statments can be initialized */
return init_stmt(&get_stmt, get_stmt_sql, sizeof(get_stmt_sql))
|| init_stmt(&del_stmt, del_stmt_sql, sizeof(del_stmt_sql))
|| init_stmt(&deltree_stmt, deltree_stmt_sql, sizeof(deltree_stmt_sql))
@@ -144,14 +150,81 @@
|| init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
}
+static int db_put_raw(const char *key, size_t keylen, const char *value, size_t valuelen)
+{
+ int res = 0;
+
+ ast_mutex_lock(&dblock);
+ if (sqlite3_bind_text(put_stmt, 1, key, keylen, SQLITE_STATIC) != SQLITE_OK) {
+ ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
+ res = -1;
+ } else if (sqlite3_bind_text(put_stmt, 2, value, valuelen, SQLITE_STATIC) != SQLITE_OK) {
+ ast_log(LOG_WARNING, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
+ res = -1;
+ } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
+ ast_log(LOG_WARNING, "Couldn't execute statment: %s\n", sqlite3_errmsg(astdb));
+ res = -1;
+ }
+ sqlite3_reset(put_stmt);
+ db_sync();
+ ast_mutex_unlock(&dblock);
+
+ return res;
+}
+
+static int convert_bdb_to_sqlite3(const char *sql3_dbname)
+{
+ DB *bdb;
+ DBT key = { 0, }, value = { 0, };
+ int res;
+
+ if (!(bdb = dbopen(ast_config_AST_DB, O_RDONLY, AST_FILE_MODE, DB_BTREE, NULL))) {
+ ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", ast_config_AST_DB, strerror(errno));
+ return -1;
+ }
+
+ for (res = bdb->seq(bdb, &key, &value, R_FIRST);
+ !res; res = bdb->seq(bdb, &key, &value, R_NEXT)) {
+ db_put_raw((const char *) key.data, key.size, (const char *) value.data, value.size);
+ }
+
+ bdb->close(bdb);
+
+ return 0;
+}
+
+static int db_create_astdb(void)
+{
+ int res = 0;
+
+ if (!create_astdb_stmt) {
+ init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql));
+ }
+
+ ast_mutex_lock(&dblock);
+ if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
+ ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
+ res = -1;
+ }
+ sqlite3_reset(create_astdb_stmt);
+ db_sync();
+ ast_mutex_unlock(&dblock);
+
+ return res;
+}
+
static int db_open(void)
{
char *dbname;
+ struct stat st;
+ int convert;
if (!(dbname = alloca(strlen(ast_config_AST_DB) + sizeof(".sqlite3")))) {
return -1;
}
strcpy(dbname, ast_config_AST_DB);
strcat(dbname, ".sqlite3");
+
+ convert = stat(dbname, &st) && !stat(ast_config_AST_DB, &st);
ast_mutex_lock(&dblock);
if (sqlite3_open_v2(dbname, &astdb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL) != SQLITE_OK) {
@@ -162,30 +235,21 @@
}
ast_mutex_unlock(&dblock);
+ if (convert) {
+ /* We didn't have an sqlite3 version of the database, but we had a BDB version */
+ ast_log(LOG_WARNING, "Converting old astdb to sqlite3!\n");
+ if (db_create_astdb() || init_statements()) {
+ return -1;
+ }
+ if (!convert_bdb_to_sqlite3(dbname)) {
+ ast_log(LOG_WARNING, "Database conversion succeeded!\n");
+ }
+ }
+
return 0;
}
-static int db_create_astdb(void)
-{
- int res = 0;
-
- if (!create_astdb_stmt) {
- init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql));
- }
-
- ast_mutex_lock(&dblock);
- if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) {
- ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb));
- res = -1;
- }
- sqlite3_reset(create_astdb_stmt);
- db_sync();
- ast_mutex_unlock(&dblock);
-
- return res;
-}
-
-static int db_init(void)
+static int db_init(void)
{
if (astdb) {
return 0;
@@ -235,7 +299,6 @@
{
char fullkey[MAX_DB_FIELD];
size_t fullkey_len;
- int res = 0;
if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) {
ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3);
@@ -244,21 +307,7 @@
fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key);
- ast_mutex_lock(&dblock);
- if (sqlite3_bind_text(put_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) {
- ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb));
- res = -1;
- } else if (sqlite3_bind_text(put_stmt, 2, value, -1, SQLITE_STATIC) != SQLITE_OK) {
- ast_log(LOG_WARNING, "Couldn't bind value to stmt: %s\n", sqlite3_errmsg(astdb));
- res = -1;
- } else if (sqlite3_step(put_stmt) != SQLITE_DONE) {
- ast_log(LOG_WARNING, "Couldn't execute statment: %s\n", sqlite3_errmsg(astdb));
- res = -1;
- }
- sqlite3_reset(put_stmt);
- ast_mutex_unlock(&dblock);
-
- return res;
+ return db_put_raw(fullkey, fullkey_len, value, strlen(value) + 1);
}
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
@@ -316,6 +365,7 @@
res = -1;
}
sqlite3_reset(del_stmt);
+ db_sync();
ast_mutex_unlock(&dblock);
return res;
@@ -351,6 +401,7 @@
}
res = sqlite3_changes(astdb);
sqlite3_reset(stmt);
+ db_sync();
ast_mutex_unlock(&dblock);
return res;
@@ -538,6 +589,7 @@
{
char prefix[MAX_DB_FIELD];
int counter = 0;
+ sqlite3_stmt *stmt = gettree_stmt;
switch (cmd) {
case CLI_INIT:
@@ -560,24 +612,35 @@
} else if (a->argc == 2) {
/* Neither */
prefix[0] = '\0';
+ stmt = gettree_all_stmt;
+
} else {
return CLI_SHOWUSAGE;
}
ast_mutex_lock(&dblock);
- while (sqlite3_step(gettree_stmt) == SQLITE_ROW) {
+ if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
+ ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
+ sqlite3_reset(stmt);
+ ast_mutex_unlock(&dblock);
+ return NULL;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
const char *key_s, *value_s;
- if (!(key_s = (const char *) sqlite3_column_text(gettree_stmt, 0))) {
- break;
- }
- if (!(value_s = (const char *) sqlite3_column_text(gettree_stmt, 1))) {
- break;
+ if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
+ ast_log(LOG_WARNING, "Skipping invalid key!\n");
+ continue;
+ }
+ if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
+ ast_log(LOG_WARNING, "Skipping invalid value!\n");
+ continue;
}
++counter;
ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
}
- sqlite3_reset(gettree_stmt);
+ sqlite3_reset(stmt);
ast_mutex_unlock(&dblock);
ast_cli(a->fd, "%d results found.\n", counter);
@@ -753,7 +816,7 @@
astman_send_error(s, m, "Database entry not found");
else
astman_send_ack(s, m, "Key tree deleted successfully");
-
+
return 0;
}
@@ -785,13 +848,14 @@
for (;;) {
/* We're ok with spurious wakeups, so we don't worry about a predicate */
ast_cond_wait(&dbcond, &dblock);
+ ast_debug(10, "Committing astdb transaction\n");
if (ast_db_commit_transaction()) {
ast_db_rollback_transaction();
}
+ ast_db_begin_transaction();
ast_mutex_unlock(&dblock);
sleep(1);
ast_mutex_lock(&dblock);
- ast_db_begin_transaction();
}
return NULL;
@@ -799,17 +863,18 @@
int astdb_init(void)
{
- pthread_t dont_care;
-
- ast_cond_init(&dbcond, NULL);
- if (ast_pthread_create_background(&dont_care, NULL, db_sync_thread, NULL)) {
- return -1;
- }
+ pthread_t syncthread;
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
if (db_init()) {
return -1;
}
+
+ ast_cond_init(&dbcond, NULL);
+ if (ast_pthread_create_background(&syncthread, NULL, db_sync_thread, NULL)) {
+ return -1;
+ }
+
ast_cli_register_multiple(cli_database, ARRAY_LEN(cli_database));
ast_manager_register_xml("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget);
ast_manager_register_xml("DBPut", EVENT_FLAG_SYSTEM, manager_dbput);
More information about the asterisk-commits
mailing list