2007-03-29 22:34:40 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2011-01-05 16:08:55 +00:00
* Copyright ( C ) 2005 - 2011 , 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 >
*
*
* 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"
2011-06-30 21:23:40 +00:00
//#define DEBUG_SQL 1
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 ;
2011-03-03 18:54:20 +00:00
struct switch_cache_db_handle * next ;
} ;
2009-12-05 18:54:56 +00:00
static struct {
switch_cache_db_handle_t * event_db ;
switch_queue_t * sql_queue [ 2 ] ;
switch_memory_pool_t * memory_pool ;
switch_event_node_t * event_node ;
switch_thread_t * thread ;
2010-09-17 21:33:47 +00:00
switch_thread_t * db_thread ;
2009-12-05 18:54:56 +00:00
int thread_running ;
2010-09-17 21:33:47 +00:00
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 ;
2011-03-03 18:54:20 +00:00
switch_cache_db_handle_t * handle_pool ;
2010-09-14 21:19:03 +00:00
switch_thread_cond_t * cond ;
switch_mutex_t * cond_mutex ;
2011-03-04 19:52:30 +00:00
uint32_t total_handles ;
uint32_t total_used_handles ;
2009-12-05 18:54:56 +00:00
} sql_manager ;
2009-12-02 02:00:17 +00:00
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 ;
}
static void add_handle ( switch_cache_db_handle_t * dbh , const char * db_str , const char * db_callsite_str , const char * thread_str )
{
switch_ssize_t hlen = - 1 ;
2011-03-03 18:54:20 +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 + + ;
2011-03-04 02:07:43 +00:00
sql_manager . total_used_handles + + ;
2011-03-03 18:54:20 +00:00
dbh - > next = sql_manager . handle_pool ;
2011-03-07 21:18:46 +00:00
2011-03-03 18:54:20 +00:00
sql_manager . handle_pool = dbh ;
sql_manager . total_handles + + ;
2011-03-04 02:07:43 +00:00
switch_mutex_lock ( dbh - > mutex ) ;
2011-03-03 18:54:20 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
}
static void del_handle ( switch_cache_db_handle_t * dbh )
{
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
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2011-03-07 21:18:46 +00:00
for ( dbh_ptr = sql_manager . handle_pool ; dbh_ptr ; dbh_ptr = dbh_ptr - > next ) {
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 {
2011-03-07 21:18:46 +00:00
sql_manager . handle_pool = dbh_ptr - > next ;
2011-03-03 18:54:20 +00:00
}
sql_manager . total_handles - - ;
break ;
}
2011-03-07 21:18:46 +00:00
last = dbh_ptr ;
2011-03-03 18:54:20 +00:00
}
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
}
2011-03-07 21:18:46 +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
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2011-03-07 21:18:46 +00:00
for ( dbh_ptr = sql_manager . handle_pool ; dbh_ptr ; dbh_ptr = dbh_ptr - > next ) {
if ( dbh_ptr - > thread_hash = = thread_hash & & dbh_ptr - > hash = = hash & &
! switch_test_flag ( dbh_ptr , CDF_PRUNE ) & & switch_mutex_trylock ( dbh_ptr - > mutex ) = = SWITCH_STATUS_SUCCESS ) {
r = dbh_ptr ;
}
}
2011-03-03 18:54:20 +00:00
2011-03-07 21:18:46 +00:00
if ( ! r ) {
for ( dbh_ptr = sql_manager . handle_pool ; dbh_ptr ; dbh_ptr = dbh_ptr - > next ) {
if ( dbh_ptr - > hash = = hash & & ! dbh_ptr - > use_count & & ! switch_test_flag ( dbh_ptr , CDF_PRUNE ) & &
switch_mutex_trylock ( dbh_ptr - > mutex ) = = SWITCH_STATUS_SUCCESS ) {
r = dbh_ptr ;
2011-03-03 18:54:20 +00:00
break ;
}
}
2011-03-07 21:18:46 +00:00
}
if ( r ) {
r - > use_count + + ;
sql_manager . total_used_handles + + ;
r - > hash = switch_ci_hashfunc_default ( db_str , & hlen ) ;
r - > thread_hash = thread_hash ;
switch_set_string ( r - > last_user , user_str ) ;
}
2011-03-03 18:54:20 +00:00
switch_mutex_unlock ( sql_manager . dbh_mutex ) ;
return r ;
}
2009-12-02 02:00:17 +00:00
# define SWITCH_CORE_DB "core"
/*!
\ 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
{
switch_cache_db_connection_options_t options = { { 0 } } ;
2009-12-05 18:54:56 +00:00
switch_status_t r ;
2010-10-12 19:48:24 +00:00
if ( ! sql_manager . manage ) {
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2011-10-17 14:34:50 +00:00
if ( zstr ( runtime . odbc_dsn ) ) {
if ( switch_test_flag ( ( & runtime ) , SCF_CORE_ODBC_REQ ) ) {
return SWITCH_STATUS_FALSE ;
}
2009-12-02 02:00:17 +00:00
2011-02-15 06:49:41 +00:00
if ( runtime . dbname ) {
options . core_db_options . db_path = runtime . dbname ;
} else {
options . core_db_options . db_path = SWITCH_CORE_DB ;
}
2009-12-05 18:54:56 +00:00
r = _switch_cache_db_get_db_handle ( dbh , SCDB_TYPE_CORE_DB , & options , file , func , line ) ;
2011-10-17 14:34:50 +00:00
} else {
options . odbc_options . dsn = runtime . odbc_dsn ;
options . odbc_options . user = runtime . odbc_user ;
options . odbc_options . pass = runtime . odbc_pass ;
r = _switch_cache_db_get_db_handle ( dbh , SCDB_TYPE_ODBC , & options , file , func , line ) ;
2009-12-02 02:00:17 +00:00
}
2011-04-15 16:18:26 +00:00
/* I *think* we can do without this now, if not let me know
2009-12-05 18:54:56 +00:00
if ( r = = SWITCH_STATUS_SUCCESS & & ! ( * dbh ) - > io_mutex ) {
( * dbh ) - > io_mutex = sql_manager . io_mutex ;
}
2011-04-15 16:18:26 +00:00
*/
2009-12-02 02:00:17 +00:00
2009-12-05 18:54:56 +00:00
return r ;
}
2007-03-29 22:34:40 +00:00
2009-11-14 21:59:01 +00:00
2010-06-30 14:05:14 +00:00
# define SQL_CACHE_TIMEOUT 120
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
2009-11-14 21:59:01 +00:00
static void sql_close ( time_t prune )
{
switch_cache_db_handle_t * dbh = NULL ;
int locked = 0 ;
2010-02-06 03:38:24 +00:00
2009-12-05 18:54:56 +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
2011-03-03 18:54:20 +00:00
for ( dbh = sql_manager . handle_pool ; dbh ; dbh = dbh - > next ) {
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 ) {
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
2011-03-03 18:54:20 +00:00
del_handle ( dbh ) ;
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 ) {
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 ) {
goto top ;
}
2009-12-05 18:54:56 +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 ;
}
2010-02-06 03:38:24 +00:00
SWITCH_DECLARE ( void ) switch_cache_db_flush_handles ( void )
{
2009-12-17 00:03:17 +00:00
sql_close ( switch_epoch_time_now ( NULL ) + SQL_CACHE_TIMEOUT + 1 ) ;
}
2010-06-30 15:35:03 +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 ) {
2011-03-03 18:54:20 +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 ) ;
2011-03-03 18:54:20 +00:00
sql_manager . total_used_handles - - ;
2009-11-14 21:59:01 +00:00
* dbh = NULL ;
2011-03-03 18:54:20 +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
}
2010-06-30 15:35:03 +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 ;
2009-11-27 16:47:08 +00:00
const char * db_user = NULL ;
const char * db_pass = NULL ;
2009-11-21 17:57:55 +00:00
2011-03-04 19:52:30 +00:00
while ( runtime . max_db_handles & & sql_manager . total_handles > = runtime . max_db_handles & & sql_manager . total_used_handles > = sql_manager . total_handles ) {
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 ) {
case SCDB_TYPE_ODBC :
{
db_name = connection_options - > odbc_options . dsn ;
2009-11-27 16:47:08 +00:00
db_user = connection_options - > odbc_options . user ;
db_pass = connection_options - > odbc_options . pass ;
2009-11-21 17:57:55 +00:00
}
break ;
case SCDB_TYPE_CORE_DB :
{
db_name = connection_options - > core_db_options . db_path ;
2009-11-27 16:47:08 +00:00
db_user = " " ;
db_pass = " " ;
2009-11-21 17:57:55 +00:00
}
break ;
}
if ( ! db_name ) {
return SWITCH_STATUS_FALSE ;
}
2009-11-14 21:59:01 +00:00
2011-03-07 21:18:46 +00:00
2009-11-27 16:47:08 +00:00
snprintf ( db_str , sizeof ( db_str ) - 1 , " db= \" %s \" ;user= \" %s \" ;pass= \" %s \" " , db_name , db_user , db_pass ) ;
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
2011-03-07 21:18:46 +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 ;
2009-11-21 17:57:55 +00:00
switch ( type ) {
case SCDB_TYPE_ODBC :
{
if ( ! switch_odbc_available ( ) ) {
2010-09-14 19:30:36 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failure! ODBC NOT AVAILABLE! \n " ) ;
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
}
if ( ! db & & ! odbc_dbh ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Failure! \n " ) ;
goto end ;
}
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , NULL , SWITCH_LOG_DEBUG10 ,
2011-03-03 18:54:20 +00:00
" Create Cached DB handle %s [%s] %s:%d \n " , new_dbh - > name , switch_cache_db_type_name ( type ) , file , line ) ;
2009-11-20 23:12:07 +00:00
2011-03-07 21:18:46 +00:00
new_dbh = create_handle ( type ) ;
2009-11-23 18:25:11 +00:00
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 ;
2010-07-23 21:15:10 +00:00
} else {
2010-02-06 03:38:24 +00:00
new_dbh - > native_handle . odbc_dbh = odbc_dbh ;
2010-07-23 21:15:10 +00:00
}
2011-03-07 21:18:46 +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 ;
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 ) {
case SCDB_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 :
{
status = switch_core_db_exec ( dbh - > native_handle . core_db_dbh , sql , NULL , NULL , & errmsg ) ;
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 ) ) {
2009-11-17 00:12:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR [%s] \n %s \n " , errmsg , sql ) ;
}
if ( err ) {
* err = errmsg ;
} else {
free ( errmsg ) ;
}
}
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 ;
}
2010-09-17 19:49:43 +00:00
static void wake_thread ( int force )
2010-09-17 19:05:48 +00:00
{
2010-09-17 19:49:43 +00:00
if ( force ) {
switch_thread_cond_signal ( sql_manager . cond ) ;
return ;
}
2010-09-17 19:05:48 +00:00
if ( switch_mutex_trylock ( sql_manager . cond_mutex ) = = SWITCH_STATUS_SUCCESS ) {
switch_thread_cond_signal ( sql_manager . cond ) ;
switch_mutex_unlock ( sql_manager . cond_mutex ) ;
}
}
2009-11-20 23:12:07 +00:00
/**
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 ;
int chunk_count ;
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 ;
}
return 0 ;
}
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 ;
}
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
SWITCH_DECLARE ( switch_status_t ) switch_cache_db_persistant_execute_trans ( switch_cache_db_handle_t * dbh , char * sql , uint32_t retries )
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
2010-06-25 18:19:53 +00:00
again :
2007-03-29 22:34:40 +00:00
while ( begin_retries > 0 ) {
again = 0 ;
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
switch_cache_db_execute_sql_real ( dbh , " BEGIN " , & errmsg ) ;
} else {
2010-11-08 14:05:23 +00:00
switch_odbc_status_t result ;
2011-03-01 16:52:12 +00:00
2010-11-08 14:05:23 +00:00
if ( ( result = switch_odbc_SQLSetAutoCommitAttr ( dbh - > native_handle . odbc_dbh , 0 ) ) ! = SWITCH_ODBC_SUCCESS ) {
char tmp [ 100 ] ;
2011-09-29 13:28:12 +00:00
switch_snprintfv ( tmp , sizeof ( tmp ) , " %q-%i " , " Unable to Set AutoCommit Off " , result ) ;
2010-11-08 14:05:23 +00:00
errmsg = strdup ( tmp ) ;
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
}
2009-11-17 00:12:54 +00:00
free ( errmsg ) ;
2008-05-16 16:43:47 +00:00
errmsg = NULL ;
2007-03-29 22:34:40 +00:00
if ( again ) {
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
switch_cache_db_execute_sql_real ( dbh , " COMMIT " , NULL ) ;
} else {
switch_odbc_SQLEndTran ( dbh - > native_handle . odbc_dbh , 1 ) ;
switch_odbc_SQLSetAutoCommitAttr ( dbh - > native_handle . odbc_dbh , 1 ) ;
}
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
}
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 ) ;
2009-11-17 00:12:54 +00:00
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 ;
}
}
2010-06-25 18:19:53 +00:00
done :
2007-03-29 22:34:40 +00:00
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
switch_cache_db_execute_sql_real ( dbh , " COMMIT " , NULL ) ;
} else {
switch_odbc_SQLEndTran ( dbh - > native_handle . odbc_dbh , 1 ) ;
switch_odbc_SQLSetAutoCommitAttr ( dbh - > native_handle . odbc_dbh , 1 ) ;
}
2007-03-29 22:34:40 +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 ;
}
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 ) {
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 :
{
status = switch_core_db_exec ( dbh - > native_handle . core_db_dbh , sql , callback , pdata , & errmsg ) ;
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 ;
}
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
{
char * errmsg ;
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
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 ) ) {
2010-08-18 14:53:22 +00:00
switch_cache_db_execute_sql ( dbh , ( char * ) test_sql , NULL ) ;
2010-08-04 14:56:53 +00:00
return SWITCH_TRUE ;
}
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 ) {
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-12-16 22:20:22 +00:00
r = SWITCH_FALSE ;
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
}
2010-01-13 01:40:11 +00:00
switch_odbc_handle_exec ( dbh - > native_handle . odbc_dbh , reactive_sql , NULL , NULL ) ;
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 :
{
if ( test_sql ) {
switch_core_db_exec ( dbh - > native_handle . core_db_dbh , test_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 ;
2009-11-21 17:57:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SQL ERR [%s] \n [%s] \n Auto Generating Table! \n " , errmsg , test_sql ) ;
2009-11-17 00:12:54 +00:00
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
2009-11-21 17:57:55 +00:00
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 , " SQL ERR [%s] \n [%s] \n " , errmsg , reactive_sql ) ;
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
}
switch_core_db_exec ( dbh - > native_handle . core_db_dbh , reactive_sql , NULL , NULL , & errmsg ) ;
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SQL ERR [%s] \n [%s] \n " , errmsg , reactive_sql ) ;
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
}
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 )
{
2011-02-12 05:10:12 +00:00
int sec = 0 , reg_sec = 0 ; ;
2009-11-14 21:59:01 +00:00
2010-09-17 21:33:47 +00:00
sql_manager . db_thread_running = 1 ;
while ( sql_manager . db_thread_running = = 1 ) {
2011-03-03 18:54:20 +00:00
if ( + + sec = = SQL_CACHE_TIMEOUT ) {
2010-09-17 21:33:47 +00:00
sql_close ( switch_epoch_time_now ( NULL ) ) ;
2010-10-05 16:11:21 +00:00
wake_thread ( 0 ) ;
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
2010-02-06 03:38:24 +00:00
static void * SWITCH_THREAD_FUNC switch_core_sql_thread ( switch_thread_t * thread , void * obj )
2007-03-29 22:34:40 +00:00
{
2010-09-15 21:21:10 +00:00
void * pop = NULL ;
2010-09-14 21:22:21 +00:00
uint32_t iterations = 0 ;
2010-09-14 21:19:03 +00:00
uint8_t trans = 0 ;
uint32_t target = 20000 ;
switch_size_t len = 0 , sql_len = runtime . sql_buffer_len ;
char * tmp , * sqlbuf = ( char * ) malloc ( sql_len ) ;
2010-12-03 18:38:49 +00:00
char * sql = NULL , * save_sql = NULL ;
2007-03-29 22:34:40 +00:00
switch_size_t newlen ;
2010-12-04 00:34:07 +00:00
int lc = 0 , wrote = 0 , do_sleep = 1 ;
2010-04-22 18:28:44 +00:00
uint32_t sanity = 120 ;
2011-07-12 02:27:06 +00:00
int auto_pause = 0 ;
2007-12-11 20:50:52 +00:00
switch_assert ( sqlbuf ) ;
2010-04-22 18:28:44 +00:00
while ( ! sql_manager . event_db ) {
2010-06-30 15:35:03 +00:00
if ( switch_core_db_handle ( & sql_manager . event_db ) = = SWITCH_STATUS_SUCCESS & & sql_manager . event_db )
break ;
2010-04-22 18:28:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Error getting core db, Retrying \n " ) ;
switch_yield ( 500000 ) ;
sanity - - ;
}
2007-05-10 16:56:29 +00:00
if ( ! sql_manager . event_db ) {
2010-04-22 18:28:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Error getting core db Disabling core sql functionality \n " ) ;
return NULL ;
2007-03-29 22:34:40 +00:00
}
2007-05-10 16:56:29 +00:00
sql_manager . thread_running = 1 ;
2007-03-29 22:34:40 +00:00
2010-09-22 23:14:24 +00:00
switch_mutex_lock ( sql_manager . cond_mutex ) ;
2010-09-14 21:19:03 +00:00
2011-07-18 14:51:08 +00:00
switch ( sql_manager . event_db - > type ) {
case SCDB_TYPE_ODBC :
break ;
case SCDB_TYPE_CORE_DB :
{
switch_cache_db_execute_sql ( sql_manager . event_db , " PRAGMA synchronous=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . event_db , " PRAGMA count_changes=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . event_db , " PRAGMA temp_store=MEMORY; " , NULL ) ;
switch_cache_db_execute_sql ( sql_manager . event_db , " PRAGMA journal_mode=OFF; " , NULL ) ;
}
break ;
}
2011-07-13 01:36:08 +00:00
2010-09-22 23:14:24 +00:00
while ( sql_manager . thread_running = = 1 ) {
2010-12-03 18:38:49 +00:00
if ( save_sql | | switch_queue_trypop ( sql_manager . sql_queue [ 0 ] , & pop ) = = SWITCH_STATUS_SUCCESS | |
2008-12-17 20:43:13 +00:00
switch_queue_trypop ( sql_manager . sql_queue [ 1 ] , & pop ) = = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:34:40 +00:00
2010-12-03 18:38:49 +00:00
if ( save_sql ) {
sql = save_sql ;
save_sql = NULL ;
} else if ( ( sql = ( char * ) pop ) ) {
pop = NULL ;
}
2007-03-29 22:34:40 +00:00
if ( sql ) {
newlen = strlen ( sql ) + 2 ;
2010-09-14 21:22:21 +00:00
if ( iterations = = 0 ) {
2007-03-29 22:34:40 +00:00
trans = 1 ;
}
2010-02-06 03:38:24 +00:00
2011-08-17 14:34:56 +00:00
if ( len + newlen + 1 > sql_len ) {
2010-09-14 21:19:03 +00:00
int new_mlen = len + newlen + 10240 ;
2010-09-07 15:51:02 +00:00
2010-09-14 21:19:03 +00:00
if ( new_mlen < runtime . max_sql_buffer_len ) {
sql_len = new_mlen ;
2010-09-17 21:33:47 +00:00
# ifdef DEBUG_SQL
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT ,
2010-09-15 06:57:31 +00:00
" REALLOC %ld %d %d \n " , ( long int ) sql_len , switch_queue_size ( sql_manager . sql_queue [ 0 ] ) ,
2010-09-14 21:19:03 +00:00
switch_queue_size ( sql_manager . sql_queue [ 1 ] ) ) ;
2010-09-17 21:33:47 +00:00
# endif
2010-09-14 21:19:03 +00:00
if ( ! ( tmp = realloc ( sqlbuf , sql_len ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL thread ending on mem err \n " ) ;
abort ( ) ;
break ;
}
sqlbuf = tmp ;
2010-09-07 15:51:02 +00:00
} else {
2010-09-17 21:33:47 +00:00
# ifdef DEBUG_SQL
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT ,
2010-09-14 21:19:03 +00:00
" SAVE %d %d \n " , switch_queue_size ( sql_manager . sql_queue [ 0 ] ) , switch_queue_size ( sql_manager . sql_queue [ 1 ] ) ) ;
2010-09-17 21:33:47 +00:00
# endif
2010-12-03 18:38:49 +00:00
save_sql = sql ;
sql = NULL ;
2010-12-04 00:34:07 +00:00
lc = 0 ;
2010-09-14 21:19:03 +00:00
goto skip ;
2007-03-29 22:34:40 +00:00
}
}
2010-09-14 21:19:03 +00:00
2010-09-14 21:22:21 +00:00
iterations + + ;
2010-09-14 21:19:03 +00:00
sprintf ( sqlbuf + len , " %s; \n " , sql ) ;
len + = newlen ;
free ( sql ) ;
sql = NULL ;
2007-03-29 22:34:40 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " SQL thread ending \n " ) ;
break ;
}
}
2010-02-06 03:38:24 +00:00
2010-12-03 18:38:49 +00:00
lc = switch_queue_size ( sql_manager . sql_queue [ 0 ] ) + switch_queue_size ( sql_manager . sql_queue [ 1 ] ) ;
2010-12-04 00:34:07 +00:00
2011-07-12 02:27:06 +00:00
2011-07-14 05:13:36 +00:00
if ( lc > SWITCH_SQL_QUEUE_PAUSE_LEN ) {
2011-07-12 02:27:06 +00:00
if ( ! auto_pause ) {
auto_pause = 1 ;
switch_core_session_ctl ( SCSC_PAUSE_INBOUND , & auto_pause ) ;
auto_pause = 1 ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " SQL Queue overflowing [%d], Pausing calls. \n " , lc ) ;
}
} else {
if ( auto_pause & & lc < 1000 ) {
auto_pause = 0 ;
switch_core_session_ctl ( SCSC_PAUSE_INBOUND , & auto_pause ) ;
auto_pause = 0 ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " SQL Queue back to normal size, resuming.. \n " ) ;
}
}
2010-12-04 00:34:07 +00:00
skip :
2010-09-14 21:19:03 +00:00
2010-12-04 00:34:07 +00:00
wrote = 0 ;
2010-09-14 21:22:21 +00:00
if ( trans & & iterations & & ( iterations > target | | ! lc ) ) {
2010-09-17 21:33:47 +00:00
# ifdef DEBUG_SQL
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT ,
2010-09-14 21:22:21 +00:00
" RUN %d %d %d \n " , switch_queue_size ( sql_manager . sql_queue [ 0 ] ) , switch_queue_size ( sql_manager . sql_queue [ 1 ] ) , iterations ) ;
2010-09-17 21:33:47 +00:00
# endif
2009-11-20 23:12:07 +00:00
if ( switch_cache_db_persistant_execute_trans ( sql_manager . event_db , sqlbuf , 1 ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL thread unable to commit transaction, records lost! \n " ) ;
2007-03-29 22:34:40 +00:00
}
2010-09-17 21:33:47 +00:00
# ifdef DEBUG_SQL
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " DONE \n " ) ;
# endif
2011-07-13 01:36:08 +00:00
2010-09-14 21:22:21 +00:00
iterations = 0 ;
2007-03-29 22:34:40 +00:00
trans = 0 ;
len = 0 ;
* sqlbuf = ' \0 ' ;
2008-02-11 16:49:07 +00:00
lc = 0 ;
2010-12-04 00:34:07 +00:00
if ( do_sleep ) {
switch_yield ( 200000 ) ;
2011-07-13 01:36:08 +00:00
} else {
switch_yield ( 1000 ) ;
2010-12-04 00:34:07 +00:00
}
wrote = 1 ;
2008-02-11 16:49:07 +00:00
}
2010-02-06 03:38:24 +00:00
2010-12-04 00:34:07 +00:00
lc = switch_queue_size ( sql_manager . sql_queue [ 0 ] ) + switch_queue_size ( sql_manager . sql_queue [ 1 ] ) ;
2010-09-17 21:33:47 +00:00
2010-09-14 21:19:03 +00:00
if ( ! lc ) {
switch_thread_cond_wait ( sql_manager . cond , sql_manager . cond_mutex ) ;
2010-12-04 00:34:07 +00:00
} else if ( wrote ) {
2011-07-12 02:27:06 +00:00
if ( lc > 2000 ) {
2010-12-04 00:34:07 +00:00
do_sleep = 0 ;
} else {
do_sleep = 1 ;
}
2007-03-29 22:34:40 +00:00
}
2010-12-04 00:34:07 +00:00
2007-03-29 22:34:40 +00:00
}
2010-09-22 23:14:24 +00:00
switch_mutex_unlock ( sql_manager . cond_mutex ) ;
2008-12-17 20:43:13 +00:00
while ( switch_queue_trypop ( sql_manager . sql_queue [ 0 ] , & pop ) = = SWITCH_STATUS_SUCCESS ) {
free ( pop ) ;
}
while ( switch_queue_trypop ( sql_manager . sql_queue [ 1 ] , & pop ) = = SWITCH_STATUS_SUCCESS ) {
2007-10-04 17:25:06 +00:00
free ( pop ) ;
}
2007-03-29 22:34:40 +00:00
free ( sqlbuf ) ;
2009-11-17 00:12:54 +00:00
sql_manager . thread_running = 0 ;
2009-11-17 19:37:04 +00:00
switch_cache_db_release_db_handle ( & sql_manager . event_db ) ;
2007-03-29 22:34:40 +00:00
return NULL ;
}
2010-07-12 02:00:13 +00:00
static char * parse_presence_data_cols ( switch_event_t * event )
{
char * cols [ 25 ] = { 0 } ;
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 ;
2011-09-29 13:28:12 +00:00
switch_snprintfv ( col_name , sizeof ( col_name ) , " variable_%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
2010-06-30 15:35:03 +00:00
# define new_sql() 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 ;
2007-03-29 22:34:40 +00:00
2008-05-16 16:43:47 +00:00
switch_assert ( event ) ;
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 " ) ,
2011-04-29 15:24:50 +00:00
switch_event_get_header_nil ( event , " task-group " ) , manager ? manager : " 0 " , switch_core_get_switchname ( )
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' " ,
2011-04-29 15:24:50 +00:00
switch_event_get_header_nil ( event , " task-id " ) , switch_core_get_switchname ( ) ) ;
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 ,
2011-04-29 15:24:50 +00:00
switch_core_get_switchname ( ) ) ;
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 :
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname) "
" values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q') " ,
switch_event_get_header_nil ( event , " unique-id " ) ,
switch_event_get_header_nil ( event , " call-direction " ) ,
switch_event_get_header_nil ( event , " event-date-local " ) ,
( 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 " ) ,
2011-04-29 15:24:50 +00:00
switch_event_get_header_nil ( event , " caller-context " ) , switch_core_get_switchname ( )
2010-06-25 18:19:53 +00:00
) ;
2007-03-29 22:34:40 +00:00
break ;
case SWITCH_EVENT_CODEC :
2011-07-13 01:36:08 +00:00
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 :
2007-03-29 22:34:40 +00:00
case CS_HANGUP :
2009-04-10 17:43:18 +00:00
case CS_DESTROY :
2011-07-13 01:36:08 +00:00
case CS_REPORTING :
2007-03-29 22:34:40 +00:00
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 :
2011-08-02 05:27: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 ) ;
2011-12-12 16:45:17 +00:00
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' " ,
2011-12-12 16:45:17 +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 ) ;
2011-12-12 16:45:17 +00:00
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' " ,
2011-04-29 15:24:50 +00:00
switch_core_get_switchname ( ) , switch_core_get_switchname ( ) , 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 ) ,
2011-04-29 15:24:50 +00:00
switch_core_get_switchname ( )
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 ,
2011-04-29 15:24:50 +00:00
switch_core_get_switchname ( ) ) ;
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 " ) ,
2011-04-29 15:24:50 +00:00
switch_event_get_header_nil ( event , " proto " ) , sticky , switch_core_get_switchname ( )
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 " ) ,
2011-04-29 15:24:50 +00:00
switch_event_get_header_nil ( event , " proto " ) , switch_core_get_switchname ( ) ) ;
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 ] ) ) {
switch_queue_push ( sql_manager . sql_queue [ 1 ] , sql [ i ] ) ;
} else {
switch_queue_push ( sql_manager . sql_queue [ 0 ] , sql [ i ] ) ;
2010-06-25 18:19:53 +00:00
}
sql [ i ] = NULL ;
2010-10-05 16:11:21 +00:00
wake_thread ( 0 ) ;
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 "
2009-12-12 21:12:18 +00:00
" secure VARCHAR(32), \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 "
" sent_callee_num VARCHAR(256) \n "
2010-06-25 18:19:53 +00:00
" ); \n "
2011-08-02 05:27:38 +00:00
" create index chidx1 on channels (hostname); \n "
" create index uuindex on channels (uuid); \n "
" create index uuindex2 on channels (call_uuid); \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 "
2010-06-30 15:35:03 +00:00
" ); \n "
2011-08-02 05:27:38 +00:00
" create index callsidx1 on calls (hostname); \n "
" create index eruuindex on calls (caller_uuid); \n "
" create index eeuuindex on calls (callee_uuid); \n "
" create index eeuuindex2 on calls (call_uuid); \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 "
2011-09-05 19:40:49 +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 "
" hostname VARCHAR(256) \n "
" ); \n "
2011-02-15 07:24:43 +00:00
" create index regindex1 on registrations (reg_user,realm,hostname); \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) " ;
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
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 ,
const char * network_ip , const char * network_port , const char * network_proto )
{
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
}
2011-04-19 15:31:19 +00:00
switch_queue_push ( sql_manager . sql_queue [ 0 ] , sql ) ;
2011-02-14 17:27:55 +00:00
sql = switch_mprintf ( " insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) "
2011-02-12 05:10:12 +00:00
" 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 ) ,
2011-04-29 15:24:50 +00:00
switch_core_get_switchname ( )
2011-02-12 05:10:12 +00:00
) ;
2011-04-19 15:31:19 +00:00
switch_queue_push ( sql_manager . sql_queue [ 0 ] , sql ) ;
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
2011-04-19 15:31:19 +00:00
switch_queue_push ( sql_manager . sql_queue [ 0 ] , sql ) ;
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
}
2011-04-19 15:31:19 +00:00
switch_queue_push ( sql_manager . sql_queue [ 0 ] , sql ) ;
2011-02-12 05:10:12 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-11-17 00:12:54 +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
{
2009-10-20 18:44:29 +00:00
switch_threadattr_t * thd_attr ;
2009-11-17 00:12:54 +00:00
switch_cache_db_handle_t * dbh ;
2010-09-22 13:28:14 +00:00
uint32_t sanity = 400 ;
2007-03-29 22:34:40 +00:00
2007-05-10 16:56:29 +00:00
sql_manager . memory_pool = pool ;
2009-11-17 00:12:54 +00:00
sql_manager . manage = manage ;
2010-02-06 03:38:24 +00:00
2009-12-05 18:54:56 +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 ) ;
2010-09-14 21:19:03 +00:00
switch_mutex_init ( & sql_manager . cond_mutex , SWITCH_MUTEX_NESTED , sql_manager . memory_pool ) ;
switch_thread_cond_create ( & sql_manager . cond , sql_manager . memory_pool ) ;
2010-02-06 03:38:24 +00:00
2010-06-25 18:19:53 +00:00
top :
2010-02-06 03:38:24 +00:00
2010-11-01 15:25:47 +00:00
if ( ! sql_manager . manage ) goto skip ;
2007-03-29 22:34:40 +00:00
/* Activate SQL database */
2009-11-17 00:12:54 +00:00
if ( switch_core_db_handle ( & 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
2011-10-17 14:34:50 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_CORE_ODBC_REQ ) ) {
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 ;
runtime . odbc_user = NULL ;
runtime . odbc_pass = 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
switch ( dbh - > type ) {
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 ] = " " ;
2010-02-06 03:38:24 +00:00
char * tables [ ] = { " channels " , " calls " , " interfaces " , " 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 ) ;
2009-11-21 17:57:55 +00:00
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
}
}
break ;
case SCDB_TYPE_CORE_DB :
{
switch_cache_db_execute_sql ( dbh , " drop table channels " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " drop table calls " , NULL ) ;
2011-08-01 00:57:42 +00:00
switch_cache_db_execute_sql ( dbh , " drop view detailed_calls " , NULL ) ;
2011-08-01 19:43:03 +00:00
switch_cache_db_execute_sql ( dbh , " drop view basic_calls " , NULL ) ;
2009-11-21 17:57:55 +00:00
switch_cache_db_execute_sql ( dbh , " drop table interfaces " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " drop table tasks " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " PRAGMA synchronous=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " PRAGMA count_changes=OFF; " , NULL ) ;
2011-07-13 01:36:08 +00:00
switch_cache_db_execute_sql ( dbh , " PRAGMA default_cache_size=8000 " , NULL ) ;
2009-11-21 17:57:55 +00:00
switch_cache_db_execute_sql ( dbh , " PRAGMA temp_store=MEMORY; " , NULL ) ;
2011-07-13 01:36:08 +00:00
switch_cache_db_execute_sql ( 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
}
2010-02-06 03:38:24 +00:00
2009-11-17 00:12:54 +00:00
switch_cache_db_test_reactive ( dbh , " select hostname from complete " , " DROP TABLE complete " , create_complete_sql ) ;
switch_cache_db_test_reactive ( dbh , " select hostname from aliases " , " DROP TABLE aliases " , create_alias_sql ) ;
switch_cache_db_test_reactive ( dbh , " select hostname from nat " , " DROP TABLE nat " , create_nat_sql ) ;
2011-02-14 17:27:55 +00:00
switch_cache_db_test_reactive ( dbh , " delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls' " ,
2011-02-12 05:10:12 +00:00
" DROP TABLE registrations " , create_registrations_sql ) ;
2009-11-17 00:12:54 +00:00
2009-11-21 17:57:55 +00:00
switch ( dbh - > type ) {
case SCDB_TYPE_ODBC :
{
char * err ;
2011-08-15 19:48:05 +00:00
switch_cache_db_test_reactive ( dbh , " select call_uuid, read_bit_rate, sent_callee_name from channels " , " DROP TABLE channels " , create_channels_sql ) ;
2011-08-11 18:01:52 +00:00
switch_cache_db_test_reactive ( dbh , " select * from detailed_calls where sent_callee_name='' " , " DROP VIEW detailed_calls " , detailed_calls_sql ) ;
switch_cache_db_test_reactive ( dbh , " select * from basic_calls where sent_callee_name='' " , " DROP VIEW basic_calls " , basic_calls_sql ) ;
2011-09-05 19:40:49 +00:00
switch_cache_db_test_reactive ( dbh , " select call_uuid from calls " , " DROP TABLE calls " , create_calls_sql ) ;
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
2011-09-05 19:40:49 +00:00
switch_cache_db_test_reactive ( dbh , " delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls' " ,
" 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) " ) ;
switch_cache_db_test_reactive ( dbh , " delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls' " ,
" DROP TABLE registrations " , tmp ) ;
2010-10-21 21:18:54 +00:00
free ( tmp ) ;
}
2009-12-08 16:37:48 +00:00
switch_cache_db_test_reactive ( dbh , " select ikey from interfaces " , " DROP TABLE interfaces " , create_interfaces_sql ) ;
2009-11-21 17:57:55 +00:00
switch_cache_db_test_reactive ( dbh , " select hostname from tasks " , " DROP TABLE tasks " , create_tasks_sql ) ;
2010-02-06 03:38:24 +00:00
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
switch_cache_db_execute_sql ( dbh , " begin;delete from channels where hostname='';delete from channels where hostname='';commit; " , & err ) ;
} else {
switch_cache_db_execute_sql ( dbh , " delete from channels where hostname='';delete from channels where hostname=''; " , & err ) ;
}
2010-02-06 03:38:24 +00:00
2009-11-21 17:57:55 +00:00
if ( err ) {
runtime . odbc_dsn = NULL ;
runtime . odbc_user = NULL ;
runtime . odbc_pass = NULL ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Transactions not supported on your DB, disabling ODBC \n " ) ;
switch_cache_db_release_db_handle ( & dbh ) ;
free ( err ) ;
goto top ;
}
2007-03-29 22:34:40 +00:00
}
2009-11-21 17:57:55 +00:00
break ;
case SCDB_TYPE_CORE_DB :
{
switch_cache_db_execute_sql ( dbh , create_channels_sql , NULL ) ;
switch_cache_db_execute_sql ( dbh , create_calls_sql , NULL ) ;
switch_cache_db_execute_sql ( dbh , create_interfaces_sql , NULL ) ;
switch_cache_db_execute_sql ( dbh , create_tasks_sql , NULL ) ;
2011-08-01 00:57:42 +00:00
switch_cache_db_execute_sql ( dbh , detailed_calls_sql , NULL ) ;
2011-08-01 19:43:03 +00:00
switch_cache_db_execute_sql ( 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
2007-03-29 22:34:40 +00:00
2009-11-17 00:12:54 +00:00
switch_cache_db_execute_sql ( dbh , " delete from complete where sticky=0 " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " delete from aliases where sticky=0 " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " delete from nat where sticky=0 " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index alias1 on aliases (alias) " , NULL ) ;
2009-12-12 21:12:18 +00:00
switch_cache_db_execute_sql ( dbh , " create index tasks1 on tasks (hostname,task_id) " , NULL ) ;
2009-11-17 00:12:54 +00:00
switch_cache_db_execute_sql ( dbh , " create index complete1 on complete (a1,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete2 on complete (a2,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete3 on complete (a3,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete4 on complete (a4,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete5 on complete (a5,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete6 on complete (a6,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete7 on complete (a7,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete8 on complete (a8,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete9 on complete (a9,hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index complete10 on complete (a10,hostname) " , NULL ) ;
2010-07-06 17:02:50 +00:00
switch_cache_db_execute_sql ( dbh , " create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname) " , NULL ) ;
2009-12-07 15:54:17 +00:00
switch_cache_db_execute_sql ( dbh , " create index nat_map_port_proto on nat (port,proto,hostname) " , NULL ) ;
2009-11-17 00:12:54 +00:00
switch_cache_db_execute_sql ( dbh , " create index channels1 on channels(hostname) " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " create index calls1 on calls(hostname) " , NULL ) ;
2010-11-01 15:25:47 +00:00
skip :
2009-11-17 00:12:54 +00:00
if ( sql_manager . manage ) {
2010-02-06 03:38:24 +00:00
if ( switch_event_bind_removable ( " core_db " , SWITCH_EVENT_ALL , SWITCH_EVENT_SUBCLASS_ANY ,
2009-11-17 00:12:54 +00:00
core_event_handler , NULL , & sql_manager . event_node ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind event handler! \n " ) ;
}
switch_queue_create ( & sql_manager . sql_queue [ 0 ] , SWITCH_SQL_QUEUE_LEN , sql_manager . memory_pool ) ;
switch_queue_create ( & sql_manager . sql_queue [ 1 ] , SWITCH_SQL_QUEUE_LEN , sql_manager . memory_pool ) ;
}
2008-05-27 04:34:23 +00:00
2007-05-10 16:56:29 +00:00
switch_threadattr_create ( & thd_attr , sql_manager . memory_pool ) ;
2007-03-29 22:34:40 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2010-09-17 21:33:47 +00:00
if ( sql_manager . manage ) {
switch_thread_create ( & sql_manager . thread , thd_attr , switch_core_sql_thread , NULL , sql_manager . memory_pool ) ;
}
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
2010-09-22 13:28:14 +00:00
while ( sql_manager . manage & & ! sql_manager . thread_running & & - - sanity ) {
2007-03-30 17:25:48 +00:00
switch_yield ( 10000 ) ;
}
2010-02-06 03:38:24 +00:00
2010-11-01 15:25:47 +00:00
if ( sql_manager . manage ) switch_cache_db_release_db_handle ( & dbh ) ;
2009-11-17 00:12:54 +00:00
return SWITCH_STATUS_SUCCESS ;
2007-03-29 22:34:40 +00:00
}
2007-03-30 02:20:13 +00:00
void switch_core_sqldb_stop ( void )
2007-03-29 22:34:40 +00:00
{
2009-10-20 18:44:29 +00:00
switch_status_t st ;
switch_event_unbind ( & sql_manager . event_node ) ;
2010-02-06 03:38:24 +00:00
2009-11-17 00:12:54 +00:00
if ( sql_manager . thread & & sql_manager . thread_running ) {
2007-03-29 22:34:40 +00:00
2009-11-17 00:12:54 +00:00
if ( sql_manager . manage ) {
switch_queue_push ( sql_manager . sql_queue [ 0 ] , NULL ) ;
switch_queue_push ( sql_manager . sql_queue [ 1 ] , NULL ) ;
2011-03-03 01:21:37 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG10 , " Waiting for unfinished SQL transactions \n " ) ;
2010-10-05 16:11:21 +00:00
wake_thread ( 0 ) ;
2009-11-17 00:12:54 +00:00
}
sql_manager . thread_running = - 1 ;
switch_thread_join ( & st , sql_manager . thread ) ;
}
2007-03-29 22:34:40 +00:00
2010-09-17 21:33:47 +00:00
if ( sql_manager . thread & & sql_manager . db_thread_running ) {
sql_manager . db_thread_running = - 1 ;
switch_thread_join ( & st , sql_manager . db_thread ) ;
}
2010-07-23 21:15:10 +00:00
switch_cache_db_flush_handles ( ) ;
2009-11-17 19:37:04 +00:00
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
2009-12-05 18:54:56 +00:00
switch_mutex_lock ( sql_manager . dbh_mutex ) ;
2010-02-06 03:38:24 +00:00
2011-03-03 18:54:20 +00:00
for ( dbh = sql_manager . handle_pool ; dbh ; dbh = dbh - > next ) {
char * needle = " pass= \" " ;
time_t diff = 0 ;
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 ) ) ;
pos1 = strstr ( dbh - > name , needle ) + strlen ( needle ) ;
pos2 = strstr ( pos1 , " \" " ) ;
strncpy ( cleankey_str , dbh - > name , pos1 - dbh - > name ) ;
strcpy ( & cleankey_str [ pos1 - dbh - > name ] , pos2 ) ;
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
2011-03-07 21:18:46 +00:00
stream - > write_function ( stream , " %s \n \t Type: %s \n \t Last used: %d \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 ,
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
2009-12-05 18:54:56 +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 :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2008-01-27 17:36:53 +00:00
*/