[asterisk-commits] twilson: branch twilson/sqlite3_playground r341905 - in /team/twilson/sqlite3...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Oct 23 00:54:10 CDT 2011
Author: twilson
Date: Sun Oct 23 00:54:06 2011
New Revision: 341905
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=341905
Log:
Make it possible to require a realtime family to exist
Since we now have a realtime engine and database that have to exist,
make it possible for modules to register a required realtime engine.
This will allow us to stop trying to shove relational data into
key-value pairs in the astdb when we need to cache data.
Modified:
team/twilson/sqlite3_playground/include/asterisk/astdb.h
team/twilson/sqlite3_playground/include/asterisk/config.h
team/twilson/sqlite3_playground/main/config.c
team/twilson/sqlite3_playground/main/db.c
team/twilson/sqlite3_playground/main/realtime_sqlite3.c
Modified: team/twilson/sqlite3_playground/include/asterisk/astdb.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sqlite3_playground/include/asterisk/astdb.h?view=diff&rev=341905&r1=341904&r2=341905
==============================================================================
--- team/twilson/sqlite3_playground/include/asterisk/astdb.h (original)
+++ team/twilson/sqlite3_playground/include/asterisk/astdb.h Sun Oct 23 00:54:06 2011
@@ -27,6 +27,8 @@
extern "C" {
#endif
+static const char * const ast_db_engine = "sqlite3";
+static const char * const ast_db_database = "astdb";
static const char * const ast_db_family = "astdb";
static const char * const ast_db_key= "key";
static const char * const ast_db_value = "value";
Modified: team/twilson/sqlite3_playground/include/asterisk/config.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sqlite3_playground/include/asterisk/config.h?view=diff&rev=341905&r1=341904&r2=341905
==============================================================================
--- team/twilson/sqlite3_playground/include/asterisk/config.h (original)
+++ team/twilson/sqlite3_playground/include/asterisk/config.h Sun Oct 23 00:54:06 2011
@@ -345,6 +345,26 @@
* order to preserve cross-platform compatibility.
*/
int ast_realtime_require_field(const char *family, ...) attribute_sentinel;
+
+/*!
+ * \brief Require a realtime family to exist, creating internally if necessary
+ * \since 11
+ *
+ * \param family which family is required
+ *
+ * \details
+ * This behaves just like ast_realtime_require_field, but adds the mapping
+ * to the internal asterisk database if necessary.
+ */
+int ast_realtime_require_family(const char *family, ...) attribute_sentinel;
+
+/*!
+ * \brief Release a previously required family
+ * \since 11
+ *
+ * \param family the family to release
+ */
+void ast_realtime_required_family_release(const char *family);
/*!
* \brief Retrieve realtime configuration
Modified: team/twilson/sqlite3_playground/main/config.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sqlite3_playground/main/config.c?view=diff&rev=341905&r1=341904&r2=341905
==============================================================================
--- team/twilson/sqlite3_playground/main/config.c (original)
+++ team/twilson/sqlite3_playground/main/config.c Sun Oct 23 00:54:06 2011
@@ -48,6 +48,7 @@
#include "asterisk/astobj2.h"
#include "asterisk/strings.h" /* for the ast_str_*() API */
#include "asterisk/netsock2.h"
+#include "asterisk/astdb.h"
#define MAX_NESTED_COMMENTS 128
#define COMMENT_START ";--"
@@ -176,6 +177,7 @@
static struct ast_config_map {
struct ast_config_map *next;
int priority;
+ int required:1;
/*! Stored in stuff[] at struct end. */
const char *name;
/*! Stored in stuff[] at struct end. */
@@ -2035,20 +2037,33 @@
static void clear_config_maps(void)
{
- struct ast_config_map *map;
+ struct ast_config_map *map, *saved = NULL;
ast_mutex_lock(&config_lock);
while (config_maps) {
- map = config_maps;
- config_maps = config_maps->next;
- ast_free(map);
- }
+ if (config_maps->required) {
+ map = config_maps->next;
+ if (!saved) {
+ saved = config_maps;
+ saved->next = NULL;
+ } else {
+ config_maps->next = saved;
+ saved = config_maps;
+ }
+ config_maps = map;
+ } else {
+ map = config_maps;
+ config_maps = config_maps->next;
+ ast_free(map);
+ }
+ }
+ config_maps = saved;
ast_mutex_unlock(&config_lock);
}
-static int append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
+static int append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority, int required)
{
struct ast_config_map *map;
char *dst;
@@ -2074,6 +2089,9 @@
dst += strlen(dst) + 1;
map->table = strcpy(dst, table);
}
+ if (required) {
+ map->required = 1;
+ }
map->priority = priority;
map->next = config_maps;
config_maps = map;
@@ -2147,14 +2165,15 @@
continue;
if (!strcasecmp(v->name, "sipfriends")) {
ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sipusers and sippeers, though they can point to the same table.\n");
- append_mapping("sipusers", driver, database, table ? table : "sipfriends", pri);
- append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
+ append_mapping("sipusers", driver, database, table ? table : "sipfriends", pri, 0);
+ append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri, 0);
} else if (!strcasecmp(v->name, "iaxfriends")) {
ast_log(LOG_WARNING, "The 'iaxfriends' table is obsolete, update your config to use iaxusers and iaxpeers, though they can point to the same table.\n");
- append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
- append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
- } else
- append_mapping(v->name, driver, database, table, pri);
+ append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri, 0);
+ append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri, 0);
+ } else {
+ append_mapping(v->name, driver, database, table, pri, 0);
+ }
}
ast_config_destroy(config);
@@ -2411,6 +2430,51 @@
va_end(ap);
return res;
+}
+
+int ast_realtime_require_family(const char *family, ...)
+{
+ struct ast_config_engine *eng;
+ char db[256];
+ char table[256];
+ va_list ap;
+ int res = -1, i;
+
+ va_start(ap, family);
+ for (i = 1; ; i++) {
+ if (!(eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
+ append_mapping(family, ast_db_engine, ast_db_database, family, 1, 1);
+ if (!(eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
+ break;
+ }
+ }
+ /* If the require succeeds, it returns 0. */
+ if (eng->require_func && !(res = eng->require_func(db, table, ap))) {
+ break;
+ }
+ }
+ va_end(ap);
+
+ return res;
+}
+
+void ast_realtime_required_family_release(const char *family)
+{
+ struct ast_config_map *map, *prev;
+
+ ast_mutex_lock(&config_lock);
+ for (map = config_maps, prev = NULL; map; prev = map, map = map->next) {
+ if (strcasecmp(map->name, family)) {
+ continue;
+ }
+ if (!prev) {
+ config_maps = map->next;
+ } else {
+ prev->next = map->next;
+ }
+ ast_free(map);
+ }
+ ast_mutex_unlock(&config_lock);
}
int ast_unload_realtime(const char *family)
Modified: team/twilson/sqlite3_playground/main/db.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sqlite3_playground/main/db.c?view=diff&rev=341905&r1=341904&r2=341905
==============================================================================
--- team/twilson/sqlite3_playground/main/db.c (original)
+++ team/twilson/sqlite3_playground/main/db.c Sun Oct 23 00:54:06 2011
@@ -623,7 +623,7 @@
int astdb_init(void)
{
- if (ast_realtime_require_field(ast_db_family, ast_db_key, RQ_CHAR, 256, ast_db_value, RQ_CHAR, 256, SENTINEL)) {
+ if (ast_realtime_require_family(ast_db_family, ast_db_key, RQ_CHAR, 256, ast_db_value, RQ_CHAR, 256, SENTINEL)) {
ast_log(LOG_ERROR, "Could not find proper internal database backend.\n");
return -1;
}
Modified: team/twilson/sqlite3_playground/main/realtime_sqlite3.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sqlite3_playground/main/realtime_sqlite3.c?view=diff&rev=341905&r1=341904&r2=341905
==============================================================================
--- team/twilson/sqlite3_playground/main/realtime_sqlite3.c (original)
+++ team/twilson/sqlite3_playground/main/realtime_sqlite3.c Sun Oct 23 00:54:06 2011
@@ -41,11 +41,13 @@
#include <sqlite3.h>
#include "asterisk/_private.h"
+#include "asterisk/paths.h"
#include "asterisk/config.h"
#include "asterisk/astobj2.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
+#include "asterisk/astdb.h"
/*** DOCUMENTATION
***/
@@ -234,7 +236,10 @@
static int mark_dirty_cb(void *obj, void *arg, int flags)
{
struct realtime_sqlite3_db *db = obj;
- db->dirty = 1;
+ /* Don't mark the internal db as dirty */
+ if (strcasecmp(db->name, ast_db_family)) {
+ db->dirty = 1;
+ }
return CMP_MATCH;
}
@@ -350,14 +355,9 @@
}
}
-/*! \brief Create a db object based on a config category
- * \note Opening the db handle and linking to databases must be handled outside of this function
- */
-static struct realtime_sqlite3_db *new_realtime_sqlite3_db(struct ast_config *config, const char *cat)
-{
- struct ast_variable *var;
+static struct realtime_sqlite3_db *realtime_sqlite3_db_alloc(const char *dbname)
+{
struct realtime_sqlite3_db *db;
-
if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
return NULL;
}
@@ -370,7 +370,21 @@
/* Set defaults */
db->requirements = REALTIME_SQLITE3_REQ_WARN;
db->batch = 100;
- ast_string_field_set(db, name, cat);
+ ast_string_field_set(db, name, dbname);
+ return db;
+}
+
+/*! \brief Create a db object based on a config category
+ * \note Opening the db handle and linking to databases must be handled outside of this function
+ */
+static struct realtime_sqlite3_db *new_realtime_sqlite3_db(struct ast_config *config, const char *cat)
+{
+ struct ast_variable *var;
+ struct realtime_sqlite3_db *db;
+
+ if (!(db = realtime_sqlite3_db_alloc(cat))) {
+ return NULL;
+ }
for (var = ast_variable_browse(config, cat); var; var = var->next) {
if (!strcasecmp(var->name, "dbfile")) {
@@ -920,7 +934,7 @@
return -1;
}
- while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
+ while ((column = va_arg(ap, typeof(column))) && ((type = va_arg(ap, typeof(type))) >= 0) && (sz = va_arg(ap, typeof(sz)))) {
if (first) {
ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
sqlite3_escape_column(column), get_sqlite_column_type(type));
@@ -1051,7 +1065,7 @@
sqlite3_free(sql);
- while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
+ while ((column = va_arg(ap, typeof(column))) && ((type = va_arg(ap, typeof(type))) >= 0) && (sz = va_arg(ap, typeof(sz)))) {
char *found;
if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
if (handle_missing_column(db, table, column, type, sz)) {
@@ -1079,6 +1093,30 @@
{
/* We currently do no caching */
return -1;
+}
+
+static int start_internal_astdb(void)
+{
+ struct realtime_sqlite3_db *db;
+
+ if (!(db = realtime_sqlite3_db_alloc(ast_db_family))) {
+ return -1;
+ }
+
+ /* Make sure we can create table on the internal databse if necessary */
+ db->requirements = REALTIME_SQLITE3_REQ_CLOSE;
+ ast_string_field_build(db, filename, "%s.sqlite3", ast_config_AST_DB);
+
+ if (db_open(db)) {
+ unref_db(&db);
+ return -1;
+ }
+
+ db_start_batch(db);
+ ao2_link(databases, db);
+ unref_db(&db);
+
+ return 0;
}
/*! \brief Parse the res_config_sqlite3 config file
@@ -1163,6 +1201,13 @@
}
ast_register_atexit(realtime_sqlite3_atexit);
+
+ /* We will always maintain a built-in internal database */
+ if (start_internal_astdb()) {
+ ao2_ref(databases, -1);
+ return -1;
+ }
+
if (parse_config(0)) {
ao2_ref(databases, -1);
return -1;
More information about the asterisk-commits
mailing list