FS-2050 Core ODBC support for transactions with MSSQL

This commit is contained in:
Jeff Lenk 2010-10-21 16:18:54 -05:00
parent fd1736b38f
commit d2ca8d4046
6 changed files with 85 additions and 6 deletions

View File

@ -86,6 +86,7 @@
<!-- <param name="core-db-dsn" value="dsn:username:password" /> -->
<!-- The system will create all the db schemas automatically, set this to false to avoid this behaviour-->
<!--<param name="auto-create-schemas" value="true"/>-->
<!-- <param name="core-dbtype" value="MSSQL"/> -->
</settings>
</configuration>

View File

@ -193,6 +193,11 @@ struct switch_media_bug {
struct switch_media_bug *next;
};
typedef enum {
DBTYPE_DEFAULT = 0,
DBTYPE_MSSQL = 1,
} switch_dbtype_t;
struct switch_runtime {
switch_time_t initiated;
switch_time_t reference;
@ -237,6 +242,7 @@ struct switch_runtime {
double min_idle_time;
int sql_buffer_len;
int max_sql_buffer_len;
switch_dbtype_t odbc_dbtype;
};
extern struct switch_runtime runtime;

View File

@ -58,6 +58,8 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_
char **err);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec_string(switch_odbc_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err);
SWITCH_DECLARE(switch_bool_t) switch_odbc_available(void);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_SQLSetAutoCommitAttr(switch_odbc_handle_t *handle, switch_bool_t on);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_SQLEndTran(switch_odbc_handle_t *handle, switch_bool_t commit);
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_statement_handle_free(switch_odbc_statement_handle_t *stmt);
/*!

View File

@ -1237,6 +1237,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION;
runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION;
runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION;
runtime.odbc_dbtype = DBTYPE_DEFAULT;
/* INIT APR and Create the pool context */
if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
@ -1590,6 +1591,12 @@ static void switch_load_core_config(const char *file)
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
}
} else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) {
if (!strcasecmp(val, "MSSQL")) {
runtime.odbc_dbtype = DBTYPE_MSSQL;
} else {
runtime.odbc_dbtype = DBTYPE_DEFAULT;
}
#ifdef ENABLE_ZRTP
} else if (!strcasecmp(var, "rtp-enable-zrtp")) {
switch_core_set_variable("zrtp_enabled", val);

View File

@ -699,7 +699,13 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_
while (begin_retries > 0) {
again = 0;
switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg);
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg);
} else {
if (switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 0) != SWITCH_ODBC_SUCCESS) {
errmsg = strdup("Unable to Set AutoCommit Off.");;
}
}
if (errmsg) {
begin_retries--;
@ -712,7 +718,13 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_
errmsg = NULL;
if (again) {
switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
} else {
switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1);
switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
}
goto again;
}
@ -750,7 +762,12 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_
done:
switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
} else {
switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1);
switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
}
if (dbh->io_mutex) {
switch_mutex_unlock(dbh->io_mutex);
@ -1304,6 +1321,7 @@ static void core_event_handler(switch_event_t *event)
case SWITCH_EVENT_CHANNEL_BRIDGE:
{
const char *callee_cid_name, *callee_cid_num, *direction;
char *func_name;
direction = switch_event_get_header(event, "other-leg-direction");
@ -1319,10 +1337,19 @@ static void core_event_handler(switch_event_t *event)
new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s' and hostname='%q'",
switch_event_get_header_nil(event, "channel-call-uuid"),
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
new_sql() = switch_mprintf("insert into calls (call_uuid,call_created,call_created_epoch,function,caller_cid_name,"
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
func_name = "function";
}
else {
func_name = "call_function";
}
new_sql() = switch_mprintf("insert into calls (call_uuid,call_created,call_created_epoch,%s,caller_cid_name,"
"caller_cid_num,caller_dest_num,caller_chan_name,caller_uuid,callee_cid_name,"
"callee_cid_num,callee_dest_num,callee_chan_name,callee_uuid,hostname) "
"values ('%s', '%s', '%ld', '%s','%q','%q','%q','%q','%s','%q','%q','%q','%q','%s','%q')",
func_name,
switch_event_get_header_nil(event, "channel-call-uuid"),
switch_event_get_header_nil(event, "event-date-local"),
(long) switch_epoch_time_now(NULL),
@ -1622,11 +1649,21 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
{
char *err;
switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate from channels", "DROP TABLE channels", create_channels_sql);
switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql);
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql);
} else {
char *tmp = switch_string_replace(create_calls_sql, "function", "call_function");
switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", tmp);
free(tmp);
}
switch_cache_db_test_reactive(dbh, "select ikey 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, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err);
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
switch_cache_db_execute_sql(dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err);
} else {
switch_cache_db_execute_sql(dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err);
}
if (err) {
runtime.odbc_dsn = NULL;

View File

@ -629,6 +629,32 @@ SWITCH_DECLARE(switch_bool_t) switch_odbc_available(void)
#endif
}
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_SQLSetAutoCommitAttr(switch_odbc_handle_t *handle, switch_bool_t on)
{
#ifdef SWITCH_HAVE_ODBC
if (on) {
return SQLSetConnectAttr(handle->con, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER *) SQL_AUTOCOMMIT_ON, 0 );
} else {
return SQLSetConnectAttr(handle->con, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER *) SQL_AUTOCOMMIT_OFF, 0 );
}
#else
return SWITCH_FALSE;
#endif
}
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_SQLEndTran(switch_odbc_handle_t *handle, switch_bool_t commit)
{
#ifdef SWITCH_HAVE_ODBC
if (commit) {
return SQLEndTran(SQL_HANDLE_DBC, handle->con, SQL_COMMIT);
} else {
return SQLEndTran(SQL_HANDLE_DBC, handle->con, SQL_ROLLBACK);
}
#else
return SWITCH_FALSE;
#endif
}
/* For Emacs:
* Local Variables: