2007-03-29 22:34:40 +00:00
|
|
|
/*
|
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
2010-02-06 03:38:24 +00:00
|
|
|
* Copyright (C) 2005-2010, 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"
|
2007-03-29 22:34:40 +00:00
|
|
|
|
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;
|
|
|
|
int thread_running;
|
|
|
|
switch_bool_t manage;
|
|
|
|
switch_mutex_t *io_mutex;
|
|
|
|
switch_mutex_t *dbh_mutex;
|
|
|
|
switch_hash_t *dbh_hash;
|
2010-09-14 21:19:03 +00:00
|
|
|
switch_thread_cond_t *cond;
|
|
|
|
switch_mutex_t *cond_mutex;
|
2009-12-05 18:54:56 +00:00
|
|
|
} sql_manager;
|
|
|
|
|
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-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 {
|
|
|
|
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
|
2009-11-14 21:59:01 +00:00
|
|
|
|
|
|
|
static void sql_close(time_t prune)
|
|
|
|
{
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
|
|
|
int locked = 0;
|
|
|
|
char *key;
|
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
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
|
2009-11-14 21:59:01 +00:00
|
|
|
switch_hash_this(hi, &var, NULL, &val);
|
|
|
|
key = (char *) var;
|
2010-05-27 01:13:46 +00:00
|
|
|
|
2009-11-14 21:59:01 +00:00
|
|
|
if ((dbh = (switch_cache_db_handle_t *) val)) {
|
|
|
|
time_t diff = 0;
|
2010-05-27 01:13:46 +00:00
|
|
|
|
2009-11-14 21:59:01 +00:00
|
|
|
if (prune > 0 && prune > dbh->last_used) {
|
|
|
|
diff = (time_t) prune - dbh->last_used;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-06-29 20:40:55 +00:00
|
|
|
if (prune > 0 && diff < SQL_CACHE_TIMEOUT && !switch_test_flag(dbh, CDF_PRUNE)) {
|
2009-11-14 21:59:01 +00:00
|
|
|
continue;
|
|
|
|
}
|
2010-05-27 01:13:46 +00:00
|
|
|
|
2009-11-14 21:59:01 +00:00
|
|
|
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
2009-12-15 01:31:17 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", key);
|
2010-05-27 01:13:46 +00:00
|
|
|
|
2009-11-21 17:57:55 +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);
|
2010-02-06 03:38:24 +00:00
|
|
|
dbh->native_handle.core_db_dbh = NULL;
|
2009-11-21 17:57:55 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-11-14 21:59:01 +00:00
|
|
|
}
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_core_hash_delete(sql_manager.dbh_hash, key);
|
2009-11-14 21:59:01 +00:00
|
|
|
switch_mutex_unlock(dbh->mutex);
|
|
|
|
switch_core_destroy_memory_pool(&dbh->pool);
|
|
|
|
goto top;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-14 21:59:01 +00:00
|
|
|
} else {
|
2010-02-06 03:38:24 +00:00
|
|
|
if (!prune)
|
|
|
|
locked++;
|
2009-11-14 21:59:01 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
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) {
|
2010-06-30 14:05:14 +00:00
|
|
|
|
|
|
|
switch ((*dbh)->type) {
|
|
|
|
case SCDB_TYPE_ODBC:
|
|
|
|
{
|
|
|
|
switch_clear_flag((*dbh), CDF_INUSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2010-06-30 15:35:03 +00:00
|
|
|
|
2009-11-14 21:59:01 +00:00
|
|
|
switch_mutex_unlock((*dbh)->mutex);
|
|
|
|
*dbh = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
|
|
|
if (dbh && *dbh) {
|
|
|
|
|
|
|
|
if ((*dbh)->type == SCDB_TYPE_CORE_DB) {
|
|
|
|
switch_set_flag((*dbh), CDF_PRUNE);
|
|
|
|
} else {
|
|
|
|
switch_clear_flag((*dbh), CDF_INUSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_mutex_unlock((*dbh)->mutex);
|
|
|
|
*dbh = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-30 15:35:03 +00:00
|
|
|
SWITCH_DECLARE(void) switch_cache_db_destroy_db_handle(switch_cache_db_handle_t **dbh)
|
2009-11-17 19:16:24 +00:00
|
|
|
{
|
|
|
|
if (dbh && *dbh) {
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_mutex_lock(sql_manager.dbh_mutex);
|
2009-12-15 01:31:17 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Deleting DB connection %s\n", (*dbh)->name);
|
2009-11-21 17:57:55 +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);
|
2010-02-06 03:38:24 +00:00
|
|
|
(*dbh)->native_handle.core_db_dbh = NULL;
|
2009-11-21 17:57:55 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-11-17 19:16:24 +00:00
|
|
|
}
|
2009-11-21 17:57:55 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
switch_core_hash_delete(sql_manager.dbh_hash, (*dbh)->name);
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_mutex_unlock((*dbh)->mutex);
|
|
|
|
switch_core_destroy_memory_pool(&(*dbh)->pool);
|
|
|
|
*dbh = NULL;
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_mutex_unlock(sql_manager.dbh_mutex);
|
2009-11-17 19:16:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SWITCH_DECLARE(void) switch_cache_db_detach(void)
|
|
|
|
{
|
|
|
|
char thread_str[CACHE_DB_LEN] = "";
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
|
|
|
char *key;
|
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
2010-06-30 21:24:55 +00:00
|
|
|
int prune = 0;
|
2009-11-17 19:16:24 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
snprintf(thread_str, sizeof(thread_str) - 1, "%lu", (unsigned long) (intptr_t) switch_thread_self());
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_mutex_lock(sql_manager.dbh_mutex);
|
2009-11-17 19:16:24 +00:00
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_hash_this(hi, &var, NULL, &val);
|
|
|
|
key = (char *) var;
|
|
|
|
if ((dbh = (switch_cache_db_handle_t *) val)) {
|
|
|
|
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
if (strstr(dbh->name, thread_str)) {
|
2010-06-29 20:40:55 +00:00
|
|
|
if (dbh->type == SCDB_TYPE_CORE_DB) {
|
|
|
|
switch_set_flag(dbh, CDF_PRUNE);
|
2010-06-30 21:24:55 +00:00
|
|
|
prune++;
|
2010-06-29 20:40:55 +00:00
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,
|
|
|
|
"Detach cached DB handle %s [%s]\n", thread_str, switch_cache_db_type_name(dbh->type));
|
|
|
|
switch_clear_flag(dbh, CDF_INUSE);
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_mutex_unlock(dbh->mutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_mutex_unlock(sql_manager.dbh_mutex);
|
2010-06-30 21:24:55 +00:00
|
|
|
|
|
|
|
if (prune) {
|
|
|
|
sql_close(switch_epoch_time_now(NULL));
|
|
|
|
}
|
|
|
|
|
2009-11-17 19:16:24 +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
|
|
|
{
|
|
|
|
switch_thread_id_t self = switch_thread_self();
|
2009-11-17 19:16:24 +00:00
|
|
|
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;
|
2009-11-23 18:25:11 +00:00
|
|
|
switch_ssize_t hlen = -1;
|
|
|
|
|
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
|
|
|
|
|
|
|
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
|
|
|
|
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);
|
2010-02-06 03:38:24 +00:00
|
|
|
snprintf(thread_str, sizeof(thread_str) - 1, "%s;thread=\"%lu\"", db_str, (unsigned long) (intptr_t) self);
|
2009-11-27 16:47:08 +00:00
|
|
|
snprintf(db_callsite_str, sizeof(db_callsite_str) - 1, "%s:%d", file, line);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_mutex_lock(sql_manager.dbh_mutex);
|
|
|
|
if ((new_dbh = switch_core_hash_find(sql_manager.dbh_hash, thread_str))) {
|
2009-11-27 16:47:08 +00:00
|
|
|
switch_set_string(new_dbh->last_user, db_callsite_str);
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
2009-11-21 17:57:55 +00:00
|
|
|
"Reuse Cached DB handle %s [%s]\n", thread_str, switch_cache_db_type_name(new_dbh->type));
|
2009-11-20 23:12:07 +00:00
|
|
|
} else {
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
|
|
|
char *key;
|
2009-11-23 18:25:11 +00:00
|
|
|
unsigned long hash = 0;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-23 18:25:11 +00:00
|
|
|
hash = switch_ci_hashfunc_default(db_str, &hlen);
|
2009-11-17 19:16:24 +00:00
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_hash_this(hi, &var, NULL, &val);
|
|
|
|
key = (char *) var;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-17 19:16:24 +00:00
|
|
|
if ((new_dbh = (switch_cache_db_handle_t *) val)) {
|
2010-02-06 03:38:24 +00:00
|
|
|
if (hash == new_dbh->hash && !strncasecmp(new_dbh->name, db_str, strlen(db_str)) &&
|
2010-06-30 15:35:03 +00:00
|
|
|
!switch_test_flag(new_dbh, CDF_INUSE) && !switch_test_flag(new_dbh, CDF_PRUNE)
|
2010-06-29 20:40:55 +00:00
|
|
|
&& switch_mutex_trylock(new_dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_set_flag(new_dbh, CDF_INUSE);
|
|
|
|
switch_set_string(new_dbh->name, thread_str);
|
2009-11-23 18:25:11 +00:00
|
|
|
new_dbh->hash = switch_ci_hashfunc_default(db_str, &hlen);
|
2009-11-27 16:47:08 +00:00
|
|
|
switch_set_string(new_dbh->last_user, db_callsite_str);
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
2009-11-21 17:57:55 +00:00
|
|
|
"Reuse Unused Cached DB handle %s [%s]\n", thread_str, switch_cache_db_type_name(new_dbh->type));
|
2009-11-17 19:16:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new_dbh = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!new_dbh) {
|
2009-11-14 21:59:01 +00:00
|
|
|
switch_memory_pool_t *pool = NULL;
|
|
|
|
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,
|
2009-11-23 18:25:11 +00:00
|
|
|
"Create Cached DB handle %s [%s]\n", thread_str, switch_cache_db_type_name(type));
|
2009-11-20 23:12:07 +00:00
|
|
|
|
2009-11-14 21:59:01 +00:00
|
|
|
switch_core_new_memory_pool(&pool);
|
2009-11-17 00:12:54 +00:00
|
|
|
new_dbh = switch_core_alloc(pool, sizeof(*new_dbh));
|
|
|
|
new_dbh->pool = pool;
|
2009-11-21 17:57:55 +00:00
|
|
|
new_dbh->type = type;
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_set_string(new_dbh->name, thread_str);
|
|
|
|
switch_set_flag(new_dbh, CDF_INUSE);
|
2009-11-23 18:25:11 +00:00
|
|
|
new_dbh->hash = switch_ci_hashfunc_default(db_str, &hlen);
|
|
|
|
|
2009-11-27 16:47:08 +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
|
|
|
}
|
|
|
|
|
2009-11-17 19:16:24 +00:00
|
|
|
switch_mutex_init(&new_dbh->mutex, SWITCH_MUTEX_UNNESTED, new_dbh->pool);
|
2009-11-27 16:47:08 +00:00
|
|
|
switch_set_string(new_dbh->creator, db_callsite_str);
|
2009-11-17 00:12:54 +00:00
|
|
|
switch_mutex_lock(new_dbh->mutex);
|
2009-11-14 21:59:01 +00:00
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_core_hash_insert(sql_manager.dbh_hash, new_dbh->name, new_dbh);
|
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
|
|
|
}
|
2009-11-14 21:59:01 +00:00
|
|
|
|
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 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;
|
2009-11-17 00:12:54 +00:00
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_lock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (err)
|
|
|
|
*err = NULL;
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_unlock(dbh->io_mutex);
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-20 23:12:07 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
OMFG you cruel bastards. Who chooses 64k 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;
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_lock(dbh->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
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_unlock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
2009-11-14 21:59:01 +00:00
|
|
|
return status;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_lock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
return NULL;
|
|
|
|
} 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
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_unlock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (!retries) {
|
|
|
|
forever = 1;
|
|
|
|
retries = 1000;
|
|
|
|
}
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_lock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
2009-11-17 00:12:54 +00:00
|
|
|
while (retries > 0) {
|
2009-11-21 17:57:55 +00:00
|
|
|
switch_cache_db_execute_sql_real(dbh, sql, &errmsg);
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_unlock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
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;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2007-03-29 22:34:40 +00:00
|
|
|
if (!retries) {
|
|
|
|
forever = 1;
|
|
|
|
retries = 1000;
|
|
|
|
}
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_lock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
2010-06-25 18:19:53 +00:00
|
|
|
again:
|
2007-03-29 22:34:40 +00:00
|
|
|
|
|
|
|
while (begin_retries > 0) {
|
|
|
|
again = 0;
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg);
|
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) {
|
2009-11-21 17:57:55 +00:00
|
|
|
switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
|
2007-03-29 22:34:40 +00:00
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_yield(100000);
|
|
|
|
|
|
|
|
if (begin_retries == 0) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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-02-06 03:38:24 +00:00
|
|
|
switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
|
2007-03-29 22:34:40 +00:00
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_unlock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
2007-03-29 22:34:40 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (err)
|
|
|
|
*err = NULL;
|
2007-03-29 22:34:40 +00:00
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_lock(dbh->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);
|
2009-11-21 17:57:55 +00:00
|
|
|
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
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_unlock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
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;
|
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;
|
|
|
|
}
|
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_lock(dbh->io_mutex);
|
|
|
|
}
|
|
|
|
|
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]\nAuto 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
|
|
|
|
|
|
|
|
|
|
|
if (dbh->io_mutex) {
|
|
|
|
switch_mutex_unlock(dbh->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-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-14 21:19:03 +00:00
|
|
|
void *pop;
|
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-09-07 15:51:02 +00:00
|
|
|
char *sql = NULL;
|
2007-03-29 22:34:40 +00:00
|
|
|
switch_size_t newlen;
|
2008-02-11 16:49:07 +00:00
|
|
|
int lc = 0;
|
2009-11-14 21:59:01 +00:00
|
|
|
uint32_t loops = 0, sec = 0;
|
2009-11-17 00:12:54 +00:00
|
|
|
uint32_t l1 = 1000;
|
2010-04-22 18:28:44 +00:00
|
|
|
uint32_t sanity = 120;
|
2009-11-14 21:59:01 +00:00
|
|
|
|
2007-12-11 20:50:52 +00:00
|
|
|
switch_assert(sqlbuf);
|
|
|
|
|
2009-11-17 00:12:54 +00:00
|
|
|
if (!sql_manager.manage) {
|
|
|
|
l1 = 10;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2010-04-22 18:28:44 +00:00
|
|
|
|
2007-05-10 16:56:29 +00:00
|
|
|
sql_manager.thread_running = 1;
|
2007-03-29 22:34:40 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
while (sql_manager.thread_running == 1) {
|
2010-09-14 21:19:03 +00:00
|
|
|
|
|
|
|
switch_mutex_lock(sql_manager.cond_mutex);
|
|
|
|
|
2009-11-17 00:12:54 +00:00
|
|
|
if (++loops == l1) {
|
2009-11-14 21:59:01 +00:00
|
|
|
if (++sec == SQL_CACHE_TIMEOUT) {
|
|
|
|
sql_close(switch_epoch_time_now(NULL));
|
|
|
|
sec = 0;
|
|
|
|
}
|
|
|
|
loops = 0;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-17 00:12:54 +00:00
|
|
|
if (!sql_manager.manage) {
|
|
|
|
switch_yield(100000);
|
|
|
|
continue;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-09-14 21:19:03 +00:00
|
|
|
if (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-09-14 21:19:03 +00:00
|
|
|
if (!sql) sql = (char *) pop;
|
|
|
|
|
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;
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,
|
|
|
|
"REALLOC %ld %d %d\n", sql_len, switch_queue_size(sql_manager.sql_queue[0]),
|
|
|
|
switch_queue_size(sql_manager.sql_queue[1]));
|
|
|
|
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-14 21:19:03 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,
|
|
|
|
"SAVE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]));
|
|
|
|
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-09-14 21:19:03 +00:00
|
|
|
skip:
|
|
|
|
|
|
|
|
lc = sql ? 1 : 0 + switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]);
|
|
|
|
|
2010-09-14 21:22:21 +00:00
|
|
|
if (trans && iterations && (iterations > target || !lc)) {
|
2010-09-14 21:19:03 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,
|
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);
|
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-14 21:19:03 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "DONE\n");
|
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-09-14 21:19:03 +00:00
|
|
|
switch_yield(400000);
|
2008-02-11 16:49:07 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-09-14 21:19:03 +00:00
|
|
|
if (!lc) {
|
|
|
|
switch_thread_cond_wait(sql_manager.cond, sql_manager.cond_mutex);
|
2007-03-29 22:34:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_variable("hostname")
|
|
|
|
);
|
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'",
|
|
|
|
switch_event_get_header_nil(event, "task-id"), switch_core_get_variable("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,
|
|
|
|
switch_core_get_variable("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");
|
|
|
|
const char *sig = switch_event_get_header(event, "signal_bridge");
|
|
|
|
|
|
|
|
if (uuid) {
|
|
|
|
new_sql() = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'",
|
|
|
|
uuid, switch_core_get_variable("hostname"));
|
|
|
|
if (switch_true(sig)) {
|
2010-08-20 19:17:59 +00:00
|
|
|
new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' || callee_uuid='%q') and hostname='%q'",
|
|
|
|
uuid, uuid, switch_core_get_variable("hostname"));
|
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"),
|
|
|
|
switch_core_get_variable("hostname"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"),
|
|
|
|
switch_event_get_header_nil(event, "old-unique-id"),
|
|
|
|
switch_core_get_variable("hostname"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"),
|
|
|
|
switch_event_get_header_nil(event, "old-unique-id"), switch_core_get_variable("hostname")
|
|
|
|
);
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "caller-context"), switch_core_get_variable("hostname")
|
|
|
|
);
|
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
|
2009-11-17 00:12:54 +00:00
|
|
|
("update channels set read_codec='%q',read_rate='%q',write_codec='%q',write_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-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"),
|
2009-11-17 00:12:54 +00:00
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("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"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")
|
|
|
|
);
|
|
|
|
|
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,
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
|
|
|
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
|
|
|
|
}
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("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"),
|
2010-06-30 15:35:03 +00:00
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
|
|
|
|
|
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,
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
|
|
|
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
|
|
|
|
}
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("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;
|
|
|
|
|
|
|
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname"));
|
|
|
|
new_sql() = switch_mprintf("insert into calls (call_uuid,call_created,call_created_epoch,function,caller_cid_name,"
|
|
|
|
"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')",
|
|
|
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "Other-Leg-unique-id"), switch_core_get_variable("hostname")
|
|
|
|
);
|
|
|
|
}
|
2007-03-29 22:34:40 +00:00
|
|
|
break;
|
|
|
|
case SWITCH_EVENT_CHANNEL_UNBRIDGE:
|
2010-06-25 18:19:53 +00:00
|
|
|
new_sql() = switch_mprintf("delete from calls where caller_uuid='%s' and hostname='%q'",
|
|
|
|
switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname"));
|
2007-03-29 22:34:40 +00:00
|
|
|
break;
|
|
|
|
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'",
|
|
|
|
switch_core_get_variable("hostname"), switch_core_get_variable("hostname"), switch_core_get_variable("hostname")
|
|
|
|
);
|
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),
|
|
|
|
switch_core_get_variable("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,
|
|
|
|
switch_core_get_variable("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'",
|
|
|
|
type, switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname")
|
|
|
|
);
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_variable("hostname")
|
|
|
|
);
|
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"),
|
|
|
|
switch_event_get_header_nil(event, "proto"), switch_core_get_variable("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-09-14 21:19:03 +00:00
|
|
|
switch_thread_cond_broadcast(sql_manager.cond);
|
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"
|
|
|
|
" write_codec VARCHAR(128),\n"
|
|
|
|
" write_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
|
|
|
|
|
|
|
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;
|
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
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_core_hash_init(&sql_manager.dbh_hash, sql_manager.memory_pool);
|
2009-11-14 21:59:01 +00:00
|
|
|
|
2010-06-25 18:19:53 +00:00
|
|
|
top:
|
2010-02-06 03:38:24 +00:00
|
|
|
|
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;
|
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;
|
|
|
|
const char *hostname = switch_core_get_variable("hostname");
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
2009-11-21 17:57:55 +00:00
|
|
|
switch (dbh->type) {
|
|
|
|
case SCDB_TYPE_ODBC:
|
|
|
|
{
|
|
|
|
char *err;
|
2010-06-25 18:19:53 +00:00
|
|
|
switch_cache_db_test_reactive(dbh, "select call_uuid from channels", "DROP TABLE channels", create_channels_sql);
|
|
|
|
switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql);
|
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
|
|
|
|
2009-11-21 17:57:55 +00:00
|
|
|
switch_cache_db_execute_sql(dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &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);
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
2009-10-20 18:44:29 +00:00
|
|
|
switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool);
|
2008-12-17 20:43:13 +00:00
|
|
|
|
2007-05-10 16:56:29 +00:00
|
|
|
while (!sql_manager.thread_running) {
|
2007-03-30 17:25:48 +00:00
|
|
|
switch_yield(10000);
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-17 00:12:54 +00:00
|
|
|
switch_cache_db_release_db_handle(&dbh);
|
|
|
|
|
|
|
|
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);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
sql_manager.thread_running = -1;
|
|
|
|
switch_thread_join(&st, sql_manager.thread);
|
|
|
|
}
|
2007-03-29 22:34:40 +00:00
|
|
|
|
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
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
switch_core_hash_destroy(&sql_manager.dbh_hash);
|
2009-11-14 21:59:01 +00:00
|
|
|
|
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_hash_index_t *hi;
|
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
|
|
|
void *val;
|
|
|
|
const void *var;
|
|
|
|
char *key;
|
|
|
|
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;
|
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
|
|
|
|
2009-12-05 18:54:56 +00:00
|
|
|
for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
|
2009-11-27 16:47:08 +00:00
|
|
|
switch_hash_this(hi, &var, NULL, &val);
|
|
|
|
key = (char *) var;
|
|
|
|
|
|
|
|
if ((dbh = (switch_cache_db_handle_t *) val)) {
|
2009-11-27 19:48:30 +00:00
|
|
|
char *needle = "pass=\"";
|
2009-11-27 16:47:08 +00:00
|
|
|
time_t diff = 0;
|
|
|
|
|
|
|
|
diff = now - dbh->last_used;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-27 16:47:08 +00:00
|
|
|
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_mutex_unlock(dbh->mutex);
|
|
|
|
locked = SWITCH_FALSE;
|
|
|
|
} else {
|
|
|
|
locked = SWITCH_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sanitize password */
|
|
|
|
memset(cleankey_str, 0, sizeof(cleankey_str));
|
|
|
|
pos1 = strstr(key, needle) + strlen(needle);
|
|
|
|
pos2 = strstr(pos1, "\"");
|
2010-02-06 03:38:24 +00:00
|
|
|
strncpy(cleankey_str, key, pos1 - key);
|
|
|
|
strcpy(&cleankey_str[pos1 - key], pos2);
|
|
|
|
|
|
|
|
|
2009-11-27 16:47:08 +00:00
|
|
|
stream->write_function(stream, "%s\n\tType: %s\n\tLast used: %d\n\tFlags: %s, %s\n"
|
2010-02-06 03:38:24 +00:00
|
|
|
"\tCreator: %s\n\tLast User: %s\n",
|
|
|
|
cleankey_str,
|
|
|
|
switch_cache_db_type_name(dbh->type),
|
|
|
|
diff,
|
|
|
|
locked ? "Locked" : "Unlocked",
|
|
|
|
switch_test_flag(dbh, CDF_INUSE) ? "Attached" : "Detached", dbh->creator, dbh->last_user);
|
2009-11-27 16:47:08 +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
|
|
|
*/
|