Revision
15487
Author
anthm
Date
2009-11-16 18:12:54 -0600 (Mon, 16 Nov 2009)

Log Message

add support for running core-db over odbc

Modified Paths

Diff

Modified: freeswitch/trunk/src/include/private/switch_core_pvt.h (15486 => 15487)


--- freeswitch/trunk/src/include/private/switch_core_pvt.h	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/include/private/switch_core_pvt.h	2009-11-17 00:12:54 UTC (rev 15487)
@@ -207,11 +207,14 @@
 	switch_frame_t dummy_cng_frame;
 	char dummy_data[5];
 	switch_bool_t colorize_console;
+	char *odbc_dsn;
+	char *odbc_user;
+	char *odbc_pass;
 };
 
 extern struct switch_runtime runtime;
 
-void switch_core_sqldb_start(switch_memory_pool_t *pool);
+switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage);
 void switch_core_sqldb_stop(void);
 void switch_core_session_init(switch_memory_pool_t *pool);
 void switch_core_session_uninit(void);

Modified: freeswitch/trunk/src/include/switch_core.h (15486 => 15487)


--- freeswitch/trunk/src/include/switch_core.h	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/include/switch_core.h	2009-11-17 00:12:54 UTC (rev 15487)
@@ -1415,6 +1415,7 @@
 
 */
 SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute(switch_core_db_t *db, char *sql, uint32_t retries);
+SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute_trans(switch_core_db_t *db, char *sql, uint32_t retries);
 
 /*! 
   \brief perform a test query then perform a reactive query if the first one fails
@@ -1425,12 +1426,6 @@
 */
 SWITCH_DECLARE(void) switch_core_db_test_reactive(switch_core_db_t *db, char *test_sql, char *drop_sql, char *reactive_sql);
 
-#define SWITCH_CORE_DB "core"
-/*!
-  \brief Open the default system database
-*/
-#define switch_core_db_handle() switch_core_db_open_file(SWITCH_CORE_DB)
-
 ///\}
 
 ///\defgroup Media File Functions
@@ -1930,13 +1925,17 @@
 } switch_cache_db_handle_t;
 
 SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh);
-SWITCH_DECLARE(switch_cache_db_handle_t *)switch_cache_db_get_db_handle(const char *db_name, const char *odbc_user, const char *odbc_pass);
-SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, char *sql);
+SWITCH_DECLARE(switch_status_t) switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh, 
+																		const char *db_name, const char *odbc_user, const char *odbc_pass);
+SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, char *sql, char **err);
 SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, char *sql, 
-																	 switch_core_db_callback_func_t callback, void *pdata);
+																	 switch_core_db_callback_func_t callback, void *pdata, char **err);
 
+SWITCH_DECLARE(switch_status_t)switch_core_db_handle(switch_cache_db_handle_t **dbh);
+SWITCH_DECLARE(void) switch_cache_db_test_reactive(switch_cache_db_handle_t *db, char *test_sql, char *drop_sql, char *reactive_sql);
+SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries);
+SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries);
 
-
 SWITCH_END_EXTERN_C
 #endif
 /* For Emacs:

Modified: freeswitch/trunk/src/include/switch_odbc.h (15486 => 15487)


--- freeswitch/trunk/src/include/switch_odbc.h	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/include/switch_odbc.h	2009-11-17 00:12:54 UTC (rev 15487)
@@ -77,7 +77,7 @@
   \note none
 */
 SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(const char *file, const char *func, int line, switch_odbc_handle_t *handle,
-																	  char *sql, switch_core_db_callback_func_t callback, void *pdata);
+																			   char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err);
 /*!
   \brief Execute the sql query and issue a callback for each row returned
   \param handle the ODBC handle
@@ -87,9 +87,9 @@
   \return SWITCH_STATUS_SUCCESS if the operation was successful
   \note none
 */
-#define switch_odbc_handle_callback_exec(handle,  sql,  callback, pdata) \
+#define switch_odbc_handle_callback_exec(handle,  sql,  callback, pdata, err) \
 		switch_odbc_handle_callback_exec_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, \
-												  handle, sql, callback, pdata)
+												  handle, sql, callback, pdata, err)
 
 																	  
 SWITCH_DECLARE(char *) switch_odbc_handle_get_error(switch_odbc_handle_t *handle, switch_odbc_statement_handle_t stmt);

Modified: freeswitch/trunk/src/mod/applications/mod_cidlookup/mod_cidlookup.c (15486 => 15487)


--- freeswitch/trunk/src/mod/applications/mod_cidlookup/mod_cidlookup.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/applications/mod_cidlookup/mod_cidlookup.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -186,7 +186,7 @@
 	
 	switch_mutex_lock(globals.db_mutex);
 	if (globals.odbc_dsn) {
-		if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, callback, pdata)
+		if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, callback, pdata, NULL)
 				== SWITCH_ODBC_FAIL) {
 			retval = SWITCH_FALSE;
 		} else {

Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c (15486 => 15487)


--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -2914,7 +2914,7 @@
 {
 	char sql[1024];
 	char *errmsg;
-	switch_core_db_t *db;
+	switch_cache_db_handle_t *db;
 	struct holder holder = { 0 };
 	int help = 0;
 	char *mydata = NULL, *argv[6] = { 0 };
@@ -2923,7 +2923,7 @@
 	switch_core_flag_t cflags = switch_core_flags();
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 
-	db = switch_core_db_handle();
+	switch_core_db_handle(&db);
 	
 	holder.justcount = 0;
 	
@@ -3090,7 +3090,7 @@
 				holder.delim = ",";
 			}
 		}
-		switch_core_db_exec(db, sql, show_callback, &holder, &errmsg);
+		switch_cache_db_execute_sql_callback(db, sql, show_callback, &holder, &errmsg);
 		if (holder.http) {
 			holder.stream->write_function(holder.stream, "</table>");
 		}
@@ -3106,7 +3106,7 @@
 			stream->write_function(stream, "\n%u total.\n", holder.count);
 		}
 	} else if (!strcasecmp(as, "xml")) {
-		switch_core_db_exec(db, sql, show_as_xml_callback, &holder, &errmsg);
+		switch_cache_db_execute_sql_callback(db, sql, show_as_xml_callback, &holder, &errmsg);
 
 		if (errmsg) {
 			stream->write_function(stream, "-ERR SQL Error [%s]\n", errmsg);
@@ -3141,7 +3141,7 @@
 	switch_safe_free(mydata);
 
 	if (db) {
-		switch_core_db_close(db);
+		switch_cache_db_release_db_handle(&db);
 	}
 
 	return status;

Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (15486 => 15487)


--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -336,7 +336,7 @@
 		switch_channel_t *channel = switch_core_session_get_channel(session);
 		const char *require_group = switch_channel_get_variable(channel, "eavesdrop_require_group");
 		if (!strcasecmp((char *) data, "all")) {
-			switch_core_db_t *db = switch_core_db_handle();
+			switch_cache_db_handle_t *db = NULL;
 			char *errmsg = NULL;
 			struct e_data e_data = { {0} };
 			char *sql = switch_mprintf("select uuid from channels where uuid != '%q'", switch_core_session_get_uuid(session));
@@ -347,12 +347,14 @@
 			char terminator;
 			switch_status_t status;
 
+			switch_core_db_handle(&db);
+
 			while (switch_channel_ready(channel)) {
 				for (x = 0; x < MAX_SPY; x++) {
 					switch_safe_free(e_data.uuid_list[x]);
 				}
 				e_data.total = 0;
-				switch_core_db_exec(db, sql, e_callback, &e_data, &errmsg);
+				switch_cache_db_execute_sql_callback(db, sql, e_callback, &e_data, &errmsg);
 				if (errmsg) {
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error: %s\n", errmsg);
 					switch_core_db_free(errmsg);
@@ -393,7 +395,7 @@
 			}
 
 			free(sql);
-			switch_core_db_close(db);
+			switch_cache_db_release_db_handle(&db);
 
 		} else {
 			switch_ivr_eavesdrop_session(session, data, require_group, ED_DTMF);

Modified: freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c (15486 => 15487)


--- freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -339,7 +339,7 @@
 	}
 
 	if (switch_odbc_available() && globals.odbc_dsn) {
-		switch_odbc_handle_callback_exec(globals.master_odbc, sql, callback, pdata);
+		switch_odbc_handle_callback_exec(globals.master_odbc, sql, callback, pdata, NULL);
 	} else {
 		if (!(db = switch_core_db_open_file(globals.dbname))) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", globals.dbname);

Modified: freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c (15486 => 15487)


--- freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -138,7 +138,7 @@
 	}
 
 	if (switch_odbc_available() && globals.odbc_dsn) {
-		switch_odbc_handle_callback_exec(globals.master_odbc, sql, callback, pdata);
+		switch_odbc_handle_callback_exec(globals.master_odbc, sql, callback, pdata, NULL);
 	} else {
 		if (!(db = switch_core_db_open_file(globals.dbname))) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", globals.dbname);

Modified: freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c (15486 => 15487)


--- freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/applications/mod_voicemail/mod_voicemail.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -201,7 +201,7 @@
 	}
 
 	if (switch_odbc_available() && profile->odbc_dsn) {
-		switch_odbc_handle_callback_exec(profile->master_odbc, sql, callback, pdata);
+		switch_odbc_handle_callback_exec(profile->master_odbc, sql, callback, pdata, NULL);
 	} else {
 		if (!(db = switch_core_db_open_file(profile->dbname))) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (15486 => 15487)


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -2876,7 +2876,8 @@
 	switch_channel_t *nchannel;
 	char *host = NULL, *dest_to = NULL;
 	const char *hval = NULL;
-
+	char *not_const = NULL;
+		
 	*new_session = NULL;
 
 	if (!outbound_profile || zstr(outbound_profile->destination_number)) {
@@ -3115,10 +3116,12 @@
 
 	caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
 	
-
+	
 	caller_profile->destination_number = switch_sanitize_number(caller_profile->destination_number);
-	caller_profile->caller_id_name = switch_sanitize_number((char *)caller_profile->caller_id_name);
-	caller_profile->caller_id_number = switch_sanitize_number((char *)caller_profile->caller_id_number);
+	not_const = (char *)caller_profile->caller_id_name;
+	caller_profile->caller_id_name = switch_sanitize_number(not_const);
+	not_const = (char *)caller_profile->caller_id_number;
+	caller_profile->caller_id_number = switch_sanitize_number(not_const);
 	
 	//caller_profile->destination_number = switch_core_strdup(caller_profile->pool, dest_num);
 	switch_channel_set_caller_profile(nchannel, caller_profile);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c (15486 => 15487)


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -4008,12 +4008,14 @@
 		if ((dbh = (sofia_cache_db_handle_t *) val)) {
 			time_t diff = 0;
 
-			if (prune > 0 && prune > dbh->last_used) {
-				diff = (time_t) prune - dbh->last_used;
-			}
+			if (prune > 0) {
+				if (prune > dbh->last_used) {
+					diff = (time_t) prune - dbh->last_used;
+				}
 			
-			if (diff < SQL_CACHE_TIMEOUT) {
-				continue;
+				if (diff < SQL_CACHE_TIMEOUT) {
+					continue;
+				}
 			}
 
 			if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
@@ -4121,7 +4123,7 @@
 
 		
 		if (db) dbh->db = db; else dbh->odbc_dbh = odbc_dbh;
-		switch_mutex_init(&dbh->mutex, SWITCH_MUTEX_NESTED, dbh->pool);
+		switch_mutex_init(&dbh->mutex, 0, dbh->pool);
 		switch_mutex_lock(dbh->mutex);
 
 		switch_core_hash_insert(profile->db_hash, thread_str, dbh);
@@ -4202,7 +4204,7 @@
     }
 
 	if (switch_odbc_available() && dbh->odbc_dbh) {
-		switch_odbc_handle_callback_exec(dbh->odbc_dbh, sql, callback, pdata);
+		switch_odbc_handle_callback_exec(dbh->odbc_dbh, sql, callback, pdata, NULL);
 	} else if (profile->odbc_dsn) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
 	} else {

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c (15486 => 15487)


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -1678,7 +1678,9 @@
 	if ((regtype == REG_REGISTER) && sofia_test_pflag(profile, PFLAG_CHECKUSER)) {
 		if (zstr(username) || zstr(to_user) || strcasecmp(to_user, username)) {
 			/* Names don't match, so fail */
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SIP username %s does not match auth username\n", switch_str_nil(to_user));
+			if (profile->debug) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SIP username %s does not match auth username\n", switch_str_nil(to_user));
+			}
 			goto end;
 		}
 	}

Modified: freeswitch/trunk/src/switch_channel.c (15486 => 15487)


--- freeswitch/trunk/src/switch_channel.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/switch_channel.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -1403,7 +1403,8 @@
 	switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL;
 	switch_codec_implementation_t impl = {0};
 	char state_num[25];
-
+	const char *v;
+	
 	switch_mutex_lock(channel->profile_mutex);
 
 	if ((caller_profile = switch_channel_get_caller_profile(channel))) {
@@ -1422,7 +1423,15 @@
 	switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Call-Direction",
 								   channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
 
+	if ((v = switch_channel_get_variable(channel, "presence_id"))) {
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-ID", v);
+	}
 
+	if ((v = switch_channel_get_variable(channel, "presence_data"))) {
+		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-Data", v);
+	}
+
+
 	if (switch_channel_test_flag(channel, CF_ANSWERED)) {
 		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "answered");
 	} else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {

Modified: freeswitch/trunk/src/switch_console.c (15486 => 15487)


--- freeswitch/trunk/src/switch_console.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/switch_console.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -199,12 +199,15 @@
 	char *r = NULL;
 	char *sql = NULL;
 	char *exp = NULL;
-	switch_core_db_t *db = switch_core_db_handle();
+	switch_cache_db_handle_t *db = NULL;
 	int full = 0;
 
+
+	switch_core_db_handle(&db);
+
 	sql = switch_mprintf("select command from aliases where alias='%q'", cmd);
 
-	switch_core_db_exec(db, sql, alias_callback, &r, &errmsg);
+	switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg);
 
 	if (errmsg) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg);
@@ -216,7 +219,7 @@
 	if (!r) {
 		sql = switch_mprintf("select command from aliases where alias='%q %q'", cmd, arg);
 
-		switch_core_db_exec(db, sql, alias_callback, &r, &errmsg);
+		switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg);
 
 		if (errmsg) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg);
@@ -240,7 +243,8 @@
 		exp = cmd;
 	}
 
-	switch_core_db_close(db);
+	switch_cache_db_release_db_handle(&db);
+
 	return exp;
 }
 
@@ -524,7 +528,7 @@
 
 static unsigned char complete(EditLine * el, int ch)
 {
-	switch_core_db_t *db = switch_core_db_handle();
+	switch_cache_db_handle_t *db = NULL;
 	char *sql;
 	const LineInfo *lf = el_line(el);
 	char *dup = strdup(lf->buffer);
@@ -534,6 +538,8 @@
 	struct helper h = { el };
 	unsigned char ret = CC_REDISPLAY;
 
+	switch_core_db_handle(&db);
+
 	h.out = switch_core_get_console();
 
 	if ((p = strchr(buf, '\r')) || (p = strchr(buf, '\n'))) {
@@ -560,12 +566,14 @@
 	fprintf(h.out, "\n\n");
 
 	if (h.words == 0) {
-		sql = switch_mprintf("select distinct name from interfaces where type='api' and name like '%s%%' order by name", buf);
+		sql = switch_mprintf("select distinct name from interfaces where type='api' and name like '%q%%' and hostname='%q' order by name", 
+							 buf, switch_core_get_variable("hostname"));
 	} else {
-		sql = switch_mprintf("select distinct uuid from channels where uuid like '%s%%' order by uuid", buf);
+		sql = switch_mprintf("select distinct uuid from channels where uuid like '%q%%' and hostname='%q' order by uuid", 
+							 buf, switch_core_get_variable("hostname"));
 	}
 
-	switch_core_db_exec(db, sql, comp_callback, &h, &errmsg);
+	switch_cache_db_execute_sql_callback(db, sql, comp_callback, &h, &errmsg);
 
 	if (errmsg) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg);
@@ -586,7 +594,8 @@
 		argc = switch_separate_string(dupdup, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
 
 		if (h.words == 0) {
-			stream.write_function(&stream, "select distinct a1 from complete where " "a1 not in (select name from interfaces) %s ", argc ? "and" : "");
+			stream.write_function(&stream, "select distinct a1 from complete where " "a1 not in (select name from interfaces where hostname='%s') %s ", 
+								  switch_core_get_variable("hostname"), argc ? "and" : "");
 		} else {
 			stream.write_function(&stream, "select distinct a%d from complete where ", h.words + 1);
 
@@ -596,8 +605,10 @@
 			stream.write_function(&stream, "(a%d = '' or a%d like '%s%%')%s", x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
 		}
 
-		switch_core_db_exec(db, stream.data, comp_callback, &h, &errmsg);
+		stream.write_function(&stream, " and hostname='%s'", switch_core_get_variable("hostname"));
 
+		switch_cache_db_execute_sql_callback(db, stream.data, comp_callback, &h, &errmsg);
+
 		if (errmsg) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", (char *) stream.data, errmsg);
 			free(errmsg);
@@ -626,7 +637,7 @@
 	switch_safe_free(sql);
 	switch_safe_free(dup);
 
-	switch_core_db_close(db);
+	switch_cache_db_release_db_handle(&db);
 
 	return (ret);
 }
@@ -640,40 +651,44 @@
 
 	if (string && (mydata = strdup(string))) {
 		if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
-			switch_core_db_t *db = switch_core_db_handle();
+			switch_cache_db_handle_t *db = NULL;
 			switch_stream_handle_t mystream = { 0 };
 			SWITCH_STANDARD_STREAM(mystream);
 
-
+			switch_core_db_handle(&db);
+			
 			if (!strcasecmp(argv[0], "stickyadd")) {
 				mystream.write_function(&mystream, "insert into complete values (1,");
 				for (x = 0; x < 10; x++) {
-					mystream.write_function(&mystream, "'%s'%s", switch_str_nil(argv[x + 1]), x == 9 ? ")" : ", ");
+					mystream.write_function(&mystream, "'%s', ", switch_str_nil(argv[x + 1]));
 				}
-				switch_core_db_persistant_execute(db, mystream.data, 5);
+				mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname"));
+				switch_cache_db_persistant_execute(db, mystream.data, 5);
 				status = SWITCH_STATUS_SUCCESS;
 			} else if (!strcasecmp(argv[0], "add")) {
 				mystream.write_function(&mystream, "insert into complete values (0,");
 				for (x = 0; x < 10; x++) {
-					mystream.write_function(&mystream, "'%s'%s", switch_str_nil(argv[x + 1]), x == 9 ? ")" : ", ");
+					mystream.write_function(&mystream, "'%s', ", switch_str_nil(argv[x + 1]));
 				}
-				switch_core_db_persistant_execute(db, mystream.data, 5);
+				mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname"));
+				switch_cache_db_persistant_execute(db, mystream.data, 5);
 				status = SWITCH_STATUS_SUCCESS;
 			} else if (!strcasecmp(argv[0], "del")) {
 				char *what = argv[1];
 				if (!strcasecmp(what, "*")) {
-					switch_core_db_persistant_execute(db, "delete from complete", 1);
+					switch_cache_db_persistant_execute(db, "delete from complete", 1);
 				} else {
 					mystream.write_function(&mystream, "delete from complete where ");
 					for (x = 0; x < argc - 1; x++) {
 						mystream.write_function(&mystream, "a%d = '%s'%s", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and ");
 					}
-					switch_core_db_persistant_execute(db, mystream.data, 1);
+					mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_variable("hostname"));
+					switch_cache_db_persistant_execute(db, mystream.data, 1);
 				}
 				status = SWITCH_STATUS_SUCCESS;
 			}
 			switch_safe_free(mystream.data);
-			switch_core_db_close(db);
+			switch_cache_db_release_db_handle(&db);
 		}
 	}
 
@@ -692,36 +707,40 @@
 
 	if (string && (mydata = strdup(string))) {
 		if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
-			switch_core_db_t *db = switch_core_db_handle();
+			switch_cache_db_handle_t *db = NULL;
 			char *sql = NULL;
 
+			switch_core_db_handle(&db);
 
 			if (!strcasecmp(argv[0], "stickyadd") && argc == 3) {
-				sql = switch_mprintf("delete from aliases where alias='%q'", argv[1]);
-				switch_core_db_persistant_execute(db, sql, 5);
+				sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname"));
+				switch_cache_db_persistant_execute(db, sql, 5);
 				switch_safe_free(sql);
-				sql = switch_mprintf("insert into aliases (sticky, alias, command) values (1, '%q','%q')", argv[1], argv[2]);
-				switch_core_db_persistant_execute(db, sql, 5);
+				sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')", 
+									 argv[1], argv[2], switch_core_get_variable("hostname"));
+				switch_cache_db_persistant_execute(db, sql, 5);
 				status = SWITCH_STATUS_SUCCESS;
 			} else if (!strcasecmp(argv[0], "add") && argc == 3) {
-				sql = switch_mprintf("delete from aliases where alias='%q'", argv[1]);
-				switch_core_db_persistant_execute(db, sql, 5);
+				sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname"));
+				switch_cache_db_persistant_execute(db, sql, 5);
 				switch_safe_free(sql);
-				sql = switch_mprintf("insert into aliases (sticky, alias, command) values (0, '%q','%q')", argv[1], argv[2]);
-				switch_core_db_persistant_execute(db, sql, 5);
+				sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q')", 
+									 argv[1], argv[2], switch_core_get_variable("hostname"));
+				switch_cache_db_persistant_execute(db, sql, 5);
 				status = SWITCH_STATUS_SUCCESS;
 			} else if (!strcasecmp(argv[0], "del") && argc == 2) {
 				char *what = argv[1];
 				if (!strcasecmp(what, "*")) {
-					switch_core_db_persistant_execute(db, "delete from aliases", 1);
+					sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_variable("hostname"));
+					switch_cache_db_persistant_execute(db, sql, 1);
 				} else {
-					sql = switch_mprintf("delete from aliases where alias='%q'", argv[1]);
-					switch_core_db_persistant_execute(db, sql, 5);
+					sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname"));
+					switch_cache_db_persistant_execute(db, sql, 5);
 				}
 				status = SWITCH_STATUS_SUCCESS;
 			}
 			switch_safe_free(sql);
-			switch_core_db_close(db);
+			switch_cache_db_release_db_handle(&db);
 		}
 	}
 

Modified: freeswitch/trunk/src/switch_core.c (15486 => 15487)


--- freeswitch/trunk/src/switch_core.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/switch_core.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -1282,9 +1282,10 @@
 
 	switch_core_state_machine_init(runtime.memory_pool);
 
-	if (switch_test_flag((&runtime), SCF_USE_SQL)) {
-		switch_core_sqldb_start(runtime.memory_pool);
+	if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
+		abort();
 	}
+
 	switch_scheduler_task_thread_start();
 
 	switch_rtp_init(runtime.memory_pool);
@@ -1422,6 +1423,18 @@
 					switch_rtp_set_start_port((switch_port_t) atoi(val));
 				} else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
 					switch_rtp_set_end_port((switch_port_t) atoi(val));
+				} else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) {
+					if (switch_odbc_available()) {
+						runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val);
+						if ((runtime.odbc_user = strchr(runtime.odbc_dsn, ':'))) {
+							*runtime.odbc_user++ = '\0';
+							if ((runtime.odbc_pass = strchr(runtime.odbc_user, ':'))) {
+								*runtime.odbc_pass++ = '\0';
+							}
+						}
+					} else {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
+					}
 #ifdef ENABLE_ZRTP
 				} else if (!strcasecmp(var, "rtp-enable-zrtp")) {
 					switch_core_set_variable("zrtp_enabled", val);
@@ -1446,7 +1459,20 @@
 
 }
 
+#define SWITCH_CORE_DB "core"
+/*!
+  \brief Open the default system database
+*/
+SWITCH_DECLARE(switch_status_t)switch_core_db_handle(switch_cache_db_handle_t **dbh)
+{
+	if (runtime.odbc_dsn && runtime.odbc_user && runtime.odbc_pass) {
+		return switch_cache_db_get_db_handle(dbh, runtime.odbc_dsn, runtime.odbc_user, runtime.odbc_pass);
+	} else {
+		return switch_cache_db_get_db_handle(dbh, SWITCH_CORE_DB, NULL, NULL);
+	}
+}
 
+
 SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
 {
 	switch_event_t *event;

Modified: freeswitch/trunk/src/switch_core_db.c (15486 => 15487)


--- freeswitch/trunk/src/switch_core_db.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/switch_core_db.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -241,6 +241,111 @@
 
 }
 
+
+SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute_trans(switch_core_db_t *db, char *sql, uint32_t retries)
+{
+	char *errmsg;
+	switch_status_t status = SWITCH_STATUS_FALSE;
+	uint8_t forever = 0;
+	unsigned begin_retries = 100;
+	uint8_t again = 0;
+
+	if (!retries) {
+		forever = 1;
+		retries = 1000;
+	}
+
+again:
+
+	while (begin_retries > 0) {
+		again = 0;
+
+		switch_core_db_exec(db, "BEGIN", NULL, NULL, &errmsg);
+
+		if (errmsg) {
+			begin_retries--;
+			if (strstr(errmsg, "cannot start a transaction within a transaction")) {
+				again = 1;
+			} else {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL Retry [%s]\n", errmsg);
+			}
+			switch_core_db_free(errmsg);
+			errmsg = NULL;
+
+			if (again) {
+				switch_core_db_exec(db, "COMMIT", NULL, NULL, NULL);
+				goto again;
+			}
+
+			switch_yield(100000);
+
+			if (begin_retries == 0) {
+				goto done;
+			}
+		} else {
+			break;
+		}
+
+	}
+
+	while (retries > 0) {
+		switch_core_db_exec(db, sql, NULL, NULL, &errmsg);
+		if (errmsg) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
+			switch_core_db_free(errmsg);
+			errmsg = NULL;
+			switch_yield(100000);
+			retries--;
+			if (retries == 0 && forever) {
+				retries = 1000;
+				continue;
+			}
+		} else {
+			status = SWITCH_STATUS_SUCCESS;
+			break;
+		}
+	}
+
+done:
+
+	switch_core_db_exec(db, "COMMIT", NULL, NULL, NULL);
+
+	return status;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute(switch_core_db_t *db, char *sql, uint32_t retries)
+{
+	char *errmsg;
+	switch_status_t status = SWITCH_STATUS_FALSE;
+	uint8_t forever = 0;
+
+	if (!retries) {
+		forever = 1;
+		retries = 1000;
+	}
+
+	while (retries > 0) {
+		switch_core_db_exec(db, sql, NULL, NULL, &errmsg);
+		if (errmsg) {
+			//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
+			switch_core_db_free(errmsg);
+			switch_yield(100000);
+			retries--;
+			if (retries == 0 && forever) {
+				retries = 1000;
+				continue;
+			}
+		} else {
+			status = SWITCH_STATUS_SUCCESS;
+			break;
+		}
+	}
+
+	return status;
+}
+
+
+
 /* For Emacs:
  * Local Variables:
  * mode:c

Modified: freeswitch/trunk/src/switch_core_sqldb.c (15486 => 15487)


--- freeswitch/trunk/src/switch_core_sqldb.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/switch_core_sqldb.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -36,13 +36,13 @@
 #include "private/switch_core_pvt.h"
 
 static struct {
-	switch_core_db_t *db;
-	switch_core_db_t *event_db;
+	switch_cache_db_handle_t *event_db;
 	switch_queue_t *sql_queue[2];
 	switch_memory_pool_t *memory_pool;
 	switch_event_node_t *event_node;
 	switch_thread_t *thread;
 	int thread_running;
+	switch_bool_t manage;
 } sql_manager;
 
 static switch_mutex_t *dbh_mutex = NULL;
@@ -58,7 +58,7 @@
 	switch_cache_db_handle_t *dbh = NULL;
 	int locked = 0;
 	char *key;
-
+	
 	switch_mutex_lock(dbh_mutex);
  top:
 	locked = 0;
@@ -74,11 +74,12 @@
 				diff = (time_t) prune - dbh->last_used;
 			}
 			
-			if (diff < SQL_CACHE_TIMEOUT) {
+			if (prune > 0 && diff < SQL_CACHE_TIMEOUT) {
 				continue;
 			}
 
 			if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping idle DB connection %s\n", key);
 				if (dbh->db) {
 					switch_core_db_close(dbh->db);
 					dbh->db = NULL;
@@ -113,18 +114,19 @@
 	}
 }
 
-SWITCH_DECLARE(switch_cache_db_handle_t *)switch_cache_db_get_db_handle(const char *db_name, const char *odbc_user, const char *odbc_pass)
+SWITCH_DECLARE(switch_status_t)switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh,
+															 const char *db_name, const char *odbc_user, const char *odbc_pass)
 {
 	switch_thread_id_t self = switch_thread_self();
 	char thread_str[256] = "";
-	switch_cache_db_handle_t *dbh = NULL;
+	switch_cache_db_handle_t *new_dbh = NULL;
 	
 	switch_assert(db_name);
 
 	snprintf(thread_str, sizeof(thread_str) - 1, "%s_%lu", db_name, (unsigned long)(intptr_t)self);
 
 	switch_mutex_lock(dbh_mutex);
-	if (!(dbh = switch_core_hash_find(dbh_hash, thread_str))) {
+	if (!(new_dbh = switch_core_hash_find(dbh_hash, thread_str))) {
 		switch_memory_pool_t *pool = NULL;
 		switch_core_db_t *db = NULL;
 		switch_odbc_handle_t *odbc_dbh = NULL;
@@ -145,83 +147,96 @@
 		}
 
 		switch_core_new_memory_pool(&pool);
-		dbh = switch_core_alloc(pool, sizeof(*dbh));
-		dbh->pool = pool;
+		new_dbh = switch_core_alloc(pool, sizeof(*new_dbh));
+		new_dbh->pool = pool;
 
 		
-		if (db) dbh->db = db; else dbh->odbc_dbh = odbc_dbh;
-		switch_mutex_init(&dbh->mutex, SWITCH_MUTEX_NESTED, dbh->pool);
-		switch_mutex_lock(dbh->mutex);
+		if (db) new_dbh->db = db; else new_dbh->odbc_dbh = odbc_dbh;
+		switch_mutex_init(&new_dbh->mutex, 0, new_dbh->pool);
+		switch_mutex_lock(new_dbh->mutex);
 
-		switch_core_hash_insert(dbh_hash, thread_str, dbh);
+		switch_core_hash_insert(dbh_hash, thread_str, new_dbh);
 	}
 
  end:
 
-	if (dbh) dbh->last_used = switch_epoch_time_now(NULL);
+	if (new_dbh) new_dbh->last_used = switch_epoch_time_now(NULL);
 
 	switch_mutex_unlock(dbh_mutex);
 
-	return dbh;
+	*dbh = new_dbh;
+
+	return *dbh ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
 }
 
 
 
-SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, char *sql)
+SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, char *sql, char **err)
 {
 	switch_status_t status = SWITCH_STATUS_FALSE;
+	char *errmsg = NULL;
 
+	if (err) *err = NULL;
+
 	if (switch_odbc_available() && dbh->odbc_dbh) {
 		switch_odbc_statement_handle_t stmt;
 		if ((status = switch_odbc_handle_exec(dbh->odbc_dbh, sql, &stmt)) != SWITCH_ODBC_SUCCESS) {
-			char *err_str;
-			err_str = switch_odbc_handle_get_error(dbh->odbc_dbh, stmt);
-			if (!zstr(err_str)) {
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, err_str);
-			}
-			switch_safe_free(err_str);
+			errmsg = switch_odbc_handle_get_error(dbh->odbc_dbh, stmt);
 		}
 		switch_odbc_statement_handle_free(&stmt);
 	} else {
-		char *errmsg;
-
         status = switch_core_db_exec(dbh->db, sql, NULL, NULL, &errmsg);
+	}
 
-        if (errmsg) {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n%s\n", errmsg, sql);
-            switch_core_db_free(errmsg);
-        }
-		
+	if (errmsg) {
+		if (!switch_stristr("already exists", errmsg)) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n%s\n", errmsg, sql);
+		}
+		if (err) {
+			*err = errmsg;
+		} else {
+			free(errmsg);
+		}
 	}
-
+	
 	return status;
 
 }
 
-SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, 
-																	 char *sql, switch_core_db_callback_func_t callback, void *pdata)
-	
+SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries)
 {
+	char *errmsg = NULL;
 	switch_status_t status = SWITCH_STATUS_FALSE;
-	char *errmsg = NULL;
-	
-	if (switch_odbc_available() && dbh->odbc_dbh) {
-		status = switch_odbc_handle_callback_exec(dbh->odbc_dbh, sql, callback, pdata);
-	} else {
-		status = switch_core_db_exec(dbh->db, sql, callback, pdata, &errmsg);
-		
+	uint8_t forever = 0;
+
+	if (!retries) {
+		forever = 1;
+		retries = 1000;
+	}
+
+	while (retries > 0) {
+		switch_cache_db_execute_sql(dbh, sql, &errmsg);
 		if (errmsg) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
-			free(errmsg);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
+			switch_safe_free(errmsg);
+			switch_yield(100000);
+			retries--;
+			if (retries == 0 && forever) {
+				retries = 1000;
+				continue;
+			}
+		} else {
+			status = SWITCH_STATUS_SUCCESS;
+			break;
 		}
 	}
 
 	return status;
 }
 
-static switch_status_t switch_core_db_persistant_execute_trans(switch_core_db_t *db, char *sql, uint32_t retries)
+SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries)
 {
-	char *errmsg;
+	char *errmsg = NULL;
 	switch_status_t status = SWITCH_STATUS_FALSE;
 	uint8_t forever = 0;
 	unsigned begin_retries = 100;
@@ -237,7 +252,7 @@
 	while (begin_retries > 0) {
 		again = 0;
 
-		switch_core_db_exec(db, "BEGIN", NULL, NULL, &errmsg);
+		switch_cache_db_execute_sql(dbh,  "BEGIN", &errmsg);
 
 		if (errmsg) {
 			begin_retries--;
@@ -246,11 +261,11 @@
 			} else {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL Retry [%s]\n", errmsg);
 			}
-			switch_core_db_free(errmsg);
+			free(errmsg);
 			errmsg = NULL;
 
 			if (again) {
-				switch_core_db_exec(db, "COMMIT", NULL, NULL, NULL);
+				switch_cache_db_execute_sql(dbh,  "COMMIT", NULL);
 				goto again;
 			}
 
@@ -266,10 +281,10 @@
 	}
 
 	while (retries > 0) {
-		switch_core_db_exec(db, sql, NULL, NULL, &errmsg);
+		switch_cache_db_execute_sql(dbh,  sql, &errmsg);
 		if (errmsg) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
-			switch_core_db_free(errmsg);
+			free(errmsg);
 			errmsg = NULL;
 			switch_yield(100000);
 			retries--;
@@ -285,45 +300,70 @@
 
 done:
 
-	switch_core_db_exec(db, "COMMIT", NULL, NULL, NULL);
+	switch_cache_db_execute_sql(dbh,  "COMMIT", NULL);
 
 	return status;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute(switch_core_db_t *db, char *sql, uint32_t retries)
+SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, 
+																	 char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err)
+	
 {
-	char *errmsg;
 	switch_status_t status = SWITCH_STATUS_FALSE;
-	uint8_t forever = 0;
+	char *errmsg = NULL;
 
-	if (!retries) {
-		forever = 1;
-		retries = 1000;
-	}
+	if (err) *err = NULL;
 
-	while (retries > 0) {
-		switch_core_db_exec(db, sql, NULL, NULL, &errmsg);
+	if (switch_odbc_available() && dbh->odbc_dbh) {
+		status = switch_odbc_handle_callback_exec(dbh->odbc_dbh, sql, callback, pdata, err);
+	} else {
+		status = switch_core_db_exec(dbh->db, sql, callback, pdata, &errmsg);
+		
 		if (errmsg) {
-			//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
-			switch_core_db_free(errmsg);
-			switch_yield(100000);
-			retries--;
-			if (retries == 0 && forever) {
-				retries = 1000;
-				continue;
-			}
-		} else {
-			status = SWITCH_STATUS_SUCCESS;
-			break;
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
+			free(errmsg);
 		}
 	}
 
 	return status;
 }
 
+SWITCH_DECLARE(void) switch_cache_db_test_reactive(switch_cache_db_handle_t *dbh, char *test_sql, char *drop_sql, char *reactive_sql)
+{
+	char *errmsg;
 
+	if (switch_odbc_available() && dbh->odbc_dbh) {
+		if (switch_odbc_handle_exec(dbh->odbc_dbh, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
+			switch_odbc_handle_exec(dbh->odbc_dbh, drop_sql, NULL);
+			switch_odbc_handle_exec(dbh->odbc_dbh, reactive_sql, NULL);
+		}
+	} else if (dbh->db) {
+		if (test_sql) {
+			switch_core_db_exec(dbh->db, test_sql, NULL, NULL, &errmsg);
 
+			if (errmsg) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\nAuto Generating Table!\n", errmsg, test_sql);
+				switch_core_db_free(errmsg);
+				errmsg = NULL;
+				if (drop_sql) {
+					switch_core_db_exec(dbh->db, drop_sql, NULL, NULL, &errmsg);
+				}
+				if (errmsg) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\n", errmsg, reactive_sql);
+					switch_core_db_free(errmsg);
+					errmsg = NULL;
+				}
+				switch_core_db_exec(dbh->db, reactive_sql, NULL, NULL, &errmsg);
+				if (errmsg) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\n", errmsg, reactive_sql);
+					switch_core_db_free(errmsg);
+					errmsg = NULL;
+				}
+			}
+		}
+	}
 
+}
 
 
 
@@ -340,24 +380,34 @@
 	switch_size_t newlen;
 	int lc = 0;
 	uint32_t loops = 0, sec = 0;
+	uint32_t l1 = 1000;
 
 	switch_assert(sqlbuf);
 
+	if (!sql_manager.manage) {
+		l1 = 10;
+	}
+
 	if (!sql_manager.event_db) {
-		sql_manager.event_db = switch_core_db_handle();
+		switch_core_db_handle(&sql_manager.event_db);
 	}
 
 	sql_manager.thread_running = 1;
 
-	for (;;) {
-		if (++loops == 1000) {
+	while(sql_manager.thread_running == 1) {
+		if (++loops == l1) {
 			if (++sec == SQL_CACHE_TIMEOUT) {
 				sql_close(switch_epoch_time_now(NULL));
 				sec = 0;
 			}
 			loops = 0;
 		}
-
+		
+		if (!sql_manager.manage) {
+			switch_yield(100000);
+			continue;
+		}
+		
 		if (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || 
 			switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) {
 			sql = (char *) pop;
@@ -396,7 +446,7 @@
 		
 		
 		if (trans && ((itterations == target) || (nothing_in_queue && ++lc >= 500))) {
-			if (switch_core_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 100) != SWITCH_STATUS_SUCCESS) {
+			if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 100) != SWITCH_STATUS_SUCCESS) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n");
 			}
 			itterations = 0;
@@ -421,6 +471,9 @@
 	}
 
 	free(sqlbuf);
+
+	sql_manager.thread_running = 0;
+
 	return NULL;
 }
 
@@ -432,45 +485,65 @@
 
 	switch (event->event_id) {
 	case SWITCH_EVENT_ADD_SCHEDULE:
-		sql = switch_mprintf("insert into tasks values('%q','%q','%q','%q')",
-							 switch_event_get_header_nil(event, "task-id"),
-							 switch_event_get_header_nil(event, "task-desc"),
-							 switch_event_get_header_nil(event, "task-group"), 
-							 switch_event_get_header_nil(event, "task-sql_manager")
-							 );
+		{
+			const char *id = switch_event_get_header(event, "task-id");
+			const char *manager = switch_event_get_header(event, "task-sql_manager");
+			
+			if (id) {
+				sql = switch_mprintf("insert into tasks values(%q,'%q','%q',%q, '%q')",
+									 id,
+									 switch_event_get_header_nil(event, "task-desc"),
+									 switch_event_get_header_nil(event, "task-group"), 
+									 manager ? manager : "0",
+									 switch_core_get_variable("hostname")
+									 );
+			}
+		}
 		break;
 	case SWITCH_EVENT_DEL_SCHEDULE:
 	case SWITCH_EVENT_EXE_SCHEDULE:
-		sql = switch_mprintf("delete from tasks where task_id=%q", switch_event_get_header_nil(event, "task-id"));
+		sql = switch_mprintf("delete from tasks where task_id=%q and hostname='%q'", 
+							 switch_event_get_header_nil(event, "task-id"), switch_core_get_variable("hostname"));
 		break;
 	case SWITCH_EVENT_RE_SCHEDULE:
-		sql = switch_mprintf("update tasks set task_desc='%q',task_group='%q', task_sql_manager='%q' where task_id=%q",
-							 switch_event_get_header_nil(event, "task-desc"), 
-							 switch_event_get_header_nil(event, "task-group"), 
-							 switch_event_get_header_nil(event, "task-sql_manager"), 
-							 switch_event_get_header_nil(event, "task-id"));
+		{
+			const char *id = switch_event_get_header(event, "task-id");
+			const char *manager = switch_event_get_header(event, "task-sql_manager");
+		
+			if (id) {
+				sql = switch_mprintf("update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q'",
+									 switch_event_get_header_nil(event, "task-desc"), 
+									 switch_event_get_header_nil(event, "task-group"), 
+									 manager ? manager : "0",
+									 id, switch_core_get_variable("hostname"));
+			}
+		}
 		break;
 	case SWITCH_EVENT_CHANNEL_DESTROY:
-		sql = switch_mprintf("delete from channels where uuid='%q'", switch_event_get_header_nil(event, "unique-id"));
+		sql = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'", 
+							 switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
 		break;
 	case SWITCH_EVENT_CHANNEL_UUID:
 		{
 			sql = switch_mprintf(
-								 "update channels set uuid='%q' where uuid='%q';"
-								 "update calls set caller_uuid='%q' where caller_uuid='%q';"
-								 "update calls set callee_uuid='%q' where callee_uuid='%q'",
+								 "update channels set uuid='%q' where uuid='%q' and hostname='%q';"
+								 "update calls set caller_uuid='%q' where caller_uuid='%q' and hostname='%q';"
+								 "update calls set callee_uuid='%q' where callee_uuid='%q' and hostname='%q'",
 								 switch_event_get_header_nil(event, "unique-id"),
 								 switch_event_get_header_nil(event, "old-unique-id"),
+								 switch_core_get_variable("hostname"),
 								 switch_event_get_header_nil(event, "unique-id"),
 								 switch_event_get_header_nil(event, "old-unique-id"),
+								 switch_core_get_variable("hostname"),
 								 switch_event_get_header_nil(event, "unique-id"),
-								 switch_event_get_header_nil(event, "old-unique-id")
+								 switch_event_get_header_nil(event, "old-unique-id"),
+								 switch_core_get_variable("hostname")
 								 );
 			break;
 		}
 	case SWITCH_EVENT_CHANNEL_CREATE:
-		sql = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,dialplan,context) "
-							 "values('%q','%q','%q','%ld','%q','%q','%q','%q')",
+		sql = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,dialplan,context,hostname) "
+							 "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q')",
 							 switch_event_get_header_nil(event, "unique-id"),
 							 switch_event_get_header_nil(event, "call-direction"),
 							 switch_event_get_header_nil(event, "event-date-local"),
@@ -478,24 +551,28 @@
 							 switch_event_get_header_nil(event, "channel-name"),
 							 switch_event_get_header_nil(event, "channel-state"),
 							 switch_event_get_header_nil(event, "caller-dialplan"),
-							 switch_event_get_header_nil(event, "caller-context")
+							 switch_event_get_header_nil(event, "caller-context"),
+							 switch_core_get_variable("hostname")
 							 );
 		break;
 	case SWITCH_EVENT_CODEC:
 		sql =
 			switch_mprintf
-			("update channels set read_codec='%q',read_rate='%q',write_codec='%q',write_rate='%q' where uuid='%q'",
+			("update channels set read_codec='%q',read_rate='%q',write_codec='%q',write_rate='%q' where uuid='%q' and hostname='%q'",
 			 switch_event_get_header_nil(event, "channel-read-codec-name"), 
 			 switch_event_get_header_nil(event, "channel-read-codec-rate"),
 			 switch_event_get_header_nil(event, "channel-write-codec-name"), 
 			 switch_event_get_header_nil(event, "channel-write-codec-rate"),
-			 switch_event_get_header_nil(event, "unique-id"));
+			 switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
 		break;
 	case SWITCH_EVENT_CHANNEL_EXECUTE:
-		sql = switch_mprintf("update channels set application='%q',application_data='%q' where uuid='%q'",
+		sql = switch_mprintf("update channels set application='%q',application_data='%q',"
+							 "presence_id='%q',presence_data='%q' where uuid='%q' and hostname='%q'",
 							 switch_event_get_header_nil(event, "application"),
 							 switch_event_get_header_nil(event, "application-data"), 
-							 switch_event_get_header_nil(event, "unique-id")
+							 switch_event_get_header_nil(event, "channel-presence-id"),
+							 switch_event_get_header_nil(event, "channel-presence-data"),
+							 switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")
 
 							 );
 
@@ -514,26 +591,30 @@
 			case CS_DESTROY:
 				break;
 			case CS_ROUTING:
-				sql = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',ip_addr='%s',dest='%q',dialplan='%q',context='%q' "
-									 "where uuid='%s'",
+				sql = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',"
+									 "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' "
+									 "where uuid='%s' and hostname='%q'",
 									 switch_event_get_header_nil(event, "channel-state"),
 									 switch_event_get_header_nil(event, "caller-caller-id-name"),
 									 switch_event_get_header_nil(event, "caller-caller-id-number"),
 									 switch_event_get_header_nil(event, "caller-network-addr"),
 									 switch_event_get_header_nil(event, "caller-destination-number"), 
 									 switch_event_get_header_nil(event, "caller-dialplan"), 
-									 switch_event_get_header_nil(event, "caller-context"), 
-									 switch_event_get_header_nil(event, "unique-id"));
+									 switch_event_get_header_nil(event, "caller-context"),
+									 switch_event_get_header_nil(event, "channel-presence-id"),
+									 switch_event_get_header_nil(event, "channel-presence-data"),
+									 switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
 				break;
 			default:
-				sql = switch_mprintf("update channels set state='%s' where uuid='%s'",
-									 switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "unique-id"));
+				sql = switch_mprintf("update channels set state='%s' where uuid='%s' and hostname='%q'",
+									 switch_event_get_header_nil(event, "channel-state"), 
+									 switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
 				break;
 			}
 			break;
 		}
 	case SWITCH_EVENT_CHANNEL_BRIDGE:
-		sql = switch_mprintf("insert into calls values ('%s', '%ld', '%s','%q','%q','%q','%q','%s','%q','%q','%q','%q','%s')",
+		sql = switch_mprintf("insert into calls values ('%s', '%ld', '%s','%q','%q','%q','%q','%s','%q','%q','%q','%q','%s','%q')",
 							 switch_event_get_header_nil(event, "event-date-local"),
 							 (long)switch_epoch_time_now(NULL),
 							 switch_event_get_header_nil(event, "event-calling-function"),
@@ -545,14 +626,23 @@
 							 switch_event_get_header_nil(event, "Other-Leg-caller-id-name"),
 							 switch_event_get_header_nil(event, "Other-Leg-caller-id-number"),
 							 switch_event_get_header_nil(event, "Other-Leg-destination-number"),
-							 switch_event_get_header_nil(event, "Other-Leg-channel-name"), switch_event_get_header_nil(event, "Other-Leg-unique-id")
+							 switch_event_get_header_nil(event, "Other-Leg-channel-name"), 
+							 switch_event_get_header_nil(event, "Other-Leg-unique-id"),
+							 switch_core_get_variable("hostname")
 			);
 		break;
 	case SWITCH_EVENT_CHANNEL_UNBRIDGE:
-		sql = switch_mprintf("delete from calls where caller_uuid='%s'", switch_event_get_header_nil(event, "caller-unique-id"));
+		sql = switch_mprintf("delete from calls where caller_uuid='%s' and hostname='%q'", 
+							 switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname"));
 		break;
 	case SWITCH_EVENT_SHUTDOWN:
-		sql = switch_mprintf("delete from channels;delete from interfaces;delete from calls");
+		sql = switch_mprintf("delete from channels where hostname='%q';"
+							 "delete from interfaces where hostname='%q';"
+							 "delete from calls where hostname='%q'",
+							 switch_core_get_variable("hostname"),
+							 switch_core_get_variable("hostname"),
+							 switch_core_get_variable("hostname")
+							 );
 		break;
 	case SWITCH_EVENT_LOG:
 		return;
@@ -566,9 +656,10 @@
 			const char *filename = switch_event_get_header_nil(event, "filename");
 			if (!zstr(type) && !zstr(name)) {
 				sql =
-					switch_mprintf("insert into interfaces (type,name,description,syntax,key,filename) values('%q','%q','%q','%q','%q','%q')",
-								   type, name, switch_str_nil(description), switch_str_nil(syntax), switch_str_nil(key), switch_str_nil(filename)
-					);
+					switch_mprintf("insert into interfaces (type,name,description,syntax,key,filename,hostname) values('%q','%q','%q','%q','%q','%q','%q')",
+								   type, name, switch_str_nil(description), switch_str_nil(syntax), 
+								   switch_str_nil(key), switch_str_nil(filename), switch_core_get_variable("hostname")
+								   );
 			}
 			break;
 		}
@@ -577,7 +668,8 @@
 			const char *type = switch_event_get_header_nil(event, "type");
 			const char *name = switch_event_get_header_nil(event, "name");
 			if (!zstr(type) && !zstr(name)) {
-				sql = switch_mprintf("delete from interfaces where type='%q' and name='%q'", type, name);
+				sql = switch_mprintf("delete from interfaces where type='%q' and name='%q' and hostname='%q'", type, name, 
+									 switch_core_get_variable("hostname"));
 			}
 			break;
 		}
@@ -588,9 +680,11 @@
 			if (zstr(type)) {
 				break;
 			}
-			sql = switch_mprintf("update channels set secure='%s' where uuid='%s'",
+			sql = switch_mprintf("update channels set secure='%s' where uuid='%s' and hostname='%q'",
 								 type,
-								 switch_event_get_header_nil(event, "caller-unique-id"));
+								 switch_event_get_header_nil(event, "caller-unique-id"),
+								 switch_core_get_variable("hostname")
+								 );
 			break;
 		}
 	case SWITCH_EVENT_NAT:
@@ -598,14 +692,17 @@
 			const char *op = switch_event_get_header_nil(event, "op");
 			switch_bool_t sticky = switch_true(switch_event_get_header_nil(event, "sticky"));
 			if (!strcmp("add", op)) {
-				sql = switch_mprintf("insert into nat (port, proto, sticky) values (%s, %s, %d)",
-									switch_event_get_header_nil(event, "port"),
-									switch_event_get_header_nil(event, "proto"),
-									sticky);
+				sql = switch_mprintf("insert into nat (port, proto, sticky, hostname) values (%s, %s, %d,'%q')",
+									 switch_event_get_header_nil(event, "port"),
+									 switch_event_get_header_nil(event, "proto"),
+									 sticky,
+									 switch_core_get_variable("hostname")
+									 );
 			} else if (!strcmp("del", op)) {
-				sql = switch_mprintf("delete from nat where port=%s and proto=%s",
-									switch_event_get_header_nil(event, "port"),
-									switch_event_get_header_nil(event, "proto"));
+				sql = switch_mprintf("delete from nat where port=%s and proto=%s and hostname='%q'",
+									 switch_event_get_header_nil(event, "port"),
+									 switch_event_get_header_nil(event, "proto"),
+									 switch_core_get_variable("hostname"));
 			} else if (!strcmp("status", op)) {
 				/* call show nat api */
 			} else if (!strcmp("status_response", op)) {
@@ -629,146 +726,219 @@
 	}
 }
 
-void switch_core_sqldb_start(switch_memory_pool_t *pool)
+
+static char create_complete_sql[] =
+	"CREATE TABLE complete (\n"
+	"   sticky  INTEGER,\n" 
+	"   a1  VARCHAR(4096),\n" 
+	"   a2  VARCHAR(4096),\n" 
+	"   a3  VARCHAR(4096),\n" 
+	"   a4  VARCHAR(4096),\n" 
+	"   a5  VARCHAR(4096),\n" 
+	"   a6  VARCHAR(4096),\n" 
+	"   a7  VARCHAR(4096),\n" 
+	"   a8  VARCHAR(4096),\n" 
+	"   a9  VARCHAR(4096),\n" 
+	"   a10 VARCHAR(4096),\n" 
+	"   hostname VARCHAR(4096)\n" 
+	");\n";
+
+static char create_alias_sql[] =
+	"CREATE TABLE aliases (\n"
+	"   sticky  INTEGER,\n" 
+	"   alias  VARCHAR(4096),\n" 
+	"   command  VARCHAR(4096),\n" 
+	"   hostname VARCHAR(4096)\n" 
+	");\n";
+
+static char create_channels_sql[] =
+	"CREATE TABLE channels (\n"
+	"   uuid  VARCHAR(4096),\n"
+	"   direction  VARCHAR(4096),\n"
+	"   created  VARCHAR(4096),\n"
+	"   created_epoch  INTEGER,\n"
+	"   name  VARCHAR(4096),\n"
+	"   state  VARCHAR(4096),\n"
+	"   cid_name  VARCHAR(4096),\n"
+	"   cid_num  VARCHAR(4096),\n"
+	"   ip_addr  VARCHAR(4096),\n"
+	"   dest  VARCHAR(4096),\n"
+	"   application  VARCHAR(4096),\n"
+	"   application_data  VARCHAR(4096),\n"
+	"   dialplan VARCHAR(4096),\n"
+	"   context VARCHAR(4096),\n"
+	"   read_codec  VARCHAR(4096),\n" 
+	"   read_rate  VARCHAR(4096),\n" 
+	"   write_codec  VARCHAR(4096),\n" 
+	"   write_rate  VARCHAR(4096),\n" 
+	"   secure VARCHAR(4096),\n"
+	"   hostname VARCHAR(4096),\n" 
+	"   presence_id VARCHAR(4096),\n" 
+	"   presence_data VARCHAR(4096)\n" 
+	");\ncreate index uuindex on channels (uuid,hostname);\n";
+static char create_calls_sql[] =
+	"CREATE TABLE calls (\n"
+	"   call_created  VARCHAR(4096),\n"
+	"   call_created_epoch  INTEGER,\n"
+	"   function  VARCHAR(4096),\n"
+	"   caller_cid_name  VARCHAR(4096),\n"
+	"   caller_cid_num   VARCHAR(4096),\n"
+	"   caller_dest_num  VARCHAR(4096),\n"
+	"   caller_chan_name VARCHAR(4096),\n"
+	"   caller_uuid      VARCHAR(4096),\n"
+	"   callee_cid_name  VARCHAR(4096),\n"
+	"   callee_cid_num   VARCHAR(4096),\n"
+	"   callee_dest_num  VARCHAR(4096),\n" 
+	"   callee_chan_name VARCHAR(4096),\n" 
+	"   callee_uuid      VARCHAR(4096),\n" 
+	"   hostname VARCHAR(4096)\n" 
+	");\n"
+	"create index eruuindex on calls (caller_uuid,hostname);\n"
+	"create index eeuuindex on calls (callee_uuid,hostname);\n";
+static char create_interfaces_sql[] =
+	"CREATE TABLE interfaces (\n"
+	"   type             VARCHAR(4096),\n"
+	"   name             VARCHAR(4096),\n" 
+	"   description      VARCHAR(4096),\n" 
+	"   key              VARCHAR(4096),\n" 
+	"   filename         VARCHAR(4096),\n" 
+	"   syntax           VARCHAR(4096),\n" 
+	"   hostname VARCHAR(4096)\n" 
+	");\n";
+static char create_tasks_sql[] =
+	"CREATE TABLE tasks (\n"
+	"   task_id             INTEGER,\n"
+	"   task_desc           VARCHAR(4096),\n" 
+	"   task_group          VARCHAR(4096),\n" 
+	"   task_sql_manager    INTEGER,\n" 
+	"   hostname VARCHAR(4096)\n" 
+	");\n";
+static char create_nat_sql[] = 
+	"CREATE TABLE nat (\n"
+	"   sticky  INTEGER,\n" 
+	"	port	INTEGER,\n"
+	"	proto	INTEGER,\n"
+	"   hostname VARCHAR(4096)\n" 
+	");\n";
+
+switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage)
 {
 	switch_threadattr_t *thd_attr;
+	switch_cache_db_handle_t *dbh;
 
 	sql_manager.memory_pool = pool;
-
+	sql_manager.manage = manage;
+	
 	switch_mutex_init(&dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
 	switch_core_hash_init(&dbh_hash, sql_manager.memory_pool);
 
+ top:
+	
 	/* Activate SQL database */
-	if ((sql_manager.db = switch_core_db_handle()) == 0) {
+	if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n");
+
+		if (runtime.odbc_dsn) {
+			runtime.odbc_dsn = NULL;
+			runtime.odbc_user = NULL;
+			runtime.odbc_pass = NULL;
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to sqlite.\n");
+			goto top;
+		}
+
+
 		switch_clear_flag((&runtime), SCF_USE_SQL);
+		return SWITCH_STATUS_FALSE;
+	}
+
+	
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n");
+	if (dbh->db) {
+		switch_cache_db_execute_sql(dbh, "drop table channels", NULL);
+		switch_cache_db_execute_sql(dbh, "drop table calls", NULL);
+		switch_cache_db_execute_sql(dbh, "drop table interfaces", NULL);
+		switch_cache_db_execute_sql(dbh, "drop table tasks", NULL);
+		switch_cache_db_execute_sql(dbh, "PRAGMA synchronous=OFF;", NULL);
+		switch_cache_db_execute_sql(dbh, "PRAGMA count_changes=OFF;", NULL);
+		switch_cache_db_execute_sql(dbh, "PRAGMA cache_size=8000", NULL);
+		switch_cache_db_execute_sql(dbh, "PRAGMA temp_store=MEMORY;", NULL);
 	} else {
-		char create_complete_sql[] =
-			"CREATE TABLE complete (\n"
-			"   sticky  INTEGER,\n" 
-			"   a1  VARCHAR(255),\n" 
-			"   a2  VARCHAR(255),\n" 
-			"   a3  VARCHAR(255),\n" 
-			"   a4  VARCHAR(255),\n" 
-			"   a5  VARCHAR(255),\n" 
-			"   a6  VARCHAR(255),\n" 
-			"   a7  VARCHAR(255),\n" 
-			"   a8  VARCHAR(255),\n" 
-			"   a9  VARCHAR(255),\n" 
-			"   a10 VARCHAR(255)\n" 
-			");\n";
+		char sql[512] = "";
+		char *tables[] = {"channels", "calls", "interfaces", "tasks", NULL};
+		int i;
+		const char *hostname = switch_core_get_variable("hostname");
 
-		char create_alias_sql[] =
-			"CREATE TABLE aliases (\n"
-			"   sticky  INTEGER,\n" 
-			"   alias  VARCHAR(255),\n" 
-			"   command  VARCHAR(255)\n" 
-			");\n";
+		for(i = 0; tables[i]; i++) {
+			switch_snprintf(sql, sizeof(sql), "delete from %s where hostname='%s'", tables[i], hostname);
+			switch_cache_db_execute_sql(dbh, sql, NULL);
+		}
+	}
 
-		char create_channels_sql[] =
-			"CREATE TABLE channels (\n"
-			"   uuid  VARCHAR(255),\n"
-			"   direction  VARCHAR(255),\n"
-			"   created  VARCHAR(255),\n"
-			"   created_epoch  INTEGER,\n"
-			"   name  VARCHAR(255),\n"
-			"   state  VARCHAR(255),\n"
-			"   cid_name  VARCHAR(255),\n"
-			"   cid_num  VARCHAR(255),\n"
-			"   ip_addr  VARCHAR(255),\n"
-			"   dest  VARCHAR(255),\n"
-			"   application  VARCHAR(255),\n"
-			"   application_data  VARCHAR(255),\n"
-			"   dialplan VARCHAR(255),\n"
-			"   context VARCHAR(255),\n"
-			"   read_codec  VARCHAR(255),\n" 
-			"   read_rate  VARCHAR(255),\n" 
-			"   write_codec  VARCHAR(255),\n" 
-			"   write_rate  VARCHAR(255),\n" 
-			"   secure VARCHAR(255)\n"
-			");\ncreate index uuindex on channels (uuid);\n";
-		char create_calls_sql[] =
-			"CREATE TABLE calls (\n"
-			"   call_created  VARCHAR(255),\n"
-			"   call_created_epoch  INTEGER,\n"
-			"   function  VARCHAR(255),\n"
-			"   caller_cid_name  VARCHAR(255),\n"
-			"   caller_cid_num   VARCHAR(255),\n"
-			"   caller_dest_num  VARCHAR(255),\n"
-			"   caller_chan_name VARCHAR(255),\n"
-			"   caller_uuid      VARCHAR(255),\n"
-			"   callee_cid_name  VARCHAR(255),\n"
-			"   callee_cid_num   VARCHAR(255),\n"
-			"   callee_dest_num  VARCHAR(255),\n" 
-			"   callee_chan_name VARCHAR(255),\n" 
-			"   callee_uuid      VARCHAR(255)\n" 
-			");\n"
-			"create index eruuindex on calls (caller_uuid);\n"
-			"create index eeuuindex on calls (callee_uuid);\n";
-		char create_interfaces_sql[] =
-			"CREATE TABLE interfaces (\n"
-			"   type             VARCHAR(255),\n"
-			"   name             VARCHAR(255),\n" 
-			"   description      VARCHAR(255),\n" 
-			"   key              VARCHAR(255),\n" 
-			"   filename         VARCHAR(255),\n" 
-			"   syntax           VARCHAR(255)\n" 
-			");\n";
-		char create_tasks_sql[] =
-			"CREATE TABLE tasks (\n"
-			"   task_id             INTEGER(4),\n"
-			"   task_desc           VARCHAR(255),\n" 
-			"   task_group          VARCHAR(255),\n" 
-			"   task_sql_manager    INTEGER(8)\n" 
-			");\n";
-		char create_nat_sql[] = 
-			"CREATE TABLE nat (\n"
-			"   sticky  INTEGER,\n" 
-			"	port	INTEGER,\n"
-			"	proto	INTEGER\n"
-			");\n";
+		
+	switch_cache_db_test_reactive(dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql);
+	switch_cache_db_test_reactive(dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql);
+	switch_cache_db_test_reactive(dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql);
 
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n");
-		switch_core_db_exec(sql_manager.db, "drop table channels", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "drop table calls", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "drop table interfaces", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "drop table tasks", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "PRAGMA synchronous=OFF;", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "PRAGMA count_changes=OFF;", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "PRAGMA cache_size=8000", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "PRAGMA temp_store=MEMORY;", NULL, NULL, NULL);
 
-		switch_core_db_test_reactive(sql_manager.db, "select sticky from complete", "DROP TABLE complete", create_complete_sql);
-		switch_core_db_test_reactive(sql_manager.db, "select sticky from aliases", "DROP TABLE aliases", create_alias_sql);
-		switch_core_db_test_reactive(sql_manager.db, "select sticky from nat", "DROP TABLE nat", create_nat_sql);
-		switch_core_db_exec(sql_manager.db, "delete from complete where sticky=0", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "delete from aliases where sticky=0", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "delete from nat where sticky=0", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists alias1 on aliases (alias)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete1 on complete (a1)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete2 on complete (a2)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete3 on complete (a3)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete4 on complete (a4)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete5 on complete (a5)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete6 on complete (a6)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete7 on complete (a7)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete8 on complete (a8)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete9 on complete (a9)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create index if not exists complete10 on complete (a10)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, "create unique index if not exists nat_map_port_proto on nat (port,proto)", NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, create_channels_sql, NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, create_calls_sql, NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, create_interfaces_sql, NULL, NULL, NULL);
-		switch_core_db_exec(sql_manager.db, create_tasks_sql, NULL, NULL, NULL);
+	if (dbh->odbc_dbh) {
+		char *err;
 
-		if (switch_event_bind_removable("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL, &sql_manager.event_node) != SWITCH_STATUS_SUCCESS) {
+		switch_cache_db_execute_sql(dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err);
+
+		if (err) {
+			runtime.odbc_dsn = NULL;
+			runtime.odbc_user = NULL;
+			runtime.odbc_pass = NULL;
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling ODBC\n");
+			switch_cache_db_release_db_handle(&dbh);
+			free(err);
+			goto top;
+		}
+	}
+
+
+	if (dbh->db) {
+		switch_cache_db_execute_sql(dbh, create_channels_sql, NULL);
+		switch_cache_db_execute_sql(dbh, create_calls_sql, NULL);
+		switch_cache_db_execute_sql(dbh, create_interfaces_sql, NULL);
+		switch_cache_db_execute_sql(dbh, create_tasks_sql, NULL);
+	} else {
+		switch_cache_db_test_reactive(dbh, "select hostname from channels", "DROP TABLE channels", create_channels_sql);
+		switch_cache_db_test_reactive(dbh, "select hostname from calls", "DROP TABLE calls", create_calls_sql);
+		switch_cache_db_test_reactive(dbh, "select hostname from interfaces", "DROP TABLE interfaces", create_interfaces_sql);
+		switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql);
+		
+	}
+
+	switch_cache_db_execute_sql(dbh, "delete from complete where sticky=0", NULL);
+	switch_cache_db_execute_sql(dbh, "delete from aliases where sticky=0", NULL);
+	switch_cache_db_execute_sql(dbh, "delete from nat where sticky=0", NULL);
+	switch_cache_db_execute_sql(dbh, "create index alias1 on aliases (alias)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete1 on complete (a1,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete2 on complete (a2,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete3 on complete (a3,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete4 on complete (a4,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete5 on complete (a5,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete6 on complete (a6,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete7 on complete (a7,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete8 on complete (a8,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete9 on complete (a9,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index complete10 on complete (a10,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create unique index nat_map_port_proto on nat (port,proto,hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index channels1 on channels(hostname)", NULL);
+	switch_cache_db_execute_sql(dbh, "create index calls1 on calls(hostname)", NULL);
+
+
+	if (sql_manager.manage) {
+		if (switch_event_bind_removable("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, 
+										core_event_handler, NULL, &sql_manager.event_node) != SWITCH_STATUS_SUCCESS) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event handler!\n");
 		}
+
+		switch_queue_create(&sql_manager.sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool);
+		switch_queue_create(&sql_manager.sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool);
 	}
 
-	switch_queue_create(&sql_manager.sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool);
-	switch_queue_create(&sql_manager.sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool);
-
 	switch_threadattr_create(&thd_attr, sql_manager.memory_pool);
 	switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
 	switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool);
@@ -776,6 +946,10 @@
 	while (!sql_manager.thread_running) {
 		switch_yield(10000);
 	}
+	
+	switch_cache_db_release_db_handle(&dbh);
+
+	return SWITCH_STATUS_SUCCESS;
 }
 
 void switch_core_sqldb_stop(void)
@@ -783,17 +957,23 @@
 	switch_status_t st;
 
 	switch_event_unbind(&sql_manager.event_node);
+	
+	switch_cache_db_release_db_handle(&sql_manager.event_db);
+	sql_close(0);
 
-	switch_queue_push(sql_manager.sql_queue[0], NULL);
-	switch_queue_push(sql_manager.sql_queue[1], NULL);
+	if (sql_manager.thread && sql_manager.thread_running) {
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n");
-	switch_thread_join(&st, sql_manager.thread);
-	sql_close(0);
+		if (sql_manager.manage) {
+			switch_queue_push(sql_manager.sql_queue[0], NULL);
+			switch_queue_push(sql_manager.sql_queue[1], NULL);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n");
+		}
 
-	switch_core_db_close(sql_manager.db);
-	switch_core_db_close(sql_manager.event_db);
+		sql_manager.thread_running = -1;
+		switch_thread_join(&st, sql_manager.thread);
+	}
 
+
 	switch_core_hash_destroy(&dbh_hash);
 
 }

Modified: freeswitch/trunk/src/switch_odbc.c (15486 => 15487)


--- freeswitch/trunk/src/switch_odbc.c	2009-11-16 21:14:38 UTC (rev 15486)
+++ freeswitch/trunk/src/switch_odbc.c	2009-11-17 00:12:54 UTC (rev 15487)
@@ -424,7 +424,7 @@
 
 SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(const char *file, const char *func, int line,
 																			   switch_odbc_handle_t *handle,
-																			   char *sql, switch_core_db_callback_func_t callback, void *pdata)
+																			   char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err)
 {
 #ifdef SWITCH_HAVE_ODBC
 	SQLHSTMT stmt = NULL;
@@ -432,7 +432,6 @@
 	SQLLEN m = 0, t = 0;
 	char *err_str = NULL;
 	int result;
-	int err = 0;
 	
 	switch_assert(callback != NULL);
 
@@ -441,12 +440,12 @@
 	}
 
 	if (SQLAllocHandle(SQL_HANDLE_STMT, handle->con, &stmt) != SQL_SUCCESS) {
-		err_str = "Unable to SQL allocate handle.";
+		err_str = strdup("Unable to SQL allocate handle.");
 		goto error;
 	}
 
 	if (SQLPrepare(stmt, (unsigned char *) sql, SQL_NTS) != SQL_SUCCESS) {
-		err_str = "Unable to prepare SQL statement.";
+		err_str = strdup("Unable to prepare SQL statement.");
 		goto error;
 	}
 
@@ -517,27 +516,24 @@
 	
 	SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
-	if (!err) {
-		return SWITCH_ODBC_SUCCESS;
-	}
-
  error:
 
-	/* err_str is already defined  for some error cases */
-	if (err_str != NULL) {
-		switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
-		err_str = NULL;
-	}
-	
 	if (stmt) {
 		err_str = switch_odbc_handle_get_error(handle, stmt);
-		if (!zstr(err_str)) {
-			switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
-		}
-		switch_safe_free(err_str);
 		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 	}
 
+	if (err_str) {
+		switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
+		if (err) {
+			*err = err_str;
+		} else {
+			*err = NULL;
+			free(err_str);
+		}
+	}
+	
+
 #endif
 	return SWITCH_ODBC_FAIL;
 }