switch_core_sqldb.c File Reference

#include <switch.h>
#include "private/switch_core_pvt.h"

Include dependency graph for switch_core_sqldb.c:

Go to the source code of this file.

Data Structures

struct  switch_cache_db_handle

Defines

#define SWITCH_SQL_QUEUE_LEN   100000
#define SWITCH_SQL_QUEUE_PAUSE_LEN   90000
#define SWITCH_CORE_DB   "core"
#define SQL_CACHE_TIMEOUT   30
#define SQL_REG_TIMEOUT   15
#define MAX_SQL   5
#define new_sql()   switch_assert(sql_idx+1 < MAX_SQL); sql[sql_idx++]

Functions

static switch_cache_db_handle_tcreate_handle (switch_cache_db_handle_type_t type)
static void add_handle (switch_cache_db_handle_t *dbh, const char *db_str, const char *db_callsite_str, const char *thread_str)
static void del_handle (switch_cache_db_handle_t *dbh)
static switch_cache_db_handle_tget_handle (const char *db_str, const char *user_str, const char *thread_str)
switch_status_t _switch_core_db_handle (switch_cache_db_handle_t **dbh, const char *file, const char *func, int line)
 Open the default system database.
static void sql_close (time_t prune)
switch_cache_db_handle_type_t switch_cache_db_get_type (switch_cache_db_handle_t *dbh)
void switch_cache_db_flush_handles (void)
void switch_cache_db_release_db_handle (switch_cache_db_handle_t **dbh)
 Returns the handle to the pool, handle is NOT available to other threads until the allocating thread actually terminates.
void switch_cache_db_dismiss_db_handle (switch_cache_db_handle_t **dbh)
 Returns the handle to the pool, immediately available for other threads to use.
switch_status_t _switch_cache_db_get_db_handle (switch_cache_db_handle_t **dbh, switch_cache_db_handle_type_t type, switch_cache_db_connection_options_t *connection_options, const char *file, const char *func, int line)
 Gets a new cached handle from the pool, potentially creating a new connection. The connection is bound to the thread until it (the thread) terminates unless you dismiss rather than release.
static switch_status_t switch_cache_db_execute_sql_real (switch_cache_db_handle_t *dbh, const char *sql, char **err)
static void wake_thread (int force)
static switch_status_t switch_cache_db_execute_sql_chunked (switch_cache_db_handle_t *dbh, char *sql, uint32_t chunk_size, char **err)
switch_status_t switch_cache_db_execute_sql (switch_cache_db_handle_t *dbh, char *sql, char **err)
 Executes the sql.
int switch_cache_db_affected_rows (switch_cache_db_handle_t *dbh)
 Get the affected rows of the last performed query.
char * switch_cache_db_execute_sql2str (switch_cache_db_handle_t *dbh, char *sql, char *str, size_t len, char **err)
 Executes the sql and returns the result as a string.
switch_status_t switch_cache_db_persistant_execute (switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries)
switch_status_t switch_cache_db_persistant_execute_trans (switch_cache_db_handle_t *dbh, char *sql, uint32_t retries)
switch_status_t switch_cache_db_execute_sql_callback (switch_cache_db_handle_t *dbh, const char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err)
 Executes the sql and uses callback for row-by-row processing.
switch_bool_t switch_cache_db_test_reactive (switch_cache_db_handle_t *dbh, const char *test_sql, const char *drop_sql, const char *reactive_sql)
static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread (switch_thread_t *thread, void *obj)
static void *SWITCH_THREAD_FUNC switch_core_sql_thread (switch_thread_t *thread, void *obj)
static char * parse_presence_data_cols (switch_event_t *event)
static void core_event_handler (switch_event_t *event)
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)
 Add user registration.
switch_status_t switch_core_del_registration (const char *user, const char *realm, const char *token)
 Delete user registration.
switch_status_t switch_core_expire_registration (int force)
 Expire user registrations.
switch_status_t switch_core_sqldb_start (switch_memory_pool_t *pool, switch_bool_t manage)
void switch_core_sqldb_stop (void)
void switch_cache_db_status (switch_stream_handle_t *stream)
 Provides some feedback as to the status of the db connection pool.
char * switch_sql_concat (void)

Variables

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
   switch_thread_t *   db_thread
   int   thread_running
   int   db_thread_running
   switch_bool_t   manage
   switch_mutex_t *   io_mutex
   switch_mutex_t *   dbh_mutex
   switch_cache_db_handle_t *   handle_pool
   switch_thread_cond_t *   cond
   switch_mutex_t *   cond_mutex
   uint32_t   total_handles
   uint32_t   total_used_handles
sql_manager
static char create_complete_sql []
static char create_alias_sql []
static char create_channels_sql []
static char create_calls_sql []
static char create_interfaces_sql []
static char create_tasks_sql []
static char create_nat_sql []
static char create_registrations_sql []
static char detailed_calls_sql []
static char basic_calls_sql []


Define Documentation

#define MAX_SQL   5

Definition at line 1218 of file switch_core_sqldb.c.

Referenced by core_event_handler().

 
#define new_sql (  )     switch_assert(sql_idx+1 < MAX_SQL); sql[sql_idx++]

Definition at line 1219 of file switch_core_sqldb.c.

Referenced by core_event_handler().

#define SQL_CACHE_TIMEOUT   30

Definition at line 221 of file switch_core_sqldb.c.

Referenced by sql_close(), switch_cache_db_execute_sql_callback(), switch_cache_db_flush_handles(), and switch_core_sql_db_thread().

#define SQL_REG_TIMEOUT   15

Definition at line 222 of file switch_core_sqldb.c.

Referenced by switch_core_sql_db_thread().

#define SWITCH_CORE_DB   "core"

Definition at line 178 of file switch_core_sqldb.c.

Referenced by _switch_core_db_handle().

#define SWITCH_SQL_QUEUE_LEN   100000

Definition at line 38 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

#define SWITCH_SQL_QUEUE_PAUSE_LEN   90000

Definition at line 39 of file switch_core_sqldb.c.

Referenced by switch_core_sql_thread().


Function Documentation

switch_status_t _switch_cache_db_get_db_handle ( switch_cache_db_handle_t **  dbh,
switch_cache_db_handle_type_t  type,
switch_cache_db_connection_options_t connection_options,
const char *  file,
const char *  func,
int  line 
)

Gets a new cached handle from the pool, potentially creating a new connection. The connection is bound to the thread until it (the thread) terminates unless you dismiss rather than release.

Parameters:
[out] dbh The handle
[in] type - ODBC or SQLLITE
[in] connection_options (userid, password, etc)

Definition at line 322 of file switch_core_sqldb.c.

References add_handle(), CACHE_DB_LEN, switch_cache_db_native_handle_t::core_db_dbh, create_handle(), switch_runtime::db_handle_timeout, get_handle(), switch_cache_db_handle::last_used, switch_runtime::max_db_handles, switch_cache_db_handle::name, switch_cache_db_handle::native_handle, switch_cache_db_native_handle_t::odbc_dbh, runtime, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, sql_manager, switch_cache_db_type_name(), SWITCH_CHANNEL_ID_LOG, SWITCH_CHANNEL_LOG, switch_core_db_open_file(), switch_epoch_time_now(), SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG10, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, switch_odbc_available(), switch_odbc_handle_connect(), switch_odbc_handle_destroy(), switch_odbc_handle_new(), SWITCH_ODBC_SUCCESS, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_self(), switch_yield, and switch_cache_db_handle::type.

Referenced by _switch_core_db_handle().

00326 {
00327         switch_thread_id_t self = switch_thread_self();
00328         char thread_str[CACHE_DB_LEN] = "";
00329         char db_str[CACHE_DB_LEN] = "";
00330         char db_callsite_str[CACHE_DB_LEN] = "";
00331         switch_cache_db_handle_t *new_dbh = NULL;
00332         int waiting = 0;
00333         uint32_t yield_len = 100000, total_yield = 0;
00334 
00335         const char *db_name = NULL;
00336         const char *db_user = NULL;
00337         const char *db_pass = NULL;
00338 
00339         while(runtime.max_db_handles && sql_manager.total_handles >= runtime.max_db_handles && sql_manager.total_used_handles >= sql_manager.total_handles) {
00340                 if (!waiting++) {
00341                         switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_WARNING, "Max handles %u exceeded, blocking....\n", 
00342                                                           runtime.max_db_handles);
00343                 }
00344 
00345                 switch_yield(yield_len);
00346                 total_yield += yield_len;
00347                 
00348                 if (runtime.db_handle_timeout && total_yield > runtime.db_handle_timeout) {
00349                         switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error connecting\n");
00350                         *dbh = NULL;
00351                         return SWITCH_STATUS_FALSE;
00352                 }
00353         }
00354 
00355         switch (type) {
00356         case SCDB_TYPE_ODBC:
00357                 {
00358                         db_name = connection_options->odbc_options.dsn;
00359                         db_user = connection_options->odbc_options.user;
00360                         db_pass = connection_options->odbc_options.pass;
00361                 }
00362                 break;
00363         case SCDB_TYPE_CORE_DB:
00364                 {
00365                         db_name = connection_options->core_db_options.db_path;
00366                         db_user = "";
00367                         db_pass = "";
00368                 }
00369                 break;
00370         }
00371 
00372         if (!db_name) {
00373                 return SWITCH_STATUS_FALSE;
00374         }
00375 
00376 
00377         snprintf(db_str, sizeof(db_str) - 1, "db=\"%s\";user=\"%s\";pass=\"%s\"", db_name, db_user, db_pass);
00378         snprintf(db_callsite_str, sizeof(db_callsite_str) - 1, "%s:%d", file, line);
00379         snprintf(thread_str, sizeof(thread_str) - 1, "thread=\"%lu\"",  (unsigned long) (intptr_t) self); 
00380 
00381         if ((new_dbh = get_handle(db_str, db_callsite_str, thread_str))) {
00382                 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
00383                                                   "Reuse Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type));
00384         } else {
00385                 switch_core_db_t *db = NULL;
00386                 switch_odbc_handle_t *odbc_dbh = NULL;
00387 
00388                 switch (type) {
00389                 case SCDB_TYPE_ODBC:
00390                         {
00391 
00392                                 if (!switch_odbc_available()) {
00393                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC NOT AVAILABLE! Can't connect to DSN %s\n", connection_options->odbc_options.dsn);
00394                                         goto end;
00395                                 }
00396 
00397                                 if ((odbc_dbh = switch_odbc_handle_new(connection_options->odbc_options.dsn,
00398                                                                                                            connection_options->odbc_options.user, connection_options->odbc_options.pass))) {
00399                                         if (switch_odbc_handle_connect(odbc_dbh) != SWITCH_ODBC_SUCCESS) {
00400                                                 switch_odbc_handle_destroy(&odbc_dbh);
00401                                         }
00402                                 }
00403 
00404 
00405                         }
00406                         break;
00407                 case SCDB_TYPE_CORE_DB:
00408                         {
00409                                 db = switch_core_db_open_file(connection_options->core_db_options.db_path);
00410                         }
00411                         break;
00412 
00413                 default:
00414                         goto end;
00415                 }
00416 
00417                 if (!db && !odbc_dbh) {
00418                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure to connect to %s %s!\n", db?"SQLITE":"ODBC", db?connection_options->core_db_options.db_path:connection_options->odbc_options.dsn);
00419                         goto end;
00420                 }
00421 
00422                 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
00423                                                   "Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line);
00424 
00425                 new_dbh = create_handle(type);
00426 
00427                 if (db) {
00428                         new_dbh->native_handle.core_db_dbh = db;
00429                 } else {
00430                         new_dbh->native_handle.odbc_dbh = odbc_dbh;
00431                 }
00432 
00433                 add_handle(new_dbh, db_str, db_callsite_str, thread_str);
00434         }
00435 
00436  end:
00437 
00438         if (new_dbh) {
00439                 new_dbh->last_used = switch_epoch_time_now(NULL);
00440         }
00441         
00442         *dbh = new_dbh;
00443 
00444         return *dbh ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
00445 }

switch_status_t _switch_core_db_handle ( switch_cache_db_handle_t **  dbh,
const char *  file,
const char *  func,
int  line 
)

Open the default system database.

Definition at line 182 of file switch_core_sqldb.c.

References _switch_cache_db_get_db_handle(), switch_cache_db_connection_options_t::core_db_options, switch_cache_db_core_db_options_t::db_path, switch_runtime::dbname, switch_cache_db_odbc_options_t::dsn, switch_runtime::odbc_dsn, switch_cache_db_connection_options_t::odbc_options, switch_runtime::odbc_pass, switch_runtime::odbc_user, switch_cache_db_odbc_options_t::pass, runtime, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SCF_CORE_ODBC_REQ, sql_manager, SWITCH_CORE_DB, SWITCH_STATUS_FALSE, switch_test_flag, switch_cache_db_odbc_options_t::user, and zstr.

00183 {
00184         switch_cache_db_connection_options_t options = { {0} };
00185         switch_status_t r;
00186         
00187         if (!sql_manager.manage) {
00188                 return SWITCH_STATUS_FALSE;
00189         }
00190 
00191         if (zstr(runtime.odbc_dsn)) {
00192                 if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) {
00193                         return SWITCH_STATUS_FALSE;
00194                 }
00195 
00196                 if (runtime.dbname) {
00197                         options.core_db_options.db_path = runtime.dbname;
00198                 } else {
00199                         options.core_db_options.db_path = SWITCH_CORE_DB;
00200                 }
00201                 r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line);
00202                 
00203         } else {
00204                 options.odbc_options.dsn = runtime.odbc_dsn;
00205                 options.odbc_options.user = runtime.odbc_user;
00206                 options.odbc_options.pass = runtime.odbc_pass;
00207 
00208                 r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line);
00209         }
00210 
00211         /* I *think* we can do without this now, if not let me know 
00212         if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) {
00213                 (*dbh)->io_mutex = sql_manager.io_mutex;
00214         }
00215         */
00216 
00217         return r;
00218 }

static void add_handle ( switch_cache_db_handle_t dbh,
const char *  db_str,
const char *  db_callsite_str,
const char *  thread_str 
) [static]

Definition at line 92 of file switch_core_sqldb.c.

References switch_cache_db_handle::creator, switch_cache_db_handle::hash, switch_cache_db_handle::mutex, switch_cache_db_handle::name, switch_cache_db_handle::next, sql_manager, switch_ci_hashfunc_default(), switch_mutex_lock(), switch_mutex_unlock(), switch_set_string, switch_cache_db_handle::thread_hash, and switch_cache_db_handle::use_count.

Referenced by _switch_cache_db_get_db_handle().

00093 {
00094         switch_ssize_t hlen = -1;
00095 
00096         switch_mutex_lock(sql_manager.dbh_mutex);
00097 
00098         switch_set_string(dbh->creator, db_callsite_str);
00099 
00100         switch_set_string(dbh->name, db_str);
00101         dbh->hash = switch_ci_hashfunc_default(db_str, &hlen);
00102         dbh->thread_hash = switch_ci_hashfunc_default(thread_str, &hlen);
00103 
00104         dbh->use_count++;
00105         sql_manager.total_used_handles++;
00106         dbh->next = sql_manager.handle_pool;
00107 
00108         sql_manager.handle_pool = dbh;
00109         sql_manager.total_handles++;
00110         switch_mutex_lock(dbh->mutex);
00111         switch_mutex_unlock(sql_manager.dbh_mutex);
00112 }

static void core_event_handler ( switch_event_t event  )  [static]

Definition at line 1221 of file switch_core_sqldb.c.

References CCS_DOWN, CCS_HANGUP, CS_DESTROY, CS_HANGUP, CS_NEW, CS_REPORTING, CS_ROUTING, switch_event::event_id, filename, MAX_SQL, new_sql, parse_presence_data_cols(), sql_manager, switch_assert, SWITCH_CHANNEL_LOG, switch_core_get_switchname(), switch_epoch_time_now(), SWITCH_EVENT_ADD_SCHEDULE, SWITCH_EVENT_CALL_SECURE, SWITCH_EVENT_CALL_UPDATE, SWITCH_EVENT_CHANNEL_BRIDGE, SWITCH_EVENT_CHANNEL_CALLSTATE, SWITCH_EVENT_CHANNEL_CREATE, SWITCH_EVENT_CHANNEL_DESTROY, SWITCH_EVENT_CHANNEL_EXECUTE, SWITCH_EVENT_CHANNEL_HOLD, SWITCH_EVENT_CHANNEL_ORIGINATE, SWITCH_EVENT_CHANNEL_STATE, SWITCH_EVENT_CHANNEL_UNBRIDGE, SWITCH_EVENT_CHANNEL_UNHOLD, SWITCH_EVENT_CHANNEL_UUID, SWITCH_EVENT_CODEC, SWITCH_EVENT_DEL_SCHEDULE, SWITCH_EVENT_EXE_SCHEDULE, switch_event_get_header, switch_event_get_header_nil, SWITCH_EVENT_LOG, SWITCH_EVENT_MODULE_LOAD, SWITCH_EVENT_MODULE_UNLOAD, SWITCH_EVENT_NAT, SWITCH_EVENT_RE_SCHEDULE, SWITCH_EVENT_SHUTDOWN, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mprintf(), switch_queue_push(), switch_str_nil, switch_stristr(), switch_true(), wake_thread(), and zstr.

Referenced by switch_core_sqldb_start().

01222 {
01223         char *sql[MAX_SQL] = { 0 };
01224         int sql_idx = 0;
01225         char *extra_cols;
01226 
01227         switch_assert(event);
01228 
01229         switch (event->event_id) {
01230         case SWITCH_EVENT_ADD_SCHEDULE:
01231                 {
01232                         const char *id = switch_event_get_header(event, "task-id");
01233                         const char *manager = switch_event_get_header(event, "task-sql_manager");
01234 
01235                         if (id) {
01236                                 new_sql() = switch_mprintf("insert into tasks values(%q,'%q','%q',%q, '%q')",
01237                                                                                    id,
01238                                                                                    switch_event_get_header_nil(event, "task-desc"),
01239                                                                                    switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_switchname()
01240                                                                                    );
01241                         }
01242                 }
01243                 break;
01244         case SWITCH_EVENT_DEL_SCHEDULE:
01245         case SWITCH_EVENT_EXE_SCHEDULE:
01246                 new_sql() = switch_mprintf("delete from tasks where task_id=%q and hostname='%q'",
01247                                                                    switch_event_get_header_nil(event, "task-id"), switch_core_get_switchname());
01248                 break;
01249         case SWITCH_EVENT_RE_SCHEDULE:
01250                 {
01251                         const char *id = switch_event_get_header(event, "task-id");
01252                         const char *manager = switch_event_get_header(event, "task-sql_manager");
01253 
01254                         if (id) {
01255                                 new_sql() = switch_mprintf("update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q'",
01256                                                                                    switch_event_get_header_nil(event, "task-desc"),
01257                                                                                    switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", id,
01258                                                                                    switch_core_get_switchname());
01259                         }
01260                 }
01261                 break;
01262         case SWITCH_EVENT_CHANNEL_DESTROY:
01263                 {
01264                         const char *uuid = switch_event_get_header(event, "unique-id");
01265                         
01266                         if (uuid) {
01267                                 new_sql() = switch_mprintf("delete from channels where uuid='%q'",
01268                                                                                    uuid);
01269 
01270                                 new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q')",
01271                                                                                    uuid, uuid);
01272 
01273                         }
01274                 }
01275                 break;
01276         case SWITCH_EVENT_CHANNEL_UUID:
01277                 {
01278                         new_sql() = switch_mprintf("update channels set uuid='%q' where uuid='%q'",
01279                                                                            switch_event_get_header_nil(event, "unique-id"),
01280                                                                            switch_event_get_header_nil(event, "old-unique-id")
01281                                                                            );
01282 
01283                         new_sql() = switch_mprintf("update channels set call_uuid='%q' where call_uuid='%q'",
01284                                                                            switch_event_get_header_nil(event, "unique-id"),
01285                                                                            switch_event_get_header_nil(event, "old-unique-id")
01286                                                                            );
01287                         break;
01288                 }
01289         case SWITCH_EVENT_CHANNEL_CREATE:
01290                 new_sql() = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname) "
01291                                                                    "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q')",
01292                                                                    switch_event_get_header_nil(event, "unique-id"),
01293                                                                    switch_event_get_header_nil(event, "call-direction"),
01294                                                                    switch_event_get_header_nil(event, "event-date-local"),
01295                                                                    (long) switch_epoch_time_now(NULL),
01296                                                                    switch_event_get_header_nil(event, "channel-name"),
01297                                                                    switch_event_get_header_nil(event, "channel-state"),
01298                                                                    switch_event_get_header_nil(event, "channel-call-state"),
01299                                                                    switch_event_get_header_nil(event, "caller-dialplan"),
01300                                                                    switch_event_get_header_nil(event, "caller-context"), switch_core_get_switchname()
01301                                                                    );
01302                 break;
01303         case SWITCH_EVENT_CODEC:
01304 
01305                 new_sql() =
01306                         switch_mprintf
01307                         ("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'",
01308                          switch_event_get_header_nil(event, "channel-read-codec-name"),
01309                          switch_event_get_header_nil(event, "channel-read-codec-rate"),
01310                          switch_event_get_header_nil(event, "channel-read-codec-bit-rate"),
01311                          switch_event_get_header_nil(event, "channel-write-codec-name"),
01312                          switch_event_get_header_nil(event, "channel-write-codec-rate"),
01313                          switch_event_get_header_nil(event, "channel-write-codec-bit-rate"),
01314                          switch_event_get_header_nil(event, "unique-id"));
01315                 break;
01316         case SWITCH_EVENT_CHANNEL_HOLD:
01317         case SWITCH_EVENT_CHANNEL_UNHOLD:
01318         case SWITCH_EVENT_CHANNEL_EXECUTE: {
01319                 
01320                 new_sql() = switch_mprintf("update channels set application='%q',application_data='%q',"
01321                                                                    "presence_id='%q',presence_data='%q' where uuid='%q'",
01322                                                                    switch_event_get_header_nil(event, "application"),
01323                                                                    switch_event_get_header_nil(event, "application-data"),
01324                                                                    switch_event_get_header_nil(event, "channel-presence-id"),
01325                                                                    switch_event_get_header_nil(event, "channel-presence-data"),
01326                                                                    switch_event_get_header_nil(event, "unique-id")
01327                                                                    );
01328 
01329         }
01330                 break;
01331 
01332         case SWITCH_EVENT_CHANNEL_ORIGINATE:
01333                 {
01334                         if ((extra_cols = parse_presence_data_cols(event))) {
01335                                 new_sql() = switch_mprintf("update channels set "
01336                                                                                    "presence_id='%q',presence_data='%q', call_uuid='%q',%s where uuid='%q'",
01337                                                                                    switch_event_get_header_nil(event, "channel-presence-id"),
01338                                                                                    switch_event_get_header_nil(event, "channel-presence-data"),
01339                                                                                    switch_event_get_header_nil(event, "channel-call-uuid"),
01340                                                                                    extra_cols,
01341                                                                                    switch_event_get_header_nil(event, "unique-id"));
01342                                 free(extra_cols);
01343                         } else {
01344                                 new_sql() = switch_mprintf("update channels set "
01345                                                                                    "presence_id='%q',presence_data='%q', call_uuid='%q' where uuid='%q'",
01346                                                                                    switch_event_get_header_nil(event, "channel-presence-id"),
01347                                                                                    switch_event_get_header_nil(event, "channel-presence-data"),
01348                                                                                    switch_event_get_header_nil(event, "channel-call-uuid"),
01349                                                                                    switch_event_get_header_nil(event, "unique-id"));
01350                         }
01351 
01352                 }
01353 
01354                 break;
01355         case SWITCH_EVENT_CALL_UPDATE:
01356                 {
01357                         new_sql() = switch_mprintf("update channels set callee_name='%q',callee_num='%q',sent_callee_name='%q',sent_callee_num='%q',callee_direction='%q',"
01358                                                                            "cid_name='%q',cid_num='%q' where uuid='%s'",
01359                                                                            switch_event_get_header_nil(event, "caller-callee-id-name"),
01360                                                                            switch_event_get_header_nil(event, "caller-callee-id-number"),
01361                                                                            switch_event_get_header_nil(event, "sent-callee-id-name"),
01362                                                                            switch_event_get_header_nil(event, "sent-callee-id-number"),
01363                                                                            switch_event_get_header_nil(event, "direction"),
01364                                                                            switch_event_get_header_nil(event, "caller-caller-id-name"),
01365                                                                            switch_event_get_header_nil(event, "caller-caller-id-number"),
01366                                                                            switch_event_get_header_nil(event, "unique-id")
01367                                                                            );
01368                 }
01369                 break;
01370         case SWITCH_EVENT_CHANNEL_CALLSTATE:
01371                 {
01372                         char *num = switch_event_get_header_nil(event, "channel-call-state-number");
01373                         switch_channel_callstate_t callstate = CCS_DOWN;
01374 
01375                         if (num) {
01376                                 callstate = atoi(num);
01377                         }
01378 
01379                         if (callstate != CCS_DOWN && callstate != CCS_HANGUP) {
01380                                 if ((extra_cols = parse_presence_data_cols(event))) {
01381                                         new_sql() = switch_mprintf("update channels set callstate='%q',%s where uuid='%q'",
01382                                                                                            switch_event_get_header_nil(event, "channel-call-state"),
01383                                                                                            extra_cols,
01384                                                                                            switch_event_get_header_nil(event, "unique-id"));
01385                                         free(extra_cols);
01386                                 } else {
01387                                         new_sql() = switch_mprintf("update channels set callstate='%q' where uuid='%q'",
01388                                                                                            switch_event_get_header_nil(event, "channel-call-state"),
01389                                                                                            switch_event_get_header_nil(event, "unique-id"));
01390                                 }
01391                         }
01392 
01393                 }
01394                 break;
01395         case SWITCH_EVENT_CHANNEL_STATE:
01396                 {
01397                         char *state = switch_event_get_header_nil(event, "channel-state-number");
01398                         switch_channel_state_t state_i = CS_DESTROY;
01399 
01400                         if (!zstr(state)) {
01401                                 state_i = atoi(state);
01402                         }
01403 
01404                         switch (state_i) {
01405                         case CS_NEW:
01406                         case CS_HANGUP:
01407                         case CS_DESTROY:
01408                         case CS_REPORTING:
01409                                 break;
01410                         case CS_ROUTING:
01411                                 if ((extra_cols = parse_presence_data_cols(event))) {
01412                                         new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q',"
01413                                                                                            "sent_callee_name='%q',sent_callee_num='%q',"
01414                                                                                            "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',%s "
01415                                                                                            "where uuid='%s'",
01416                                                                                            switch_event_get_header_nil(event, "channel-state"),
01417                                                                                            switch_event_get_header_nil(event, "caller-caller-id-name"),
01418                                                                                            switch_event_get_header_nil(event, "caller-caller-id-number"),
01419                                                                                            switch_event_get_header_nil(event, "caller-callee-id-name"),
01420                                                                                            switch_event_get_header_nil(event, "caller-callee-id-number"),
01421                                                                                            switch_event_get_header_nil(event, "sent-callee-id-name"),
01422                                                                                            switch_event_get_header_nil(event, "sent-callee-id-number"),
01423                                                                                            switch_event_get_header_nil(event, "caller-network-addr"),
01424                                                                                            switch_event_get_header_nil(event, "caller-destination-number"),
01425                                                                                            switch_event_get_header_nil(event, "caller-dialplan"),
01426                                                                                            switch_event_get_header_nil(event, "caller-context"),
01427                                                                                            switch_event_get_header_nil(event, "channel-presence-id"),
01428                                                                                            switch_event_get_header_nil(event, "channel-presence-data"),
01429                                                                                            extra_cols,
01430                                                                                            switch_event_get_header_nil(event, "unique-id"));
01431                                         free(extra_cols);
01432                                 } else {
01433                                         new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q',"
01434                                                                                            "sent_callee_name='%q',sent_callee_num='%q',"
01435                                                                                            "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' "
01436                                                                                            "where uuid='%s'",
01437                                                                                            switch_event_get_header_nil(event, "channel-state"),
01438                                                                                            switch_event_get_header_nil(event, "caller-caller-id-name"),
01439                                                                                            switch_event_get_header_nil(event, "caller-caller-id-number"),
01440                                                                                            switch_event_get_header_nil(event, "caller-callee-id-name"),
01441                                                                                            switch_event_get_header_nil(event, "caller-callee-id-number"),
01442                                                                                            switch_event_get_header_nil(event, "sent-callee-id-name"),
01443                                                                                            switch_event_get_header_nil(event, "sent-callee-id-number"),
01444                                                                                            switch_event_get_header_nil(event, "caller-network-addr"),
01445                                                                                            switch_event_get_header_nil(event, "caller-destination-number"),
01446                                                                                            switch_event_get_header_nil(event, "caller-dialplan"),
01447                                                                                            switch_event_get_header_nil(event, "caller-context"),
01448                                                                                            switch_event_get_header_nil(event, "channel-presence-id"),
01449                                                                                            switch_event_get_header_nil(event, "channel-presence-data"),
01450                                                                                            switch_event_get_header_nil(event, "unique-id"));
01451                                 }
01452                                 break;
01453                         default:
01454                                 new_sql() = switch_mprintf("update channels set state='%s' where uuid='%s'",
01455                                                                                    switch_event_get_header_nil(event, "channel-state"),
01456                                                                                    switch_event_get_header_nil(event, "unique-id"));
01457                                 break;
01458                         }
01459 
01460                         break;
01461 
01462 
01463                 }
01464         case SWITCH_EVENT_CHANNEL_BRIDGE:
01465                 {
01466                         const char *a_uuid, *b_uuid, *uuid;
01467 
01468                         a_uuid = switch_event_get_header(event, "Bridge-A-Unique-ID");
01469                         b_uuid = switch_event_get_header(event, "Bridge-B-Unique-ID");
01470                         uuid = switch_event_get_header(event, "unique-id");
01471 
01472                         if (zstr(a_uuid) || zstr(b_uuid)) {
01473                                 a_uuid = switch_event_get_header_nil(event, "caller-unique-id");
01474                                 b_uuid = switch_event_get_header_nil(event, "other-leg-unique-id");
01475                         }
01476 
01477                         if (uuid && (extra_cols = parse_presence_data_cols(event))) {
01478                                 new_sql() = switch_mprintf("update channels set %s where uuid='%s'", extra_cols, uuid);
01479                                 free(extra_cols);
01480                         } 
01481 
01482                         new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s' or uuid='%s'",
01483                                                                                    switch_event_get_header_nil(event, "channel-call-uuid"), a_uuid, b_uuid);
01484                         
01485 
01486                         new_sql() = switch_mprintf("insert into calls (call_uuid,call_created,call_created_epoch,"
01487                                                                            "caller_uuid,callee_uuid,hostname) "
01488                                                                            "values ('%s','%s','%ld','%q','%q','%q')",
01489                                                                            switch_event_get_header_nil(event, "channel-call-uuid"),
01490                                                                            switch_event_get_header_nil(event, "event-date-local"),
01491                                                                            (long) switch_epoch_time_now(NULL),
01492                                                                            a_uuid,
01493                                                                            b_uuid,
01494                                                                            switch_core_get_switchname()
01495                                                                            );
01496                 }
01497                 break;
01498         case SWITCH_EVENT_CHANNEL_UNBRIDGE:
01499                 {
01500                         char *cuuid = switch_event_get_header_nil(event, "caller-unique-id");
01501                         char *uuid = switch_event_get_header(event, "unique-id");
01502 
01503                         if (uuid && (extra_cols = parse_presence_data_cols(event))) {
01504                                 new_sql() = switch_mprintf("update channels set %s where uuid='%s'", extra_cols, uuid);
01505                                 free(extra_cols);
01506                         } 
01507 
01508                         new_sql() = switch_mprintf("update channels set call_uuid=uuid where call_uuid='%s'",
01509                                                                            switch_event_get_header_nil(event, "channel-call-uuid"));
01510                         
01511                         new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q')",
01512                                                                            cuuid, cuuid);
01513                         break;
01514                 }
01515         case SWITCH_EVENT_SHUTDOWN:
01516                 new_sql() = switch_mprintf("delete from channels where hostname='%q';"
01517                                                                    "delete from interfaces where hostname='%q';"
01518                                                                    "delete from calls where hostname='%q'",
01519                                                                    switch_core_get_switchname(), switch_core_get_switchname(), switch_core_get_switchname()
01520                                                                    );
01521                 break;
01522         case SWITCH_EVENT_LOG:
01523                 return;
01524         case SWITCH_EVENT_MODULE_LOAD:
01525                 {
01526                         const char *type = switch_event_get_header_nil(event, "type");
01527                         const char *name = switch_event_get_header_nil(event, "name");
01528                         const char *description = switch_event_get_header_nil(event, "description");
01529                         const char *syntax = switch_event_get_header_nil(event, "syntax");
01530                         const char *key = switch_event_get_header_nil(event, "key");
01531                         const char *filename = switch_event_get_header_nil(event, "filename");
01532                         if (!zstr(type) && !zstr(name)) {
01533                                 new_sql() =
01534                                         switch_mprintf
01535                                         ("insert into interfaces (type,name,description,syntax,ikey,filename,hostname) values('%q','%q','%q','%q','%q','%q','%q')", type, name,
01536                                          switch_str_nil(description), switch_str_nil(syntax), switch_str_nil(key), switch_str_nil(filename),
01537                                          switch_core_get_switchname()
01538                                          );
01539                         }
01540                         break;
01541                 }
01542         case SWITCH_EVENT_MODULE_UNLOAD:
01543                 {
01544                         const char *type = switch_event_get_header_nil(event, "type");
01545                         const char *name = switch_event_get_header_nil(event, "name");
01546                         if (!zstr(type) && !zstr(name)) {
01547                                 new_sql() = switch_mprintf("delete from interfaces where type='%q' and name='%q' and hostname='%q'", type, name,
01548                                                                                    switch_core_get_switchname());
01549                         }
01550                         break;
01551                 }
01552         case SWITCH_EVENT_CALL_SECURE:
01553                 {
01554                         const char *type = switch_event_get_header_nil(event, "secure_type");
01555                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Secure Type: %s\n", type);
01556                         if (zstr(type)) {
01557                                 break;
01558                         }
01559                         new_sql() = switch_mprintf("update channels set secure='%s' where uuid='%s'",
01560                                                                            type, switch_event_get_header_nil(event, "caller-unique-id")
01561                                                                            );
01562                         break;
01563                 }
01564         case SWITCH_EVENT_NAT:
01565                 {
01566                         const char *op = switch_event_get_header_nil(event, "op");
01567                         switch_bool_t sticky = switch_true(switch_event_get_header_nil(event, "sticky"));
01568                         if (!strcmp("add", op)) {
01569                                 new_sql() = switch_mprintf("insert into nat (port, proto, sticky, hostname) values (%s, %s, %d,'%q')",
01570                                                                                    switch_event_get_header_nil(event, "port"),
01571                                                                                    switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_switchname()
01572                                                                                    );
01573                         } else if (!strcmp("del", op)) {
01574                                 new_sql() = switch_mprintf("delete from nat where port=%s and proto=%s and hostname='%q'",
01575                                                                                    switch_event_get_header_nil(event, "port"),
01576                                                                                    switch_event_get_header_nil(event, "proto"), switch_core_get_switchname());
01577                         } else if (!strcmp("status", op)) {
01578                                 /* call show nat api */
01579                         } else if (!strcmp("status_response", op)) {
01580                                 /* ignore */
01581                         } else {
01582                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown op for SWITCH_EVENT_NAT: %s\n", op);
01583                         }
01584                         break;
01585                 }
01586         default:
01587                 break;
01588         }
01589 
01590         if (sql_idx) {
01591                 int i = 0;
01592                 
01593 
01594                 for (i = 0; i < sql_idx; i++) {
01595                         if (switch_stristr("update channels", sql[i]) || switch_stristr("delete from channels", sql[i])) {
01596                                 switch_queue_push(sql_manager.sql_queue[1], sql[i]);
01597                         } else {
01598                                 switch_queue_push(sql_manager.sql_queue[0], sql[i]);
01599                         }
01600                         sql[i] = NULL;
01601                         wake_thread(0);
01602                 }
01603         }
01604 }

static switch_cache_db_handle_t* create_handle ( switch_cache_db_handle_type_t  type  )  [static]

Definition at line 78 of file switch_core_sqldb.c.

References pool, switch_core_alloc, switch_core_new_memory_pool, switch_mutex_init(), and SWITCH_MUTEX_NESTED.

Referenced by _switch_cache_db_get_db_handle().

00079 {
00080         switch_cache_db_handle_t *new_dbh = NULL;
00081         switch_memory_pool_t *pool = NULL;
00082 
00083         switch_core_new_memory_pool(&pool);
00084         new_dbh = switch_core_alloc(pool, sizeof(*new_dbh));
00085         new_dbh->pool = pool;
00086         new_dbh->type = type;
00087         switch_mutex_init(&new_dbh->mutex, SWITCH_MUTEX_NESTED, new_dbh->pool);
00088 
00089         return new_dbh;
00090 }

static void del_handle ( switch_cache_db_handle_t dbh  )  [static]

Definition at line 114 of file switch_core_sqldb.c.

References switch_cache_db_handle::next, sql_manager, switch_mutex_lock(), and switch_mutex_unlock().

Referenced by sql_close().

00115 {
00116         switch_cache_db_handle_t *dbh_ptr, *last = NULL;
00117 
00118         switch_mutex_lock(sql_manager.dbh_mutex);
00119         for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) {
00120                 if (dbh_ptr == dbh) {
00121                         if (last) {
00122                                 last->next = dbh_ptr->next;
00123                         } else {
00124                                 sql_manager.handle_pool = dbh_ptr->next;
00125                         }
00126                         sql_manager.total_handles--;
00127                         break;
00128                 }
00129                 
00130                 last = dbh_ptr;
00131         }
00132         switch_mutex_unlock(sql_manager.dbh_mutex);
00133 }

static switch_cache_db_handle_t* get_handle ( const char *  db_str,
const char *  user_str,
const char *  thread_str 
) [static]

Definition at line 135 of file switch_core_sqldb.c.

References CDF_PRUNE, switch_cache_db_handle::hash, switch_cache_db_handle::last_user, switch_cache_db_handle::mutex, switch_cache_db_handle::next, sql_manager, switch_ci_hashfunc_default(), switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), switch_set_string, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_cache_db_handle::thread_hash, and switch_cache_db_handle::use_count.

Referenced by _switch_cache_db_get_db_handle().

00136 {
00137         switch_ssize_t hlen = -1;
00138         unsigned long hash = 0, thread_hash = 0;
00139         switch_cache_db_handle_t *dbh_ptr, *r = NULL;
00140 
00141         hash = switch_ci_hashfunc_default(db_str, &hlen);
00142         thread_hash = switch_ci_hashfunc_default(thread_str, &hlen);
00143         
00144         switch_mutex_lock(sql_manager.dbh_mutex);
00145 
00146         for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) {
00147                 if (dbh_ptr->thread_hash == thread_hash && dbh_ptr->hash == hash &&
00148                         !switch_test_flag(dbh_ptr, CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) {
00149                         r = dbh_ptr;
00150                 }
00151         }
00152                         
00153         if (!r) {
00154                 for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) {
00155                         if (dbh_ptr->hash == hash && !dbh_ptr->use_count && !switch_test_flag(dbh_ptr, CDF_PRUNE) && 
00156                                 switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) {
00157                                 r = dbh_ptr;
00158                         break;
00159                 }
00160         }       
00161         }
00162         
00163         if (r) {
00164                 r->use_count++;
00165                 sql_manager.total_used_handles++;
00166                 r->hash = switch_ci_hashfunc_default(db_str, &hlen);
00167                 r->thread_hash = thread_hash;
00168                 switch_set_string(r->last_user, user_str);
00169         }
00170 
00171         switch_mutex_unlock(sql_manager.dbh_mutex);
00172 
00173         return r;
00174         
00175 }

static char* parse_presence_data_cols ( switch_event_t event  )  [static]

Definition at line 1172 of file switch_core_sqldb.c.

References switch_stream_handle::data, end_of, switch_event_get_header, switch_event_get_header_nil, switch_safe_free, switch_snprintfv(), switch_split, SWITCH_STANDARD_STREAM, switch_stream_handle::write_function, and zstr.

Referenced by core_event_handler().

01173 {
01174         char *cols[128] = { 0 };
01175         int col_count = 0;
01176         char *data_copy;
01177         switch_stream_handle_t stream = { 0 };
01178         int i;
01179         char *r;
01180         char col_name[128] = "";
01181         const char *data = switch_event_get_header(event, "presence-data-cols");
01182 
01183         if (zstr(data)) {
01184                 return NULL;
01185         }
01186 
01187         data_copy = strdup(data);
01188         
01189         col_count = switch_split(data_copy, ':', cols);
01190 
01191         SWITCH_STANDARD_STREAM(stream);
01192 
01193         for (i = 0; i < col_count; i++) {
01194                 const char *val = NULL;
01195 
01196                 switch_snprintfv(col_name, sizeof(col_name), "variable_%q", cols[i]);
01197                 val = switch_event_get_header_nil(event, col_name);
01198                 if (zstr(val)) {
01199                         stream.write_function(&stream, "%q=NULL,", cols[i]);
01200                 } else {
01201                         stream.write_function(&stream, "%q='%q',", cols[i], val);
01202                 }
01203         }
01204 
01205         r = (char *) stream.data;
01206 
01207         if (end_of(r) == ',') {
01208                 end_of(r) = '\0';
01209         }
01210 
01211         switch_safe_free(data_copy);
01212         
01213         return r;
01214         
01215 }

static void sql_close ( time_t  prune  )  [static]

Definition at line 225 of file switch_core_sqldb.c.

References CDF_PRUNE, switch_cache_db_native_handle_t::core_db_dbh, del_handle(), switch_cache_db_handle::last_used, switch_cache_db_handle::mutex, switch_cache_db_handle::name, switch_cache_db_handle::native_handle, switch_cache_db_handle::next, switch_cache_db_native_handle_t::odbc_dbh, switch_cache_db_handle::pool, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SQL_CACHE_TIMEOUT, sql_manager, SWITCH_CHANNEL_LOG, switch_core_db_close(), switch_core_destroy_memory_pool, SWITCH_LOG_DEBUG10, switch_log_printf(), switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), switch_odbc_handle_destroy(), SWITCH_STATUS_SUCCESS, switch_test_flag, switch_cache_db_handle::type, and switch_cache_db_handle::use_count.

Referenced by switch_cache_db_flush_handles(), switch_core_sql_db_thread(), and switch_core_sqldb_stop().

00226 {
00227         switch_cache_db_handle_t *dbh = NULL;
00228         int locked = 0;
00229 
00230         switch_mutex_lock(sql_manager.dbh_mutex);
00231  top:
00232         locked = 0;
00233 
00234         for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) {
00235                 time_t diff = 0;
00236 
00237                 if (prune > 0 && prune > dbh->last_used) {
00238                         diff = (time_t) prune - dbh->last_used;
00239                 }
00240 
00241                 if (prune > 0 && (dbh->use_count || (diff < SQL_CACHE_TIMEOUT && !switch_test_flag(dbh, CDF_PRUNE)))) {
00242                         continue;
00243                 }
00244 
00245                 if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
00246                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", dbh->name);
00247 
00248                         switch (dbh->type) {
00249                         case SCDB_TYPE_ODBC:
00250                                 {
00251                                         switch_odbc_handle_destroy(&dbh->native_handle.odbc_dbh);
00252                                 }
00253                                 break;
00254                         case SCDB_TYPE_CORE_DB:
00255                                 {
00256                                         switch_core_db_close(dbh->native_handle.core_db_dbh);
00257                                         dbh->native_handle.core_db_dbh = NULL;
00258                                 }
00259                                 break;
00260                         }
00261 
00262                         del_handle(dbh);
00263                         switch_mutex_unlock(dbh->mutex);
00264                         switch_core_destroy_memory_pool(&dbh->pool);
00265                         goto top;
00266 
00267                 } else {
00268                         if (!prune) {
00269                                 locked++;
00270                         }
00271                         continue;
00272                 }
00273                 
00274         }
00275 
00276         if (locked) {
00277                 goto top;
00278         }
00279 
00280         switch_mutex_unlock(sql_manager.dbh_mutex);
00281 }

int switch_cache_db_affected_rows ( switch_cache_db_handle_t dbh  ) 

Get the affected rows of the last performed query.

Parameters:
[in] dbh The handle
[out] the number of affected rows

Definition at line 600 of file switch_core_sqldb.c.

References SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, switch_core_db_changes(), and switch_odbc_handle_affected_rows().

00601 {
00602         switch (dbh->type) {
00603         case SCDB_TYPE_CORE_DB:
00604                 {
00605                         return switch_core_db_changes(dbh->native_handle.core_db_dbh);
00606                 }
00607                 break;
00608         case SCDB_TYPE_ODBC:
00609                 {
00610                         return switch_odbc_handle_affected_rows(dbh->native_handle.odbc_dbh);
00611                 }
00612                 break;
00613         }
00614         return 0;
00615 }

void switch_cache_db_dismiss_db_handle ( switch_cache_db_handle_t **  dbh  ) 

Returns the handle to the pool, immediately available for other threads to use.

Parameters:
[in] The handle

Definition at line 316 of file switch_core_sqldb.c.

References switch_cache_db_release_db_handle().

00317 {
00318         switch_cache_db_release_db_handle(dbh);
00319 }

switch_status_t switch_cache_db_execute_sql ( switch_cache_db_handle_t dbh,
char *  sql,
char **  err 
)

Executes the sql.

Parameters:
[in] dbh The handle
[in] sql - sql to run
[out] err - Error if it exists

Definition at line 578 of file switch_core_sqldb.c.

References io_mutex, switch_cache_db_execute_sql_chunked(), switch_mutex_lock(), switch_mutex_unlock(), and SWITCH_STATUS_FALSE.

Referenced by switch_cache_db_persistant_execute_trans(), switch_cache_db_test_reactive(), switch_core_sql_thread(), and switch_core_sqldb_start().

00579 {
00580         switch_status_t status = SWITCH_STATUS_FALSE;
00581         switch_mutex_t *io_mutex = dbh->io_mutex;
00582 
00583         if (io_mutex) switch_mutex_lock(io_mutex);
00584 
00585         switch (dbh->type) {
00586         default:
00587                 {
00588                         status = switch_cache_db_execute_sql_chunked(dbh, (char *) sql, 32768, err);
00589                 }
00590                 break;
00591         }
00592 
00593         if (io_mutex) switch_mutex_unlock(io_mutex);
00594 
00595         return status;
00596 
00597 }

char* switch_cache_db_execute_sql2str ( switch_cache_db_handle_t dbh,
char *  sql,
char *  str,
size_t  len,
char **  err 
)

Executes the sql and returns the result as a string.

Parameters:
[in] dbh The handle
[in] sql - sql to run
[out] str - buffer for result
[in] len - length of str buffer
[out] err - Error if it exists

Definition at line 618 of file switch_core_sqldb.c.

References io_mutex, running, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SWITCH_CHANNEL_LOG, switch_cond_next(), switch_copy_string(), SWITCH_CORE_DB_BUSY, switch_core_db_column_count(), switch_core_db_column_text(), switch_core_db_finalize(), switch_core_db_prepare(), SWITCH_CORE_DB_ROW, switch_core_db_step(), SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_odbc_handle_exec_string(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

00619 {
00620         switch_status_t status = SWITCH_STATUS_FALSE;
00621         switch_mutex_t *io_mutex = dbh->io_mutex;
00622 
00623         if (io_mutex) switch_mutex_lock(io_mutex);
00624 
00625         memset(str, 0, len);
00626 
00627         switch (dbh->type) {
00628         case SCDB_TYPE_CORE_DB:
00629                 {
00630                         switch_core_db_stmt_t *stmt;
00631 
00632                         if (switch_core_db_prepare(dbh->native_handle.core_db_dbh, sql, -1, &stmt, 0)) {
00633                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Statement Error [%s]!\n", sql);
00634                                 goto end;
00635                         } else {
00636                                 int running = 1;
00637                                 int colcount;
00638 
00639                                 while (running < 5000) {
00640                                         int result = switch_core_db_step(stmt);
00641                                         const unsigned char *txt;
00642 
00643                                         if (result == SWITCH_CORE_DB_ROW) {
00644                                                 if ((colcount = switch_core_db_column_count(stmt)) > 0) {
00645                                                         if ((txt = switch_core_db_column_text(stmt, 0))) {
00646                                                                 switch_copy_string(str, (char *) txt, len);
00647                                                                 status = SWITCH_STATUS_SUCCESS;
00648                                                         } else {
00649                                                                 goto end;
00650                                                         }
00651                                                 }
00652                                                 break;
00653                                         } else if (result == SWITCH_CORE_DB_BUSY) {
00654                                                 running++;
00655                                                 switch_cond_next();
00656                                                 continue;
00657                                         }
00658                                         break;
00659                                 }
00660 
00661                                 switch_core_db_finalize(stmt);
00662                         }
00663                 }
00664                 break;
00665         case SCDB_TYPE_ODBC:
00666                 {
00667                         status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err);
00668                 }
00669                 break;
00670         }
00671 
00672  end:
00673 
00674         if (io_mutex) switch_mutex_unlock(io_mutex);
00675 
00676         return status == SWITCH_STATUS_SUCCESS ? str : NULL;
00677 
00678 }

switch_status_t switch_cache_db_execute_sql_callback ( switch_cache_db_handle_t dbh,
const char *  sql,
switch_core_db_callback_func_t  callback,
void *  pdata,
char **  err 
)

Executes the sql and uses callback for row-by-row processing.

Parameters:
[in] dbh The handle
[in] sql - sql to run
[in] callback - function pointer to callback
[in] pdata - data to pass to callback
[out] err - Error if it exists

Definition at line 851 of file switch_core_sqldb.c.

References io_mutex, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SQL_CACHE_TIMEOUT, SWITCH_CHANNEL_LOG, SWITCH_CORE_DB_ABORT, switch_core_db_exec(), switch_core_db_free(), SWITCH_CORE_DB_OK, switch_epoch_time_now(), SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_odbc_handle_callback_exec, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_console_complete(), switch_console_expand_alias(), and switch_console_list_uuid().

00853 {
00854         switch_status_t status = SWITCH_STATUS_FALSE;
00855         char *errmsg = NULL;
00856         switch_mutex_t *io_mutex = dbh->io_mutex;
00857 
00858         if (err) {
00859                 *err = NULL;
00860         }
00861 
00862         if (io_mutex) switch_mutex_lock(io_mutex);
00863 
00864 
00865         switch (dbh->type) {
00866         case SCDB_TYPE_ODBC:
00867                 {
00868                         status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err);
00869                 }
00870                 break;
00871         case SCDB_TYPE_CORE_DB:
00872                 {
00873                         int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, callback, pdata, &errmsg);
00874 
00875                         if (ret == SWITCH_CORE_DB_OK || ret == SWITCH_CORE_DB_ABORT) {
00876                                 status = SWITCH_STATUS_SUCCESS;
00877                         }
00878 
00879                         if (errmsg) {
00880                                 dbh->last_used = switch_epoch_time_now(NULL) - (SQL_CACHE_TIMEOUT * 2);
00881                                 if (!strstr(errmsg, "query abort")) {
00882                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
00883                                 }
00884                                 switch_core_db_free(errmsg);
00885                         }
00886                 }
00887                 break;
00888         }
00889 
00890         if (io_mutex) switch_mutex_unlock(io_mutex);
00891 
00892         return status;
00893 }

static switch_status_t switch_cache_db_execute_sql_chunked ( switch_cache_db_handle_t dbh,
char *  sql,
uint32_t  chunk_size,
char **  err 
) [static]

OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions?

Definition at line 517 of file switch_core_sqldb.c.

References end_of_p, switch_assert, switch_cache_db_execute_sql_real(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_cache_db_execute_sql().

00518 {
00519         switch_status_t status = SWITCH_STATUS_FALSE;
00520         char *p, *s, *e;
00521         int chunk_count;
00522         switch_size_t len;
00523 
00524         switch_assert(chunk_size);
00525 
00526         if (err)
00527                 *err = NULL;
00528 
00529         len = strlen(sql);
00530 
00531         if (chunk_size > len) {
00532                 return switch_cache_db_execute_sql_real(dbh, sql, err);
00533         }
00534 
00535         if (!(chunk_count = strlen(sql) / chunk_size)) {
00536                 return SWITCH_STATUS_FALSE;
00537         }
00538 
00539         e = end_of_p(sql);
00540         s = sql;
00541 
00542         while (s && s < e) {
00543                 p = s + chunk_size;
00544 
00545                 if (p > e) {
00546                         p = e;
00547                 }
00548 
00549                 while (p > s) {
00550                         if (*p == '\n' && *(p - 1) == ';') {
00551                                 *p = '\0';
00552                                 *(p - 1) = '\0';
00553                                 p++;
00554                                 break;
00555                         }
00556 
00557                         p--;
00558                 }
00559 
00560                 if (p <= s)
00561                         break;
00562 
00563 
00564                 status = switch_cache_db_execute_sql_real(dbh, s, err);
00565                 if (status != SWITCH_STATUS_SUCCESS || (err && *err)) {
00566                         break;
00567                 }
00568 
00569                 s = p;
00570 
00571         }
00572 
00573         return status;
00574 
00575 }

static switch_status_t switch_cache_db_execute_sql_real ( switch_cache_db_handle_t dbh,
const char *  sql,
char **  err 
) [static]

Definition at line 448 of file switch_core_sqldb.c.

References switch_cache_db_native_handle_t::core_db_dbh, switch_cache_db_handle::io_mutex, io_mutex, switch_cache_db_handle::native_handle, switch_cache_db_native_handle_t::odbc_dbh, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SWITCH_CHANNEL_LOG, switch_core_db_exec(), switch_core_db_free(), SWITCH_CORE_DB_OK, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_odbc_handle_exec(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_strdup, switch_stristr(), and switch_cache_db_handle::type.

Referenced by switch_cache_db_execute_sql_chunked(), switch_cache_db_persistant_execute(), and switch_cache_db_persistant_execute_trans().

00449 {
00450         switch_status_t status = SWITCH_STATUS_FALSE;
00451         char *errmsg = NULL;
00452         char *tmp = NULL;
00453         switch_mutex_t *io_mutex = dbh->io_mutex;
00454         
00455         if (io_mutex) switch_mutex_lock(io_mutex);
00456 
00457         if (err) {
00458                 *err = NULL;
00459         }
00460 
00461         switch (dbh->type) {
00462         case SCDB_TYPE_ODBC:
00463                 {
00464                         status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL, &errmsg);
00465                 }
00466                 break;
00467         case SCDB_TYPE_CORE_DB:
00468                 {
00469                         int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, NULL, NULL, &errmsg);
00470 
00471                         if (ret == SWITCH_CORE_DB_OK) {
00472                                 status = SWITCH_STATUS_SUCCESS;
00473                         }
00474 
00475                         if (errmsg) {
00476                                 switch_strdup(tmp, errmsg);
00477                                 switch_core_db_free(errmsg);
00478                                 errmsg = tmp;
00479                         }
00480                 }
00481                 break;
00482         }
00483 
00484         if (errmsg) {
00485                 if (!switch_stristr("already exists", errmsg) && !switch_stristr("duplicate key name", errmsg)) {
00486                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n%s\n", errmsg, sql);
00487                 }
00488                 if (err) {
00489                         *err = errmsg;
00490                 } else {
00491                         free(errmsg);
00492                 }
00493         }
00494 
00495 
00496         if (io_mutex) switch_mutex_unlock(io_mutex);
00497 
00498         return status;
00499 }

void switch_cache_db_flush_handles ( void   ) 

Definition at line 289 of file switch_core_sqldb.c.

References SQL_CACHE_TIMEOUT, sql_close(), and switch_epoch_time_now().

Referenced by switch_core_session_ctl(), and switch_core_sqldb_stop().

00290 {
00291         sql_close(switch_epoch_time_now(NULL) + SQL_CACHE_TIMEOUT + 1);
00292 }

switch_cache_db_handle_type_t switch_cache_db_get_type ( switch_cache_db_handle_t dbh  ) 

Definition at line 284 of file switch_core_sqldb.c.

Referenced by switch_console_complete(), switch_console_expand_alias(), switch_console_set_alias(), and switch_console_set_complete().

00285 {
00286         return dbh->type;
00287 }

switch_status_t switch_cache_db_persistant_execute ( switch_cache_db_handle_t dbh,
const char *  sql,
uint32_t  retries 
)

Definition at line 680 of file switch_core_sqldb.c.

References io_mutex, switch_cache_db_execute_sql_real(), SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_safe_free, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_yield.

Referenced by switch_console_set_alias(), and switch_console_set_complete().

00681 {
00682         char *errmsg = NULL;
00683         switch_status_t status = SWITCH_STATUS_FALSE;
00684         uint8_t forever = 0;
00685         switch_mutex_t *io_mutex = dbh->io_mutex;
00686 
00687         if (!retries) {
00688                 forever = 1;
00689                 retries = 1000;
00690         }
00691 
00692         while (retries > 0) {
00693 
00694                 if (io_mutex) switch_mutex_lock(io_mutex);
00695                 switch_cache_db_execute_sql_real(dbh, sql, &errmsg);
00696                 if (io_mutex) switch_mutex_unlock(io_mutex);
00697 
00698                 
00699                 if (errmsg) {
00700                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
00701                         switch_safe_free(errmsg);
00702                         switch_yield(100000);
00703                         retries--;
00704                         if (retries == 0 && forever) {
00705                                 retries = 1000;
00706                                 continue;
00707                         }
00708                 } else {
00709                         status = SWITCH_STATUS_SUCCESS;
00710                         break;
00711                 }
00712         }
00713         
00714         return status;
00715 }

switch_status_t switch_cache_db_persistant_execute_trans ( switch_cache_db_handle_t dbh,
char *  sql,
uint32_t  retries 
)

Definition at line 718 of file switch_core_sqldb.c.

References switch_runtime::core_db_inner_post_trans_execute, switch_runtime::core_db_inner_pre_trans_execute, switch_runtime::core_db_post_trans_execute, switch_runtime::core_db_pre_trans_execute, DBTYPE_DEFAULT, io_mutex, switch_runtime::odbc_dbtype, runtime, switch_cache_db_execute_sql(), switch_cache_db_execute_sql_real(), SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_odbc_SQLEndTran(), switch_odbc_SQLSetAutoCommitAttr(), SWITCH_ODBC_SUCCESS, switch_snprintfv(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_yield, and zstr.

Referenced by switch_core_sql_thread().

00719 {
00720         char *errmsg = NULL;
00721         switch_status_t status = SWITCH_STATUS_FALSE;
00722         uint8_t forever = 0;
00723         unsigned begin_retries = 100;
00724         uint8_t again = 0;
00725         switch_mutex_t *io_mutex = dbh->io_mutex;
00726 
00727         if (!retries) {
00728                 forever = 1;
00729                 retries = 1000;
00730         }
00731 
00732         if (io_mutex) switch_mutex_lock(io_mutex);
00733 
00734         if (!zstr(runtime.core_db_pre_trans_execute)) {
00735                 switch_cache_db_execute_sql_real(dbh, runtime.core_db_pre_trans_execute, &errmsg);
00736                 if (errmsg) {
00737                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", runtime.core_db_pre_trans_execute, errmsg);
00738                         free(errmsg);
00739                 }
00740         }
00741 
00742  again:
00743 
00744         while (begin_retries > 0) {
00745                 again = 0;
00746 
00747                 if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
00748                         switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg);
00749                 } else {
00750                         switch_odbc_status_t result;
00751 
00752                         if ((result = switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) {
00753                                 char tmp[100];
00754                                 switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result);
00755                                 errmsg = strdup(tmp);
00756                         }
00757                 }
00758 
00759                 if (errmsg) {
00760                         begin_retries--;
00761                         if (strstr(errmsg, "cannot start a transaction within a transaction")) {
00762                                 again = 1;
00763                         } else {
00764                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL Retry [%s]\n", errmsg);
00765                         }
00766                         free(errmsg);
00767                         errmsg = NULL;
00768 
00769                         if (again) {
00770                                 if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
00771                                         switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
00772                                 } else  {
00773                                         switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1);
00774                                         switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
00775                                 }
00776 
00777                                 goto again;
00778                         }
00779                         
00780                         switch_yield(100000);
00781 
00782                         if (begin_retries == 0) {
00783                                 goto done;
00784                         }
00785 
00786                         continue;
00787                 }
00788 
00789                 break;
00790         }
00791 
00792 
00793         if (!zstr(runtime.core_db_inner_pre_trans_execute)) {
00794                 switch_cache_db_execute_sql_real(dbh, runtime.core_db_inner_pre_trans_execute, &errmsg);
00795                 if (errmsg) {
00796                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", runtime.core_db_inner_pre_trans_execute, errmsg);
00797                         free(errmsg);
00798                 }
00799         }
00800 
00801         while (retries > 0) {
00802 
00803                 switch_cache_db_execute_sql(dbh, sql, &errmsg);
00804 
00805                 if (errmsg) {
00806                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
00807                         free(errmsg);
00808                         errmsg = NULL;
00809                         switch_yield(100000);
00810                         retries--;
00811                         if (retries == 0 && forever) {
00812                                 retries = 1000;
00813                                 continue;
00814                         }
00815                 } else {
00816                         status = SWITCH_STATUS_SUCCESS;
00817                         break;
00818                 }
00819         }
00820 
00821         if (!zstr(runtime.core_db_inner_post_trans_execute)) {
00822                 switch_cache_db_execute_sql_real(dbh, runtime.core_db_inner_post_trans_execute, &errmsg);
00823                 if (errmsg) {
00824                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", runtime.core_db_inner_post_trans_execute, errmsg);
00825                         free(errmsg);
00826                 }
00827         }
00828 
00829  done:
00830 
00831         if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
00832                 switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
00833         } else {
00834                 switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1);
00835                 switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1);
00836         }
00837 
00838         if (!zstr(runtime.core_db_post_trans_execute)) {
00839                 switch_cache_db_execute_sql_real(dbh, runtime.core_db_post_trans_execute, &errmsg);
00840                 if (errmsg) {
00841                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", runtime.core_db_post_trans_execute, errmsg);
00842                         free(errmsg);
00843                 }
00844         }
00845 
00846         if (io_mutex) switch_mutex_unlock(io_mutex);
00847 
00848         return status;
00849 }

void switch_cache_db_release_db_handle ( switch_cache_db_handle_t **  dbh  ) 

Returns the handle to the pool, handle is NOT available to other threads until the allocating thread actually terminates.

Parameters:
[in] The handle

Definition at line 295 of file switch_core_sqldb.c.

References sql_manager, switch_epoch_time_now(), switch_mutex_lock(), and switch_mutex_unlock().

Referenced by switch_cache_db_dismiss_db_handle(), switch_console_expand_alias(), switch_console_list_uuid(), switch_console_set_alias(), switch_console_set_complete(), switch_core_sql_thread(), and switch_core_sqldb_start().

00296 {
00297         if (dbh && *dbh) {
00298                 switch_mutex_lock(sql_manager.dbh_mutex);
00299                 (*dbh)->last_used = switch_epoch_time_now(NULL);
00300 
00301                 (*dbh)->io_mutex = NULL;
00302                 
00303                 if ((*dbh)->use_count) {
00304                         if (--(*dbh)->use_count == 0) {
00305                                 (*dbh)->thread_hash = 1;
00306                         }
00307                 }
00308                 switch_mutex_unlock((*dbh)->mutex);
00309                 sql_manager.total_used_handles--;
00310                 *dbh = NULL;
00311                 switch_mutex_unlock(sql_manager.dbh_mutex);
00312         }
00313 }

void switch_cache_db_status ( switch_stream_handle_t stream  ) 

Provides some feedback as to the status of the db connection pool.

Parameters:
[in] stream stream for status

Definition at line 2147 of file switch_core_sqldb.c.

References CACHE_DB_LEN, switch_cache_db_handle::creator, switch_cache_db_handle::last_used, switch_cache_db_handle::last_user, switch_cache_db_handle::mutex, switch_cache_db_handle::name, switch_cache_db_handle::next, sql_manager, switch_cache_db_type_name(), switch_epoch_time_now(), SWITCH_FALSE, switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), SWITCH_STATUS_SUCCESS, SWITCH_TRUE, switch_cache_db_handle::type, and switch_cache_db_handle::use_count.

02148 {
02149         /* return some status info suitable for the cli */
02150         switch_cache_db_handle_t *dbh = NULL;
02151         switch_bool_t locked = SWITCH_FALSE;
02152         time_t now = switch_epoch_time_now(NULL);
02153         char cleankey_str[CACHE_DB_LEN];
02154         char *pos1 = NULL;
02155         char *pos2 = NULL;
02156         int count = 0, used = 0;
02157 
02158         switch_mutex_lock(sql_manager.dbh_mutex);
02159 
02160         for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) {
02161                 char *needle = "pass=\"";
02162                 time_t diff = 0;
02163 
02164                 diff = now - dbh->last_used;
02165 
02166                 if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
02167                         switch_mutex_unlock(dbh->mutex);
02168                         locked = SWITCH_FALSE;
02169                 } else {
02170                         locked = SWITCH_TRUE;
02171                 }
02172 
02173                 /* sanitize password */
02174                 memset(cleankey_str, 0, sizeof(cleankey_str));
02175                 pos1 = strstr(dbh->name, needle) + strlen(needle);
02176                 pos2 = strstr(pos1, "\"");
02177                 strncpy(cleankey_str, dbh->name, pos1 - dbh->name);
02178                 strcpy(&cleankey_str[pos1 - dbh->name], pos2);
02179                 
02180                 count++;
02181                 
02182                 if (dbh->use_count) {
02183                         used++;
02184                 }
02185                 
02186                 stream->write_function(stream, "%s\n\tType: %s\n\tLast used: %d\n\tFlags: %s, %s(%d)\n"
02187                                                            "\tCreator: %s\n\tLast User: %s\n",
02188                                                            cleankey_str,
02189                                                            switch_cache_db_type_name(dbh->type),
02190                                                            diff,
02191                                                            locked ? "Locked" : "Unlocked",
02192                                                            dbh->use_count ? "Attached" : "Detached", dbh->use_count, dbh->creator, dbh->last_user);
02193         }
02194 
02195         stream->write_function(stream, "%d total. %d in use.\n", count, used);
02196 
02197         switch_mutex_unlock(sql_manager.dbh_mutex);
02198 }

switch_bool_t switch_cache_db_test_reactive ( switch_cache_db_handle_t dbh,
const char *  test_sql,
const char *  drop_sql,
const char *  reactive_sql 
)

Definition at line 895 of file switch_core_sqldb.c.

References io_mutex, runtime, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SCF_AUTO_SCHEMAS, SCF_CLEAR_SQL, switch_cache_db_execute_sql(), SWITCH_CHANNEL_LOG, switch_core_db_exec(), switch_core_db_free(), SWITCH_FALSE, SWITCH_LOG_DEBUG, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_odbc_handle_exec(), SWITCH_ODBC_SUCCESS, switch_test_flag, and SWITCH_TRUE.

Referenced by switch_core_sqldb_start().

00897 {
00898         char *errmsg;
00899         switch_bool_t r = SWITCH_TRUE;
00900         switch_mutex_t *io_mutex = dbh->io_mutex;
00901 
00902         if (!switch_test_flag((&runtime), SCF_CLEAR_SQL)) {
00903                 return SWITCH_TRUE;
00904         }
00905 
00906         if (!switch_test_flag((&runtime), SCF_AUTO_SCHEMAS)) {
00907                 switch_cache_db_execute_sql(dbh, (char *)test_sql, NULL);
00908                 return SWITCH_TRUE;
00909         }
00910 
00911         if (io_mutex) switch_mutex_lock(io_mutex);
00912 
00913         switch (dbh->type) {
00914         case SCDB_TYPE_ODBC:
00915                 {
00916                         if (switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, test_sql, NULL, NULL) != SWITCH_ODBC_SUCCESS) {
00917                                 r = SWITCH_FALSE;
00918                                 if (drop_sql) {
00919                                         switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, drop_sql, NULL, NULL);
00920                                 }
00921                                 switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, reactive_sql, NULL, NULL);
00922                         }
00923                 }
00924                 break;
00925         case SCDB_TYPE_CORE_DB:
00926                 {
00927                         if (test_sql) {
00928                                 switch_core_db_exec(dbh->native_handle.core_db_dbh, test_sql, NULL, NULL, &errmsg);
00929 
00930                                 if (errmsg) {
00931                                         r = SWITCH_FALSE;
00932                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\nAuto Generating Table!\n", errmsg, test_sql);
00933                                         switch_core_db_free(errmsg);
00934                                         errmsg = NULL;
00935                                         if (drop_sql) {
00936                                                 switch_core_db_exec(dbh->native_handle.core_db_dbh, drop_sql, NULL, NULL, &errmsg);
00937                                         }
00938                                         if (errmsg) {
00939                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\n", errmsg, drop_sql);
00940                                                 switch_core_db_free(errmsg);
00941                                                 errmsg = NULL;
00942                                         }
00943                                         switch_core_db_exec(dbh->native_handle.core_db_dbh, reactive_sql, NULL, NULL, &errmsg);
00944                                         if (errmsg) {
00945                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\n", errmsg, reactive_sql);
00946                                                 switch_core_db_free(errmsg);
00947                                                 errmsg = NULL;
00948                                         }
00949                                 }
00950                         }
00951                 }
00952                 break;
00953         }
00954 
00955 
00956         if (io_mutex) switch_mutex_unlock(io_mutex);
00957 
00958         return r;
00959 }

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 
)

Add user registration.

Parameters:
[in] user 
[in] realm 
[in] token 
[in] url - a freeswitch dial string
[in] expires 
[in] network_ip 
[in] network_port 
[in] network_proto - one of tls, tcp, udp
[out] err - Error if it exists

Definition at line 1845 of file switch_core_sqldb.c.

References switch_runtime::multiple_registrations, runtime, SCF_USE_SQL, sql_manager, switch_core_get_switchname(), switch_mprintf(), switch_queue_push(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_str_nil, and switch_test_flag.

01847 {
01848         char *sql;
01849 
01850         if (!switch_test_flag((&runtime), SCF_USE_SQL)) {
01851                 return SWITCH_STATUS_FALSE;
01852         }
01853 
01854         if (runtime.multiple_registrations) {
01855                 sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", 
01856                                                          switch_core_get_switchname(), url, switch_str_nil(token));
01857         } else {
01858                 sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", 
01859                                                          user, realm, switch_core_get_switchname());
01860         }
01861 
01862         switch_queue_push(sql_manager.sql_queue[0], sql);
01863         
01864         sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) "
01865                                                  "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
01866                                                  switch_str_nil(user),
01867                                                  switch_str_nil(realm),
01868                                                  switch_str_nil(token),
01869                                                  switch_str_nil(url),
01870                                                  expires,
01871                                                  switch_str_nil(network_ip),
01872                                                  switch_str_nil(network_port),
01873                                                  switch_str_nil(network_proto),
01874                                                  switch_core_get_switchname()
01875                                                  );
01876 
01877         
01878         switch_queue_push(sql_manager.sql_queue[0], sql);
01879         
01880         return SWITCH_STATUS_SUCCESS;
01881 }

switch_status_t switch_core_del_registration ( const char *  user,
const char *  realm,
const char *  token 
)

Delete user registration.

Parameters:
[in] user 
[in] realm 
[in] token 
[out] err - Error if it exists

Definition at line 1883 of file switch_core_sqldb.c.

References switch_runtime::multiple_registrations, runtime, SCF_USE_SQL, sql_manager, switch_core_get_switchname(), switch_mprintf(), switch_queue_push(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, and zstr.

01884 {
01885 
01886         char *sql;
01887 
01888         if (!switch_test_flag((&runtime), SCF_USE_SQL)) {
01889                 return SWITCH_STATUS_FALSE;
01890         }
01891 
01892         if (!zstr(token) && runtime.multiple_registrations) {
01893                 sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' and token='%q'", user, realm, switch_core_get_switchname(), token);
01894         } else {
01895                 sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_switchname());
01896         }
01897 
01898         switch_queue_push(sql_manager.sql_queue[0], sql);
01899 
01900         return SWITCH_STATUS_SUCCESS;
01901 }

switch_status_t switch_core_expire_registration ( int  force  ) 

Expire user registrations.

Parameters:
[in] force delete all registrations
[out] err - Error if it exists

Definition at line 1903 of file switch_core_sqldb.c.

References runtime, SCF_USE_SQL, sql_manager, switch_core_get_switchname(), switch_epoch_time_now(), switch_mprintf(), switch_queue_push(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_test_flag.

Referenced by switch_core_sql_db_thread().

01904 {
01905         
01906         char *sql;
01907         time_t now;
01908 
01909         if (!switch_test_flag((&runtime), SCF_USE_SQL)) {
01910                 return SWITCH_STATUS_FALSE;
01911         }
01912 
01913         now = switch_epoch_time_now(NULL);
01914 
01915         if (force) {
01916                 sql = switch_mprintf("delete from registrations where hostname='%q'", switch_core_get_switchname());
01917         } else {
01918                 sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_switchname());
01919         }
01920 
01921         switch_queue_push(sql_manager.sql_queue[0], sql);
01922 
01923         return SWITCH_STATUS_SUCCESS;
01924 
01925 }

static void* SWITCH_THREAD_FUNC switch_core_sql_db_thread ( switch_thread_t thread,
void *  obj 
) [static]

Definition at line 962 of file switch_core_sqldb.c.

References runtime, SCF_USE_SQL, SQL_CACHE_TIMEOUT, sql_close(), sql_manager, SQL_REG_TIMEOUT, switch_core_expire_registration(), switch_epoch_time_now(), switch_test_flag, switch_yield, and wake_thread().

Referenced by switch_core_sqldb_start().

00963 {
00964         int sec = 0, reg_sec = 0;;
00965 
00966         sql_manager.db_thread_running = 1;
00967 
00968         while (sql_manager.db_thread_running == 1) {
00969                 if (++sec == SQL_CACHE_TIMEOUT) {
00970                         sql_close(switch_epoch_time_now(NULL));         
00971                         wake_thread(0);
00972                         sec = 0;
00973                 }
00974 
00975                 if (switch_test_flag((&runtime), SCF_USE_SQL) && ++reg_sec == SQL_REG_TIMEOUT) {
00976                         switch_core_expire_registration(0);
00977                         reg_sec = 0;
00978                 }
00979                 switch_yield(1000000);
00980         }
00981 
00982 
00983         return NULL;
00984 }

static void* SWITCH_THREAD_FUNC switch_core_sql_thread ( switch_thread_t thread,
void *  obj 
) [static]

Definition at line 986 of file switch_core_sqldb.c.

References do_sleep(), switch_runtime::max_sql_buffer_len, runtime, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SCF_DEBUG_SQL, SCSC_PAUSE_INBOUND, skip(), switch_runtime::sql_buffer_len, sql_manager, switch_assert, switch_cache_db_execute_sql(), switch_cache_db_persistant_execute_trans(), switch_cache_db_release_db_handle(), SWITCH_CHANNEL_LOG, switch_core_db_handle, switch_core_session_ctl(), SWITCH_LOG_CRIT, SWITCH_LOG_NOTICE, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_lock(), switch_mutex_unlock(), switch_queue_size(), switch_queue_trypop(), SWITCH_SQL_QUEUE_PAUSE_LEN, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_cond_wait(), and switch_yield.

Referenced by switch_core_sqldb_start().

00987 {
00988         void *pop = NULL;
00989         uint32_t iterations = 0;
00990         uint8_t trans = 0;
00991         uint32_t target = 20000;
00992         switch_size_t len = 0, sql_len = runtime.sql_buffer_len;
00993         char *tmp, *sqlbuf = (char *) malloc(sql_len);
00994         char *sql = NULL, *save_sql = NULL;
00995         switch_size_t newlen;
00996         int lc = 0, wrote = 0, do_sleep = 1;
00997         uint32_t sanity = 120;
00998         int auto_pause = 0;
00999 
01000         switch_assert(sqlbuf);
01001 
01002         while (!sql_manager.event_db) {
01003                 if (switch_core_db_handle(&sql_manager.event_db) == SWITCH_STATUS_SUCCESS && sql_manager.event_db)
01004                         break;
01005                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error getting core db, Retrying\n");
01006                 switch_yield(500000);
01007                 sanity--;
01008         }
01009 
01010         if (!sql_manager.event_db) {
01011                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error getting core db Disabling core sql functionality\n");
01012                 return NULL;
01013         }
01014 
01015         sql_manager.thread_running = 1;
01016 
01017         switch_mutex_lock(sql_manager.cond_mutex);
01018 
01019         switch (sql_manager.event_db->type) {
01020                 case SCDB_TYPE_ODBC:
01021                         break;
01022                 case SCDB_TYPE_CORE_DB:
01023                         {
01024                                 switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA synchronous=OFF;", NULL);
01025                                 switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA count_changes=OFF;", NULL);
01026                                 switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA temp_store=MEMORY;", NULL);
01027                                 switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA journal_mode=OFF;", NULL);
01028                         }
01029                         break;
01030         }
01031 
01032         while (sql_manager.thread_running == 1) {
01033                 if (save_sql || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS ||
01034                         switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) {
01035 
01036                         if (save_sql) {
01037                                 sql = save_sql;
01038                                 save_sql = NULL;
01039                         } else if ((sql = (char *) pop)) {
01040                                 pop = NULL;
01041                         }
01042                         
01043                         if (sql) {
01044                                 newlen = strlen(sql) + 2;
01045 
01046                                 if (iterations == 0) {
01047                                         trans = 1;
01048                                 }
01049 
01050                                 if (len + newlen + 1 > sql_len) {
01051                                         int new_mlen = len + newlen + 10240;
01052                                         
01053                                         if (new_mlen < runtime.max_sql_buffer_len) {
01054                                                 sql_len = new_mlen;
01055                                                 if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) {
01056                                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
01057                                                                                           "REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager.sql_queue[0]), 
01058                                                                                           switch_queue_size(sql_manager.sql_queue[1]));
01059                                                 }
01060                                                 if (!(tmp = realloc(sqlbuf, sql_len))) {
01061                                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n");
01062                                                         abort();
01063                                                         break;
01064                                                 }
01065                                                 sqlbuf = tmp;
01066                                         } else {
01067                                                 if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) {
01068                                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
01069                                                                                           "SAVE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]));
01070                                                 }
01071                                                 save_sql = sql;
01072                                                 sql = NULL;
01073                                                 lc = 0;
01074                                                 goto skip;
01075                                         }
01076                                 }
01077 
01078                                 iterations++;                           
01079                                 sprintf(sqlbuf + len, "%s;\n", sql);
01080                                 len += newlen;
01081                                 free(sql);
01082                                 sql = NULL;
01083                         } else {
01084                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "SQL thread ending\n");
01085                                 break;
01086                         }
01087                 }
01088 
01089                 lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]);
01090 
01091 
01092                 if (lc > SWITCH_SQL_QUEUE_PAUSE_LEN) {
01093                         if (!auto_pause) {
01094                                 auto_pause = 1;
01095                                 switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause);
01096                                 auto_pause = 1;
01097                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue overflowing [%d], Pausing calls.\n", lc);
01098                         }
01099                 } else {
01100                         if (auto_pause && lc < 1000) {
01101                                 auto_pause = 0;
01102                                 switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause);
01103                                 auto_pause = 0;
01104                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue back to normal size, resuming..\n");
01105                         }
01106                 }
01107 
01108         skip:
01109                 
01110                 wrote = 0;
01111 
01112                 if (trans && iterations && (iterations > target || !lc)) {
01113                         if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) {
01114                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
01115                                                                   "RUN %d %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]), iterations);
01116                         }
01117                         if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) {
01118                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n");
01119                         }
01120                         if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { 
01121                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DONE\n");
01122                         }
01123 
01124 
01125                         iterations = 0;
01126                         trans = 0;
01127                         len = 0;
01128                         *sqlbuf = '\0';
01129                         lc = 0;
01130                         if (do_sleep) {
01131                                 switch_yield(200000);
01132                         } else {
01133                                 switch_yield(1000);
01134                         }
01135                         wrote = 1;
01136                 }
01137 
01138                 lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]);
01139                 
01140                 if (!lc) {
01141                         switch_thread_cond_wait(sql_manager.cond, sql_manager.cond_mutex);
01142                 } else if (wrote) {
01143                         if (lc > 2000) {
01144                                 do_sleep = 0;
01145                         } else {
01146                                 do_sleep = 1;
01147                         }
01148                 }
01149                 
01150                 
01151         }
01152 
01153         switch_mutex_unlock(sql_manager.cond_mutex);
01154 
01155         while (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) {
01156                 free(pop);
01157         }
01158 
01159         while (switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) {
01160                 free(pop);
01161         }
01162 
01163         free(sqlbuf);
01164 
01165         sql_manager.thread_running = 0;
01166 
01167         switch_cache_db_release_db_handle(&sql_manager.event_db);
01168 
01169         return NULL;
01170 }

switch_status_t switch_core_sqldb_start ( switch_memory_pool_t pool,
switch_bool_t  manage 
)

Definition at line 1927 of file switch_core_sqldb.c.

References basic_calls_sql, core_event_handler(), create_alias_sql, create_calls_sql, create_channels_sql, create_complete_sql, create_interfaces_sql, create_nat_sql, create_registrations_sql, create_tasks_sql, DBTYPE_DEFAULT, detailed_calls_sql, switch_runtime::odbc_dbtype, switch_runtime::odbc_dsn, switch_runtime::odbc_pass, switch_runtime::odbc_user, runtime, SCDB_TYPE_CORE_DB, SCDB_TYPE_ODBC, SCF_CLEAR_SQL, SCF_CORE_ODBC_REQ, SCF_USE_SQL, skip(), sql_manager, switch_cache_db_execute_sql(), switch_cache_db_release_db_handle(), switch_cache_db_test_reactive(), SWITCH_CHANNEL_LOG, switch_clear_flag, switch_core_db_handle, switch_core_get_switchname(), switch_core_sql_db_thread(), switch_core_sql_thread(), SWITCH_EVENT_ALL, switch_event_bind_removable(), SWITCH_EVENT_SUBCLASS_ANY, SWITCH_LOG_CRIT, SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_init(), SWITCH_MUTEX_NESTED, switch_queue_create(), switch_snprintfv(), SWITCH_SQL_QUEUE_LEN, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_string_replace(), switch_test_flag, switch_thread_cond_create(), switch_thread_create(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_stacksize_set(), switch_yield, and switch_cache_db_handle::type.

Referenced by switch_core_init().

01928 {
01929         switch_threadattr_t *thd_attr;
01930         switch_cache_db_handle_t *dbh;
01931         uint32_t sanity = 400;
01932 
01933         sql_manager.memory_pool = pool;
01934         sql_manager.manage = manage;
01935 
01936         switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
01937         switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
01938         switch_mutex_init(&sql_manager.cond_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
01939 
01940         switch_thread_cond_create(&sql_manager.cond, sql_manager.memory_pool);
01941 
01942  top:
01943 
01944         if (!sql_manager.manage) goto skip;
01945 
01946         /* Activate SQL database */
01947         if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) {
01948                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n");
01949 
01950                 if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) {
01951                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC IS REQUIRED!\n");
01952                         return SWITCH_STATUS_FALSE;
01953                 }
01954 
01955                 if (runtime.odbc_dsn) {
01956                         runtime.odbc_dsn = NULL;
01957                         runtime.odbc_user = NULL;
01958                         runtime.odbc_pass = NULL;
01959                         runtime.odbc_dbtype = DBTYPE_DEFAULT;
01960                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n");
01961                         goto top;
01962                 }
01963 
01964 
01965                 switch_clear_flag((&runtime), SCF_USE_SQL);
01966                 return SWITCH_STATUS_FALSE;
01967         }
01968 
01969 
01970         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n");
01971 
01972         switch (dbh->type) {
01973         case SCDB_TYPE_ODBC:
01974                 if (switch_test_flag((&runtime), SCF_CLEAR_SQL)) {
01975                         char sql[512] = "";
01976                         char *tables[] = { "channels", "calls", "interfaces", "tasks", NULL };
01977                         int i;
01978                         const char *hostname = switch_core_get_switchname();
01979 
01980                         for (i = 0; tables[i]; i++) {
01981                                 switch_snprintfv(sql, sizeof(sql), "delete from %q where hostname='%q'", tables[i], hostname);
01982                                 switch_cache_db_execute_sql(dbh, sql, NULL);
01983                         }
01984                 }
01985                 break;
01986         case SCDB_TYPE_CORE_DB:
01987                 {
01988                         switch_cache_db_execute_sql(dbh, "drop table channels", NULL);
01989                         switch_cache_db_execute_sql(dbh, "drop table calls", NULL);
01990                         switch_cache_db_execute_sql(dbh, "drop view detailed_calls", NULL);
01991                         switch_cache_db_execute_sql(dbh, "drop view basic_calls", NULL);
01992                         switch_cache_db_execute_sql(dbh, "drop table interfaces", NULL);
01993                         switch_cache_db_execute_sql(dbh, "drop table tasks", NULL);
01994                         switch_cache_db_execute_sql(dbh, "PRAGMA synchronous=OFF;", NULL);
01995                         switch_cache_db_execute_sql(dbh, "PRAGMA count_changes=OFF;", NULL);
01996                         switch_cache_db_execute_sql(dbh, "PRAGMA default_cache_size=8000", NULL);
01997                         switch_cache_db_execute_sql(dbh, "PRAGMA temp_store=MEMORY;", NULL);
01998                         switch_cache_db_execute_sql(dbh, "PRAGMA journal_mode=OFF;", NULL);
01999                 }
02000                 break;
02001         }
02002 
02003 
02004         switch_cache_db_test_reactive(dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql);
02005         switch_cache_db_test_reactive(dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql);
02006         switch_cache_db_test_reactive(dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql);
02007         switch_cache_db_test_reactive(dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", 
02008                                                                   "DROP TABLE registrations", create_registrations_sql);
02009 
02010 
02011         switch (dbh->type) {
02012         case SCDB_TYPE_ODBC:
02013                 {
02014                         char *err;
02015                         switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql);
02016                         switch_cache_db_test_reactive(dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql);
02017                         switch_cache_db_test_reactive(dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql);
02018                         switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql);
02019                         if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
02020                                 switch_cache_db_test_reactive(dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", 
02021                                                                                           "DROP TABLE registrations", create_registrations_sql);
02022                         } else {
02023                                 char *tmp = switch_string_replace(create_registrations_sql, "url      TEXT", "url      VARCHAR(max)");
02024                                 switch_cache_db_test_reactive(dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", 
02025                                                                                           "DROP TABLE registrations", tmp);
02026                                 free(tmp);
02027                         }
02028                         switch_cache_db_test_reactive(dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql);
02029                         switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql);
02030 
02031                         if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
02032                                 switch_cache_db_execute_sql(dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err);
02033                         } else {
02034                                 switch_cache_db_execute_sql(dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err);
02035                         }
02036 
02037                         if (err) {
02038                                 runtime.odbc_dsn = NULL;
02039                                 runtime.odbc_user = NULL;
02040                                 runtime.odbc_pass = NULL;
02041                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling ODBC\n");
02042                                 switch_cache_db_release_db_handle(&dbh);
02043                                 free(err);
02044                                 goto top;
02045                         }
02046                 }
02047                 break;
02048         case SCDB_TYPE_CORE_DB:
02049                 {
02050                         switch_cache_db_execute_sql(dbh, create_channels_sql, NULL);
02051                         switch_cache_db_execute_sql(dbh, create_calls_sql, NULL);
02052                         switch_cache_db_execute_sql(dbh, create_interfaces_sql, NULL);
02053                         switch_cache_db_execute_sql(dbh, create_tasks_sql, NULL);
02054                         switch_cache_db_execute_sql(dbh, detailed_calls_sql, NULL);
02055                         switch_cache_db_execute_sql(dbh, basic_calls_sql, NULL);
02056                 }
02057                 break;
02058         }
02059 
02060 
02061         switch_cache_db_execute_sql(dbh, "delete from complete where sticky=0", NULL);
02062         switch_cache_db_execute_sql(dbh, "delete from aliases where sticky=0", NULL);
02063         switch_cache_db_execute_sql(dbh, "delete from nat where sticky=0", NULL);
02064         switch_cache_db_execute_sql(dbh, "create index alias1 on aliases (alias)", NULL);
02065         switch_cache_db_execute_sql(dbh, "create index tasks1 on tasks (hostname,task_id)", NULL);
02066         switch_cache_db_execute_sql(dbh, "create index complete1 on complete (a1,hostname)", NULL);
02067         switch_cache_db_execute_sql(dbh, "create index complete2 on complete (a2,hostname)", NULL);
02068         switch_cache_db_execute_sql(dbh, "create index complete3 on complete (a3,hostname)", NULL);
02069         switch_cache_db_execute_sql(dbh, "create index complete4 on complete (a4,hostname)", NULL);
02070         switch_cache_db_execute_sql(dbh, "create index complete5 on complete (a5,hostname)", NULL);
02071         switch_cache_db_execute_sql(dbh, "create index complete6 on complete (a6,hostname)", NULL);
02072         switch_cache_db_execute_sql(dbh, "create index complete7 on complete (a7,hostname)", NULL);
02073         switch_cache_db_execute_sql(dbh, "create index complete8 on complete (a8,hostname)", NULL);
02074         switch_cache_db_execute_sql(dbh, "create index complete9 on complete (a9,hostname)", NULL);
02075         switch_cache_db_execute_sql(dbh, "create index complete10 on complete (a10,hostname)", NULL);
02076         switch_cache_db_execute_sql(dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL);
02077         switch_cache_db_execute_sql(dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL);
02078         switch_cache_db_execute_sql(dbh, "create index channels1 on channels(hostname)", NULL);
02079         switch_cache_db_execute_sql(dbh, "create index calls1 on calls(hostname)", NULL);
02080         switch_cache_db_execute_sql(dbh, "create index chidx1 on channels (hostname)", NULL);
02081         switch_cache_db_execute_sql(dbh, "create index uuindex on channels (uuid)", NULL);
02082         switch_cache_db_execute_sql(dbh, "create index uuindex2 on channels (call_uuid)", NULL);
02083         switch_cache_db_execute_sql(dbh, "create index callsidx1 on calls (hostname)", NULL);
02084         switch_cache_db_execute_sql(dbh, "create index eruuindex on calls (caller_uuid)", NULL);
02085         switch_cache_db_execute_sql(dbh, "create index eeuuindex on calls (callee_uuid)", NULL);
02086         switch_cache_db_execute_sql(dbh, "create index eeuuindex2 on calls (call_uuid)", NULL);
02087         switch_cache_db_execute_sql(dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL);
02088 
02089 
02090  skip:
02091 
02092         if (sql_manager.manage) {
02093                 if (switch_event_bind_removable("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY,
02094                                                                                 core_event_handler, NULL, &sql_manager.event_node) != SWITCH_STATUS_SUCCESS) {
02095                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind event handler!\n");
02096                 }
02097 
02098                 switch_queue_create(&sql_manager.sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool);
02099                 switch_queue_create(&sql_manager.sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool);
02100         }
02101 
02102         switch_threadattr_create(&thd_attr, sql_manager.memory_pool);
02103         switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
02104         if (sql_manager.manage) {
02105                 switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool);
02106         }
02107         switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool);
02108 
02109         while (sql_manager.manage && !sql_manager.thread_running && --sanity) {
02110                 switch_yield(10000);
02111         }
02112 
02113         if (sql_manager.manage) switch_cache_db_release_db_handle(&dbh);
02114 
02115         return SWITCH_STATUS_SUCCESS;
02116 }

void switch_core_sqldb_stop ( void   ) 

Definition at line 2118 of file switch_core_sqldb.c.

References sql_close(), sql_manager, switch_cache_db_flush_handles(), SWITCH_CHANNEL_LOG, switch_event_unbind(), SWITCH_LOG_DEBUG10, switch_log_printf(), switch_queue_push(), switch_thread_join(), and wake_thread().

Referenced by switch_core_destroy().

02119 {
02120         switch_status_t st;
02121 
02122         switch_event_unbind(&sql_manager.event_node);
02123 
02124         if (sql_manager.thread && sql_manager.thread_running) {
02125 
02126                 if (sql_manager.manage) {
02127                         switch_queue_push(sql_manager.sql_queue[0], NULL);
02128                         switch_queue_push(sql_manager.sql_queue[1], NULL);
02129                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Waiting for unfinished SQL transactions\n");
02130                         wake_thread(0);
02131                 }
02132 
02133                 sql_manager.thread_running = -1;
02134                 switch_thread_join(&st, sql_manager.thread);
02135         }
02136 
02137 
02138         if (sql_manager.thread && sql_manager.db_thread_running) {
02139                 sql_manager.db_thread_running = -1;
02140                 switch_thread_join(&st, sql_manager.db_thread);
02141         }
02142 
02143         switch_cache_db_flush_handles();
02144         sql_close(0);
02145 }

char* switch_sql_concat ( void   ) 

This routine is a variant of the "sprintf()" from the standard C library. The resulting string is written into memory obtained from malloc() so that there is never a possiblity of buffer overflow. This routine also implement some additional formatting options that are useful for constructing SQL statements.

The strings returned by this routine should be freed by calling switch_core_db_free().

All of the usual printf formatting options apply. In addition, there is a "%q" option. q works like s in that it substitutes a null-terminated string from the argument list. But q also doubles every '\'' character. q is designed for use inside a string literal. By doubling each '\'' character it escapes that character and allows it to be inserted into the string.

For example, so some string variable contains text as follows:

char *zText = "It's a happy day!";

We can use this text in an SQL statement as follows:

char *z = switch_core_db_mprintf("INSERT INTO TABLES('%q')", zText); switch_core_db_exec(db, z, callback1, 0, 0); switch_core_db_free(z);

Because the q format string is used, the '\'' character in zText is escaped and the SQL generated is as follows:

INSERT INTO table1 VALUES('It''s a happy day!')

This is correct. Had we used s instead of q, the generated SQL would have looked like this:

INSERT INTO table1 VALUES('It's a happy day!');

This second example is an SQL syntax error. As a general rule you should always use q instead of s when inserting text into a string literal.

Definition at line 2200 of file switch_core_sqldb.c.

References DBTYPE_MSSQL, switch_runtime::odbc_dbtype, and runtime.

02201 {
02202         if(runtime.odbc_dbtype == DBTYPE_MSSQL)
02203                 return "+";
02204 
02205         return "||";
02206 }

static void wake_thread ( int  force  )  [static]

Definition at line 501 of file switch_core_sqldb.c.

References sql_manager, switch_mutex_trylock(), switch_mutex_unlock(), SWITCH_STATUS_SUCCESS, and switch_thread_cond_signal().

Referenced by core_event_handler(), switch_core_sql_db_thread(), and switch_core_sqldb_stop().

00502 {
00503         if (force) {
00504                 switch_thread_cond_signal(sql_manager.cond);
00505                 return;
00506         }
00507 
00508         if (switch_mutex_trylock(sql_manager.cond_mutex) == SWITCH_STATUS_SUCCESS) {
00509                 switch_thread_cond_signal(sql_manager.cond);
00510                 switch_mutex_unlock(sql_manager.cond_mutex);
00511         }
00512 }


Variable Documentation

char basic_calls_sql[] [static]

Definition at line 1793 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

switch_thread_cond_t* cond

Definition at line 71 of file switch_core_sqldb.c.

Referenced by switch_cond_next(), switch_cond_yield(), SWITCH_MODULE_RUNTIME_FUNCTION(), and timer_next().

switch_mutex_t* cond_mutex

Definition at line 72 of file switch_core_sqldb.c.

char create_alias_sql[] [static]

Initial value:

        "CREATE TABLE aliases (\n"
        "   sticky  INTEGER,\n"
        "   alias  VARCHAR(128),\n"
        "   command  VARCHAR(4096),\n"
        "   hostname VARCHAR(256)\n"
        ");\n"

Definition at line 1623 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

char create_calls_sql[] [static]

Initial value:

        "CREATE TABLE calls (\n"
        "   call_uuid  VARCHAR(255),\n"
        "   call_created  VARCHAR(128),\n"
        "   call_created_epoch  INTEGER,\n"
        "   caller_uuid      VARCHAR(256),\n"
        "   callee_uuid      VARCHAR(256),\n"
        "   hostname VARCHAR(256)\n"
        ");\n"

Definition at line 1666 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

char create_channels_sql[] [static]

Definition at line 1631 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

char create_complete_sql[] [static]

Initial value:

        "CREATE TABLE complete (\n"
        "   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"
        "   a7  VARCHAR(128),\n"
        "   a8  VARCHAR(128),\n"
        "   a9  VARCHAR(128),\n"
        "   a10 VARCHAR(128),\n"
        "   hostname VARCHAR(256)\n"
        ");\n"

Definition at line 1607 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

char create_interfaces_sql[] [static]

Initial value:

        "CREATE TABLE interfaces (\n"
        "   type             VARCHAR(128),\n"
        "   name             VARCHAR(1024),\n"
        "   description      VARCHAR(4096),\n"
        "   ikey             VARCHAR(1024),\n"
        "   filename         VARCHAR(4096),\n"
        "   syntax           VARCHAR(4096),\n"
        "   hostname VARCHAR(256)\n"
        ");\n"

Definition at line 1676 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

char create_nat_sql[] [static]

Initial value:

        "CREATE TABLE nat (\n"
        "   sticky  INTEGER,\n"
        "       port    INTEGER,\n"
        "       proto   INTEGER,\n"
        "   hostname VARCHAR(256)\n"
        ");\n"

Definition at line 1696 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

char create_registrations_sql[] [static]

Initial value:

        "CREATE TABLE registrations (\n"
        "   reg_user      VARCHAR(256),\n"
        "   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"

Definition at line 1705 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

char create_tasks_sql[] [static]

Initial value:

        "CREATE TABLE tasks (\n"
        "   task_id             INTEGER,\n"
        "   task_desc           VARCHAR(4096),\n"
        "   task_group          VARCHAR(1024),\n"
        "   task_sql_manager    INTEGER,\n"
        "   hostname VARCHAR(256)\n"
        ");\n"

Definition at line 1687 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

switch_thread_t* db_thread

Definition at line 64 of file switch_core_sqldb.c.

int db_thread_running

Definition at line 66 of file switch_core_sqldb.c.

switch_mutex_t* dbh_mutex

Definition at line 69 of file switch_core_sqldb.c.

char detailed_calls_sql[] [static]

Definition at line 1722 of file switch_core_sqldb.c.

Referenced by switch_core_sqldb_start().

switch_cache_db_handle_t* event_db

Definition at line 59 of file switch_core_sqldb.c.

switch_event_node_t* event_node

Definition at line 62 of file switch_core_sqldb.c.

Referenced by switch_event_bind_removable().

switch_cache_db_handle_t* handle_pool

Definition at line 70 of file switch_core_sqldb.c.

switch_mutex_t* io_mutex

Definition at line 68 of file switch_core_sqldb.c.

Referenced by switch_cache_db_execute_sql(), switch_cache_db_execute_sql2str(), switch_cache_db_execute_sql_callback(), switch_cache_db_execute_sql_real(), switch_cache_db_persistant_execute(), switch_cache_db_persistant_execute_trans(), and switch_cache_db_test_reactive().

switch_bool_t manage

Definition at line 67 of file switch_core_sqldb.c.

switch_memory_pool_t* memory_pool

Definition at line 61 of file switch_core_sqldb.c.

struct { ... } sql_manager [static]

Referenced by _switch_cache_db_get_db_handle(), _switch_core_db_handle(), add_handle(), core_event_handler(), del_handle(), get_handle(), sql_close(), switch_cache_db_release_db_handle(), switch_cache_db_status(), switch_core_add_registration(), switch_core_del_registration(), switch_core_expire_registration(), switch_core_sql_db_thread(), switch_core_sql_thread(), switch_core_sqldb_start(), switch_core_sqldb_stop(), and wake_thread().

switch_queue_t* sql_queue[2]

Definition at line 60 of file switch_core_sqldb.c.

switch_thread_t* thread

Definition at line 63 of file switch_core_sqldb.c.

Referenced by launch_collect_thread(), switch_core_launch_thread(), switch_core_session_launch_thread(), switch_core_session_thread_launch(), switch_ivr_enterprise_originate(), switch_log_init(), switch_log_shutdown(), switch_system_thread(), switch_xml_free_in_thread(), task_thread_loop(), and unicast_thread_launch().

int thread_running

Definition at line 65 of file switch_core_sqldb.c.

uint32_t total_handles

Definition at line 73 of file switch_core_sqldb.c.

uint32_t total_used_handles

Definition at line 74 of file switch_core_sqldb.c.


Generated on Sun May 20 04:00:10 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7