add support for running core-db over odbc

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15487 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-11-17 00:12:54 +00:00
parent 220ebe8175
commit 5d815cfdfe
18 changed files with 692 additions and 346 deletions

View File

@ -207,11 +207,14 @@ struct switch_runtime {
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);

View File

@ -1415,6 +1415,7 @@ SWITCH_DECLARE(switch_core_db_t *) switch_core_db_open_file(const char *filename
*/
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(switch_status_t) switch_core_db_persistant_execute(switch_core_db
*/
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,12 +1925,16 @@ typedef struct {
} 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

View File

@ -77,7 +77,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_statement_handle_free(switch_od
\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 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
\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);

View File

@ -186,7 +186,7 @@ static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_ca
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 {

View File

@ -2914,7 +2914,7 @@ SWITCH_STANDARD_API(show_function)
{
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_STANDARD_API(show_function)
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 @@ SWITCH_STANDARD_API(show_function)
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 @@ SWITCH_STANDARD_API(show_function)
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_STANDARD_API(show_function)
switch_safe_free(mydata);
if (db) {
switch_core_db_close(db);
switch_cache_db_release_db_handle(&db);
}
return status;

View File

@ -336,7 +336,7 @@ SWITCH_STANDARD_APP(eavesdrop_function)
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 @@ SWITCH_STANDARD_APP(eavesdrop_function)
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 @@ SWITCH_STANDARD_APP(eavesdrop_function)
}
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);

View File

@ -339,7 +339,7 @@ static switch_bool_t fifo_execute_sql_callback(switch_mutex_t *mutex, char *sql,
}
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);

View File

@ -138,7 +138,7 @@ static switch_bool_t limit_execute_sql_callback(switch_mutex_t *mutex, char *sql
}
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);

View File

@ -201,7 +201,7 @@ static switch_bool_t vm_execute_sql_callback(vm_profile_t *profile, switch_mutex
}
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);

View File

@ -2876,7 +2876,8 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
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 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
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);

View File

@ -4008,12 +4008,14 @@ void sofia_glue_sql_close(sofia_profile_t *profile, time_t prune)
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 @@ sofia_cache_db_handle_t *sofia_glue_get_db_handle(sofia_profile_t *profile)
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 @@ switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
}
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 {

View File

@ -1678,7 +1678,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
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;
}
}

View File

@ -1403,7 +1403,8 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann
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,6 +1423,14 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann
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");

View File

@ -199,12 +199,15 @@ char *expand_alias(char *cmd, char *arg)
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 @@ char *expand_alias(char *cmd, char *arg)
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 @@ char *expand_alias(char *cmd, char *arg)
exp = cmd;
}
switch_core_db_close(db);
switch_cache_db_release_db_handle(&db);
return exp;
}
@ -524,7 +528,7 @@ static int comp_callback(void *pArg, int argc, char **argv, char **columnNames)
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 @@ static unsigned char complete(EditLine * el, int ch)
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 @@ static unsigned char complete(EditLine * el, int ch)
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 @@ static unsigned char complete(EditLine * el, int ch)
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,7 +605,9 @@ static unsigned char complete(EditLine * el, int ch)
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);
@ -626,7 +637,7 @@ static unsigned char complete(EditLine * el, int ch)
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 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string)
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 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string)
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);
}
}

View File

@ -1282,9 +1282,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
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 @@ static void switch_load_core_config(const char *file)
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,6 +1459,19 @@ static void switch_load_core_config(const char *file)
}
#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)
{

View File

@ -241,6 +241,111 @@ SWITCH_DECLARE(void) switch_core_db_test_reactive(switch_core_db_t *db, char *te
}
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

View File

@ -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 @@ static void sql_close(time_t prune)
switch_cache_db_handle_t *dbh = NULL;
int locked = 0;
char *key;
switch_mutex_lock(dbh_mutex);
top:
locked = 0;
@ -74,11 +74,12 @@ static void sql_close(time_t prune)
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(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t
}
}
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_DECLARE(switch_cache_db_handle_t *)switch_cache_db_get_db_handle(const ch
}
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)
{
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);
switch_status_t status = SWITCH_STATUS_FALSE;
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 @@ again:
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 @@ again:
} 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 @@ again:
}
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 @@ again:
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 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t * thread,
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 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t * thread,
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 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t * thread,
}
free(sqlbuf);
sql_manager.thread_running = 0;
return NULL;
}
@ -432,45 +485,65 @@ static void core_event_handler(switch_event_t *event)
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 @@ static void core_event_handler(switch_event_t *event)
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 @@ static void core_event_handler(switch_event_t *event)
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 @@ static void core_event_handler(switch_event_t *event)
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 @@ static void core_event_handler(switch_event_t *event)
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 @@ static void core_event_handler(switch_event_t *event)
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 @@ static void core_event_handler(switch_event_t *event)
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 @@ static void core_event_handler(switch_event_t *event)
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,145 +726,218 @@ static void core_event_handler(switch_event_t *event)
}
}
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";
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_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 (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");
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);
}
}
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_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);
if (dbh->odbc_dbh) {
char *err;
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_threadattr_create(&thd_attr, sql_manager.memory_pool);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
@ -776,6 +946,10 @@ void switch_core_sqldb_start(switch_memory_pool_t *pool)
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,16 +957,22 @@ void switch_core_sqldb_stop(void)
switch_status_t st;
switch_event_unbind(&sql_manager.event_node);
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_thread_join(&st, sql_manager.thread);
switch_cache_db_release_db_handle(&sql_manager.event_db);
sql_close(0);
switch_core_db_close(sql_manager.db);
switch_core_db_close(sql_manager.event_db);
if (sql_manager.thread && sql_manager.thread_running) {
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");
}
sql_manager.thread_running = -1;
switch_thread_join(&st, sql_manager.thread);
}
switch_core_hash_destroy(&dbh_hash);

View File

@ -424,7 +424,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_
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 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
SQLLEN m = 0, t = 0;
char *err_str = NULL;
int result;
int err = 0;
switch_assert(callback != NULL);
@ -441,12 +440,12 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
}
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 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
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;
}