[svn-commits] twilson: branch twilson/sqlite3_playground r341905 - in /team/twilson/sqlite3...

SVN commits to the Digium repositories svn-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 svn-commits mailing list