diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 56aaf48ff6..b7d5f75868 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -247,14 +247,7 @@ struct switch_runtime { char dummy_data[5]; switch_bool_t colorize_console; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; char *dbname; - char *recovery_odbc_dsn; - char *recovery_odbc_user; - char *recovery_odbc_pass; - char *recovery_dbname; - switch_dbtype_t recovery_odbc_dbtype; uint32_t debug_level; uint32_t runlevel; uint32_t tipping_point; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index d62cd8058d..3577bb4f47 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1627,6 +1627,9 @@ 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); +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 @@ -2296,6 +2299,10 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h const char *file, const char *func, int line); #define switch_cache_db_get_db_handle(_a, _b, _c) _switch_cache_db_get_db_handle(_a, _b, _c, __FILE__, __SWITCH_FUNC__, __LINE__) +SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_db_handle_t **dbh, const char *dsn, + const char *file, const char *func, int line); +#define switch_cache_db_get_db_handle_dsn(_a, _b) _switch_cache_db_get_db_handle_dsn(_a, _b, __FILE__, __SWITCH_FUNC__, __LINE__) + /*! \brief Executes the sql and returns the result as a string \param [in] dbh The handle @@ -2341,7 +2348,12 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_handle_t *db, const char *test_sql, const char *drop_sql, const char *reactive_sql); SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const 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_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute); +#define switch_cache_db_persistant_execute_trans(_d, _s, _r) switch_cache_db_persistant_execute_trans_full(_d, _s, _r, NULL, NULL, NULL, NULL) SWITCH_DECLARE(void) switch_core_set_signal_handlers(void); SWITCH_DECLARE(uint32_t) switch_core_debug_level(void); @@ -2395,12 +2407,25 @@ SWITCH_DECLARE(void) switch_os_yield(void); SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max); +SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_core_dbtype(void); +SWITCH_DECLARE(void) switch_core_sql_exec(const char *sql); SWITCH_DECLARE(int) switch_core_recovery_recover(const char *technology, const char *profile_name); SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session, switch_bool_t force); SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_recovery_flush(const char *technology, const char *profile_name); - +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp); +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init(switch_sql_queue_manager_t **qmp, + uint32_t numq, const char *dsn, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute); + +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm); +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm); + SWITCH_DECLARE(pid_t) switch_fork(void); SWITCH_END_EXTERN_C diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 6f77f32ef4..7bdf230690 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1819,6 +1819,7 @@ typedef struct switch_loadable_module switch_loadable_module_t; typedef struct switch_frame switch_frame_t; typedef struct switch_rtcp_frame switch_rtcp_frame_t; typedef struct switch_channel switch_channel_t; +typedef struct switch_sql_queue_manager switch_sql_queue_manager_t; typedef struct switch_file_handle switch_file_handle_t; typedef struct switch_core_session switch_core_session_t; typedef struct switch_caller_profile switch_caller_profile_t; @@ -2065,6 +2066,7 @@ struct switch_core_session; struct switch_media_bug; /*! \brief A digit stream parser object */ struct switch_ivr_digit_stream_parser; +struct sql_queue_manager; SWITCH_END_EXTERN_C #endif diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index e6f7ea7945..82893aef0d 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -410,8 +410,6 @@ static struct { switch_hash_t *queue_hash; int debug; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; char *dbname; int32_t threads; int32_t running; @@ -506,23 +504,21 @@ static void destroy_queue(const char *queue_name, switch_bool_t block) switch_cache_db_handle_t *cc_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(globals.odbc_dsn)) { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - return dbh; + dsn = globals.odbc_dsn; } else { - options.core_db_options.db_path = globals.dbname; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - return dbh; + dsn = globals.dbname; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + + return dbh; + } /*! * \brief Sets the queue's configuration instructions @@ -1276,15 +1272,6 @@ static switch_status_t load_config(void) globals.dbname = strdup(val); } else if (!strcasecmp(var, "odbc-dsn")) { globals.odbc_dsn = strdup(val); - - if (!zstr(globals.odbc_dsn)) { - if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { - *(globals.odbc_user++) = '\0'; - if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) { - *(globals.odbc_pass++) = '\0'; - } - } - } } } } diff --git a/src/mod/applications/mod_cidlookup/mod_cidlookup.c b/src/mod/applications/mod_cidlookup/mod_cidlookup.c index d71278dd2f..3844acb342 100755 --- a/src/mod/applications/mod_cidlookup/mod_cidlookup.c +++ b/src/mod/applications/mod_cidlookup/mod_cidlookup.c @@ -57,8 +57,6 @@ static struct { int cache_expire; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; char *sql; char *citystate_sql; @@ -90,25 +88,19 @@ static switch_event_node_t *reload_xml_event = NULL; static switch_cache_db_handle_t *cidlookup_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(globals.odbc_dsn)) { - char *dsn; - if ((dsn = strstr(globals.odbc_dsn, "pgsql;")) != NULL) { - options.pgsql_options.dsn = (char*)(dsn + 6); - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } else { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } + dsn = globals.odbc_dsn; + } else { + return NULL; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + return dbh; } @@ -120,11 +112,6 @@ static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const switch_cache_db_handle_t *dbh = NULL; - if (!switch_odbc_available() && !switch_pgsql_available()) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC and PGSQL are not compiled in. Do not configure odbc-dsn parameter!\n"); - return SWITCH_STATUS_FALSE; - } - if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD) && changed) { if (zstr(newvalue)) { @@ -132,13 +119,6 @@ static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const } else { switch_safe_free(globals.odbc_dsn); globals.odbc_dsn = strdup(newvalue); - if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { - *globals.odbc_user++ = '\0'; - if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) { - *globals.odbc_pass++ = '\0'; - } - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connecting to dsn: %s\n", globals.odbc_dsn); if (!(dbh = cidlookup_get_db_handle())) { @@ -572,7 +552,7 @@ static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "caller_id_number", number); /* database always wins */ - if ((switch_odbc_available() || switch_pgsql_available()) && globals.odbc_dsn && globals.sql) { + if (globals.odbc_dsn && globals.sql) { name = do_db_lookup(pool, event, number, globals.sql); if (name) { cid->name = name; @@ -618,7 +598,7 @@ static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, switch_assert(cid); } /* append area if we can */ - if (!cid->area && !skipcitystate && strlen(number) == 11 && number[0] == '1' && (switch_odbc_available() || switch_pgsql_available()) && globals.odbc_dsn && globals.citystate_sql) { + if (!cid->area && !skipcitystate && strlen(number) == 11 && number[0] == '1' && globals.odbc_dsn && globals.citystate_sql) { /* yes, this is really area */ name = do_db_lookup(pool, event, number, globals.citystate_sql); @@ -776,7 +756,7 @@ SWITCH_STANDARD_API(cidlookup_function) stream->write_function(stream, " odbc-dsn: %s\n sql: %s\n citystate-sql: %s\n", globals.odbc_dsn ? globals.odbc_dsn : "(null)", globals.sql ? globals.sql : "(null)", globals.citystate_sql ? globals.citystate_sql : "(null)"); - stream->write_function(stream, " ODBC Compiled: %s; PGSQL Compiled: %s\n", switch_odbc_available() ? "true" : "false", switch_pgsql_available() ? "true" : "false"); + switch_goto_status(SWITCH_STATUS_SUCCESS, done); } diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index 69e0522be7..fd077b14ff 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -44,8 +44,6 @@ static struct { char hostname[256]; char *dbname; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; switch_mutex_t *mutex; switch_mutex_t *db_hash_mutex; switch_hash_t *db_hash; @@ -88,31 +86,21 @@ static char group_sql[] = switch_cache_db_handle_t *limit_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(globals.odbc_dsn)) { - char *dsn; - if ((dsn = strstr(globals.odbc_dsn, "pgsql;")) != NULL) { - options.pgsql_options.dsn = (char*)(dsn + 6); - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } else { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } - return dbh; + dsn = globals.odbc_dsn; } else { - options.core_db_options.db_path = globals.dbname; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - return dbh; + dsn = globals.dbname; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + + return dbh; + } @@ -304,15 +292,8 @@ static switch_status_t do_config() } if (globals.odbc_dsn) { - if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { - *globals.odbc_user++ = '\0'; - if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) { - *globals.odbc_pass++ = '\0'; - } - } - if (!(dbh = limit_get_db_handle())) { - globals.odbc_dsn = globals.odbc_user = globals.odbc_pass; + globals.odbc_dsn = NULL; } } diff --git a/src/mod/applications/mod_directory/mod_directory.c b/src/mod/applications/mod_directory/mod_directory.c index 7df55748d5..2c97e102cb 100644 --- a/src/mod/applications/mod_directory/mod_directory.c +++ b/src/mod/applications/mod_directory/mod_directory.c @@ -74,8 +74,6 @@ static struct { switch_mutex_t *mutex; switch_memory_pool_t *pool; char odbc_dsn[1024]; - char *odbc_user; - char *odbc_pass; } globals; #define DIR_PROFILE_CONFIGITEM_COUNT 100 @@ -192,25 +190,21 @@ char *string_to_keypad_digit(const char *in) switch_cache_db_handle_t *directory_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(globals.odbc_dsn)) { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) { - dbh = NULL; - } - return dbh; + dsn = globals.odbc_dsn; } else { - options.core_db_options.db_path = globals.dbname; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) { - dbh = NULL; - } - return dbh; + dsn = globals.dbname; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + + return dbh; + } static switch_status_t directory_execute_sql(char *sql, switch_mutex_t *mutex) @@ -464,12 +458,6 @@ static switch_status_t load_config(switch_bool_t reload) if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { if (switch_odbc_available()) { switch_set_string(globals.odbc_dsn, val); - if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { - *globals.odbc_user++ = '\0'; - if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) { - *globals.odbc_pass++ = '\0'; - } - } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); } diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c index 4431aac2ee..217d8fc45c 100644 --- a/src/mod/applications/mod_easyroute/mod_easyroute.c +++ b/src/mod/applications/mod_easyroute/mod_easyroute.c @@ -138,23 +138,23 @@ static switch_status_t load_config(void) set_global_db_dsn("easyroute"); } - if (switch_odbc_available() && globals.db_dsn) { + if (globals.db_dsn) { if (!(globals.master_odbc = switch_odbc_handle_new(globals.db_dsn, globals.db_username, globals.db_password))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open Database!\n"); status = SWITCH_STATUS_FALSE; goto reallydone; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened ODBC Database!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened Database!\n"); } if (globals.odbc_num_retries) { switch_odbc_set_num_retries(globals.master_odbc, globals.odbc_num_retries); } if (switch_odbc_handle_connect(globals.master_odbc) != SWITCH_ODBC_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open Database!\n"); status = SWITCH_STATUS_FALSE; goto reallydone; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened ODBC Database!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened Database!\n"); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", globals.db_dsn); if (!globals.custom_query) { @@ -192,12 +192,6 @@ static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int char *sql = NULL; route_callback_t pdata; - if (!switch_odbc_available()) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "mod_easyroute requires core ODBC support. Please refer to the documentation on how to enable this\n"); - return sstatus; - } - memset(&pdata, 0, sizeof(pdata)); if (!globals.custom_query) { sql = switch_mprintf(SQL_LOOKUP, dn); @@ -339,12 +333,6 @@ SWITCH_STANDARD_API(easyroute_function) goto done; } - if (!switch_odbc_available()) { - stream->write_function(stream, "mod_easyroute requires you enable core odbc support\n"); - status = SWITCH_STATUS_SUCCESS; - goto done; - } - if (!cmd || !(mydata = strdup(cmd))) { stream->write_function(stream, "Usage: easyroute \n"); status = SWITCH_STATUS_SUCCESS; diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 56383a2973..78e8950b40 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -588,8 +588,6 @@ static struct { char hostname[256]; char *dbname; char odbc_dsn[1024]; - char *odbc_user; - char *odbc_pass; int node_thread_running; switch_odbc_handle_t *master_odbc; int threads; @@ -727,33 +725,21 @@ static void cancel_consumer_outbound_call(const char *key, switch_call_cause_t c switch_cache_db_handle_t *fifo_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; + switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(globals.odbc_dsn)) { - char *dsn; - if ((dsn = strstr(globals.odbc_dsn, "pgsql;")) != NULL) { - options.pgsql_options.dsn = (char*)(dsn + 6); - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } else { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) { - dbh = NULL; - } - } - return dbh; + dsn = globals.odbc_dsn; } else { - options.core_db_options.db_path = globals.dbname; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) { - dbh = NULL; - } - return dbh; + dsn = globals.dbname; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + + return dbh; } @@ -4020,12 +4006,6 @@ static switch_status_t load_config(int reload, int del_all) if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { if (switch_odbc_available() || switch_pgsql_available()) { switch_set_string(globals.odbc_dsn, val); - if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { - *globals.odbc_user++ = '\0'; - if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) { - *globals.odbc_pass++ = '\0'; - } - } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); } diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index f3d3c0fe41..8da2bd1dcc 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -142,8 +142,6 @@ static struct { switch_memory_pool_t *pool; char *dbname; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; switch_mutex_t *mutex; switch_hash_t *profile_hash; profile_t *default_profile; @@ -430,16 +428,19 @@ static switch_status_t process_max_lengths(max_obj_t *maxes, lcr_route routes, c static switch_cache_db_handle_t *lcr_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; + char *dsn; if (!zstr(globals.odbc_dsn)) { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) dbh = NULL; + dsn = globals.odbc_dsn; + } else { + dsn = globals.dbname; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + return dbh; } @@ -998,12 +999,6 @@ static switch_status_t lcr_load_config() switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "odbc_dsn is %s\n", val); switch_safe_free(globals.odbc_dsn); globals.odbc_dsn = strdup(val); - if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { - *globals.odbc_user++ = '\0'; - if ((globals.odbc_pass = strchr(globals.odbc_user, ':'))) { - *globals.odbc_pass++ = '\0'; - } - } } } } @@ -1011,8 +1006,8 @@ static switch_status_t lcr_load_config() /* initialize sql here, 'cause we need to verify custom_sql for each profile below */ if (globals.odbc_dsn) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG - , "dsn is \"%s\", user is \"%s\"\n" - , globals.odbc_dsn, globals.odbc_user + , "dsn is \"%s\"\n" + , globals.odbc_dsn ); if (!(dbh = lcr_get_db_handle())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); @@ -2021,12 +2016,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lcr_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); - if (!switch_odbc_available()) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "You must have ODBC support in FreeSWITCH to use this module\n"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\t./configure --enable-core-odbc-support\n"); - return SWITCH_STATUS_FALSE; - } - globals.pool = pool; if (switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool) != SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 5a5071ea26..1bc5462e99 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -83,8 +83,6 @@ struct vm_profile { char *name; char *dbname; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; char terminator_key[2]; char play_new_messages_key[2]; char play_saved_messages_key[2]; @@ -163,31 +161,21 @@ typedef struct vm_profile vm_profile_t; switch_cache_db_handle_t *vm_get_db_handle(vm_profile_t *profile) { - switch_cache_db_connection_options_t options = { {0} }; + switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(profile->odbc_dsn)) { - char *dsn; - if ((dsn = strstr(profile->odbc_dsn, "pgsql;")) != NULL) { - options.pgsql_options.dsn = (char*)(dsn + 6); - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } else { - options.odbc_options.dsn = profile->odbc_dsn; - options.odbc_options.user = profile->odbc_user; - options.odbc_options.pass = profile->odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } - return dbh; + dsn = profile->odbc_dsn; } else { - options.core_db_options.db_path = profile->dbname; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - return dbh; + dsn = profile->dbname; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + + return dbh; } @@ -722,15 +710,6 @@ static vm_profile_t *load_profile(const char *profile_name) switch_thread_rwlock_create(&profile->rwlock, pool); profile->name = switch_core_strdup(pool, profile_name); - if (!zstr(profile->odbc_dsn)) { - if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) { - *(profile->odbc_user++) = '\0'; - if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) { - *(profile->odbc_pass++) = '\0'; - } - } - } - if (zstr(profile->dbname)) { profile->dbname = switch_core_sprintf(profile->pool, "voicemail_%s", profile_name); } diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 9dd89b0e59..6e36486d7d 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -133,11 +133,8 @@ struct mdl_profile { char *dbname; char *avatar; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; switch_bool_t purge; switch_thread_rwlock_t *rwlock; - switch_odbc_handle_t *master_odbc; switch_mutex_t *mutex; ldl_handle_t *handle; uint32_t flags; @@ -324,73 +321,110 @@ static char *translate_rpid(char *in, char *ext) } - - -static void mdl_execute_sql(mdl_profile_t *profile, char *sql, switch_mutex_t *mutex) +static switch_cache_db_handle_t *mdl_get_db_handle(mdl_profile_t *profile) { - switch_core_db_t *db; - - if (mutex) { - switch_mutex_lock(mutex); - } - - if (switch_odbc_available() && profile->odbc_dsn) { - switch_odbc_statement_handle_t stmt; - if (switch_odbc_handle_exec(profile->master_odbc, sql, &stmt, NULL) != SWITCH_ODBC_SUCCESS) { - char *err_str; - err_str = switch_odbc_handle_get_error(profile->master_odbc, stmt); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); - switch_safe_free(err_str); - } - switch_odbc_statement_handle_free(&stmt); + switch_cache_db_handle_t *dbh = NULL; + char *dsn; + + if (!zstr(profile->odbc_dsn)) { + dsn = profile->odbc_dsn; } 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); - goto end; - } - switch_core_db_persistant_execute(db, sql, 1); - switch_core_db_close(db); + dsn = profile->dbname; } - end: - if (mutex) { - switch_mutex_unlock(mutex); + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; } + + return dbh; + } -static switch_bool_t mdl_execute_sql_callback(mdl_profile_t *profile, - switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata) +static switch_status_t mdl_execute_sql(mdl_profile_t *profile, char *sql, switch_mutex_t *mutex) { - switch_bool_t ret = SWITCH_FALSE; - switch_core_db_t *db; - char *errmsg = NULL; + switch_cache_db_handle_t *dbh = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; if (mutex) { switch_mutex_lock(mutex); } - if (switch_odbc_available() && profile->odbc_dsn) { - 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); - goto end; - } - switch_core_db_exec(db, sql, callback, pdata, &errmsg); + if (!(dbh = mdl_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + goto end; + } - if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); - switch_core_db_free(errmsg); - } + status = switch_cache_db_execute_sql(dbh, sql, NULL); - if (db) { - switch_core_db_close(db); - } + end: + + switch_cache_db_release_db_handle(&dbh); + + if (mutex) { + switch_mutex_unlock(mutex); + } + + return status; +} + +char *mdl_execute_sql2str(mdl_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len) +{ + switch_cache_db_handle_t *dbh = NULL; + + char *ret = NULL; + + if (mutex) { + switch_mutex_lock(mutex); + } + + if (!(dbh = mdl_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + goto end; + } + + ret = switch_cache_db_execute_sql2str(dbh, sql, resbuf, len, NULL); + +end: + + switch_cache_db_release_db_handle(&dbh); + + if (mutex) { + switch_mutex_unlock(mutex); + } + + return ret; + +} + + +static switch_bool_t mdl_execute_sql_callback(mdl_profile_t *profile, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, + void *pdata) +{ + switch_bool_t ret = SWITCH_FALSE; + char *errmsg = NULL; + switch_cache_db_handle_t *dbh = NULL; + + if (mutex) { + switch_mutex_lock(mutex); + } + + if (!(dbh = mdl_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + goto end; + } + + switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg); + + if (errmsg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); + free(errmsg); } end: + switch_cache_db_release_db_handle(&dbh); + if (mutex) { switch_mutex_unlock(mutex); } @@ -398,6 +432,9 @@ static switch_bool_t mdl_execute_sql_callback(mdl_profile_t *profile, return ret; } + + + static int sub_callback(void *pArg, int argc, char **argv, char **columnNames) { mdl_profile_t *profile = (mdl_profile_t *) pArg; @@ -2790,17 +2827,7 @@ static void set_profile_val(mdl_profile_t *profile, char *var, char *val) } else if (!strcasecmp(var, "avatar")) { profile->avatar = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { - if (switch_odbc_available()) { - profile->odbc_dsn = switch_core_strdup(module_pool, val); - if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) { - *profile->odbc_user++ = '\0'; - if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) { - *profile->odbc_pass++ = '\0'; - } - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); - } + profile->odbc_dsn = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "use-rtp-timer") && switch_true(val)) { switch_set_flag(profile, TFLAG_TIMER); } else if (!strcasecmp(var, "dialplan") && !zstr(val)) { @@ -3109,17 +3136,13 @@ static switch_bool_t match_profile(mdl_profile_t *profile, mdl_profile_t *new_pr (new_profile->user_flags == profile->user_flags) && (new_profile->acl_count == profile->acl_count) ) { uint32_t i; - if (switch_odbc_available()) { - if (!(((!new_profile->odbc_dsn && !profile->odbc_dsn) || - (new_profile->odbc_dsn && profile->odbc_dsn && !strcasecmp(new_profile->odbc_dsn, profile->odbc_dsn))) && - ((!new_profile->odbc_user && !profile->odbc_user) || - (new_profile->odbc_user && profile->odbc_user && !strcasecmp(new_profile->odbc_user, profile->odbc_user))) && - ((!new_profile->odbc_pass && !profile->odbc_pass) || - (new_profile->odbc_pass && profile->odbc_pass && !strcasecmp(new_profile->odbc_pass, profile->odbc_pass))) - )) { - return SWITCH_FALSE; - } + + if (!(((!new_profile->odbc_dsn && !profile->odbc_dsn) || + (new_profile->odbc_dsn && profile->odbc_dsn && !strcasecmp(new_profile->odbc_dsn, profile->odbc_dsn))) + )) { + return SWITCH_FALSE; } + for (i = 0; i < new_profile->acl_count; i++) { if (strcasecmp(new_profile->acl[i], profile->acl[i]) != 0) { @@ -3137,11 +3160,6 @@ static switch_status_t destroy_profile(char *name) if ((profile = switch_core_hash_find(globals.profile_hash, name))) { if (profile->user_flags & LDL_FLAG_COMPONENT) { - if (switch_odbc_available() && profile->odbc_dsn && profile->master_odbc) { - switch_odbc_handle_disconnect(profile->master_odbc); - switch_odbc_handle_destroy(&profile->master_odbc); - } - switch_mutex_destroy(profile->mutex); } @@ -3205,7 +3223,7 @@ static switch_status_t soft_reload(void) if (profile && type && !strcasecmp(type, "component")) { char dbname[256]; - switch_core_db_t *db; + switch_cache_db_handle_t *dbh = NULL; if (!profile->login && profile->name) { profile->login = switch_core_strdup(module_pool, profile->name); @@ -3218,28 +3236,9 @@ static switch_status_t soft_reload(void) switch_snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name); profile->dbname = switch_core_strdup(module_pool, dbname); - if (switch_odbc_available() && profile->odbc_dsn) { - if (!(profile->master_odbc = switch_odbc_handle_new(profile->odbc_dsn, profile->odbc_user, profile->odbc_pass))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); - continue; - - } - if (switch_odbc_handle_connect(profile->master_odbc) != SWITCH_ODBC_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); - continue; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", profile->odbc_dsn); - switch_odbc_handle_exec(profile->master_odbc, sub_sql, NULL, NULL); - //mdl_execute_sql(profile, sub_sql, NULL); - } else { - if ((db = switch_core_db_open_file(profile->dbname))) { - switch_core_db_test_reactive(db, "select * from jabber_subscriptions", NULL, sub_sql); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n"); - continue; - } - switch_core_db_close(db); + if ((dbh = mdl_get_db_handle(profile))) { + switch_cache_db_test_reactive(dbh, "select * from jabber_subscriptions", NULL, sub_sql); + switch_cache_db_release_db_handle(&dbh); } } @@ -3354,7 +3353,7 @@ static switch_status_t load_config(void) if (profile && type && !strcasecmp(type, "component")) { char dbname[256]; - switch_core_db_t *db; + switch_cache_db_handle_t *dbh = NULL; if (!profile->login && profile->name) { profile->login = switch_core_strdup(module_pool, profile->name); @@ -3367,28 +3366,10 @@ static switch_status_t load_config(void) switch_snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name); profile->dbname = switch_core_strdup(module_pool, dbname); - if (switch_odbc_available() && profile->odbc_dsn) { - if (!(profile->master_odbc = switch_odbc_handle_new(profile->odbc_dsn, profile->odbc_user, profile->odbc_pass))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); - continue; - } - if (switch_odbc_handle_connect(profile->master_odbc) != SWITCH_ODBC_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); - continue; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", profile->odbc_dsn); - switch_odbc_handle_exec(profile->master_odbc, sub_sql, NULL, NULL); - //mdl_execute_sql(profile, sub_sql, NULL); - } else { - if ((db = switch_core_db_open_file(profile->dbname))) { - switch_core_db_test_reactive(db, "select * from jabber_subscriptions", NULL, sub_sql); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n"); - continue; - } - switch_core_db_close(db); + if ((dbh = mdl_get_db_handle(profile))) { + switch_cache_db_test_reactive(dbh, "select * from jabber_subscriptions", NULL, sub_sql); + switch_cache_db_release_db_handle(&dbh); } } diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 317833f9f3..cb5597487b 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -304,23 +304,21 @@ switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, l /*****************************************************************************/ switch_cache_db_handle_t *skinny_get_db_handle(skinny_profile_t *profile) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(profile->odbc_dsn)) { - options.odbc_options.dsn = profile->odbc_dsn; - options.odbc_options.user = profile->odbc_user; - options.odbc_options.pass = profile->odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - return dbh; + dsn = profile->odbc_dsn; } else { - options.core_db_options.db_path = profile->dbname; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - return dbh; + dsn = profile->dbname; } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + + return dbh; + } @@ -1751,6 +1749,7 @@ static switch_status_t load_skinny_config(void) { char *cf = "skinny.conf"; switch_xml_t xcfg, xml, xprofiles, xprofile; + switch_cache_db_handle_t *dbh = NULL; if (!(xml = switch_xml_open_cfg(cf, &xcfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); @@ -1770,7 +1769,6 @@ static switch_status_t load_skinny_config(void) if ((xsettings = switch_xml_child(xprofile, "settings"))) { switch_memory_pool_t *profile_pool = NULL; char dbname[256]; - switch_core_db_t *db; skinny_profile_t *profile = NULL; switch_xml_t param; @@ -1914,34 +1912,17 @@ static switch_status_t load_skinny_config(void) switch_snprintf(dbname, sizeof(dbname), "skinny_%s", profile->name); profile->dbname = switch_core_strdup(profile->pool, dbname); - if (switch_odbc_available() && profile->odbc_dsn) { - if (!(profile->master_odbc = switch_odbc_handle_new(profile->odbc_dsn, profile->odbc_user, profile->odbc_pass))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); - continue; - - } - if (switch_odbc_handle_connect(profile->master_odbc) != SWITCH_ODBC_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); - continue; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", profile->odbc_dsn); - switch_odbc_handle_exec(profile->master_odbc, devices_sql, NULL, NULL); - switch_odbc_handle_exec(profile->master_odbc, lines_sql, NULL, NULL); - switch_odbc_handle_exec(profile->master_odbc, buttons_sql, NULL, NULL); - switch_odbc_handle_exec(profile->master_odbc, active_lines_sql, NULL, NULL); - } else { - if ((db = switch_core_db_open_file(profile->dbname))) { - switch_core_db_test_reactive(db, "SELECT headset FROM skinny_devices", "DROP TABLE skinny_devices", devices_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_lines", "DROP TABLE skinny_lines", lines_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_buttons", "DROP TABLE skinny_buttons", buttons_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_active_lines", "DROP TABLE skinny_active_lines", active_lines_sql); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n"); - continue; - } - switch_core_db_close(db); + + + + if ((dbh = skinny_get_db_handle(profile))) { + switch_cache_db_test_reactive(dbh, "SELECT headset FROM skinny_devices", "DROP TABLE skinny_devices", devices_sql); + switch_cache_db_test_reactive(dbh, "SELECT * FROM skinny_lines", "DROP TABLE skinny_lines", lines_sql); + switch_cache_db_test_reactive(dbh, "SELECT * FROM skinny_buttons", "DROP TABLE skinny_buttons", buttons_sql); + switch_cache_db_test_reactive(dbh, "SELECT * FROM skinny_active_lines", "DROP TABLE skinny_active_lines", active_lines_sql); + switch_cache_db_release_db_handle(&dbh); } + skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_devices", NULL, NULL); skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_lines", NULL, NULL); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 683929a88a..dfd472e65d 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -626,9 +626,10 @@ struct sofia_profile { uint32_t rtp_timeout_sec; uint32_t rtp_hold_timeout_sec; char *odbc_dsn; - char *odbc_user; - char *odbc_pass; - // switch_odbc_handle_t *master_odbc; + char *pre_trans_execute; + char *post_trans_execute; + char *inner_pre_trans_execute; + char *inner_post_trans_execute; switch_queue_t *sql_queue; char *acl[SOFIA_MAX_ACL]; uint32_t acl_count; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ae501d57e7..cfcc550eba 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4414,17 +4414,15 @@ switch_status_t config_sofia(int reload, char *profile_name) sofia_set_flag(profile, TFLAG_CAPTURE); nua_set_params(profile->nua, TPTAG_CAPT(mod_sofia_globals.capture_server), TAG_END()); } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { - if (switch_odbc_available() || switch_pgsql_available()) { - profile->odbc_dsn = switch_core_strdup(profile->pool, val); - if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) { - *profile->odbc_user++ = '\0'; - if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) { - *profile->odbc_pass++ = '\0'; - } - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NEITHER ODBC NOR PGSQL ARE AVAILABLE!\n"); - } + profile->odbc_dsn = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "db-pre-trans-execute") && !zstr(val)) { + profile->pre_trans_execute = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "db-post-trans-execute") && !zstr(val)) { + profile->post_trans_execute = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "db-inner-pre-trans-execute") && !zstr(val)) { + profile->inner_pre_trans_execute = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "db-inner-post-trans-execute") && !zstr(val)) { + profile->inner_post_trans_execute = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 0e7ed4db0a..15745a2ce6 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -36,8 +36,8 @@ #include "mod_sofia.h" #include -switch_cache_db_handle_t *sofia_glue_get_db_handle(sofia_profile_t *profile); - +switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line); +#define sofia_glue_get_db_handle(_p) _sofia_glue_get_db_handle(_p, __FILE__, __SWITCH_FUNC__, __LINE__) void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options, int insist) { @@ -6361,33 +6361,22 @@ void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bo } -switch_cache_db_handle_t *sofia_glue_get_db_handle(sofia_profile_t *profile) +switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; - + char *dsn; + if (!zstr(profile->odbc_dsn)) { - char *dsn; - if ((dsn = strstr(profile->odbc_dsn, "pgsql;")) != NULL) { - options.pgsql_options.dsn = (char*)(dsn + 6); - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } else { - options.odbc_options.dsn = profile->odbc_dsn; - options.odbc_options.user = profile->odbc_user; - options.odbc_options.pass = profile->odbc_pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - } - return dbh; + dsn = profile->odbc_dsn; } else { - options.core_db_options.db_path = profile->dbname; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; - return dbh; + dsn = profile->dbname; } + + if (_switch_cache_db_get_db_handle_dsn(&dbh, dsn, file, func, line) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } + + return dbh; } void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex) @@ -6403,7 +6392,12 @@ void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, switch_mutex_lock(mutex); } - switch_cache_db_persistant_execute_trans(dbh, sql, 1); + switch_cache_db_persistant_execute_trans_full(dbh, sql, 1, + profile->pre_trans_execute, + profile->post_trans_execute, + profile->inner_pre_trans_execute, + profile->inner_post_trans_execute + ); switch_cache_db_release_db_handle(&dbh); diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index f4e3f6c10e..e52b0ac37c 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -79,12 +79,12 @@ SWITCH_MODULE_DEFINITION(mod_cdr_sqlite, mod_cdr_sqlite_load, mod_cdr_sqlite_shu switch_cache_db_handle_t *cdr_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; switch_cache_db_handle_t *dbh = NULL; - options.core_db_options.db_path = globals.db_name; - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) + if (switch_cache_db_get_db_handle_dsn(&dbh, globals.db_name) != SWITCH_STATUS_SUCCESS) { dbh = NULL; + } + return dbh; } diff --git a/src/switch_console.c b/src/switch_console.c index 059ff79d59..121e8de336 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -1771,26 +1771,16 @@ 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_cache_db_handle_t *db = NULL; switch_stream_handle_t mystream = { 0 }; SWITCH_STANDARD_STREAM(mystream); - - - if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); - free(mystream.data); - free(mydata); - return SWITCH_STATUS_FALSE; - } - - + if (!strcasecmp(argv[0], "stickyadd")) { mystream.write_function(&mystream, "insert into complete values (1,"); for (x = 0; x < 10; x++) { if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) { mystream.write_function(&mystream, "%s", "'', "); } else { - if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { + if (switch_core_dbtype() == SCDB_TYPE_CORE_DB) { mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1])); } else { mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1])); @@ -1798,7 +1788,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } } mystream.write_function(&mystream, " '%s')", switch_core_get_switchname()); - switch_cache_db_persistant_execute(db, mystream.data, 5); + switch_core_sql_exec(mystream.data); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add")) { mystream.write_function(&mystream, "insert into complete values (0,"); @@ -1806,7 +1796,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) { mystream.write_function(&mystream, "%s", "'', "); } else { - if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { + if (switch_core_dbtype() == SCDB_TYPE_CORE_DB) { mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1])); } else { mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1])); @@ -1815,29 +1805,28 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } mystream.write_function(&mystream, " '%s')", switch_core_get_switchname()); - switch_cache_db_persistant_execute(db, mystream.data, 5); + switch_core_sql_exec(mystream.data); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "del")) { char *what = argv[1]; if (!strcasecmp(what, "*")) { - switch_cache_db_persistant_execute(db, "delete from complete", 1); + switch_core_sql_exec("delete from complete"); } else { mystream.write_function(&mystream, "delete from complete where "); for (x = 0; x < argc - 1; x++) { - if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { + if (switch_core_dbtype() == SCDB_TYPE_CORE_DB) { mystream.write_function(&mystream, "a%d = '%q'%q", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and "); } else { mystream.write_function(&mystream, "a%d = '%w'%w", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and "); } } mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_switchname()); - switch_cache_db_persistant_execute(db, mystream.data, 1); + switch_core_sql_exec(mystream.data); } status = SWITCH_STATUS_SUCCESS; } switch_safe_free(mystream.data); - switch_cache_db_release_db_handle(&db); } } diff --git a/src/switch_core.c b/src/switch_core.c index 389bbde756..82b08e3808 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1912,12 +1912,6 @@ static void switch_load_core_config(const char *file) } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) { if (switch_odbc_available() || switch_pgsql_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 AND PGSQL ARE NOT AVAILABLE!\n"); } diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index a557a867ff..543ff50bd0 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -175,106 +175,33 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user } - -#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, const char *file, const char *func, int line) { - switch_cache_db_connection_options_t options = { {0} }; switch_status_t r; + char *dsn; if (!sql_manager.manage) { return SWITCH_STATUS_FALSE; } - if (zstr(runtime.odbc_dsn)) { - if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { - return SWITCH_STATUS_FALSE; - } - - if (runtime.dbname) { - options.core_db_options.db_path = runtime.dbname; - } else { - options.core_db_options.db_path = SWITCH_CORE_DB; - } - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); - + if (!zstr(runtime.odbc_dsn)) { + dsn = runtime.odbc_dsn; + } else if (!zstr(runtime.dbname)) { + dsn = runtime.dbname; } else { - char *dsn; - if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { - options.pgsql_options.dsn = (char*)(dsn + 6); - - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); - } else { - options.odbc_options.dsn = runtime.odbc_dsn; - options.odbc_options.user = runtime.odbc_user; - options.odbc_options.pass = runtime.odbc_pass; - - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); - } + dsn = "core"; } - /* I *think* we can do without this now, if not let me know - if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager.io_mutex; - } - */ - - return r; -} - -#define SWITCH_CORE_PERSIST_DB "core" -/*! - \brief Open the default system database -*/ -SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) -{ - switch_cache_db_connection_options_t options = { {0} }; - switch_status_t r; + if ((r = _switch_cache_db_get_db_handle_dsn(dbh, dsn, file, func, line)) != SWITCH_STATUS_SUCCESS) { + *dbh = NULL; + } - if (!sql_manager.manage) { - return SWITCH_STATUS_FALSE; - } - - if (zstr(runtime.odbc_dsn)) { - if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { - return SWITCH_STATUS_FALSE; - } - - if (runtime.dbname) { - options.core_db_options.db_path = runtime.dbname; - } else { - options.core_db_options.db_path = SWITCH_CORE_PERSIST_DB; - } - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); - - } else { - char *dsn; - if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { - options.pgsql_options.dsn = (char*)(dsn + 6); - - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); - } else { - options.odbc_options.dsn = runtime.odbc_dsn; - options.odbc_options.user = runtime.odbc_user; - options.odbc_options.pass = runtime.odbc_pass; - - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); - } - } - - /* I *think* we can do without this now, if not let me know - if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager.io_mutex; - } - */ - return r; } - #define SQL_CACHE_TIMEOUT 30 #define SQL_REG_TIMEOUT 15 @@ -381,6 +308,55 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t } +SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_db_handle_t **dbh, const char *dsn, + const char *file, const char *func, int line) +{ + switch_cache_db_connection_options_t connection_options = { {0} }; + switch_cache_db_handle_type_t type; + char tmp[256] = ""; + char *p; + switch_status_t status = SWITCH_STATUS_FALSE; + int i; + + if (!strncmp(dsn, "pgsql;", 6)) { + type = SCDB_TYPE_PGSQL; + connection_options.pgsql_options.dsn = (char *)(dsn + 6); + } else if ((!(i = strncmp(dsn, "odbc;", 6))) || strchr(dsn, ':')) { + type = SCDB_TYPE_ODBC; + + if (i) { + switch_set_string(tmp, dsn); + } else { + switch_set_string(tmp, dsn+6); + } + + connection_options.odbc_options.dsn = tmp; + + if ((p = strchr(tmp, ':'))) { + *p++ = '\0'; + connection_options.odbc_options.user = p; + + if ((p = strchr(connection_options.odbc_options.user, ':'))) { + *p++ = '\0'; + connection_options.odbc_options.pass = p; + } + + } + + } else { + type = SCDB_TYPE_CORE_DB; + connection_options.core_db_options.db_path = (char *)dsn; + } + + status = _switch_cache_db_get_db_handle(dbh, type, &connection_options, file, func, line); + + if (status != SWITCH_STATUS_SUCCESS) *dbh = NULL; + + return status; + +} + + SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh, switch_cache_db_handle_type_t type, switch_cache_db_connection_options_t *connection_options, @@ -822,7 +798,12 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_ } -SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries) +SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(switch_cache_db_handle_t *dbh, + char *sql, uint32_t retries, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute) { char *errmsg = NULL; switch_status_t status = SWITCH_STATUS_FALSE; @@ -838,10 +819,10 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ if (io_mutex) switch_mutex_lock(io_mutex); - if (!zstr(runtime.core_db_pre_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, runtime.core_db_pre_trans_execute, &errmsg); + if (!zstr(pre_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, pre_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", runtime.core_db_pre_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", pre_trans_execute, errmsg); free(errmsg); } } @@ -929,10 +910,10 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ } - if (!zstr(runtime.core_db_inner_pre_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, runtime.core_db_inner_pre_trans_execute, &errmsg); + if (!zstr(inner_pre_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, inner_pre_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", runtime.core_db_inner_pre_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", inner_pre_trans_execute, errmsg); free(errmsg); } } @@ -957,10 +938,10 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ } } - if (!zstr(runtime.core_db_inner_post_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, runtime.core_db_inner_post_trans_execute, &errmsg); + if (!zstr(inner_post_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, inner_post_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", runtime.core_db_inner_post_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", inner_post_trans_execute, errmsg); free(errmsg); } } @@ -988,10 +969,10 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ break; } - if (!zstr(runtime.core_db_post_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, runtime.core_db_post_trans_execute, &errmsg); + if (!zstr(post_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, post_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", runtime.core_db_post_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", post_trans_execute, errmsg); free(errmsg); } } @@ -1152,6 +1133,396 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *threa return NULL; } + +static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, void *obj); + +struct switch_sql_queue_manager { + switch_cache_db_handle_t *event_db; + switch_queue_t **sql_queue; + uint32_t numq; + char *dsn; + switch_thread_t *thread; + int thread_running; + switch_thread_cond_t *cond; + switch_mutex_t *cond_mutex; + char *pre_trans_execute; + char *post_trans_execute; + char *inner_pre_trans_execute; + char *inner_post_trans_execute; + switch_memory_pool_t *pool; +}; + +static void qm_wake(switch_sql_queue_manager_t *qm) +{ + if (switch_mutex_trylock(qm->cond_mutex) == SWITCH_STATUS_SUCCESS) { + switch_thread_cond_signal(qm->cond); + switch_mutex_unlock(qm->cond_mutex); + } +} + +static uint32_t qm_ttl(switch_sql_queue_manager_t *qm) +{ + uint32_t ttl = 0; + int i; + + for (i = 0; i < qm->numq; i++) { + ttl += switch_queue_size(qm->sql_queue[i]); + } + + return ttl; +} + + +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + if (qm->thread_running) { + qm->thread_running = 0; + switch_queue_push(qm->sql_queue[0], NULL); + qm_wake(qm); + status = SWITCH_STATUS_SUCCESS; + } + + if (qm->thread) { + switch_thread_join(&status, qm->thread); + qm->thread = NULL; + status = SWITCH_STATUS_SUCCESS; + } + + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm) +{ + switch_threadattr_t *thd_attr; + + if (!qm->thread_running) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting SQL thread.\n"); + switch_threadattr_create(&thd_attr, qm->pool); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_NORMAL); + switch_thread_create(&qm->thread, thd_attr, switch_user_sql_thread, qm, qm->pool); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + + +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp) +{ + switch_sql_queue_manager_t *qm; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_memory_pool_t *pool; + void *pop; + int i; + + switch_assert(qmp); + qm = *qmp; + *qmp = NULL; + + switch_switch_sql_queue_manager_stop(qm); + + for(i = 0; i < qm->numq; i++) { + while (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { + switch_safe_free(pop); + } + } + + pool = qm->pool; + switch_core_destroy_memory_pool(&pool); + + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) +{ + + if (!qm->thread_running) { + return SWITCH_STATUS_FALSE; + } + + if (sql_manager.thread_running != 1) { + return SWITCH_STATUS_FALSE; + } + + if (pos > qm->numq - 1) { + pos = 0; + } + + switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql); + qm_wake(qm); + + return SWITCH_STATUS_SUCCESS; +} + + + + + +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init(switch_sql_queue_manager_t **qmp, + uint32_t numq, const char *dsn, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute) +{ + switch_memory_pool_t *pool; + switch_sql_queue_manager_t *qm; + int i; + + if (!numq) numq = 1; + + switch_core_new_memory_pool(&pool); + qm = switch_core_alloc(pool, sizeof(*qm)); + + qm->pool = pool; + qm->numq = numq; + qm->dsn = switch_core_strdup(qm->pool, dsn); + + switch_mutex_init(&qm->cond_mutex, SWITCH_MUTEX_NESTED, qm->pool); + switch_thread_cond_create(&qm->cond, qm->pool); + + qm->sql_queue = switch_core_alloc(qm->pool, sizeof(switch_queue_t *) * numq); + + for (i = 0; i < qm->numq; i++) { + switch_queue_create(&qm->sql_queue[i], SWITCH_SQL_QUEUE_LEN, qm->pool); + } + + if (pre_trans_execute) { + qm->pre_trans_execute = switch_core_strdup(qm->pool, qm->pre_trans_execute); + qm->post_trans_execute = switch_core_strdup(qm->pool, qm->post_trans_execute); + qm->inner_pre_trans_execute = switch_core_strdup(qm->pool, qm->inner_pre_trans_execute); + qm->inner_post_trans_execute = switch_core_strdup(qm->pool, qm->inner_post_trans_execute); + } + + *qmp = qm; + + return SWITCH_STATUS_SUCCESS; + +} +static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, void *obj) +{ + void *pop = NULL; + uint32_t iterations = 0; + uint8_t trans = 0; + uint32_t target = 20000; + switch_size_t len = 0, sql_len = runtime.sql_buffer_len; + char *tmp, *sqlbuf = (char *) malloc(sql_len); + char *sql = NULL, *save_sql = NULL; + switch_size_t newlen; + int lc = 0, wrote = 0, do_sleep = 1; + uint32_t sanity = 120; + int auto_pause = 0; + switch_sql_queue_manager_t *qm = (switch_sql_queue_manager_t *) obj; + int i; + + switch_assert(sqlbuf); + + while (!qm->event_db) { + if (switch_cache_db_get_db_handle_dsn(&qm->event_db, qm->dsn) == SWITCH_STATUS_SUCCESS && qm->event_db) + break; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error getting core db, Retrying\n"); + switch_yield(500000); + sanity--; + } + + if (!qm->event_db) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error getting core db\n"); + return NULL; + } + + qm->thread_running = 1; + + switch_mutex_lock(qm->cond_mutex); + + switch (qm->event_db->type) { + case SCDB_TYPE_PGSQL: + break; + case SCDB_TYPE_ODBC: + break; + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql(qm->event_db, "PRAGMA synchronous=OFF;", NULL); + switch_cache_db_execute_sql(qm->event_db, "PRAGMA count_changes=OFF;", NULL); + switch_cache_db_execute_sql(qm->event_db, "PRAGMA temp_store=MEMORY;", NULL); + switch_cache_db_execute_sql(qm->event_db, "PRAGMA journal_mode=OFF;", NULL); + } + break; + } + + while (qm->thread_running == 1) { + int proceed = !!save_sql; + + if (!proceed) { + for (i = 0; i < qm->numq; i++) { + if (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { + if (sql_manager.thread_running != 1) { + free(pop); + pop = NULL; + } else { + proceed = 1; + break; + } + } + } + } + + if (proceed) { + + if (save_sql) { + sql = save_sql; + save_sql = NULL; + } else if ((sql = (char *) pop)) { + pop = NULL; + } + + if (sql) { + newlen = strlen(sql) + 2; + + if (iterations == 0) { + trans = 1; + } + + if (len + newlen + 1 > sql_len) { + int new_mlen = len + newlen + 10240; + + if (new_mlen < runtime.max_sql_buffer_len) { + sql_len = new_mlen; + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + for (i = 0; i < qm->numq; i++) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "REALLOC QUEUE %ld %d %d\n", + sql_len, + i, + switch_queue_size(qm->sql_queue[i])); + + } + } + if (!(tmp = realloc(sqlbuf, sql_len))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n"); + abort(); + break; + } + sqlbuf = tmp; + } else { + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + for (i = 0; i < qm->numq; i++) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "SAVE QUEUE %d %d\n", + i, + switch_queue_size(qm->sql_queue[i])); + + } + } + save_sql = sql; + sql = NULL; + lc = 0; + goto skip; + } + } + + iterations++; + sprintf(sqlbuf + len, "%s;\n", sql); + len += newlen; + free(sql); + sql = NULL; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "SQL thread ending\n"); + break; + } + } + + lc = qm_ttl(qm); + + + if (lc > SWITCH_SQL_QUEUE_PAUSE_LEN) { + if (!auto_pause) { + auto_pause = 1; + switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); + auto_pause = 1; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue overflowing [%d], Pausing calls.\n", lc); + } + } else { + if (auto_pause && lc < 1000) { + auto_pause = 0; + switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); + auto_pause = 0; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue back to normal size, resuming..\n"); + } + } + + skip: + + wrote = 0; + + if (trans && iterations && (iterations > target || !lc)) { + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + for (i = 0; i < qm->numq; i++) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "RUN QUEUE %d %d %d\n", + i, + switch_queue_size(qm->sql_queue[i]), + iterations); + } + } + if (switch_cache_db_persistant_execute_trans_full(qm->event_db, sqlbuf, 1, + qm->pre_trans_execute, + qm->post_trans_execute, + qm->inner_pre_trans_execute, + qm->inner_post_trans_execute + ) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); + } + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DONE\n"); + } + + + iterations = 0; + trans = 0; + len = 0; + *sqlbuf = '\0'; + lc = 0; + if (do_sleep) { + switch_yield(200000); + } else { + switch_yield(1000); + } + wrote = 1; + } + + lc = qm_ttl(qm); + + if (!lc) { + switch_thread_cond_wait(qm->cond, qm->cond_mutex); + } else if (wrote) { + if (lc > 2000) { + do_sleep = 0; + } else { + do_sleep = 1; + } + } + } + + switch_mutex_unlock(qm->cond_mutex); + + for(i = 0; i < qm->numq; i++) { + while (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { + switch_safe_free(pop); + } + } + + free(sqlbuf); + + qm->thread_running = 0; + + switch_cache_db_release_db_handle(&qm->event_db); + + return NULL; +} + static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, void *obj) { void *pop = NULL; @@ -1300,7 +1671,12 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, switch_queue_size(sql_manager.sql_queue[3]), iterations); } - if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) { + if (switch_cache_db_persistant_execute_trans_full(sql_manager.event_db, sqlbuf, 1, + runtime.core_db_pre_trans_execute, + runtime.core_db_post_trans_execute, + runtime.core_db_inner_pre_trans_execute, + runtime.core_db_inner_post_trans_execute + ) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); } if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { @@ -2250,6 +2626,19 @@ SWITCH_DECLARE(int) switch_core_recovery_recover(const char *technology, const c } +SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_core_dbtype(void) +{ + return sql_manager.event_db->type; +} + +SWITCH_DECLARE(void) switch_core_sql_exec(const char *sql) +{ + if (!switch_test_flag((&runtime), SCF_USE_SQL)) { + return; + } + + switch_queue_push(sql_manager.sql_queue[3], strdup(sql)); +} SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session, switch_bool_t force) { @@ -2454,8 +2843,6 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ if (runtime.odbc_dsn) { runtime.odbc_dsn = NULL; - runtime.odbc_user = NULL; - runtime.odbc_pass = NULL; runtime.odbc_dbtype = DBTYPE_DEFAULT; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n"); goto top; @@ -2539,8 +2926,6 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ 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 non-SQLite support; using SQLite\n"); switch_cache_db_release_db_handle(&sql_manager.dbh); free(err); @@ -2709,8 +3094,6 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) if (runtime.odbc_dsn) { runtime.odbc_dsn = NULL; - runtime.odbc_user = NULL; - runtime.odbc_pass = NULL; runtime.odbc_dbtype = DBTYPE_DEFAULT; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n"); sql_manager.dbh = NULL;