FS-10801: [core] Add a database interface to the FreeSWITCH Core.
This commit is contained in:
parent
fbbac95744
commit
07e0d4f90c
|
@ -24,6 +24,7 @@
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
*
|
*
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* switch_core.h -- Core Library Private Data (not to be installed into the system)
|
* switch_core.h -- Core Library Private Data (not to be installed into the system)
|
||||||
|
@ -334,6 +335,8 @@ extern struct switch_session_manager session_manager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch_status_t switch_core_sqldb_init(const char **err);
|
||||||
|
void switch_core_sqldb_destroy();
|
||||||
switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage);
|
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_sqldb_stop(void);
|
||||||
void switch_core_session_init(switch_memory_pool_t *pool);
|
void switch_core_session_init(switch_memory_pool_t *pool);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||||
* Joseph Sullivan <jossulli@amazon.com>
|
* Joseph Sullivan <jossulli@amazon.com>
|
||||||
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
* switch_core.h -- Core Library
|
* switch_core.h -- Core Library
|
||||||
*
|
*
|
||||||
|
@ -2474,13 +2475,15 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SCDB_TYPE_CORE_DB,
|
SCDB_TYPE_CORE_DB,
|
||||||
SCDB_TYPE_ODBC,
|
SCDB_TYPE_ODBC,
|
||||||
SCDB_TYPE_PGSQL
|
SCDB_TYPE_PGSQL,
|
||||||
|
SCDB_TYPE_DATABASE_INTERFACE
|
||||||
} switch_cache_db_handle_type_t;
|
} switch_cache_db_handle_type_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
switch_core_db_t *core_db_dbh;
|
switch_core_db_t *core_db_dbh;
|
||||||
switch_odbc_handle_t *odbc_dbh;
|
switch_odbc_handle_t *odbc_dbh;
|
||||||
switch_pgsql_handle_t *pgsql_dbh;
|
switch_pgsql_handle_t *pgsql_dbh;
|
||||||
|
switch_database_interface_handle_t *database_interface_dbh;
|
||||||
} switch_cache_db_native_handle_t;
|
} switch_cache_db_native_handle_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -2497,10 +2500,18 @@ typedef struct {
|
||||||
char *dsn;
|
char *dsn;
|
||||||
} switch_cache_db_pgsql_options_t;
|
} switch_cache_db_pgsql_options_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *dsn;
|
||||||
|
char prefix[16];
|
||||||
|
switch_database_interface_t *database_interface;
|
||||||
|
switch_bool_t make_module_no_unloadable;
|
||||||
|
} switch_cache_db_database_interface_options_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
switch_cache_db_core_db_options_t core_db_options;
|
switch_cache_db_core_db_options_t core_db_options;
|
||||||
switch_cache_db_odbc_options_t odbc_options;
|
switch_cache_db_odbc_options_t odbc_options;
|
||||||
switch_cache_db_pgsql_options_t pgsql_options;
|
switch_cache_db_pgsql_options_t pgsql_options;
|
||||||
|
switch_cache_db_database_interface_options_t database_interface_options;
|
||||||
} switch_cache_db_connection_options_t;
|
} switch_cache_db_connection_options_t;
|
||||||
|
|
||||||
struct switch_cache_db_handle;
|
struct switch_cache_db_handle;
|
||||||
|
@ -2511,6 +2522,11 @@ static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_
|
||||||
const char *type_str = "INVALID";
|
const char *type_str = "INVALID";
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
type_str = "DATABASE_INTERFACE";
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
type_str = "PGSQL";
|
type_str = "PGSQL";
|
||||||
|
@ -2559,6 +2575,8 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
const char *file, const char *func, int line);
|
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__)
|
#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_ex(switch_cache_db_handle_t **dbh, const char *dsn, switch_bool_t make_module_no_unloadable,
|
||||||
|
const char *file, const char *func, int line);
|
||||||
SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_db_handle_t **dbh, const char *dsn,
|
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);
|
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__)
|
#define switch_cache_db_get_db_handle_dsn(_a, _b) _switch_cache_db_get_db_handle_dsn(_a, _b, __FILE__, __SWITCH_FUNC__, __LINE__)
|
||||||
|
@ -2643,6 +2661,13 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(sw
|
||||||
const char *inner_post_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)
|
#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_cache_db_database_interface_flush_handles(switch_database_interface_t *database_interface);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns error if no suitable database interface found to serve core db dsn.
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_check_core_db_dsn();
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_core_set_signal_handlers(void);
|
SWITCH_DECLARE(void) switch_core_set_signal_handlers(void);
|
||||||
SWITCH_DECLARE(uint32_t) switch_core_debug_level(void);
|
SWITCH_DECLARE(uint32_t) switch_core_debug_level(void);
|
||||||
SWITCH_DECLARE(int32_t) switch_core_sps(void);
|
SWITCH_DECLARE(int32_t) switch_core_sps(void);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
*
|
*
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* switch_loadable_module.h -- Loadable Modules
|
* switch_loadable_module.h -- Loadable Modules
|
||||||
|
@ -51,6 +52,14 @@ SWITCH_BEGIN_EXTERN_C
|
||||||
\ingroup core1
|
\ingroup core1
|
||||||
\{
|
\{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*! \brief List of loadable module types */
|
||||||
|
typedef enum {
|
||||||
|
SWITCH_LOADABLE_MODULE_TYPE_PRELOAD,
|
||||||
|
SWITCH_LOADABLE_MODULE_TYPE_COMMON,
|
||||||
|
SWITCH_LOADABLE_MODULE_TYPE_POSTLOAD
|
||||||
|
} switch_loadable_module_type_t;
|
||||||
|
|
||||||
/*! \brief The abstraction of a loadable module */
|
/*! \brief The abstraction of a loadable module */
|
||||||
struct switch_loadable_module_interface {
|
struct switch_loadable_module_interface {
|
||||||
/*! the name of the module */
|
/*! the name of the module */
|
||||||
|
@ -87,6 +96,8 @@ SWITCH_BEGIN_EXTERN_C
|
||||||
switch_management_interface_t *management_interface;
|
switch_management_interface_t *management_interface;
|
||||||
/*! the table of limit interfaces the module has implemented */
|
/*! the table of limit interfaces the module has implemented */
|
||||||
switch_limit_interface_t *limit_interface;
|
switch_limit_interface_t *limit_interface;
|
||||||
|
/*! the table of database interfaces the module has implemented */
|
||||||
|
switch_database_interface_t *database_interface;
|
||||||
switch_thread_rwlock_t *rwlock;
|
switch_thread_rwlock_t *rwlock;
|
||||||
int refs;
|
int refs;
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
|
@ -205,6 +216,13 @@ SWITCH_DECLARE(switch_json_api_interface_t *) switch_loadable_module_get_json_ap
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(const char *name, const char *modname);
|
SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(const char *name, const char *modname);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Retrieve the database interface by it's registered name
|
||||||
|
\param name the name of the dsn prefix
|
||||||
|
\return the desired database format interface
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_database_interface_t *) switch_loadable_module_get_database_interface(const char *name, const char *modname);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Retrieve the speech interface by it's registered name
|
\brief Retrieve the speech interface by it's registered name
|
||||||
\param name the name of the speech interface
|
\param name the name of the speech interface
|
||||||
|
@ -311,6 +329,13 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(const char *d
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(switch_status_t) switch_loadable_module_exists(const char *mod);
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_exists(const char *mod);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Protect module from beeing unloaded
|
||||||
|
\param mod the module name
|
||||||
|
\return the status
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_protect(const char *mod);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Unoad a module
|
\brief Unoad a module
|
||||||
\param dir the directory where the module resides
|
\param dir the directory where the module resides
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*
|
*
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* switch_module_interfaces.h -- Module Interface Definitions
|
* switch_module_interfaces.h -- Module Interface Definitions
|
||||||
|
@ -614,6 +615,38 @@ struct switch_directory_handle {
|
||||||
void *private_info;
|
void *private_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*! \brief Abstract interface to a database module */
|
||||||
|
struct switch_database_interface {
|
||||||
|
/*! the name of the interface */
|
||||||
|
const char *interface_name;
|
||||||
|
switch_status_t(*handle_new)(char *dsn, switch_database_interface_handle_t **dih);
|
||||||
|
switch_status_t(*handle_destroy)(switch_database_interface_handle_t **dih);
|
||||||
|
switch_status_t(*flush)(switch_database_interface_handle_t *dih);
|
||||||
|
switch_status_t(*exec_detailed)(const char *file, const char *func, int line,
|
||||||
|
switch_database_interface_handle_t *dih, const char *sql, char **err);
|
||||||
|
switch_status_t(*exec_string)(switch_database_interface_handle_t *dih, const char *sql, char *resbuf, size_t len, char **err);
|
||||||
|
switch_status_t(*sql_set_auto_commit_attr)(switch_database_interface_handle_t *dih, switch_bool_t on);
|
||||||
|
switch_status_t(*commit)(switch_database_interface_handle_t *dih);
|
||||||
|
switch_status_t(*rollback)(switch_database_interface_handle_t *dih);
|
||||||
|
switch_status_t(*callback_exec_detailed)(const char *file, const char *func, int line,
|
||||||
|
switch_database_interface_handle_t *dih, const char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err);
|
||||||
|
switch_status_t(*affected_rows)(switch_database_interface_handle_t *dih, int *affected_rows);
|
||||||
|
|
||||||
|
/*! list of supported dsn prefixes */
|
||||||
|
char **prefixes;
|
||||||
|
switch_thread_rwlock_t *rwlock;
|
||||||
|
int refs;
|
||||||
|
switch_mutex_t *reflock;
|
||||||
|
switch_loadable_module_interface_t *parent;
|
||||||
|
struct switch_database_interface *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! an abstract representation of a database interface. */
|
||||||
|
struct switch_database_interface_handle {
|
||||||
|
switch_cache_db_database_interface_options_t connection_options;
|
||||||
|
void *handle;
|
||||||
|
};
|
||||||
|
|
||||||
struct switch_audio_codec_settings {
|
struct switch_audio_codec_settings {
|
||||||
int unused;
|
int unused;
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
* Joseph Sullivan <jossulli@amazon.com>
|
* Joseph Sullivan <jossulli@amazon.com>
|
||||||
* Raymond Chandler <intralanman@freeswitch.org>
|
* Raymond Chandler <intralanman@freeswitch.org>
|
||||||
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
* switch_types.h -- Data Types
|
* switch_types.h -- Data Types
|
||||||
*
|
*
|
||||||
|
@ -400,6 +401,7 @@ typedef enum {
|
||||||
SWITCH_LIMIT_INTERFACE,
|
SWITCH_LIMIT_INTERFACE,
|
||||||
SWITCH_CHAT_APPLICATION_INTERFACE,
|
SWITCH_CHAT_APPLICATION_INTERFACE,
|
||||||
SWITCH_JSON_API_INTERFACE,
|
SWITCH_JSON_API_INTERFACE,
|
||||||
|
SWITCH_DATABASE_INTERFACE,
|
||||||
} switch_module_interface_name_t;
|
} switch_module_interface_name_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -2290,6 +2292,7 @@ typedef struct switch_codec_fmtp switch_codec_fmtp_t;
|
||||||
typedef struct switch_odbc_handle switch_odbc_handle_t;
|
typedef struct switch_odbc_handle switch_odbc_handle_t;
|
||||||
typedef struct switch_pgsql_handle switch_pgsql_handle_t;
|
typedef struct switch_pgsql_handle switch_pgsql_handle_t;
|
||||||
typedef struct switch_pgsql_result switch_pgsql_result_t;
|
typedef struct switch_pgsql_result switch_pgsql_result_t;
|
||||||
|
typedef struct switch_database_interface_handle switch_database_interface_handle_t;
|
||||||
|
|
||||||
typedef struct switch_io_routines switch_io_routines_t;
|
typedef struct switch_io_routines switch_io_routines_t;
|
||||||
typedef struct switch_speech_handle switch_speech_handle_t;
|
typedef struct switch_speech_handle switch_speech_handle_t;
|
||||||
|
@ -2313,6 +2316,7 @@ typedef struct switch_management_interface switch_management_interface_t;
|
||||||
typedef struct switch_core_port_allocator switch_core_port_allocator_t;
|
typedef struct switch_core_port_allocator switch_core_port_allocator_t;
|
||||||
typedef struct switch_media_bug switch_media_bug_t;
|
typedef struct switch_media_bug switch_media_bug_t;
|
||||||
typedef struct switch_limit_interface switch_limit_interface_t;
|
typedef struct switch_limit_interface switch_limit_interface_t;
|
||||||
|
typedef struct switch_database_interface switch_database_interface_t;
|
||||||
|
|
||||||
typedef void (*hashtable_destructor_t)(void *ptr);
|
typedef void (*hashtable_destructor_t)(void *ptr);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
||||||
* Joseph Sullivan <jossulli@amazon.com>
|
* Joseph Sullivan <jossulli@amazon.com>
|
||||||
* Seven Du <dujinfang@gmail.com>
|
* Seven Du <dujinfang@gmail.com>
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
* switch_core.c -- Main Core Library
|
* switch_core.c -- Main Core Library
|
||||||
*
|
*
|
||||||
|
@ -2015,10 +2016,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
|
||||||
|
|
||||||
switch_core_state_machine_init(runtime.memory_pool);
|
switch_core_state_machine_init(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) {
|
|
||||||
*err = "Error activating database";
|
|
||||||
return SWITCH_STATUS_FALSE;
|
|
||||||
}
|
|
||||||
switch_core_media_init();
|
switch_core_media_init();
|
||||||
switch_scheduler_task_thread_start();
|
switch_scheduler_task_thread_start();
|
||||||
|
|
||||||
|
@ -2343,11 +2340,7 @@ static void switch_load_core_config(const char *file)
|
||||||
} else if (!strcasecmp(var, "core-db-name") && !zstr(val)) {
|
} else if (!strcasecmp(var, "core-db-name") && !zstr(val)) {
|
||||||
runtime.dbname = switch_core_strdup(runtime.memory_pool, val);
|
runtime.dbname = switch_core_strdup(runtime.memory_pool, val);
|
||||||
} else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) {
|
} 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);
|
runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val);
|
||||||
} else {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n");
|
|
||||||
}
|
|
||||||
} else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) {
|
} else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) {
|
||||||
switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ);
|
switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ);
|
||||||
} else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) {
|
} else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) {
|
||||||
|
@ -2425,6 +2418,20 @@ SWITCH_DECLARE(const char *) switch_core_banner(void)
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_status_t switch_core_sqldb_init(const char **err)
|
||||||
|
{
|
||||||
|
if (switch_core_check_core_db_dsn() != SWITCH_STATUS_SUCCESS) {
|
||||||
|
*err = "NO SUITABLE DATABASE INTERFACE IS AVAILABLE TO SERVE 'core-db-dsn'!\n";
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
*err = "Error activating database";
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
|
SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err)
|
||||||
{
|
{
|
||||||
|
@ -2969,6 +2976,13 @@ SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void)
|
||||||
return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;
|
return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void switch_core_sqldb_destroy()
|
||||||
|
{
|
||||||
|
if (switch_test_flag((&runtime), SCF_USE_SQL)) {
|
||||||
|
switch_core_sqldb_stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
|
SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
|
||||||
{
|
{
|
||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
|
@ -2989,9 +3003,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
|
||||||
|
|
||||||
switch_ssl_destroy_ssl_locks();
|
switch_ssl_destroy_ssl_locks();
|
||||||
|
|
||||||
if (switch_test_flag((&runtime), SCF_USE_SQL)) {
|
|
||||||
switch_core_sqldb_stop();
|
|
||||||
}
|
|
||||||
switch_scheduler_task_thread_stop();
|
switch_scheduler_task_thread_stop();
|
||||||
|
|
||||||
switch_rtp_shutdown();
|
switch_rtp_shutdown();
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* Michael Jerris <mike@jerris.com>
|
* Michael Jerris <mike@jerris.com>
|
||||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
* Paul D. Tinsley <pdt at jackhammer.org>
|
||||||
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* switch_core_sqldb.c -- Main Core Library (statistics tracker)
|
* switch_core_sqldb.c -- Main Core Library (statistics tracker)
|
||||||
|
@ -77,6 +78,9 @@ static struct {
|
||||||
static void switch_core_sqldb_start_thread(void);
|
static void switch_core_sqldb_start_thread(void);
|
||||||
static void switch_core_sqldb_stop_thread(void);
|
static void switch_core_sqldb_stop_thread(void);
|
||||||
|
|
||||||
|
#define database_interface_handle_callback_exec(database_interface, dih, sql, callback, pdata, err) database_interface->callback_exec_detailed(__FILE__, (char *)__SWITCH_FUNC__, __LINE__, dih, sql, callback, pdata, err)
|
||||||
|
#define database_interface_handle_exec(database_interface, dih, sql, err) database_interface->exec_detailed(__FILE__, (char *)__SWITCH_FUNC__, __LINE__, dih, sql, err)
|
||||||
|
|
||||||
static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t type)
|
static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t type)
|
||||||
{
|
{
|
||||||
switch_cache_db_handle_t *new_dbh = NULL;
|
switch_cache_db_handle_t *new_dbh = NULL;
|
||||||
|
@ -135,6 +139,35 @@ static void del_handle(switch_cache_db_handle_t *dbh)
|
||||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(void) switch_cache_db_database_interface_flush_handles(switch_database_interface_t *database_interface)
|
||||||
|
{
|
||||||
|
switch_cache_db_handle_t *dbh_ptr = NULL;
|
||||||
|
|
||||||
|
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||||
|
|
||||||
|
for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) {
|
||||||
|
if (switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (dbh_ptr->type != SCDB_TYPE_DATABASE_INTERFACE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dbh_ptr->native_handle.database_interface_dbh->connection_options.database_interface != database_interface) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping DB connection %s\n", dbh_ptr->name);
|
||||||
|
|
||||||
|
database_interface->handle_destroy(&dbh_ptr->native_handle.database_interface_dbh);
|
||||||
|
|
||||||
|
del_handle(dbh_ptr);
|
||||||
|
switch_mutex_unlock(dbh_ptr->mutex);
|
||||||
|
switch_core_destroy_memory_pool(&dbh_ptr->pool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user_str, const char *thread_str)
|
static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user_str, const char *thread_str)
|
||||||
{
|
{
|
||||||
switch_ssize_t hlen = -1;
|
switch_ssize_t hlen = -1;
|
||||||
|
@ -155,7 +188,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) {
|
for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) {
|
||||||
if (dbh_ptr->hash == hash && (dbh_ptr->type != SCDB_TYPE_PGSQL || !dbh_ptr->use_count) && !switch_test_flag(dbh_ptr, CDF_PRUNE) &&
|
if (dbh_ptr->hash == hash && ((dbh_ptr->type != SCDB_TYPE_PGSQL && dbh_ptr->type != SCDB_TYPE_DATABASE_INTERFACE) || !dbh_ptr->use_count) && !switch_test_flag(dbh_ptr, CDF_PRUNE) &&
|
||||||
switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) {
|
switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||||
r = dbh_ptr;
|
r = dbh_ptr;
|
||||||
break;
|
break;
|
||||||
|
@ -198,7 +231,7 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t
|
||||||
dsn = "core";
|
dsn = "core";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = _switch_cache_db_get_db_handle_dsn(dbh, dsn, file, func, line)) != SWITCH_STATUS_SUCCESS) {
|
if ((r = _switch_cache_db_get_db_handle_dsn_ex(dbh, dsn, SWITCH_TRUE, file, func, line)) != SWITCH_STATUS_SUCCESS) {
|
||||||
*dbh = NULL;
|
*dbh = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +267,12 @@ static void sql_close(time_t prune)
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", dbh->name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", dbh->name);
|
||||||
|
|
||||||
switch (dbh->type) {
|
switch (dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
database_interface->handle_destroy(&dbh->native_handle.database_interface_dbh);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_handle_destroy(&dbh->native_handle.pgsql_dbh);
|
switch_pgsql_handle_destroy(&dbh->native_handle.pgsql_dbh);
|
||||||
|
@ -299,6 +338,12 @@ SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t
|
||||||
if (dbh && *dbh) {
|
if (dbh && *dbh) {
|
||||||
|
|
||||||
switch((*dbh)->type) {
|
switch((*dbh)->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = (*dbh)->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
database_interface->flush((*dbh)->native_handle.database_interface_dbh);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_flush((*dbh)->native_handle.pgsql_dbh);
|
switch_pgsql_flush((*dbh)->native_handle.pgsql_dbh);
|
||||||
|
@ -331,29 +376,96 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t
|
||||||
switch_cache_db_release_db_handle(dbh);
|
switch_cache_db_release_db_handle(dbh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_core_check_core_db_dsn()
|
||||||
|
{
|
||||||
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
|
switch_database_interface_t *database_interface;
|
||||||
|
|
||||||
|
if (!runtime.odbc_dsn) {
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
char *colon_slashes = NULL;
|
||||||
|
if (NULL != (colon_slashes = strstr(runtime.odbc_dsn, "://")))
|
||||||
|
{
|
||||||
|
char prefix[16] = "";
|
||||||
|
strncpy(prefix, runtime.odbc_dsn, MIN(colon_slashes - runtime.odbc_dsn, 15));
|
||||||
|
|
||||||
|
if (!strncasecmp(prefix, "odbc", 4)) {
|
||||||
|
if (switch_odbc_available()) status = SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (!strncasecmp(prefix, "sqlite", 6)) {
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (!strncasecmp(prefix, "pgsql", 5)) {
|
||||||
|
if (switch_pgsql_available()) status = SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if ((database_interface = switch_loadable_module_get_database_interface(prefix, NULL))) {
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
UNPROTECT_INTERFACE(database_interface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strchr(runtime.odbc_dsn + 2, ':')) {
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_db_handle_t **dbh, const char *dsn,
|
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)
|
const char *file, const char *func, int line)
|
||||||
|
{
|
||||||
|
return _switch_cache_db_get_db_handle_dsn_ex(dbh, dsn, SWITCH_FALSE, file, func, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn_ex(switch_cache_db_handle_t **dbh, const char *dsn, switch_bool_t make_module_no_unloadable,
|
||||||
|
const char *file, const char *func, int line)
|
||||||
{
|
{
|
||||||
switch_cache_db_connection_options_t connection_options = { {0} };
|
switch_cache_db_connection_options_t connection_options = { {0} };
|
||||||
switch_cache_db_handle_type_t type;
|
switch_cache_db_handle_type_t type;
|
||||||
|
switch_database_interface_t *database_interface = NULL;
|
||||||
char tmp[256] = "";
|
char tmp[256] = "";
|
||||||
char *p;
|
char *p;
|
||||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
char *colon_slashes = NULL;
|
||||||
|
if ( NULL != (colon_slashes = strstr(dsn, "://")) )
|
||||||
|
{
|
||||||
|
char prefix[16] = "";
|
||||||
|
strncpy(prefix, dsn, MIN(colon_slashes - dsn, 15));
|
||||||
|
|
||||||
|
if ((database_interface = switch_loadable_module_get_database_interface(prefix, NULL))) {
|
||||||
|
type = SCDB_TYPE_DATABASE_INTERFACE;
|
||||||
|
connection_options.database_interface_options.make_module_no_unloadable = make_module_no_unloadable;
|
||||||
|
connection_options.database_interface_options.database_interface = database_interface;
|
||||||
|
connection_options.database_interface_options.dsn = colon_slashes + 3;
|
||||||
|
strcpy(connection_options.database_interface_options.prefix, prefix);
|
||||||
|
UNPROTECT_INTERFACE(database_interface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!connection_options.database_interface_options.dsn)
|
||||||
|
{
|
||||||
if (!strncasecmp(dsn, "pgsql://", 8)) {
|
if (!strncasecmp(dsn, "pgsql://", 8)) {
|
||||||
type = SCDB_TYPE_PGSQL;
|
type = SCDB_TYPE_PGSQL;
|
||||||
connection_options.pgsql_options.dsn = (char *)(dsn + 8);
|
connection_options.pgsql_options.dsn = (char *)(dsn + 8);
|
||||||
} else if (!strncasecmp(dsn, "sqlite://", 9)) {
|
}
|
||||||
|
else if (!strncasecmp(dsn, "sqlite://", 9)) {
|
||||||
type = SCDB_TYPE_CORE_DB;
|
type = SCDB_TYPE_CORE_DB;
|
||||||
connection_options.core_db_options.db_path = (char *)(dsn + 9);
|
connection_options.core_db_options.db_path = (char *)(dsn + 9);
|
||||||
} else if ((!(i = strncasecmp(dsn, "odbc://", 7))) || strchr(dsn+2, ':')) {
|
}
|
||||||
|
else if ((!(i = strncasecmp(dsn, "odbc://", 7))) || (strchr(dsn + 2, ':') && !colon_slashes)) {
|
||||||
type = SCDB_TYPE_ODBC;
|
type = SCDB_TYPE_ODBC;
|
||||||
|
|
||||||
if (i) {
|
if (i) {
|
||||||
switch_set_string(tmp, dsn);
|
switch_set_string(tmp, dsn);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
switch_set_string(tmp, dsn + 7);
|
switch_set_string(tmp, dsn + 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,10 +480,12 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_
|
||||||
connection_options.odbc_options.pass = p;
|
connection_options.odbc_options.pass = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
type = SCDB_TYPE_CORE_DB;
|
type = SCDB_TYPE_CORE_DB;
|
||||||
connection_options.core_db_options.db_path = (char *)dsn;
|
connection_options.core_db_options.db_path = (char *)dsn;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
status = _switch_cache_db_get_db_handle(dbh, type, &connection_options, file, func, line);
|
status = _switch_cache_db_get_db_handle(dbh, type, &connection_options, file, func, line);
|
||||||
|
|
||||||
|
@ -416,6 +530,14 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
db_name = connection_options->database_interface_options.dsn;
|
||||||
|
odbc_user = NULL;
|
||||||
|
odbc_pass = NULL;
|
||||||
|
db_type = "database_interface";
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
db_name = connection_options->pgsql_options.dsn;
|
db_name = connection_options->pgsql_options.dsn;
|
||||||
|
@ -423,6 +545,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
odbc_pass = NULL;
|
odbc_pass = NULL;
|
||||||
db_type = "pgsql";
|
db_type = "pgsql";
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_ODBC:
|
case SCDB_TYPE_ODBC:
|
||||||
{
|
{
|
||||||
db_name = connection_options->odbc_options.dsn;
|
db_name = connection_options->odbc_options.dsn;
|
||||||
|
@ -454,14 +577,41 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
snprintf(thread_str, sizeof(thread_str) - 1, "thread=\"%lu\"", (unsigned long) (intptr_t) self);
|
snprintf(thread_str, sizeof(thread_str) - 1, "thread=\"%lu\"", (unsigned long) (intptr_t) self);
|
||||||
|
|
||||||
if ((new_dbh = get_handle(db_str, db_callsite_str, thread_str))) {
|
if ((new_dbh = get_handle(db_str, db_callsite_str, thread_str))) {
|
||||||
|
if (type == SCDB_TYPE_DATABASE_INTERFACE) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
||||||
|
"Reuse Unused Cached DB handle %s [Database interface prefix: %s]\n", new_dbh->name, connection_options->database_interface_options.prefix);
|
||||||
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
||||||
"Reuse Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type));
|
"Reuse Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch_core_db_t *db = NULL;
|
switch_core_db_t *db = NULL;
|
||||||
switch_odbc_handle_t *odbc_dbh = NULL;
|
switch_odbc_handle_t *odbc_dbh = NULL;
|
||||||
switch_pgsql_handle_t *pgsql_dbh = NULL;
|
switch_pgsql_handle_t *pgsql_dbh = NULL;
|
||||||
|
switch_database_interface_handle_t *database_interface_dbh = NULL;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = connection_options->database_interface_options.database_interface;
|
||||||
|
|
||||||
|
if (SWITCH_STATUS_SUCCESS != database_interface->handle_new(connection_options->database_interface_options.dsn, &database_interface_dbh)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! Can't create new handle! Can't connect to DSN %s\n", connection_options->database_interface_options.dsn);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (database_interface_dbh) {
|
||||||
|
database_interface_dbh->connection_options = connection_options->database_interface_options;
|
||||||
|
|
||||||
|
if (connection_options->database_interface_options.make_module_no_unloadable == SWITCH_TRUE)
|
||||||
|
{
|
||||||
|
PROTECT_INTERFACE(database_interface)
|
||||||
|
switch_loadable_module_protect(database_interface->parent->module_name);
|
||||||
|
UNPROTECT_INTERFACE(database_interface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
if (!switch_pgsql_available()) {
|
if (!switch_pgsql_available()) {
|
||||||
|
@ -478,7 +628,6 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
break;
|
break;
|
||||||
case SCDB_TYPE_ODBC:
|
case SCDB_TYPE_ODBC:
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!switch_odbc_available()) {
|
if (!switch_odbc_available()) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC NOT AVAILABLE! Can't connect to DSN %s\n", connection_options->odbc_options.dsn);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC NOT AVAILABLE! Can't connect to DSN %s\n", connection_options->odbc_options.dsn);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -490,8 +639,6 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
switch_odbc_handle_destroy(&odbc_dbh);
|
switch_odbc_handle_destroy(&odbc_dbh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCDB_TYPE_CORE_DB:
|
case SCDB_TYPE_CORE_DB:
|
||||||
|
@ -504,7 +651,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!db && !odbc_dbh && !pgsql_dbh) {
|
if (!db && !odbc_dbh && !pgsql_dbh && !database_interface_dbh) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure to connect to %s %s!\n", switch_cache_db_type_name(type), db_name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure to connect to %s %s!\n", switch_cache_db_type_name(type), db_name);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -514,7 +661,9 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
||||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
||||||
"Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line);
|
"Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line);
|
||||||
|
|
||||||
if (db) {
|
if (database_interface_dbh) {
|
||||||
|
new_dbh->native_handle.database_interface_dbh = database_interface_dbh;
|
||||||
|
} else if (db) {
|
||||||
new_dbh->native_handle.core_db_dbh = db;
|
new_dbh->native_handle.core_db_dbh = db;
|
||||||
} else if (odbc_dbh) {
|
} else if (odbc_dbh) {
|
||||||
new_dbh->native_handle.odbc_dbh = odbc_dbh;
|
new_dbh->native_handle.odbc_dbh = odbc_dbh;
|
||||||
|
@ -552,6 +701,13 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (dbh->type) {
|
switch (dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
type = (char *)dbh->native_handle.database_interface_dbh->connection_options.prefix;
|
||||||
|
status = database_interface_handle_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, &errmsg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
type = "PGSQL";
|
type = "PGSQL";
|
||||||
|
@ -698,6 +854,13 @@ SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh)
|
||||||
return switch_odbc_handle_affected_rows(dbh->native_handle.odbc_dbh);
|
return switch_odbc_handle_affected_rows(dbh->native_handle.odbc_dbh);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
int affected_rows = 0;
|
||||||
|
database_interface->affected_rows(dbh->native_handle.database_interface_dbh, &affected_rows);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
return switch_pgsql_handle_affected_rows(dbh->native_handle.pgsql_dbh);
|
return switch_pgsql_handle_affected_rows(dbh->native_handle.pgsql_dbh);
|
||||||
|
@ -721,6 +884,11 @@ SWITCH_DECLARE(int) switch_cache_db_load_extension(switch_cache_db_handle_t *dbh
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "load extension not supported by type ODBC!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "load extension not supported by type ODBC!\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "load extension not supported by type DATABASE_INTERFACE!\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "load extension not supported by type PGSQL!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "load extension not supported by type PGSQL!\n");
|
||||||
|
@ -783,6 +951,12 @@ SWITCH_DECLARE(char *) switch_cache_db_execute_sql2str(switch_cache_db_handle_t
|
||||||
status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err);
|
status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
status = database_interface->exec_string(dbh->native_handle.database_interface_dbh, sql, str, len, err);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
status = switch_pgsql_handle_exec_string(dbh->native_handle.pgsql_dbh, sql, str, len, err);
|
status = switch_pgsql_handle_exec_string(dbh->native_handle.pgsql_dbh, sql, str, len, err);
|
||||||
|
@ -887,6 +1061,18 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(sw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface->sql_set_auto_commit_attr(dbh->native_handle.database_interface_dbh, 0)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result);
|
||||||
|
errmsg = strdup(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_status_t result;
|
switch_pgsql_status_t result;
|
||||||
|
@ -922,6 +1108,17 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(sw
|
||||||
switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
|
switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface->commit(dbh->native_handle.database_interface_dbh)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1);
|
switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1);
|
||||||
|
@ -997,6 +1194,17 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(sw
|
||||||
switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
|
switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface->commit(dbh->native_handle.database_interface_dbh)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1);
|
switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1);
|
||||||
|
@ -1058,6 +1266,17 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback(switc
|
||||||
h.pdata = pdata;
|
h.pdata = pdata;
|
||||||
|
|
||||||
switch (dbh->type) {
|
switch (dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, helper_callback, &h, err)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_event_callback", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, helper_callback, &h, err);
|
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, helper_callback, &h, err);
|
||||||
|
@ -1113,6 +1332,21 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback_err(s
|
||||||
h.pdata = pdata;
|
h.pdata = pdata;
|
||||||
|
|
||||||
switch (dbh->type) {
|
switch (dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, helper_callback, &h, err)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_event_callback_err", result);
|
||||||
|
} else {
|
||||||
|
if (err && *err) {
|
||||||
|
(*err_callback)(pdata, (const char*)*err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, helper_callback, &h, err);
|
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, helper_callback, &h, err);
|
||||||
|
@ -1173,6 +1407,17 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach
|
||||||
|
|
||||||
|
|
||||||
switch (dbh->type) {
|
switch (dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, callback, pdata, err)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_callback", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, callback, pdata, err);
|
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, callback, pdata, err);
|
||||||
|
@ -1223,6 +1468,21 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback_err(switch_
|
||||||
|
|
||||||
|
|
||||||
switch (dbh->type) {
|
switch (dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, callback, pdata, err)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_callback_err", result);
|
||||||
|
} else {
|
||||||
|
if (err && *err) {
|
||||||
|
(*err_callback)(pdata, (const char*)*err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, callback, pdata, err);
|
status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, callback, pdata, err);
|
||||||
|
@ -1318,6 +1578,31 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand
|
||||||
if (io_mutex) switch_mutex_lock(io_mutex);
|
if (io_mutex) switch_mutex_lock(io_mutex);
|
||||||
|
|
||||||
switch (dbh->type) {
|
switch (dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface_handle_exec(database_interface, dbh->native_handle.database_interface_dbh, test_sql, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to test_reactive with test_sql", result);
|
||||||
|
|
||||||
|
if (drop_sql) {
|
||||||
|
if ((result = database_interface_handle_exec(database_interface, dbh->native_handle.database_interface_dbh, drop_sql, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to test_reactive with drop_sql", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result = database_interface_handle_exec(database_interface, dbh->native_handle.database_interface_dbh, reactive_sql, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to test_reactive with reactive_sql", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
if (switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, test_sql, NULL) != SWITCH_PGSQL_SUCCESS) {
|
if (switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, test_sql, NULL) != SWITCH_PGSQL_SUCCESS) {
|
||||||
|
@ -1940,6 +2225,18 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = qm->event_db->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface->sql_set_auto_commit_attr(qm->event_db->native_handle.database_interface_dbh, 0)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result);
|
||||||
|
errmsg = strdup(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_status_t result;
|
switch_pgsql_status_t result;
|
||||||
|
@ -2016,6 +2313,17 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
|
||||||
switch_odbc_SQLSetAutoCommitAttr(qm->event_db->native_handle.odbc_dbh, 1);
|
switch_odbc_SQLSetAutoCommitAttr(qm->event_db->native_handle.odbc_dbh, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = qm->event_db->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface->commit(qm->event_db->native_handle.database_interface_dbh)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_SQLEndTran(qm->event_db->native_handle.pgsql_dbh, 1);
|
switch_pgsql_SQLEndTran(qm->event_db->native_handle.pgsql_dbh, 1);
|
||||||
|
@ -2072,6 +2380,8 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread,
|
||||||
switch_mutex_lock(qm->cond_mutex);
|
switch_mutex_lock(qm->cond_mutex);
|
||||||
|
|
||||||
switch (qm->event_db->type) {
|
switch (qm->event_db->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
break;
|
break;
|
||||||
case SCDB_TYPE_ODBC:
|
case SCDB_TYPE_ODBC:
|
||||||
|
@ -3390,6 +3700,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n");
|
||||||
|
|
||||||
switch (sql_manager.dbh->type) {
|
switch (sql_manager.dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
case SCDB_TYPE_ODBC:
|
case SCDB_TYPE_ODBC:
|
||||||
if (switch_test_flag((&runtime), SCF_CLEAR_SQL)) {
|
if (switch_test_flag((&runtime), SCF_CLEAR_SQL)) {
|
||||||
|
@ -3440,6 +3751,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
|
||||||
|
|
||||||
|
|
||||||
switch (sql_manager.dbh->type) {
|
switch (sql_manager.dbh->type) {
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
case SCDB_TYPE_ODBC:
|
case SCDB_TYPE_ODBC:
|
||||||
{
|
{
|
||||||
|
@ -3481,6 +3793,18 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = sql_manager.dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface->sql_set_auto_commit_attr(sql_manager.dbh->native_handle.database_interface_dbh, 0)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result);
|
||||||
|
err = strdup(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
switch_pgsql_status_t result;
|
switch_pgsql_status_t result;
|
||||||
|
@ -3514,6 +3838,18 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCDB_TYPE_DATABASE_INTERFACE:
|
||||||
|
{
|
||||||
|
switch_database_interface_t *database_interface = sql_manager.dbh->native_handle.database_interface_dbh->connection_options.database_interface;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
if ((result = database_interface->commit(sql_manager.dbh->native_handle.database_interface_dbh)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
char tmp[100];
|
||||||
|
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction", result);
|
||||||
|
err = strdup(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCDB_TYPE_PGSQL:
|
case SCDB_TYPE_PGSQL:
|
||||||
{
|
{
|
||||||
if (switch_pgsql_SQLEndTran(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS ||
|
if (switch_pgsql_SQLEndTran(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS ||
|
||||||
|
|
|
@ -25,12 +25,14 @@
|
||||||
*
|
*
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Seven Du <dujinfang@gmail.com>
|
* Seven Du <dujinfang@gmail.com>
|
||||||
|
* Andrey Volk <andywolk@gmail.com>
|
||||||
*
|
*
|
||||||
* switch_loadable_module.c -- Loadable Modules
|
* switch_loadable_module.c -- Loadable Modules
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include "private/switch_core_pvt.h"
|
||||||
|
|
||||||
/* for apr_pstrcat */
|
/* for apr_pstrcat */
|
||||||
#include <apr_strings.h>
|
#include <apr_strings.h>
|
||||||
|
@ -47,6 +49,12 @@ typedef struct switch_file_node_s {
|
||||||
struct switch_file_node_s *next;
|
struct switch_file_node_s *next;
|
||||||
} switch_file_node_t;
|
} switch_file_node_t;
|
||||||
|
|
||||||
|
typedef struct switch_database_node_s {
|
||||||
|
const switch_database_interface_t *ptr;
|
||||||
|
const char *interface_name;
|
||||||
|
struct switch_database_node_s *next;
|
||||||
|
} switch_database_node_t;
|
||||||
|
|
||||||
typedef struct switch_codec_node_s {
|
typedef struct switch_codec_node_s {
|
||||||
const switch_codec_interface_t *ptr;
|
const switch_codec_interface_t *ptr;
|
||||||
const char *interface_name;
|
const char *interface_name;
|
||||||
|
@ -67,6 +75,7 @@ struct switch_loadable_module {
|
||||||
switch_status_t status;
|
switch_status_t status;
|
||||||
switch_thread_t *thread;
|
switch_thread_t *thread;
|
||||||
switch_bool_t shutting_down;
|
switch_bool_t shutting_down;
|
||||||
|
switch_loadable_module_type_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct switch_loadable_module_container {
|
struct switch_loadable_module_container {
|
||||||
|
@ -87,6 +96,7 @@ struct switch_loadable_module_container {
|
||||||
switch_hash_t *say_hash;
|
switch_hash_t *say_hash;
|
||||||
switch_hash_t *management_hash;
|
switch_hash_t *management_hash;
|
||||||
switch_hash_t *limit_hash;
|
switch_hash_t *limit_hash;
|
||||||
|
switch_hash_t *database_hash;
|
||||||
switch_hash_t *secondary_recover_hash;
|
switch_hash_t *secondary_recover_hash;
|
||||||
switch_mutex_t *mutex;
|
switch_mutex_t *mutex;
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
|
@ -95,7 +105,7 @@ struct switch_loadable_module_container {
|
||||||
static struct switch_loadable_module_container loadable_modules;
|
static struct switch_loadable_module_container loadable_modules;
|
||||||
static switch_status_t do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload, switch_bool_t fail_if_busy,
|
static switch_status_t do_shutdown(switch_loadable_module_t *module, switch_bool_t shutdown, switch_bool_t unload, switch_bool_t fail_if_busy,
|
||||||
const char **err);
|
const char **err);
|
||||||
static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err);
|
static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash);
|
||||||
|
|
||||||
static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
|
static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
|
||||||
{
|
{
|
||||||
|
@ -143,11 +153,28 @@ static void switch_loadable_module_runtime(void)
|
||||||
switch_mutex_unlock(loadable_modules.mutex);
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module)
|
static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module, switch_hash_t *event_hash)
|
||||||
{
|
{
|
||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
|
int *event_num = NULL;
|
||||||
|
char str_event_num[10];
|
||||||
|
void *val;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
|
|
||||||
|
if (event_hash) {
|
||||||
|
if ((val = switch_core_hash_find(event_hash, "0"))) {
|
||||||
|
event_num = (int*)val;
|
||||||
|
} else {
|
||||||
|
if (!(event_num = malloc(sizeof(int)))) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Allocation error.\n");
|
||||||
|
return SWITCH_STATUS_MEMERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*event_num = 0;
|
||||||
|
switch_core_hash_insert(event_hash, "0", (const void*)event_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new_module->key = switch_core_strdup(new_module->pool, key);
|
new_module->key = switch_core_strdup(new_module->pool, key);
|
||||||
|
|
||||||
switch_mutex_lock(loadable_modules.mutex);
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
|
@ -166,7 +193,14 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
} else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +266,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +295,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.dialplan_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.dialplan_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -274,7 +324,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.timer_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.timer_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -297,7 +355,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.application_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.application_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -320,7 +386,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.chat_application_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.chat_application_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -343,7 +417,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.api_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.api_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -366,7 +448,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.json_api_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.json_api_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -394,7 +484,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
node = switch_core_alloc(new_module->pool, sizeof(*node));
|
node = switch_core_alloc(new_module->pool, sizeof(*node));
|
||||||
|
@ -410,6 +508,52 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_module->module_interface->database_interface) {
|
||||||
|
const switch_database_interface_t *ptr;
|
||||||
|
|
||||||
|
for (ptr = new_module->module_interface->database_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (!ptr->interface_name) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no interface name.\n", key);
|
||||||
|
}
|
||||||
|
else if (!ptr->prefixes) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load database interface from %s due to no prefixes.\n", key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
switch_database_node_t *node, *head;
|
||||||
|
|
||||||
|
for (i = 0; ptr->prefixes[i]; i++) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding dsn prefix '%s'\n", ptr->prefixes[i]);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->prefixes[i]);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", new_module->module_interface->module_name);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
|
added++;
|
||||||
|
}
|
||||||
|
node = switch_core_alloc(new_module->pool, sizeof(*node));
|
||||||
|
node->ptr = ptr;
|
||||||
|
node->interface_name = switch_core_strdup(new_module->pool, new_module->module_interface->module_name);
|
||||||
|
if ((head = switch_core_hash_find(loadable_modules.database_hash, ptr->prefixes[i]))) {
|
||||||
|
node->next = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (new_module->module_interface->speech_interface) {
|
if (new_module->module_interface->speech_interface) {
|
||||||
const switch_speech_interface_t *ptr;
|
const switch_speech_interface_t *ptr;
|
||||||
|
|
||||||
|
@ -423,7 +567,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.speech_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.speech_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -444,7 +596,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.asr_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.asr_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -465,7 +625,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.directory_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.directory_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -486,7 +654,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.chat_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.chat_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -507,7 +683,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
switch_core_hash_insert(loadable_modules.say_hash, ptr->interface_name, (const void *) ptr);
|
switch_core_hash_insert(loadable_modules.say_hash, ptr->interface_name, (const void *) ptr);
|
||||||
|
@ -534,7 +718,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->relative_oid);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->relative_oid);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,7 +753,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,7 +776,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "key", new_module->key);
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", new_module->filename);
|
||||||
|
|
||||||
|
if (!event_hash) {
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(str_event_num, "%i", ++*event_num);
|
||||||
|
switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event);
|
||||||
|
}
|
||||||
|
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1215,6 +1423,62 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old_module->module_interface->database_interface) {
|
||||||
|
const switch_database_interface_t *ptr;
|
||||||
|
switch_database_node_t *node, *head, *last = NULL;
|
||||||
|
|
||||||
|
for (ptr = old_module->module_interface->database_interface; ptr; ptr = ptr->next) {
|
||||||
|
if (ptr->interface_name) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n",
|
||||||
|
ptr->interface_name);
|
||||||
|
|
||||||
|
if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_thread_rwlock_unlock(ptr->rwlock);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; ptr->prefixes[i]; i++) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting dsn prefix '%s'\n", ptr->prefixes[i]);
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "database");
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->prefixes[i]);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "module", old_module->module_interface->module_name);
|
||||||
|
switch_event_fire(&event);
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((head = switch_core_hash_find(loadable_modules.database_hash, ptr->prefixes[i]))) {
|
||||||
|
for (node = head; node; node = node->next) {
|
||||||
|
if (!strcmp(node->interface_name, old_module->module_interface->module_name)) {
|
||||||
|
if (node == head) {
|
||||||
|
if ((node = node->next)) {
|
||||||
|
switch_core_hash_insert(loadable_modules.database_hash, ptr->prefixes[i], (const void *)node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch_core_hash_delete(loadable_modules.database_hash, ptr->prefixes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (last) {
|
||||||
|
last->next = node->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_cache_db_database_interface_flush_handles(old_module->module_interface->database_interface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (old_module->module_interface->speech_interface) {
|
if (old_module->module_interface->speech_interface) {
|
||||||
const switch_speech_interface_t *ptr;
|
const switch_speech_interface_t *ptr;
|
||||||
|
|
||||||
|
@ -1546,10 +1810,10 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena
|
||||||
}
|
}
|
||||||
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(const char *dir, const char *fname, switch_bool_t runtime, const char **err)
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(const char *dir, const char *fname, switch_bool_t runtime, const char **err)
|
||||||
{
|
{
|
||||||
return switch_loadable_module_load_module_ex(dir, fname, runtime, SWITCH_FALSE, err);
|
return switch_loadable_module_load_module_ex(dir, fname, runtime, SWITCH_FALSE, err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err)
|
static switch_status_t switch_loadable_module_load_module_ex(const char *dir, const char *fname, switch_bool_t runtime, switch_bool_t global, const char **err, switch_loadable_module_type_t type, switch_hash_t *event_hash)
|
||||||
{
|
{
|
||||||
switch_size_t len = 0;
|
switch_size_t len = 0;
|
||||||
char *path;
|
char *path;
|
||||||
|
@ -1593,7 +1857,9 @@ static switch_status_t switch_loadable_module_load_module_ex(const char *dir, co
|
||||||
*err = "Module already loaded";
|
*err = "Module already loaded";
|
||||||
status = SWITCH_STATUS_FALSE;
|
status = SWITCH_STATUS_FALSE;
|
||||||
} else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
|
} else if ((status = switch_loadable_module_load_file(path, file, global, &new_module)) == SWITCH_STATUS_SUCCESS) {
|
||||||
if ((status = switch_loadable_module_process(file, new_module)) == SWITCH_STATUS_SUCCESS && runtime) {
|
new_module->type = type;
|
||||||
|
|
||||||
|
if ((status = switch_loadable_module_process(file, new_module, event_hash)) == SWITCH_STATUS_SUCCESS && runtime) {
|
||||||
if (new_module->switch_module_runtime) {
|
if (new_module->switch_module_runtime) {
|
||||||
new_module->thread = switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
|
new_module->thread = switch_core_launch_thread(switch_loadable_module_exec, new_module, new_module->pool);
|
||||||
}
|
}
|
||||||
|
@ -1628,6 +1894,30 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_exists(const char *mod)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_protect(const char *mod)
|
||||||
|
{
|
||||||
|
switch_loadable_module_t *module = NULL;
|
||||||
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
|
|
||||||
|
if (zstr(mod)) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
|
if ((module = switch_core_hash_find(loadable_modules.module_hash, mod))) {
|
||||||
|
if (!module->perm) {
|
||||||
|
module->perm++;
|
||||||
|
}
|
||||||
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
status = SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(const char *dir, const char *fname, switch_bool_t force, const char **err)
|
SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(const char *dir, const char *fname, switch_bool_t force, const char **err)
|
||||||
{
|
{
|
||||||
switch_loadable_module_t *module = NULL;
|
switch_loadable_module_t *module = NULL;
|
||||||
|
@ -1801,7 +2091,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_build_dynamic(char *filen
|
||||||
module->thread = switch_core_launch_thread(switch_loadable_module_exec, module, module->pool);
|
module->thread = switch_core_launch_thread(switch_loadable_module_exec, module, module->pool);
|
||||||
}
|
}
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
|
||||||
return switch_loadable_module_process((char *) module->filename, module);
|
return switch_loadable_module_process((char *) module->filename, module, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -1826,12 +2116,17 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo
|
||||||
apr_finfo_t finfo = { 0 };
|
apr_finfo_t finfo = { 0 };
|
||||||
apr_dir_t *module_dir_handle = NULL;
|
apr_dir_t *module_dir_handle = NULL;
|
||||||
apr_int32_t finfo_flags = APR_FINFO_DIRENT | APR_FINFO_TYPE | APR_FINFO_NAME;
|
apr_int32_t finfo_flags = APR_FINFO_DIRENT | APR_FINFO_TYPE | APR_FINFO_NAME;
|
||||||
|
char *precf = "pre_load_modules.conf";
|
||||||
char *cf = "modules.conf";
|
char *cf = "modules.conf";
|
||||||
char *pcf = "post_load_modules.conf";
|
char *pcf = "post_load_modules.conf";
|
||||||
switch_xml_t cfg, xml;
|
switch_xml_t cfg, xml;
|
||||||
unsigned char all = 0;
|
unsigned char all = 0;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
const char *err;
|
const char *err;
|
||||||
|
switch_hash_t *event_hash;
|
||||||
|
switch_hash_index_t *hi;
|
||||||
|
void *hash_val;
|
||||||
|
switch_event_t *event;
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -1869,21 +2164,94 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo
|
||||||
switch_core_hash_init_nocase(&loadable_modules.say_hash);
|
switch_core_hash_init_nocase(&loadable_modules.say_hash);
|
||||||
switch_core_hash_init_nocase(&loadable_modules.management_hash);
|
switch_core_hash_init_nocase(&loadable_modules.management_hash);
|
||||||
switch_core_hash_init_nocase(&loadable_modules.limit_hash);
|
switch_core_hash_init_nocase(&loadable_modules.limit_hash);
|
||||||
|
switch_core_hash_init_nocase(&loadable_modules.database_hash);
|
||||||
switch_core_hash_init_nocase(&loadable_modules.dialplan_hash);
|
switch_core_hash_init_nocase(&loadable_modules.dialplan_hash);
|
||||||
switch_core_hash_init(&loadable_modules.secondary_recover_hash);
|
switch_core_hash_init(&loadable_modules.secondary_recover_hash);
|
||||||
switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED, loadable_modules.pool);
|
switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED, loadable_modules.pool);
|
||||||
|
|
||||||
if (!autoload) return SWITCH_STATUS_SUCCESS;
|
if (!autoload) return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, &err);
|
/*
|
||||||
switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_FALSE, &err);
|
switch_core_sqldb_init() is not yet ready and is executed after starting modules from pre_load_modules.conf
|
||||||
switch_loadable_module_load_module("", "CORE_SPEEX_MODULE", SWITCH_FALSE, &err);
|
Modules loading procedure generates events used by sqldb.
|
||||||
|
This is why we should hold those events (storing in the event_hash) not firing them until sqldb is ready.
|
||||||
|
*/
|
||||||
|
switch_core_hash_init(&event_hash);
|
||||||
|
|
||||||
|
switch_loadable_module_load_module_ex("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, SWITCH_FALSE, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, event_hash);
|
||||||
|
switch_loadable_module_load_module_ex("", "CORE_PCM_MODULE", SWITCH_FALSE, SWITCH_FALSE, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, event_hash);
|
||||||
|
switch_loadable_module_load_module_ex("", "CORE_SPEEX_MODULE", SWITCH_FALSE, SWITCH_FALSE, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, event_hash);
|
||||||
#ifdef SWITCH_HAVE_YUV
|
#ifdef SWITCH_HAVE_YUV
|
||||||
#ifdef SWITCH_HAVE_VPX
|
#ifdef SWITCH_HAVE_VPX
|
||||||
switch_loadable_module_load_module("", "CORE_VPX_MODULE", SWITCH_FALSE, &err);
|
switch_loadable_module_load_module_ex("", "CORE_VPX_MODULE", SWITCH_FALSE, SWITCH_FALSE, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, event_hash);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if ((xml = switch_xml_open_cfg(precf, &cfg, NULL))) {
|
||||||
|
switch_xml_t mods, ld;
|
||||||
|
if ((mods = switch_xml_child(cfg, "modules"))) {
|
||||||
|
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
|
||||||
|
switch_bool_t global = SWITCH_FALSE;
|
||||||
|
const char *val = switch_xml_attr_soft(ld, "module");
|
||||||
|
const char *path = switch_xml_attr_soft(ld, "path");
|
||||||
|
const char *critical = switch_xml_attr_soft(ld, "critical");
|
||||||
|
const char *sglobal = switch_xml_attr_soft(ld, "global");
|
||||||
|
|
||||||
|
if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
global = switch_true(sglobal);
|
||||||
|
|
||||||
|
if (path && zstr(path)) {
|
||||||
|
path = SWITCH_GLOBAL_dirs.mod_dir;
|
||||||
|
}
|
||||||
|
if (switch_loadable_module_load_module_ex((char *)path, (char *)val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_PRELOAD, event_hash) == SWITCH_STATUS_GENERR) {
|
||||||
|
if (critical && switch_true(critical)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
|
||||||
|
|
||||||
|
if ((hash_val = switch_core_hash_find(event_hash, "0"))) {
|
||||||
|
switch_safe_free(hash_val);
|
||||||
|
}
|
||||||
|
switch_core_hash_destroy(&event_hash);
|
||||||
|
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch_xml_free(xml);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "open of %s failed\n", cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_core_sqldb_init(&err) != SWITCH_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Loading modules interrupted. [Error: %s]\n", err);
|
||||||
|
if ((hash_val = switch_core_hash_find(event_hash, "0"))) {
|
||||||
|
switch_safe_free(hash_val);
|
||||||
|
}
|
||||||
|
switch_core_hash_destroy(&event_hash);
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sqldb is ready. Fire holding events! */
|
||||||
|
if ((hash_val = switch_core_hash_find(event_hash, "0"))) {
|
||||||
|
switch_safe_free(hash_val);
|
||||||
|
switch_core_hash_delete(event_hash, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hi = switch_core_hash_first(event_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||||
|
switch_core_hash_this(hi, NULL, NULL, &hash_val);
|
||||||
|
event = (switch_event_t *)hash_val;
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_hash_destroy(&event_hash);
|
||||||
|
|
||||||
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||||
switch_xml_t mods, ld;
|
switch_xml_t mods, ld;
|
||||||
if ((mods = switch_xml_child(cfg, "modules"))) {
|
if ((mods = switch_xml_child(cfg, "modules"))) {
|
||||||
|
@ -1902,7 +2270,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo
|
||||||
if (path && zstr(path)) {
|
if (path && zstr(path)) {
|
||||||
path = SWITCH_GLOBAL_dirs.mod_dir;
|
path = SWITCH_GLOBAL_dirs.mod_dir;
|
||||||
}
|
}
|
||||||
if (switch_loadable_module_load_module_ex(path, val, SWITCH_FALSE, global, &err) == SWITCH_STATUS_GENERR) {
|
if (switch_loadable_module_load_module_ex(path, val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_COMMON, NULL) == SWITCH_STATUS_GENERR) {
|
||||||
if (critical && switch_true(critical)) {
|
if (critical && switch_true(critical)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val);
|
||||||
abort();
|
abort();
|
||||||
|
@ -1935,7 +2303,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo
|
||||||
if (path && zstr(path)) {
|
if (path && zstr(path)) {
|
||||||
path = SWITCH_GLOBAL_dirs.mod_dir;
|
path = SWITCH_GLOBAL_dirs.mod_dir;
|
||||||
}
|
}
|
||||||
switch_loadable_module_load_module_ex(path, val, SWITCH_FALSE, global, &err);
|
switch_loadable_module_load_module_ex(path, val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_POSTLOAD, NULL);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2047,6 +2415,7 @@ SWITCH_DECLARE(void) switch_loadable_module_shutdown(void)
|
||||||
{
|
{
|
||||||
switch_hash_index_t *hi;
|
switch_hash_index_t *hi;
|
||||||
void *val;
|
void *val;
|
||||||
|
const void *key;
|
||||||
switch_loadable_module_t *module;
|
switch_loadable_module_t *module;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -2069,20 +2438,48 @@ SWITCH_DECLARE(void) switch_loadable_module_shutdown(void)
|
||||||
for (hi = switch_core_hash_first(loadable_modules.module_hash); hi; hi = switch_core_hash_next(&hi)) {
|
for (hi = switch_core_hash_first(loadable_modules.module_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||||
switch_core_hash_this(hi, NULL, NULL, &val);
|
switch_core_hash_this(hi, NULL, NULL, &val);
|
||||||
module = (switch_loadable_module_t *)val;
|
module = (switch_loadable_module_t *)val;
|
||||||
if (!module->perm) {
|
if (module->type != SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
|
||||||
do_shutdown(module, SWITCH_TRUE, SWITCH_FALSE, SWITCH_FALSE, NULL);
|
do_shutdown(module, SWITCH_TRUE, SWITCH_FALSE, SWITCH_FALSE, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_yield(1000000);
|
switch_yield(1000000);
|
||||||
|
|
||||||
|
for (hi = switch_core_hash_first(loadable_modules.module_hash); hi;) {
|
||||||
|
switch_core_hash_this(hi, &key, NULL, &val);
|
||||||
|
module = (switch_loadable_module_t *)val;
|
||||||
|
|
||||||
|
hi = switch_core_hash_next(&hi);
|
||||||
|
|
||||||
|
if (module->type != SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
|
||||||
|
if (do_shutdown(module, SWITCH_FALSE, SWITCH_TRUE, SWITCH_FALSE, NULL) == SWITCH_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
switch_core_hash_delete(loadable_modules.module_hash, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_sqldb_destroy();
|
||||||
|
|
||||||
|
for (hi = switch_core_hash_first(loadable_modules.module_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||||
|
switch_core_hash_this(hi, NULL, NULL, &val);
|
||||||
|
if ((module = (switch_loadable_module_t *)val)) {
|
||||||
|
if (module->type == SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
|
||||||
|
do_shutdown(module, SWITCH_TRUE, SWITCH_FALSE, SWITCH_FALSE, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_yield(1000000);
|
||||||
|
|
||||||
for (hi = switch_core_hash_first(loadable_modules.module_hash); hi; hi = switch_core_hash_next(&hi)) {
|
for (hi = switch_core_hash_first(loadable_modules.module_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||||
switch_core_hash_this(hi, NULL, NULL, &val);
|
switch_core_hash_this(hi, NULL, NULL, &val);
|
||||||
module = (switch_loadable_module_t *) val;
|
if ((module = (switch_loadable_module_t *)val)) {
|
||||||
if (!module->perm) {
|
if (module->type == SWITCH_LOADABLE_MODULE_TYPE_PRELOAD && !module->perm) {
|
||||||
do_shutdown(module, SWITCH_FALSE, SWITCH_TRUE, SWITCH_FALSE, NULL);
|
do_shutdown(module, SWITCH_FALSE, SWITCH_TRUE, SWITCH_FALSE, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch_core_hash_destroy(&loadable_modules.module_hash);
|
switch_core_hash_destroy(&loadable_modules.module_hash);
|
||||||
switch_core_hash_destroy(&loadable_modules.endpoint_hash);
|
switch_core_hash_destroy(&loadable_modules.endpoint_hash);
|
||||||
|
@ -2100,6 +2497,7 @@ SWITCH_DECLARE(void) switch_loadable_module_shutdown(void)
|
||||||
switch_core_hash_destroy(&loadable_modules.say_hash);
|
switch_core_hash_destroy(&loadable_modules.say_hash);
|
||||||
switch_core_hash_destroy(&loadable_modules.management_hash);
|
switch_core_hash_destroy(&loadable_modules.management_hash);
|
||||||
switch_core_hash_destroy(&loadable_modules.limit_hash);
|
switch_core_hash_destroy(&loadable_modules.limit_hash);
|
||||||
|
switch_core_hash_destroy(&loadable_modules.database_hash);
|
||||||
switch_core_hash_destroy(&loadable_modules.dialplan_hash);
|
switch_core_hash_destroy(&loadable_modules.dialplan_hash);
|
||||||
|
|
||||||
switch_core_destroy_memory_pool(&loadable_modules.pool);
|
switch_core_destroy_memory_pool(&loadable_modules.pool);
|
||||||
|
@ -2147,6 +2545,34 @@ SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interf
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_database_interface_t *) switch_loadable_module_get_database_interface(const char *name, const char *modname)
|
||||||
|
{
|
||||||
|
switch_database_interface_t *i = NULL;
|
||||||
|
switch_database_node_t *node, *head;
|
||||||
|
|
||||||
|
switch_mutex_lock(loadable_modules.mutex);
|
||||||
|
|
||||||
|
if ((head = switch_core_hash_find(loadable_modules.database_hash, name))) {
|
||||||
|
if (modname) {
|
||||||
|
for (node = head; node; node = node->next) {
|
||||||
|
if (!strcasecmp(node->interface_name, modname)) {
|
||||||
|
i = (switch_database_interface_t *)node->ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i = (switch_database_interface_t *)head->ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_unlock(loadable_modules.mutex);
|
||||||
|
|
||||||
|
if (i) PROTECT_INTERFACE(i);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(const char *name, const char *modname)
|
SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(const char *name, const char *modname)
|
||||||
{
|
{
|
||||||
switch_codec_interface_t *codec = NULL;
|
switch_codec_interface_t *codec = NULL;
|
||||||
|
@ -2711,6 +3137,9 @@ SWITCH_DECLARE(void *) switch_loadable_module_create_interface(switch_loadable_m
|
||||||
case SWITCH_LIMIT_INTERFACE:
|
case SWITCH_LIMIT_INTERFACE:
|
||||||
ALLOC_INTERFACE(limit)
|
ALLOC_INTERFACE(limit)
|
||||||
|
|
||||||
|
case SWITCH_DATABASE_INTERFACE:
|
||||||
|
ALLOC_INTERFACE(database)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Module Type!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Module Type!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue