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"
2010-09-17 21:33:47 +00:00
//*#define DEBUG_SQL 1
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
2010-01-13 18:02:42 +00:00
if ( ! zstr ( runtime . odbc_dsn ) ) {
2009-12-02 02:00:17 +00:00
options . odbc_options . dsn = runtime . odbc_dsn ;
options . odbc_options . user = runtime . odbc_user ;
options . odbc_options . pass = runtime . odbc_pass ;
2009-12-05 18:54:56 +00:00
r = _switch_cache_db_get_db_handle ( dbh , SCDB_TYPE_ODBC , & options , file , func , line ) ;
2009-12-02 02:00:17 +00:00
} else {
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 ) ;
2009-12-02 02:00:17 +00:00
}
2009-12-05 18:54:56 +00:00
if ( r = = SWITCH_STATUS_SUCCESS & & ! ( * dbh ) - > io_mutex ) {
( * dbh ) - > io_mutex = sql_manager . io_mutex ;
}
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
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
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 ] ;
switch_snprintf ( tmp , sizeof ( tmp ) , " %s-%i " , " Unable to Set AutoCommit Off " , result ) ;
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
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 ;
2010-12-04 00:34:07 +00:00
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
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
2010-09-14 21:19:03 +00:00
if ( len + newlen > sql_len ) {
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
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
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 ) ;
}
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 ) {
if ( lc > 2000 ) {
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 + + ) {
switch_snprintf ( col_name , sizeof ( col_name ) , " variable_%s " , cols [ i ] ) ;
stream . write_function ( & stream , " %q='%q', " , cols [ i ] , switch_event_get_header_nil ( event , col_name ) ) ;
}
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-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " task-group " ) , manager ? manager : " 0 " , switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
2009-11-17 00:12:54 +00:00
}
}
2007-03-30 00:10:33 +00:00
break ;
case SWITCH_EVENT_DEL_SCHEDULE :
case SWITCH_EVENT_EXE_SCHEDULE :
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " delete from tasks where task_id=%q and hostname='%q' " ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " task-id " ) , switch_core_get_hostname ( ) ) ;
2007-03-30 00:10:33 +00:00
break ;
case SWITCH_EVENT_RE_SCHEDULE :
2009-11-17 00:12:54 +00:00
{
const char * id = switch_event_get_header ( event , " task-id " ) ;
const char * manager = switch_event_get_header ( event , " task-sql_manager " ) ;
2010-02-06 03:38:24 +00:00
2009-11-17 00:12:54 +00:00
if ( id ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q' " ,
switch_event_get_header_nil ( event , " task-desc " ) ,
2010-06-30 15:35:03 +00:00
switch_event_get_header_nil ( event , " task-group " ) , manager ? manager : " 0 " , id ,
2011-02-02 21:43:26 +00:00
switch_core_get_hostname ( ) ) ;
2009-11-17 00:12:54 +00:00
}
}
2007-03-30 00:10:33 +00:00
break ;
2007-03-29 22:34:40 +00:00
case SWITCH_EVENT_CHANNEL_DESTROY :
2010-08-20 18:28:17 +00:00
{
const char * uuid = switch_event_get_header ( event , " unique-id " ) ;
if ( uuid ) {
new_sql ( ) = switch_mprintf ( " delete from channels where uuid='%q' and hostname='%q' " ,
2011-02-02 21:43:26 +00:00
uuid , switch_core_get_hostname ( ) ) ;
2011-01-29 19:43:59 +00:00
new_sql ( ) = switch_mprintf ( " delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q' " ,
2011-02-02 21:43:26 +00:00
uuid , uuid , switch_core_get_hostname ( ) ) ;
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 :
{
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " update channels set uuid='%q' where uuid='%q' and hostname='%q'; "
" update calls set caller_uuid='%q' where caller_uuid='%q' and hostname='%q'; "
" update calls set callee_uuid='%q' where callee_uuid='%q' and hostname='%q' " ,
switch_event_get_header_nil ( event , " unique-id " ) ,
switch_event_get_header_nil ( event , " old-unique-id " ) ,
2011-02-02 21:43:26 +00:00
switch_core_get_hostname ( ) ,
2010-06-25 18:19:53 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ,
switch_event_get_header_nil ( event , " old-unique-id " ) ,
2011-02-02 21:43:26 +00:00
switch_core_get_hostname ( ) ,
2010-06-25 18:19:53 +00:00
switch_event_get_header_nil ( event , " unique-id " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " old-unique-id " ) , switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
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-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " caller-context " ) , switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
2007-03-29 22:34:40 +00:00
break ;
case SWITCH_EVENT_CODEC :
2010-06-25 18:19:53 +00:00
new_sql ( ) =
2007-03-29 22:34:40 +00:00
switch_mprintf
2010-09-29 21:52:34 +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' and hostname='%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-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
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', "
" presence_id='%q',presence_data='%q' where uuid='%q' and hostname='%q' " ,
switch_event_get_header_nil ( event , " application " ) ,
switch_event_get_header_nil ( event , " application-data " ) ,
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( )
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 "
" presence_id='%q',presence_data='%q', call_uuid='%q',%s where uuid='%q' and hostname='%q' " ,
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-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
2010-07-12 02:00:13 +00:00
free ( extra_cols ) ;
} else {
new_sql ( ) = switch_mprintf ( " update channels set "
" presence_id='%q',presence_data='%q', call_uuid='%q' where uuid='%q' and hostname='%q' " ,
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-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
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 :
{
2010-08-17 22:26:36 +00:00
const char * name = NULL , * number = NULL , * direction ;
int recv = 0 ;
2010-06-15 16:44:48 +00:00
2010-08-17 22:26:36 +00:00
direction = switch_event_get_header ( event , " direction " ) ;
if ( direction & & strcasecmp ( direction , " send " ) ) {
recv = 1 ;
name = switch_event_get_header ( event , " callee-name " ) ;
number = switch_event_get_header ( event , " callee-number " ) ;
}
2010-06-15 16:44:48 +00:00
if ( ! name ) {
name = switch_event_get_header ( event , " caller-callee-id-name " ) ;
}
2010-06-30 15:35:03 +00:00
2010-06-15 16:44:48 +00:00
if ( ! number ) {
number = switch_event_get_header ( event , " caller-callee-id-number " ) ;
}
if ( ! zstr ( name ) & & ! zstr ( number ) ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " update channels set state='%s',callstate='%s',callee_name='%q', "
" callee_num='%q',callee_direction='%q' where uuid='%s' and hostname='%q' " ,
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " channel-call-state " ) ,
switch_str_nil ( name ) ,
switch_str_nil ( number ) ,
switch_event_get_header_nil ( event , " direction " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
2010-08-17 22:26:36 +00:00
name = switch_event_get_header ( event , " callee-name " ) ;
number = switch_event_get_header ( event , " callee-number " ) ;
if ( name & & number & & recv ) {
new_sql ( ) = switch_mprintf ( " update calls set callee_cid_name='%q',callee_cid_num='%q' where caller_uuid='%q' " ,
name , number , 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 :
{
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " update channels set callstate='%q' where uuid='%q' and hostname='%q' " ,
switch_event_get_header_nil ( event , " channel-call-state " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
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 ) {
case CS_HANGUP :
2009-04-10 17:43:18 +00:00
case CS_DESTROY :
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 ) ) ) {
new_sql ( ) = switch_mprintf ( " update channels set state='%s',cid_name='%q',cid_num='%q', "
" ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',%s "
" where uuid='%s' and hostname='%q' " ,
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-name " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-number " ) ,
switch_event_get_header_nil ( event , " caller-network-addr " ) ,
switch_event_get_header_nil ( event , " caller-destination-number " ) ,
switch_event_get_header_nil ( event , " caller-dialplan " ) ,
switch_event_get_header_nil ( event , " caller-context " ) ,
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
extra_cols ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
2010-07-12 02:00:13 +00:00
free ( extra_cols ) ;
} else {
new_sql ( ) = switch_mprintf ( " update channels set state='%s',cid_name='%q',cid_num='%q', "
" ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' "
" where uuid='%s' and hostname='%q' " ,
switch_event_get_header_nil ( event , " channel-state " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-name " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-number " ) ,
switch_event_get_header_nil ( event , " caller-network-addr " ) ,
switch_event_get_header_nil ( event , " caller-destination-number " ) ,
switch_event_get_header_nil ( event , " caller-dialplan " ) ,
switch_event_get_header_nil ( event , " caller-context " ) ,
switch_event_get_header_nil ( event , " channel-presence-id " ) ,
switch_event_get_header_nil ( event , " channel-presence-data " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
2010-07-12 02:00:13 +00:00
}
2007-03-29 22:34:40 +00:00
break ;
default :
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " update channels set state='%s' where uuid='%s' and hostname='%q' " ,
switch_event_get_header_nil ( event , " channel-state " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
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
{
const char * callee_cid_name , * callee_cid_num , * direction ;
2010-10-21 21:18:54 +00:00
char * func_name ;
2010-08-17 22:26:36 +00:00
direction = switch_event_get_header ( event , " other-leg-direction " ) ;
if ( direction & & ! strcasecmp ( direction , " outbound " ) ) {
callee_cid_name = switch_event_get_header_nil ( event , " Other-Leg-callee-id-name " ) ;
callee_cid_num = switch_event_get_header_nil ( event , " Other-Leg-callee-id-number " ) ;
} else {
callee_cid_name = switch_event_get_header_nil ( event , " Other-Leg-caller-id-name " ) ;
callee_cid_num = switch_event_get_header_nil ( event , " Other-Leg-caller-id-number " ) ;
}
new_sql ( ) = switch_mprintf ( " update channels set call_uuid='%q' where uuid='%s' and hostname='%q' " ,
switch_event_get_header_nil ( event , " channel-call-uuid " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " unique-id " ) , switch_core_get_hostname ( ) ) ;
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
func_name = " function " ;
}
else {
func_name = " call_function " ;
}
new_sql ( ) = switch_mprintf ( " insert into calls (call_uuid,call_created,call_created_epoch,%s,caller_cid_name, "
2010-08-17 22:26:36 +00:00
" caller_cid_num,caller_dest_num,caller_chan_name,caller_uuid,callee_cid_name, "
" callee_cid_num,callee_dest_num,callee_chan_name,callee_uuid,hostname) "
" values ('%s', '%s', '%ld', '%s','%q','%q','%q','%q','%s','%q','%q','%q','%q','%s','%q') " ,
2010-10-21 21:18:54 +00:00
func_name ,
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 ) ,
switch_event_get_header_nil ( event , " event-calling-function " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-name " ) ,
switch_event_get_header_nil ( event , " caller-caller-id-number " ) ,
switch_event_get_header_nil ( event , " caller-destination-number " ) ,
switch_event_get_header_nil ( event , " caller-channel-name " ) ,
switch_event_get_header_nil ( event , " caller-unique-id " ) ,
callee_cid_name ,
callee_cid_num ,
switch_event_get_header_nil ( event , " Other-Leg-destination-number " ) ,
switch_event_get_header_nil ( event , " Other-Leg-channel-name " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " Other-Leg-unique-id " ) , switch_core_get_hostname ( )
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
{
char * uuid = switch_event_get_header_nil ( event , " caller-unique-id " ) ;
new_sql ( ) = switch_mprintf ( " delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q' " ,
2011-02-02 21:43:26 +00:00
uuid , uuid , switch_core_get_hostname ( ) ) ;
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-02-02 21:43:26 +00:00
switch_core_get_hostname ( ) , switch_core_get_hostname ( ) , switch_core_get_hostname ( )
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-02-02 21:43:26 +00:00
switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
2007-03-29 22:34:40 +00:00
}
break ;
}
2008-08-22 17:18:26 +00:00
case SWITCH_EVENT_MODULE_UNLOAD :
{
const char * type = switch_event_get_header_nil ( event , " type " ) ;
const char * name = switch_event_get_header_nil ( event , " name " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( type ) & & ! zstr ( name ) ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " delete from interfaces where type='%q' and name='%q' and hostname='%q' " , type , name ,
2011-02-02 21:43:26 +00:00
switch_core_get_hostname ( ) ) ;
2008-08-22 17:18:26 +00:00
}
break ;
}
2009-05-29 02:08:24 +00:00
case SWITCH_EVENT_CALL_SECURE :
{
const char * type = switch_event_get_header_nil ( event , " secure_type " ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Secure Type: %s \n " , type ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( type ) ) {
2009-05-29 02:08:24 +00:00
break ;
}
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " update channels set secure='%s' where uuid='%s' and hostname='%q' " ,
2011-02-02 21:43:26 +00:00
type , switch_event_get_header_nil ( event , " caller-unique-id " ) , switch_core_get_hostname ( )
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-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " proto " ) , sticky , switch_core_get_hostname ( )
2010-06-25 18:19:53 +00:00
) ;
2009-06-30 18:59:05 +00:00
} else if ( ! strcmp ( " del " , op ) ) {
2010-06-25 18:19:53 +00:00
new_sql ( ) = switch_mprintf ( " delete from nat where port=%s and proto=%s and hostname='%q' " ,
switch_event_get_header_nil ( event , " port " ) ,
2011-02-02 21:43:26 +00:00
switch_event_get_header_nil ( event , " proto " ) , switch_core_get_hostname ( ) ) ;
2009-06-30 18:59:05 +00:00
} else if ( ! strcmp ( " status " , op ) ) {
/* call show nat api */
} else if ( ! strcmp ( " status_response " , op ) ) {
/* ignore */
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unknown op for SWITCH_EVENT_NAT: %s \n " , op ) ;
}
break ;
}
2007-03-29 22:34:40 +00:00
default :
break ;
}
2010-06-25 18:19:53 +00:00
if ( sql_idx ) {
2010-07-06 20:06:25 +00:00
int i = 0 ;
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 "
" call_uuid VARCHAR(256) \n "
" ); \n "
" create index uuindex on channels (uuid,hostname); \n "
" create index uuindex2 on channels (call_uuid,hostname); \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-12 21:12:18 +00:00
" function VARCHAR(1024), \n "
" caller_cid_name VARCHAR(1024), \n "
" caller_cid_num VARCHAR(256), \n "
" caller_dest_num VARCHAR(256), \n "
" caller_chan_name VARCHAR(1024), \n "
2009-12-15 23:49:30 +00:00
" caller_uuid VARCHAR(256), \n "
2009-12-12 21:12:18 +00:00
" callee_cid_name VARCHAR(1024), \n "
" callee_cid_num VARCHAR(256), \n "
2010-02-06 03:38:24 +00:00
" callee_dest_num VARCHAR(256), \n "
" callee_chan_name VARCHAR(1024), \n "
" callee_uuid VARCHAR(256), \n "
" hostname VARCHAR(256) \n "
2010-06-30 15:35:03 +00:00
" ); \n "
" create index eruuindex on calls (caller_uuid,hostname); \n "
2010-06-25 18:19:53 +00:00
" create index eeuuindex on calls (callee_uuid,hostname); \n "
2010-06-30 15:35:03 +00:00
" create index eeuuindex2 on calls (call_uuid,hostname); \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 "
" 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
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 )
{
switch_cache_db_handle_t * dbh ;
char * sql ;
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
if ( switch_core_db_handle ( & dbh ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB! \n " ) ;
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') " ,
switch_core_get_hostname ( ) , url , switch_str_nil ( token ) ) ;
} else {
sql = switch_mprintf ( " delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' " ,
user , realm , switch_core_get_hostname ( ) ) ;
}
2011-02-12 05:10:12 +00:00
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
free ( 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 ) ,
switch_core_get_hostname ( )
) ;
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
switch_cache_db_release_db_handle ( & dbh ) ;
free ( sql ) ;
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_del_registration ( const char * user , const char * realm , const char * token )
{
switch_cache_db_handle_t * dbh ;
char * sql ;
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
if ( switch_core_db_handle ( & dbh ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB! \n " ) ;
return SWITCH_STATUS_FALSE ;
}
2011-02-22 23:56:00 +00:00
if ( ! zstr ( token ) & & runtime . multiple_registrations ) {
sql = switch_mprintf ( " delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' and token='%q' " , user , realm , switch_core_get_hostname ( ) , token ) ;
} else {
sql = switch_mprintf ( " delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' " , user , realm , switch_core_get_hostname ( ) ) ;
}
2011-02-12 05:10:12 +00:00
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
switch_cache_db_release_db_handle ( & dbh ) ;
free ( sql ) ;
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_expire_registration ( int force )
{
switch_cache_db_handle_t * dbh ;
char * sql ;
switch_time_t now ;
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
if ( switch_core_db_handle ( & dbh ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB! \n " ) ;
return SWITCH_STATUS_FALSE ;
}
now = switch_epoch_time_now ( NULL ) ;
if ( force ) {
sql = switch_mprintf ( " delete from registrations where hostname='%q' " , switch_core_get_hostname ( ) ) ;
} else {
2011-02-22 23:56:00 +00:00
sql = switch_mprintf ( " delete from registrations where expires > 0 and expires <= %ld and hostname='%q' " , now , switch_core_get_hostname ( ) ) ;
2011-02-12 05:10:12 +00:00
}
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
switch_cache_db_release_db_handle ( & dbh ) ;
free ( sql ) ;
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
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 :
{
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-02-02 21:43:26 +00:00
const char * hostname = switch_core_get_hostname ( ) ;
2009-11-21 17:57:55 +00:00
2010-02-06 03:38:24 +00:00
for ( i = 0 ; tables [ i ] ; i + + ) {
2009-11-21 17:57:55 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " delete from %s where hostname='%s' " , tables [ i ] , hostname ) ;
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 ) ;
switch_cache_db_execute_sql ( dbh , " drop table interfaces " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " drop table tasks " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " PRAGMA synchronous=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " PRAGMA count_changes=OFF; " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " PRAGMA cache_size=8000 " , NULL ) ;
switch_cache_db_execute_sql ( dbh , " PRAGMA temp_store=MEMORY; " , NULL ) ;
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 ;
2010-09-29 21:52:34 +00:00
switch_cache_db_test_reactive ( dbh , " select call_uuid, read_bit_rate from channels " , " DROP TABLE channels " , create_channels_sql ) ;
2010-10-21 21:18:54 +00:00
if ( runtime . odbc_dbtype = = DBTYPE_DEFAULT ) {
switch_cache_db_test_reactive ( dbh , " select call_uuid from calls " , " DROP TABLE calls " , create_calls_sql ) ;
} else {
char * tmp = switch_string_replace ( create_calls_sql , " function " , " call_function " ) ;
switch_cache_db_test_reactive ( dbh , " select call_uuid from calls " , " DROP TABLE calls " , tmp ) ;
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 ) ;
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 ) ;
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 ) ;
}
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
}
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
*/