2007-03-29 22:34:40 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2014-02-05 21:02:28 +00:00
* Copyright ( C ) 2005 - 2014 , Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Michael Jerris < mike @ jerris . com >
* Paul D . Tinsley < pdt at jackhammer . org >
2015-01-22 20:41:22 +00:00
* Emmanuel Schmidbauer < eschmidbauer @ gmail . com >
2007-03-29 22:34:40 +00:00
*
*
* switch_core_sqldb . c - - Main Core Library ( statistics tracker )
*
*/
2008-01-27 17:36:53 +00:00
2007-03-29 22:34:40 +00:00
# include <switch.h>
2007-05-14 17:10:46 +00:00
# include "private/switch_core_pvt.h"
2012-04-02 17:58:40 +00:00
2011-07-14 05:13:36 +00:00
# define SWITCH_SQL_QUEUE_LEN 100000
# define SWITCH_SQL_QUEUE_PAUSE_LEN 90000
2007-03-29 22:34:40 +00:00
2011-03-03 18:54:20 +00:00
struct switch_cache_db_handle {
char name [ CACHE_DB_LEN ] ;
switch_cache_db_handle_type_t type ;
switch_cache_db_native_handle_t native_handle ;
time_t last_used ;
switch_mutex_t * mutex ;
switch_mutex_t * io_mutex ;
switch_memory_pool_t * pool ;
int32_t flags ;
unsigned long hash ;
2011-03-07 21:18:46 +00:00
unsigned long thread_hash ;
2011-03-03 18:54:20 +00:00
char creator [ CACHE_DB_LEN ] ;
char last_user [ CACHE_DB_LEN ] ;
2011-03-07 21:18:46 +00:00
uint32_t use_count ;
2013-11-17 12:55:38 +00:00
uint64_t total_used_count ;
2011-03-03 18:54:20 +00:00
struct switch_cache_db_handle * next ;
} ;
2012-10-08 20:57:44 +00:00
static struct {
2009-12-05 18:54:56 +00:00
switch_memory_pool_t * memory_pool ;
2010-09-17 21:33:47 +00:00
switch_thread_t * db_thread ;
int db_thread_running ;
2009-12-05 18:54:56 +00:00
switch_bool_t manage ;
switch_mutex_t * io_mutex ;
switch_mutex_t * dbh_mutex ;
2012-07-12 19:30:37 +00:00
switch_mutex_t * ctl_mutex ;
2011-03-03 18:54:20 +00:00
switch_cache_db_handle_t * handle_pool ;
2011-03-04 19:52:30 +00:00
uint32_t total_handles ;
uint32_t total_used_handles ;
2012-07-12 19:30:37 +00:00
switch_cache_db_handle_t * dbh ;
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_t * qm ;
int paused ;
2012-10-08 20:57:44 +00:00
} sql_manager ;
2009-12-05 18:54:56 +00:00
2009-12-02 02:00:17 +00:00
2012-10-27 01:51:51 +00:00
static void switch_core_sqldb_start_thread ( void ) ;
static void switch_core_sqldb_stop_thread ( void ) ;
2011-03-07 21:18:46 +00:00
static switch_cache_db_handle_t * create_handle ( switch_cache_db_handle_type_t type )
2011-03-03 18:54:20 +00:00
{
2011-03-07 21:18:46 +00:00
switch_cache_db_handle_t * new_dbh = NULL ;
switch_memory_pool_t * pool = NULL ;
switch_core_new_memory_pool ( & pool ) ;
new_dbh = switch_core_alloc ( pool , sizeof ( * new_dbh ) ) ;
new_dbh - > pool = pool ;
new_dbh - > type = type ;
switch_mutex_init ( & new_dbh - > mutex , SWITCH_MUTEX_NESTED , new_dbh - > pool ) ;
return new_dbh ;
}
2012-10-08 20:57:44 +00:00
static void add_handle ( switch_cache_db_handle_t * dbh , const char * db_str , const char * db_callsite_str , const char * thread_str )
2011-03-07 21:18:46 +00:00
{
switch_ssize_t hlen = - 1 ;
2012-10-08 20:57:44 +00:00
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2011-03-07 21:18:46 +00:00
switch_set_string ( dbh - > creator , db_callsite_str ) ;
switch_set_string ( dbh - > name , db_str ) ;
dbh - > hash = switch_ci_hashfunc_default ( db_str , & hlen ) ;
dbh - > thread_hash = switch_ci_hashfunc_default ( thread_str , & hlen ) ;
dbh - > use_count + + ;
2013-11-17 12:55:38 +00:00
dbh - > total_used_count + + ;
2012-10-08 20:57:44 +00:00
sql_manager . total_used_handles + + ;
dbh - > next = sql_manager . handle_pool ;
2011-03-07 21:18:46 +00:00
2012-10-08 20:57:44 +00:00
sql_manager . handle_pool = dbh ;
sql_manager . total_handles + + ;
2011-03-04 02:07:43 +00:00
switch_mutex_lock ( dbh - > mutex ) ;
2012-10-08 20:57:44 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
2011-03-03 18:54:20 +00:00
}
2012-10-08 20:57:44 +00:00
static void del_handle ( switch_cache_db_handle_t * dbh )
2011-03-03 18:54:20 +00:00
{
2011-03-07 21:18:46 +00:00
switch_cache_db_handle_t * dbh_ptr , * last = NULL ;
2011-03-03 18:54:20 +00:00
2012-10-08 20:57:44 +00:00
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
for ( dbh_ptr = sql_manager . handle_pool ; dbh_ptr ; dbh_ptr = dbh_ptr - > next ) {
2011-03-07 21:18:46 +00:00
if ( dbh_ptr = = dbh ) {
2011-03-03 18:54:20 +00:00
if ( last ) {
2011-03-07 21:18:46 +00:00
last - > next = dbh_ptr - > next ;
2011-03-03 18:54:20 +00:00
} else {
2012-10-08 20:57:44 +00:00
sql_manager . handle_pool = dbh_ptr - > next ;
2011-03-03 18:54:20 +00:00
}
2012-10-08 20:57:44 +00:00
sql_manager . total_handles - - ;
2011-03-03 18:54:20 +00:00
break ;
}
2011-03-07 21:18:46 +00:00
last = dbh_ptr ;
2011-03-03 18:54:20 +00:00
}
2012-10-08 20:57:44 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
2011-03-03 18:54:20 +00:00
}
2012-10-08 20:57:44 +00:00
static switch_cache_db_handle_t * get_handle ( const char * db_str , const char * user_str , const char * thread_str )
2011-03-03 18:54:20 +00:00
{
switch_ssize_t hlen = - 1 ;
2011-03-07 21:18:46 +00:00
unsigned long hash = 0 , thread_hash = 0 ;
switch_cache_db_handle_t * dbh_ptr , * r = NULL ;
2011-03-03 18:54:20 +00:00
hash = switch_ci_hashfunc_default ( db_str , & hlen ) ;
2011-03-07 21:18:46 +00:00
thread_hash = switch_ci_hashfunc_default ( thread_str , & hlen ) ;
2011-03-03 18:54:20 +00:00
2012-10-08 20:57:44 +00:00
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2011-03-07 21:18:46 +00:00
2012-10-08 20:57:44 +00:00
for ( dbh_ptr = sql_manager . handle_pool ; dbh_ptr ; dbh_ptr = dbh_ptr - > next ) {
2012-11-20 14:09:02 +00:00
if ( dbh_ptr - > thread_hash = = thread_hash & & dbh_ptr - > hash = = hash & & ! dbh_ptr - > use_count & &
2011-03-07 21:18:46 +00:00
! switch_test_flag ( dbh_ptr , CDF_PRUNE ) & & switch_mutex_trylock ( dbh_ptr - > mutex ) = = SWITCH_STATUS_SUCCESS ) {
r = dbh_ptr ;
}
}
2013-11-17 12:55:38 +00:00
2011-03-07 21:18:46 +00:00
if ( ! r ) {
2012-10-08 20:57:44 +00:00
for ( dbh_ptr = sql_manager . handle_pool ; dbh_ptr ; dbh_ptr = dbh_ptr - > next ) {
2012-11-26 16:56:57 +00:00
if ( dbh_ptr - > hash = = hash & & ( dbh_ptr - > type ! = SCDB_TYPE_PGSQL | | ! dbh_ptr - > use_count ) & & ! switch_test_flag ( dbh_ptr , CDF_PRUNE ) & &
2011-03-07 21:18:46 +00:00
switch_mutex_trylock ( dbh_ptr - > mutex ) = = SWITCH_STATUS_SUCCESS ) {
r = dbh_ptr ;
2012-07-31 12:59:58 +00:00
break ;
}
}
2011-03-07 21:18:46 +00:00
}
if ( r ) {
r - > use_count + + ;
2013-11-17 12:55:38 +00:00
r - > total_used_count + + ;
2012-10-08 20:57:44 +00:00
sql_manager . total_used_handles + + ;
2011-03-07 21:18:46 +00:00
r - > hash = switch_ci_hashfunc_default ( db_str , & hlen ) ;
r - > thread_hash = thread_hash ;
switch_set_string ( r - > last_user , user_str ) ;
}
2012-10-08 20:57:44 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
2011-03-03 18:54:20 +00:00
return r ;
}
2009-12-02 02:00:17 +00:00
/*!
\ brief Open the default system database
*/
2010-06-30 15:35:03 +00:00
SWITCH_DECLARE ( switch_status_t ) _switch_core_db_handle ( switch_cache_db_handle_t * * dbh , const char * file , const char * func , int line )
2009-12-02 02:00:17 +00:00
{
2009-12-05 18:54:56 +00:00
switch_status_t r ;
2012-10-10 01:20:32 +00:00
char * dsn ;
2010-10-12 19:48:24 +00:00
2012-10-08 20:57:44 +00:00
if ( ! sql_manager . manage ) {
2010-10-12 19:48:24 +00:00
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2012-10-10 01:20:32 +00:00
if ( ! zstr ( runtime . odbc_dsn ) ) {
dsn = runtime . odbc_dsn ;
} else if ( ! zstr ( runtime . dbname ) ) {
dsn = runtime . dbname ;
2011-10-17 14:34:50 +00:00
} else {
2012-10-10 01:20:32 +00:00
dsn = " core " ;
2012-09-30 01:48:48 +00:00
}
2012-10-10 01:20:32 +00:00
if ( ( r = _switch_cache_db_get_db_handle_dsn ( dbh , dsn , file , func , line ) ) ! = SWITCH_STATUS_SUCCESS ) {
* dbh = NULL ;
2012-09-30 01:48:48 +00:00
}
2012-10-10 01:20:32 +00:00
2012-09-30 01:48:48 +00:00
return r ;
}
2012-05-18 00:57:02 +00:00
# define SQL_CACHE_TIMEOUT 30
2011-02-12 05:10:12 +00:00
# define SQL_REG_TIMEOUT 15
2009-11-14 21:59:01 +00:00
2011-03-03 01:21:37 +00:00
2012-10-08 20:57:44 +00:00
static void sql_close ( time_t prune )
2009-11-14 21:59:01 +00:00
{
switch_cache_db_handle_t * dbh = NULL ;
int locked = 0 ;
2012-10-31 15:31:23 +00:00
int sanity = 10000 ;
2010-02-06 03:38:24 +00:00
2012-10-08 20:57:44 +00:00
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2010-06-25 18:19:53 +00:00
top :
2009-11-14 21:59:01 +00:00
locked = 0 ;
2010-05-27 01:13:46 +00:00
2012-10-08 20:57:44 +00:00
for ( dbh = sql_manager . handle_pool ; dbh ; dbh = dbh - > next ) {
2011-03-03 18:54:20 +00:00
time_t diff = 0 ;
2010-05-27 01:13:46 +00:00
2011-03-03 18:54:20 +00:00
if ( prune > 0 & & prune > dbh - > last_used ) {
diff = ( time_t ) prune - dbh - > last_used ;
}
2010-02-06 03:38:24 +00:00
2011-03-07 21:18:46 +00:00
if ( prune > 0 & & ( dbh - > use_count | | ( diff < SQL_CACHE_TIMEOUT & & ! switch_test_flag ( dbh , CDF_PRUNE ) ) ) ) {
2011-03-03 18:54:20 +00:00
continue ;
}
2010-05-27 01:13:46 +00:00
2011-03-03 18:54:20 +00:00
if ( switch_mutex_trylock ( dbh - > mutex ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG10 , " Dropping idle DB connection %s \n " , dbh - > name ) ;
2010-05-27 01:13:46 +00:00
2011-03-03 18:54:20 +00:00
switch ( dbh - > type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
switch_pgsql_handle_destroy ( & dbh - > native_handle . pgsql_dbh ) ;
}
break ;
2011-03-03 18:54:20 +00:00
case SCDB_TYPE_ODBC :
{
switch_odbc_handle_destroy ( & dbh - > native_handle . odbc_dbh ) ;
}
break ;
case SCDB_TYPE_CORE_DB :
{
switch_core_db_close ( dbh - > native_handle . core_db_dbh ) ;
dbh - > native_handle . core_db_dbh = NULL ;
2009-11-14 21:59:01 +00:00
}
2011-03-03 18:54:20 +00:00
break ;
}
2009-11-14 21:59:01 +00:00
2012-10-08 20:57:44 +00:00
del_handle ( dbh ) ;
2011-03-03 18:54:20 +00:00
switch_mutex_unlock ( dbh - > mutex ) ;
switch_core_destroy_memory_pool ( & dbh - > pool ) ;
goto top ;
2010-02-06 03:38:24 +00:00
2011-03-03 18:54:20 +00:00
} else {
if ( ! prune ) {
2012-10-31 15:31:23 +00:00
if ( ! sanity ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SANITY CHECK FAILED! Handle %s (%s;%s) was not properly released. \n " ,
dbh - > name , dbh - > creator , dbh - > last_user ) ;
} else {
locked + + ;
}
2009-11-14 21:59:01 +00:00
}
2011-03-03 18:54:20 +00:00
continue ;
2009-11-14 21:59:01 +00:00
}
2011-03-03 18:54:20 +00:00
2009-11-14 21:59:01 +00:00
}
if ( locked ) {
2012-10-31 15:31:23 +00:00
if ( ! prune ) {
switch_cond_next ( ) ;
if ( sanity ) sanity - - ;
}
2009-11-14 21:59:01 +00:00
goto top ;
}
2012-10-08 20:57:44 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
2009-11-14 21:59:01 +00:00
}
2009-11-17 19:16:24 +00:00
2011-03-03 18:54:20 +00:00
SWITCH_DECLARE ( switch_cache_db_handle_type_t ) switch_cache_db_get_type ( switch_cache_db_handle_t * dbh )
{
return dbh - > type ;
}
2012-10-08 20:57:44 +00:00
SWITCH_DECLARE ( void ) switch_cache_db_flush_handles ( void )
2010-02-06 03:38:24 +00:00
{
2012-10-08 20:57:44 +00:00
sql_close ( switch_epoch_time_now ( NULL ) + SQL_CACHE_TIMEOUT + 1 ) ;
2009-12-17 00:03:17 +00:00
}
2012-10-04 20:19:38 +00:00
2012-10-08 20:57:44 +00:00
SWITCH_DECLARE ( void ) switch_cache_db_release_db_handle ( switch_cache_db_handle_t * * dbh )
2009-11-14 21:59:01 +00:00
{
if ( dbh & & * dbh ) {
2012-11-20 00:21:19 +00:00
switch ( ( * dbh ) - > type ) {
case SCDB_TYPE_PGSQL :
{
switch_pgsql_flush ( ( * dbh ) - > native_handle . pgsql_dbh ) ;
}
break ;
default :
break ;
}
2012-10-08 20:57:44 +00:00
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2011-03-03 01:21:37 +00:00
( * dbh ) - > last_used = switch_epoch_time_now ( NULL ) ;
2011-03-07 21:18:46 +00:00
2011-04-14 22:44:18 +00:00
( * dbh ) - > io_mutex = NULL ;
2011-03-07 21:18:46 +00:00
if ( ( * dbh ) - > use_count ) {
if ( - - ( * dbh ) - > use_count = = 0 ) {
( * dbh ) - > thread_hash = 1 ;
}
}
2009-11-14 21:59:01 +00:00
switch_mutex_unlock ( ( * dbh ) - > mutex ) ;
2012-10-08 20:57:44 +00:00
sql_manager . total_used_handles - - ;
2009-11-14 21:59:01 +00:00
* dbh = NULL ;
2012-10-08 20:57:44 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
2009-11-14 21:59:01 +00:00
}
}
2009-11-17 19:16:24 +00:00
2010-06-30 15:35:03 +00:00
SWITCH_DECLARE ( void ) switch_cache_db_dismiss_db_handle ( switch_cache_db_handle_t * * dbh )
2010-06-29 20:40:55 +00:00
{
2011-03-03 01:21:37 +00:00
switch_cache_db_release_db_handle ( dbh ) ;
2010-06-29 20:40:55 +00:00
}
2012-10-10 01:20:32 +00:00
SWITCH_DECLARE ( switch_status_t ) _switch_cache_db_get_db_handle_dsn ( switch_cache_db_handle_t * * dbh , const char * dsn ,
const char * file , const char * func , int line )
{
switch_cache_db_connection_options_t connection_options = { { 0 } } ;
switch_cache_db_handle_type_t type ;
char tmp [ 256 ] = " " ;
char * p ;
switch_status_t status = SWITCH_STATUS_FALSE ;
int i ;
2012-10-12 15:54:36 +00:00
if ( ! strncasecmp ( dsn , " pgsql:// " , 8 ) ) {
2012-10-10 01:20:32 +00:00
type = SCDB_TYPE_PGSQL ;
2012-10-12 15:54:36 +00:00
connection_options . pgsql_options . dsn = ( char * ) ( dsn + 8 ) ;
2013-02-05 20:52:55 +00:00
} else if ( ! strncasecmp ( dsn , " sqlite:// " , 9 ) ) {
type = SCDB_TYPE_CORE_DB ;
connection_options . core_db_options . db_path = ( char * ) ( dsn + 9 ) ;
2013-12-24 17:37:09 +00:00
} else if ( ( ! ( i = strncasecmp ( dsn , " odbc:// " , 7 ) ) ) | | strchr ( dsn + 2 , ' : ' ) ) {
2012-10-10 01:20:32 +00:00
type = SCDB_TYPE_ODBC ;
if ( i ) {
switch_set_string ( tmp , dsn ) ;
} else {
2012-11-02 17:49:39 +00:00
switch_set_string ( tmp , dsn + 7 ) ;
2012-10-10 01:20:32 +00:00
}
connection_options . odbc_options . dsn = tmp ;
if ( ( p = strchr ( tmp , ' : ' ) ) ) {
* p + + = ' \0 ' ;
connection_options . odbc_options . user = p ;
if ( ( p = strchr ( connection_options . odbc_options . user , ' : ' ) ) ) {
* p + + = ' \0 ' ;
connection_options . odbc_options . pass = p ;
}
}
} else {
type = SCDB_TYPE_CORE_DB ;
connection_options . core_db_options . db_path = ( char * ) dsn ;
}
status = _switch_cache_db_get_db_handle ( dbh , type , & connection_options , file , func , line ) ;
if ( status ! = SWITCH_STATUS_SUCCESS ) * dbh = NULL ;
return status ;
}
2012-10-08 20:57:44 +00:00
SWITCH_DECLARE ( switch_status_t ) _switch_cache_db_get_db_handle ( switch_cache_db_handle_t * * dbh ,
2010-02-06 03:38:24 +00:00
switch_cache_db_handle_type_t type ,
switch_cache_db_connection_options_t * connection_options ,
const char * file , const char * func , int line )
2009-11-14 21:59:01 +00:00
{
2011-03-07 21:18:46 +00:00
switch_thread_id_t self = switch_thread_self ( ) ;
char thread_str [ CACHE_DB_LEN ] = " " ;
2009-11-23 18:25:11 +00:00
char db_str [ CACHE_DB_LEN ] = " " ;
2009-11-27 16:47:08 +00:00
char db_callsite_str [ CACHE_DB_LEN ] = " " ;
2009-11-17 00:12:54 +00:00
switch_cache_db_handle_t * new_dbh = NULL ;
2011-03-04 19:52:30 +00:00
int waiting = 0 ;
uint32_t yield_len = 100000 , total_yield = 0 ;
2009-11-23 18:25:11 +00:00
2009-11-21 17:57:55 +00:00
const char * db_name = NULL ;
2012-09-30 01:48:48 +00:00
const char * odbc_user = NULL ;
const char * odbc_pass = NULL ;
2013-08-03 13:49:55 +00:00
const char * db_type = NULL ;
2009-11-21 17:57:55 +00:00
2012-10-08 20:57:44 +00:00
while ( runtime . max_db_handles & & sql_manager . total_handles > = runtime . max_db_handles & & sql_manager . total_used_handles > = sql_manager . total_handles ) {
2011-03-04 19:52:30 +00:00
if ( ! waiting + + ) {
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , NULL , SWITCH_LOG_WARNING , " Max handles %u exceeded, blocking.... \n " ,
runtime . max_db_handles ) ;
}
switch_yield ( yield_len ) ;
total_yield + = yield_len ;
if ( runtime . db_handle_timeout & & total_yield > runtime . db_handle_timeout ) {
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , NULL , SWITCH_LOG_ERROR , " Error connecting \n " ) ;
* dbh = NULL ;
return SWITCH_STATUS_FALSE ;
}
}
2009-11-21 17:57:55 +00:00
switch ( type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
2012-11-20 00:21:19 +00:00
db_name = connection_options - > pgsql_options . dsn ;
2012-09-30 01:48:48 +00:00
odbc_user = NULL ;
odbc_pass = NULL ;
2013-08-03 13:49:55 +00:00
db_type = " pgsql " ;
2012-09-30 01:48:48 +00:00
}
2009-11-21 17:57:55 +00:00
case SCDB_TYPE_ODBC :
{
db_name = connection_options - > odbc_options . dsn ;
2012-09-30 01:48:48 +00:00
odbc_user = connection_options - > odbc_options . user ;
odbc_pass = connection_options - > odbc_options . pass ;
2013-08-03 13:49:55 +00:00
db_type = " odbc " ;
2009-11-21 17:57:55 +00:00
}
break ;
case SCDB_TYPE_CORE_DB :
{
db_name = connection_options - > core_db_options . db_path ;
2012-09-30 01:48:48 +00:00
odbc_user = NULL ;
odbc_pass = NULL ;
2013-08-03 13:49:55 +00:00
db_type = " core_db " ;
2009-11-21 17:57:55 +00:00
}
break ;
}
if ( ! db_name ) {
return SWITCH_STATUS_FALSE ;
}
2009-11-14 21:59:01 +00:00
2012-09-30 01:48:48 +00:00
if ( odbc_user | | odbc_pass ) {
2013-08-03 13:49:55 +00:00
snprintf ( db_str , sizeof ( db_str ) - 1 , " db= \" %s \" ;type= \" %s \" user= \" %s \" ;pass= \" %s \" " , db_name , db_type , odbc_user , odbc_pass ) ;
2012-09-30 01:48:48 +00:00
} else {
2013-08-03 13:49:55 +00:00
snprintf ( db_str , sizeof ( db_str ) - 1 , " db= \" %s \" ,type= \" %s \" " , db_name , db_type ) ;
2012-09-30 01:48:48 +00:00
}
2009-11-27 16:47:08 +00:00
snprintf ( db_callsite_str , sizeof ( db_callsite_str ) - 1 , " %s:%d " , file , line ) ;
2011-03-07 21:18:46 +00:00
snprintf ( thread_str , sizeof ( thread_str ) - 1 , " thread= \" %lu \" " , ( unsigned long ) ( intptr_t ) self ) ;
2010-02-06 03:38:24 +00:00
2012-10-08 20:57:44 +00:00
if ( ( new_dbh = get_handle ( db_str , db_callsite_str , thread_str ) ) ) {
2011-03-03 18:54:20 +00:00
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 ) ) ;
} else {
2009-11-14 21:59:01 +00:00
switch_core_db_t * db = NULL ;
switch_odbc_handle_t * odbc_dbh = NULL ;
2012-09-30 01:48:48 +00:00
switch_pgsql_handle_t * pgsql_dbh = NULL ;
2009-11-14 21:59:01 +00:00
2009-11-21 17:57:55 +00:00
switch ( type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
if ( ! switch_pgsql_available ( ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failure! PGSQL NOT AVAILABLE! Can't connect to DSN %s \n " , connection_options - > pgsql_options . dsn ) ;
goto end ;
}
if ( ( pgsql_dbh = switch_pgsql_handle_new ( connection_options - > pgsql_options . dsn ) ) ) {
if ( switch_pgsql_handle_connect ( pgsql_dbh ) ! = SWITCH_PGSQL_SUCCESS ) {
switch_pgsql_handle_destroy ( & pgsql_dbh ) ;
}
}
}
break ;
2009-11-21 17:57:55 +00:00
case SCDB_TYPE_ODBC :
{
if ( ! switch_odbc_available ( ) ) {
2012-04-10 21:17:16 +00:00
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 ) ;
2009-11-21 17:57:55 +00:00
goto end ;
}
2010-02-06 03:38:24 +00:00
if ( ( odbc_dbh = switch_odbc_handle_new ( connection_options - > odbc_options . dsn ,
connection_options - > odbc_options . user , connection_options - > odbc_options . pass ) ) ) {
2010-04-17 11:13:25 +00:00
if ( switch_odbc_handle_connect ( odbc_dbh ) ! = SWITCH_ODBC_SUCCESS ) {
2009-11-21 17:57:55 +00:00
switch_odbc_handle_destroy ( & odbc_dbh ) ;
}
2009-11-14 21:59:01 +00:00
}
2010-02-06 03:38:24 +00:00
2009-11-21 17:57:55 +00:00
2009-11-14 21:59:01 +00:00
}
2009-11-21 17:57:55 +00:00
break ;
case SCDB_TYPE_CORE_DB :
{
db = switch_core_db_open_file ( connection_options - > core_db_options . db_path ) ;
}
break ;
default :
goto end ;
2009-11-14 21:59:01 +00:00
}
2012-09-30 01:48:48 +00:00
if ( ! db & & ! odbc_dbh & & ! pgsql_dbh ) {
2013-02-08 01:27:36 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failure to connect to %s %s! \n " , switch_cache_db_type_name ( type ) , db_name ) ;
2009-11-14 21:59:01 +00:00
goto end ;
}
2013-05-09 19:34:39 +00:00
new_dbh = create_handle ( type ) ;
2012-10-08 20:57:44 +00:00
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 ) ;
2010-07-23 21:15:10 +00:00
if ( db ) {
2010-02-06 03:38:24 +00:00
new_dbh - > native_handle . core_db_dbh = db ;
2012-09-30 01:48:48 +00:00
} else if ( odbc_dbh ) {
2010-02-06 03:38:24 +00:00
new_dbh - > native_handle . odbc_dbh = odbc_dbh ;
2012-09-30 01:48:48 +00:00
} else {
new_dbh - > native_handle . pgsql_dbh = pgsql_dbh ;
2010-07-23 21:15:10 +00:00
}
2012-10-08 20:57:44 +00:00
add_handle ( new_dbh , db_str , db_callsite_str , thread_str ) ;
2009-11-14 21:59:01 +00:00
}
2010-06-25 18:19:53 +00:00
end :
2009-11-14 21:59:01 +00:00
2010-07-23 21:15:10 +00:00
if ( new_dbh ) {
2010-02-06 03:38:24 +00:00
new_dbh - > last_used = switch_epoch_time_now ( NULL ) ;
2010-07-23 21:15:10 +00:00
}
2011-03-04 02:07:43 +00:00
2009-11-17 00:12:54 +00:00
* dbh = new_dbh ;
return * dbh ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE ;
2009-11-14 21:59:01 +00:00
}
2009-11-20 23:12:07 +00:00
static switch_status_t switch_cache_db_execute_sql_real ( switch_cache_db_handle_t * dbh , const char * sql , char * * err )
2009-11-14 21:59:01 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2009-11-17 00:12:54 +00:00
char * errmsg = NULL ;
2010-06-07 21:47:35 +00:00
char * tmp = NULL ;
2012-10-08 20:56:05 +00:00
char * type = NULL ;
2011-03-01 16:52:12 +00:00
switch_mutex_t * io_mutex = dbh - > io_mutex ;
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2009-11-17 00:12:54 +00:00
2011-03-01 16:52:12 +00:00
if ( err ) {
2010-02-06 03:38:24 +00:00
* err = NULL ;
2011-03-01 16:52:12 +00:00
}
2010-02-06 03:38:24 +00:00
2009-11-21 17:57:55 +00:00
switch ( dbh - > type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
2012-10-08 20:56:05 +00:00
type = " PGSQL " ;
2012-09-30 01:48:48 +00:00
status = switch_pgsql_handle_exec ( dbh - > native_handle . pgsql_dbh , sql , & errmsg ) ;
}
break ;
2009-11-21 17:57:55 +00:00
case SCDB_TYPE_ODBC :
{
2012-10-08 20:56:05 +00:00
type = " ODBC " ;
2010-07-23 05:36:40 +00:00
status = switch_odbc_handle_exec ( dbh - > native_handle . odbc_dbh , sql , NULL , & errmsg ) ;
2009-11-14 21:59:01 +00:00
}
2009-11-21 17:57:55 +00:00
break ;
case SCDB_TYPE_CORE_DB :
{
2012-03-09 17:28:29 +00:00
int ret = switch_core_db_exec ( dbh - > native_handle . core_db_dbh , sql , NULL , NULL , & errmsg ) ;
2012-10-08 20:56:05 +00:00
type = " NATIVE " ;
2012-03-09 17:28:29 +00:00
if ( ret = = SWITCH_CORE_DB_OK ) {
status = SWITCH_STATUS_SUCCESS ;
}
2010-06-07 21:47:35 +00:00
if ( errmsg ) {
switch_strdup ( tmp , errmsg ) ;
switch_core_db_free ( errmsg ) ;
errmsg = tmp ;
}
2009-11-21 17:57:55 +00:00
}
break ;
2009-11-14 21:59:01 +00:00
}
2009-11-17 00:12:54 +00:00
if ( errmsg ) {
2009-12-09 16:06:30 +00:00
if ( ! switch_stristr ( " already exists " , errmsg ) & & ! switch_stristr ( " duplicate key name " , errmsg ) ) {
2012-10-08 20:56:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " %s SQL ERR [%s] \n %s \n " , ( type ? type : " Unknown " ) , errmsg , sql ) ;
2009-11-17 00:12:54 +00:00
}
if ( err ) {
* err = errmsg ;
} else {
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2009-11-17 00:12:54 +00:00
}
}
2009-12-05 18:54:56 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2010-02-06 03:38:24 +00:00
2009-11-20 23:12:07 +00:00
return status ;
}
/**
OMFG you cruel bastards . Who chooses 64 k as a max buffer len for a sql statement , have you ever heard of transactions ?
2010-06-25 18:19:53 +00:00
* */
2009-11-21 17:57:55 +00:00
static switch_status_t switch_cache_db_execute_sql_chunked ( switch_cache_db_handle_t * dbh , char * sql , uint32_t chunk_size , char * * err )
2009-11-20 23:12:07 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
char * p , * s , * e ;
2014-01-22 21:28:53 +00:00
switch_size_t chunk_count ;
2009-11-20 23:12:07 +00:00
switch_size_t len ;
2009-11-25 20:55:19 +00:00
2009-11-20 23:12:07 +00:00
switch_assert ( chunk_size ) ;
2010-02-06 03:38:24 +00:00
if ( err )
* err = NULL ;
2009-11-20 23:12:07 +00:00
len = strlen ( sql ) ;
if ( chunk_size > len ) {
return switch_cache_db_execute_sql_real ( dbh , sql , err ) ;
}
if ( ! ( chunk_count = strlen ( sql ) / chunk_size ) ) {
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2009-11-21 17:57:55 +00:00
e = end_of_p ( sql ) ;
s = sql ;
2009-11-20 23:12:07 +00:00
2010-02-06 03:38:24 +00:00
while ( s & & s < e ) {
2009-11-20 23:12:07 +00:00
p = s + chunk_size ;
if ( p > e ) {
p = e ;
}
2010-02-06 03:38:24 +00:00
2009-11-25 20:55:19 +00:00
while ( p > s ) {
2010-02-06 03:38:24 +00:00
if ( * p = = ' \n ' & & * ( p - 1 ) = = ' ; ' ) {
2009-11-25 20:55:19 +00:00
* p = ' \0 ' ;
2010-02-06 03:38:24 +00:00
* ( p - 1 ) = ' \0 ' ;
2009-12-01 22:09:04 +00:00
p + + ;
2009-11-25 20:55:19 +00:00
break ;
}
2010-02-06 03:38:24 +00:00
2009-11-20 23:12:07 +00:00
p - - ;
}
2010-02-06 03:38:24 +00:00
if ( p < = s )
break ;
2009-11-20 23:12:07 +00:00
status = switch_cache_db_execute_sql_real ( dbh , s , err ) ;
if ( status ! = SWITCH_STATUS_SUCCESS | | ( err & & * err ) ) {
break ;
}
2009-11-25 20:55:19 +00:00
s = p ;
2010-02-06 03:38:24 +00:00
2009-11-20 23:12:07 +00:00
}
return status ;
}
2009-11-21 17:57:55 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_execute_sql ( switch_cache_db_handle_t * dbh , char * sql , char * * err )
2009-11-20 23:12:07 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2011-03-01 16:52:12 +00:00
switch_mutex_t * io_mutex = dbh - > io_mutex ;
2009-11-20 23:12:07 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2009-11-21 17:57:55 +00:00
switch ( dbh - > type ) {
default :
{
2010-09-14 21:19:03 +00:00
status = switch_cache_db_execute_sql_chunked ( dbh , ( char * ) sql , 32768 , err ) ;
2009-11-21 17:57:55 +00:00
}
break ;
2009-11-20 23:12:07 +00:00
}
2009-11-21 17:57:55 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2009-12-05 18:54:56 +00:00
2009-11-14 21:59:01 +00:00
return status ;
}
2009-11-21 18:57:15 +00:00
2011-01-05 17:45:48 +00:00
SWITCH_DECLARE ( int ) switch_cache_db_affected_rows ( switch_cache_db_handle_t * dbh )
{
switch ( dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
return switch_core_db_changes ( dbh - > native_handle . core_db_dbh ) ;
}
break ;
case SCDB_TYPE_ODBC :
{
return switch_odbc_handle_affected_rows ( dbh - > native_handle . odbc_dbh ) ;
}
break ;
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
return switch_pgsql_handle_affected_rows ( dbh - > native_handle . pgsql_dbh ) ;
}
break ;
2011-01-05 17:45:48 +00:00
}
return 0 ;
}
2012-11-29 14:58:44 +00:00
SWITCH_DECLARE ( int ) switch_cache_db_load_extension ( switch_cache_db_handle_t * dbh , const char * extension )
{
switch ( dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " try to load extension [%s]! \n " , extension ) ;
return switch_core_db_load_extension ( dbh - > native_handle . core_db_dbh , extension ) ;
}
break ;
case SCDB_TYPE_ODBC :
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " load extension not supported by type ODBC! \n " ) ;
}
break ;
case SCDB_TYPE_PGSQL :
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " load extension not supported by type PGSQL! \n " ) ;
}
break ;
}
return 0 ;
}
2011-01-05 17:45:48 +00:00
2009-11-21 18:57:15 +00:00
SWITCH_DECLARE ( char * ) switch_cache_db_execute_sql2str ( switch_cache_db_handle_t * dbh , char * sql , char * str , size_t len , char * * err )
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2011-03-01 16:52:12 +00:00
switch_mutex_t * io_mutex = dbh - > io_mutex ;
2009-11-21 18:57:15 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2009-12-05 18:54:56 +00:00
2011-03-25 22:05:13 +00:00
memset ( str , 0 , len ) ;
2009-11-21 18:57:15 +00:00
switch ( dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
switch_core_db_stmt_t * stmt ;
2010-02-06 03:38:24 +00:00
2009-11-21 18:57:15 +00:00
if ( switch_core_db_prepare ( dbh - > native_handle . core_db_dbh , sql , - 1 , & stmt , 0 ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Statement Error [%s]! \n " , sql ) ;
2011-03-01 16:52:12 +00:00
goto end ;
2009-11-21 18:57:15 +00:00
} else {
int running = 1 ;
int colcount ;
while ( running < 5000 ) {
int result = switch_core_db_step ( stmt ) ;
const unsigned char * txt ;
2010-02-06 03:38:24 +00:00
2009-11-21 18:57:15 +00:00
if ( result = = SWITCH_CORE_DB_ROW ) {
if ( ( colcount = switch_core_db_column_count ( stmt ) ) > 0 ) {
if ( ( txt = switch_core_db_column_text ( stmt , 0 ) ) ) {
switch_copy_string ( str , ( char * ) txt , len ) ;
status = SWITCH_STATUS_SUCCESS ;
} else {
goto end ;
}
}
break ;
} else if ( result = = SWITCH_CORE_DB_BUSY ) {
running + + ;
switch_cond_next ( ) ;
continue ;
}
break ;
}
2010-02-06 03:38:24 +00:00
2009-11-21 18:57:15 +00:00
switch_core_db_finalize ( stmt ) ;
}
}
break ;
case SCDB_TYPE_ODBC :
{
2010-01-13 01:40:11 +00:00
status = switch_odbc_handle_exec_string ( dbh - > native_handle . odbc_dbh , sql , str , len , err ) ;
2009-11-21 18:57:15 +00:00
}
break ;
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
status = switch_pgsql_handle_exec_string ( dbh - > native_handle . pgsql_dbh , sql , str , len , err ) ;
}
break ;
2009-11-21 18:57:15 +00:00
}
2010-06-25 18:19:53 +00:00
end :
2009-11-21 18:57:15 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2009-12-05 18:54:56 +00:00
2009-11-21 18:57:15 +00:00
return status = = SWITCH_STATUS_SUCCESS ? str : NULL ;
}
2009-11-17 15:59:13 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_persistant_execute ( switch_cache_db_handle_t * dbh , const char * sql , uint32_t retries )
2009-11-14 21:59:01 +00:00
{
char * errmsg = NULL ;
2009-11-17 00:12:54 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
uint8_t forever = 0 ;
2011-03-01 16:52:12 +00:00
switch_mutex_t * io_mutex = dbh - > io_mutex ;
2009-11-17 00:12:54 +00:00
if ( ! retries ) {
forever = 1 ;
retries = 1000 ;
}
while ( retries > 0 ) {
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2009-11-21 17:57:55 +00:00
switch_cache_db_execute_sql_real ( dbh , sql , & errmsg ) ;
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2009-11-14 21:59:01 +00:00
if ( errmsg ) {
2009-11-17 00:12:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR [%s] \n " , errmsg ) ;
switch_safe_free ( errmsg ) ;
switch_yield ( 100000 ) ;
retries - - ;
if ( retries = = 0 & & forever ) {
retries = 1000 ;
continue ;
}
} else {
status = SWITCH_STATUS_SUCCESS ;
break ;
2009-11-14 21:59:01 +00:00
}
}
2011-03-01 16:52:12 +00:00
2009-11-14 21:59:01 +00:00
return status ;
}
2009-11-21 17:57:55 +00:00
2012-10-10 01:20:32 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_persistant_execute_trans_full ( switch_cache_db_handle_t * dbh ,
char * sql , uint32_t retries ,
const char * pre_trans_execute ,
const char * post_trans_execute ,
const char * inner_pre_trans_execute ,
const char * inner_post_trans_execute )
2007-03-29 22:34:40 +00:00
{
2009-11-17 00:12:54 +00:00
char * errmsg = NULL ;
2007-03-29 22:34:40 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
uint8_t forever = 0 ;
unsigned begin_retries = 100 ;
uint8_t again = 0 ;
2011-03-01 16:52:12 +00:00
switch_mutex_t * io_mutex = dbh - > io_mutex ;
2010-02-06 03:38:24 +00:00
2007-03-29 22:34:40 +00:00
if ( ! retries ) {
forever = 1 ;
retries = 1000 ;
}
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2009-12-05 18:54:56 +00:00
2012-10-10 01:20:32 +00:00
if ( ! zstr ( pre_trans_execute ) ) {
switch_cache_db_execute_sql_real ( dbh , pre_trans_execute , & errmsg ) ;
2012-04-26 16:12:11 +00:00
if ( errmsg ) {
2012-10-10 01:20:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL PRE TRANS EXEC %s [%s] \n " , pre_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-04-26 16:12:11 +00:00
}
}
2010-06-25 18:19:53 +00:00
again :
2007-03-29 22:34:40 +00:00
while ( begin_retries > 0 ) {
again = 0 ;
2012-09-30 01:48:48 +00:00
switch ( dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
2012-11-17 02:09:38 +00:00
switch_cache_db_execute_sql_real ( dbh , " BEGIN EXCLUSIVE " , & errmsg ) ;
2012-09-30 01:48:48 +00:00
}
break ;
case SCDB_TYPE_ODBC :
{
switch_odbc_status_t result ;
if ( ( result = switch_odbc_SQLSetAutoCommitAttr ( dbh - > native_handle . odbc_dbh , 0 ) ) ! = SWITCH_ODBC_SUCCESS ) {
char tmp [ 100 ] ;
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to Set AutoCommit Off " , result ) ;
errmsg = strdup ( tmp ) ;
}
2010-10-21 21:18:54 +00:00
}
2012-09-30 01:48:48 +00:00
break ;
case SCDB_TYPE_PGSQL :
{
switch_pgsql_status_t result ;
if ( ( result = switch_pgsql_SQLSetAutoCommitAttr ( dbh - > native_handle . pgsql_dbh , 0 ) ) ! = SWITCH_PGSQL_SUCCESS ) {
char tmp [ 100 ] ;
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to Set AutoCommit Off " , result ) ;
errmsg = strdup ( tmp ) ;
}
}
break ;
2010-10-21 21:18:54 +00:00
}
2007-03-29 22:34:40 +00:00
if ( errmsg ) {
begin_retries - - ;
if ( strstr ( errmsg , " cannot start a transaction within a transaction " ) ) {
again = 1 ;
2007-06-08 15:43:59 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SQL Retry [%s] \n " , errmsg ) ;
2007-03-29 22:34:40 +00:00
}
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2007-03-29 22:34:40 +00:00
if ( again ) {
2012-09-30 01:48:48 +00:00
switch ( dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
switch_cache_db_execute_sql_real ( dbh , " COMMIT " , NULL ) ;
}
break ;
case SCDB_TYPE_ODBC :
{
switch_odbc_SQLEndTran ( dbh - > native_handle . odbc_dbh , 1 ) ;
switch_odbc_SQLSetAutoCommitAttr ( dbh - > native_handle . odbc_dbh , 1 ) ;
}
break ;
case SCDB_TYPE_PGSQL :
{
switch_pgsql_SQLEndTran ( dbh - > native_handle . pgsql_dbh , 1 ) ;
switch_pgsql_SQLSetAutoCommitAttr ( dbh - > native_handle . pgsql_dbh , 1 ) ;
switch_pgsql_finish_results ( dbh - > native_handle . pgsql_dbh ) ;
}
break ;
2010-10-21 21:18:54 +00:00
}
2007-03-29 22:34:40 +00:00
goto again ;
}
2011-03-01 16:52:12 +00:00
2007-03-29 22:34:40 +00:00
switch_yield ( 100000 ) ;
if ( begin_retries = = 0 ) {
goto done ;
}
2011-03-01 16:52:12 +00:00
continue ;
2007-03-29 22:34:40 +00:00
}
2011-03-01 16:52:12 +00:00
break ;
2007-03-29 22:34:40 +00:00
}
2012-04-26 16:28:47 +00:00
2012-10-10 01:20:32 +00:00
if ( ! zstr ( inner_pre_trans_execute ) ) {
switch_cache_db_execute_sql_real ( dbh , inner_pre_trans_execute , & errmsg ) ;
2012-04-26 16:28:47 +00:00
if ( errmsg ) {
2012-10-10 01:20:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL PRE TRANS EXEC %s [%s] \n " , inner_pre_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-04-26 16:28:47 +00:00
}
}
2007-03-29 22:34:40 +00:00
while ( retries > 0 ) {
2009-11-20 23:12:07 +00:00
switch_cache_db_execute_sql ( dbh , sql , & errmsg ) ;
2007-03-29 22:34:40 +00:00
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR [%s] \n " , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2008-05-16 16:43:47 +00:00
errmsg = NULL ;
2007-03-29 22:34:40 +00:00
switch_yield ( 100000 ) ;
retries - - ;
if ( retries = = 0 & & forever ) {
retries = 1000 ;
continue ;
}
} else {
status = SWITCH_STATUS_SUCCESS ;
break ;
}
}
2012-10-10 01:20:32 +00:00
if ( ! zstr ( inner_post_trans_execute ) ) {
switch_cache_db_execute_sql_real ( dbh , inner_post_trans_execute , & errmsg ) ;
2012-04-26 16:28:47 +00:00
if ( errmsg ) {
2012-10-10 01:20:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL POST TRANS EXEC %s [%s] \n " , inner_post_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-04-26 16:28:47 +00:00
}
}
2010-06-25 18:19:53 +00:00
done :
2007-03-29 22:34:40 +00:00
2012-09-30 01:48:48 +00:00
switch ( dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
switch_cache_db_execute_sql_real ( dbh , " COMMIT " , NULL ) ;
}
break ;
case SCDB_TYPE_ODBC :
{
switch_odbc_SQLEndTran ( dbh - > native_handle . odbc_dbh , 1 ) ;
switch_odbc_SQLSetAutoCommitAttr ( dbh - > native_handle . odbc_dbh , 1 ) ;
}
break ;
case SCDB_TYPE_PGSQL :
{
switch_pgsql_SQLEndTran ( dbh - > native_handle . pgsql_dbh , 1 ) ;
switch_pgsql_SQLSetAutoCommitAttr ( dbh - > native_handle . pgsql_dbh , 1 ) ;
switch_pgsql_finish_results ( dbh - > native_handle . pgsql_dbh ) ;
}
break ;
2010-10-21 21:18:54 +00:00
}
2007-03-29 22:34:40 +00:00
2012-10-10 01:20:32 +00:00
if ( ! zstr ( post_trans_execute ) ) {
switch_cache_db_execute_sql_real ( dbh , post_trans_execute , & errmsg ) ;
2012-04-26 16:12:11 +00:00
if ( errmsg ) {
2012-10-10 01:20:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL POST TRANS EXEC %s [%s] \n " , post_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-04-26 16:12:11 +00:00
}
}
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2009-12-05 18:54:56 +00:00
2007-03-29 22:34:40 +00:00
return status ;
}
2012-10-11 18:47:06 +00:00
struct helper {
2013-01-31 14:59:21 +00:00
switch_core_db_event_callback_func_t callback ;
2012-10-11 18:47:06 +00:00
void * pdata ;
} ;
static int helper_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
struct helper * h = ( struct helper * ) pArg ;
int r = 0 ;
switch_event_t * event ;
switch_event_create_array_pair ( & event , columnNames , argv , argc ) ;
r = h - > callback ( h - > pdata , event ) ;
switch_event_destroy ( & event ) ;
return r ;
}
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_execute_sql_event_callback ( switch_cache_db_handle_t * dbh ,
2013-01-31 14:59:21 +00:00
const char * sql , switch_core_db_event_callback_func_t callback , void * pdata , char * * err )
2014-03-14 15:54:05 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
char * errmsg = NULL ;
switch_mutex_t * io_mutex = dbh - > io_mutex ;
struct helper h = { 0 } ;
if ( err ) {
* err = NULL ;
}
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
h . callback = callback ;
h . pdata = pdata ;
switch ( dbh - > type ) {
case SCDB_TYPE_PGSQL :
{
status = switch_pgsql_handle_callback_exec ( dbh - > native_handle . pgsql_dbh , sql , helper_callback , & h , err ) ;
}
break ;
case SCDB_TYPE_ODBC :
{
status = switch_odbc_handle_callback_exec ( dbh - > native_handle . odbc_dbh , sql , helper_callback , & h , err ) ;
}
break ;
case SCDB_TYPE_CORE_DB :
{
int ret = switch_core_db_exec ( dbh - > native_handle . core_db_dbh , sql , helper_callback , & h , & errmsg ) ;
if ( ret = = SWITCH_CORE_DB_OK | | ret = = SWITCH_CORE_DB_ABORT ) {
status = SWITCH_STATUS_SUCCESS ;
}
if ( errmsg ) {
dbh - > last_used = switch_epoch_time_now ( NULL ) - ( SQL_CACHE_TIMEOUT * 2 ) ;
if ( ! strstr ( errmsg , " query abort " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , sql , errmsg ) ;
}
switch_core_db_free ( errmsg ) ;
}
}
break ;
}
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
return status ;
}
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_execute_sql_event_callback_err ( switch_cache_db_handle_t * dbh , const char * sql ,
switch_core_db_event_callback_func_t callback ,
switch_core_db_err_callback_func_t err_callback ,
void * pdata , char * * err )
2012-10-11 18:47:06 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
char * errmsg = NULL ;
switch_mutex_t * io_mutex = dbh - > io_mutex ;
struct helper h ;
if ( err ) {
* err = NULL ;
}
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
h . callback = callback ;
h . pdata = pdata ;
switch ( dbh - > type ) {
case SCDB_TYPE_PGSQL :
{
status = switch_pgsql_handle_callback_exec ( dbh - > native_handle . pgsql_dbh , sql , helper_callback , & h , err ) ;
2014-03-14 15:54:05 +00:00
if ( err & & * err ) {
( * err_callback ) ( pdata , ( const char * ) * err ) ;
}
2012-10-11 18:47:06 +00:00
}
break ;
case SCDB_TYPE_ODBC :
{
status = switch_odbc_handle_callback_exec ( dbh - > native_handle . odbc_dbh , sql , helper_callback , & h , err ) ;
2014-03-14 15:54:05 +00:00
if ( err & & * err ) {
( * err_callback ) ( pdata , ( const char * ) * err ) ;
}
2012-10-11 18:47:06 +00:00
}
break ;
case SCDB_TYPE_CORE_DB :
{
int ret = switch_core_db_exec ( dbh - > native_handle . core_db_dbh , sql , helper_callback , & h , & errmsg ) ;
if ( ret = = SWITCH_CORE_DB_OK | | ret = = SWITCH_CORE_DB_ABORT ) {
status = SWITCH_STATUS_SUCCESS ;
}
if ( errmsg ) {
dbh - > last_used = switch_epoch_time_now ( NULL ) - ( SQL_CACHE_TIMEOUT * 2 ) ;
if ( ! strstr ( errmsg , " query abort " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , sql , errmsg ) ;
}
2014-03-14 15:54:05 +00:00
}
if ( ( ret = = SWITCH_CORE_DB_ABORT | | errmsg ) & & err_callback ) {
( * err_callback ) ( pdata , errmsg ) ;
}
if ( errmsg ) {
2012-10-11 18:47:06 +00:00
switch_core_db_free ( errmsg ) ;
}
}
break ;
}
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
return status ;
}
2010-02-06 03:38:24 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_execute_sql_callback ( switch_cache_db_handle_t * dbh ,
2009-11-17 15:59:13 +00:00
const char * sql , switch_core_db_callback_func_t callback , void * pdata , char * * err )
2007-03-29 22:34:40 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2009-11-17 00:12:54 +00:00
char * errmsg = NULL ;
2011-03-01 16:52:12 +00:00
switch_mutex_t * io_mutex = dbh - > io_mutex ;
2007-03-29 22:34:40 +00:00
2011-03-01 16:52:12 +00:00
if ( err ) {
2010-02-06 03:38:24 +00:00
* err = NULL ;
2009-12-05 18:54:56 +00:00
}
2009-11-21 17:57:55 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2009-11-21 17:57:55 +00:00
switch ( dbh - > type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
status = switch_pgsql_handle_callback_exec ( dbh - > native_handle . pgsql_dbh , sql , callback , pdata , err ) ;
}
break ;
2009-11-21 17:57:55 +00:00
case SCDB_TYPE_ODBC :
{
status = switch_odbc_handle_callback_exec ( dbh - > native_handle . odbc_dbh , sql , callback , pdata , err ) ;
2007-03-29 22:34:40 +00:00
}
2009-11-21 17:57:55 +00:00
break ;
case SCDB_TYPE_CORE_DB :
{
2012-03-09 17:28:29 +00:00
int ret = switch_core_db_exec ( dbh - > native_handle . core_db_dbh , sql , callback , pdata , & errmsg ) ;
if ( ret = = SWITCH_CORE_DB_OK | | ret = = SWITCH_CORE_DB_ABORT ) {
status = SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2009-11-21 17:57:55 +00:00
if ( errmsg ) {
2010-05-04 14:50:55 +00:00
dbh - > last_used = switch_epoch_time_now ( NULL ) - ( SQL_CACHE_TIMEOUT * 2 ) ;
2011-03-03 01:21:37 +00:00
if ( ! strstr ( errmsg , " query abort " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , sql , errmsg ) ;
}
2010-06-07 21:47:35 +00:00
switch_core_db_free ( errmsg ) ;
2009-11-21 17:57:55 +00:00
}
}
break ;
2007-03-29 22:34:40 +00:00
}
2010-02-06 03:38:24 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2009-12-05 18:54:56 +00:00
2007-03-29 22:34:40 +00:00
return status ;
}
2014-03-14 15:54:05 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_execute_sql_callback_err ( switch_cache_db_handle_t * dbh , const char * sql ,
switch_core_db_callback_func_t callback ,
switch_core_db_err_callback_func_t err_callback , void * pdata , char * * err )
{
switch_status_t status = SWITCH_STATUS_FALSE ;
char * errmsg = NULL ;
switch_mutex_t * io_mutex = dbh - > io_mutex ;
if ( err ) {
* err = NULL ;
}
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
switch ( dbh - > type ) {
case SCDB_TYPE_PGSQL :
{
status = switch_pgsql_handle_callback_exec ( dbh - > native_handle . pgsql_dbh , sql , callback , pdata , err ) ;
if ( err & & * err ) {
( * err_callback ) ( pdata , ( const char * ) * err ) ;
}
}
break ;
case SCDB_TYPE_ODBC :
{
status = switch_odbc_handle_callback_exec ( dbh - > native_handle . odbc_dbh , sql , callback , pdata , err ) ;
if ( err & & * err ) {
( * err_callback ) ( pdata , ( const char * ) * err ) ;
}
}
break ;
case SCDB_TYPE_CORE_DB :
{
int ret = switch_core_db_exec ( dbh - > native_handle . core_db_dbh , sql , callback , pdata , & errmsg ) ;
if ( ret = = SWITCH_CORE_DB_OK | | ret = = SWITCH_CORE_DB_ABORT ) {
status = SWITCH_STATUS_SUCCESS ;
}
if ( errmsg ) {
dbh - > last_used = switch_epoch_time_now ( NULL ) - ( SQL_CACHE_TIMEOUT * 2 ) ;
if ( ! strstr ( errmsg , " query abort " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , sql , errmsg ) ;
}
}
if ( ( ret = = SWITCH_CORE_DB_ABORT | | errmsg ) & & err_callback ) {
( * err_callback ) ( pdata , errmsg ) ;
}
if ( errmsg ) {
switch_core_db_free ( errmsg ) ;
}
}
break ;
}
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
return status ;
}
2015-01-22 20:41:22 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_create_schema ( switch_cache_db_handle_t * dbh , char * sql , char * * err )
{
switch_status_t r = SWITCH_STATUS_SUCCESS ;
switch_assert ( sql ! = NULL ) ;
if ( switch_test_flag ( ( & runtime ) , SCF_AUTO_SCHEMAS ) ) {
r = switch_cache_db_execute_sql ( dbh , sql , err ) ;
}
return r ;
}
2014-09-15 13:36:48 +00:00
/*!
* \ brief Performs test_sql and if it fails performs drop_sql and reactive_sql .
*
* If auto - clear - sql is disabled , then this function will do nothing and it is
* assumed that the queries are not needed . If auto - create - schemas is disabled ,
* then just test_sql is executed , but drop_sql and reactive_sql are not .
*
* Otherwise , test_sql gets executed . If that succeeds , then there is nothing to
* do . Otherwise drop_sql is executed ( its result is ignored ) and then finally
* reactive_sql is executed .
*
* \ return If auto - create - schemas is enabled , SWITCH_TRUE is returned if
* test_sql succeeds , SWITCH_FALSE otherwise . If reactive_sql is executed
* successfully SWITCH_TRUE is returned , otherwise SWITCH_FALSE is returned .
*/
2010-02-06 03:38:24 +00:00
SWITCH_DECLARE ( switch_bool_t ) switch_cache_db_test_reactive ( switch_cache_db_handle_t * dbh ,
2009-12-16 22:20:22 +00:00
const char * test_sql , const char * drop_sql , const char * reactive_sql )
2009-11-17 00:12:54 +00:00
{
2009-12-16 22:20:22 +00:00
switch_bool_t r = SWITCH_TRUE ;
2011-03-01 16:52:12 +00:00
switch_mutex_t * io_mutex = dbh - > io_mutex ;
2009-12-05 18:54:56 +00:00
2014-09-15 13:36:48 +00:00
switch_assert ( test_sql ! = NULL ) ;
switch_assert ( reactive_sql ! = NULL ) ;
2011-08-24 18:36:13 +00:00
if ( ! switch_test_flag ( ( & runtime ) , SCF_CLEAR_SQL ) ) {
return SWITCH_TRUE ;
}
2010-08-04 14:56:53 +00:00
if ( ! switch_test_flag ( ( & runtime ) , SCF_AUTO_SCHEMAS ) ) {
2014-11-12 05:31:30 +00:00
switch_status_t status = switch_cache_db_execute_sql ( dbh , ( char * ) test_sql , NULL ) ;
return ( status = = SWITCH_STATUS_SUCCESS ) ? SWITCH_TRUE : SWITCH_FALSE ;
2010-08-04 14:56:53 +00:00
}
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2009-12-05 18:54:56 +00:00
2009-11-21 17:57:55 +00:00
switch ( dbh - > type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
{
if ( switch_pgsql_handle_exec ( dbh - > native_handle . pgsql_dbh , test_sql , NULL ) ! = SWITCH_PGSQL_SUCCESS ) {
if ( drop_sql ) {
switch_pgsql_handle_exec ( dbh - > native_handle . pgsql_dbh , drop_sql , NULL ) ;
}
2014-09-15 13:36:48 +00:00
r = switch_pgsql_handle_exec ( dbh - > native_handle . pgsql_dbh , reactive_sql , NULL ) = = SWITCH_PGSQL_SUCCESS ;
2012-09-30 01:48:48 +00:00
}
}
break ;
2009-11-21 17:57:55 +00:00
case SCDB_TYPE_ODBC :
{
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( dbh - > native_handle . odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
2009-11-26 00:07:24 +00:00
if ( drop_sql ) {
2010-01-13 01:40:11 +00:00
switch_odbc_handle_exec ( dbh - > native_handle . odbc_dbh , drop_sql , NULL , NULL ) ;
2009-11-26 00:07:24 +00:00
}
2014-09-15 13:36:48 +00:00
r = switch_odbc_handle_exec ( dbh - > native_handle . odbc_dbh , reactive_sql , NULL , NULL ) = = SWITCH_ODBC_SUCCESS ;
2009-11-21 17:57:55 +00:00
}
2009-11-17 00:12:54 +00:00
}
2009-11-21 17:57:55 +00:00
break ;
case SCDB_TYPE_CORE_DB :
{
2014-09-15 13:36:48 +00:00
char * errmsg = NULL ;
switch_core_db_exec ( dbh - > native_handle . core_db_dbh , test_sql , NULL , NULL , & errmsg ) ;
2009-11-17 00:12:54 +00:00
2014-09-15 13:36:48 +00:00
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SQL ERR [%s] \n [%s] \n Auto Generating Table! \n " , errmsg , test_sql ) ;
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
if ( drop_sql ) {
switch_core_db_exec ( dbh - > native_handle . core_db_dbh , drop_sql , NULL , NULL , & errmsg ) ;
}
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Ignoring SQL ERR [%s] \n [%s] \n " , errmsg , drop_sql ) ;
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
}
switch_core_db_exec ( dbh - > native_handle . core_db_dbh , reactive_sql , NULL , NULL , & errmsg ) ;
2009-11-17 00:12:54 +00:00
if ( errmsg ) {
2009-12-16 22:20:22 +00:00
r = SWITCH_FALSE ;
2014-09-15 13:36:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SQL ERR [%s] \n [%s] \n " , errmsg , reactive_sql ) ;
2009-11-17 00:12:54 +00:00
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
2014-09-15 13:36:48 +00:00
} else {
r = SWITCH_TRUE ;
2009-11-17 00:12:54 +00:00
}
}
}
2009-11-21 17:57:55 +00:00
break ;
2009-11-17 00:12:54 +00:00
}
2009-12-05 18:54:56 +00:00
2011-03-01 16:52:12 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2009-12-16 22:20:22 +00:00
return r ;
2009-11-17 00:12:54 +00:00
}
2009-11-14 21:59:01 +00:00
2010-09-17 21:33:47 +00:00
static void * SWITCH_THREAD_FUNC switch_core_sql_db_thread ( switch_thread_t * thread , void * obj )
{
2012-10-08 20:57:44 +00:00
int sec = 0 , reg_sec = 0 ; ;
2009-11-14 21:59:01 +00:00
2012-10-08 20:57:44 +00:00
sql_manager . db_thread_running = 1 ;
2010-09-17 21:33:47 +00:00
2012-10-08 20:57:44 +00:00
while ( sql_manager . db_thread_running = = 1 ) {
2011-03-03 18:54:20 +00:00
if ( + + sec = = SQL_CACHE_TIMEOUT ) {
2012-10-08 20:57:44 +00:00
sql_close ( switch_epoch_time_now ( NULL ) ) ;
2010-09-17 21:33:47 +00:00
sec = 0 ;
}
2011-02-12 05:10:12 +00:00
2011-02-26 03:39:37 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) & & + + reg_sec = = SQL_REG_TIMEOUT ) {
2011-02-12 05:10:12 +00:00
switch_core_expire_registration ( 0 ) ;
reg_sec = 0 ;
}
2010-11-18 16:17:11 +00:00
switch_yield ( 1000000 ) ;
2010-09-17 21:33:47 +00:00
}
return NULL ;
}
2010-09-07 15:51:02 +00:00
2012-10-10 01:20:32 +00:00
static void * SWITCH_THREAD_FUNC switch_user_sql_thread ( switch_thread_t * thread , void * obj ) ;
struct switch_sql_queue_manager {
2012-10-25 16:31:42 +00:00
const char * name ;
2012-10-10 01:20:32 +00:00
switch_cache_db_handle_t * event_db ;
switch_queue_t * * sql_queue ;
2012-10-29 20:16:55 +00:00
uint32_t * pre_written ;
2012-10-25 16:31:42 +00:00
uint32_t * written ;
2012-10-10 01:20:32 +00:00
uint32_t numq ;
char * dsn ;
switch_thread_t * thread ;
int thread_running ;
switch_thread_cond_t * cond ;
switch_mutex_t * cond_mutex ;
2013-03-13 21:10:36 +00:00
switch_mutex_t * cond2_mutex ;
2012-10-25 16:31:42 +00:00
switch_mutex_t * mutex ;
2012-10-10 01:20:32 +00:00
char * pre_trans_execute ;
char * post_trans_execute ;
char * inner_pre_trans_execute ;
char * inner_post_trans_execute ;
switch_memory_pool_t * pool ;
2012-10-27 17:27:00 +00:00
uint32_t max_trans ;
2012-12-06 17:11:02 +00:00
uint32_t confirm ;
2014-03-12 16:42:37 +00:00
uint8_t paused ;
2012-10-10 01:20:32 +00:00
} ;
2012-10-25 16:31:42 +00:00
static int qm_wake ( switch_sql_queue_manager_t * qm )
2012-10-10 01:20:32 +00:00
{
2013-03-13 21:10:36 +00:00
switch_status_t status ;
int tries = 0 ;
top :
status = switch_mutex_trylock ( qm - > cond_mutex ) ;
if ( status = = SWITCH_STATUS_SUCCESS ) {
2012-10-10 01:20:32 +00:00
switch_thread_cond_signal ( qm - > cond ) ;
switch_mutex_unlock ( qm - > cond_mutex ) ;
2012-10-25 16:31:42 +00:00
return 1 ;
2013-03-13 21:10:36 +00:00
} else {
if ( switch_mutex_trylock ( qm - > cond2_mutex ) = = SWITCH_STATUS_SUCCESS ) {
switch_mutex_unlock ( qm - > cond2_mutex ) ;
} else {
if ( + + tries < 10 ) {
switch_cond_next ( ) ;
goto top ;
}
}
2012-10-10 01:20:32 +00:00
}
2012-10-25 16:31:42 +00:00
return 0 ;
2012-10-10 01:20:32 +00:00
}
static uint32_t qm_ttl ( switch_sql_queue_manager_t * qm )
{
uint32_t ttl = 0 ;
2012-10-10 13:32:16 +00:00
uint32_t i ;
2012-10-10 01:20:32 +00:00
for ( i = 0 ; i < qm - > numq ; i + + ) {
ttl + = switch_queue_size ( qm - > sql_queue [ i ] ) ;
}
return ttl ;
}
2013-01-31 14:59:21 +00:00
struct db_job {
switch_sql_queue_manager_t * qm ;
char * sql ;
switch_core_db_callback_func_t callback ;
2014-03-14 15:54:05 +00:00
switch_core_db_err_callback_func_t err_callback ;
2013-01-31 14:59:21 +00:00
switch_core_db_event_callback_func_t event_callback ;
2014-03-14 15:54:05 +00:00
switch_core_db_err_callback_func_t event_err_callback ;
2013-01-31 14:59:21 +00:00
void * pdata ;
int event ;
switch_memory_pool_t * pool ;
} ;
static void * SWITCH_THREAD_FUNC sql_in_thread ( switch_thread_t * thread , void * obj )
{
struct db_job * job = ( struct db_job * ) obj ;
switch_memory_pool_t * pool = job - > pool ;
char * err = NULL ;
switch_cache_db_handle_t * dbh ;
if ( switch_cache_db_get_db_handle_dsn ( & dbh , job - > qm - > dsn ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Cannot connect DSN %s \n " , job - > qm - > dsn ) ;
return NULL ;
}
2014-03-14 15:54:05 +00:00
if ( job - > callback & & ! job - > err_callback ) {
2013-01-31 14:59:21 +00:00
switch_cache_db_execute_sql_callback ( dbh , job - > sql , job - > callback , job - > pdata , & err ) ;
2014-03-14 15:54:05 +00:00
} else if ( job - > callback & & job - > err_callback ) {
switch_cache_db_execute_sql_callback_err ( dbh , job - > sql , job - > callback , job - > err_callback , job - > pdata , & err ) ;
} else if ( job - > event_callback & & ! job - > event_err_callback ) {
2013-01-31 14:59:21 +00:00
switch_cache_db_execute_sql_event_callback ( dbh , job - > sql , job - > event_callback , job - > pdata , & err ) ;
2014-03-14 15:54:05 +00:00
} else if ( job - > event_callback & & job - > event_err_callback ) {
switch_cache_db_execute_sql_event_callback_err ( dbh , job - > sql , job - > event_callback , job - > event_err_callback , job - > pdata , & err ) ;
2013-01-31 14:59:21 +00:00
}
if ( err ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , job - > sql , err ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( err ) ;
2013-01-31 14:59:21 +00:00
}
switch_cache_db_release_db_handle ( & dbh ) ;
if ( pool ) {
switch_core_destroy_memory_pool ( & pool ) ;
}
return NULL ;
}
2014-03-14 15:54:05 +00:00
static switch_thread_data_t * new_job ( switch_sql_queue_manager_t * qm , const char * sql ,
switch_core_db_callback_func_t callback ,
switch_core_db_err_callback_func_t err_callback ,
switch_core_db_event_callback_func_t event_callback ,
switch_core_db_err_callback_func_t event_err_callback ,
void * pdata )
2013-01-31 14:59:21 +00:00
{
switch_memory_pool_t * pool ;
switch_thread_data_t * td ;
struct db_job * job ;
switch_core_new_memory_pool ( & pool ) ;
td = switch_core_alloc ( pool , sizeof ( * td ) ) ;
job = switch_core_alloc ( pool , sizeof ( * job ) ) ;
td - > func = sql_in_thread ;
td - > obj = job ;
job - > sql = switch_core_strdup ( pool , sql ) ;
job - > qm = qm ;
if ( callback ) {
job - > callback = callback ;
2014-03-14 15:54:05 +00:00
job - > err_callback = err_callback ;
2013-01-31 14:59:21 +00:00
} else if ( event_callback ) {
job - > event_callback = event_callback ;
2014-03-14 15:54:05 +00:00
job - > event_err_callback = event_err_callback ;
2013-01-31 14:59:21 +00:00
}
job - > pdata = pdata ;
job - > pool = pool ;
return td ;
}
2014-03-14 15:54:05 +00:00
SWITCH_DECLARE ( void ) switch_sql_queue_manager_execute_sql_callback ( switch_sql_queue_manager_t * qm ,
2013-01-31 14:59:21 +00:00
const char * sql , switch_core_db_callback_func_t callback , void * pdata )
{
switch_thread_data_t * td ;
2014-03-14 15:54:05 +00:00
if ( ( td = new_job ( qm , sql , callback , NULL , NULL , NULL , pdata ) ) ) {
switch_thread_pool_launch_thread ( & td ) ;
}
}
SWITCH_DECLARE ( void ) switch_sql_queue_manager_execute_sql_callback_err ( switch_sql_queue_manager_t * qm , const char * sql ,
switch_core_db_callback_func_t callback ,
switch_core_db_err_callback_func_t err_callback , void * pdata )
{
switch_thread_data_t * td ;
if ( ( td = new_job ( qm , sql , callback , err_callback , NULL , NULL , pdata ) ) ) {
switch_thread_pool_launch_thread ( & td ) ;
}
}
SWITCH_DECLARE ( void ) switch_sql_queue_manager_execute_sql_event_callback ( switch_sql_queue_manager_t * qm ,
const char * sql , switch_core_db_event_callback_func_t callback , void * pdata )
{
switch_thread_data_t * td ;
if ( ( td = new_job ( qm , sql , NULL , NULL , callback , NULL , pdata ) ) ) {
2013-01-31 14:59:21 +00:00
switch_thread_pool_launch_thread ( & td ) ;
}
}
2014-03-14 15:54:05 +00:00
SWITCH_DECLARE ( void ) switch_sql_queue_manager_execute_sql_event_callback_err ( switch_sql_queue_manager_t * qm , const char * sql ,
switch_core_db_event_callback_func_t callback ,
switch_core_db_err_callback_func_t err_callback ,
void * pdata )
2013-01-31 14:59:21 +00:00
{
switch_thread_data_t * td ;
2014-03-14 15:54:05 +00:00
if ( ( td = new_job ( qm , sql , NULL , NULL , callback , err_callback , pdata ) ) ) {
2013-01-31 14:59:21 +00:00
switch_thread_pool_launch_thread ( & td ) ;
}
}
2014-03-12 16:42:37 +00:00
static void do_flush ( switch_sql_queue_manager_t * qm , int i , switch_cache_db_handle_t * dbh )
{
void * pop = NULL ;
switch_queue_t * q = qm - > sql_queue [ i ] ;
switch_mutex_lock ( qm - > mutex ) ;
while ( switch_queue_trypop ( q , & pop ) = = SWITCH_STATUS_SUCCESS ) {
if ( pop ) {
if ( dbh ) {
switch_cache_db_execute_sql ( dbh , ( char * ) pop , NULL ) ;
}
2014-04-30 21:37:17 +00:00
switch_safe_free ( pop ) ;
2014-03-12 16:42:37 +00:00
}
}
switch_mutex_unlock ( qm - > mutex ) ;
}
SWITCH_DECLARE ( void ) switch_sql_queue_manager_resume ( switch_sql_queue_manager_t * qm )
{
switch_mutex_lock ( qm - > mutex ) ;
qm - > paused = 0 ;
switch_mutex_unlock ( qm - > mutex ) ;
qm_wake ( qm ) ;
}
SWITCH_DECLARE ( void ) switch_sql_queue_manager_pause ( switch_sql_queue_manager_t * qm , switch_bool_t flush )
{
uint32_t i ;
switch_mutex_lock ( qm - > mutex ) ;
qm - > paused = 1 ;
switch_mutex_unlock ( qm - > mutex ) ;
if ( flush ) {
for ( i = 0 ; i < qm - > numq ; i + + ) {
do_flush ( qm , i , NULL ) ;
}
}
}
2012-10-26 19:17:52 +00:00
SWITCH_DECLARE ( int ) switch_sql_queue_manager_size ( switch_sql_queue_manager_t * qm , uint32_t index )
{
int size = 0 ;
switch_mutex_lock ( qm - > mutex ) ;
if ( index < qm - > numq ) {
size = switch_queue_size ( qm - > sql_queue [ index ] ) ;
}
switch_mutex_unlock ( qm - > mutex ) ;
return size ;
}
2012-10-10 01:20:32 +00:00
2012-10-25 21:22:52 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_sql_queue_manager_stop ( switch_sql_queue_manager_t * qm )
2012-10-10 01:20:32 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2013-03-14 18:35:42 +00:00
uint32_t i , sanity = 100 ;
2012-10-10 01:20:32 +00:00
2013-03-14 18:35:42 +00:00
if ( qm - > thread_running = = 1 ) {
qm - > thread_running = - 1 ;
2013-02-18 18:58:33 +00:00
2013-03-14 18:35:42 +00:00
while ( - - sanity & & qm - > thread_running = = - 1 ) {
for ( i = 0 ; i < qm - > numq ; i + + ) {
switch_queue_push ( qm - > sql_queue [ i ] , NULL ) ;
switch_queue_interrupt_all ( qm - > sql_queue [ i ] ) ;
}
qm_wake ( qm ) ;
if ( qm - > thread_running = = - 1 ) {
switch_yield ( 100000 ) ;
}
2013-02-18 18:58:33 +00:00
}
2012-10-10 01:20:32 +00:00
status = SWITCH_STATUS_SUCCESS ;
}
if ( qm - > thread ) {
2012-10-27 01:51:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " %s Stopping SQL thread. \n " , qm - > name ) ;
2013-03-13 21:10:36 +00:00
qm_wake ( qm ) ;
2012-10-10 01:20:32 +00:00
switch_thread_join ( & status , qm - > thread ) ;
qm - > thread = NULL ;
status = SWITCH_STATUS_SUCCESS ;
}
return status ;
}
2012-10-25 21:22:52 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_sql_queue_manager_start ( switch_sql_queue_manager_t * qm )
2012-10-10 01:20:32 +00:00
{
switch_threadattr_t * thd_attr ;
if ( ! qm - > thread_running ) {
2012-10-27 01:51:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " %s Starting SQL thread. \n " , qm - > name ) ;
2012-10-10 01:20:32 +00:00
switch_threadattr_create ( & thd_attr , qm - > pool ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
switch_threadattr_priority_set ( thd_attr , SWITCH_PRI_NORMAL ) ;
switch_thread_create ( & qm - > thread , thd_attr , switch_user_sql_thread , qm , qm - > pool ) ;
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
}
2012-10-25 21:22:52 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_sql_queue_manager_destroy ( switch_sql_queue_manager_t * * qmp )
2012-10-10 01:20:32 +00:00
{
switch_sql_queue_manager_t * qm ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_memory_pool_t * pool ;
2012-10-10 13:32:16 +00:00
uint32_t i ;
2012-10-10 01:20:32 +00:00
switch_assert ( qmp ) ;
qm = * qmp ;
* qmp = NULL ;
2012-10-27 01:51:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " %s Destroying SQL queue. \n " , qm - > name ) ;
2012-10-25 21:22:52 +00:00
switch_sql_queue_manager_stop ( qm ) ;
2012-10-10 01:20:32 +00:00
2012-10-27 01:51:51 +00:00
2012-10-10 01:20:32 +00:00
for ( i = 0 ; i < qm - > numq ; i + + ) {
2012-11-22 03:15:31 +00:00
do_flush ( qm , i , NULL ) ;
2012-10-10 01:20:32 +00:00
}
pool = qm - > pool ;
switch_core_destroy_memory_pool ( & pool ) ;
return status ;
}
2012-10-25 21:22:52 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_sql_queue_manager_push ( switch_sql_queue_manager_t * qm , const char * sql , uint32_t pos , switch_bool_t dup )
2012-10-10 01:20:32 +00:00
{
2014-05-23 18:13:38 +00:00
char * sqlptr = NULL ;
switch_status_t status ;
int x = 0 ;
2012-10-10 01:20:32 +00:00
2013-03-14 18:35:42 +00:00
if ( sql_manager . paused | | qm - > thread_running ! = 1 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG1 , " DROP [%s] \n " , sql ) ;
2012-10-27 01:51:51 +00:00
if ( ! dup ) free ( ( char * ) sql ) ;
qm_wake ( qm ) ;
return SWITCH_STATUS_SUCCESS ;
2012-10-10 01:20:32 +00:00
}
2013-03-14 18:35:42 +00:00
if ( qm - > thread_running ! = 1 ) {
2012-10-27 01:51:51 +00:00
if ( ! dup ) free ( ( char * ) sql ) ;
2012-10-10 01:20:32 +00:00
return SWITCH_STATUS_FALSE ;
}
2012-10-27 01:51:51 +00:00
2012-10-10 01:20:32 +00:00
if ( pos > qm - > numq - 1 ) {
pos = 0 ;
}
2012-10-26 19:17:52 +00:00
2014-05-23 18:13:38 +00:00
sqlptr = dup ? strdup ( sql ) : ( char * ) sql ;
2012-10-26 19:17:52 +00:00
2014-05-23 18:13:38 +00:00
do {
switch_mutex_lock ( qm - > mutex ) ;
status = switch_queue_trypush ( qm - > sql_queue [ pos ] , sqlptr ) ;
switch_mutex_unlock ( qm - > mutex ) ;
if ( status ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG1 , " Delay %d sending sql \n " , x ) ;
if ( x + + ) {
switch_yield ( 1000000 * x ) ;
}
}
} while ( status ! = SWITCH_STATUS_SUCCESS ) ;
2012-10-10 01:20:32 +00:00
qm_wake ( qm ) ;
return SWITCH_STATUS_SUCCESS ;
}
2012-10-25 21:22:52 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_sql_queue_manager_push_confirm ( switch_sql_queue_manager_t * qm , const char * sql , uint32_t pos , switch_bool_t dup )
2012-10-25 16:31:42 +00:00
{
2013-01-15 04:17:34 +00:00
# define EXEC_NOW
# ifdef EXEC_NOW
switch_cache_db_handle_t * dbh ;
2013-03-14 18:35:42 +00:00
if ( sql_manager . paused | | qm - > thread_running ! = 1 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG1 , " DROP [%s] \n " , sql ) ;
if ( ! dup ) free ( ( char * ) sql ) ;
qm_wake ( qm ) ;
return SWITCH_STATUS_SUCCESS ;
}
2013-01-15 04:17:34 +00:00
if ( switch_cache_db_get_db_handle_dsn ( & dbh , qm - > dsn ) = = SWITCH_STATUS_SUCCESS ) {
switch_cache_db_execute_sql ( dbh , ( char * ) sql , NULL ) ;
switch_cache_db_release_db_handle ( & dbh ) ;
}
if ( ! dup ) free ( ( char * ) sql ) ;
# else
2012-10-26 00:00:28 +00:00
int size , x = 0 , sanity = 0 ;
uint32_t written , want ;
2012-10-25 16:31:42 +00:00
2012-10-27 01:51:51 +00:00
if ( sql_manager . paused ) {
if ( ! dup ) free ( ( char * ) sql ) ;
qm_wake ( qm ) ;
return SWITCH_STATUS_SUCCESS ;
2012-10-25 16:31:42 +00:00
}
2013-03-14 18:35:42 +00:00
if ( qm - > thread_running ! = 1 ) {
2012-10-27 01:51:51 +00:00
if ( ! dup ) free ( ( char * ) sql ) ;
2012-10-25 16:31:42 +00:00
return SWITCH_STATUS_FALSE ;
}
2012-10-27 01:51:51 +00:00
2012-10-25 16:31:42 +00:00
if ( pos > qm - > numq - 1 ) {
pos = 0 ;
}
switch_mutex_lock ( qm - > mutex ) ;
2012-12-06 17:11:02 +00:00
qm - > confirm + + ;
2012-10-26 19:17:52 +00:00
switch_queue_push ( qm - > sql_queue [ pos ] , dup ? strdup ( sql ) : ( char * ) sql ) ;
2012-11-22 21:19:38 +00:00
written = qm - > pre_written [ pos ] ;
2012-10-26 19:17:52 +00:00
size = switch_sql_queue_manager_size ( qm , pos ) ;
2012-11-22 21:19:38 +00:00
want = written + size ;
2012-10-25 16:31:42 +00:00
switch_mutex_unlock ( qm - > mutex ) ;
qm_wake ( qm ) ;
while ( ( qm - > written [ pos ] < want ) | | ( qm - > written [ pos ] > = written & & want < written & & qm - > written [ pos ] > want ) ) {
switch_yield ( 5000 ) ;
if ( + + x = = 200 ) {
qm_wake ( qm ) ;
x = 0 ;
if ( + + sanity = = 20 ) {
break ;
}
}
}
2012-12-06 17:11:02 +00:00
switch_mutex_lock ( qm - > mutex ) ;
qm - > confirm - - ;
switch_mutex_unlock ( qm - > mutex ) ;
2013-01-15 04:17:34 +00:00
# endif
2012-12-06 17:11:02 +00:00
2012-10-25 16:31:42 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2012-10-10 01:20:32 +00:00
2012-10-25 21:22:52 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_sql_queue_manager_init_name ( const char * name ,
2012-10-27 17:27:00 +00:00
switch_sql_queue_manager_t * * qmp ,
uint32_t numq , const char * dsn , uint32_t max_trans ,
const char * pre_trans_execute ,
const char * post_trans_execute ,
const char * inner_pre_trans_execute ,
const char * inner_post_trans_execute )
2012-10-10 01:20:32 +00:00
{
switch_memory_pool_t * pool ;
switch_sql_queue_manager_t * qm ;
2012-10-10 13:32:16 +00:00
uint32_t i ;
2012-10-10 01:20:32 +00:00
if ( ! numq ) numq = 1 ;
switch_core_new_memory_pool ( & pool ) ;
qm = switch_core_alloc ( pool , sizeof ( * qm ) ) ;
qm - > pool = pool ;
qm - > numq = numq ;
qm - > dsn = switch_core_strdup ( qm - > pool , dsn ) ;
2012-10-25 16:31:42 +00:00
qm - > name = switch_core_strdup ( qm - > pool , name ) ;
2012-10-27 17:27:00 +00:00
qm - > max_trans = max_trans ;
2012-10-10 01:20:32 +00:00
switch_mutex_init ( & qm - > cond_mutex , SWITCH_MUTEX_NESTED , qm - > pool ) ;
2013-03-13 21:10:36 +00:00
switch_mutex_init ( & qm - > cond2_mutex , SWITCH_MUTEX_NESTED , qm - > pool ) ;
2012-10-25 16:31:42 +00:00
switch_mutex_init ( & qm - > mutex , SWITCH_MUTEX_NESTED , qm - > pool ) ;
2012-10-10 01:20:32 +00:00
switch_thread_cond_create ( & qm - > cond , qm - > pool ) ;
qm - > sql_queue = switch_core_alloc ( qm - > pool , sizeof ( switch_queue_t * ) * numq ) ;
2012-10-25 16:31:42 +00:00
qm - > written = switch_core_alloc ( qm - > pool , sizeof ( uint32_t ) * numq ) ;
2012-10-29 20:16:55 +00:00
qm - > pre_written = switch_core_alloc ( qm - > pool , sizeof ( uint32_t ) * numq ) ;
2012-10-10 01:20:32 +00:00
for ( i = 0 ; i < qm - > numq ; i + + ) {
switch_queue_create ( & qm - > sql_queue [ i ] , SWITCH_SQL_QUEUE_LEN , qm - > pool ) ;
}
if ( pre_trans_execute ) {
2013-01-18 22:06:30 +00:00
qm - > pre_trans_execute = switch_core_strdup ( qm - > pool , pre_trans_execute ) ;
}
if ( post_trans_execute ) {
qm - > post_trans_execute = switch_core_strdup ( qm - > pool , post_trans_execute ) ;
}
if ( inner_pre_trans_execute ) {
qm - > inner_pre_trans_execute = switch_core_strdup ( qm - > pool , inner_pre_trans_execute ) ;
}
if ( inner_post_trans_execute ) {
qm - > inner_post_trans_execute = switch_core_strdup ( qm - > pool , inner_post_trans_execute ) ;
2012-10-10 01:20:32 +00:00
}
* qmp = qm ;
return SWITCH_STATUS_SUCCESS ;
}
2012-10-29 16:46:17 +00:00
static uint32_t do_trans ( switch_sql_queue_manager_t * qm )
2012-10-27 01:51:51 +00:00
{
char * errmsg = NULL ;
void * pop ;
switch_status_t status ;
uint32_t ttl = 0 ;
2012-10-29 16:46:17 +00:00
switch_mutex_t * io_mutex = qm - > event_db - > io_mutex ;
2012-10-30 03:34:51 +00:00
uint32_t i ;
2012-10-10 01:20:32 +00:00
2012-10-27 17:27:00 +00:00
if ( io_mutex ) switch_mutex_lock ( io_mutex ) ;
2012-10-29 16:46:17 +00:00
if ( ! zstr ( qm - > pre_trans_execute ) ) {
switch_cache_db_execute_sql_real ( qm - > event_db , qm - > pre_trans_execute , & errmsg ) ;
2012-10-27 17:27:00 +00:00
if ( errmsg ) {
2012-10-29 16:46:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL PRE TRANS EXEC %s [%s] \n " , qm - > pre_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-10-27 17:27:00 +00:00
}
}
2012-10-29 16:46:17 +00:00
switch ( qm - > event_db - > type ) {
2012-10-10 01:20:32 +00:00
case SCDB_TYPE_CORE_DB :
{
2012-11-17 02:09:38 +00:00
switch_cache_db_execute_sql_real ( qm - > event_db , " BEGIN EXCLUSIVE " , & errmsg ) ;
2012-10-10 01:20:32 +00:00
}
break ;
2012-10-27 01:51:51 +00:00
case SCDB_TYPE_ODBC :
{
switch_odbc_status_t result ;
2012-10-10 01:20:32 +00:00
2012-10-29 16:46:17 +00:00
if ( ( result = switch_odbc_SQLSetAutoCommitAttr ( qm - > event_db - > native_handle . odbc_dbh , 0 ) ) ! = SWITCH_ODBC_SUCCESS ) {
2012-10-27 01:51:51 +00:00
char tmp [ 100 ] ;
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to Set AutoCommit Off " , result ) ;
errmsg = strdup ( tmp ) ;
2012-10-10 01:20:32 +00:00
}
}
2012-10-27 01:51:51 +00:00
break ;
case SCDB_TYPE_PGSQL :
{
switch_pgsql_status_t result ;
2012-10-29 16:46:17 +00:00
if ( ( result = switch_pgsql_SQLSetAutoCommitAttr ( qm - > event_db - > native_handle . pgsql_dbh , 0 ) ) ! = SWITCH_PGSQL_SUCCESS ) {
2012-10-27 01:51:51 +00:00
char tmp [ 100 ] ;
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to Set AutoCommit Off " , result ) ;
errmsg = strdup ( tmp ) ;
2012-10-10 01:20:32 +00:00
}
}
2012-10-27 01:51:51 +00:00
break ;
}
2012-10-25 16:31:42 +00:00
2012-10-27 01:51:51 +00:00
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " ERROR [%s] \n " , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-10-27 01:51:51 +00:00
goto end ;
}
2012-10-25 16:31:42 +00:00
2012-10-29 16:46:17 +00:00
if ( ! zstr ( qm - > inner_pre_trans_execute ) ) {
switch_cache_db_execute_sql_real ( qm - > event_db , qm - > inner_pre_trans_execute , & errmsg ) ;
2012-10-27 17:27:00 +00:00
if ( errmsg ) {
2012-10-29 16:46:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL PRE TRANS EXEC %s [%s] \n " , qm - > inner_pre_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-10-27 17:27:00 +00:00
}
}
2012-10-10 01:20:32 +00:00
2012-10-29 16:46:17 +00:00
while ( qm - > max_trans = = 0 | | ttl < = qm - > max_trans ) {
pop = NULL ;
for ( i = 0 ; ( qm - > max_trans = = 0 | | ttl < = qm - > max_trans ) & & ( i < qm - > numq ) ; i + + ) {
switch_mutex_lock ( qm - > mutex ) ;
switch_queue_trypop ( qm - > sql_queue [ i ] , & pop ) ;
switch_mutex_unlock ( qm - > mutex ) ;
if ( pop ) break ;
2012-10-10 01:20:32 +00:00
}
2012-10-29 16:46:17 +00:00
if ( pop ) {
if ( ( status = switch_cache_db_execute_sql ( qm - > event_db , ( char * ) pop , NULL ) ) = = SWITCH_STATUS_SUCCESS ) {
2012-11-22 03:15:31 +00:00
switch_mutex_lock ( qm - > mutex ) ;
2012-10-29 20:16:55 +00:00
qm - > pre_written [ i ] + + ;
2012-11-22 03:15:31 +00:00
switch_mutex_unlock ( qm - > mutex ) ;
2012-10-29 16:46:17 +00:00
ttl + + ;
}
2014-04-30 21:37:17 +00:00
switch_safe_free ( pop ) ;
2012-10-29 16:46:17 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS ) break ;
} else {
break ;
}
2012-10-10 01:20:32 +00:00
}
2012-10-29 16:46:17 +00:00
if ( ! zstr ( qm - > inner_post_trans_execute ) ) {
switch_cache_db_execute_sql_real ( qm - > event_db , qm - > inner_post_trans_execute , & errmsg ) ;
2012-10-27 17:27:00 +00:00
if ( errmsg ) {
2012-10-29 16:46:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL POST TRANS EXEC %s [%s] \n " , qm - > inner_post_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-10-27 17:27:00 +00:00
}
}
2012-10-27 01:51:51 +00:00
end :
2012-10-10 01:20:32 +00:00
2012-10-29 16:46:17 +00:00
switch ( qm - > event_db - > type ) {
2012-10-27 01:51:51 +00:00
case SCDB_TYPE_CORE_DB :
{
2012-10-29 16:46:17 +00:00
switch_cache_db_execute_sql_real ( qm - > event_db , " COMMIT " , NULL ) ;
2012-10-10 01:20:32 +00:00
}
2012-10-27 01:51:51 +00:00
break ;
case SCDB_TYPE_ODBC :
{
2012-10-29 16:46:17 +00:00
switch_odbc_SQLEndTran ( qm - > event_db - > native_handle . odbc_dbh , 1 ) ;
switch_odbc_SQLSetAutoCommitAttr ( qm - > event_db - > native_handle . odbc_dbh , 1 ) ;
2012-10-27 01:51:51 +00:00
}
break ;
case SCDB_TYPE_PGSQL :
{
2012-10-29 16:46:17 +00:00
switch_pgsql_SQLEndTran ( qm - > event_db - > native_handle . pgsql_dbh , 1 ) ;
switch_pgsql_SQLSetAutoCommitAttr ( qm - > event_db - > native_handle . pgsql_dbh , 1 ) ;
switch_pgsql_finish_results ( qm - > event_db - > native_handle . pgsql_dbh ) ;
2012-10-27 01:51:51 +00:00
}
break ;
2012-10-10 01:20:32 +00:00
}
2012-10-29 16:46:17 +00:00
if ( ! zstr ( qm - > post_trans_execute ) ) {
switch_cache_db_execute_sql_real ( qm - > event_db , qm - > post_trans_execute , & errmsg ) ;
2012-10-27 17:27:00 +00:00
if ( errmsg ) {
2012-10-29 16:46:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL POST TRANS EXEC %s [%s] \n " , qm - > post_trans_execute , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-10-27 17:27:00 +00:00
}
}
2012-10-29 20:16:55 +00:00
switch_mutex_lock ( qm - > mutex ) ;
for ( i = 0 ; i < qm - > numq ; i + + ) {
2012-11-22 21:19:38 +00:00
qm - > written [ i ] = qm - > pre_written [ i ] ;
2012-10-29 20:16:55 +00:00
}
switch_mutex_unlock ( qm - > mutex ) ;
2012-10-27 17:27:00 +00:00
if ( io_mutex ) switch_mutex_unlock ( io_mutex ) ;
2012-10-10 01:20:32 +00:00
2012-10-27 01:51:51 +00:00
return ttl ;
2012-10-10 01:20:32 +00:00
}
2012-10-27 01:51:51 +00:00
static void * SWITCH_THREAD_FUNC switch_user_sql_thread ( switch_thread_t * thread , void * obj )
2007-03-29 22:34:40 +00:00
{
2011-07-12 02:27:06 +00:00
2012-10-27 01:51:51 +00:00
uint32_t sanity = 120 ;
switch_sql_queue_manager_t * qm = ( switch_sql_queue_manager_t * ) obj ;
2012-11-22 03:15:31 +00:00
uint32_t i ;
2007-12-11 20:50:52 +00:00
2012-10-27 01:51:51 +00:00
while ( ! qm - > event_db ) {
if ( switch_cache_db_get_db_handle_dsn ( & qm - > event_db , qm - > dsn ) = = SWITCH_STATUS_SUCCESS & & qm - > event_db )
2010-06-30 15:35:03 +00:00
break ;
2012-10-27 01:51:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " %s Error getting db handle, Retrying \n " , qm - > name ) ;
2010-04-22 18:28:44 +00:00
switch_yield ( 500000 ) ;
sanity - - ;
}
2012-10-27 01:51:51 +00:00
if ( ! qm - > event_db ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " %s Error getting db handle \n " , qm - > name ) ;
2010-04-22 18:28:44 +00:00
return NULL ;
2007-03-29 22:34:40 +00:00
}
2012-10-27 01:51:51 +00:00
qm - > thread_running = 1 ;
2007-03-29 22:34:40 +00:00
2012-10-27 01:51:51 +00:00
switch_mutex_lock ( qm - > cond_mutex ) ;
2010-09-14 21:19:03 +00:00
2012-10-27 01:51:51 +00:00
switch ( qm - > event_db - > type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
break ;
2012-07-31 12:59:58 +00:00
case SCDB_TYPE_ODBC :
break ;
case SCDB_TYPE_CORE_DB :
{
2012-10-27 01:51:51 +00:00
switch_cache_db_execute_sql ( qm - > event_db , " PRAGMA synchronous=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( qm - > event_db , " PRAGMA count_changes=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( qm - > event_db , " PRAGMA temp_store=MEMORY; " , NULL ) ;
switch_cache_db_execute_sql ( qm - > event_db , " PRAGMA journal_mode=OFF; " , NULL ) ;
2012-07-31 12:59:58 +00:00
}
break ;
2011-07-18 14:51:08 +00:00
}
2011-07-13 01:36:08 +00:00
2010-12-04 00:34:07 +00:00
2012-10-27 01:51:51 +00:00
while ( qm - > thread_running = = 1 ) {
2012-10-30 03:34:51 +00:00
uint32_t i , lc ;
2012-11-20 19:45:32 +00:00
uint32_t written = 0 , iterations = 0 ;
2011-07-12 02:27:06 +00:00
2014-03-12 16:42:37 +00:00
if ( qm - > paused ) {
goto check ;
}
2012-10-27 01:51:51 +00:00
if ( sql_manager . paused ) {
for ( i = 0 ; i < qm - > numq ; i + + ) {
2012-11-22 03:15:31 +00:00
do_flush ( qm , i , NULL ) ;
2011-07-12 02:27:06 +00:00
}
2012-10-27 01:51:51 +00:00
goto check ;
2011-07-12 02:27:06 +00:00
}
2012-10-27 17:27:00 +00:00
2012-10-29 16:46:17 +00:00
do {
2012-11-20 19:45:32 +00:00
if ( ! qm_ttl ( qm ) ) {
goto check ;
}
written = do_trans ( qm ) ;
2012-10-29 16:46:17 +00:00
iterations + = written ;
} while ( written = = qm - > max_trans ) ;
2010-09-17 21:33:47 +00:00
2012-10-27 01:51:51 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_DEBUG_SQL ) ) {
char line [ 128 ] = " " ;
2014-01-22 21:28:53 +00:00
switch_size_t l ;
2012-10-27 01:51:51 +00:00
switch_snprintf ( line , sizeof ( line ) , " %s RUN QUEUE [ " , qm - > name ) ;
for ( i = 0 ; i < qm - > numq ; i + + ) {
l = strlen ( line ) ;
switch_snprintf ( line + l , sizeof ( line ) - l , " %d%s " , switch_queue_size ( qm - > sql_queue [ i ] ) , i = = qm - > numq - 1 ? " " : " | " ) ;
2010-12-04 00:34:07 +00:00
}
2012-10-27 01:51:51 +00:00
l = strlen ( line ) ;
switch_snprintf ( line + l , sizeof ( line ) - l , " ]--[%d] \n " , iterations ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " %s " , line ) ;
2007-03-29 22:34:40 +00:00
}
2012-10-27 01:51:51 +00:00
check :
2010-09-22 23:14:24 +00:00
2012-11-27 18:48:57 +00:00
if ( ( lc = qm_ttl ( qm ) ) = = 0 ) {
2013-03-13 21:10:36 +00:00
switch_mutex_lock ( qm - > cond2_mutex ) ;
2012-11-27 18:48:57 +00:00
switch_thread_cond_wait ( qm - > cond , qm - > cond_mutex ) ;
2013-03-13 21:10:36 +00:00
switch_mutex_unlock ( qm - > cond2_mutex ) ;
2012-11-27 18:48:57 +00:00
}
2012-12-06 17:11:02 +00:00
i = 40 ;
2012-11-27 18:48:57 +00:00
2013-01-15 04:17:34 +00:00
while ( - - i > 0 & & ( lc = qm_ttl ( qm ) ) < 500 ) {
2012-12-06 17:11:02 +00:00
switch_yield ( 5000 ) ;
2012-10-27 01:51:51 +00:00
}
2012-12-06 17:11:02 +00:00
2007-10-04 17:25:06 +00:00
}
2007-03-29 22:34:40 +00:00
2012-10-27 01:51:51 +00:00
switch_mutex_unlock ( qm - > cond_mutex ) ;
2012-10-08 22:59:38 +00:00
2012-10-27 01:51:51 +00:00
for ( i = 0 ; i < qm - > numq ; i + + ) {
2012-11-22 03:15:31 +00:00
do_flush ( qm , i , qm - > event_db ) ;
2012-10-08 22:59:38 +00:00
}
2012-10-27 01:51:51 +00:00
switch_cache_db_release_db_handle ( & qm - > event_db ) ;
2013-03-14 18:35:42 +00:00
qm - > thread_running = 0 ;
2012-10-27 01:51:51 +00:00
2007-03-29 22:34:40 +00:00
return NULL ;
}
2012-10-27 01:51:51 +00:00
2010-07-12 02:00:13 +00:00
static char * parse_presence_data_cols ( switch_event_t * event )
{
2012-05-10 17:15:25 +00:00
char * cols [ 128 ] = { 0 } ;
2010-07-12 02:00:13 +00:00
int col_count = 0 ;
char * data_copy ;
switch_stream_handle_t stream = { 0 } ;
int i ;
char * r ;
char col_name [ 128 ] = " " ;
2010-07-13 05:47:41 +00:00
const char * data = switch_event_get_header ( event , " presence-data-cols " ) ;
2010-07-12 02:00:13 +00:00
if ( zstr ( data ) ) {
return NULL ;
}
data_copy = strdup ( data ) ;
col_count = switch_split ( data_copy , ' : ' , cols ) ;
SWITCH_STANDARD_STREAM ( stream ) ;
for ( i = 0 ; i < col_count ; i + + ) {
2011-12-12 16:45:17 +00:00
const char * val = NULL ;
2012-06-01 18:28:30 +00:00
switch_snprintfv ( col_name , sizeof ( col_name ) , " PD-%q " , cols [ i ] ) ;
2011-12-12 16:45:17 +00:00
val = switch_event_get_header_nil ( event , col_name ) ;
if ( zstr ( val ) ) {
stream . write_function ( & stream , " %q=NULL, " , cols [ i ] ) ;
} else {
stream . write_function ( & stream , " %q='%q', " , cols [ i ] , val ) ;
}
2010-07-12 02:00:13 +00:00
}
r = ( char * ) stream . data ;
if ( end_of ( r ) = = ' , ' ) {
end_of ( r ) = ' \0 ' ;
}
switch_safe_free ( data_copy ) ;
return r ;
}
2010-06-25 18:19:53 +00:00
# define MAX_SQL 5
2012-10-30 23:02:10 +00:00
# define new_sql() switch_assert(sql_idx+1 < MAX_SQL); if (exists) sql[sql_idx++]
2012-10-31 14:44:38 +00:00
# define new_sql_a() switch_assert(sql_idx+1 < MAX_SQL); sql[sql_idx++]
2010-06-25 18:19:53 +00:00
2007-03-29 22:34:40 +00:00
static void core_event_handler ( switch_event_t * event )
{
2010-06-25 18:19:53 +00:00
char * sql [ MAX_SQL ] = { 0 } ;
int sql_idx = 0 ;
2010-07-12 02:00:13 +00:00
char * extra_cols ;
2012-10-26 17:10:36 +00:00
int exists = 1 ;
char * uuid = NULL ;
2007-03-29 22:34:40 +00:00
2008-05-16 16:43:47 +00:00
switch_assert ( event ) ;
2012-10-26 17:10:36 +00:00
switch ( event - > event_id ) {
case SWITCH_EVENT_CHANNEL_UUID :
case SWITCH_EVENT_CHANNEL_CREATE :
case SWITCH_EVENT_CHANNEL_ANSWER :
case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA :
case SWITCH_EVENT_CHANNEL_HOLD :
case SWITCH_EVENT_CHANNEL_UNHOLD :
case SWITCH_EVENT_CHANNEL_EXECUTE :
case SWITCH_EVENT_CHANNEL_ORIGINATE :
case SWITCH_EVENT_CALL_UPDATE :
case SWITCH_EVENT_CHANNEL_CALLSTATE :
case SWITCH_EVENT_CHANNEL_STATE :
case SWITCH_EVENT_CHANNEL_BRIDGE :
case SWITCH_EVENT_CHANNEL_UNBRIDGE :
case SWITCH_EVENT_CALL_SECURE :
{
if ( ( uuid = switch_event_get_header ( event , " unique-id " ) ) ) {
2012-10-31 14:44:38 +00:00
exists = switch_ivr_uuid_exists ( uuid ) ;
2012-10-26 17:10:36 +00:00
}
}
break ;
default :
break ;
}
2007-03-29 22:34:40 +00:00
switch ( event - > event_id ) {
2007-03-30 00:10:33 +00:00
case SWITCH_EVENT_ADD_SCHEDULE :
2009-11-17 00:12:54 +00:00
{
const char * id = switch_event_get_header ( event , " task-id " ) ;
const char * manager = switch_event_get_header ( event , " task-sql_manager " ) ;
2010-02-06 03:38:24 +00:00
2009-11-17 00:12:54 +00:00
if ( id ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " insert into tasks values(%q,'%q','%q',%q, '%q') " ,
id ,
switch_event_get_header_nil ( event , " task-desc " ) ,
2013-10-01 14:46:28 +00:00
switch_event_get_header_nil ( event , " task-group " ) , manager ? manager : " 0 " , switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
2009-11-17 00:12:54 +00:00
}
}
2007-03-30 00:10:33 +00:00
break ;
case SWITCH_EVENT_DEL_SCHEDULE :
case SWITCH_EVENT_EXE_SCHEDULE :
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " delete from tasks where task_id=%q and hostname='%q' " ,
2013-10-01 14:46:28 +00:00
switch_event_get_header_nil ( event , " task-id " ) , switch_core_get_hostname ( ) ) ;
2007-03-30 00:10:33 +00:00
break ;
case SWITCH_EVENT_RE_SCHEDULE :
2009-11-17 00:12:54 +00:00
{
const char * id = switch_event_get_header ( event , " task-id " ) ;
const char * manager = switch_event_get_header ( event , " task-sql_manager " ) ;
2010-02-06 03:38:24 +00:00
2009-11-17 00:12:54 +00:00
if ( id ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q' " ,
switch_event_get_header_nil ( event , " task-desc " ) ,
2010-06-30 15:35:03 +00:00
switch_event_get_header_nil ( event , " task-group " ) , manager ? manager : " 0 " , id ,
2013-10-01 14:46:28 +00:00
switch_core_get_hostname ( ) ) ;
2009-11-17 00:12:54 +00:00
}
}
2007-03-30 00:10:33 +00:00
break ;
2007-03-29 22:34:40 +00:00
case SWITCH_EVENT_CHANNEL_DESTROY :
2010-08-20 18:28:17 +00:00
{
const char * uuid = switch_event_get_header ( event , " unique-id " ) ;
if ( uuid ) {
2011-08-02 05:27:38 +00:00
new_sql ( ) = switch_mprintf ( " delete from channels where uuid='%q' " ,
uuid ) ;
2011-01-29 19:43:59 +00:00
2011-08-02 05:27:38 +00:00
new_sql ( ) = switch_mprintf ( " delete from calls where (caller_uuid='%q' or callee_uuid='%q') " ,
uuid , uuid ) ;
2011-01-29 19:43:59 +00:00
2010-08-20 18:28:17 +00:00
}
}
2007-03-29 22:34:40 +00:00
break ;
2008-11-04 16:46:33 +00:00
case SWITCH_EVENT_CHANNEL_UUID :
{
2011-08-02 05:27:38 +00:00
new_sql ( ) = switch_mprintf ( " update channels set uuid='%q' where uuid='%q' " ,
2010-06-25 18:19:53 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " old-unique-id " )
2010-06-25 18:19:53 +00:00
) ;
2011-08-04 06:04:21 +00:00
new_sql ( ) = switch_mprintf ( " update channels set call_uuid='%q' where call_uuid='%q' " ,
switch_event_get_header_nil ( event , " unique-id " ) ,
switch_event_get_header_nil ( event , " old-unique-id " )
) ;
2008-11-04 16:46:33 +00:00
break ;
}
2007-03-29 22:34:40 +00:00
case SWITCH_EVENT_CHANNEL_CREATE :
2014-05-24 08:42:54 +00:00
new_sql ( ) = switch_mprintf ( " insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname,initial_cid_name,initial_cid_num,initial_ip_addr,initial_dest,initial_dialplan,initial_context) "
" values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q') " ,
2010-06-25 18:19:53 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ,
switch_event_get_header_nil ( event , " call-direction " ) ,
switch_event_get_header_nil ( event , " event-date-local " ) ,
( long ) switch_epoch_time_now ( NULL ) ,
switch_event_get_header_nil ( event , " channel-name " ) ,
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " channel-call-state " ) ,
switch_event_get_header_nil ( event , " caller-dialplan " ) ,
2014-05-24 08:42:54 +00:00
switch_event_get_header_nil ( event , " caller-context " ) , switch_core_get_switchname ( ) ,
switch_event_get_header_nil ( event , " caller-caller-id-name " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-number " ) ,
switch_event_get_header_nil ( event , " caller-network-addr " ) ,
switch_event_get_header_nil ( event , " caller-destination-number " ) ,
switch_event_get_header_nil ( event , " caller-dialplan " ) ,
switch_event_get_header_nil ( event , " caller-context " )
2010-06-25 18:19:53 +00:00
) ;
2007-03-29 22:34:40 +00:00
break ;
2012-10-26 17:10:36 +00:00
case SWITCH_EVENT_CHANNEL_ANSWER :
case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA :
2013-02-27 20:15:44 +00:00
case SWITCH_EVENT_CODEC :
2010-06-25 18:19:53 +00:00
new_sql ( ) =
2007-03-29 22:34:40 +00:00
switch_mprintf
2011-08-02 05:27:38 +00:00
( " update channels set read_codec='%q',read_rate='%q',read_bit_rate='%q',write_codec='%q',write_rate='%q',write_bit_rate='%q' where uuid='%q' " ,
2010-02-06 03:38:24 +00:00
switch_event_get_header_nil ( event , " channel-read-codec-name " ) ,
2008-12-17 20:43:13 +00:00
switch_event_get_header_nil ( event , " channel-read-codec-rate " ) ,
2010-09-29 21:52:34 +00:00
switch_event_get_header_nil ( event , " channel-read-codec-bit-rate " ) ,
2010-02-06 03:38:24 +00:00
switch_event_get_header_nil ( event , " channel-write-codec-name " ) ,
2008-12-17 20:43:13 +00:00
switch_event_get_header_nil ( event , " channel-write-codec-rate " ) ,
2010-09-29 21:52:34 +00:00
switch_event_get_header_nil ( event , " channel-write-codec-bit-rate " ) ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ) ;
2007-03-29 22:34:40 +00:00
break ;
2010-06-05 00:03:36 +00:00
case SWITCH_EVENT_CHANNEL_HOLD :
case SWITCH_EVENT_CHANNEL_UNHOLD :
2010-07-12 02:00:13 +00:00
case SWITCH_EVENT_CHANNEL_EXECUTE : {
2010-07-13 05:47:41 +00:00
new_sql ( ) = switch_mprintf ( " update channels set application='%q',application_data='%q', "
2011-08-02 05:27:38 +00:00
" presence_id='%q',presence_data='%q' where uuid='%q' " ,
2010-07-13 05:47:41 +00:00
switch_event_get_header_nil ( event , " application " ) ,
switch_event_get_header_nil ( event , " application-data " ) ,
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " )
2010-07-13 05:47:41 +00:00
) ;
2010-07-12 02:00:13 +00:00
}
2010-06-25 18:19:53 +00:00
break ;
case SWITCH_EVENT_CHANNEL_ORIGINATE :
{
2010-07-12 02:00:13 +00:00
if ( ( extra_cols = parse_presence_data_cols ( event ) ) ) {
new_sql ( ) = switch_mprintf ( " update channels set "
2011-08-02 05:27:38 +00:00
" presence_id='%q',presence_data='%q', call_uuid='%q',%s where uuid='%q' " ,
2010-07-12 02:00:13 +00:00
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
switch_event_get_header_nil ( event , " channel-call-uuid " ) ,
extra_cols ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ) ;
2010-07-12 02:00:13 +00:00
free ( extra_cols ) ;
} else {
new_sql ( ) = switch_mprintf ( " update channels set "
2011-08-02 05:27:38 +00:00
" presence_id='%q',presence_data='%q', call_uuid='%q' where uuid='%q' " ,
2010-07-12 02:00:13 +00:00
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
switch_event_get_header_nil ( event , " channel-call-uuid " ) ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ) ;
2010-07-12 02:00:13 +00:00
}
2010-06-25 18:19:53 +00:00
}
2007-03-29 22:34:40 +00:00
break ;
2010-06-15 16:44:48 +00:00
case SWITCH_EVENT_CALL_UPDATE :
{
2011-08-04 04:43:41 +00:00
new_sql ( ) = switch_mprintf ( " update channels set callee_name='%q',callee_num='%q',sent_callee_name='%q',sent_callee_num='%q',callee_direction='%q', "
2011-08-02 05:27:38 +00:00
" cid_name='%q',cid_num='%q' where uuid='%s' " ,
2011-08-01 19:43:03 +00:00
switch_event_get_header_nil ( event , " caller-callee-id-name " ) ,
switch_event_get_header_nil ( event , " caller-callee-id-number " ) ,
2011-08-04 04:43:41 +00:00
switch_event_get_header_nil ( event , " sent-callee-id-name " ) ,
switch_event_get_header_nil ( event , " sent-callee-id-number " ) ,
2011-08-01 19:43:03 +00:00
switch_event_get_header_nil ( event , " direction " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-name " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-number " ) ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " )
) ;
2010-06-15 16:44:48 +00:00
}
break ;
2010-06-24 15:32:45 +00:00
case SWITCH_EVENT_CHANNEL_CALLSTATE :
{
2011-07-13 01:36:08 +00:00
char * num = switch_event_get_header_nil ( event , " channel-call-state-number " ) ;
switch_channel_callstate_t callstate = CCS_DOWN ;
if ( num ) {
callstate = atoi ( num ) ;
}
if ( callstate ! = CCS_DOWN & & callstate ! = CCS_HANGUP ) {
2011-12-12 16:45:17 +00:00
if ( ( extra_cols = parse_presence_data_cols ( event ) ) ) {
new_sql ( ) = switch_mprintf ( " update channels set callstate='%q',%s where uuid='%q' " ,
switch_event_get_header_nil ( event , " channel-call-state " ) ,
extra_cols ,
switch_event_get_header_nil ( event , " unique-id " ) ) ;
free ( extra_cols ) ;
} else {
new_sql ( ) = switch_mprintf ( " update channels set callstate='%q' where uuid='%q' " ,
switch_event_get_header_nil ( event , " channel-call-state " ) ,
switch_event_get_header_nil ( event , " unique-id " ) ) ;
}
2011-07-13 01:36:08 +00:00
}
2010-06-30 15:35:03 +00:00
2010-06-24 15:32:45 +00:00
}
break ;
2007-03-29 22:34:40 +00:00
case SWITCH_EVENT_CHANNEL_STATE :
2008-05-16 16:43:47 +00:00
{
2008-05-06 20:00:43 +00:00
char * state = switch_event_get_header_nil ( event , " channel-state-number " ) ;
2009-04-10 17:43:18 +00:00
switch_channel_state_t state_i = CS_DESTROY ;
2007-03-29 22:34:40 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( state ) ) {
2008-05-16 16:43:47 +00:00
state_i = atoi ( state ) ;
}
2008-05-27 04:34:23 +00:00
2007-03-29 22:34:40 +00:00
switch ( state_i ) {
2011-07-13 01:36:08 +00:00
case CS_NEW :
2009-04-10 17:43:18 +00:00
case CS_DESTROY :
2011-07-13 01:36:08 +00:00
case CS_REPORTING :
2012-10-31 15:22:01 +00:00
# ifndef SWITCH_DEPRECATED_CORE_DB
case CS_HANGUP : /* marked for deprication */
# endif
2012-10-26 17:10:36 +00:00
case CS_INIT :
2007-03-29 22:34:40 +00:00
break ;
2012-10-31 15:22:01 +00:00
# ifdef SWITCH_DEPRECATED_CORE_DB
2012-10-31 14:44:38 +00:00
case CS_HANGUP : /* marked for deprication */
new_sql_a ( ) = switch_mprintf ( " update channels set state='%s' where uuid='%s' " ,
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " unique-id " ) ) ;
break ;
2012-10-31 15:22:01 +00:00
# endif
2012-06-01 18:21:12 +00:00
case CS_EXECUTE :
if ( ( extra_cols = parse_presence_data_cols ( event ) ) ) {
new_sql ( ) = switch_mprintf ( " update channels set state='%s',%s where uuid='%q' " ,
switch_event_get_header_nil ( event , " channel-state " ) ,
extra_cols ,
switch_event_get_header_nil ( event , " unique-id " ) ) ;
free ( extra_cols ) ;
} else {
new_sql ( ) = switch_mprintf ( " update channels set state='%s' where uuid='%s' " ,
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " unique-id " ) ) ;
}
break ;
2008-05-05 15:30:55 +00:00
case CS_ROUTING :
2010-07-12 02:00:13 +00:00
if ( ( extra_cols = parse_presence_data_cols ( event ) ) ) {
2011-08-02 01:59:55 +00:00
new_sql ( ) = switch_mprintf ( " update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q', "
2011-08-04 04:43:41 +00:00
" sent_callee_name='%q',sent_callee_num='%q', "
2010-07-12 02:00:13 +00:00
" ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',%s "
2011-08-02 05:27:38 +00:00
" where uuid='%s' " ,
2010-07-12 02:00:13 +00:00
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-name " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-number " ) ,
2011-08-02 01:59:55 +00:00
switch_event_get_header_nil ( event , " caller-callee-id-name " ) ,
switch_event_get_header_nil ( event , " caller-callee-id-number " ) ,
2011-08-04 04:43:41 +00:00
switch_event_get_header_nil ( event , " sent-callee-id-name " ) ,
switch_event_get_header_nil ( event , " sent-callee-id-number " ) ,
2010-07-12 02:00:13 +00:00
switch_event_get_header_nil ( event , " caller-network-addr " ) ,
switch_event_get_header_nil ( event , " caller-destination-number " ) ,
switch_event_get_header_nil ( event , " caller-dialplan " ) ,
switch_event_get_header_nil ( event , " caller-context " ) ,
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
extra_cols ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ) ;
2010-07-12 02:00:13 +00:00
free ( extra_cols ) ;
} else {
2011-08-05 04:21:38 +00:00
new_sql ( ) = switch_mprintf ( " update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q', "
" sent_callee_name='%q',sent_callee_num='%q', "
2010-07-12 02:00:13 +00:00
" ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' "
2011-08-02 05:27:38 +00:00
" where uuid='%s' " ,
2010-07-12 02:00:13 +00:00
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-name " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-number " ) ,
2011-08-02 01:59:55 +00:00
switch_event_get_header_nil ( event , " caller-callee-id-name " ) ,
switch_event_get_header_nil ( event , " caller-callee-id-number " ) ,
2011-08-04 04:43:41 +00:00
switch_event_get_header_nil ( event , " sent-callee-id-name " ) ,
switch_event_get_header_nil ( event , " sent-callee-id-number " ) ,
2010-07-12 02:00:13 +00:00
switch_event_get_header_nil ( event , " caller-network-addr " ) ,
switch_event_get_header_nil ( event , " caller-destination-number " ) ,
switch_event_get_header_nil ( event , " caller-dialplan " ) ,
switch_event_get_header_nil ( event , " caller-context " ) ,
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ) ;
2010-07-12 02:00:13 +00:00
}
2007-03-29 22:34:40 +00:00
break ;
default :
2012-10-31 14:44:38 +00:00
new_sql ( ) = switch_mprintf ( " update channels set state='%s' where uuid='%s' " ,
2010-06-25 18:19:53 +00:00
switch_event_get_header_nil ( event , " channel-state " ) ,
2011-08-02 05:27:38 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ) ;
2007-03-29 22:34:40 +00:00
break ;
}
2010-06-25 18:19:53 +00:00
2008-05-16 16:43:47 +00:00
break ;
2010-06-25 18:19:53 +00:00
2007-03-29 22:34:40 +00:00
}
case SWITCH_EVENT_CHANNEL_BRIDGE :
2010-08-17 22:26:36 +00:00
{
2012-01-02 18:22:18 +00:00
const char * a_uuid , * b_uuid , * uuid ;
2011-08-04 04:43:41 +00:00
a_uuid = switch_event_get_header ( event , " Bridge-A-Unique-ID " ) ;
b_uuid = switch_event_get_header ( event , " Bridge-B-Unique-ID " ) ;
2012-01-02 18:22:18 +00:00
uuid = switch_event_get_header ( event , " unique-id " ) ;
2011-08-04 04:43:41 +00:00
if ( zstr ( a_uuid ) | | zstr ( b_uuid ) ) {
a_uuid = switch_event_get_header_nil ( event , " caller-unique-id " ) ;
b_uuid = switch_event_get_header_nil ( event , " other-leg-unique-id " ) ;
}
2010-08-17 22:26:36 +00:00
2012-01-02 18:22:18 +00:00
if ( uuid & & ( extra_cols = parse_presence_data_cols ( event ) ) ) {
new_sql ( ) = switch_mprintf ( " update channels set %s where uuid='%s' " , extra_cols , uuid ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( extra_cols ) ;
2012-01-02 18:22:18 +00:00
}
new_sql ( ) = switch_mprintf ( " update channels set call_uuid='%q' where uuid='%s' or uuid='%s' " ,
2012-07-31 12:59:58 +00:00
switch_event_get_header_nil ( event , " channel-call-uuid " ) , a_uuid , b_uuid ) ;
2012-01-02 18:22:18 +00:00
2010-10-21 21:18:54 +00:00
2011-08-01 19:43:03 +00:00
new_sql ( ) = switch_mprintf ( " insert into calls (call_uuid,call_created,call_created_epoch, "
" caller_uuid,callee_uuid,hostname) "
" values ('%s','%s','%ld','%q','%q','%q') " ,
2010-08-17 22:26:36 +00:00
switch_event_get_header_nil ( event , " channel-call-uuid " ) ,
switch_event_get_header_nil ( event , " event-date-local " ) ,
( long ) switch_epoch_time_now ( NULL ) ,
2011-08-04 04:43:41 +00:00
a_uuid ,
b_uuid ,
2011-08-01 19:43:03 +00:00
switch_core_get_switchname ( )
2010-08-17 22:26:36 +00:00
) ;
}
2007-03-29 22:34:40 +00:00
break ;
case SWITCH_EVENT_CHANNEL_UNBRIDGE :
2011-02-02 16:53:33 +00:00
{
2012-01-02 18:22:18 +00:00
char * cuuid = switch_event_get_header_nil ( event , " caller-unique-id " ) ;
char * uuid = switch_event_get_header ( event , " unique-id " ) ;
2011-02-02 16:53:33 +00:00
2012-01-02 18:22:18 +00:00
if ( uuid & & ( extra_cols = parse_presence_data_cols ( event ) ) ) {
new_sql ( ) = switch_mprintf ( " update channels set %s where uuid='%s' " , extra_cols , uuid ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( extra_cols ) ;
2012-01-02 18:22:18 +00:00
}
2011-08-04 06:04:21 +00:00
2012-01-02 18:22:18 +00:00
new_sql ( ) = switch_mprintf ( " update channels set call_uuid=uuid where call_uuid='%s' " ,
switch_event_get_header_nil ( event , " channel-call-uuid " ) ) ;
2011-08-02 05:27:38 +00:00
new_sql ( ) = switch_mprintf ( " delete from calls where (caller_uuid='%q' or callee_uuid='%q') " ,
2012-01-02 18:22:18 +00:00
cuuid , cuuid ) ;
2011-02-02 16:53:33 +00:00
break ;
}
2007-03-29 22:34:40 +00:00
case SWITCH_EVENT_SHUTDOWN :
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " delete from channels where hostname='%q'; "
" delete from interfaces where hostname='%q'; "
" delete from calls where hostname='%q' " ,
2013-10-02 17:24:34 +00:00
switch_core_get_switchname ( ) , switch_core_get_hostname ( ) , switch_core_get_switchname ( )
2010-06-25 18:19:53 +00:00
) ;
2007-03-29 22:34:40 +00:00
break ;
case SWITCH_EVENT_LOG :
return ;
case SWITCH_EVENT_MODULE_LOAD :
{
2008-05-06 20:00:43 +00:00
const char * type = switch_event_get_header_nil ( event , " type " ) ;
const char * name = switch_event_get_header_nil ( event , " name " ) ;
const char * description = switch_event_get_header_nil ( event , " description " ) ;
const char * syntax = switch_event_get_header_nil ( event , " syntax " ) ;
2009-03-27 17:49:10 +00:00
const char * key = switch_event_get_header_nil ( event , " key " ) ;
const char * filename = switch_event_get_header_nil ( event , " filename " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( type ) & & ! zstr ( name ) ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) =
2010-02-06 03:38:24 +00:00
switch_mprintf
( " insert into interfaces (type,name,description,syntax,ikey,filename,hostname) values('%q','%q','%q','%q','%q','%q','%q') " , type , name ,
switch_str_nil ( description ) , switch_str_nil ( syntax ) , switch_str_nil ( key ) , switch_str_nil ( filename ) ,
2013-10-01 14:46:28 +00:00
switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
2007-03-29 22:34:40 +00:00
}
break ;
}
2008-08-22 17:18:26 +00:00
case SWITCH_EVENT_MODULE_UNLOAD :
{
const char * type = switch_event_get_header_nil ( event , " type " ) ;
const char * name = switch_event_get_header_nil ( event , " name " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( type ) & & ! zstr ( name ) ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " delete from interfaces where type='%q' and name='%q' and hostname='%q' " , type , name ,
2013-10-01 14:46:28 +00:00
switch_core_get_hostname ( ) ) ;
2008-08-22 17:18:26 +00:00
}
break ;
}
2009-05-29 02:08:24 +00:00
case SWITCH_EVENT_CALL_SECURE :
{
const char * type = switch_event_get_header_nil ( event , " secure_type " ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Secure Type: %s \n " , type ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( type ) ) {
2009-05-29 02:08:24 +00:00
break ;
}
2011-08-02 05:27:38 +00:00
new_sql ( ) = switch_mprintf ( " update channels set secure='%s' where uuid='%s' " ,
type , switch_event_get_header_nil ( event , " caller-unique-id " )
2010-06-25 18:19:53 +00:00
) ;
2009-05-29 02:08:24 +00:00
break ;
}
2009-06-30 18:59:05 +00:00
case SWITCH_EVENT_NAT :
{
const char * op = switch_event_get_header_nil ( event , " op " ) ;
switch_bool_t sticky = switch_true ( switch_event_get_header_nil ( event , " sticky " ) ) ;
if ( ! strcmp ( " add " , op ) ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " insert into nat (port, proto, sticky, hostname) values (%s, %s, %d,'%q') " ,
switch_event_get_header_nil ( event , " port " ) ,
2013-10-01 14:46:28 +00:00
switch_event_get_header_nil ( event , " proto " ) , sticky , switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
2009-06-30 18:59:05 +00:00
} else if ( ! strcmp ( " del " , op ) ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " delete from nat where port=%s and proto=%s and hostname='%q' " ,
switch_event_get_header_nil ( event , " port " ) ,
2013-10-01 14:46:28 +00:00
switch_event_get_header_nil ( event , " proto " ) , switch_core_get_hostname ( ) ) ;
2009-06-30 18:59:05 +00:00
} else if ( ! strcmp ( " status " , op ) ) {
/* call show nat api */
} else if ( ! strcmp ( " status_response " , op ) ) {
/* ignore */
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unknown op for SWITCH_EVENT_NAT: %s \n " , op ) ;
}
break ;
}
2007-03-29 22:34:40 +00:00
default :
break ;
}
2010-06-25 18:19:53 +00:00
if ( sql_idx ) {
2010-07-06 20:06:25 +00:00
int i = 0 ;
2011-08-05 04:21:38 +00:00
2010-06-25 18:19:53 +00:00
2010-06-30 15:35:03 +00:00
for ( i = 0 ; i < sql_idx ; i + + ) {
2010-07-06 20:06:25 +00:00
if ( switch_stristr ( " update channels " , sql [ i ] ) | | switch_stristr ( " delete from channels " , sql [ i ] ) ) {
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql [ i ] , 1 , SWITCH_FALSE ) ;
2010-07-06 20:06:25 +00:00
} else {
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql [ i ] , 0 , SWITCH_FALSE ) ;
2010-06-25 18:19:53 +00:00
}
sql [ i ] = NULL ;
2008-12-17 20:43:13 +00:00
}
2007-03-29 22:34:40 +00:00
}
}
2009-11-17 00:12:54 +00:00
static char create_complete_sql [ ] =
" CREATE TABLE complete ( \n "
2010-02-06 03:38:24 +00:00
" sticky INTEGER, \n "
" a1 VARCHAR(128), \n "
" a2 VARCHAR(128), \n "
" a3 VARCHAR(128), \n "
" a4 VARCHAR(128), \n "
" a5 VARCHAR(128), \n "
" a6 VARCHAR(128), \n "
2010-02-22 23:41:56 +00:00
" a7 VARCHAR(128), \n "
" a8 VARCHAR(128), \n "
" a9 VARCHAR(128), \n "
" a10 VARCHAR(128), \n "
" hostname VARCHAR(256) \n "
" ); \n " ;
2009-11-17 00:12:54 +00:00
static char create_alias_sql [ ] =
2010-02-22 23:41:56 +00:00
" CREATE TABLE aliases ( \n "
" sticky INTEGER, \n "
" alias VARCHAR(128), \n "
" command VARCHAR(4096), \n "
" hostname VARCHAR(256) \n "
" ); \n " ;
2009-11-17 00:12:54 +00:00
static char create_channels_sql [ ] =
" CREATE TABLE channels ( \n "
2009-12-15 23:49:30 +00:00
" uuid VARCHAR(256), \n "
2009-12-12 21:12:18 +00:00
" direction VARCHAR(32), \n "
" created VARCHAR(128), \n "
2009-11-17 00:12:54 +00:00
" created_epoch INTEGER, \n "
2009-12-12 21:12:18 +00:00
" name VARCHAR(1024), \n "
" state VARCHAR(64), \n "
" cid_name VARCHAR(1024), \n "
" cid_num VARCHAR(256), \n "
" ip_addr VARCHAR(256), \n "
" dest VARCHAR(1024), \n "
" application VARCHAR(128), \n "
2009-11-17 00:12:54 +00:00
" application_data VARCHAR(4096), \n "
2009-12-12 21:12:18 +00:00
" dialplan VARCHAR(128), \n "
" context VARCHAR(128), \n "
2010-02-06 03:38:24 +00:00
" read_codec VARCHAR(128), \n "
" read_rate VARCHAR(32), \n "
2010-09-29 21:52:34 +00:00
" read_bit_rate VARCHAR(32), \n "
2010-02-06 03:38:24 +00:00
" write_codec VARCHAR(128), \n "
" write_rate VARCHAR(32), \n "
2010-09-29 21:52:34 +00:00
" write_bit_rate VARCHAR(32), \n "
2013-04-10 15:04:41 +00:00
" secure VARCHAR(64), \n "
2010-02-06 03:38:24 +00:00
" hostname VARCHAR(256), \n "
2010-02-22 23:41:56 +00:00
" presence_id VARCHAR(4096), \n "
2010-06-15 16:44:48 +00:00
" presence_data VARCHAR(4096), \n "
" callstate VARCHAR(64), \n "
" callee_name VARCHAR(1024), \n "
" callee_num VARCHAR(256), \n "
2010-06-25 18:19:53 +00:00
" callee_direction VARCHAR(5), \n "
2011-08-04 04:43:41 +00:00
" call_uuid VARCHAR(256), \n "
" sent_callee_name VARCHAR(1024), \n "
2014-05-24 08:42:54 +00:00
" sent_callee_num VARCHAR(256), \n "
" initial_cid_name VARCHAR(1024), \n "
" initial_cid_num VARCHAR(256), \n "
" initial_ip_addr VARCHAR(256), \n "
" initial_dest VARCHAR(1024), \n "
" initial_dialplan VARCHAR(128), \n "
" initial_context VARCHAR(128) \n "
2012-04-05 17:39:47 +00:00
" ); \n " ;
2010-02-22 23:41:56 +00:00
2009-11-17 00:12:54 +00:00
static char create_calls_sql [ ] =
" CREATE TABLE calls ( \n "
2010-06-25 18:19:53 +00:00
" call_uuid VARCHAR(255), \n "
2009-12-12 21:12:18 +00:00
" call_created VARCHAR(128), \n "
2009-11-17 00:12:54 +00:00
" call_created_epoch INTEGER, \n "
2009-12-15 23:49:30 +00:00
" caller_uuid VARCHAR(256), \n "
2010-02-06 03:38:24 +00:00
" callee_uuid VARCHAR(256), \n "
" hostname VARCHAR(256) \n "
2012-04-05 17:39:47 +00:00
" ); \n " ;
2010-02-22 23:41:56 +00:00
2009-11-17 00:12:54 +00:00
static char create_interfaces_sql [ ] =
" CREATE TABLE interfaces ( \n "
2009-12-12 21:12:18 +00:00
" type VARCHAR(128), \n "
2010-02-06 03:38:24 +00:00
" name VARCHAR(1024), \n "
" description VARCHAR(4096), \n "
" ikey VARCHAR(1024), \n "
2010-02-22 23:41:56 +00:00
" filename VARCHAR(4096), \n "
" syntax VARCHAR(4096), \n "
" hostname VARCHAR(256) \n "
" ); \n " ;
2009-11-17 00:12:54 +00:00
static char create_tasks_sql [ ] =
" CREATE TABLE tasks ( \n "
" task_id INTEGER, \n "
2010-02-06 03:38:24 +00:00
" task_desc VARCHAR(4096), \n "
2010-02-22 23:41:56 +00:00
" task_group VARCHAR(1024), \n "
" task_sql_manager INTEGER, \n "
" hostname VARCHAR(256) \n "
" ); \n " ;
2010-02-06 03:38:24 +00:00
static char create_nat_sql [ ] =
2010-02-22 23:41:56 +00:00
" CREATE TABLE nat ( \n "
" sticky INTEGER, \n "
" port INTEGER, \n "
" proto INTEGER, \n "
" hostname VARCHAR(256) \n "
" ); \n " ;
2009-11-17 00:12:54 +00:00
2011-02-12 05:10:12 +00:00
static char create_registrations_sql [ ] =
" CREATE TABLE registrations ( \n "
2011-02-14 17:27:55 +00:00
" reg_user VARCHAR(256), \n "
2011-02-12 05:10:12 +00:00
" realm VARCHAR(256), \n "
" token VARCHAR(256), \n "
2012-07-31 12:59:58 +00:00
/* If url is modified please check for code in switch_core_sqldb_start for dependencies for MSSQL" */
2011-02-12 05:10:12 +00:00
" url TEXT, \n "
" expires INTEGER, \n "
" network_ip VARCHAR(256), \n "
" network_port VARCHAR(256), \n "
" network_proto VARCHAR(256), \n "
2012-05-30 18:05:05 +00:00
" hostname VARCHAR(256), \n "
" metadata VARCHAR(256) \n "
2012-04-05 17:39:47 +00:00
" ); \n " ;
2011-02-12 05:10:12 +00:00
2011-08-01 00:57:42 +00:00
static char detailed_calls_sql [ ] =
2011-08-01 15:03:00 +00:00
" create view detailed_calls as select "
" a.uuid as uuid, "
" a.direction as direction, "
" a.created as created, "
" a.created_epoch as created_epoch, "
" a.name as name, "
" a.state as state, "
" a.cid_name as cid_name, "
" a.cid_num as cid_num, "
" a.ip_addr as ip_addr, "
" a.dest as dest, "
" a.application as application, "
" a.application_data as application_data, "
" a.dialplan as dialplan, "
" a.context as context, "
" a.read_codec as read_codec, "
" a.read_rate as read_rate, "
" a.read_bit_rate as read_bit_rate, "
" a.write_codec as write_codec, "
" a.write_rate as write_rate, "
" a.write_bit_rate as write_bit_rate, "
" a.secure as secure, "
" a.hostname as hostname, "
" a.presence_id as presence_id, "
" a.presence_data as presence_data, "
" a.callstate as callstate, "
" a.callee_name as callee_name, "
" a.callee_num as callee_num, "
" a.callee_direction as callee_direction, "
" a.call_uuid as call_uuid, "
2011-08-04 04:43:41 +00:00
" a.sent_callee_name as sent_callee_name, "
" a.sent_callee_num as sent_callee_num, "
2011-08-01 15:03:00 +00:00
" b.uuid as b_uuid, "
" b.direction as b_direction, "
" b.created as b_created, "
" b.created_epoch as b_created_epoch, "
" b.name as b_name, "
" b.state as b_state, "
" b.cid_name as b_cid_name, "
" b.cid_num as b_cid_num, "
" b.ip_addr as b_ip_addr, "
" b.dest as b_dest, "
" b.application as b_application, "
" b.application_data as b_application_data, "
" b.dialplan as b_dialplan, "
" b.context as b_context, "
" b.read_codec as b_read_codec, "
" b.read_rate as b_read_rate, "
" b.read_bit_rate as b_read_bit_rate, "
" b.write_codec as b_write_codec, "
" b.write_rate as b_write_rate, "
" b.write_bit_rate as b_write_bit_rate, "
" b.secure as b_secure, "
" b.hostname as b_hostname, "
" b.presence_id as b_presence_id, "
" b.presence_data as b_presence_data, "
" b.callstate as b_callstate, "
" b.callee_name as b_callee_name, "
" b.callee_num as b_callee_num, "
" b.callee_direction as b_callee_direction, "
2011-08-01 19:43:03 +00:00
" b.call_uuid as b_call_uuid, "
2011-08-04 04:43:41 +00:00
" b.sent_callee_name as b_sent_callee_name, "
" b.sent_callee_num as b_sent_callee_num, "
2011-08-01 19:43:03 +00:00
" c.call_created_epoch as call_created_epoch "
" from channels a "
" left join calls c on a.uuid = c.caller_uuid and a.hostname = c.hostname "
" left join channels b on b.uuid = c.callee_uuid and b.hostname = c.hostname "
" where a.uuid = c.caller_uuid or a.uuid not in (select callee_uuid from calls) " ;
2012-08-22 21:24:09 +00:00
static char recovery_sql [ ] =
" CREATE TABLE recovery ( \n "
" runtime_uuid VARCHAR(255), \n "
" technology VARCHAR(255), \n "
" profile_name VARCHAR(255), \n "
" hostname VARCHAR(255), \n "
" uuid VARCHAR(255), \n "
" metadata text \n "
" ); \n " ;
2011-08-01 19:43:03 +00:00
static char basic_calls_sql [ ] =
" create view basic_calls as select "
" a.uuid as uuid, "
" a.direction as direction, "
" a.created as created, "
" a.created_epoch as created_epoch, "
" a.name as name, "
" a.state as state, "
" a.cid_name as cid_name, "
" a.cid_num as cid_num, "
" a.ip_addr as ip_addr, "
" a.dest as dest, "
" a.presence_id as presence_id, "
" a.presence_data as presence_data, "
" a.callstate as callstate, "
" a.callee_name as callee_name, "
" a.callee_num as callee_num, "
" a.callee_direction as callee_direction, "
" a.call_uuid as call_uuid, "
" a.hostname as hostname, "
2011-08-04 04:43:41 +00:00
" a.sent_callee_name as sent_callee_name, "
" a.sent_callee_num as sent_callee_num, "
2011-08-01 19:43:03 +00:00
" b.uuid as b_uuid, "
" b.direction as b_direction, "
" b.created as b_created, "
" b.created_epoch as b_created_epoch, "
" b.name as b_name, "
" b.state as b_state, "
" b.cid_name as b_cid_name, "
" b.cid_num as b_cid_num, "
" b.ip_addr as b_ip_addr, "
" b.dest as b_dest, "
" b.presence_id as b_presence_id, "
" b.presence_data as b_presence_data, "
" b.callstate as b_callstate, "
" b.callee_name as b_callee_name, "
" b.callee_num as b_callee_num, "
" b.callee_direction as b_callee_direction, "
2011-08-04 04:43:41 +00:00
" b.sent_callee_name as b_sent_callee_name, "
" b.sent_callee_num as b_sent_callee_num, "
2011-08-01 19:43:03 +00:00
" c.call_created_epoch as call_created_epoch "
2011-08-01 15:03:00 +00:00
" from channels a "
" left join calls c on a.uuid = c.caller_uuid and a.hostname = c.hostname "
" left join channels b on b.uuid = c.callee_uuid and b.hostname = c.hostname "
" where a.uuid = c.caller_uuid or a.uuid not in (select callee_uuid from calls) " ;
2011-08-01 00:57:42 +00:00
2012-08-22 21:24:09 +00:00
SWITCH_DECLARE ( void ) switch_core_recovery_flush ( const char * technology , const char * profile_name )
{
char * sql = NULL ;
switch_cache_db_handle_t * dbh ;
2012-10-08 22:59:38 +00:00
if ( switch_core_db_handle ( & dbh ) ! = SWITCH_STATUS_SUCCESS ) {
2012-08-22 21:24:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB! \n " ) ;
return ;
}
if ( zstr ( technology ) ) {
if ( zstr ( profile_name ) ) {
sql = switch_mprintf ( " delete from recovery " ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " INVALID \n " ) ;
}
} else {
if ( zstr ( profile_name ) ) {
sql = switch_mprintf ( " delete from recovery where technology='%q' " , technology ) ;
} else {
sql = switch_mprintf ( " delete from recovery where technology='%q' and profile_name='%q' " , technology , profile_name ) ;
}
}
if ( sql ) {
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
switch_safe_free ( sql ) ;
}
switch_cache_db_release_db_handle ( & dbh ) ;
}
static int recover_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
int * rp = ( int * ) pArg ;
switch_xml_t xml ;
switch_endpoint_interface_t * ep ;
switch_core_session_t * session ;
if ( argc < 4 ) {
return 0 ;
}
if ( ! ( xml = switch_xml_parse_str_dynamic ( argv [ 4 ] , SWITCH_TRUE ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " XML ERROR \n " ) ;
return 0 ;
}
if ( ! ( ep = switch_loadable_module_get_endpoint_interface ( argv [ 0 ] ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " EP ERROR \n " ) ;
return 0 ;
}
if ( ! ( session = switch_core_session_request_xml ( ep , NULL , xml ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid cdr data, call not recovered \n " ) ;
goto end ;
}
if ( ep - > recover_callback ) {
switch_caller_extension_t * extension = NULL ;
2013-10-15 21:24:32 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
int r = 0 ;
2012-08-22 21:24:09 +00:00
2013-10-15 21:24:32 +00:00
if ( ( r = ep - > recover_callback ( session ) ) > 0 ) {
const char * cbname ;
2012-08-22 21:24:09 +00:00
2013-10-15 21:24:32 +00:00
switch_channel_set_flag ( session - > channel , CF_RECOVERING ) ;
2012-08-22 21:24:09 +00:00
if ( switch_channel_get_partner_uuid ( channel ) ) {
switch_channel_set_flag ( channel , CF_RECOVERING_BRIDGE ) ;
2013-10-15 21:24:32 +00:00
}
switch_core_media_recover_session ( session ) ;
if ( ( cbname = switch_channel_get_variable ( channel , " secondary_recovery_module " ) ) ) {
switch_core_recover_callback_t recover_callback ;
if ( ( recover_callback = switch_core_get_secondary_recover_callback ( cbname ) ) ) {
r = recover_callback ( session ) ;
}
}
}
if ( r > 0 ) {
if ( ! switch_channel_test_flag ( channel , CF_RECOVERING_BRIDGE ) ) {
2012-08-22 21:24:09 +00:00
switch_xml_t callflow , param , x_extension ;
if ( ( extension = switch_caller_extension_new ( session , " recovery " , " recovery " ) ) = = 0 ) {
abort ( ) ;
}
if ( ( callflow = switch_xml_child ( xml , " callflow " ) ) & & ( x_extension = switch_xml_child ( callflow , " extension " ) ) ) {
for ( param = switch_xml_child ( x_extension , " application " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " app_name " ) ;
const char * val = switch_xml_attr_soft ( param , " app_data " ) ;
/* skip announcement type apps */
if ( strcasecmp ( var , " speak " ) & & strcasecmp ( var , " playback " ) & & strcasecmp ( var , " gentones " ) & & strcasecmp ( var , " say " ) ) {
switch_caller_extension_add_application ( session , extension , var , val ) ;
}
}
}
switch_channel_set_caller_extension ( channel , extension ) ;
}
switch_channel_set_state ( channel , CS_INIT ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE ,
" Resurrecting fallen channel %s \n " , switch_channel_get_name ( channel ) ) ;
switch_core_session_thread_launch ( session ) ;
* rp = ( * rp ) + 1 ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Endpoint %s has no recovery function \n " , argv [ 0 ] ) ;
}
end :
UNPROTECT_INTERFACE ( ep ) ;
switch_xml_free ( xml ) ;
return 0 ;
}
SWITCH_DECLARE ( int ) switch_core_recovery_recover ( const char * technology , const char * profile_name )
{
char * sql = NULL ;
char * errmsg = NULL ;
switch_cache_db_handle_t * dbh ;
int r = 0 ;
2012-10-27 01:51:51 +00:00
if ( ! sql_manager . manage ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " DATABASE NOT AVAIALBLE, REVCOVERY NOT POSSIBLE \n " ) ;
return 0 ;
}
2012-10-08 22:59:38 +00:00
if ( switch_core_db_handle ( & dbh ) ! = SWITCH_STATUS_SUCCESS ) {
2012-08-22 21:24:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB! \n " ) ;
return 0 ;
}
if ( zstr ( technology ) ) {
if ( zstr ( profile_name ) ) {
sql = switch_mprintf ( " select technology, profile_name, hostname, uuid, metadata "
" from recovery where runtime_uuid!='%q' " ,
switch_core_get_uuid ( ) ) ;
} else {
sql = switch_mprintf ( " select technology, profile_name, hostname, uuid, metadata "
" from recovery where runtime_uuid!='%q' and profile_name='%q' " ,
switch_core_get_uuid ( ) , profile_name ) ;
}
} else {
if ( zstr ( profile_name ) ) {
sql = switch_mprintf ( " select technology, profile_name, hostname, uuid, metadata "
" from recovery where technology='%q' and runtime_uuid!='%q' " ,
technology , switch_core_get_uuid ( ) ) ;
} else {
sql = switch_mprintf ( " select technology, profile_name, hostname, uuid, metadata "
" from recovery where technology='%q' and runtime_uuid!='%q' and profile_name='%q' " ,
technology , switch_core_get_uuid ( ) , profile_name ) ;
}
}
switch_cache_db_execute_sql_callback ( dbh , sql , recover_callback , & r , & errmsg ) ;
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , sql , errmsg ) ;
2014-04-30 21:37:17 +00:00
switch_safe_free ( errmsg ) ;
2012-08-22 21:24:09 +00:00
}
switch_safe_free ( sql ) ;
if ( zstr ( technology ) ) {
if ( zstr ( profile_name ) ) {
sql = switch_mprintf ( " delete from recovery where runtime_uuid!='%q' " ,
switch_core_get_uuid ( ) ) ;
} else {
sql = switch_mprintf ( " delete from recovery where runtime_uuid!='%q' and profile_name='%q' " ,
switch_core_get_uuid ( ) , profile_name ) ;
}
} else {
if ( zstr ( profile_name ) ) {
sql = switch_mprintf ( " delete from recovery where runtime_uuid!='%q' and technology='%q' " ,
switch_core_get_uuid ( ) , technology ) ;
} else {
sql = switch_mprintf ( " delete from recovery where runtime_uuid!='%q' and technology='%q' and profile_name='%q' " ,
switch_core_get_uuid ( ) , technology , profile_name ) ;
}
}
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
switch_safe_free ( sql ) ;
switch_cache_db_release_db_handle ( & dbh ) ;
return r ;
}
2012-10-10 01:20:32 +00:00
SWITCH_DECLARE ( switch_cache_db_handle_type_t ) switch_core_dbtype ( void )
{
2012-10-29 18:46:17 +00:00
switch_cache_db_handle_type_t type = SCDB_TYPE_CORE_DB ;
switch_mutex_lock ( sql_manager . ctl_mutex ) ;
if ( sql_manager . qm & & sql_manager . qm - > event_db ) {
type = sql_manager . qm - > event_db - > type ;
}
switch_mutex_unlock ( sql_manager . ctl_mutex ) ;
return type ;
2012-10-10 01:20:32 +00:00
}
SWITCH_DECLARE ( void ) switch_core_sql_exec ( const char * sql )
{
2012-10-27 01:51:51 +00:00
if ( ! sql_manager . manage ) {
return ;
}
2012-10-10 01:20:32 +00:00
if ( ! switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) ) {
return ;
}
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql , 3 , SWITCH_TRUE ) ;
2012-10-10 01:20:32 +00:00
}
2012-08-22 21:24:09 +00:00
SWITCH_DECLARE ( void ) switch_core_recovery_untrack ( switch_core_session_t * session , switch_bool_t force )
{
char * sql = NULL ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2012-10-27 01:51:51 +00:00
if ( ! sql_manager . manage ) {
return ;
}
2012-10-24 17:33:13 +00:00
if ( ! switch_channel_test_flag ( channel , CF_ANSWERED ) | | switch_channel_get_state ( channel ) < CS_SOFT_EXECUTE ) {
return ;
}
2012-08-22 21:24:09 +00:00
if ( ! switch_channel_test_flag ( channel , CF_TRACKABLE ) ) {
return ;
}
if ( ( switch_channel_test_flag ( channel , CF_RECOVERING ) ) ) {
return ;
}
2012-08-29 06:00:58 +00:00
if ( switch_channel_test_flag ( channel , CF_TRACKED ) | | force ) {
2012-08-22 21:24:09 +00:00
if ( force ) {
sql = switch_mprintf ( " delete from recovery where uuid='%q' " , switch_core_session_get_uuid ( session ) ) ;
} else {
sql = switch_mprintf ( " delete from recovery where runtime_uuid='%q' and uuid='%q' " ,
switch_core_get_uuid ( ) , switch_core_session_get_uuid ( session ) ) ;
}
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql , 3 , SWITCH_FALSE ) ;
2012-08-22 21:24:09 +00:00
switch_channel_clear_flag ( channel , CF_TRACKED ) ;
}
}
SWITCH_DECLARE ( void ) switch_core_recovery_track ( switch_core_session_t * session )
{
switch_xml_t cdr = NULL ;
char * xml_cdr_text = NULL ;
char * sql = NULL ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
const char * profile_name ;
const char * technology ;
2012-10-27 01:51:51 +00:00
if ( ! sql_manager . manage ) {
return ;
}
2012-10-24 17:33:13 +00:00
if ( ! switch_channel_test_flag ( channel , CF_ANSWERED ) | | switch_channel_get_state ( channel ) < CS_SOFT_EXECUTE ) {
return ;
}
2012-08-22 21:24:09 +00:00
if ( switch_channel_test_flag ( channel , CF_RECOVERING ) | | ! switch_channel_test_flag ( channel , CF_TRACKABLE ) ) {
return ;
}
profile_name = switch_channel_get_variable_dup ( channel , " recovery_profile_name " , SWITCH_FALSE , - 1 ) ;
technology = session - > endpoint_interface - > interface_name ;
if ( switch_ivr_generate_xml_cdr ( session , & cdr ) = = SWITCH_STATUS_SUCCESS ) {
xml_cdr_text = switch_xml_toxml_nolock ( cdr , SWITCH_FALSE ) ;
switch_xml_free ( cdr ) ;
}
if ( xml_cdr_text ) {
if ( switch_channel_test_flag ( channel , CF_TRACKED ) ) {
sql = switch_mprintf ( " update recovery set metadata='%q' where uuid='%q' " , xml_cdr_text , switch_core_session_get_uuid ( session ) ) ;
} else {
sql = switch_mprintf ( " insert into recovery (runtime_uuid, technology, profile_name, hostname, uuid, metadata) "
" values ('%q','%q','%q','%q','%q','%q') " ,
switch_core_get_uuid ( ) , switch_str_nil ( technology ) ,
2013-04-15 19:47:50 +00:00
switch_str_nil ( profile_name ) , switch_core_get_switchname ( ) , switch_core_session_get_uuid ( session ) , xml_cdr_text ) ;
2012-08-22 21:24:09 +00:00
}
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql , 2 , SWITCH_FALSE ) ;
2012-10-08 22:59:38 +00:00
2014-04-30 21:37:17 +00:00
switch_safe_free ( xml_cdr_text ) ;
2012-08-22 21:24:09 +00:00
switch_channel_set_flag ( channel , CF_TRACKED ) ;
}
}
2011-02-12 05:10:12 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_add_registration ( const char * user , const char * realm , const char * token , const char * url , uint32_t expires ,
2012-05-30 18:05:05 +00:00
const char * network_ip , const char * network_port , const char * network_proto ,
const char * metadata )
2011-02-12 05:10:12 +00:00
{
char * sql ;
2011-02-26 03:39:37 +00:00
if ( ! switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) ) {
return SWITCH_STATUS_FALSE ;
}
2011-02-17 18:12:43 +00:00
if ( runtime . multiple_registrations ) {
sql = switch_mprintf ( " delete from registrations where hostname='%q' and (url='%q' or token='%q') " ,
2011-04-29 15:24:50 +00:00
switch_core_get_switchname ( ) , url , switch_str_nil ( token ) ) ;
2011-02-17 18:12:43 +00:00
} else {
sql = switch_mprintf ( " delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' " ,
2011-04-29 15:24:50 +00:00
user , realm , switch_core_get_switchname ( ) ) ;
2011-02-17 18:12:43 +00:00
}
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql , 0 , SWITCH_FALSE ) ;
2012-05-30 18:05:05 +00:00
if ( ! zstr ( metadata ) ) {
sql = switch_mprintf ( " insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname,metadata) "
" values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%q') " ,
switch_str_nil ( user ) ,
switch_str_nil ( realm ) ,
switch_str_nil ( token ) ,
switch_str_nil ( url ) ,
expires ,
switch_str_nil ( network_ip ) ,
switch_str_nil ( network_port ) ,
switch_str_nil ( network_proto ) ,
switch_core_get_switchname ( ) ,
metadata
) ;
} else {
sql = switch_mprintf ( " insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) "
" values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q') " ,
switch_str_nil ( user ) ,
switch_str_nil ( realm ) ,
switch_str_nil ( token ) ,
switch_str_nil ( url ) ,
expires ,
switch_str_nil ( network_ip ) ,
switch_str_nil ( network_port ) ,
switch_str_nil ( network_proto ) ,
switch_core_get_switchname ( )
) ;
}
2011-02-12 05:10:12 +00:00
2011-04-19 15:31:19 +00:00
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql , 0 , SWITCH_FALSE ) ;
2011-04-19 15:31:19 +00:00
2011-02-12 05:10:12 +00:00
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_del_registration ( const char * user , const char * realm , const char * token )
{
char * sql ;
2011-02-26 03:39:37 +00:00
if ( ! switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) ) {
return SWITCH_STATUS_FALSE ;
}
2011-02-22 23:56:00 +00:00
if ( ! zstr ( token ) & & runtime . multiple_registrations ) {
2011-04-29 15:24:50 +00:00
sql = switch_mprintf ( " delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' and token='%q' " , user , realm , switch_core_get_switchname ( ) , token ) ;
2011-02-22 23:56:00 +00:00
} else {
2011-04-29 15:24:50 +00:00
sql = switch_mprintf ( " delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' " , user , realm , switch_core_get_switchname ( ) ) ;
2011-02-22 23:56:00 +00:00
}
2011-02-12 05:10:12 +00:00
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql , 0 , SWITCH_FALSE ) ;
2011-02-12 05:10:12 +00:00
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_expire_registration ( int force )
{
char * sql ;
2011-03-10 17:33:01 +00:00
time_t now ;
2011-02-12 05:10:12 +00:00
2011-02-26 03:39:37 +00:00
if ( ! switch_test_flag ( ( & runtime ) , SCF_USE_SQL ) ) {
return SWITCH_STATUS_FALSE ;
}
2011-02-12 05:10:12 +00:00
now = switch_epoch_time_now ( NULL ) ;
if ( force ) {
2011-04-29 15:24:50 +00:00
sql = switch_mprintf ( " delete from registrations where hostname='%q' " , switch_core_get_switchname ( ) ) ;
2011-02-12 05:10:12 +00:00
} else {
2011-04-29 15:24:50 +00:00
sql = switch_mprintf ( " delete from registrations where expires > 0 and expires <= %ld and hostname='%q' " , now , switch_core_get_switchname ( ) ) ;
2011-02-12 05:10:12 +00:00
}
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_push ( sql_manager . qm , sql , 0 , SWITCH_FALSE ) ;
2011-02-12 05:10:12 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2012-10-08 20:57:44 +00:00
switch_status_t switch_core_sqldb_start ( switch_memory_pool_t * pool , switch_bool_t manage )
2007-03-29 22:34:40 +00:00
{
2012-10-08 20:57:44 +00:00
switch_threadattr_t * thd_attr ;
2010-09-14 21:19:03 +00:00
2012-10-08 20:57:44 +00:00
sql_manager . memory_pool = pool ;
sql_manager . manage = manage ;
2010-02-06 03:38:24 +00:00
2012-10-08 20:57:44 +00:00
switch_mutex_init ( & sql_manager . dbh_mutex , SWITCH_MUTEX_NESTED , sql_manager . memory_pool ) ;
switch_mutex_init ( & sql_manager . io_mutex , SWITCH_MUTEX_NESTED , sql_manager . memory_pool ) ;
switch_mutex_init ( & sql_manager . ctl_mutex , SWITCH_MUTEX_NESTED , sql_manager . memory_pool ) ;
2012-07-12 19:30:37 +00:00
2012-10-08 20:57:44 +00:00
if ( ! sql_manager . manage ) goto skip ;
top :
2012-07-12 19:30:37 +00:00
2007-03-29 22:34:40 +00:00
/* Activate SQL database */
2012-10-08 20:57:44 +00:00
if ( switch_core_db_handle ( & sql_manager . dbh ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:34:40 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB! \n " ) ;
2009-11-17 00:12:54 +00:00
2012-09-30 01:48:48 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_CORE_NON_SQLITE_DB_REQ ) ) {
2011-10-17 14:34:50 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failure! ODBC IS REQUIRED! \n " ) ;
return SWITCH_STATUS_FALSE ;
}
2009-11-17 00:12:54 +00:00
if ( runtime . odbc_dsn ) {
runtime . odbc_dsn = NULL ;
2010-12-10 05:05:49 +00:00
runtime . odbc_dbtype = DBTYPE_DEFAULT ;
2009-11-23 18:25:11 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Falling back to core_db. \n " ) ;
2009-11-17 00:12:54 +00:00
goto top ;
}
2007-12-28 15:48:50 +00:00
switch_clear_flag ( ( & runtime ) , SCF_USE_SQL ) ;
2009-11-17 00:12:54 +00:00
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2009-11-17 00:12:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Opening DB \n " ) ;
2009-11-21 17:57:55 +00:00
2012-10-08 20:57:44 +00:00
switch ( sql_manager . dbh - > type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
2009-11-21 17:57:55 +00:00
case SCDB_TYPE_ODBC :
2011-08-24 18:36:13 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_CLEAR_SQL ) ) {
2009-11-21 17:57:55 +00:00
char sql [ 512 ] = " " ;
2013-10-02 17:24:34 +00:00
char * tables [ ] = { " channels " , " calls " , " tasks " , NULL } ;
2009-11-21 17:57:55 +00:00
int i ;
2011-04-29 15:24:50 +00:00
const char * hostname = switch_core_get_switchname ( ) ;
2009-11-21 17:57:55 +00:00
2010-02-06 03:38:24 +00:00
for ( i = 0 ; tables [ i ] ; i + + ) {
2011-09-29 13:28:12 +00:00
switch_snprintfv ( sql , sizeof ( sql ) , " delete from %q where hostname='%q' " , tables [ i ] , hostname ) ;
2012-10-08 20:57:44 +00:00
switch_cache_db_execute_sql ( sql_manager . dbh , sql , NULL ) ;
2009-11-21 17:57:55 +00:00
}
}
break ;
case SCDB_TYPE_CORE_DB :
{
2012-10-08 20:57:44 +00:00
switch_cache_db_execute_sql ( sql_manager . dbh , " drop table channels " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " drop table calls " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " drop view detailed_calls " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " drop view basic_calls " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " drop table interfaces " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " drop table tasks " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " PRAGMA synchronous=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " PRAGMA count_changes=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " PRAGMA default_cache_size=8000 " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " PRAGMA temp_store=MEMORY; " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , " PRAGMA journal_mode=OFF; " , NULL ) ;
2009-11-17 00:12:54 +00:00
}
2009-11-21 17:57:55 +00:00
break ;
2009-11-17 00:12:54 +00:00
}
2012-10-08 20:57:44 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " select hostname from aliases " , " DROP TABLE aliases " , create_alias_sql ) ;
switch_cache_db_test_reactive ( sql_manager . dbh , " select hostname from complete " , " DROP TABLE complete " , create_complete_sql ) ;
switch_cache_db_test_reactive ( sql_manager . dbh , " select hostname from nat " , " DROP TABLE nat " , create_nat_sql ) ;
2014-03-11 21:25:51 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " delete from registrations where reg_user='' " ,
2011-02-12 05:10:12 +00:00
" DROP TABLE registrations " , create_registrations_sql ) ;
2009-11-17 00:12:54 +00:00
2012-10-08 20:57:44 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " select metadata from registrations " , NULL , " ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256) " ) ;
2012-05-30 18:05:05 +00:00
2009-11-17 00:12:54 +00:00
2012-10-27 01:51:51 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " select hostname from recovery " , " DROP TABLE recovery " , recovery_sql ) ;
2015-01-22 20:41:22 +00:00
switch_cache_db_create_schema ( sql_manager . dbh , " create index recovery1 on recovery(technology) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index recovery2 on recovery(profile_name) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index recovery3 on recovery(uuid) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index recovery3 on recovery(runtime_uuid) " , NULL ) ;
2012-10-27 01:51:51 +00:00
2012-10-08 20:57:44 +00:00
switch ( sql_manager . dbh - > type ) {
2012-09-30 01:48:48 +00:00
case SCDB_TYPE_PGSQL :
2009-11-21 17:57:55 +00:00
case SCDB_TYPE_ODBC :
{
char * err ;
2012-11-09 14:47:30 +00:00
int result = 0 ;
2014-05-24 08:42:54 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " select call_uuid, read_bit_rate, sent_callee_name, initial_cid_name, initial_cid_num, initial_ip_addr, initial_dest, initial_dialplan, initial_context from channels " , " DROP TABLE channels " , create_channels_sql ) ;
2012-10-08 20:57:44 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " select call_uuid from calls " , " DROP TABLE calls " , create_calls_sql ) ;
2015-03-03 18:45:15 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " select * from basic_calls where sent_callee_name='' " , " DROP VIEW basic_calls " , basic_calls_sql ) ;
switch_cache_db_test_reactive ( sql_manager . dbh , " select * from detailed_calls where sent_callee_name='' " , " DROP VIEW detailed_calls " , detailed_calls_sql ) ;
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
2014-03-11 21:25:51 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " delete from registrations where reg_user='' " ,
2011-09-05 19:40:49 +00:00
" DROP TABLE registrations " , create_registrations_sql ) ;
2010-10-21 21:18:54 +00:00
} else {
2011-09-05 19:40:49 +00:00
char * tmp = switch_string_replace ( create_registrations_sql , " url TEXT " , " url VARCHAR(max) " ) ;
2014-03-11 21:25:51 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " delete from registrations where reg_user='' " ,
2011-09-05 19:40:49 +00:00
" DROP TABLE registrations " , tmp ) ;
2010-10-21 21:18:54 +00:00
free ( tmp ) ;
}
2012-10-08 20:57:44 +00:00
switch_cache_db_test_reactive ( sql_manager . dbh , " select ikey from interfaces " , " DROP TABLE interfaces " , create_interfaces_sql ) ;
switch_cache_db_test_reactive ( sql_manager . dbh , " select hostname from tasks " , " DROP TABLE tasks " , create_tasks_sql ) ;
2010-02-06 03:38:24 +00:00
2012-11-09 14:47:30 +00:00
switch ( sql_manager . dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
2012-11-17 02:09:38 +00:00
switch_cache_db_execute_sql_real ( sql_manager . dbh , " BEGIN EXCLUSIVE " , & err ) ;
2012-11-09 14:47:30 +00:00
}
break ;
case SCDB_TYPE_ODBC :
{
switch_odbc_status_t result ;
if ( ( result = switch_odbc_SQLSetAutoCommitAttr ( sql_manager . dbh - > native_handle . odbc_dbh , 0 ) ) ! = SWITCH_ODBC_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 :
{
switch_pgsql_status_t result ;
if ( ( result = switch_pgsql_SQLSetAutoCommitAttr ( sql_manager . dbh - > native_handle . pgsql_dbh , 0 ) ) ! = SWITCH_PGSQL_SUCCESS ) {
char tmp [ 100 ] ;
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to Set AutoCommit Off " , result ) ;
err = strdup ( tmp ) ;
}
}
break ;
2010-10-21 21:18:54 +00:00
}
2012-11-09 14:47:30 +00:00
switch_cache_db_execute_sql ( sql_manager . dbh , " delete from channels where hostname='' " , & err ) ;
if ( ! err ) {
switch_cache_db_execute_sql ( sql_manager . dbh , " delete from channels where hostname='' " , & err ) ;
2010-02-06 03:38:24 +00:00
2012-11-09 14:47:30 +00:00
switch ( sql_manager . dbh - > type ) {
case SCDB_TYPE_CORE_DB :
{
switch_cache_db_execute_sql_real ( sql_manager . dbh , " COMMIT " , & err ) ;
}
break ;
case SCDB_TYPE_ODBC :
{
if ( switch_odbc_SQLEndTran ( sql_manager . dbh - > native_handle . odbc_dbh , 1 ) ! = SWITCH_ODBC_SUCCESS | |
switch_odbc_SQLSetAutoCommitAttr ( sql_manager . dbh - > native_handle . odbc_dbh , 1 ) ! = SWITCH_ODBC_SUCCESS ) {
char tmp [ 100 ] ;
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to commit transaction. " , result ) ;
err = strdup ( tmp ) ;
}
}
break ;
case SCDB_TYPE_PGSQL :
{
if ( switch_pgsql_SQLEndTran ( sql_manager . dbh - > native_handle . pgsql_dbh , 1 ) ! = SWITCH_PGSQL_SUCCESS | |
switch_pgsql_SQLSetAutoCommitAttr ( sql_manager . dbh - > native_handle . pgsql_dbh , 1 ) ! = SWITCH_PGSQL_SUCCESS | |
switch_pgsql_finish_results ( sql_manager . dbh - > native_handle . pgsql_dbh ) ! = SWITCH_PGSQL_SUCCESS ) {
char tmp [ 100 ] ;
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to commit transaction. " , result ) ;
err = strdup ( tmp ) ;
}
}
break ;
}
}
2009-11-21 17:57:55 +00:00
if ( err ) {
2013-04-17 19:57:06 +00:00
//runtime.odbc_dsn = NULL;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Database Error [%s] \n " , err ) ;
//switch_cache_db_release_db_handle(&sql_manager.dbh);
2013-04-17 22:33:42 +00:00
if ( switch_stristr ( " read-only " , err ) ) {
2014-04-30 21:37:17 +00:00
switch_safe_free ( err ) ;
2013-04-17 22:33:42 +00:00
} else {
2014-04-30 21:37:17 +00:00
switch_safe_free ( err ) ;
2013-04-17 22:33:42 +00:00
goto top ;
}
2009-11-21 17:57:55 +00:00
}
2007-03-29 22:34:40 +00:00
}
2009-11-21 17:57:55 +00:00
break ;
case SCDB_TYPE_CORE_DB :
{
2012-10-08 20:57:44 +00:00
switch_cache_db_execute_sql ( sql_manager . dbh , create_channels_sql , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , create_calls_sql , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , create_interfaces_sql , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , create_tasks_sql , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , detailed_calls_sql , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , basic_calls_sql , NULL ) ;
2009-11-21 17:57:55 +00:00
}
break ;
2007-03-29 22:34:40 +00:00
}
2010-02-06 03:38:24 +00:00
2013-10-02 17:24:34 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_CLEAR_SQL ) ) {
char sql [ 512 ] = " " ;
2014-04-05 22:51:36 +00:00
char * tables [ ] = { " complete " , " aliases " , " nat " , NULL } ;
2013-10-02 17:24:34 +00:00
int i ;
const char * hostname = switch_core_get_hostname ( ) ;
for ( i = 0 ; tables [ i ] ; i + + ) {
2014-04-05 22:51:36 +00:00
switch_snprintfv ( sql , sizeof ( sql ) , " delete from %q where sticky=0 and hostname='%q' " , tables [ i ] , hostname ) ;
2013-10-02 17:24:34 +00:00
switch_cache_db_execute_sql ( sql_manager . dbh , sql , NULL ) ;
}
2014-04-05 22:51:36 +00:00
switch_snprintfv ( sql , sizeof ( sql ) , " delete from interfaces where hostname='%q' " , hostname ) ;
switch_cache_db_execute_sql ( sql_manager . dbh , sql , NULL ) ;
2013-10-02 17:24:34 +00:00
}
2007-03-29 22:34:40 +00:00
2015-01-22 20:41:22 +00:00
switch_cache_db_create_schema ( sql_manager . dbh , " create index alias1 on aliases (alias) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index tasks1 on tasks (hostname,task_id) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete1 on complete (a1,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete2 on complete (a2,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete3 on complete (a3,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete4 on complete (a4,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete5 on complete (a5,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete6 on complete (a6,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete7 on complete (a7,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete8 on complete (a8,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete9 on complete (a9,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete10 on complete (a10,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index nat_map_port_proto on nat (port,proto,hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index channels1 on channels(hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index calls1 on calls(hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index chidx1 on channels (hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index uuindex on channels (uuid, hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index uuindex2 on channels (call_uuid) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index callsidx1 on calls (hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index eruuindex on calls (caller_uuid, hostname) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index eeuuindex on calls (callee_uuid) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index eeuuindex2 on calls (call_uuid) " , NULL ) ;
switch_cache_db_create_schema ( sql_manager . dbh , " create index regindex1 on registrations (reg_user,realm,hostname) " , NULL ) ;
2012-04-05 17:39:47 +00:00
2009-11-17 00:12:54 +00:00
2010-11-01 15:25:47 +00:00
skip :
2009-11-17 00:12:54 +00:00
2012-10-08 20:57:44 +00:00
if ( sql_manager . manage ) {
2012-07-05 21:42:49 +00:00
# ifdef SWITCH_SQL_BIND_EVERY_EVENT
switch_event_bind ( " core_db " , SWITCH_EVENT_ALL , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
# else
switch_event_bind ( " core_db " , SWITCH_EVENT_ADD_SCHEDULE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_DEL_SCHEDULE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_EXE_SCHEDULE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_RE_SCHEDULE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_DESTROY , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_UUID , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_CREATE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
2012-10-26 17:10:36 +00:00
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_ANSWER , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
2012-07-05 21:42:49 +00:00
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_HOLD , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_UNHOLD , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_EXECUTE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_ORIGINATE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CALL_UPDATE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_CALLSTATE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_STATE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_BRIDGE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CHANNEL_UNBRIDGE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_SHUTDOWN , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_LOG , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_MODULE_LOAD , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_MODULE_UNLOAD , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_CALL_SECURE , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
switch_event_bind ( " core_db " , SWITCH_EVENT_NAT , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
2013-02-27 20:15:44 +00:00
switch_event_bind ( " core_db " , SWITCH_EVENT_CODEC , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ;
2012-07-05 21:42:49 +00:00
# endif
2009-11-17 00:12:54 +00:00
2012-10-08 20:57:44 +00:00
switch_threadattr_create ( & thd_attr , sql_manager . memory_pool ) ;
2012-07-31 13:03:07 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2012-10-01 15:20:48 +00:00
switch_threadattr_priority_set ( thd_attr , SWITCH_PRI_REALTIME ) ;
2012-07-31 13:03:07 +00:00
switch_core_sqldb_start_thread ( ) ;
2012-10-08 20:57:44 +00:00
switch_thread_create ( & sql_manager . db_thread , thd_attr , switch_core_sql_db_thread , NULL , sql_manager . memory_pool ) ;
2008-12-17 20:43:13 +00:00
2007-03-30 17:25:48 +00:00
}
2012-11-09 14:47:30 +00:00
switch_cache_db_release_db_handle ( & sql_manager . dbh ) ;
2009-11-17 00:12:54 +00:00
return SWITCH_STATUS_SUCCESS ;
2007-03-29 22:34:40 +00:00
}
2012-10-27 01:51:51 +00:00
SWITCH_DECLARE ( void ) switch_core_sqldb_pause ( void )
2012-07-12 19:30:37 +00:00
{
2012-10-27 01:51:51 +00:00
if ( sql_manager . paused ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " SQL is already paused. \n " ) ;
2012-07-12 19:30:37 +00:00
}
2012-10-27 01:51:51 +00:00
sql_manager . paused = 1 ;
2012-07-12 19:30:37 +00:00
}
2012-10-27 01:51:51 +00:00
SWITCH_DECLARE ( void ) switch_core_sqldb_resume ( void )
2012-07-12 19:30:37 +00:00
{
2012-10-27 01:51:51 +00:00
if ( ! sql_manager . paused ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " SQL is already running. \n " ) ;
}
sql_manager . paused = 0 ;
}
2012-08-22 21:24:09 +00:00
2012-10-08 20:57:44 +00:00
2012-10-27 01:51:51 +00:00
static void switch_core_sqldb_stop_thread ( void )
{
switch_mutex_lock ( sql_manager . ctl_mutex ) ;
if ( sql_manager . manage ) {
if ( sql_manager . qm ) {
switch_sql_queue_manager_destroy ( & sql_manager . qm ) ;
2012-08-22 21:24:09 +00:00
}
} else {
2012-10-27 01:51:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL is not enabled \n " ) ;
2012-08-22 21:24:09 +00:00
}
2012-10-27 01:51:51 +00:00
switch_mutex_unlock ( sql_manager . ctl_mutex ) ;
}
2012-08-22 21:24:09 +00:00
2012-10-27 01:51:51 +00:00
static void switch_core_sqldb_start_thread ( void )
{
2012-08-22 21:24:09 +00:00
2012-10-27 01:51:51 +00:00
switch_mutex_lock ( sql_manager . ctl_mutex ) ;
2012-10-08 20:57:44 +00:00
if ( sql_manager . manage ) {
2012-10-27 01:51:51 +00:00
if ( ! sql_manager . qm ) {
char * dbname = runtime . odbc_dsn ;
2012-07-12 19:30:37 +00:00
2012-10-27 01:51:51 +00:00
if ( zstr ( dbname ) ) {
dbname = runtime . dbname ;
if ( zstr ( dbname ) ) {
dbname = " core " ;
2012-07-12 19:30:37 +00:00
}
}
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_init_name ( " CORE " ,
& sql_manager . qm ,
4 ,
dbname ,
2012-10-27 17:27:00 +00:00
SWITCH_MAX_TRANS ,
2012-10-27 01:51:51 +00:00
runtime . core_db_pre_trans_execute ,
runtime . core_db_post_trans_execute ,
runtime . core_db_inner_pre_trans_execute ,
runtime . core_db_inner_post_trans_execute ) ;
2012-07-12 19:30:37 +00:00
}
2012-10-27 01:51:51 +00:00
switch_sql_queue_manager_start ( sql_manager . qm ) ;
2012-07-12 19:30:37 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL is not enabled \n " ) ;
2009-11-17 00:12:54 +00:00
}
2012-10-08 20:57:44 +00:00
switch_mutex_unlock ( sql_manager . ctl_mutex ) ;
2012-07-12 19:30:37 +00:00
}
2012-10-08 20:57:44 +00:00
void switch_core_sqldb_stop ( void )
2012-07-12 19:30:37 +00:00
{
switch_status_t st ;
switch_event_unbind_callback ( core_event_handler ) ;
2012-10-08 20:57:44 +00:00
if ( sql_manager . db_thread & & sql_manager . db_thread_running ) {
sql_manager . db_thread_running = - 1 ;
switch_thread_join ( & st , sql_manager . db_thread ) ;
2010-09-17 21:33:47 +00:00
}
2013-01-03 23:07:54 +00:00
switch_core_sqldb_stop_thread ( ) ;
2012-10-08 20:57:44 +00:00
switch_cache_db_flush_handles ( ) ;
sql_close ( 0 ) ;
2007-03-29 22:34:40 +00:00
}
2008-01-27 17:36:53 +00:00
2009-11-27 16:47:08 +00:00
SWITCH_DECLARE ( void ) switch_cache_db_status ( switch_stream_handle_t * stream )
{
/* return some status info suitable for the cli */
switch_cache_db_handle_t * dbh = NULL ;
switch_bool_t locked = SWITCH_FALSE ;
time_t now = switch_epoch_time_now ( NULL ) ;
char cleankey_str [ CACHE_DB_LEN ] ;
char * pos1 = NULL ;
char * pos2 = NULL ;
2011-03-03 18:54:20 +00:00
int count = 0 , used = 0 ;
2010-02-06 03:38:24 +00:00
2012-10-08 20:57:44 +00:00
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2010-02-06 03:38:24 +00:00
2012-10-08 20:57:44 +00:00
for ( dbh = sql_manager . handle_pool ; dbh ; dbh = dbh - > next ) {
2012-10-08 21:28:03 +00:00
char * needles [ 3 ] ;
2011-03-03 18:54:20 +00:00
time_t diff = 0 ;
2012-10-08 21:28:03 +00:00
int i = 0 ;
needles [ 0 ] = " pass= \" " ;
needles [ 1 ] = " password= " ;
needles [ 2 ] = " password=' " ;
2009-11-27 16:47:08 +00:00
2011-03-03 18:54:20 +00:00
diff = now - dbh - > last_used ;
2010-02-06 03:38:24 +00:00
2011-03-03 18:54:20 +00:00
if ( switch_mutex_trylock ( dbh - > mutex ) = = SWITCH_STATUS_SUCCESS ) {
switch_mutex_unlock ( dbh - > mutex ) ;
locked = SWITCH_FALSE ;
} else {
locked = SWITCH_TRUE ;
}
2009-11-27 16:47:08 +00:00
2011-03-03 18:54:20 +00:00
/* sanitize password */
memset ( cleankey_str , 0 , sizeof ( cleankey_str ) ) ;
2012-10-08 21:28:03 +00:00
for ( i = 0 ; i < 3 ; i + + ) {
if ( ( pos1 = strstr ( dbh - > name , needles [ i ] ) ) ) {
pos1 + = strlen ( needles [ i ] ) ;
if ( ! ( pos2 = strstr ( pos1 , " \" " ) ) ) {
if ( ! ( pos2 = strstr ( pos1 , " ' " ) ) ) {
if ( ! ( pos2 = strstr ( pos1 , " " ) ) ) {
pos2 = pos1 + strlen ( pos1 ) ;
}
}
}
strncpy ( cleankey_str , dbh - > name , pos1 - dbh - > name ) ;
strcpy ( & cleankey_str [ pos1 - dbh - > name ] , pos2 ) ;
break ;
}
}
if ( i = = 3 ) {
strncpy ( cleankey_str , dbh - > name , strlen ( dbh - > name ) ) ;
}
2011-03-03 18:54:20 +00:00
count + + ;
2011-03-07 21:18:46 +00:00
if ( dbh - > use_count ) {
2011-03-03 18:54:20 +00:00
used + + ;
2009-11-27 16:47:08 +00:00
}
2011-03-03 18:54:20 +00:00
2013-11-17 12:55:38 +00:00
stream - > write_function ( stream , " %s \n \t Type: %s \n \t Last used: %d \n \t Total used: %ld \n \t Flags: %s, %s(%d) \n "
2011-03-03 18:54:20 +00:00
" \t Creator: %s \n \t Last User: %s \n " ,
cleankey_str ,
switch_cache_db_type_name ( dbh - > type ) ,
diff ,
2013-11-17 12:55:38 +00:00
dbh - > total_used_count ,
2011-03-03 18:54:20 +00:00
locked ? " Locked " : " Unlocked " ,
2011-03-07 21:18:46 +00:00
dbh - > use_count ? " Attached " : " Detached " , dbh - > use_count , dbh - > creator , dbh - > last_user ) ;
2009-11-27 16:47:08 +00:00
}
2011-03-03 01:21:37 +00:00
2011-03-03 18:54:20 +00:00
stream - > write_function ( stream , " %d total. %d in use. \n " , count , used ) ;
2011-03-03 01:21:37 +00:00
2012-10-08 20:57:44 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
2009-11-27 16:47:08 +00:00
}
2011-09-01 08:31:47 +00:00
SWITCH_DECLARE ( char * ) switch_sql_concat ( void )
2011-08-31 21:04:20 +00:00
{
if ( runtime . odbc_dbtype = = DBTYPE_MSSQL )
return " + " ;
return " || " ;
}
2008-01-27 17:36:53 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2008-01-27 17:36:53 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2013-06-25 16:50:17 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 noet :
2008-01-27 17:36:53 +00:00
*/