mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-13 15:50:59 +00:00
FS-2050 Core ODBC support for transactions with MSSQL
This commit is contained in:
parent
fd1736b38f
commit
d2ca8d4046
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
/*!
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user