| File: | src/switch_core_sqldb.c |
| Location: | line 420, column 4 |
| Description: | Value stored to 'db_name' is never read |
| 1 | /* |
| 2 | * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application |
| 3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> |
| 4 | * |
| 5 | * Version: MPL 1.1 |
| 6 | * |
| 7 | * The contents of this file are subject to the Mozilla Public License Version |
| 8 | * 1.1 (the "License"); you may not use this file except in compliance with |
| 9 | * the License. You may obtain a copy of the License at |
| 10 | * http://www.mozilla.org/MPL/ |
| 11 | * |
| 12 | * Software distributed under the License is distributed on an "AS IS" basis, |
| 13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 14 | * for the specific language governing rights and limitations under the |
| 15 | * License. |
| 16 | * |
| 17 | * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application |
| 18 | * |
| 19 | * The Initial Developer of the Original Code is |
| 20 | * Anthony Minessale II <anthm@freeswitch.org> |
| 21 | * Portions created by the Initial Developer are Copyright (C) |
| 22 | * the Initial Developer. All Rights Reserved. |
| 23 | * |
| 24 | * Contributor(s): |
| 25 | * |
| 26 | * Anthony Minessale II <anthm@freeswitch.org> |
| 27 | * Michael Jerris <mike@jerris.com> |
| 28 | * Paul D. Tinsley <pdt at jackhammer.org> |
| 29 | * |
| 30 | * |
| 31 | * switch_core_sqldb.c -- Main Core Library (statistics tracker) |
| 32 | * |
| 33 | */ |
| 34 | |
| 35 | #include <switch.h> |
| 36 | #include "private/switch_core_pvt.h" |
| 37 | |
| 38 | #define SWITCH_SQL_QUEUE_LEN100000 100000 |
| 39 | #define SWITCH_SQL_QUEUE_PAUSE_LEN90000 90000 |
| 40 | |
| 41 | struct switch_cache_db_handle { |
| 42 | char name[CACHE_DB_LEN256]; |
| 43 | switch_cache_db_handle_type_t type; |
| 44 | switch_cache_db_native_handle_t native_handle; |
| 45 | time_t last_used; |
| 46 | switch_mutex_t *mutex; |
| 47 | switch_mutex_t *io_mutex; |
| 48 | switch_memory_pool_t *pool; |
| 49 | int32_t flags; |
| 50 | unsigned long hash; |
| 51 | unsigned long thread_hash; |
| 52 | char creator[CACHE_DB_LEN256]; |
| 53 | char last_user[CACHE_DB_LEN256]; |
| 54 | uint32_t use_count; |
| 55 | uint64_t total_used_count; |
| 56 | struct switch_cache_db_handle *next; |
| 57 | }; |
| 58 | |
| 59 | static struct { |
| 60 | switch_memory_pool_t *memory_pool; |
| 61 | switch_thread_t *db_thread; |
| 62 | int db_thread_running; |
| 63 | switch_bool_t manage; |
| 64 | switch_mutex_t *io_mutex; |
| 65 | switch_mutex_t *dbh_mutex; |
| 66 | switch_mutex_t *ctl_mutex; |
| 67 | switch_cache_db_handle_t *handle_pool; |
| 68 | uint32_t total_handles; |
| 69 | uint32_t total_used_handles; |
| 70 | switch_cache_db_handle_t *dbh; |
| 71 | switch_sql_queue_manager_t *qm; |
| 72 | int paused; |
| 73 | } sql_manager; |
| 74 | |
| 75 | |
| 76 | static void switch_core_sqldb_start_thread(void); |
| 77 | static void switch_core_sqldb_stop_thread(void); |
| 78 | |
| 79 | static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t type) |
| 80 | { |
| 81 | switch_cache_db_handle_t *new_dbh = NULL((void*)0); |
| 82 | switch_memory_pool_t *pool = NULL((void*)0); |
| 83 | |
| 84 | switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_sqldb.c" , (const char *)__func__, 84); |
| 85 | new_dbh = switch_core_alloc(pool, sizeof(*new_dbh))switch_core_perform_alloc(pool, sizeof(*new_dbh), "src/switch_core_sqldb.c" , (const char *)__func__, 85); |
| 86 | new_dbh->pool = pool; |
| 87 | new_dbh->type = type; |
| 88 | switch_mutex_init(&new_dbh->mutex, SWITCH_MUTEX_NESTED0x1, new_dbh->pool); |
| 89 | |
| 90 | return new_dbh; |
| 91 | } |
| 92 | |
| 93 | static void add_handle(switch_cache_db_handle_t *dbh, const char *db_str, const char *db_callsite_str, const char *thread_str) |
| 94 | { |
| 95 | switch_ssize_t hlen = -1; |
| 96 | |
| 97 | switch_mutex_lock(sql_manager.dbh_mutex); |
| 98 | |
| 99 | switch_set_string(dbh->creator, db_callsite_str)switch_copy_string(dbh->creator, db_callsite_str, sizeof(dbh ->creator)); |
| 100 | |
| 101 | switch_set_string(dbh->name, db_str)switch_copy_string(dbh->name, db_str, sizeof(dbh->name) ); |
| 102 | dbh->hash = switch_ci_hashfunc_default(db_str, &hlen); |
| 103 | dbh->thread_hash = switch_ci_hashfunc_default(thread_str, &hlen); |
| 104 | |
| 105 | dbh->use_count++; |
| 106 | dbh->total_used_count++; |
| 107 | sql_manager.total_used_handles++; |
| 108 | dbh->next = sql_manager.handle_pool; |
| 109 | |
| 110 | sql_manager.handle_pool = dbh; |
| 111 | sql_manager.total_handles++; |
| 112 | switch_mutex_lock(dbh->mutex); |
| 113 | switch_mutex_unlock(sql_manager.dbh_mutex); |
| 114 | } |
| 115 | |
| 116 | static void del_handle(switch_cache_db_handle_t *dbh) |
| 117 | { |
| 118 | switch_cache_db_handle_t *dbh_ptr, *last = NULL((void*)0); |
| 119 | |
| 120 | switch_mutex_lock(sql_manager.dbh_mutex); |
| 121 | for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { |
| 122 | if (dbh_ptr == dbh) { |
| 123 | if (last) { |
| 124 | last->next = dbh_ptr->next; |
| 125 | } else { |
| 126 | sql_manager.handle_pool = dbh_ptr->next; |
| 127 | } |
| 128 | sql_manager.total_handles--; |
| 129 | break; |
| 130 | } |
| 131 | |
| 132 | last = dbh_ptr; |
| 133 | } |
| 134 | switch_mutex_unlock(sql_manager.dbh_mutex); |
| 135 | } |
| 136 | |
| 137 | static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user_str, const char *thread_str) |
| 138 | { |
| 139 | switch_ssize_t hlen = -1; |
| 140 | unsigned long hash = 0, thread_hash = 0; |
| 141 | switch_cache_db_handle_t *dbh_ptr, *r = NULL((void*)0); |
| 142 | |
| 143 | hash = switch_ci_hashfunc_default(db_str, &hlen); |
| 144 | thread_hash = switch_ci_hashfunc_default(thread_str, &hlen); |
| 145 | |
| 146 | switch_mutex_lock(sql_manager.dbh_mutex); |
| 147 | |
| 148 | for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { |
| 149 | if (dbh_ptr->thread_hash == thread_hash && dbh_ptr->hash == hash && !dbh_ptr->use_count && |
| 150 | !switch_test_flag(dbh_ptr, CDF_PRUNE)((dbh_ptr)->flags & CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { |
| 151 | r = dbh_ptr; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | if (!r) { |
| 156 | for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { |
| 157 | if (dbh_ptr->hash == hash && (dbh_ptr->type != SCDB_TYPE_PGSQL || !dbh_ptr->use_count) && !switch_test_flag(dbh_ptr, CDF_PRUNE)((dbh_ptr)->flags & CDF_PRUNE) && |
| 158 | switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { |
| 159 | r = dbh_ptr; |
| 160 | break; |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | if (r) { |
| 166 | r->use_count++; |
| 167 | r->total_used_count++; |
| 168 | sql_manager.total_used_handles++; |
| 169 | r->hash = switch_ci_hashfunc_default(db_str, &hlen); |
| 170 | r->thread_hash = thread_hash; |
| 171 | switch_set_string(r->last_user, user_str)switch_copy_string(r->last_user, user_str, sizeof(r->last_user )); |
| 172 | } |
| 173 | |
| 174 | switch_mutex_unlock(sql_manager.dbh_mutex); |
| 175 | |
| 176 | return r; |
| 177 | |
| 178 | } |
| 179 | |
| 180 | /*! |
| 181 | \brief Open the default system database |
| 182 | */ |
| 183 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t _switch_core_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) |
| 184 | { |
| 185 | switch_status_t r; |
| 186 | char *dsn; |
| 187 | |
| 188 | if (!sql_manager.manage) { |
| 189 | return SWITCH_STATUS_FALSE; |
| 190 | } |
| 191 | |
| 192 | if (!zstr(runtime.odbc_dsn)_zstr(runtime.odbc_dsn)) { |
| 193 | dsn = runtime.odbc_dsn; |
| 194 | } else if (!zstr(runtime.dbname)_zstr(runtime.dbname)) { |
| 195 | dsn = runtime.dbname; |
| 196 | } else { |
| 197 | dsn = "core"; |
| 198 | } |
| 199 | |
| 200 | if ((r = _switch_cache_db_get_db_handle_dsn(dbh, dsn, file, func, line)) != SWITCH_STATUS_SUCCESS) { |
| 201 | *dbh = NULL((void*)0); |
| 202 | } |
| 203 | |
| 204 | return r; |
| 205 | } |
| 206 | |
| 207 | #define SQL_CACHE_TIMEOUT30 30 |
| 208 | #define SQL_REG_TIMEOUT15 15 |
| 209 | |
| 210 | |
| 211 | static void sql_close(time_t prune) |
| 212 | { |
| 213 | switch_cache_db_handle_t *dbh = NULL((void*)0); |
| 214 | int locked = 0; |
| 215 | int sanity = 10000; |
| 216 | |
| 217 | switch_mutex_lock(sql_manager.dbh_mutex); |
| 218 | top: |
| 219 | locked = 0; |
| 220 | |
| 221 | for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) { |
| 222 | time_t diff = 0; |
| 223 | |
| 224 | if (prune > 0 && prune > dbh->last_used) { |
| 225 | diff = (time_t) prune - dbh->last_used; |
| 226 | } |
| 227 | |
| 228 | if (prune > 0 && (dbh->use_count || (diff < SQL_CACHE_TIMEOUT30 && !switch_test_flag(dbh, CDF_PRUNE)((dbh)->flags & CDF_PRUNE)))) { |
| 229 | continue; |
| 230 | } |
| 231 | |
| 232 | if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) { |
| 233 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 233, ((void*)0), SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", dbh->name); |
| 234 | |
| 235 | switch (dbh->type) { |
| 236 | case SCDB_TYPE_PGSQL: |
| 237 | { |
| 238 | switch_pgsql_handle_destroy(&dbh->native_handle.pgsql_dbh); |
| 239 | } |
| 240 | break; |
| 241 | case SCDB_TYPE_ODBC: |
| 242 | { |
| 243 | switch_odbc_handle_destroy(&dbh->native_handle.odbc_dbh); |
| 244 | } |
| 245 | break; |
| 246 | case SCDB_TYPE_CORE_DB: |
| 247 | { |
| 248 | switch_core_db_close(dbh->native_handle.core_db_dbh); |
| 249 | dbh->native_handle.core_db_dbh = NULL((void*)0); |
| 250 | } |
| 251 | break; |
| 252 | } |
| 253 | |
| 254 | del_handle(dbh); |
| 255 | switch_mutex_unlock(dbh->mutex); |
| 256 | switch_core_destroy_memory_pool(&dbh->pool)switch_core_perform_destroy_memory_pool(&dbh->pool, "src/switch_core_sqldb.c" , (const char *)__func__, 256); |
| 257 | goto top; |
| 258 | |
| 259 | } else { |
| 260 | if (!prune) { |
| 261 | if (!sanity) { |
| 262 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 262, ((void*)0), SWITCH_LOG_CRIT, "SANITY CHECK FAILED! Handle %s (%s;%s) was not properly released.\n", |
| 263 | dbh->name, dbh->creator, dbh->last_user); |
| 264 | } else { |
| 265 | locked++; |
| 266 | } |
| 267 | } |
| 268 | continue; |
| 269 | } |
| 270 | |
| 271 | } |
| 272 | |
| 273 | if (locked) { |
| 274 | if (!prune) { |
| 275 | switch_cond_next(); |
| 276 | if (sanity) sanity--; |
| 277 | } |
| 278 | goto top; |
| 279 | } |
| 280 | |
| 281 | switch_mutex_unlock(sql_manager.dbh_mutex); |
| 282 | } |
| 283 | |
| 284 | |
| 285 | SWITCH_DECLARE(switch_cache_db_handle_type_t)__attribute__((visibility("default"))) switch_cache_db_handle_type_t switch_cache_db_get_type(switch_cache_db_handle_t *dbh) |
| 286 | { |
| 287 | return dbh->type; |
| 288 | } |
| 289 | |
| 290 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_cache_db_flush_handles(void) |
| 291 | { |
| 292 | sql_close(switch_epoch_time_now(NULL((void*)0)) + SQL_CACHE_TIMEOUT30 + 1); |
| 293 | } |
| 294 | |
| 295 | |
| 296 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh) |
| 297 | { |
| 298 | if (dbh && *dbh) { |
| 299 | |
| 300 | switch((*dbh)->type) { |
| 301 | case SCDB_TYPE_PGSQL: |
| 302 | { |
| 303 | switch_pgsql_flush((*dbh)->native_handle.pgsql_dbh); |
| 304 | } |
| 305 | break; |
| 306 | default: |
| 307 | break; |
| 308 | } |
| 309 | |
| 310 | switch_mutex_lock(sql_manager.dbh_mutex); |
| 311 | (*dbh)->last_used = switch_epoch_time_now(NULL((void*)0)); |
| 312 | |
| 313 | (*dbh)->io_mutex = NULL((void*)0); |
| 314 | |
| 315 | if ((*dbh)->use_count) { |
| 316 | if (--(*dbh)->use_count == 0) { |
| 317 | (*dbh)->thread_hash = 1; |
| 318 | } |
| 319 | } |
| 320 | switch_mutex_unlock((*dbh)->mutex); |
| 321 | sql_manager.total_used_handles--; |
| 322 | *dbh = NULL((void*)0); |
| 323 | switch_mutex_unlock(sql_manager.dbh_mutex); |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | |
| 328 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t **dbh) |
| 329 | { |
| 330 | switch_cache_db_release_db_handle(dbh); |
| 331 | } |
| 332 | |
| 333 | |
| 334 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t _switch_cache_db_get_db_handle_dsn(switch_cache_db_handle_t **dbh, const char *dsn, |
| 335 | const char *file, const char *func, int line) |
| 336 | { |
| 337 | switch_cache_db_connection_options_t connection_options = { {0} }; |
| 338 | switch_cache_db_handle_type_t type; |
| 339 | char tmp[256] = ""; |
| 340 | char *p; |
| 341 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 342 | int i; |
| 343 | |
| 344 | if (!strncasecmp(dsn, "pgsql://", 8)) { |
| 345 | type = SCDB_TYPE_PGSQL; |
| 346 | connection_options.pgsql_options.dsn = (char *)(dsn + 8); |
| 347 | } else if (!strncasecmp(dsn, "sqlite://", 9)) { |
| 348 | type = SCDB_TYPE_CORE_DB; |
| 349 | connection_options.core_db_options.db_path = (char *)(dsn + 9); |
| 350 | } else if ((!(i = strncasecmp(dsn, "odbc://", 7))) || strchr(dsn+2, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (dsn+2) && (':') == '\0' ? (char *) __rawmemchr (dsn +2, ':') : __builtin_strchr (dsn+2, ':')))) { |
| 351 | type = SCDB_TYPE_ODBC; |
| 352 | |
| 353 | if (i) { |
| 354 | switch_set_string(tmp, dsn)switch_copy_string(tmp, dsn, sizeof(tmp)); |
| 355 | } else { |
| 356 | switch_set_string(tmp, dsn+7)switch_copy_string(tmp, dsn+7, sizeof(tmp)); |
| 357 | } |
| 358 | |
| 359 | connection_options.odbc_options.dsn = tmp; |
| 360 | |
| 361 | if ((p = strchr(tmp, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (tmp) && (':') == '\0' ? (char *) __rawmemchr (tmp, ':' ) : __builtin_strchr (tmp, ':'))))) { |
| 362 | *p++ = '\0'; |
| 363 | connection_options.odbc_options.user = p; |
| 364 | |
| 365 | if ((p = strchr(connection_options.odbc_options.user, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p (connection_options.odbc_options.user) && (':') == '\0' ? (char *) __rawmemchr (connection_options.odbc_options.user , ':') : __builtin_strchr (connection_options.odbc_options.user , ':'))))) { |
| 366 | *p++ = '\0'; |
| 367 | connection_options.odbc_options.pass = p; |
| 368 | } |
| 369 | } |
| 370 | } else { |
| 371 | type = SCDB_TYPE_CORE_DB; |
| 372 | connection_options.core_db_options.db_path = (char *)dsn; |
| 373 | } |
| 374 | |
| 375 | status = _switch_cache_db_get_db_handle(dbh, type, &connection_options, file, func, line); |
| 376 | |
| 377 | if (status != SWITCH_STATUS_SUCCESS) *dbh = NULL((void*)0); |
| 378 | |
| 379 | return status; |
| 380 | } |
| 381 | |
| 382 | |
| 383 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t _switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh, |
| 384 | switch_cache_db_handle_type_t type, |
| 385 | switch_cache_db_connection_options_t *connection_options, |
| 386 | const char *file, const char *func, int line) |
| 387 | { |
| 388 | switch_thread_id_t self = switch_thread_self(); |
| 389 | char thread_str[CACHE_DB_LEN256] = ""; |
| 390 | char db_str[CACHE_DB_LEN256] = ""; |
| 391 | char db_callsite_str[CACHE_DB_LEN256] = ""; |
| 392 | switch_cache_db_handle_t *new_dbh = NULL((void*)0); |
| 393 | int waiting = 0; |
| 394 | uint32_t yield_len = 100000, total_yield = 0; |
| 395 | |
| 396 | const char *db_name = NULL((void*)0); |
| 397 | const char *odbc_user = NULL((void*)0); |
| 398 | const char *odbc_pass = NULL((void*)0); |
| 399 | const char *db_type = NULL((void*)0); |
| 400 | |
| 401 | while(runtime.max_db_handles && sql_manager.total_handles >= runtime.max_db_handles && sql_manager.total_used_handles >= sql_manager.total_handles) { |
| 402 | if (!waiting++) { |
| 403 | switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_WARNING, "Max handles %u exceeded, blocking....\n", |
| 404 | runtime.max_db_handles); |
| 405 | } |
| 406 | |
| 407 | switch_yield(yield_len)switch_sleep(yield_len);; |
| 408 | total_yield += yield_len; |
| 409 | |
| 410 | if (runtime.db_handle_timeout && total_yield > runtime.db_handle_timeout) { |
| 411 | switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_ERROR, "Error connecting\n"); |
| 412 | *dbh = NULL((void*)0); |
| 413 | return SWITCH_STATUS_FALSE; |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | switch (type) { |
| 418 | case SCDB_TYPE_PGSQL: |
| 419 | { |
| 420 | db_name = connection_options->pgsql_options.dsn; |
Value stored to 'db_name' is never read | |
| 421 | odbc_user = NULL((void*)0); |
| 422 | odbc_pass = NULL((void*)0); |
| 423 | db_type = "pgsql"; |
| 424 | } |
| 425 | case SCDB_TYPE_ODBC: |
| 426 | { |
| 427 | db_name = connection_options->odbc_options.dsn; |
| 428 | odbc_user = connection_options->odbc_options.user; |
| 429 | odbc_pass = connection_options->odbc_options.pass; |
| 430 | db_type = "odbc"; |
| 431 | } |
| 432 | break; |
| 433 | case SCDB_TYPE_CORE_DB: |
| 434 | { |
| 435 | db_name = connection_options->core_db_options.db_path; |
| 436 | odbc_user = NULL((void*)0); |
| 437 | odbc_pass = NULL((void*)0); |
| 438 | db_type = "core_db"; |
| 439 | } |
| 440 | break; |
| 441 | } |
| 442 | |
| 443 | if (!db_name) { |
| 444 | return SWITCH_STATUS_FALSE; |
| 445 | } |
| 446 | |
| 447 | if (odbc_user || odbc_pass) { |
| 448 | snprintf(db_str, sizeof(db_str) - 1, "db=\"%s\";type=\"%s\"user=\"%s\";pass=\"%s\"", db_name, db_type, odbc_user, odbc_pass); |
| 449 | } else { |
| 450 | snprintf(db_str, sizeof(db_str) - 1, "db=\"%s\",type=\"%s\"", db_name, db_type); |
| 451 | } |
| 452 | snprintf(db_callsite_str, sizeof(db_callsite_str) - 1, "%s:%d", file, line); |
| 453 | snprintf(thread_str, sizeof(thread_str) - 1, "thread=\"%lu\"", (unsigned long) (intptr_t) self); |
| 454 | |
| 455 | if ((new_dbh = get_handle(db_str, db_callsite_str, thread_str))) { |
| 456 | switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_DEBUG10, |
| 457 | "Reuse Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type)); |
| 458 | } else { |
| 459 | switch_core_db_t *db = NULL((void*)0); |
| 460 | switch_odbc_handle_t *odbc_dbh = NULL((void*)0); |
| 461 | switch_pgsql_handle_t *pgsql_dbh = NULL((void*)0); |
| 462 | |
| 463 | switch (type) { |
| 464 | case SCDB_TYPE_PGSQL: |
| 465 | { |
| 466 | if (!switch_pgsql_available()) { |
| 467 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 467, ((void*)0), SWITCH_LOG_CRIT, "Failure! PGSQL NOT AVAILABLE! Can't connect to DSN %s\n", connection_options->pgsql_options.dsn); |
| 468 | goto end; |
| 469 | } |
| 470 | |
| 471 | if ((pgsql_dbh = switch_pgsql_handle_new(connection_options->pgsql_options.dsn))) { |
| 472 | if (switch_pgsql_handle_connect(pgsql_dbh) != SWITCH_PGSQL_SUCCESS) { |
| 473 | switch_pgsql_handle_destroy(&pgsql_dbh); |
| 474 | } |
| 475 | } |
| 476 | } |
| 477 | break; |
| 478 | case SCDB_TYPE_ODBC: |
| 479 | { |
| 480 | |
| 481 | if (!switch_odbc_available()) { |
| 482 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 482, ((void*)0), SWITCH_LOG_CRIT, "Failure! ODBC NOT AVAILABLE! Can't connect to DSN %s\n", connection_options->odbc_options.dsn); |
| 483 | goto end; |
| 484 | } |
| 485 | |
| 486 | if ((odbc_dbh = switch_odbc_handle_new(connection_options->odbc_options.dsn, |
| 487 | connection_options->odbc_options.user, connection_options->odbc_options.pass))) { |
| 488 | if (switch_odbc_handle_connect(odbc_dbh) != SWITCH_ODBC_SUCCESS) { |
| 489 | switch_odbc_handle_destroy(&odbc_dbh); |
| 490 | } |
| 491 | } |
| 492 | |
| 493 | |
| 494 | } |
| 495 | break; |
| 496 | case SCDB_TYPE_CORE_DB: |
| 497 | { |
| 498 | db = switch_core_db_open_file(connection_options->core_db_options.db_path); |
| 499 | } |
| 500 | break; |
| 501 | |
| 502 | default: |
| 503 | goto end; |
| 504 | } |
| 505 | |
| 506 | if (!db && !odbc_dbh && !pgsql_dbh) { |
| 507 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 507, ((void*)0), SWITCH_LOG_CRIT, "Failure to connect to %s %s!\n", switch_cache_db_type_name(type), db_name); |
| 508 | goto end; |
| 509 | } |
| 510 | |
| 511 | new_dbh = create_handle(type); |
| 512 | |
| 513 | switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_DEBUG10, |
| 514 | "Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line); |
| 515 | |
| 516 | if (db) { |
| 517 | new_dbh->native_handle.core_db_dbh = db; |
| 518 | } else if (odbc_dbh) { |
| 519 | new_dbh->native_handle.odbc_dbh = odbc_dbh; |
| 520 | } else { |
| 521 | new_dbh->native_handle.pgsql_dbh = pgsql_dbh; |
| 522 | } |
| 523 | |
| 524 | add_handle(new_dbh, db_str, db_callsite_str, thread_str); |
| 525 | } |
| 526 | |
| 527 | end: |
| 528 | |
| 529 | if (new_dbh) { |
| 530 | new_dbh->last_used = switch_epoch_time_now(NULL((void*)0)); |
| 531 | } |
| 532 | |
| 533 | *dbh = new_dbh; |
| 534 | |
| 535 | return *dbh ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; |
| 536 | } |
| 537 | |
| 538 | |
| 539 | static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t *dbh, const char *sql, char **err) |
| 540 | { |
| 541 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 542 | char *errmsg = NULL((void*)0); |
| 543 | char *tmp = NULL((void*)0); |
| 544 | char *type = NULL((void*)0); |
| 545 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 546 | |
| 547 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 548 | |
| 549 | if (err) { |
| 550 | *err = NULL((void*)0); |
| 551 | } |
| 552 | |
| 553 | switch (dbh->type) { |
| 554 | case SCDB_TYPE_PGSQL: |
| 555 | { |
| 556 | type = "PGSQL"; |
| 557 | status = switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, sql, &errmsg)switch_pgsql_handle_exec_detailed("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 557, dbh->native_handle.pgsql_dbh , sql, &errmsg); |
| 558 | } |
| 559 | break; |
| 560 | case SCDB_TYPE_ODBC: |
| 561 | { |
| 562 | type = "ODBC"; |
| 563 | status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL((void*)0), &errmsg); |
| 564 | } |
| 565 | break; |
| 566 | case SCDB_TYPE_CORE_DB: |
| 567 | { |
| 568 | int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, NULL((void*)0), NULL((void*)0), &errmsg); |
| 569 | type = "NATIVE"; |
| 570 | |
| 571 | if (ret == SWITCH_CORE_DB_OK0) { |
| 572 | status = SWITCH_STATUS_SUCCESS; |
| 573 | } |
| 574 | |
| 575 | if (errmsg) { |
| 576 | switch_strdup(tmp, errmsg)(void)(((((tmp) = (__extension__ (__builtin_constant_p ((errmsg )) && ((size_t)(const void *)(((errmsg)) + 1) - (size_t )(const void *)((errmsg)) == 1) ? (((const char *) ((errmsg)) )[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((errmsg)) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (errmsg), __len); __retval; })) : __strdup ((errmsg )))))) ? (void) (0) : __assert_fail ("((tmp) = (__extension__ (__builtin_constant_p ((errmsg)) && ((size_t)(const void *)(((errmsg)) + 1) - (size_t)(const void *)((errmsg)) == 1) ? (((const char *) ((errmsg)))[0] == '\\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ((errmsg)) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, (errmsg), __len); __retval; })) : __strdup ((errmsg)))))" , "src/switch_core_sqldb.c", 576, __PRETTY_FUNCTION__)),tmp); |
| 577 | switch_core_db_free(errmsg); |
| 578 | errmsg = tmp; |
| 579 | } |
| 580 | } |
| 581 | break; |
| 582 | } |
| 583 | |
| 584 | if (errmsg) { |
| 585 | if (!switch_stristr("already exists", errmsg) && !switch_stristr("duplicate key name", errmsg)) { |
| 586 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 586, ((void*)0), SWITCH_LOG_ERROR, "%s SQL ERR [%s]\n%s\n", (type ? type : "Unknown"), errmsg, sql); |
| 587 | } |
| 588 | if (err) { |
| 589 | *err = errmsg; |
| 590 | } else { |
| 591 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | |
| 596 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 597 | |
| 598 | return status; |
| 599 | } |
| 600 | |
| 601 | /** |
| 602 | OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions? |
| 603 | **/ |
| 604 | static switch_status_t switch_cache_db_execute_sql_chunked(switch_cache_db_handle_t *dbh, char *sql, uint32_t chunk_size, char **err) |
| 605 | { |
| 606 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 607 | char *p, *s, *e; |
| 608 | switch_size_t chunk_count; |
| 609 | switch_size_t len; |
| 610 | |
| 611 | switch_assert(chunk_size)((chunk_size) ? (void) (0) : __assert_fail ("chunk_size", "src/switch_core_sqldb.c" , 611, __PRETTY_FUNCTION__)); |
| 612 | |
| 613 | if (err) |
| 614 | *err = NULL((void*)0); |
| 615 | |
| 616 | len = strlen(sql); |
| 617 | |
| 618 | if (chunk_size > len) { |
| 619 | return switch_cache_db_execute_sql_real(dbh, sql, err); |
| 620 | } |
| 621 | |
| 622 | if (!(chunk_count = strlen(sql) / chunk_size)) { |
| 623 | return SWITCH_STATUS_FALSE; |
| 624 | } |
| 625 | |
| 626 | e = end_of_p(sql)(*sql == '\0' ? sql : sql + strlen(sql) - 1); |
| 627 | s = sql; |
| 628 | |
| 629 | while (s && s < e) { |
| 630 | p = s + chunk_size; |
| 631 | |
| 632 | if (p > e) { |
| 633 | p = e; |
| 634 | } |
| 635 | |
| 636 | while (p > s) { |
| 637 | if (*p == '\n' && *(p - 1) == ';') { |
| 638 | *p = '\0'; |
| 639 | *(p - 1) = '\0'; |
| 640 | p++; |
| 641 | break; |
| 642 | } |
| 643 | |
| 644 | p--; |
| 645 | } |
| 646 | |
| 647 | if (p <= s) |
| 648 | break; |
| 649 | |
| 650 | |
| 651 | status = switch_cache_db_execute_sql_real(dbh, s, err); |
| 652 | if (status != SWITCH_STATUS_SUCCESS || (err && *err)) { |
| 653 | break; |
| 654 | } |
| 655 | |
| 656 | s = p; |
| 657 | |
| 658 | } |
| 659 | |
| 660 | return status; |
| 661 | |
| 662 | } |
| 663 | |
| 664 | |
| 665 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, char *sql, char **err) |
| 666 | { |
| 667 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 668 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 669 | |
| 670 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 671 | |
| 672 | switch (dbh->type) { |
| 673 | default: |
| 674 | { |
| 675 | status = switch_cache_db_execute_sql_chunked(dbh, (char *) sql, 32768, err); |
| 676 | } |
| 677 | break; |
| 678 | } |
| 679 | |
| 680 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 681 | |
| 682 | return status; |
| 683 | |
| 684 | } |
| 685 | |
| 686 | |
| 687 | SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh) |
| 688 | { |
| 689 | switch (dbh->type) { |
| 690 | case SCDB_TYPE_CORE_DB: |
| 691 | { |
| 692 | return switch_core_db_changes(dbh->native_handle.core_db_dbh); |
| 693 | } |
| 694 | break; |
| 695 | case SCDB_TYPE_ODBC: |
| 696 | { |
| 697 | return switch_odbc_handle_affected_rows(dbh->native_handle.odbc_dbh); |
| 698 | } |
| 699 | break; |
| 700 | case SCDB_TYPE_PGSQL: |
| 701 | { |
| 702 | return switch_pgsql_handle_affected_rows(dbh->native_handle.pgsql_dbh); |
| 703 | } |
| 704 | break; |
| 705 | } |
| 706 | return 0; |
| 707 | } |
| 708 | |
| 709 | SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_cache_db_load_extension(switch_cache_db_handle_t *dbh, const char *extension) |
| 710 | { |
| 711 | switch (dbh->type) { |
| 712 | case SCDB_TYPE_CORE_DB: |
| 713 | { |
| 714 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 714, ((void*)0), SWITCH_LOG_DEBUG, "try to load extension [%s]!\n", extension); |
| 715 | return switch_core_db_load_extension(dbh->native_handle.core_db_dbh, extension); |
| 716 | } |
| 717 | break; |
| 718 | case SCDB_TYPE_ODBC: |
| 719 | { |
| 720 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 720, ((void*)0), SWITCH_LOG_ERROR, "load extension not supported by type ODBC!\n"); |
| 721 | } |
| 722 | break; |
| 723 | case SCDB_TYPE_PGSQL: |
| 724 | { |
| 725 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 725, ((void*)0), SWITCH_LOG_ERROR, "load extension not supported by type PGSQL!\n"); |
| 726 | } |
| 727 | break; |
| 728 | } |
| 729 | return 0; |
| 730 | } |
| 731 | |
| 732 | |
| 733 | SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_cache_db_execute_sql2str(switch_cache_db_handle_t *dbh, char *sql, char *str, size_t len, char **err) |
| 734 | { |
| 735 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 736 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 737 | |
| 738 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 739 | |
| 740 | memset(str, 0, len); |
| 741 | |
| 742 | switch (dbh->type) { |
| 743 | case SCDB_TYPE_CORE_DB: |
| 744 | { |
| 745 | switch_core_db_stmt_t *stmt; |
| 746 | |
| 747 | if (switch_core_db_prepare(dbh->native_handle.core_db_dbh, sql, -1, &stmt, 0)) { |
| 748 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 748, ((void*)0), SWITCH_LOG_ERROR, "Statement Error [%s]!\n", sql); |
| 749 | goto end; |
| 750 | } else { |
| 751 | int running = 1; |
| 752 | int colcount; |
| 753 | |
| 754 | while (running < 5000) { |
| 755 | int result = switch_core_db_step(stmt); |
| 756 | const unsigned char *txt; |
| 757 | |
| 758 | if (result == SWITCH_CORE_DB_ROW100) { |
| 759 | if ((colcount = switch_core_db_column_count(stmt)) > 0) { |
| 760 | if ((txt = switch_core_db_column_text(stmt, 0))) { |
| 761 | switch_copy_string(str, (char *) txt, len); |
| 762 | status = SWITCH_STATUS_SUCCESS; |
| 763 | } else { |
| 764 | goto end; |
| 765 | } |
| 766 | } |
| 767 | break; |
| 768 | } else if (result == SWITCH_CORE_DB_BUSY5) { |
| 769 | running++; |
| 770 | switch_cond_next(); |
| 771 | continue; |
| 772 | } |
| 773 | break; |
| 774 | } |
| 775 | |
| 776 | switch_core_db_finalize(stmt); |
| 777 | } |
| 778 | } |
| 779 | break; |
| 780 | case SCDB_TYPE_ODBC: |
| 781 | { |
| 782 | status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err); |
| 783 | } |
| 784 | break; |
| 785 | case SCDB_TYPE_PGSQL: |
| 786 | { |
| 787 | status = switch_pgsql_handle_exec_string(dbh->native_handle.pgsql_dbh, sql, str, len, err)switch_pgsql_handle_exec_string_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 787, dbh->native_handle .pgsql_dbh, sql, str, len, err); |
| 788 | } |
| 789 | break; |
| 790 | } |
| 791 | |
| 792 | end: |
| 793 | |
| 794 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 795 | |
| 796 | return status == SWITCH_STATUS_SUCCESS ? str : NULL((void*)0); |
| 797 | |
| 798 | } |
| 799 | |
| 800 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries) |
| 801 | { |
| 802 | char *errmsg = NULL((void*)0); |
| 803 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 804 | uint8_t forever = 0; |
| 805 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 806 | |
| 807 | if (!retries) { |
| 808 | forever = 1; |
| 809 | retries = 1000; |
| 810 | } |
| 811 | |
| 812 | while (retries > 0) { |
| 813 | |
| 814 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 815 | switch_cache_db_execute_sql_real(dbh, sql, &errmsg); |
| 816 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 817 | |
| 818 | |
| 819 | if (errmsg) { |
| 820 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 820, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg); |
| 821 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 822 | switch_yield(100000)switch_sleep(100000);; |
| 823 | retries--; |
| 824 | if (retries == 0 && forever) { |
| 825 | retries = 1000; |
| 826 | continue; |
| 827 | } |
| 828 | } else { |
| 829 | status = SWITCH_STATUS_SUCCESS; |
| 830 | break; |
| 831 | } |
| 832 | } |
| 833 | |
| 834 | return status; |
| 835 | } |
| 836 | |
| 837 | |
| 838 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_cache_db_persistant_execute_trans_full(switch_cache_db_handle_t *dbh, |
| 839 | char *sql, uint32_t retries, |
| 840 | const char *pre_trans_execute, |
| 841 | const char *post_trans_execute, |
| 842 | const char *inner_pre_trans_execute, |
| 843 | const char *inner_post_trans_execute) |
| 844 | { |
| 845 | char *errmsg = NULL((void*)0); |
| 846 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 847 | uint8_t forever = 0; |
| 848 | unsigned begin_retries = 100; |
| 849 | uint8_t again = 0; |
| 850 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 851 | |
| 852 | if (!retries) { |
| 853 | forever = 1; |
| 854 | retries = 1000; |
| 855 | } |
| 856 | |
| 857 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 858 | |
| 859 | if (!zstr(pre_trans_execute)_zstr(pre_trans_execute)) { |
| 860 | switch_cache_db_execute_sql_real(dbh, pre_trans_execute, &errmsg); |
| 861 | if (errmsg) { |
| 862 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 862, ((void*)0), SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", pre_trans_execute, errmsg); |
| 863 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 864 | } |
| 865 | } |
| 866 | |
| 867 | again: |
| 868 | |
| 869 | while (begin_retries > 0) { |
| 870 | again = 0; |
| 871 | |
| 872 | switch(dbh->type) { |
| 873 | case SCDB_TYPE_CORE_DB: |
| 874 | { |
| 875 | switch_cache_db_execute_sql_real(dbh, "BEGIN EXCLUSIVE", &errmsg); |
| 876 | } |
| 877 | break; |
| 878 | case SCDB_TYPE_ODBC: |
| 879 | { |
| 880 | switch_odbc_status_t result; |
| 881 | |
| 882 | if ((result = switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { |
| 883 | char tmp[100]; |
| 884 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); |
| 885 | errmsg = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 886 | } |
| 887 | } |
| 888 | break; |
| 889 | case SCDB_TYPE_PGSQL: |
| 890 | { |
| 891 | switch_pgsql_status_t result; |
| 892 | |
| 893 | if ((result = switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { |
| 894 | char tmp[100]; |
| 895 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); |
| 896 | errmsg = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 897 | } |
| 898 | } |
| 899 | break; |
| 900 | } |
| 901 | |
| 902 | if (errmsg) { |
| 903 | begin_retries--; |
| 904 | if (strstr(errmsg, "cannot start a transaction within a transaction")) { |
| 905 | again = 1; |
| 906 | } else { |
| 907 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 907, ((void*)0), SWITCH_LOG_DEBUG, "SQL Retry [%s]\n", errmsg); |
| 908 | } |
| 909 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 910 | |
| 911 | if (again) { |
| 912 | switch(dbh->type) { |
| 913 | case SCDB_TYPE_CORE_DB: |
| 914 | { |
| 915 | switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL((void*)0)); |
| 916 | } |
| 917 | break; |
| 918 | case SCDB_TYPE_ODBC: |
| 919 | { |
| 920 | switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); |
| 921 | switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); |
| 922 | } |
| 923 | break; |
| 924 | case SCDB_TYPE_PGSQL: |
| 925 | { |
| 926 | switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1); |
| 927 | switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 1); |
| 928 | switch_pgsql_finish_results(dbh->native_handle.pgsql_dbh)switch_pgsql_finish_results_real("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 928, dbh->native_handle.pgsql_dbh ); |
| 929 | } |
| 930 | break; |
| 931 | } |
| 932 | |
| 933 | goto again; |
| 934 | } |
| 935 | |
| 936 | switch_yield(100000)switch_sleep(100000);; |
| 937 | |
| 938 | if (begin_retries == 0) { |
| 939 | goto done; |
| 940 | } |
| 941 | |
| 942 | continue; |
| 943 | } |
| 944 | |
| 945 | break; |
| 946 | } |
| 947 | |
| 948 | |
| 949 | if (!zstr(inner_pre_trans_execute)_zstr(inner_pre_trans_execute)) { |
| 950 | switch_cache_db_execute_sql_real(dbh, inner_pre_trans_execute, &errmsg); |
| 951 | if (errmsg) { |
| 952 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 952, ((void*)0), SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", inner_pre_trans_execute, errmsg); |
| 953 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 954 | } |
| 955 | } |
| 956 | |
| 957 | while (retries > 0) { |
| 958 | |
| 959 | switch_cache_db_execute_sql(dbh, sql, &errmsg); |
| 960 | |
| 961 | if (errmsg) { |
| 962 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 962, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg); |
| 963 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 964 | errmsg = NULL((void*)0); |
| 965 | switch_yield(100000)switch_sleep(100000);; |
| 966 | retries--; |
| 967 | if (retries == 0 && forever) { |
| 968 | retries = 1000; |
| 969 | continue; |
| 970 | } |
| 971 | } else { |
| 972 | status = SWITCH_STATUS_SUCCESS; |
| 973 | break; |
| 974 | } |
| 975 | } |
| 976 | |
| 977 | if (!zstr(inner_post_trans_execute)_zstr(inner_post_trans_execute)) { |
| 978 | switch_cache_db_execute_sql_real(dbh, inner_post_trans_execute, &errmsg); |
| 979 | if (errmsg) { |
| 980 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 980, ((void*)0), SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", inner_post_trans_execute, errmsg); |
| 981 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 982 | } |
| 983 | } |
| 984 | |
| 985 | done: |
| 986 | |
| 987 | switch(dbh->type) { |
| 988 | case SCDB_TYPE_CORE_DB: |
| 989 | { |
| 990 | switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL((void*)0)); |
| 991 | } |
| 992 | break; |
| 993 | case SCDB_TYPE_ODBC: |
| 994 | { |
| 995 | switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); |
| 996 | switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); |
| 997 | } |
| 998 | break; |
| 999 | case SCDB_TYPE_PGSQL: |
| 1000 | { |
| 1001 | switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1); |
| 1002 | switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 1); |
| 1003 | switch_pgsql_finish_results(dbh->native_handle.pgsql_dbh)switch_pgsql_finish_results_real("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 1003, dbh->native_handle.pgsql_dbh ); |
| 1004 | } |
| 1005 | break; |
| 1006 | } |
| 1007 | |
| 1008 | if (!zstr(post_trans_execute)_zstr(post_trans_execute)) { |
| 1009 | switch_cache_db_execute_sql_real(dbh, post_trans_execute, &errmsg); |
| 1010 | if (errmsg) { |
| 1011 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1011, ((void*)0), SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", post_trans_execute, errmsg); |
| 1012 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 1013 | } |
| 1014 | } |
| 1015 | |
| 1016 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 1017 | |
| 1018 | return status; |
| 1019 | } |
| 1020 | |
| 1021 | struct helper { |
| 1022 | switch_core_db_event_callback_func_t callback; |
| 1023 | void *pdata; |
| 1024 | }; |
| 1025 | |
| 1026 | static int helper_callback(void *pArg, int argc, char **argv, char **columnNames) |
| 1027 | { |
| 1028 | struct helper *h = (struct helper *) pArg; |
| 1029 | int r = 0; |
| 1030 | switch_event_t *event; |
| 1031 | |
| 1032 | switch_event_create_array_pair(&event, columnNames, argv, argc); |
| 1033 | |
| 1034 | r = h->callback(h->pdata, event); |
| 1035 | |
| 1036 | switch_event_destroy(&event); |
| 1037 | |
| 1038 | return r; |
| 1039 | } |
| 1040 | |
| 1041 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_cache_db_execute_sql_event_callback(switch_cache_db_handle_t *dbh, |
| 1042 | const char *sql, switch_core_db_event_callback_func_t callback, void *pdata, char **err) |
| 1043 | { |
| 1044 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 1045 | char *errmsg = NULL((void*)0); |
| 1046 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 1047 | struct helper h = {0}; |
| 1048 | |
| 1049 | |
| 1050 | if (err) { |
| 1051 | *err = NULL((void*)0); |
| 1052 | } |
| 1053 | |
| 1054 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 1055 | |
| 1056 | h.callback = callback; |
| 1057 | h.pdata = pdata; |
| 1058 | |
| 1059 | switch (dbh->type) { |
| 1060 | case SCDB_TYPE_PGSQL: |
| 1061 | { |
| 1062 | status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, helper_callback, &h, err)switch_pgsql_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1062, dbh->native_handle .pgsql_dbh, sql, helper_callback, &h, err); |
| 1063 | } |
| 1064 | break; |
| 1065 | case SCDB_TYPE_ODBC: |
| 1066 | { |
| 1067 | status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err)switch_odbc_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1067, dbh->native_handle .odbc_dbh, sql, helper_callback, &h, err); |
| 1068 | } |
| 1069 | break; |
| 1070 | case SCDB_TYPE_CORE_DB: |
| 1071 | { |
| 1072 | int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, helper_callback, &h, &errmsg); |
| 1073 | |
| 1074 | if (ret == SWITCH_CORE_DB_OK0 || ret == SWITCH_CORE_DB_ABORT4) { |
| 1075 | status = SWITCH_STATUS_SUCCESS; |
| 1076 | } |
| 1077 | |
| 1078 | if (errmsg) { |
| 1079 | dbh->last_used = switch_epoch_time_now(NULL((void*)0)) - (SQL_CACHE_TIMEOUT30 * 2); |
| 1080 | if (!strstr(errmsg, "query abort")) { |
| 1081 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1081, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); |
| 1082 | } |
| 1083 | switch_core_db_free(errmsg); |
| 1084 | } |
| 1085 | } |
| 1086 | break; |
| 1087 | } |
| 1088 | |
| 1089 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 1090 | |
| 1091 | return status; |
| 1092 | } |
| 1093 | |
| 1094 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_cache_db_execute_sql_event_callback_err(switch_cache_db_handle_t *dbh, const char *sql, |
| 1095 | switch_core_db_event_callback_func_t callback, |
| 1096 | switch_core_db_err_callback_func_t err_callback, |
| 1097 | void *pdata, char **err) |
| 1098 | { |
| 1099 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 1100 | char *errmsg = NULL((void*)0); |
| 1101 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 1102 | struct helper h; |
| 1103 | |
| 1104 | |
| 1105 | if (err) { |
| 1106 | *err = NULL((void*)0); |
| 1107 | } |
| 1108 | |
| 1109 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 1110 | |
| 1111 | h.callback = callback; |
| 1112 | h.pdata = pdata; |
| 1113 | |
| 1114 | switch (dbh->type) { |
| 1115 | case SCDB_TYPE_PGSQL: |
| 1116 | { |
| 1117 | status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, helper_callback, &h, err)switch_pgsql_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1117, dbh->native_handle .pgsql_dbh, sql, helper_callback, &h, err); |
| 1118 | if (err && *err) { |
| 1119 | (*err_callback)(pdata, (const char*)*err); |
| 1120 | } |
| 1121 | } |
| 1122 | break; |
| 1123 | case SCDB_TYPE_ODBC: |
| 1124 | { |
| 1125 | status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err)switch_odbc_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1125, dbh->native_handle .odbc_dbh, sql, helper_callback, &h, err); |
| 1126 | if (err && *err) { |
| 1127 | (*err_callback)(pdata, (const char*)*err); |
| 1128 | } |
| 1129 | } |
| 1130 | break; |
| 1131 | case SCDB_TYPE_CORE_DB: |
| 1132 | { |
| 1133 | int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, helper_callback, &h, &errmsg); |
| 1134 | |
| 1135 | if (ret == SWITCH_CORE_DB_OK0 || ret == SWITCH_CORE_DB_ABORT4) { |
| 1136 | status = SWITCH_STATUS_SUCCESS; |
| 1137 | } |
| 1138 | |
| 1139 | if (errmsg) { |
| 1140 | dbh->last_used = switch_epoch_time_now(NULL((void*)0)) - (SQL_CACHE_TIMEOUT30 * 2); |
| 1141 | if (!strstr(errmsg, "query abort")) { |
| 1142 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1142, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); |
| 1143 | } |
| 1144 | } |
| 1145 | if ((ret == SWITCH_CORE_DB_ABORT4 || errmsg) && err_callback) { |
| 1146 | (*err_callback)(pdata, errmsg); |
| 1147 | } |
| 1148 | if (errmsg) { |
| 1149 | switch_core_db_free(errmsg); |
| 1150 | } |
| 1151 | } |
| 1152 | break; |
| 1153 | } |
| 1154 | |
| 1155 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 1156 | |
| 1157 | return status; |
| 1158 | } |
| 1159 | |
| 1160 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, |
| 1161 | const char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err) |
| 1162 | { |
| 1163 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 1164 | char *errmsg = NULL((void*)0); |
| 1165 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 1166 | |
| 1167 | if (err) { |
| 1168 | *err = NULL((void*)0); |
| 1169 | } |
| 1170 | |
| 1171 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 1172 | |
| 1173 | |
| 1174 | switch (dbh->type) { |
| 1175 | case SCDB_TYPE_PGSQL: |
| 1176 | { |
| 1177 | status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, callback, pdata, err)switch_pgsql_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1177, dbh->native_handle .pgsql_dbh, sql, callback, pdata, err); |
| 1178 | } |
| 1179 | break; |
| 1180 | case SCDB_TYPE_ODBC: |
| 1181 | { |
| 1182 | status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err)switch_odbc_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1182, dbh->native_handle .odbc_dbh, sql, callback, pdata, err); |
| 1183 | } |
| 1184 | break; |
| 1185 | case SCDB_TYPE_CORE_DB: |
| 1186 | { |
| 1187 | int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, callback, pdata, &errmsg); |
| 1188 | |
| 1189 | if (ret == SWITCH_CORE_DB_OK0 || ret == SWITCH_CORE_DB_ABORT4) { |
| 1190 | status = SWITCH_STATUS_SUCCESS; |
| 1191 | } |
| 1192 | |
| 1193 | if (errmsg) { |
| 1194 | dbh->last_used = switch_epoch_time_now(NULL((void*)0)) - (SQL_CACHE_TIMEOUT30 * 2); |
| 1195 | if (!strstr(errmsg, "query abort")) { |
| 1196 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1196, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); |
| 1197 | } |
| 1198 | switch_core_db_free(errmsg); |
| 1199 | } |
| 1200 | } |
| 1201 | break; |
| 1202 | } |
| 1203 | |
| 1204 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 1205 | |
| 1206 | return status; |
| 1207 | } |
| 1208 | |
| 1209 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_cache_db_execute_sql_callback_err(switch_cache_db_handle_t *dbh, const char *sql, |
| 1210 | switch_core_db_callback_func_t callback, |
| 1211 | switch_core_db_err_callback_func_t err_callback, void *pdata, char **err) |
| 1212 | { |
| 1213 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 1214 | char *errmsg = NULL((void*)0); |
| 1215 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 1216 | |
| 1217 | if (err) { |
| 1218 | *err = NULL((void*)0); |
| 1219 | } |
| 1220 | |
| 1221 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 1222 | |
| 1223 | |
| 1224 | switch (dbh->type) { |
| 1225 | case SCDB_TYPE_PGSQL: |
| 1226 | { |
| 1227 | status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, callback, pdata, err)switch_pgsql_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1227, dbh->native_handle .pgsql_dbh, sql, callback, pdata, err); |
| 1228 | if (err && *err) { |
| 1229 | (*err_callback)(pdata, (const char*)*err); |
| 1230 | } |
| 1231 | } |
| 1232 | break; |
| 1233 | case SCDB_TYPE_ODBC: |
| 1234 | { |
| 1235 | status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err)switch_odbc_handle_callback_exec_detailed("src/switch_core_sqldb.c" , (char * )(const char *)__func__, 1235, dbh->native_handle .odbc_dbh, sql, callback, pdata, err); |
| 1236 | if (err && *err) { |
| 1237 | (*err_callback)(pdata, (const char*)*err); |
| 1238 | } |
| 1239 | } |
| 1240 | break; |
| 1241 | case SCDB_TYPE_CORE_DB: |
| 1242 | { |
| 1243 | int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, callback, pdata, &errmsg); |
| 1244 | |
| 1245 | if (ret == SWITCH_CORE_DB_OK0 || ret == SWITCH_CORE_DB_ABORT4) { |
| 1246 | status = SWITCH_STATUS_SUCCESS; |
| 1247 | } |
| 1248 | |
| 1249 | if (errmsg) { |
| 1250 | dbh->last_used = switch_epoch_time_now(NULL((void*)0)) - (SQL_CACHE_TIMEOUT30 * 2); |
| 1251 | if (!strstr(errmsg, "query abort")) { |
| 1252 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1252, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); |
| 1253 | } |
| 1254 | } |
| 1255 | if ((ret == SWITCH_CORE_DB_ABORT4 || errmsg) && err_callback) { |
| 1256 | (*err_callback)(pdata, errmsg); |
| 1257 | } |
| 1258 | if (errmsg) { |
| 1259 | switch_core_db_free(errmsg); |
| 1260 | } |
| 1261 | } |
| 1262 | break; |
| 1263 | } |
| 1264 | |
| 1265 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 1266 | |
| 1267 | return status; |
| 1268 | } |
| 1269 | |
| 1270 | /*! |
| 1271 | * \brief Performs test_sql and if it fails performs drop_sql and reactive_sql. |
| 1272 | * |
| 1273 | * If auto-clear-sql is disabled, then this function will do nothing and it is |
| 1274 | * assumed that the queries are not needed. If auto-create-schemas is disabled, |
| 1275 | * then just test_sql is executed, but drop_sql and reactive_sql are not. |
| 1276 | * |
| 1277 | * Otherwise, test_sql gets executed. If that succeeds, then there is nothing to |
| 1278 | * do. Otherwise drop_sql is executed (its result is ignored) and then finally |
| 1279 | * reactive_sql is executed. |
| 1280 | * |
| 1281 | * \return If auto-create-schemas is enabled, SWITCH_TRUE is returned if |
| 1282 | * test_sql succeeds, SWITCH_FALSE otherwise. If reactive_sql is executed |
| 1283 | * successfully SWITCH_TRUE is returned, otherwise SWITCH_FALSE is returned. |
| 1284 | */ |
| 1285 | SWITCH_DECLARE(switch_bool_t)__attribute__((visibility("default"))) switch_bool_t switch_cache_db_test_reactive(switch_cache_db_handle_t *dbh, |
| 1286 | const char *test_sql, const char *drop_sql, const char *reactive_sql) |
| 1287 | { |
| 1288 | switch_bool_t r = SWITCH_TRUE; |
| 1289 | switch_mutex_t *io_mutex = dbh->io_mutex; |
| 1290 | |
| 1291 | switch_assert(test_sql != NULL)((test_sql != ((void*)0)) ? (void) (0) : __assert_fail ("test_sql != ((void*)0)" , "src/switch_core_sqldb.c", 1291, __PRETTY_FUNCTION__)); |
| 1292 | switch_assert(reactive_sql != NULL)((reactive_sql != ((void*)0)) ? (void) (0) : __assert_fail ("reactive_sql != ((void*)0)" , "src/switch_core_sqldb.c", 1292, __PRETTY_FUNCTION__)); |
| 1293 | |
| 1294 | if (!switch_test_flag((&runtime), SCF_CLEAR_SQL)(((&runtime))->flags & SCF_CLEAR_SQL)) { |
| 1295 | return SWITCH_TRUE; |
| 1296 | } |
| 1297 | |
| 1298 | if (!switch_test_flag((&runtime), SCF_AUTO_SCHEMAS)(((&runtime))->flags & SCF_AUTO_SCHEMAS)) { |
| 1299 | switch_status_t status = switch_cache_db_execute_sql(dbh, (char *)test_sql, NULL((void*)0)); |
| 1300 | |
| 1301 | return (status == SWITCH_STATUS_SUCCESS) ? SWITCH_TRUE : SWITCH_FALSE; |
| 1302 | } |
| 1303 | |
| 1304 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 1305 | |
| 1306 | switch (dbh->type) { |
| 1307 | case SCDB_TYPE_PGSQL: |
| 1308 | { |
| 1309 | if (switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, test_sql, NULL)switch_pgsql_handle_exec_detailed("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 1309, dbh->native_handle.pgsql_dbh , test_sql, ((void*)0)) != SWITCH_PGSQL_SUCCESS) { |
| 1310 | if (drop_sql) { |
| 1311 | switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, drop_sql, NULL)switch_pgsql_handle_exec_detailed("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 1311, dbh->native_handle.pgsql_dbh , drop_sql, ((void*)0)); |
| 1312 | } |
| 1313 | r = switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, reactive_sql, NULL)switch_pgsql_handle_exec_detailed("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 1313, dbh->native_handle.pgsql_dbh , reactive_sql, ((void*)0)) == SWITCH_PGSQL_SUCCESS; |
| 1314 | } |
| 1315 | } |
| 1316 | break; |
| 1317 | case SCDB_TYPE_ODBC: |
| 1318 | { |
| 1319 | if (switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, test_sql, NULL((void*)0), NULL((void*)0)) != SWITCH_ODBC_SUCCESS) { |
| 1320 | if (drop_sql) { |
| 1321 | switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, drop_sql, NULL((void*)0), NULL((void*)0)); |
| 1322 | } |
| 1323 | r = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, reactive_sql, NULL((void*)0), NULL((void*)0)) == SWITCH_ODBC_SUCCESS; |
| 1324 | } |
| 1325 | } |
| 1326 | break; |
| 1327 | case SCDB_TYPE_CORE_DB: |
| 1328 | { |
| 1329 | char *errmsg = NULL((void*)0); |
| 1330 | switch_core_db_exec(dbh->native_handle.core_db_dbh, test_sql, NULL((void*)0), NULL((void*)0), &errmsg); |
| 1331 | |
| 1332 | if (errmsg) { |
| 1333 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1333, ((void*)0), SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\nAuto Generating Table!\n", errmsg, test_sql); |
| 1334 | switch_core_db_free(errmsg); |
| 1335 | errmsg = NULL((void*)0); |
| 1336 | if (drop_sql) { |
| 1337 | switch_core_db_exec(dbh->native_handle.core_db_dbh, drop_sql, NULL((void*)0), NULL((void*)0), &errmsg); |
| 1338 | } |
| 1339 | if (errmsg) { |
| 1340 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1340, ((void*)0), SWITCH_LOG_DEBUG, "Ignoring SQL ERR [%s]\n[%s]\n", errmsg, drop_sql); |
| 1341 | switch_core_db_free(errmsg); |
| 1342 | errmsg = NULL((void*)0); |
| 1343 | } |
| 1344 | switch_core_db_exec(dbh->native_handle.core_db_dbh, reactive_sql, NULL((void*)0), NULL((void*)0), &errmsg); |
| 1345 | if (errmsg) { |
| 1346 | r = SWITCH_FALSE; |
| 1347 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1347, ((void*)0), SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\n", errmsg, reactive_sql); |
| 1348 | switch_core_db_free(errmsg); |
| 1349 | errmsg = NULL((void*)0); |
| 1350 | } else { |
| 1351 | r = SWITCH_TRUE; |
| 1352 | } |
| 1353 | } |
| 1354 | } |
| 1355 | break; |
| 1356 | } |
| 1357 | |
| 1358 | |
| 1359 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 1360 | |
| 1361 | return r; |
| 1362 | } |
| 1363 | |
| 1364 | |
| 1365 | static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *thread, void *obj) |
| 1366 | { |
| 1367 | int sec = 0, reg_sec = 0;; |
| 1368 | |
| 1369 | sql_manager.db_thread_running = 1; |
| 1370 | |
| 1371 | while (sql_manager.db_thread_running == 1) { |
| 1372 | if (++sec == SQL_CACHE_TIMEOUT30) { |
| 1373 | sql_close(switch_epoch_time_now(NULL((void*)0))); |
| 1374 | sec = 0; |
| 1375 | } |
| 1376 | |
| 1377 | if (switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL) && ++reg_sec == SQL_REG_TIMEOUT15) { |
| 1378 | switch_core_expire_registration(0); |
| 1379 | reg_sec = 0; |
| 1380 | } |
| 1381 | switch_yield(1000000)switch_sleep(1000000);; |
| 1382 | } |
| 1383 | |
| 1384 | |
| 1385 | return NULL((void*)0); |
| 1386 | } |
| 1387 | |
| 1388 | |
| 1389 | static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, void *obj); |
| 1390 | |
| 1391 | struct switch_sql_queue_manager { |
| 1392 | const char *name; |
| 1393 | switch_cache_db_handle_t *event_db; |
| 1394 | switch_queue_t **sql_queue; |
| 1395 | uint32_t *pre_written; |
| 1396 | uint32_t *written; |
| 1397 | uint32_t numq; |
| 1398 | char *dsn; |
| 1399 | switch_thread_t *thread; |
| 1400 | int thread_running; |
| 1401 | switch_thread_cond_t *cond; |
| 1402 | switch_mutex_t *cond_mutex; |
| 1403 | switch_mutex_t *cond2_mutex; |
| 1404 | switch_mutex_t *mutex; |
| 1405 | char *pre_trans_execute; |
| 1406 | char *post_trans_execute; |
| 1407 | char *inner_pre_trans_execute; |
| 1408 | char *inner_post_trans_execute; |
| 1409 | switch_memory_pool_t *pool; |
| 1410 | uint32_t max_trans; |
| 1411 | uint32_t confirm; |
| 1412 | uint8_t paused; |
| 1413 | }; |
| 1414 | |
| 1415 | static int qm_wake(switch_sql_queue_manager_t *qm) |
| 1416 | { |
| 1417 | switch_status_t status; |
| 1418 | int tries = 0; |
| 1419 | |
| 1420 | top: |
| 1421 | |
| 1422 | status = switch_mutex_trylock(qm->cond_mutex); |
| 1423 | |
| 1424 | if (status == SWITCH_STATUS_SUCCESS) { |
| 1425 | switch_thread_cond_signal(qm->cond); |
| 1426 | switch_mutex_unlock(qm->cond_mutex); |
| 1427 | return 1; |
| 1428 | } else { |
| 1429 | if (switch_mutex_trylock(qm->cond2_mutex) == SWITCH_STATUS_SUCCESS) { |
| 1430 | switch_mutex_unlock(qm->cond2_mutex); |
| 1431 | } else { |
| 1432 | if (++tries < 10) { |
| 1433 | switch_cond_next(); |
| 1434 | goto top; |
| 1435 | } |
| 1436 | } |
| 1437 | } |
| 1438 | |
| 1439 | return 0; |
| 1440 | } |
| 1441 | |
| 1442 | static uint32_t qm_ttl(switch_sql_queue_manager_t *qm) |
| 1443 | { |
| 1444 | uint32_t ttl = 0; |
| 1445 | uint32_t i; |
| 1446 | |
| 1447 | for (i = 0; i < qm->numq; i++) { |
| 1448 | ttl += switch_queue_size(qm->sql_queue[i]); |
| 1449 | } |
| 1450 | |
| 1451 | return ttl; |
| 1452 | } |
| 1453 | |
| 1454 | struct db_job { |
| 1455 | switch_sql_queue_manager_t *qm; |
| 1456 | char *sql; |
| 1457 | switch_core_db_callback_func_t callback; |
| 1458 | switch_core_db_err_callback_func_t err_callback; |
| 1459 | switch_core_db_event_callback_func_t event_callback; |
| 1460 | switch_core_db_err_callback_func_t event_err_callback; |
| 1461 | void *pdata; |
| 1462 | int event; |
| 1463 | switch_memory_pool_t *pool; |
| 1464 | }; |
| 1465 | |
| 1466 | static void *SWITCH_THREAD_FUNC sql_in_thread (switch_thread_t *thread, void *obj) |
| 1467 | { |
| 1468 | struct db_job *job = (struct db_job *) obj; |
| 1469 | switch_memory_pool_t *pool = job->pool; |
| 1470 | char *err = NULL((void*)0); |
| 1471 | switch_cache_db_handle_t *dbh; |
| 1472 | |
| 1473 | |
| 1474 | if (switch_cache_db_get_db_handle_dsn(&dbh, job->qm->dsn)_switch_cache_db_get_db_handle_dsn(&dbh, job->qm->dsn , "src/switch_core_sqldb.c", (const char *)__func__, 1474) != SWITCH_STATUS_SUCCESS) { |
| 1475 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1475, ((void*)0), SWITCH_LOG_ERROR, "Cannot connect DSN %s\n", job->qm->dsn); |
| 1476 | return NULL((void*)0); |
| 1477 | } |
| 1478 | |
| 1479 | if (job->callback && !job->err_callback) { |
| 1480 | switch_cache_db_execute_sql_callback(dbh, job->sql, job->callback, job->pdata, &err); |
| 1481 | } else if (job->callback && job->err_callback) { |
| 1482 | switch_cache_db_execute_sql_callback_err(dbh, job->sql, job->callback, job->err_callback, job->pdata, &err); |
| 1483 | } else if (job->event_callback && !job->event_err_callback) { |
| 1484 | switch_cache_db_execute_sql_event_callback(dbh, job->sql, job->event_callback, job->pdata, &err); |
| 1485 | } else if (job->event_callback && job->event_err_callback) { |
| 1486 | switch_cache_db_execute_sql_event_callback_err(dbh, job->sql, job->event_callback, job->event_err_callback, job->pdata, &err); |
| 1487 | } |
| 1488 | |
| 1489 | if (err) { |
| 1490 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1490, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", job->sql, err); |
| 1491 | switch_safe_free(err)if (err) {free(err);err=((void*)0);}; |
| 1492 | } |
| 1493 | |
| 1494 | switch_cache_db_release_db_handle(&dbh); |
| 1495 | |
| 1496 | if (pool) { |
| 1497 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_sqldb.c" , (const char *)__func__, 1497); |
| 1498 | } |
| 1499 | |
| 1500 | return NULL((void*)0); |
| 1501 | } |
| 1502 | |
| 1503 | static switch_thread_data_t *new_job(switch_sql_queue_manager_t *qm, const char *sql, |
| 1504 | switch_core_db_callback_func_t callback, |
| 1505 | switch_core_db_err_callback_func_t err_callback, |
| 1506 | switch_core_db_event_callback_func_t event_callback, |
| 1507 | switch_core_db_err_callback_func_t event_err_callback, |
| 1508 | void *pdata) |
| 1509 | { |
| 1510 | switch_memory_pool_t *pool; |
| 1511 | switch_thread_data_t *td; |
| 1512 | struct db_job *job; |
| 1513 | switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_sqldb.c" , (const char *)__func__, 1513); |
| 1514 | |
| 1515 | td = switch_core_alloc(pool, sizeof(*td))switch_core_perform_alloc(pool, sizeof(*td), "src/switch_core_sqldb.c" , (const char *)__func__, 1515); |
| 1516 | job = switch_core_alloc(pool, sizeof(*job))switch_core_perform_alloc(pool, sizeof(*job), "src/switch_core_sqldb.c" , (const char *)__func__, 1516); |
| 1517 | |
| 1518 | td->func = sql_in_thread; |
| 1519 | td->obj = job; |
| 1520 | |
| 1521 | job->sql = switch_core_strdup(pool, sql)switch_core_perform_strdup(pool, sql, "src/switch_core_sqldb.c" , (const char *)__func__, 1521); |
| 1522 | job->qm = qm; |
| 1523 | |
| 1524 | if (callback) { |
| 1525 | job->callback = callback; |
| 1526 | job->err_callback = err_callback; |
| 1527 | } else if (event_callback) { |
| 1528 | job->event_callback = event_callback; |
| 1529 | job->event_err_callback = event_err_callback; |
| 1530 | } |
| 1531 | |
| 1532 | job->pdata = pdata; |
| 1533 | job->pool = pool; |
| 1534 | |
| 1535 | return td; |
| 1536 | } |
| 1537 | |
| 1538 | |
| 1539 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_sql_queue_manager_execute_sql_callback(switch_sql_queue_manager_t *qm, |
| 1540 | const char *sql, switch_core_db_callback_func_t callback, void *pdata) |
| 1541 | { |
| 1542 | |
| 1543 | switch_thread_data_t *td; |
| 1544 | if ((td = new_job(qm, sql, callback, NULL((void*)0), NULL((void*)0), NULL((void*)0), pdata))) { |
| 1545 | switch_thread_pool_launch_thread(&td); |
| 1546 | } |
| 1547 | } |
| 1548 | |
| 1549 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_sql_queue_manager_execute_sql_callback_err(switch_sql_queue_manager_t *qm, const char *sql, |
| 1550 | switch_core_db_callback_func_t callback, |
| 1551 | switch_core_db_err_callback_func_t err_callback, void *pdata) |
| 1552 | { |
| 1553 | |
| 1554 | switch_thread_data_t *td; |
| 1555 | if ((td = new_job(qm, sql, callback, err_callback, NULL((void*)0), NULL((void*)0), pdata))) { |
| 1556 | switch_thread_pool_launch_thread(&td); |
| 1557 | } |
| 1558 | } |
| 1559 | |
| 1560 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_sql_queue_manager_execute_sql_event_callback(switch_sql_queue_manager_t *qm, |
| 1561 | const char *sql, switch_core_db_event_callback_func_t callback, void *pdata) |
| 1562 | { |
| 1563 | |
| 1564 | switch_thread_data_t *td; |
| 1565 | if ((td = new_job(qm, sql, NULL((void*)0), NULL((void*)0), callback, NULL((void*)0), pdata))) { |
| 1566 | switch_thread_pool_launch_thread(&td); |
| 1567 | } |
| 1568 | } |
| 1569 | |
| 1570 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_sql_queue_manager_execute_sql_event_callback_err(switch_sql_queue_manager_t *qm, const char *sql, |
| 1571 | switch_core_db_event_callback_func_t callback, |
| 1572 | switch_core_db_err_callback_func_t err_callback, |
| 1573 | void *pdata) |
| 1574 | { |
| 1575 | |
| 1576 | switch_thread_data_t *td; |
| 1577 | if ((td = new_job(qm, sql, NULL((void*)0), NULL((void*)0), callback, err_callback, pdata))) { |
| 1578 | switch_thread_pool_launch_thread(&td); |
| 1579 | } |
| 1580 | } |
| 1581 | |
| 1582 | |
| 1583 | static void do_flush(switch_sql_queue_manager_t *qm, int i, switch_cache_db_handle_t *dbh) |
| 1584 | { |
| 1585 | void *pop = NULL((void*)0); |
| 1586 | switch_queue_t *q = qm->sql_queue[i]; |
| 1587 | |
| 1588 | switch_mutex_lock(qm->mutex); |
| 1589 | while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) { |
| 1590 | if (pop) { |
| 1591 | if (dbh) { |
| 1592 | switch_cache_db_execute_sql(dbh, (char *) pop, NULL((void*)0)); |
| 1593 | } |
| 1594 | switch_safe_free(pop)if (pop) {free(pop);pop=((void*)0);}; |
| 1595 | } |
| 1596 | } |
| 1597 | switch_mutex_unlock(qm->mutex); |
| 1598 | |
| 1599 | } |
| 1600 | |
| 1601 | |
| 1602 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_sql_queue_manager_resume(switch_sql_queue_manager_t *qm) |
| 1603 | { |
| 1604 | switch_mutex_lock(qm->mutex); |
| 1605 | qm->paused = 0; |
| 1606 | switch_mutex_unlock(qm->mutex); |
| 1607 | |
| 1608 | qm_wake(qm); |
| 1609 | |
| 1610 | } |
| 1611 | |
| 1612 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_sql_queue_manager_pause(switch_sql_queue_manager_t *qm, switch_bool_t flush) |
| 1613 | { |
| 1614 | uint32_t i; |
| 1615 | |
| 1616 | switch_mutex_lock(qm->mutex); |
| 1617 | qm->paused = 1; |
| 1618 | switch_mutex_unlock(qm->mutex); |
| 1619 | |
| 1620 | if (flush) { |
| 1621 | for(i = 0; i < qm->numq; i++) { |
| 1622 | do_flush(qm, i, NULL((void*)0)); |
| 1623 | } |
| 1624 | } |
| 1625 | |
| 1626 | } |
| 1627 | |
| 1628 | SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_sql_queue_manager_size(switch_sql_queue_manager_t *qm, uint32_t index) |
| 1629 | { |
| 1630 | int size = 0; |
| 1631 | |
| 1632 | switch_mutex_lock(qm->mutex); |
| 1633 | if (index < qm->numq) { |
| 1634 | size = switch_queue_size(qm->sql_queue[index]); |
| 1635 | } |
| 1636 | switch_mutex_unlock(qm->mutex); |
| 1637 | |
| 1638 | return size; |
| 1639 | } |
| 1640 | |
| 1641 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm) |
| 1642 | { |
| 1643 | switch_status_t status = SWITCH_STATUS_FALSE; |
| 1644 | uint32_t i, sanity = 100; |
| 1645 | |
| 1646 | if (qm->thread_running == 1) { |
| 1647 | qm->thread_running = -1; |
| 1648 | |
| 1649 | while(--sanity && qm->thread_running == -1) { |
| 1650 | for(i = 0; i < qm->numq; i++) { |
| 1651 | switch_queue_push(qm->sql_queue[i], NULL((void*)0)); |
| 1652 | switch_queue_interrupt_all(qm->sql_queue[i]); |
| 1653 | } |
| 1654 | qm_wake(qm); |
| 1655 | |
| 1656 | if (qm->thread_running == -1) { |
| 1657 | switch_yield(100000)switch_sleep(100000);; |
| 1658 | } |
| 1659 | } |
| 1660 | status = SWITCH_STATUS_SUCCESS; |
| 1661 | } |
| 1662 | |
| 1663 | if (qm->thread) { |
| 1664 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1664, ((void*)0), SWITCH_LOG_INFO, "%s Stopping SQL thread.\n", qm->name); |
| 1665 | qm_wake(qm); |
| 1666 | switch_thread_join(&status, qm->thread); |
| 1667 | qm->thread = NULL((void*)0); |
| 1668 | status = SWITCH_STATUS_SUCCESS; |
| 1669 | } |
| 1670 | |
| 1671 | return status; |
| 1672 | } |
| 1673 | |
| 1674 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm) |
| 1675 | { |
| 1676 | switch_threadattr_t *thd_attr; |
| 1677 | |
| 1678 | if (!qm->thread_running) { |
| 1679 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1679, ((void*)0), SWITCH_LOG_INFO, "%s Starting SQL thread.\n", qm->name); |
| 1680 | switch_threadattr_create(&thd_attr, qm->pool); |
| 1681 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); |
| 1682 | switch_threadattr_priority_set(thd_attr, SWITCH_PRI_NORMAL); |
| 1683 | switch_thread_create(&qm->thread, thd_attr, switch_user_sql_thread, qm, qm->pool); |
| 1684 | return SWITCH_STATUS_SUCCESS; |
| 1685 | } |
| 1686 | |
| 1687 | return SWITCH_STATUS_FALSE; |
| 1688 | } |
| 1689 | |
| 1690 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp) |
| 1691 | { |
| 1692 | switch_sql_queue_manager_t *qm; |
| 1693 | switch_status_t status = SWITCH_STATUS_SUCCESS; |
| 1694 | switch_memory_pool_t *pool; |
| 1695 | uint32_t i; |
| 1696 | |
| 1697 | switch_assert(qmp)((qmp) ? (void) (0) : __assert_fail ("qmp", "src/switch_core_sqldb.c" , 1697, __PRETTY_FUNCTION__)); |
| 1698 | qm = *qmp; |
| 1699 | *qmp = NULL((void*)0); |
| 1700 | |
| 1701 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1701, ((void*)0), SWITCH_LOG_INFO, "%s Destroying SQL queue.\n", qm->name); |
| 1702 | |
| 1703 | switch_sql_queue_manager_stop(qm); |
| 1704 | |
| 1705 | |
| 1706 | |
| 1707 | for(i = 0; i < qm->numq; i++) { |
| 1708 | do_flush(qm, i, NULL((void*)0)); |
| 1709 | } |
| 1710 | |
| 1711 | pool = qm->pool; |
| 1712 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_core_sqldb.c" , (const char *)__func__, 1712); |
| 1713 | |
| 1714 | return status; |
| 1715 | } |
| 1716 | |
| 1717 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) |
| 1718 | { |
| 1719 | char *sqlptr = NULL((void*)0); |
| 1720 | switch_status_t status; |
| 1721 | int x = 0; |
| 1722 | |
| 1723 | if (sql_manager.paused || qm->thread_running != 1) { |
| 1724 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1724, ((void*)0), SWITCH_LOG_DEBUG1, "DROP [%s]\n", sql); |
| 1725 | if (!dup) free((char *)sql); |
| 1726 | qm_wake(qm); |
| 1727 | return SWITCH_STATUS_SUCCESS; |
| 1728 | } |
| 1729 | |
| 1730 | if (qm->thread_running != 1) { |
| 1731 | if (!dup) free((char *)sql); |
| 1732 | return SWITCH_STATUS_FALSE; |
| 1733 | } |
| 1734 | |
| 1735 | if (pos > qm->numq - 1) { |
| 1736 | pos = 0; |
| 1737 | } |
| 1738 | |
| 1739 | sqlptr = dup ? strdup(sql)(__extension__ (__builtin_constant_p (sql) && ((size_t )(const void *)((sql) + 1) - (size_t)(const void *)(sql) == 1 ) ? (((const char *) (sql))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (sql) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, sql, __len); __retval ; })) : __strdup (sql))) : (char *)sql; |
| 1740 | |
| 1741 | do { |
| 1742 | switch_mutex_lock(qm->mutex); |
| 1743 | status = switch_queue_trypush(qm->sql_queue[pos], sqlptr); |
| 1744 | switch_mutex_unlock(qm->mutex); |
| 1745 | if (status != SWITCH_STATUS_SUCCESS) { |
| 1746 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1746, ((void*)0), SWITCH_LOG_DEBUG1, "Delay %d sending sql\n", x); |
| 1747 | if (x++) { |
| 1748 | switch_yield(1000000 * x)switch_sleep(1000000 * x);; |
| 1749 | } |
| 1750 | } |
| 1751 | } while(status != SWITCH_STATUS_SUCCESS); |
| 1752 | |
| 1753 | qm_wake(qm); |
| 1754 | |
| 1755 | return SWITCH_STATUS_SUCCESS; |
| 1756 | } |
| 1757 | |
| 1758 | |
| 1759 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) |
| 1760 | { |
| 1761 | #define EXEC_NOW |
| 1762 | #ifdef EXEC_NOW |
| 1763 | switch_cache_db_handle_t *dbh; |
| 1764 | |
| 1765 | if (sql_manager.paused || qm->thread_running != 1) { |
| 1766 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1766, ((void*)0), SWITCH_LOG_DEBUG1, "DROP [%s]\n", sql); |
| 1767 | if (!dup) free((char *)sql); |
| 1768 | qm_wake(qm); |
| 1769 | return SWITCH_STATUS_SUCCESS; |
| 1770 | } |
| 1771 | |
| 1772 | if (switch_cache_db_get_db_handle_dsn(&dbh, qm->dsn)_switch_cache_db_get_db_handle_dsn(&dbh, qm->dsn, "src/switch_core_sqldb.c" , (const char *)__func__, 1772) == SWITCH_STATUS_SUCCESS) { |
| 1773 | switch_cache_db_execute_sql(dbh, (char *)sql, NULL((void*)0)); |
| 1774 | switch_cache_db_release_db_handle(&dbh); |
| 1775 | } |
| 1776 | |
| 1777 | if (!dup) free((char *)sql); |
| 1778 | |
| 1779 | #else |
| 1780 | |
| 1781 | int size, x = 0, sanity = 0; |
| 1782 | uint32_t written, want; |
| 1783 | |
| 1784 | if (sql_manager.paused) { |
| 1785 | if (!dup) free((char *)sql); |
| 1786 | qm_wake(qm); |
| 1787 | return SWITCH_STATUS_SUCCESS; |
| 1788 | } |
| 1789 | |
| 1790 | if (qm->thread_running != 1) { |
| 1791 | if (!dup) free((char *)sql); |
| 1792 | return SWITCH_STATUS_FALSE; |
| 1793 | } |
| 1794 | |
| 1795 | if (pos > qm->numq - 1) { |
| 1796 | pos = 0; |
| 1797 | } |
| 1798 | |
| 1799 | switch_mutex_lock(qm->mutex); |
| 1800 | qm->confirm++; |
| 1801 | switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql)(__extension__ (__builtin_constant_p (sql) && ((size_t )(const void *)((sql) + 1) - (size_t)(const void *)(sql) == 1 ) ? (((const char *) (sql))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (sql) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, sql, __len); __retval ; })) : __strdup (sql))) : (char *)sql); |
| 1802 | written = qm->pre_written[pos]; |
| 1803 | size = switch_sql_queue_manager_size(qm, pos); |
| 1804 | want = written + size; |
| 1805 | switch_mutex_unlock(qm->mutex); |
| 1806 | |
| 1807 | qm_wake(qm); |
| 1808 | |
| 1809 | while((qm->written[pos] < want) || (qm->written[pos] >= written && want < written && qm->written[pos] > want)) { |
| 1810 | switch_yield(5000)switch_sleep(5000);; |
| 1811 | |
| 1812 | if (++x == 200) { |
| 1813 | qm_wake(qm); |
| 1814 | x = 0; |
| 1815 | if (++sanity == 20) { |
| 1816 | break; |
| 1817 | } |
| 1818 | } |
| 1819 | } |
| 1820 | |
| 1821 | switch_mutex_lock(qm->mutex); |
| 1822 | qm->confirm--; |
| 1823 | switch_mutex_unlock(qm->mutex); |
| 1824 | #endif |
| 1825 | |
| 1826 | return SWITCH_STATUS_SUCCESS; |
| 1827 | } |
| 1828 | |
| 1829 | |
| 1830 | |
| 1831 | |
| 1832 | |
| 1833 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_sql_queue_manager_init_name(const char *name, |
| 1834 | switch_sql_queue_manager_t **qmp, |
| 1835 | uint32_t numq, const char *dsn, uint32_t max_trans, |
| 1836 | const char *pre_trans_execute, |
| 1837 | const char *post_trans_execute, |
| 1838 | const char *inner_pre_trans_execute, |
| 1839 | const char *inner_post_trans_execute) |
| 1840 | { |
| 1841 | switch_memory_pool_t *pool; |
| 1842 | switch_sql_queue_manager_t *qm; |
| 1843 | uint32_t i; |
| 1844 | |
| 1845 | if (!numq) numq = 1; |
| 1846 | |
| 1847 | switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_core_sqldb.c" , (const char *)__func__, 1847); |
| 1848 | qm = switch_core_alloc(pool, sizeof(*qm))switch_core_perform_alloc(pool, sizeof(*qm), "src/switch_core_sqldb.c" , (const char *)__func__, 1848); |
| 1849 | |
| 1850 | qm->pool = pool; |
| 1851 | qm->numq = numq; |
| 1852 | qm->dsn = switch_core_strdup(qm->pool, dsn)switch_core_perform_strdup(qm->pool, dsn, "src/switch_core_sqldb.c" , (const char *)__func__, 1852); |
| 1853 | qm->name = switch_core_strdup(qm->pool, name)switch_core_perform_strdup(qm->pool, name, "src/switch_core_sqldb.c" , (const char *)__func__, 1853); |
| 1854 | qm->max_trans = max_trans; |
| 1855 | |
| 1856 | switch_mutex_init(&qm->cond_mutex, SWITCH_MUTEX_NESTED0x1, qm->pool); |
| 1857 | switch_mutex_init(&qm->cond2_mutex, SWITCH_MUTEX_NESTED0x1, qm->pool); |
| 1858 | switch_mutex_init(&qm->mutex, SWITCH_MUTEX_NESTED0x1, qm->pool); |
| 1859 | switch_thread_cond_create(&qm->cond, qm->pool); |
| 1860 | |
| 1861 | qm->sql_queue = switch_core_alloc(qm->pool, sizeof(switch_queue_t *) * numq)switch_core_perform_alloc(qm->pool, sizeof(switch_queue_t * ) * numq, "src/switch_core_sqldb.c", (const char *)__func__, 1861 ); |
| 1862 | qm->written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq)switch_core_perform_alloc(qm->pool, sizeof(uint32_t) * numq , "src/switch_core_sqldb.c", (const char *)__func__, 1862); |
| 1863 | qm->pre_written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq)switch_core_perform_alloc(qm->pool, sizeof(uint32_t) * numq , "src/switch_core_sqldb.c", (const char *)__func__, 1863); |
| 1864 | |
| 1865 | for (i = 0; i < qm->numq; i++) { |
| 1866 | switch_queue_create(&qm->sql_queue[i], SWITCH_SQL_QUEUE_LEN100000, qm->pool); |
| 1867 | } |
| 1868 | |
| 1869 | if (pre_trans_execute) { |
| 1870 | qm->pre_trans_execute = switch_core_strdup(qm->pool, pre_trans_execute)switch_core_perform_strdup(qm->pool, pre_trans_execute, "src/switch_core_sqldb.c" , (const char *)__func__, 1870); |
| 1871 | } |
| 1872 | if (post_trans_execute) { |
| 1873 | qm->post_trans_execute = switch_core_strdup(qm->pool, post_trans_execute)switch_core_perform_strdup(qm->pool, post_trans_execute, "src/switch_core_sqldb.c" , (const char *)__func__, 1873); |
| 1874 | } |
| 1875 | if (inner_pre_trans_execute) { |
| 1876 | qm->inner_pre_trans_execute = switch_core_strdup(qm->pool, inner_pre_trans_execute)switch_core_perform_strdup(qm->pool, inner_pre_trans_execute , "src/switch_core_sqldb.c", (const char *)__func__, 1876); |
| 1877 | } |
| 1878 | if (inner_post_trans_execute) { |
| 1879 | qm->inner_post_trans_execute = switch_core_strdup(qm->pool, inner_post_trans_execute)switch_core_perform_strdup(qm->pool, inner_post_trans_execute , "src/switch_core_sqldb.c", (const char *)__func__, 1879); |
| 1880 | } |
| 1881 | |
| 1882 | *qmp = qm; |
| 1883 | |
| 1884 | return SWITCH_STATUS_SUCCESS; |
| 1885 | |
| 1886 | } |
| 1887 | |
| 1888 | static uint32_t do_trans(switch_sql_queue_manager_t *qm) |
| 1889 | { |
| 1890 | char *errmsg = NULL((void*)0); |
| 1891 | void *pop; |
| 1892 | switch_status_t status; |
| 1893 | uint32_t ttl = 0; |
| 1894 | switch_mutex_t *io_mutex = qm->event_db->io_mutex; |
| 1895 | uint32_t i; |
| 1896 | |
| 1897 | if (io_mutex) switch_mutex_lock(io_mutex); |
| 1898 | |
| 1899 | if (!zstr(qm->pre_trans_execute)_zstr(qm->pre_trans_execute)) { |
| 1900 | switch_cache_db_execute_sql_real(qm->event_db, qm->pre_trans_execute, &errmsg); |
| 1901 | if (errmsg) { |
| 1902 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1902, ((void*)0), SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", qm->pre_trans_execute, errmsg); |
| 1903 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 1904 | } |
| 1905 | } |
| 1906 | |
| 1907 | switch(qm->event_db->type) { |
| 1908 | case SCDB_TYPE_CORE_DB: |
| 1909 | { |
| 1910 | switch_cache_db_execute_sql_real(qm->event_db, "BEGIN EXCLUSIVE", &errmsg); |
| 1911 | } |
| 1912 | break; |
| 1913 | case SCDB_TYPE_ODBC: |
| 1914 | { |
| 1915 | switch_odbc_status_t result; |
| 1916 | |
| 1917 | if ((result = switch_odbc_SQLSetAutoCommitAttr(qm->event_db->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { |
| 1918 | char tmp[100]; |
| 1919 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); |
| 1920 | errmsg = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 1921 | } |
| 1922 | } |
| 1923 | break; |
| 1924 | case SCDB_TYPE_PGSQL: |
| 1925 | { |
| 1926 | switch_pgsql_status_t result; |
| 1927 | |
| 1928 | if ((result = switch_pgsql_SQLSetAutoCommitAttr(qm->event_db->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { |
| 1929 | char tmp[100]; |
| 1930 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); |
| 1931 | errmsg = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 1932 | } |
| 1933 | } |
| 1934 | break; |
| 1935 | } |
| 1936 | |
| 1937 | if (errmsg) { |
| 1938 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1938, ((void*)0), SWITCH_LOG_CRIT, "ERROR [%s]\n", errmsg); |
| 1939 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 1940 | goto end; |
| 1941 | } |
| 1942 | |
| 1943 | |
| 1944 | if (!zstr(qm->inner_pre_trans_execute)_zstr(qm->inner_pre_trans_execute)) { |
| 1945 | switch_cache_db_execute_sql_real(qm->event_db, qm->inner_pre_trans_execute, &errmsg); |
| 1946 | if (errmsg) { |
| 1947 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1947, ((void*)0), SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", qm->inner_pre_trans_execute, errmsg); |
| 1948 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 1949 | } |
| 1950 | } |
| 1951 | |
| 1952 | |
| 1953 | while(qm->max_trans == 0 || ttl <= qm->max_trans) { |
| 1954 | pop = NULL((void*)0); |
| 1955 | |
| 1956 | for (i = 0; (qm->max_trans == 0 || ttl <= qm->max_trans) && (i < qm->numq); i++) { |
| 1957 | switch_mutex_lock(qm->mutex); |
| 1958 | switch_queue_trypop(qm->sql_queue[i], &pop); |
| 1959 | switch_mutex_unlock(qm->mutex); |
| 1960 | if (pop) break; |
| 1961 | } |
| 1962 | |
| 1963 | if (pop) { |
| 1964 | if ((status = switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL((void*)0))) == SWITCH_STATUS_SUCCESS) { |
| 1965 | switch_mutex_lock(qm->mutex); |
| 1966 | qm->pre_written[i]++; |
| 1967 | switch_mutex_unlock(qm->mutex); |
| 1968 | ttl++; |
| 1969 | } |
| 1970 | switch_safe_free(pop)if (pop) {free(pop);pop=((void*)0);}; |
| 1971 | if (status != SWITCH_STATUS_SUCCESS) break; |
| 1972 | } else { |
| 1973 | break; |
| 1974 | } |
| 1975 | } |
| 1976 | |
| 1977 | if (!zstr(qm->inner_post_trans_execute)_zstr(qm->inner_post_trans_execute)) { |
| 1978 | switch_cache_db_execute_sql_real(qm->event_db, qm->inner_post_trans_execute, &errmsg); |
| 1979 | if (errmsg) { |
| 1980 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 1980, ((void*)0), SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", qm->inner_post_trans_execute, errmsg); |
| 1981 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 1982 | } |
| 1983 | } |
| 1984 | |
| 1985 | |
| 1986 | end: |
| 1987 | |
| 1988 | switch(qm->event_db->type) { |
| 1989 | case SCDB_TYPE_CORE_DB: |
| 1990 | { |
| 1991 | switch_cache_db_execute_sql_real(qm->event_db, "COMMIT", NULL((void*)0)); |
| 1992 | } |
| 1993 | break; |
| 1994 | case SCDB_TYPE_ODBC: |
| 1995 | { |
| 1996 | switch_odbc_SQLEndTran(qm->event_db->native_handle.odbc_dbh, 1); |
| 1997 | switch_odbc_SQLSetAutoCommitAttr(qm->event_db->native_handle.odbc_dbh, 1); |
| 1998 | } |
| 1999 | break; |
| 2000 | case SCDB_TYPE_PGSQL: |
| 2001 | { |
| 2002 | switch_pgsql_SQLEndTran(qm->event_db->native_handle.pgsql_dbh, 1); |
| 2003 | switch_pgsql_SQLSetAutoCommitAttr(qm->event_db->native_handle.pgsql_dbh, 1); |
| 2004 | switch_pgsql_finish_results(qm->event_db->native_handle.pgsql_dbh)switch_pgsql_finish_results_real("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 2004, qm->event_db->native_handle .pgsql_dbh); |
| 2005 | } |
| 2006 | break; |
| 2007 | } |
| 2008 | |
| 2009 | |
| 2010 | if (!zstr(qm->post_trans_execute)_zstr(qm->post_trans_execute)) { |
| 2011 | switch_cache_db_execute_sql_real(qm->event_db, qm->post_trans_execute, &errmsg); |
| 2012 | if (errmsg) { |
| 2013 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2013, ((void*)0), SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", qm->post_trans_execute, errmsg); |
| 2014 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 2015 | } |
| 2016 | } |
| 2017 | |
| 2018 | |
| 2019 | switch_mutex_lock(qm->mutex); |
| 2020 | for (i = 0; i < qm->numq; i++) { |
| 2021 | qm->written[i] = qm->pre_written[i]; |
| 2022 | } |
| 2023 | switch_mutex_unlock(qm->mutex); |
| 2024 | |
| 2025 | |
| 2026 | if (io_mutex) switch_mutex_unlock(io_mutex); |
| 2027 | |
| 2028 | return ttl; |
| 2029 | } |
| 2030 | |
| 2031 | static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, void *obj) |
| 2032 | { |
| 2033 | |
| 2034 | uint32_t sanity = 120; |
| 2035 | switch_sql_queue_manager_t *qm = (switch_sql_queue_manager_t *) obj; |
| 2036 | uint32_t i; |
| 2037 | |
| 2038 | while (!qm->event_db) { |
| 2039 | if (switch_cache_db_get_db_handle_dsn(&qm->event_db, qm->dsn)_switch_cache_db_get_db_handle_dsn(&qm->event_db, qm-> dsn, "src/switch_core_sqldb.c", (const char *)__func__, 2039) == SWITCH_STATUS_SUCCESS && qm->event_db) |
| 2040 | break; |
| 2041 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2041, ((void*)0), SWITCH_LOG_WARNING, "%s Error getting db handle, Retrying\n", qm->name); |
| 2042 | switch_yield(500000)switch_sleep(500000);; |
| 2043 | sanity--; |
| 2044 | } |
| 2045 | |
| 2046 | if (!qm->event_db) { |
| 2047 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2047, ((void*)0), SWITCH_LOG_CRIT, "%s Error getting db handle\n", qm->name); |
| 2048 | return NULL((void*)0); |
| 2049 | } |
| 2050 | |
| 2051 | qm->thread_running = 1; |
| 2052 | |
| 2053 | switch_mutex_lock(qm->cond_mutex); |
| 2054 | |
| 2055 | switch (qm->event_db->type) { |
| 2056 | case SCDB_TYPE_PGSQL: |
| 2057 | break; |
| 2058 | case SCDB_TYPE_ODBC: |
| 2059 | break; |
| 2060 | case SCDB_TYPE_CORE_DB: |
| 2061 | { |
| 2062 | switch_cache_db_execute_sql(qm->event_db, "PRAGMA synchronous=OFF;", NULL((void*)0)); |
| 2063 | switch_cache_db_execute_sql(qm->event_db, "PRAGMA count_changes=OFF;", NULL((void*)0)); |
| 2064 | switch_cache_db_execute_sql(qm->event_db, "PRAGMA temp_store=MEMORY;", NULL((void*)0)); |
| 2065 | switch_cache_db_execute_sql(qm->event_db, "PRAGMA journal_mode=OFF;", NULL((void*)0)); |
| 2066 | } |
| 2067 | break; |
| 2068 | } |
| 2069 | |
| 2070 | |
| 2071 | while (qm->thread_running == 1) { |
| 2072 | uint32_t i, lc; |
| 2073 | uint32_t written = 0, iterations = 0; |
| 2074 | |
| 2075 | if (qm->paused) { |
| 2076 | goto check; |
| 2077 | } |
| 2078 | |
| 2079 | if (sql_manager.paused) { |
| 2080 | for (i = 0; i < qm->numq; i++) { |
| 2081 | do_flush(qm, i, NULL((void*)0)); |
| 2082 | } |
| 2083 | goto check; |
| 2084 | } |
| 2085 | |
| 2086 | do { |
| 2087 | if (!qm_ttl(qm)) { |
| 2088 | goto check; |
| 2089 | } |
| 2090 | written = do_trans(qm); |
| 2091 | iterations += written; |
| 2092 | } while(written == qm->max_trans); |
| 2093 | |
| 2094 | if (switch_test_flag((&runtime), SCF_DEBUG_SQL)(((&runtime))->flags & SCF_DEBUG_SQL)) { |
| 2095 | char line[128] = ""; |
| 2096 | switch_size_t l; |
| 2097 | |
| 2098 | switch_snprintf(line, sizeof(line), "%s RUN QUEUE [", qm->name); |
| 2099 | |
| 2100 | for (i = 0; i < qm->numq; i++) { |
| 2101 | l = strlen(line); |
| 2102 | switch_snprintf(line + l, sizeof(line) - l, "%d%s", switch_queue_size(qm->sql_queue[i]), i == qm->numq - 1 ? "" : "|"); |
| 2103 | } |
| 2104 | |
| 2105 | l = strlen(line); |
| 2106 | switch_snprintf(line + l, sizeof(line) - l, "]--[%d]\n", iterations); |
| 2107 | |
| 2108 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2108, ((void*)0), SWITCH_LOG_CRIT, "%s", line); |
| 2109 | |
| 2110 | } |
| 2111 | |
| 2112 | check: |
| 2113 | |
| 2114 | if ((lc = qm_ttl(qm)) == 0) { |
| 2115 | switch_mutex_lock(qm->cond2_mutex); |
| 2116 | switch_thread_cond_wait(qm->cond, qm->cond_mutex); |
| 2117 | switch_mutex_unlock(qm->cond2_mutex); |
| 2118 | } |
| 2119 | |
| 2120 | i = 40; |
| 2121 | |
| 2122 | while (--i > 0 && (lc = qm_ttl(qm)) < 500) { |
| 2123 | switch_yield(5000)switch_sleep(5000);; |
| 2124 | } |
| 2125 | |
| 2126 | |
| 2127 | } |
| 2128 | |
| 2129 | switch_mutex_unlock(qm->cond_mutex); |
| 2130 | |
| 2131 | for(i = 0; i < qm->numq; i++) { |
| 2132 | do_flush(qm, i, qm->event_db); |
| 2133 | } |
| 2134 | |
| 2135 | switch_cache_db_release_db_handle(&qm->event_db); |
| 2136 | |
| 2137 | qm->thread_running = 0; |
| 2138 | |
| 2139 | return NULL((void*)0); |
| 2140 | } |
| 2141 | |
| 2142 | |
| 2143 | static char *parse_presence_data_cols(switch_event_t *event) |
| 2144 | { |
| 2145 | char *cols[128] = { 0 }; |
| 2146 | int col_count = 0; |
| 2147 | char *data_copy; |
| 2148 | switch_stream_handle_t stream = { 0 }; |
| 2149 | int i; |
| 2150 | char *r; |
| 2151 | char col_name[128] = ""; |
| 2152 | const char *data = switch_event_get_header(event, "presence-data-cols")switch_event_get_header_idx(event, "presence-data-cols", -1); |
| 2153 | |
| 2154 | if (zstr(data)_zstr(data)) { |
| 2155 | return NULL((void*)0); |
| 2156 | } |
| 2157 | |
| 2158 | data_copy = strdup(data)(__extension__ (__builtin_constant_p (data) && ((size_t )(const void *)((data) + 1) - (size_t)(const void *)(data) == 1) ? (((const char *) (data))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (data) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, data, __len) ; __retval; })) : __strdup (data))); |
| 2159 | |
| 2160 | col_count = switch_split(data_copy, ':', cols)switch_separate_string(data_copy, ':', cols, (sizeof(cols) / sizeof (cols[0]))); |
| 2161 | |
| 2162 | SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc( 1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data" , "src/switch_core_sqldb.c", 2162, __PRETTY_FUNCTION__)); memset (stream.data, 0, 1024); stream.end = stream.data; stream.data_size = 1024; stream.write_function = switch_console_stream_write; stream.raw_write_function = switch_console_stream_raw_write; stream.alloc_len = 1024; stream.alloc_chunk = 1024; |
| 2163 | |
| 2164 | for (i = 0; i < col_count; i++) { |
| 2165 | const char *val = NULL((void*)0); |
| 2166 | |
| 2167 | switch_snprintfv(col_name, sizeof(col_name), "PD-%q", cols[i]); |
| 2168 | val = switch_event_get_header_nil(event, col_name)(switch_event_get_header_idx(event, col_name, -1) ? switch_event_get_header_idx (event, col_name, -1) : ""); |
| 2169 | if (zstr(val)_zstr(val)) { |
| 2170 | stream.write_function(&stream, "%q=NULL,", cols[i]); |
| 2171 | } else { |
| 2172 | stream.write_function(&stream, "%q='%q',", cols[i], val); |
| 2173 | } |
| 2174 | } |
| 2175 | |
| 2176 | r = (char *) stream.data; |
| 2177 | |
| 2178 | if (end_of(r)*(*r == '\0' ? r : r + strlen(r) - 1) == ',') { |
| 2179 | end_of(r)*(*r == '\0' ? r : r + strlen(r) - 1) = '\0'; |
| 2180 | } |
| 2181 | |
| 2182 | switch_safe_free(data_copy)if (data_copy) {free(data_copy);data_copy=((void*)0);}; |
| 2183 | |
| 2184 | return r; |
| 2185 | |
| 2186 | } |
| 2187 | |
| 2188 | |
| 2189 | #define MAX_SQL5 5 |
| 2190 | #define new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2190, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] switch_assert(sql_idx+1 < MAX_SQL)((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2190, __PRETTY_FUNCTION__)); if (exists) sql[sql_idx++] |
| 2191 | #define new_sql_a()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2191, __PRETTY_FUNCTION__)); sql [sql_idx++] switch_assert(sql_idx+1 < MAX_SQL)((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2191, __PRETTY_FUNCTION__)); sql[sql_idx++] |
| 2192 | |
| 2193 | static void core_event_handler(switch_event_t *event) |
| 2194 | { |
| 2195 | char *sql[MAX_SQL5] = { 0 }; |
| 2196 | int sql_idx = 0; |
| 2197 | char *extra_cols; |
| 2198 | int exists = 1; |
| 2199 | char *uuid = NULL((void*)0); |
| 2200 | |
| 2201 | switch_assert(event)((event) ? (void) (0) : __assert_fail ("event", "src/switch_core_sqldb.c" , 2201, __PRETTY_FUNCTION__)); |
| 2202 | |
| 2203 | switch (event->event_id) { |
| 2204 | case SWITCH_EVENT_CHANNEL_UUID: |
| 2205 | case SWITCH_EVENT_CHANNEL_CREATE: |
| 2206 | case SWITCH_EVENT_CHANNEL_ANSWER: |
| 2207 | case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA: |
| 2208 | case SWITCH_EVENT_CHANNEL_HOLD: |
| 2209 | case SWITCH_EVENT_CHANNEL_UNHOLD: |
| 2210 | case SWITCH_EVENT_CHANNEL_EXECUTE: |
| 2211 | case SWITCH_EVENT_CHANNEL_ORIGINATE: |
| 2212 | case SWITCH_EVENT_CALL_UPDATE: |
| 2213 | case SWITCH_EVENT_CHANNEL_CALLSTATE: |
| 2214 | case SWITCH_EVENT_CHANNEL_STATE: |
| 2215 | case SWITCH_EVENT_CHANNEL_BRIDGE: |
| 2216 | case SWITCH_EVENT_CHANNEL_UNBRIDGE: |
| 2217 | case SWITCH_EVENT_CALL_SECURE: |
| 2218 | { |
| 2219 | if ((uuid = switch_event_get_header(event, "unique-id")switch_event_get_header_idx(event, "unique-id", -1))) { |
| 2220 | exists = switch_ivr_uuid_exists(uuid); |
| 2221 | } |
| 2222 | } |
| 2223 | break; |
| 2224 | default: |
| 2225 | break; |
| 2226 | } |
| 2227 | |
| 2228 | switch (event->event_id) { |
| 2229 | case SWITCH_EVENT_ADD_SCHEDULE: |
| 2230 | { |
| 2231 | const char *id = switch_event_get_header(event, "task-id")switch_event_get_header_idx(event, "task-id", -1); |
| 2232 | const char *manager = switch_event_get_header(event, "task-sql_manager")switch_event_get_header_idx(event, "task-sql_manager", -1); |
| 2233 | |
| 2234 | if (id) { |
| 2235 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2235, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("insert into tasks values(%q,'%q','%q',%q, '%q')", |
| 2236 | id, |
| 2237 | switch_event_get_header_nil(event, "task-desc")(switch_event_get_header_idx(event, "task-desc", -1) ? switch_event_get_header_idx (event, "task-desc", -1) : ""), |
| 2238 | switch_event_get_header_nil(event, "task-group")(switch_event_get_header_idx(event, "task-group", -1) ? switch_event_get_header_idx (event, "task-group", -1) : ""), manager ? manager : "0", switch_core_get_hostname() |
| 2239 | ); |
| 2240 | } |
| 2241 | } |
| 2242 | break; |
| 2243 | case SWITCH_EVENT_DEL_SCHEDULE: |
| 2244 | case SWITCH_EVENT_EXE_SCHEDULE: |
| 2245 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2245, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("delete from tasks where task_id=%q and hostname='%q'", |
| 2246 | switch_event_get_header_nil(event, "task-id")(switch_event_get_header_idx(event, "task-id", -1) ? switch_event_get_header_idx (event, "task-id", -1) : ""), switch_core_get_hostname()); |
| 2247 | break; |
| 2248 | case SWITCH_EVENT_RE_SCHEDULE: |
| 2249 | { |
| 2250 | const char *id = switch_event_get_header(event, "task-id")switch_event_get_header_idx(event, "task-id", -1); |
| 2251 | const char *manager = switch_event_get_header(event, "task-sql_manager")switch_event_get_header_idx(event, "task-sql_manager", -1); |
| 2252 | |
| 2253 | if (id) { |
| 2254 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2254, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q'", |
| 2255 | switch_event_get_header_nil(event, "task-desc")(switch_event_get_header_idx(event, "task-desc", -1) ? switch_event_get_header_idx (event, "task-desc", -1) : ""), |
| 2256 | switch_event_get_header_nil(event, "task-group")(switch_event_get_header_idx(event, "task-group", -1) ? switch_event_get_header_idx (event, "task-group", -1) : ""), manager ? manager : "0", id, |
| 2257 | switch_core_get_hostname()); |
| 2258 | } |
| 2259 | } |
| 2260 | break; |
| 2261 | case SWITCH_EVENT_CHANNEL_DESTROY: |
| 2262 | { |
| 2263 | const char *uuid = switch_event_get_header(event, "unique-id")switch_event_get_header_idx(event, "unique-id", -1); |
| 2264 | |
| 2265 | if (uuid) { |
| 2266 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2266, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("delete from channels where uuid='%q'", |
| 2267 | uuid); |
| 2268 | |
| 2269 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2269, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q')", |
| 2270 | uuid, uuid); |
| 2271 | |
| 2272 | } |
| 2273 | } |
| 2274 | break; |
| 2275 | case SWITCH_EVENT_CHANNEL_UUID: |
| 2276 | { |
| 2277 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2277, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set uuid='%q' where uuid='%q'", |
| 2278 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : ""), |
| 2279 | switch_event_get_header_nil(event, "old-unique-id")(switch_event_get_header_idx(event, "old-unique-id", -1) ? switch_event_get_header_idx (event, "old-unique-id", -1) : "") |
| 2280 | ); |
| 2281 | |
| 2282 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2282, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set call_uuid='%q' where call_uuid='%q'", |
| 2283 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : ""), |
| 2284 | switch_event_get_header_nil(event, "old-unique-id")(switch_event_get_header_idx(event, "old-unique-id", -1) ? switch_event_get_header_idx (event, "old-unique-id", -1) : "") |
| 2285 | ); |
| 2286 | break; |
| 2287 | } |
| 2288 | case SWITCH_EVENT_CHANNEL_CREATE: |
| 2289 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2289, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname,initial_cid_name,initial_cid_num,initial_ip_addr,initial_dest,initial_dialplan,initial_context) " |
| 2290 | "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q')", |
| 2291 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : ""), |
| 2292 | switch_event_get_header_nil(event, "call-direction")(switch_event_get_header_idx(event, "call-direction", -1) ? switch_event_get_header_idx (event, "call-direction", -1) : ""), |
| 2293 | switch_event_get_header_nil(event, "event-date-local")(switch_event_get_header_idx(event, "event-date-local", -1) ? switch_event_get_header_idx(event, "event-date-local", -1) : ""), |
| 2294 | (long) switch_epoch_time_now(NULL((void*)0)), |
| 2295 | switch_event_get_header_nil(event, "channel-name")(switch_event_get_header_idx(event, "channel-name", -1) ? switch_event_get_header_idx (event, "channel-name", -1) : ""), |
| 2296 | switch_event_get_header_nil(event, "channel-state")(switch_event_get_header_idx(event, "channel-state", -1) ? switch_event_get_header_idx (event, "channel-state", -1) : ""), |
| 2297 | switch_event_get_header_nil(event, "channel-call-state")(switch_event_get_header_idx(event, "channel-call-state", -1) ? switch_event_get_header_idx(event, "channel-call-state", - 1) : ""), |
| 2298 | switch_event_get_header_nil(event, "caller-dialplan")(switch_event_get_header_idx(event, "caller-dialplan", -1) ? switch_event_get_header_idx (event, "caller-dialplan", -1) : ""), |
| 2299 | switch_event_get_header_nil(event, "caller-context")(switch_event_get_header_idx(event, "caller-context", -1) ? switch_event_get_header_idx (event, "caller-context", -1) : ""), switch_core_get_switchname(), |
| 2300 | switch_event_get_header_nil(event, "caller-caller-id-name")(switch_event_get_header_idx(event, "caller-caller-id-name", - 1) ? switch_event_get_header_idx(event, "caller-caller-id-name" , -1) : ""), |
| 2301 | switch_event_get_header_nil(event, "caller-caller-id-number")(switch_event_get_header_idx(event, "caller-caller-id-number" , -1) ? switch_event_get_header_idx(event, "caller-caller-id-number" , -1) : ""), |
| 2302 | switch_event_get_header_nil(event, "caller-network-addr")(switch_event_get_header_idx(event, "caller-network-addr", -1 ) ? switch_event_get_header_idx(event, "caller-network-addr", -1) : ""), |
| 2303 | switch_event_get_header_nil(event, "caller-destination-number")(switch_event_get_header_idx(event, "caller-destination-number" , -1) ? switch_event_get_header_idx(event, "caller-destination-number" , -1) : ""), |
| 2304 | switch_event_get_header_nil(event, "caller-dialplan")(switch_event_get_header_idx(event, "caller-dialplan", -1) ? switch_event_get_header_idx (event, "caller-dialplan", -1) : ""), |
| 2305 | switch_event_get_header_nil(event, "caller-context")(switch_event_get_header_idx(event, "caller-context", -1) ? switch_event_get_header_idx (event, "caller-context", -1) : "") |
| 2306 | ); |
| 2307 | break; |
| 2308 | case SWITCH_EVENT_CHANNEL_ANSWER: |
| 2309 | case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA: |
| 2310 | case SWITCH_EVENT_CODEC: |
| 2311 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2311, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = |
| 2312 | switch_mprintf |
| 2313 | ("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'", |
| 2314 | switch_event_get_header_nil(event, "channel-read-codec-name")(switch_event_get_header_idx(event, "channel-read-codec-name" , -1) ? switch_event_get_header_idx(event, "channel-read-codec-name" , -1) : ""), |
| 2315 | switch_event_get_header_nil(event, "channel-read-codec-rate")(switch_event_get_header_idx(event, "channel-read-codec-rate" , -1) ? switch_event_get_header_idx(event, "channel-read-codec-rate" , -1) : ""), |
| 2316 | switch_event_get_header_nil(event, "channel-read-codec-bit-rate")(switch_event_get_header_idx(event, "channel-read-codec-bit-rate" , -1) ? switch_event_get_header_idx(event, "channel-read-codec-bit-rate" , -1) : ""), |
| 2317 | switch_event_get_header_nil(event, "channel-write-codec-name")(switch_event_get_header_idx(event, "channel-write-codec-name" , -1) ? switch_event_get_header_idx(event, "channel-write-codec-name" , -1) : ""), |
| 2318 | switch_event_get_header_nil(event, "channel-write-codec-rate")(switch_event_get_header_idx(event, "channel-write-codec-rate" , -1) ? switch_event_get_header_idx(event, "channel-write-codec-rate" , -1) : ""), |
| 2319 | switch_event_get_header_nil(event, "channel-write-codec-bit-rate")(switch_event_get_header_idx(event, "channel-write-codec-bit-rate" , -1) ? switch_event_get_header_idx(event, "channel-write-codec-bit-rate" , -1) : ""), |
| 2320 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2321 | break; |
| 2322 | case SWITCH_EVENT_CHANNEL_HOLD: |
| 2323 | case SWITCH_EVENT_CHANNEL_UNHOLD: |
| 2324 | case SWITCH_EVENT_CHANNEL_EXECUTE: { |
| 2325 | |
| 2326 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2326, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set application='%q',application_data='%q'," |
| 2327 | "presence_id='%q',presence_data='%q' where uuid='%q'", |
| 2328 | switch_event_get_header_nil(event, "application")(switch_event_get_header_idx(event, "application", -1) ? switch_event_get_header_idx (event, "application", -1) : ""), |
| 2329 | switch_event_get_header_nil(event, "application-data")(switch_event_get_header_idx(event, "application-data", -1) ? switch_event_get_header_idx(event, "application-data", -1) : ""), |
| 2330 | switch_event_get_header_nil(event, "channel-presence-id")(switch_event_get_header_idx(event, "channel-presence-id", -1 ) ? switch_event_get_header_idx(event, "channel-presence-id", -1) : ""), |
| 2331 | switch_event_get_header_nil(event, "channel-presence-data")(switch_event_get_header_idx(event, "channel-presence-data", - 1) ? switch_event_get_header_idx(event, "channel-presence-data" , -1) : ""), |
| 2332 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "") |
| 2333 | ); |
| 2334 | |
| 2335 | } |
| 2336 | break; |
| 2337 | |
| 2338 | case SWITCH_EVENT_CHANNEL_ORIGINATE: |
| 2339 | { |
| 2340 | if ((extra_cols = parse_presence_data_cols(event))) { |
| 2341 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2341, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set " |
| 2342 | "presence_id='%q',presence_data='%q', call_uuid='%q',%s where uuid='%q'", |
| 2343 | switch_event_get_header_nil(event, "channel-presence-id")(switch_event_get_header_idx(event, "channel-presence-id", -1 ) ? switch_event_get_header_idx(event, "channel-presence-id", -1) : ""), |
| 2344 | switch_event_get_header_nil(event, "channel-presence-data")(switch_event_get_header_idx(event, "channel-presence-data", - 1) ? switch_event_get_header_idx(event, "channel-presence-data" , -1) : ""), |
| 2345 | switch_event_get_header_nil(event, "channel-call-uuid")(switch_event_get_header_idx(event, "channel-call-uuid", -1) ? switch_event_get_header_idx(event, "channel-call-uuid", -1) : ""), |
| 2346 | extra_cols, |
| 2347 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2348 | free(extra_cols); |
| 2349 | } else { |
| 2350 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2350, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set " |
| 2351 | "presence_id='%q',presence_data='%q', call_uuid='%q' where uuid='%q'", |
| 2352 | switch_event_get_header_nil(event, "channel-presence-id")(switch_event_get_header_idx(event, "channel-presence-id", -1 ) ? switch_event_get_header_idx(event, "channel-presence-id", -1) : ""), |
| 2353 | switch_event_get_header_nil(event, "channel-presence-data")(switch_event_get_header_idx(event, "channel-presence-data", - 1) ? switch_event_get_header_idx(event, "channel-presence-data" , -1) : ""), |
| 2354 | switch_event_get_header_nil(event, "channel-call-uuid")(switch_event_get_header_idx(event, "channel-call-uuid", -1) ? switch_event_get_header_idx(event, "channel-call-uuid", -1) : ""), |
| 2355 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2356 | } |
| 2357 | |
| 2358 | } |
| 2359 | |
| 2360 | break; |
| 2361 | case SWITCH_EVENT_CALL_UPDATE: |
| 2362 | { |
| 2363 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2363, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set callee_name='%q',callee_num='%q',sent_callee_name='%q',sent_callee_num='%q',callee_direction='%q'," |
| 2364 | "cid_name='%q',cid_num='%q' where uuid='%s'", |
| 2365 | switch_event_get_header_nil(event, "caller-callee-id-name")(switch_event_get_header_idx(event, "caller-callee-id-name", - 1) ? switch_event_get_header_idx(event, "caller-callee-id-name" , -1) : ""), |
| 2366 | switch_event_get_header_nil(event, "caller-callee-id-number")(switch_event_get_header_idx(event, "caller-callee-id-number" , -1) ? switch_event_get_header_idx(event, "caller-callee-id-number" , -1) : ""), |
| 2367 | switch_event_get_header_nil(event, "sent-callee-id-name")(switch_event_get_header_idx(event, "sent-callee-id-name", -1 ) ? switch_event_get_header_idx(event, "sent-callee-id-name", -1) : ""), |
| 2368 | switch_event_get_header_nil(event, "sent-callee-id-number")(switch_event_get_header_idx(event, "sent-callee-id-number", - 1) ? switch_event_get_header_idx(event, "sent-callee-id-number" , -1) : ""), |
| 2369 | switch_event_get_header_nil(event, "direction")(switch_event_get_header_idx(event, "direction", -1) ? switch_event_get_header_idx (event, "direction", -1) : ""), |
| 2370 | switch_event_get_header_nil(event, "caller-caller-id-name")(switch_event_get_header_idx(event, "caller-caller-id-name", - 1) ? switch_event_get_header_idx(event, "caller-caller-id-name" , -1) : ""), |
| 2371 | switch_event_get_header_nil(event, "caller-caller-id-number")(switch_event_get_header_idx(event, "caller-caller-id-number" , -1) ? switch_event_get_header_idx(event, "caller-caller-id-number" , -1) : ""), |
| 2372 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "") |
| 2373 | ); |
| 2374 | } |
| 2375 | break; |
| 2376 | case SWITCH_EVENT_CHANNEL_CALLSTATE: |
| 2377 | { |
| 2378 | char *num = switch_event_get_header_nil(event, "channel-call-state-number")(switch_event_get_header_idx(event, "channel-call-state-number" , -1) ? switch_event_get_header_idx(event, "channel-call-state-number" , -1) : ""); |
| 2379 | switch_channel_callstate_t callstate = CCS_DOWN; |
| 2380 | |
| 2381 | if (num) { |
| 2382 | callstate = atoi(num); |
| 2383 | } |
| 2384 | |
| 2385 | if (callstate != CCS_DOWN && callstate != CCS_HANGUP) { |
| 2386 | if ((extra_cols = parse_presence_data_cols(event))) { |
| 2387 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2387, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set callstate='%q',%s where uuid='%q'", |
| 2388 | switch_event_get_header_nil(event, "channel-call-state")(switch_event_get_header_idx(event, "channel-call-state", -1) ? switch_event_get_header_idx(event, "channel-call-state", - 1) : ""), |
| 2389 | extra_cols, |
| 2390 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2391 | free(extra_cols); |
| 2392 | } else { |
| 2393 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2393, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set callstate='%q' where uuid='%q'", |
| 2394 | switch_event_get_header_nil(event, "channel-call-state")(switch_event_get_header_idx(event, "channel-call-state", -1) ? switch_event_get_header_idx(event, "channel-call-state", - 1) : ""), |
| 2395 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2396 | } |
| 2397 | } |
| 2398 | |
| 2399 | } |
| 2400 | break; |
| 2401 | case SWITCH_EVENT_CHANNEL_STATE: |
| 2402 | { |
| 2403 | char *state = switch_event_get_header_nil(event, "channel-state-number")(switch_event_get_header_idx(event, "channel-state-number", - 1) ? switch_event_get_header_idx(event, "channel-state-number" , -1) : ""); |
| 2404 | switch_channel_state_t state_i = CS_DESTROY; |
| 2405 | |
| 2406 | if (!zstr(state)_zstr(state)) { |
| 2407 | state_i = atoi(state); |
| 2408 | } |
| 2409 | |
| 2410 | switch (state_i) { |
| 2411 | case CS_NEW: |
| 2412 | case CS_DESTROY: |
| 2413 | case CS_REPORTING: |
| 2414 | #ifndef SWITCH_DEPRECATED_CORE_DB |
| 2415 | case CS_HANGUP: /* marked for deprication */ |
| 2416 | #endif |
| 2417 | case CS_INIT: |
| 2418 | break; |
| 2419 | #ifdef SWITCH_DEPRECATED_CORE_DB |
| 2420 | case CS_HANGUP: /* marked for deprication */ |
| 2421 | new_sql_a()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2421, __PRETTY_FUNCTION__)); sql [sql_idx++] = switch_mprintf("update channels set state='%s' where uuid='%s'", |
| 2422 | switch_event_get_header_nil(event, "channel-state")(switch_event_get_header_idx(event, "channel-state", -1) ? switch_event_get_header_idx (event, "channel-state", -1) : ""), |
| 2423 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2424 | break; |
| 2425 | #endif |
| 2426 | case CS_EXECUTE: |
| 2427 | if ((extra_cols = parse_presence_data_cols(event))) { |
| 2428 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2428, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set state='%s',%s where uuid='%q'", |
| 2429 | switch_event_get_header_nil(event, "channel-state")(switch_event_get_header_idx(event, "channel-state", -1) ? switch_event_get_header_idx (event, "channel-state", -1) : ""), |
| 2430 | extra_cols, |
| 2431 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2432 | free(extra_cols); |
| 2433 | |
| 2434 | } else { |
| 2435 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2435, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set state='%s' where uuid='%s'", |
| 2436 | switch_event_get_header_nil(event, "channel-state")(switch_event_get_header_idx(event, "channel-state", -1) ? switch_event_get_header_idx (event, "channel-state", -1) : ""), |
| 2437 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2438 | } |
| 2439 | break; |
| 2440 | case CS_ROUTING: |
| 2441 | if ((extra_cols = parse_presence_data_cols(event))) { |
| 2442 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2442, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," |
| 2443 | "sent_callee_name='%q',sent_callee_num='%q'," |
| 2444 | "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',%s " |
| 2445 | "where uuid='%s'", |
| 2446 | switch_event_get_header_nil(event, "channel-state")(switch_event_get_header_idx(event, "channel-state", -1) ? switch_event_get_header_idx (event, "channel-state", -1) : ""), |
| 2447 | switch_event_get_header_nil(event, "caller-caller-id-name")(switch_event_get_header_idx(event, "caller-caller-id-name", - 1) ? switch_event_get_header_idx(event, "caller-caller-id-name" , -1) : ""), |
| 2448 | switch_event_get_header_nil(event, "caller-caller-id-number")(switch_event_get_header_idx(event, "caller-caller-id-number" , -1) ? switch_event_get_header_idx(event, "caller-caller-id-number" , -1) : ""), |
| 2449 | switch_event_get_header_nil(event, "caller-callee-id-name")(switch_event_get_header_idx(event, "caller-callee-id-name", - 1) ? switch_event_get_header_idx(event, "caller-callee-id-name" , -1) : ""), |
| 2450 | switch_event_get_header_nil(event, "caller-callee-id-number")(switch_event_get_header_idx(event, "caller-callee-id-number" , -1) ? switch_event_get_header_idx(event, "caller-callee-id-number" , -1) : ""), |
| 2451 | switch_event_get_header_nil(event, "sent-callee-id-name")(switch_event_get_header_idx(event, "sent-callee-id-name", -1 ) ? switch_event_get_header_idx(event, "sent-callee-id-name", -1) : ""), |
| 2452 | switch_event_get_header_nil(event, "sent-callee-id-number")(switch_event_get_header_idx(event, "sent-callee-id-number", - 1) ? switch_event_get_header_idx(event, "sent-callee-id-number" , -1) : ""), |
| 2453 | switch_event_get_header_nil(event, "caller-network-addr")(switch_event_get_header_idx(event, "caller-network-addr", -1 ) ? switch_event_get_header_idx(event, "caller-network-addr", -1) : ""), |
| 2454 | switch_event_get_header_nil(event, "caller-destination-number")(switch_event_get_header_idx(event, "caller-destination-number" , -1) ? switch_event_get_header_idx(event, "caller-destination-number" , -1) : ""), |
| 2455 | switch_event_get_header_nil(event, "caller-dialplan")(switch_event_get_header_idx(event, "caller-dialplan", -1) ? switch_event_get_header_idx (event, "caller-dialplan", -1) : ""), |
| 2456 | switch_event_get_header_nil(event, "caller-context")(switch_event_get_header_idx(event, "caller-context", -1) ? switch_event_get_header_idx (event, "caller-context", -1) : ""), |
| 2457 | switch_event_get_header_nil(event, "channel-presence-id")(switch_event_get_header_idx(event, "channel-presence-id", -1 ) ? switch_event_get_header_idx(event, "channel-presence-id", -1) : ""), |
| 2458 | switch_event_get_header_nil(event, "channel-presence-data")(switch_event_get_header_idx(event, "channel-presence-data", - 1) ? switch_event_get_header_idx(event, "channel-presence-data" , -1) : ""), |
| 2459 | extra_cols, |
| 2460 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2461 | free(extra_cols); |
| 2462 | } else { |
| 2463 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2463, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," |
| 2464 | "sent_callee_name='%q',sent_callee_num='%q'," |
| 2465 | "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' " |
| 2466 | "where uuid='%s'", |
| 2467 | switch_event_get_header_nil(event, "channel-state")(switch_event_get_header_idx(event, "channel-state", -1) ? switch_event_get_header_idx (event, "channel-state", -1) : ""), |
| 2468 | switch_event_get_header_nil(event, "caller-caller-id-name")(switch_event_get_header_idx(event, "caller-caller-id-name", - 1) ? switch_event_get_header_idx(event, "caller-caller-id-name" , -1) : ""), |
| 2469 | switch_event_get_header_nil(event, "caller-caller-id-number")(switch_event_get_header_idx(event, "caller-caller-id-number" , -1) ? switch_event_get_header_idx(event, "caller-caller-id-number" , -1) : ""), |
| 2470 | switch_event_get_header_nil(event, "caller-callee-id-name")(switch_event_get_header_idx(event, "caller-callee-id-name", - 1) ? switch_event_get_header_idx(event, "caller-callee-id-name" , -1) : ""), |
| 2471 | switch_event_get_header_nil(event, "caller-callee-id-number")(switch_event_get_header_idx(event, "caller-callee-id-number" , -1) ? switch_event_get_header_idx(event, "caller-callee-id-number" , -1) : ""), |
| 2472 | switch_event_get_header_nil(event, "sent-callee-id-name")(switch_event_get_header_idx(event, "sent-callee-id-name", -1 ) ? switch_event_get_header_idx(event, "sent-callee-id-name", -1) : ""), |
| 2473 | switch_event_get_header_nil(event, "sent-callee-id-number")(switch_event_get_header_idx(event, "sent-callee-id-number", - 1) ? switch_event_get_header_idx(event, "sent-callee-id-number" , -1) : ""), |
| 2474 | switch_event_get_header_nil(event, "caller-network-addr")(switch_event_get_header_idx(event, "caller-network-addr", -1 ) ? switch_event_get_header_idx(event, "caller-network-addr", -1) : ""), |
| 2475 | switch_event_get_header_nil(event, "caller-destination-number")(switch_event_get_header_idx(event, "caller-destination-number" , -1) ? switch_event_get_header_idx(event, "caller-destination-number" , -1) : ""), |
| 2476 | switch_event_get_header_nil(event, "caller-dialplan")(switch_event_get_header_idx(event, "caller-dialplan", -1) ? switch_event_get_header_idx (event, "caller-dialplan", -1) : ""), |
| 2477 | switch_event_get_header_nil(event, "caller-context")(switch_event_get_header_idx(event, "caller-context", -1) ? switch_event_get_header_idx (event, "caller-context", -1) : ""), |
| 2478 | switch_event_get_header_nil(event, "channel-presence-id")(switch_event_get_header_idx(event, "channel-presence-id", -1 ) ? switch_event_get_header_idx(event, "channel-presence-id", -1) : ""), |
| 2479 | switch_event_get_header_nil(event, "channel-presence-data")(switch_event_get_header_idx(event, "channel-presence-data", - 1) ? switch_event_get_header_idx(event, "channel-presence-data" , -1) : ""), |
| 2480 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2481 | } |
| 2482 | break; |
| 2483 | default: |
| 2484 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2484, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set state='%s' where uuid='%s'", |
| 2485 | switch_event_get_header_nil(event, "channel-state")(switch_event_get_header_idx(event, "channel-state", -1) ? switch_event_get_header_idx (event, "channel-state", -1) : ""), |
| 2486 | switch_event_get_header_nil(event, "unique-id")(switch_event_get_header_idx(event, "unique-id", -1) ? switch_event_get_header_idx (event, "unique-id", -1) : "")); |
| 2487 | break; |
| 2488 | } |
| 2489 | |
| 2490 | break; |
| 2491 | |
| 2492 | |
| 2493 | } |
| 2494 | case SWITCH_EVENT_CHANNEL_BRIDGE: |
| 2495 | { |
| 2496 | const char *a_uuid, *b_uuid, *uuid; |
| 2497 | |
| 2498 | a_uuid = switch_event_get_header(event, "Bridge-A-Unique-ID")switch_event_get_header_idx(event, "Bridge-A-Unique-ID", -1); |
| 2499 | b_uuid = switch_event_get_header(event, "Bridge-B-Unique-ID")switch_event_get_header_idx(event, "Bridge-B-Unique-ID", -1); |
| 2500 | uuid = switch_event_get_header(event, "unique-id")switch_event_get_header_idx(event, "unique-id", -1); |
| 2501 | |
| 2502 | if (zstr(a_uuid)_zstr(a_uuid) || zstr(b_uuid)_zstr(b_uuid)) { |
| 2503 | a_uuid = switch_event_get_header_nil(event, "caller-unique-id")(switch_event_get_header_idx(event, "caller-unique-id", -1) ? switch_event_get_header_idx(event, "caller-unique-id", -1) : ""); |
| 2504 | b_uuid = switch_event_get_header_nil(event, "other-leg-unique-id")(switch_event_get_header_idx(event, "other-leg-unique-id", -1 ) ? switch_event_get_header_idx(event, "other-leg-unique-id", -1) : ""); |
| 2505 | } |
| 2506 | |
| 2507 | if (uuid && (extra_cols = parse_presence_data_cols(event))) { |
| 2508 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2508, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set %s where uuid='%s'", extra_cols, uuid); |
| 2509 | switch_safe_free(extra_cols)if (extra_cols) {free(extra_cols);extra_cols=((void*)0);}; |
| 2510 | } |
| 2511 | |
| 2512 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2512, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set call_uuid='%q' where uuid='%s' or uuid='%s'", |
| 2513 | switch_event_get_header_nil(event, "channel-call-uuid")(switch_event_get_header_idx(event, "channel-call-uuid", -1) ? switch_event_get_header_idx(event, "channel-call-uuid", -1) : ""), a_uuid, b_uuid); |
| 2514 | |
| 2515 | |
| 2516 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2516, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("insert into calls (call_uuid,call_created,call_created_epoch," |
| 2517 | "caller_uuid,callee_uuid,hostname) " |
| 2518 | "values ('%s','%s','%ld','%q','%q','%q')", |
| 2519 | switch_event_get_header_nil(event, "channel-call-uuid")(switch_event_get_header_idx(event, "channel-call-uuid", -1) ? switch_event_get_header_idx(event, "channel-call-uuid", -1) : ""), |
| 2520 | switch_event_get_header_nil(event, "event-date-local")(switch_event_get_header_idx(event, "event-date-local", -1) ? switch_event_get_header_idx(event, "event-date-local", -1) : ""), |
| 2521 | (long) switch_epoch_time_now(NULL((void*)0)), |
| 2522 | a_uuid, |
| 2523 | b_uuid, |
| 2524 | switch_core_get_switchname() |
| 2525 | ); |
| 2526 | } |
| 2527 | break; |
| 2528 | case SWITCH_EVENT_CHANNEL_UNBRIDGE: |
| 2529 | { |
| 2530 | char *cuuid = switch_event_get_header_nil(event, "caller-unique-id")(switch_event_get_header_idx(event, "caller-unique-id", -1) ? switch_event_get_header_idx(event, "caller-unique-id", -1) : ""); |
| 2531 | char *uuid = switch_event_get_header(event, "unique-id")switch_event_get_header_idx(event, "unique-id", -1); |
| 2532 | |
| 2533 | if (uuid && (extra_cols = parse_presence_data_cols(event))) { |
| 2534 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2534, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set %s where uuid='%s'", extra_cols, uuid); |
| 2535 | switch_safe_free(extra_cols)if (extra_cols) {free(extra_cols);extra_cols=((void*)0);}; |
| 2536 | } |
| 2537 | |
| 2538 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2538, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set call_uuid=uuid where call_uuid='%s'", |
| 2539 | switch_event_get_header_nil(event, "channel-call-uuid")(switch_event_get_header_idx(event, "channel-call-uuid", -1) ? switch_event_get_header_idx(event, "channel-call-uuid", -1) : "")); |
| 2540 | |
| 2541 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2541, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q')", |
| 2542 | cuuid, cuuid); |
| 2543 | break; |
| 2544 | } |
| 2545 | case SWITCH_EVENT_SHUTDOWN: |
| 2546 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2546, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("delete from channels where hostname='%q';" |
| 2547 | "delete from interfaces where hostname='%q';" |
| 2548 | "delete from calls where hostname='%q'", |
| 2549 | switch_core_get_switchname(), switch_core_get_hostname(), switch_core_get_switchname() |
| 2550 | ); |
| 2551 | break; |
| 2552 | case SWITCH_EVENT_LOG: |
| 2553 | return; |
| 2554 | case SWITCH_EVENT_MODULE_LOAD: |
| 2555 | { |
| 2556 | const char *type = switch_event_get_header_nil(event, "type")(switch_event_get_header_idx(event, "type", -1) ? switch_event_get_header_idx (event, "type", -1) : ""); |
| 2557 | const char *name = switch_event_get_header_nil(event, "name")(switch_event_get_header_idx(event, "name", -1) ? switch_event_get_header_idx (event, "name", -1) : ""); |
| 2558 | const char *description = switch_event_get_header_nil(event, "description")(switch_event_get_header_idx(event, "description", -1) ? switch_event_get_header_idx (event, "description", -1) : ""); |
| 2559 | const char *syntax = switch_event_get_header_nil(event, "syntax")(switch_event_get_header_idx(event, "syntax", -1) ? switch_event_get_header_idx (event, "syntax", -1) : ""); |
| 2560 | const char *key = switch_event_get_header_nil(event, "key")(switch_event_get_header_idx(event, "key", -1) ? switch_event_get_header_idx (event, "key", -1) : ""); |
| 2561 | const char *filename = switch_event_get_header_nil(event, "filename")(switch_event_get_header_idx(event, "filename", -1) ? switch_event_get_header_idx (event, "filename", -1) : ""); |
| 2562 | if (!zstr(type)_zstr(type) && !zstr(name)_zstr(name)) { |
| 2563 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2563, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = |
| 2564 | switch_mprintf |
| 2565 | ("insert into interfaces (type,name,description,syntax,ikey,filename,hostname) values('%q','%q','%q','%q','%q','%q','%q')", type, name, |
| 2566 | switch_str_nil(description)(description ? description : ""), switch_str_nil(syntax)(syntax ? syntax : ""), switch_str_nil(key)(key ? key : ""), switch_str_nil(filename)(filename ? filename : ""), |
| 2567 | switch_core_get_hostname() |
| 2568 | ); |
| 2569 | } |
| 2570 | break; |
| 2571 | } |
| 2572 | case SWITCH_EVENT_MODULE_UNLOAD: |
| 2573 | { |
| 2574 | const char *type = switch_event_get_header_nil(event, "type")(switch_event_get_header_idx(event, "type", -1) ? switch_event_get_header_idx (event, "type", -1) : ""); |
| 2575 | const char *name = switch_event_get_header_nil(event, "name")(switch_event_get_header_idx(event, "name", -1) ? switch_event_get_header_idx (event, "name", -1) : ""); |
| 2576 | if (!zstr(type)_zstr(type) && !zstr(name)_zstr(name)) { |
| 2577 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2577, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("delete from interfaces where type='%q' and name='%q' and hostname='%q'", type, name, |
| 2578 | switch_core_get_hostname()); |
| 2579 | } |
| 2580 | break; |
| 2581 | } |
| 2582 | case SWITCH_EVENT_CALL_SECURE: |
| 2583 | { |
| 2584 | const char *type = switch_event_get_header_nil(event, "secure_type")(switch_event_get_header_idx(event, "secure_type", -1) ? switch_event_get_header_idx (event, "secure_type", -1) : ""); |
| 2585 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2585, ((void*)0), SWITCH_LOG_DEBUG, "Secure Type: %s\n", type); |
| 2586 | if (zstr(type)_zstr(type)) { |
| 2587 | break; |
| 2588 | } |
| 2589 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2589, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("update channels set secure='%s' where uuid='%s'", |
| 2590 | type, switch_event_get_header_nil(event, "caller-unique-id")(switch_event_get_header_idx(event, "caller-unique-id", -1) ? switch_event_get_header_idx(event, "caller-unique-id", -1) : "") |
| 2591 | ); |
| 2592 | break; |
| 2593 | } |
| 2594 | case SWITCH_EVENT_NAT: |
| 2595 | { |
| 2596 | const char *op = switch_event_get_header_nil(event, "op")(switch_event_get_header_idx(event, "op", -1) ? switch_event_get_header_idx (event, "op", -1) : ""); |
| 2597 | switch_bool_t sticky = switch_true(switch_event_get_header_nil(event, "sticky")(switch_event_get_header_idx(event, "sticky", -1) ? switch_event_get_header_idx (event, "sticky", -1) : "")); |
| 2598 | if (!strcmp("add", op)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ("add") && __builtin_constant_p (op) && (__s1_len = __builtin_strlen ("add"), __s2_len = __builtin_strlen (op) , (!((size_t)(const void *)(("add") + 1) - (size_t)(const void *)("add") == 1) || __s1_len >= 4) && (!((size_t)( const void *)((op) + 1) - (size_t)(const void *)(op) == 1) || __s2_len >= 4)) ? __builtin_strcmp ("add", op) : (__builtin_constant_p ("add") && ((size_t)(const void *)(("add") + 1) - (size_t )(const void *)("add") == 1) && (__s1_len = __builtin_strlen ("add"), __s1_len < 4) ? (__builtin_constant_p (op) && ((size_t)(const void *)((op) + 1) - (size_t)(const void *)(op ) == 1) ? __builtin_strcmp ("add", op) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (op); int __result = (((const unsigned char *) (const char * ) ("add"))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "add"))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "add"))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("add" ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( op) && ((size_t)(const void *)((op) + 1) - (size_t)(const void *)(op) == 1) && (__s2_len = __builtin_strlen (op ), __s2_len < 4) ? (__builtin_constant_p ("add") && ((size_t)(const void *)(("add") + 1) - (size_t)(const void * )("add") == 1) ? __builtin_strcmp ("add", op) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("add"); int __result = (((const unsigned char *) (const char *) (op))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( op))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (op ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (op))[3 ] - __s2[3]); } } __result; })))) : __builtin_strcmp ("add", op )))); })) { |
| 2599 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2599, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("insert into nat (port, proto, sticky, hostname) values (%s, %s, %d,'%q')", |
| 2600 | switch_event_get_header_nil(event, "port")(switch_event_get_header_idx(event, "port", -1) ? switch_event_get_header_idx (event, "port", -1) : ""), |
| 2601 | switch_event_get_header_nil(event, "proto")(switch_event_get_header_idx(event, "proto", -1) ? switch_event_get_header_idx (event, "proto", -1) : ""), sticky, switch_core_get_hostname() |
| 2602 | ); |
| 2603 | } else if (!strcmp("del", op)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ("del") && __builtin_constant_p (op) && (__s1_len = __builtin_strlen ("del"), __s2_len = __builtin_strlen (op) , (!((size_t)(const void *)(("del") + 1) - (size_t)(const void *)("del") == 1) || __s1_len >= 4) && (!((size_t)( const void *)((op) + 1) - (size_t)(const void *)(op) == 1) || __s2_len >= 4)) ? __builtin_strcmp ("del", op) : (__builtin_constant_p ("del") && ((size_t)(const void *)(("del") + 1) - (size_t )(const void *)("del") == 1) && (__s1_len = __builtin_strlen ("del"), __s1_len < 4) ? (__builtin_constant_p (op) && ((size_t)(const void *)((op) + 1) - (size_t)(const void *)(op ) == 1) ? __builtin_strcmp ("del", op) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (op); int __result = (((const unsigned char *) (const char * ) ("del"))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "del"))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "del"))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("del" ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( op) && ((size_t)(const void *)((op) + 1) - (size_t)(const void *)(op) == 1) && (__s2_len = __builtin_strlen (op ), __s2_len < 4) ? (__builtin_constant_p ("del") && ((size_t)(const void *)(("del") + 1) - (size_t)(const void * )("del") == 1) ? __builtin_strcmp ("del", op) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("del"); int __result = (((const unsigned char *) (const char *) (op))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( op))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (op ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (op))[3 ] - __s2[3]); } } __result; })))) : __builtin_strcmp ("del", op )))); })) { |
| 2604 | new_sql()((sql_idx+1 < 5) ? (void) (0) : __assert_fail ("sql_idx+1 < 5" , "src/switch_core_sqldb.c", 2604, __PRETTY_FUNCTION__)); if ( exists) sql[sql_idx++] = switch_mprintf("delete from nat where port=%s and proto=%s and hostname='%q'", |
| 2605 | switch_event_get_header_nil(event, "port")(switch_event_get_header_idx(event, "port", -1) ? switch_event_get_header_idx (event, "port", -1) : ""), |
| 2606 | switch_event_get_header_nil(event, "proto")(switch_event_get_header_idx(event, "proto", -1) ? switch_event_get_header_idx (event, "proto", -1) : ""), switch_core_get_hostname()); |
| 2607 | } else if (!strcmp("status", op)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ("status") && __builtin_constant_p (op) && ( __s1_len = __builtin_strlen ("status"), __s2_len = __builtin_strlen (op), (!((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) || __s1_len >= 4) && (!(( size_t)(const void *)((op) + 1) - (size_t)(const void *)(op) == 1) || __s2_len >= 4)) ? __builtin_strcmp ("status", op) : (__builtin_constant_p ("status") && ((size_t)(const void *)(("status") + 1) - (size_t)(const void *)("status") == 1) && (__s1_len = __builtin_strlen ("status"), __s1_len < 4) ? ( __builtin_constant_p (op) && ((size_t)(const void *)( (op) + 1) - (size_t)(const void *)(op) == 1) ? __builtin_strcmp ("status", op) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (op); int __result = (((const unsigned char *) (const char *) ("status"))[0] - __s2 [0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("status"))[1] - __s2 [1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("status"))[2] - __s2 [2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("status"))[3] - __s2 [3]); } } __result; }))) : (__builtin_constant_p (op) && ((size_t)(const void *)((op) + 1) - (size_t)(const void *)(op ) == 1) && (__s2_len = __builtin_strlen (op), __s2_len < 4) ? (__builtin_constant_p ("status") && ((size_t )(const void *)(("status") + 1) - (size_t)(const void *)("status" ) == 1) ? __builtin_strcmp ("status", op) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("status"); int __result = (((const unsigned char *) (const char *) (op))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (op))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( op))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (op)) [3] - __s2[3]); } } __result; })))) : __builtin_strcmp ("status" , op)))); })) { |
| 2608 | /* call show nat api */ |
| 2609 | } else if (!strcmp("status_response", op)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ("status_response") && __builtin_constant_p (op) && (__s1_len = __builtin_strlen ("status_response"), __s2_len = __builtin_strlen (op), (!((size_t)(const void *)(("status_response" ) + 1) - (size_t)(const void *)("status_response") == 1) || __s1_len >= 4) && (!((size_t)(const void *)((op) + 1) - (size_t )(const void *)(op) == 1) || __s2_len >= 4)) ? __builtin_strcmp ("status_response", op) : (__builtin_constant_p ("status_response" ) && ((size_t)(const void *)(("status_response") + 1) - (size_t)(const void *)("status_response") == 1) && (__s1_len = __builtin_strlen ("status_response"), __s1_len < 4) ? (__builtin_constant_p (op) && ((size_t)(const void *)((op) + 1) - (size_t)(const void *)(op) == 1) ? __builtin_strcmp ("status_response", op) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (op); int __result = (((const unsigned char *) (const char *) ("status_response" ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("status_response" ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) ("status_response" ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) ("status_response" ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( op) && ((size_t)(const void *)((op) + 1) - (size_t)(const void *)(op) == 1) && (__s2_len = __builtin_strlen (op ), __s2_len < 4) ? (__builtin_constant_p ("status_response" ) && ((size_t)(const void *)(("status_response") + 1) - (size_t)(const void *)("status_response") == 1) ? __builtin_strcmp ("status_response", op) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("status_response" ); int __result = (((const unsigned char *) (const char *) (op ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (op)) [1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (op))[ 2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (op))[3] - __s2[3 ]); } } __result; })))) : __builtin_strcmp ("status_response" , op)))); })) { |
| 2610 | /* ignore */ |
| 2611 | } else { |
| 2612 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2612, ((void*)0), SWITCH_LOG_ERROR, "Unknown op for SWITCH_EVENT_NAT: %s\n", op); |
| 2613 | } |
| 2614 | break; |
| 2615 | } |
| 2616 | default: |
| 2617 | break; |
| 2618 | } |
| 2619 | |
| 2620 | if (sql_idx) { |
| 2621 | int i = 0; |
| 2622 | |
| 2623 | |
| 2624 | for (i = 0; i < sql_idx; i++) { |
| 2625 | if (switch_stristr("update channels", sql[i]) || switch_stristr("delete from channels", sql[i])) { |
| 2626 | switch_sql_queue_manager_push(sql_manager.qm, sql[i], 1, SWITCH_FALSE); |
| 2627 | } else { |
| 2628 | switch_sql_queue_manager_push(sql_manager.qm, sql[i], 0, SWITCH_FALSE); |
| 2629 | } |
| 2630 | sql[i] = NULL((void*)0); |
| 2631 | } |
| 2632 | } |
| 2633 | } |
| 2634 | |
| 2635 | |
| 2636 | static char create_complete_sql[] = |
| 2637 | "CREATE TABLE complete (\n" |
| 2638 | " sticky INTEGER,\n" |
| 2639 | " a1 VARCHAR(128),\n" |
| 2640 | " a2 VARCHAR(128),\n" |
| 2641 | " a3 VARCHAR(128),\n" |
| 2642 | " a4 VARCHAR(128),\n" |
| 2643 | " a5 VARCHAR(128),\n" |
| 2644 | " a6 VARCHAR(128),\n" |
| 2645 | " a7 VARCHAR(128),\n" |
| 2646 | " a8 VARCHAR(128),\n" |
| 2647 | " a9 VARCHAR(128),\n" |
| 2648 | " a10 VARCHAR(128),\n" |
| 2649 | " hostname VARCHAR(256)\n" |
| 2650 | ");\n"; |
| 2651 | |
| 2652 | static char create_alias_sql[] = |
| 2653 | "CREATE TABLE aliases (\n" |
| 2654 | " sticky INTEGER,\n" |
| 2655 | " alias VARCHAR(128),\n" |
| 2656 | " command VARCHAR(4096),\n" |
| 2657 | " hostname VARCHAR(256)\n" |
| 2658 | ");\n"; |
| 2659 | |
| 2660 | static char create_channels_sql[] = |
| 2661 | "CREATE TABLE channels (\n" |
| 2662 | " uuid VARCHAR(256),\n" |
| 2663 | " direction VARCHAR(32),\n" |
| 2664 | " created VARCHAR(128),\n" |
| 2665 | " created_epoch INTEGER,\n" |
| 2666 | " name VARCHAR(1024),\n" |
| 2667 | " state VARCHAR(64),\n" |
| 2668 | " cid_name VARCHAR(1024),\n" |
| 2669 | " cid_num VARCHAR(256),\n" |
| 2670 | " ip_addr VARCHAR(256),\n" |
| 2671 | " dest VARCHAR(1024),\n" |
| 2672 | " application VARCHAR(128),\n" |
| 2673 | " application_data VARCHAR(4096),\n" |
| 2674 | " dialplan VARCHAR(128),\n" |
| 2675 | " context VARCHAR(128),\n" |
| 2676 | " read_codec VARCHAR(128),\n" |
| 2677 | " read_rate VARCHAR(32),\n" |
| 2678 | " read_bit_rate VARCHAR(32),\n" |
| 2679 | " write_codec VARCHAR(128),\n" |
| 2680 | " write_rate VARCHAR(32),\n" |
| 2681 | " write_bit_rate VARCHAR(32),\n" |
| 2682 | " secure VARCHAR(64),\n" |
| 2683 | " hostname VARCHAR(256),\n" |
| 2684 | " presence_id VARCHAR(4096),\n" |
| 2685 | " presence_data VARCHAR(4096),\n" |
| 2686 | " callstate VARCHAR(64),\n" |
| 2687 | " callee_name VARCHAR(1024),\n" |
| 2688 | " callee_num VARCHAR(256),\n" |
| 2689 | " callee_direction VARCHAR(5),\n" |
| 2690 | " call_uuid VARCHAR(256),\n" |
| 2691 | " sent_callee_name VARCHAR(1024),\n" |
| 2692 | " sent_callee_num VARCHAR(256),\n" |
| 2693 | " initial_cid_name VARCHAR(1024),\n" |
| 2694 | " initial_cid_num VARCHAR(256),\n" |
| 2695 | " initial_ip_addr VARCHAR(256),\n" |
| 2696 | " initial_dest VARCHAR(1024),\n" |
| 2697 | " initial_dialplan VARCHAR(128),\n" |
| 2698 | " initial_context VARCHAR(128)\n" |
| 2699 | ");\n"; |
| 2700 | |
| 2701 | static char create_calls_sql[] = |
| 2702 | "CREATE TABLE calls (\n" |
| 2703 | " call_uuid VARCHAR(255),\n" |
| 2704 | " call_created VARCHAR(128),\n" |
| 2705 | " call_created_epoch INTEGER,\n" |
| 2706 | " caller_uuid VARCHAR(256),\n" |
| 2707 | " callee_uuid VARCHAR(256),\n" |
| 2708 | " hostname VARCHAR(256)\n" |
| 2709 | ");\n"; |
| 2710 | |
| 2711 | static char create_interfaces_sql[] = |
| 2712 | "CREATE TABLE interfaces (\n" |
| 2713 | " type VARCHAR(128),\n" |
| 2714 | " name VARCHAR(1024),\n" |
| 2715 | " description VARCHAR(4096),\n" |
| 2716 | " ikey VARCHAR(1024),\n" |
| 2717 | " filename VARCHAR(4096),\n" |
| 2718 | " syntax VARCHAR(4096),\n" |
| 2719 | " hostname VARCHAR(256)\n" |
| 2720 | ");\n"; |
| 2721 | |
| 2722 | static char create_tasks_sql[] = |
| 2723 | "CREATE TABLE tasks (\n" |
| 2724 | " task_id INTEGER,\n" |
| 2725 | " task_desc VARCHAR(4096),\n" |
| 2726 | " task_group VARCHAR(1024),\n" |
| 2727 | " task_sql_manager INTEGER,\n" |
| 2728 | " hostname VARCHAR(256)\n" |
| 2729 | ");\n"; |
| 2730 | |
| 2731 | static char create_nat_sql[] = |
| 2732 | "CREATE TABLE nat (\n" |
| 2733 | " sticky INTEGER,\n" |
| 2734 | " port INTEGER,\n" |
| 2735 | " proto INTEGER,\n" |
| 2736 | " hostname VARCHAR(256)\n" |
| 2737 | ");\n"; |
| 2738 | |
| 2739 | |
| 2740 | static char create_registrations_sql[] = |
| 2741 | "CREATE TABLE registrations (\n" |
| 2742 | " reg_user VARCHAR(256),\n" |
| 2743 | " realm VARCHAR(256),\n" |
| 2744 | " token VARCHAR(256),\n" |
| 2745 | /* If url is modified please check for code in switch_core_sqldb_start for dependencies for MSSQL" */ |
| 2746 | " url TEXT,\n" |
| 2747 | " expires INTEGER,\n" |
| 2748 | " network_ip VARCHAR(256),\n" |
| 2749 | " network_port VARCHAR(256),\n" |
| 2750 | " network_proto VARCHAR(256),\n" |
| 2751 | " hostname VARCHAR(256),\n" |
| 2752 | " metadata VARCHAR(256)\n" |
| 2753 | ");\n"; |
| 2754 | |
| 2755 | |
| 2756 | |
| 2757 | |
| 2758 | static char detailed_calls_sql[] = |
| 2759 | "create view detailed_calls as select " |
| 2760 | "a.uuid as uuid," |
| 2761 | "a.direction as direction," |
| 2762 | "a.created as created," |
| 2763 | "a.created_epoch as created_epoch," |
| 2764 | "a.name as name," |
| 2765 | "a.state as state," |
| 2766 | "a.cid_name as cid_name," |
| 2767 | "a.cid_num as cid_num," |
| 2768 | "a.ip_addr as ip_addr," |
| 2769 | "a.dest as dest," |
| 2770 | "a.application as application," |
| 2771 | "a.application_data as application_data," |
| 2772 | "a.dialplan as dialplan," |
| 2773 | "a.context as context," |
| 2774 | "a.read_codec as read_codec," |
| 2775 | "a.read_rate as read_rate," |
| 2776 | "a.read_bit_rate as read_bit_rate," |
| 2777 | "a.write_codec as write_codec," |
| 2778 | "a.write_rate as write_rate," |
| 2779 | "a.write_bit_rate as write_bit_rate," |
| 2780 | "a.secure as secure," |
| 2781 | "a.hostname as hostname," |
| 2782 | "a.presence_id as presence_id," |
| 2783 | "a.presence_data as presence_data," |
| 2784 | "a.callstate as callstate," |
| 2785 | "a.callee_name as callee_name," |
| 2786 | "a.callee_num as callee_num," |
| 2787 | "a.callee_direction as callee_direction," |
| 2788 | "a.call_uuid as call_uuid," |
| 2789 | "a.sent_callee_name as sent_callee_name," |
| 2790 | "a.sent_callee_num as sent_callee_num," |
| 2791 | "b.uuid as b_uuid," |
| 2792 | "b.direction as b_direction," |
| 2793 | "b.created as b_created," |
| 2794 | "b.created_epoch as b_created_epoch," |
| 2795 | "b.name as b_name," |
| 2796 | "b.state as b_state," |
| 2797 | "b.cid_name as b_cid_name," |
| 2798 | "b.cid_num as b_cid_num," |
| 2799 | "b.ip_addr as b_ip_addr," |
| 2800 | "b.dest as b_dest," |
| 2801 | "b.application as b_application," |
| 2802 | "b.application_data as b_application_data," |
| 2803 | "b.dialplan as b_dialplan," |
| 2804 | "b.context as b_context," |
| 2805 | "b.read_codec as b_read_codec," |
| 2806 | "b.read_rate as b_read_rate," |
| 2807 | "b.read_bit_rate as b_read_bit_rate," |
| 2808 | "b.write_codec as b_write_codec," |
| 2809 | "b.write_rate as b_write_rate," |
| 2810 | "b.write_bit_rate as b_write_bit_rate," |
| 2811 | "b.secure as b_secure," |
| 2812 | "b.hostname as b_hostname," |
| 2813 | "b.presence_id as b_presence_id," |
| 2814 | "b.presence_data as b_presence_data," |
| 2815 | "b.callstate as b_callstate," |
| 2816 | "b.callee_name as b_callee_name," |
| 2817 | "b.callee_num as b_callee_num," |
| 2818 | "b.callee_direction as b_callee_direction," |
| 2819 | "b.call_uuid as b_call_uuid," |
| 2820 | "b.sent_callee_name as b_sent_callee_name," |
| 2821 | "b.sent_callee_num as b_sent_callee_num," |
| 2822 | "c.call_created_epoch as call_created_epoch " |
| 2823 | "from channels a " |
| 2824 | "left join calls c on a.uuid = c.caller_uuid and a.hostname = c.hostname " |
| 2825 | "left join channels b on b.uuid = c.callee_uuid and b.hostname = c.hostname " |
| 2826 | "where a.uuid = c.caller_uuid or a.uuid not in (select callee_uuid from calls)"; |
| 2827 | |
| 2828 | |
| 2829 | static char recovery_sql[] = |
| 2830 | "CREATE TABLE recovery (\n" |
| 2831 | " runtime_uuid VARCHAR(255),\n" |
| 2832 | " technology VARCHAR(255),\n" |
| 2833 | " profile_name VARCHAR(255),\n" |
| 2834 | " hostname VARCHAR(255),\n" |
| 2835 | " uuid VARCHAR(255),\n" |
| 2836 | " metadata text\n" |
| 2837 | ");\n"; |
| 2838 | |
| 2839 | static char basic_calls_sql[] = |
| 2840 | "create view basic_calls as select " |
| 2841 | "a.uuid as uuid," |
| 2842 | "a.direction as direction," |
| 2843 | "a.created as created," |
| 2844 | "a.created_epoch as created_epoch," |
| 2845 | "a.name as name," |
| 2846 | "a.state as state," |
| 2847 | "a.cid_name as cid_name," |
| 2848 | "a.cid_num as cid_num," |
| 2849 | "a.ip_addr as ip_addr," |
| 2850 | "a.dest as dest," |
| 2851 | |
| 2852 | "a.presence_id as presence_id," |
| 2853 | "a.presence_data as presence_data," |
| 2854 | "a.callstate as callstate," |
| 2855 | "a.callee_name as callee_name," |
| 2856 | "a.callee_num as callee_num," |
| 2857 | "a.callee_direction as callee_direction," |
| 2858 | "a.call_uuid as call_uuid," |
| 2859 | "a.hostname as hostname," |
| 2860 | "a.sent_callee_name as sent_callee_name," |
| 2861 | "a.sent_callee_num as sent_callee_num," |
| 2862 | |
| 2863 | |
| 2864 | "b.uuid as b_uuid," |
| 2865 | "b.direction as b_direction," |
| 2866 | "b.created as b_created," |
| 2867 | "b.created_epoch as b_created_epoch," |
| 2868 | "b.name as b_name," |
| 2869 | "b.state as b_state," |
| 2870 | "b.cid_name as b_cid_name," |
| 2871 | "b.cid_num as b_cid_num," |
| 2872 | "b.ip_addr as b_ip_addr," |
| 2873 | "b.dest as b_dest," |
| 2874 | |
| 2875 | "b.presence_id as b_presence_id," |
| 2876 | "b.presence_data as b_presence_data," |
| 2877 | "b.callstate as b_callstate," |
| 2878 | "b.callee_name as b_callee_name," |
| 2879 | "b.callee_num as b_callee_num," |
| 2880 | "b.callee_direction as b_callee_direction," |
| 2881 | "b.sent_callee_name as b_sent_callee_name," |
| 2882 | "b.sent_callee_num as b_sent_callee_num," |
| 2883 | "c.call_created_epoch as call_created_epoch " |
| 2884 | |
| 2885 | "from channels a " |
| 2886 | "left join calls c on a.uuid = c.caller_uuid and a.hostname = c.hostname " |
| 2887 | "left join channels b on b.uuid = c.callee_uuid and b.hostname = c.hostname " |
| 2888 | "where a.uuid = c.caller_uuid or a.uuid not in (select callee_uuid from calls)"; |
| 2889 | |
| 2890 | |
| 2891 | |
| 2892 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_recovery_flush(const char *technology, const char *profile_name) |
| 2893 | { |
| 2894 | char *sql = NULL((void*)0); |
| 2895 | switch_cache_db_handle_t *dbh; |
| 2896 | |
| 2897 | if (switch_core_db_handle(&dbh)_switch_core_db_handle(&dbh, "src/switch_core_sqldb.c", ( const char *)__func__, 2897) != SWITCH_STATUS_SUCCESS) { |
| 2898 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2898, ((void*)0), SWITCH_LOG_ERROR, "Error Opening DB!\n"); |
| 2899 | return; |
| 2900 | } |
| 2901 | |
| 2902 | if (zstr(technology)_zstr(technology)) { |
| 2903 | |
| 2904 | if (zstr(profile_name)_zstr(profile_name)) { |
| 2905 | sql = switch_mprintf("delete from recovery"); |
| 2906 | } else { |
| 2907 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2907, ((void*)0), SWITCH_LOG_WARNING, "INVALID\n"); |
| 2908 | } |
| 2909 | |
| 2910 | } else { |
| 2911 | if (zstr(profile_name)_zstr(profile_name)) { |
| 2912 | sql = switch_mprintf("delete from recovery where technology='%q' ", technology); |
| 2913 | } else { |
| 2914 | sql = switch_mprintf("delete from recovery where technology='%q' and profile_name='%q'", technology, profile_name); |
| 2915 | } |
| 2916 | } |
| 2917 | |
| 2918 | if (sql) { |
| 2919 | switch_cache_db_execute_sql(dbh, sql, NULL((void*)0)); |
| 2920 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; |
| 2921 | } |
| 2922 | |
| 2923 | switch_cache_db_release_db_handle(&dbh); |
| 2924 | } |
| 2925 | |
| 2926 | |
| 2927 | static int recover_callback(void *pArg, int argc, char **argv, char **columnNames) |
| 2928 | { |
| 2929 | int *rp = (int *) pArg; |
| 2930 | switch_xml_t xml; |
| 2931 | switch_endpoint_interface_t *ep; |
| 2932 | switch_core_session_t *session; |
| 2933 | |
| 2934 | if (argc < 4) { |
| 2935 | return 0; |
| 2936 | } |
| 2937 | |
| 2938 | if (!(xml = switch_xml_parse_str_dynamic(argv[4], SWITCH_TRUE))) { |
| 2939 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2939, ((void*)0), SWITCH_LOG_WARNING, "XML ERROR\n"); |
| 2940 | return 0; |
| 2941 | } |
| 2942 | |
| 2943 | if (!(ep = switch_loadable_module_get_endpoint_interface(argv[0]))) { |
| 2944 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2944, ((void*)0), SWITCH_LOG_WARNING, "EP ERROR\n"); |
| 2945 | return 0; |
| 2946 | } |
| 2947 | |
| 2948 | if (!(session = switch_core_session_request_xml(ep, NULL((void*)0), xml))) { |
| 2949 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 2949, ((void*)0), SWITCH_LOG_WARNING, "Invalid cdr data, call not recovered\n"); |
| 2950 | goto end; |
| 2951 | } |
| 2952 | |
| 2953 | if (ep->recover_callback) { |
| 2954 | switch_caller_extension_t *extension = NULL((void*)0); |
| 2955 | switch_channel_t *channel = switch_core_session_get_channel(session); |
| 2956 | int r = 0; |
| 2957 | |
| 2958 | if ((r = ep->recover_callback(session)) > 0) { |
| 2959 | const char *cbname; |
| 2960 | |
| 2961 | switch_channel_set_flag(session->channel, CF_RECOVERING)switch_channel_set_flag_value(session->channel, CF_RECOVERING , 1); |
| 2962 | |
| 2963 | |
| 2964 | if (switch_channel_get_partner_uuid(channel)) { |
| 2965 | switch_channel_set_flag(channel, CF_RECOVERING_BRIDGE)switch_channel_set_flag_value(channel, CF_RECOVERING_BRIDGE, 1 ); |
| 2966 | } |
| 2967 | |
| 2968 | switch_core_media_recover_session(session); |
| 2969 | |
| 2970 | if ((cbname = switch_channel_get_variable(channel, "secondary_recovery_module")switch_channel_get_variable_dup(channel, "secondary_recovery_module" , SWITCH_TRUE, -1))) { |
| 2971 | switch_core_recover_callback_t recover_callback; |
| 2972 | |
| 2973 | if ((recover_callback = switch_core_get_secondary_recover_callback(cbname))) { |
| 2974 | r = recover_callback(session); |
| 2975 | } |
| 2976 | } |
| 2977 | |
| 2978 | |
| 2979 | } |
| 2980 | |
| 2981 | if (r > 0) { |
| 2982 | |
| 2983 | if (!switch_channel_test_flag(channel, CF_RECOVERING_BRIDGE)) { |
| 2984 | switch_xml_t callflow, param, x_extension; |
| 2985 | if ((extension = switch_caller_extension_new(session, "recovery", "recovery")) == 0) { |
| 2986 | abort(); |
| 2987 | } |
| 2988 | |
| 2989 | if ((callflow = switch_xml_child(xml, "callflow")) && (x_extension = switch_xml_child(callflow, "extension"))) { |
| 2990 | for (param = switch_xml_child(x_extension, "application"); param; param = param->next) { |
| 2991 | const char *var = switch_xml_attr_soft(param, "app_name"); |
| 2992 | const char *val = switch_xml_attr_soft(param, "app_data"); |
| 2993 | /* skip announcement type apps */ |
| 2994 | if (strcasecmp(var, "speak") && strcasecmp(var, "playback") && strcasecmp(var, "gentones") && strcasecmp(var, "say")) { |
| 2995 | switch_caller_extension_add_application(session, extension, var, val); |
| 2996 | } |
| 2997 | } |
| 2998 | } |
| 2999 | |
| 3000 | switch_channel_set_caller_extension(channel, extension); |
| 3001 | } |
| 3002 | |
| 3003 | switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "src/switch_core_sqldb.c" , (const char *)__func__, 3003, CS_INIT); |
| 3004 | switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_sqldb.c", (const char *)__func__, 3004, (const char*)(session), SWITCH_LOG_NOTICE, |
| 3005 | "Resurrecting fallen channel %s\n", switch_channel_get_name(channel)); |
| 3006 | switch_core_session_thread_launch(session); |
| 3007 | |
| 3008 | *rp = (*rp) + 1; |
| 3009 | |
| 3010 | } |
| 3011 | |
| 3012 | } else { |
| 3013 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3013, ((void*)0), SWITCH_LOG_WARNING, "Endpoint %s has no recovery function\n", argv[0]); |
| 3014 | } |
| 3015 | |
| 3016 | |
| 3017 | end: |
| 3018 | |
| 3019 | UNPROTECT_INTERFACE(ep)if (ep) {switch_mutex_lock(ep->reflock); switch_thread_rwlock_unlock (ep->rwlock); switch_thread_rwlock_unlock(ep->parent-> rwlock); ep->refs--; ep->parent->refs--; switch_mutex_unlock (ep->reflock);}; |
| 3020 | |
| 3021 | switch_xml_free(xml); |
| 3022 | |
| 3023 | return 0; |
| 3024 | } |
| 3025 | |
| 3026 | SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_recovery_recover(const char *technology, const char *profile_name) |
| 3027 | |
| 3028 | { |
| 3029 | char *sql = NULL((void*)0); |
| 3030 | char *errmsg = NULL((void*)0); |
| 3031 | switch_cache_db_handle_t *dbh; |
| 3032 | int r = 0; |
| 3033 | |
| 3034 | if (!sql_manager.manage) { |
| 3035 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3035, ((void*)0), SWITCH_LOG_ERROR, "DATABASE NOT AVAIALBLE, REVCOVERY NOT POSSIBLE\n"); |
| 3036 | return 0; |
| 3037 | } |
| 3038 | |
| 3039 | if (switch_core_db_handle(&dbh)_switch_core_db_handle(&dbh, "src/switch_core_sqldb.c", ( const char *)__func__, 3039) != SWITCH_STATUS_SUCCESS) { |
| 3040 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3040, ((void*)0), SWITCH_LOG_ERROR, "Error Opening DB!\n"); |
| 3041 | return 0; |
| 3042 | } |
| 3043 | |
| 3044 | if (zstr(technology)_zstr(technology)) { |
| 3045 | |
| 3046 | if (zstr(profile_name)_zstr(profile_name)) { |
| 3047 | sql = switch_mprintf("select technology, profile_name, hostname, uuid, metadata " |
| 3048 | "from recovery where runtime_uuid!='%q'", |
| 3049 | switch_core_get_uuid()); |
| 3050 | } else { |
| 3051 | sql = switch_mprintf("select technology, profile_name, hostname, uuid, metadata " |
| 3052 | "from recovery where runtime_uuid!='%q' and profile_name='%q'", |
| 3053 | switch_core_get_uuid(), profile_name); |
| 3054 | } |
| 3055 | |
| 3056 | } else { |
| 3057 | |
| 3058 | if (zstr(profile_name)_zstr(profile_name)) { |
| 3059 | sql = switch_mprintf("select technology, profile_name, hostname, uuid, metadata " |
| 3060 | "from recovery where technology='%q' and runtime_uuid!='%q'", |
| 3061 | technology, switch_core_get_uuid()); |
| 3062 | } else { |
| 3063 | sql = switch_mprintf("select technology, profile_name, hostname, uuid, metadata " |
| 3064 | "from recovery where technology='%q' and runtime_uuid!='%q' and profile_name='%q'", |
| 3065 | technology, switch_core_get_uuid(), profile_name); |
| 3066 | } |
| 3067 | } |
| 3068 | |
| 3069 | |
| 3070 | switch_cache_db_execute_sql_callback(dbh, sql, recover_callback, &r, &errmsg); |
| 3071 | |
| 3072 | if (errmsg) { |
| 3073 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3073, ((void*)0), SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); |
| 3074 | switch_safe_free(errmsg)if (errmsg) {free(errmsg);errmsg=((void*)0);}; |
| 3075 | } |
| 3076 | |
| 3077 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; |
| 3078 | |
| 3079 | if (zstr(technology)_zstr(technology)) { |
| 3080 | if (zstr(profile_name)_zstr(profile_name)) { |
| 3081 | sql = switch_mprintf("delete from recovery where runtime_uuid!='%q'", |
| 3082 | switch_core_get_uuid()); |
| 3083 | } else { |
| 3084 | sql = switch_mprintf("delete from recovery where runtime_uuid!='%q' and profile_name='%q'", |
| 3085 | switch_core_get_uuid(), profile_name); |
| 3086 | } |
| 3087 | } else { |
| 3088 | if (zstr(profile_name)_zstr(profile_name)) { |
| 3089 | sql = switch_mprintf("delete from recovery where runtime_uuid!='%q' and technology='%q' ", |
| 3090 | switch_core_get_uuid(), technology); |
| 3091 | } else { |
| 3092 | sql = switch_mprintf("delete from recovery where runtime_uuid!='%q' and technology='%q' and profile_name='%q'", |
| 3093 | switch_core_get_uuid(), technology, profile_name); |
| 3094 | } |
| 3095 | } |
| 3096 | |
| 3097 | switch_cache_db_execute_sql(dbh, sql, NULL((void*)0)); |
| 3098 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; |
| 3099 | |
| 3100 | switch_cache_db_release_db_handle(&dbh); |
| 3101 | |
| 3102 | return r; |
| 3103 | |
| 3104 | } |
| 3105 | |
| 3106 | SWITCH_DECLARE(switch_cache_db_handle_type_t)__attribute__((visibility("default"))) switch_cache_db_handle_type_t switch_core_dbtype(void) |
| 3107 | { |
| 3108 | switch_cache_db_handle_type_t type = SCDB_TYPE_CORE_DB; |
| 3109 | |
| 3110 | switch_mutex_lock(sql_manager.ctl_mutex); |
| 3111 | if (sql_manager.qm && sql_manager.qm->event_db) { |
| 3112 | type = sql_manager.qm->event_db->type; |
| 3113 | } |
| 3114 | switch_mutex_unlock(sql_manager.ctl_mutex); |
| 3115 | |
| 3116 | return type; |
| 3117 | } |
| 3118 | |
| 3119 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_sql_exec(const char *sql) |
| 3120 | { |
| 3121 | if (!sql_manager.manage) { |
| 3122 | return; |
| 3123 | } |
| 3124 | |
| 3125 | if (!switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL)) { |
| 3126 | return; |
| 3127 | } |
| 3128 | |
| 3129 | |
| 3130 | switch_sql_queue_manager_push(sql_manager.qm, sql, 3, SWITCH_TRUE); |
| 3131 | } |
| 3132 | |
| 3133 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_recovery_untrack(switch_core_session_t *session, switch_bool_t force) |
| 3134 | { |
| 3135 | char *sql = NULL((void*)0); |
| 3136 | switch_channel_t *channel = switch_core_session_get_channel(session); |
| 3137 | |
| 3138 | if (!sql_manager.manage) { |
| 3139 | return; |
| 3140 | } |
| 3141 | |
| 3142 | if (!switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_get_state(channel) < CS_SOFT_EXECUTE) { |
| 3143 | return; |
| 3144 | } |
| 3145 | |
| 3146 | if (!switch_channel_test_flag(channel, CF_TRACKABLE)) { |
| 3147 | return; |
| 3148 | } |
| 3149 | |
| 3150 | if ((switch_channel_test_flag(channel, CF_RECOVERING))) { |
| 3151 | return; |
| 3152 | } |
| 3153 | |
| 3154 | if (switch_channel_test_flag(channel, CF_TRACKED) || force) { |
| 3155 | |
| 3156 | if (force) { |
| 3157 | sql = switch_mprintf("delete from recovery where uuid='%q'", switch_core_session_get_uuid(session)); |
| 3158 | |
| 3159 | } else { |
| 3160 | sql = switch_mprintf("delete from recovery where runtime_uuid='%q' and uuid='%q'", |
| 3161 | switch_core_get_uuid(), switch_core_session_get_uuid(session)); |
| 3162 | } |
| 3163 | |
| 3164 | switch_sql_queue_manager_push(sql_manager.qm, sql, 3, SWITCH_FALSE); |
| 3165 | |
| 3166 | switch_channel_clear_flag(channel, CF_TRACKED); |
| 3167 | } |
| 3168 | |
| 3169 | } |
| 3170 | |
| 3171 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_recovery_track(switch_core_session_t *session) |
| 3172 | { |
| 3173 | switch_xml_t cdr = NULL((void*)0); |
| 3174 | char *xml_cdr_text = NULL((void*)0); |
| 3175 | char *sql = NULL((void*)0); |
| 3176 | switch_channel_t *channel = switch_core_session_get_channel(session); |
| 3177 | const char *profile_name; |
| 3178 | const char *technology; |
| 3179 | |
| 3180 | if (!sql_manager.manage) { |
| 3181 | return; |
| 3182 | } |
| 3183 | |
| 3184 | if (!switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_get_state(channel) < CS_SOFT_EXECUTE) { |
| 3185 | return; |
| 3186 | } |
| 3187 | |
| 3188 | if (switch_channel_test_flag(channel, CF_RECOVERING) || !switch_channel_test_flag(channel, CF_TRACKABLE)) { |
| 3189 | return; |
| 3190 | } |
| 3191 | |
| 3192 | profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1); |
| 3193 | technology = session->endpoint_interface->interface_name; |
| 3194 | |
| 3195 | if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { |
| 3196 | xml_cdr_text = switch_xml_toxml_nolock(cdr, SWITCH_FALSE); |
| 3197 | switch_xml_free(cdr); |
| 3198 | } |
| 3199 | |
| 3200 | if (xml_cdr_text) { |
| 3201 | if (switch_channel_test_flag(channel, CF_TRACKED)) { |
| 3202 | sql = switch_mprintf("update recovery set metadata='%q' where uuid='%q'", xml_cdr_text, switch_core_session_get_uuid(session)); |
| 3203 | } else { |
| 3204 | sql = switch_mprintf("insert into recovery (runtime_uuid, technology, profile_name, hostname, uuid, metadata) " |
| 3205 | "values ('%q','%q','%q','%q','%q','%q')", |
| 3206 | switch_core_get_uuid(), switch_str_nil(technology)(technology ? technology : ""), |
| 3207 | switch_str_nil(profile_name)(profile_name ? profile_name : ""), switch_core_get_switchname(), switch_core_session_get_uuid(session), xml_cdr_text); |
| 3208 | } |
| 3209 | |
| 3210 | switch_sql_queue_manager_push(sql_manager.qm, sql, 2, SWITCH_FALSE); |
| 3211 | |
| 3212 | switch_safe_free(xml_cdr_text)if (xml_cdr_text) {free(xml_cdr_text);xml_cdr_text=((void*)0) ;}; |
| 3213 | switch_channel_set_flag(channel, CF_TRACKED)switch_channel_set_flag_value(channel, CF_TRACKED, 1); |
| 3214 | |
| 3215 | } |
| 3216 | |
| 3217 | } |
| 3218 | |
| 3219 | |
| 3220 | |
| 3221 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires, |
| 3222 | const char *network_ip, const char *network_port, const char *network_proto, |
| 3223 | const char *metadata) |
| 3224 | { |
| 3225 | char *sql; |
| 3226 | |
| 3227 | if (!switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL)) { |
| 3228 | return SWITCH_STATUS_FALSE; |
| 3229 | } |
| 3230 | |
| 3231 | if (runtime.multiple_registrations) { |
| 3232 | sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", |
| 3233 | switch_core_get_switchname(), url, switch_str_nil(token)(token ? token : "")); |
| 3234 | } else { |
| 3235 | sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", |
| 3236 | user, realm, switch_core_get_switchname()); |
| 3237 | } |
| 3238 | |
| 3239 | switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); |
| 3240 | |
| 3241 | if ( !zstr(metadata)_zstr(metadata) ) { |
| 3242 | sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname,metadata) " |
| 3243 | "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%q')", |
| 3244 | switch_str_nil(user)(user ? user : ""), |
| 3245 | switch_str_nil(realm)(realm ? realm : ""), |
| 3246 | switch_str_nil(token)(token ? token : ""), |
| 3247 | switch_str_nil(url)(url ? url : ""), |
| 3248 | expires, |
| 3249 | switch_str_nil(network_ip)(network_ip ? network_ip : ""), |
| 3250 | switch_str_nil(network_port)(network_port ? network_port : ""), |
| 3251 | switch_str_nil(network_proto)(network_proto ? network_proto : ""), |
| 3252 | switch_core_get_switchname(), |
| 3253 | metadata |
| 3254 | ); |
| 3255 | } else { |
| 3256 | sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) " |
| 3257 | "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')", |
| 3258 | switch_str_nil(user)(user ? user : ""), |
| 3259 | switch_str_nil(realm)(realm ? realm : ""), |
| 3260 | switch_str_nil(token)(token ? token : ""), |
| 3261 | switch_str_nil(url)(url ? url : ""), |
| 3262 | expires, |
| 3263 | switch_str_nil(network_ip)(network_ip ? network_ip : ""), |
| 3264 | switch_str_nil(network_port)(network_port ? network_port : ""), |
| 3265 | switch_str_nil(network_proto)(network_proto ? network_proto : ""), |
| 3266 | switch_core_get_switchname() |
| 3267 | ); |
| 3268 | } |
| 3269 | |
| 3270 | |
| 3271 | switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); |
| 3272 | |
| 3273 | return SWITCH_STATUS_SUCCESS; |
| 3274 | } |
| 3275 | |
| 3276 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_del_registration(const char *user, const char *realm, const char *token) |
| 3277 | { |
| 3278 | |
| 3279 | char *sql; |
| 3280 | |
| 3281 | if (!switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL)) { |
| 3282 | return SWITCH_STATUS_FALSE; |
| 3283 | } |
| 3284 | |
| 3285 | if (!zstr(token)_zstr(token) && runtime.multiple_registrations) { |
| 3286 | 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); |
| 3287 | } else { |
| 3288 | sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_switchname()); |
| 3289 | } |
| 3290 | |
| 3291 | switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); |
| 3292 | |
| 3293 | |
| 3294 | return SWITCH_STATUS_SUCCESS; |
| 3295 | } |
| 3296 | |
| 3297 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_expire_registration(int force) |
| 3298 | { |
| 3299 | |
| 3300 | char *sql; |
| 3301 | time_t now; |
| 3302 | |
| 3303 | if (!switch_test_flag((&runtime), SCF_USE_SQL)(((&runtime))->flags & SCF_USE_SQL)) { |
| 3304 | return SWITCH_STATUS_FALSE; |
| 3305 | } |
| 3306 | |
| 3307 | now = switch_epoch_time_now(NULL((void*)0)); |
| 3308 | |
| 3309 | if (force) { |
| 3310 | sql = switch_mprintf("delete from registrations where hostname='%q'", switch_core_get_switchname()); |
| 3311 | } else { |
| 3312 | sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_switchname()); |
| 3313 | } |
| 3314 | |
| 3315 | switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); |
| 3316 | |
| 3317 | return SWITCH_STATUS_SUCCESS; |
| 3318 | |
| 3319 | } |
| 3320 | |
| 3321 | switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage) |
| 3322 | { |
| 3323 | switch_threadattr_t *thd_attr; |
| 3324 | |
| 3325 | sql_manager.memory_pool = pool; |
| 3326 | sql_manager.manage = manage; |
| 3327 | |
| 3328 | switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED0x1, sql_manager.memory_pool); |
| 3329 | switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED0x1, sql_manager.memory_pool); |
| 3330 | switch_mutex_init(&sql_manager.ctl_mutex, SWITCH_MUTEX_NESTED0x1, sql_manager.memory_pool); |
| 3331 | |
| 3332 | if (!sql_manager.manage) goto skip; |
| 3333 | |
| 3334 | top: |
| 3335 | |
| 3336 | /* Activate SQL database */ |
| 3337 | if (switch_core_db_handle(&sql_manager.dbh)_switch_core_db_handle(&sql_manager.dbh, "src/switch_core_sqldb.c" , (const char *)__func__, 3337) != SWITCH_STATUS_SUCCESS) { |
| 3338 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3338, ((void*)0), SWITCH_LOG_ERROR, "Error Opening DB!\n"); |
| 3339 | |
| 3340 | if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)(((&runtime))->flags & SCF_CORE_NON_SQLITE_DB_REQ)) { |
| 3341 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3341, ((void*)0), SWITCH_LOG_CRIT, "Failure! ODBC IS REQUIRED!\n"); |
| 3342 | return SWITCH_STATUS_FALSE; |
| 3343 | } |
| 3344 | |
| 3345 | if (runtime.odbc_dsn) { |
| 3346 | runtime.odbc_dsn = NULL((void*)0); |
| 3347 | runtime.odbc_dbtype = DBTYPE_DEFAULT; |
| 3348 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3348, ((void*)0), SWITCH_LOG_WARNING, "Falling back to core_db.\n"); |
| 3349 | goto top; |
| 3350 | } |
| 3351 | |
| 3352 | |
| 3353 | switch_clear_flag((&runtime), SCF_USE_SQL)((&runtime))->flags &= ~(SCF_USE_SQL); |
| 3354 | return SWITCH_STATUS_FALSE; |
| 3355 | } |
| 3356 | |
| 3357 | |
| 3358 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3358, ((void*)0), SWITCH_LOG_INFO, "Opening DB\n"); |
| 3359 | |
| 3360 | switch (sql_manager.dbh->type) { |
| 3361 | case SCDB_TYPE_PGSQL: |
| 3362 | case SCDB_TYPE_ODBC: |
| 3363 | if (switch_test_flag((&runtime), SCF_CLEAR_SQL)(((&runtime))->flags & SCF_CLEAR_SQL)) { |
| 3364 | char sql[512] = ""; |
| 3365 | char *tables[] = { "channels", "calls", "tasks", NULL((void*)0) }; |
| 3366 | int i; |
| 3367 | const char *hostname = switch_core_get_switchname(); |
| 3368 | |
| 3369 | for (i = 0; tables[i]; i++) { |
| 3370 | switch_snprintfv(sql, sizeof(sql), "delete from %q where hostname='%q'", tables[i], hostname); |
| 3371 | switch_cache_db_execute_sql(sql_manager.dbh, sql, NULL((void*)0)); |
| 3372 | } |
| 3373 | } |
| 3374 | break; |
| 3375 | case SCDB_TYPE_CORE_DB: |
| 3376 | { |
| 3377 | switch_cache_db_execute_sql(sql_manager.dbh, "drop table channels", NULL((void*)0)); |
| 3378 | switch_cache_db_execute_sql(sql_manager.dbh, "drop table calls", NULL((void*)0)); |
| 3379 | switch_cache_db_execute_sql(sql_manager.dbh, "drop view detailed_calls", NULL((void*)0)); |
| 3380 | switch_cache_db_execute_sql(sql_manager.dbh, "drop view basic_calls", NULL((void*)0)); |
| 3381 | switch_cache_db_execute_sql(sql_manager.dbh, "drop table interfaces", NULL((void*)0)); |
| 3382 | switch_cache_db_execute_sql(sql_manager.dbh, "drop table tasks", NULL((void*)0)); |
| 3383 | switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA synchronous=OFF;", NULL((void*)0)); |
| 3384 | switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA count_changes=OFF;", NULL((void*)0)); |
| 3385 | switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA default_cache_size=8000", NULL((void*)0)); |
| 3386 | switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA temp_store=MEMORY;", NULL((void*)0)); |
| 3387 | switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA journal_mode=OFF;", NULL((void*)0)); |
| 3388 | } |
| 3389 | break; |
| 3390 | } |
| 3391 | |
| 3392 | switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); |
| 3393 | switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); |
| 3394 | switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); |
| 3395 | switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user=''", |
| 3396 | "DROP TABLE registrations", create_registrations_sql); |
| 3397 | |
| 3398 | switch_cache_db_test_reactive(sql_manager.dbh, "select metadata from registrations", NULL((void*)0), "ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256)"); |
| 3399 | |
| 3400 | |
| 3401 | switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from recovery", "DROP TABLE recovery", recovery_sql); |
| 3402 | switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery1 on recovery(technology)", NULL((void*)0)); |
| 3403 | switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery2 on recovery(profile_name)", NULL((void*)0)); |
| 3404 | switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery3 on recovery(uuid)", NULL((void*)0)); |
| 3405 | switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery3 on recovery(runtime_uuid)", NULL((void*)0)); |
| 3406 | |
| 3407 | |
| 3408 | |
| 3409 | |
| 3410 | switch (sql_manager.dbh->type) { |
| 3411 | case SCDB_TYPE_PGSQL: |
| 3412 | case SCDB_TYPE_ODBC: |
| 3413 | { |
| 3414 | char *err; |
| 3415 | int result = 0; |
| 3416 | |
| 3417 | switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name, initial_cid_name, initial_cid_num, initial_ip_addr, initial_dest, initial_dialplan, initial_context from channels", "DROP TABLE channels", create_channels_sql); |
| 3418 | switch_cache_db_test_reactive(sql_manager.dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); |
| 3419 | switch_cache_db_test_reactive(sql_manager.dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); |
| 3420 | switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); |
| 3421 | if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { |
| 3422 | switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user=''", |
| 3423 | "DROP TABLE registrations", create_registrations_sql); |
| 3424 | } else { |
| 3425 | char *tmp = switch_string_replace(create_registrations_sql, "url TEXT", "url VARCHAR(max)"); |
| 3426 | switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user=''", |
| 3427 | "DROP TABLE registrations", tmp); |
| 3428 | free(tmp); |
| 3429 | } |
| 3430 | switch_cache_db_test_reactive(sql_manager.dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); |
| 3431 | switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); |
| 3432 | |
| 3433 | |
| 3434 | switch(sql_manager.dbh->type) { |
| 3435 | case SCDB_TYPE_CORE_DB: |
| 3436 | { |
| 3437 | switch_cache_db_execute_sql_real(sql_manager.dbh, "BEGIN EXCLUSIVE", &err); |
| 3438 | } |
| 3439 | break; |
| 3440 | case SCDB_TYPE_ODBC: |
| 3441 | { |
| 3442 | switch_odbc_status_t result; |
| 3443 | |
| 3444 | if ((result = switch_odbc_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { |
| 3445 | char tmp[100]; |
| 3446 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); |
| 3447 | err = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 3448 | } |
| 3449 | } |
| 3450 | break; |
| 3451 | case SCDB_TYPE_PGSQL: |
| 3452 | { |
| 3453 | switch_pgsql_status_t result; |
| 3454 | |
| 3455 | if ((result = switch_pgsql_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { |
| 3456 | char tmp[100]; |
| 3457 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); |
| 3458 | err = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 3459 | } |
| 3460 | } |
| 3461 | break; |
| 3462 | } |
| 3463 | |
| 3464 | switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname=''", &err); |
| 3465 | if (!err) { |
| 3466 | switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname=''", &err); |
| 3467 | |
| 3468 | switch(sql_manager.dbh->type) { |
| 3469 | case SCDB_TYPE_CORE_DB: |
| 3470 | { |
| 3471 | switch_cache_db_execute_sql_real(sql_manager.dbh, "COMMIT", &err); |
| 3472 | } |
| 3473 | break; |
| 3474 | case SCDB_TYPE_ODBC: |
| 3475 | { |
| 3476 | if (switch_odbc_SQLEndTran(sql_manager.dbh->native_handle.odbc_dbh, 1) != SWITCH_ODBC_SUCCESS || |
| 3477 | switch_odbc_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.odbc_dbh, 1) != SWITCH_ODBC_SUCCESS) { |
| 3478 | char tmp[100]; |
| 3479 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction.", result); |
| 3480 | err = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 3481 | } |
| 3482 | } |
| 3483 | break; |
| 3484 | case SCDB_TYPE_PGSQL: |
| 3485 | { |
| 3486 | if (switch_pgsql_SQLEndTran(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS || |
| 3487 | switch_pgsql_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS || |
| 3488 | switch_pgsql_finish_results(sql_manager.dbh->native_handle.pgsql_dbh)switch_pgsql_finish_results_real("src/switch_core_sqldb.c", ( char * )(const char *)__func__, 3488, sql_manager.dbh->native_handle .pgsql_dbh) != SWITCH_PGSQL_SUCCESS) { |
| 3489 | char tmp[100]; |
| 3490 | switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction.", result); |
| 3491 | err = strdup(tmp)(__extension__ (__builtin_constant_p (tmp) && ((size_t )(const void *)((tmp) + 1) - (size_t)(const void *)(tmp) == 1 ) ? (((const char *) (tmp))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (tmp) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, tmp, __len); __retval ; })) : __strdup (tmp))); |
| 3492 | } |
| 3493 | } |
| 3494 | break; |
| 3495 | } |
| 3496 | } |
| 3497 | |
| 3498 | |
| 3499 | if (err) { |
| 3500 | //runtime.odbc_dsn = NULL; |
| 3501 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3501, ((void*)0), SWITCH_LOG_ERROR, "Database Error [%s]\n", err); |
| 3502 | //switch_cache_db_release_db_handle(&sql_manager.dbh); |
| 3503 | if (switch_stristr("read-only", err)) { |
| 3504 | switch_safe_free(err)if (err) {free(err);err=((void*)0);}; |
| 3505 | } else { |
| 3506 | switch_safe_free(err)if (err) {free(err);err=((void*)0);}; |
| 3507 | goto top; |
| 3508 | } |
| 3509 | } |
| 3510 | } |
| 3511 | break; |
| 3512 | case SCDB_TYPE_CORE_DB: |
| 3513 | { |
| 3514 | switch_cache_db_execute_sql(sql_manager.dbh, create_channels_sql, NULL((void*)0)); |
| 3515 | switch_cache_db_execute_sql(sql_manager.dbh, create_calls_sql, NULL((void*)0)); |
| 3516 | switch_cache_db_execute_sql(sql_manager.dbh, create_interfaces_sql, NULL((void*)0)); |
| 3517 | switch_cache_db_execute_sql(sql_manager.dbh, create_tasks_sql, NULL((void*)0)); |
| 3518 | switch_cache_db_execute_sql(sql_manager.dbh, detailed_calls_sql, NULL((void*)0)); |
| 3519 | switch_cache_db_execute_sql(sql_manager.dbh, basic_calls_sql, NULL((void*)0)); |
| 3520 | } |
| 3521 | break; |
| 3522 | } |
| 3523 | |
| 3524 | if (switch_test_flag((&runtime), SCF_CLEAR_SQL)(((&runtime))->flags & SCF_CLEAR_SQL)) { |
| 3525 | char sql[512] = ""; |
| 3526 | char *tables[] = { "complete", "aliases", "nat", NULL((void*)0) }; |
| 3527 | int i; |
| 3528 | const char *hostname = switch_core_get_hostname(); |
| 3529 | |
| 3530 | for (i = 0; tables[i]; i++) { |
| 3531 | switch_snprintfv(sql, sizeof(sql), "delete from %q where sticky=0 and hostname='%q'", tables[i], hostname); |
| 3532 | switch_cache_db_execute_sql(sql_manager.dbh, sql, NULL((void*)0)); |
| 3533 | } |
| 3534 | |
| 3535 | switch_snprintfv(sql, sizeof(sql), "delete from interfaces where hostname='%q'", hostname); |
| 3536 | switch_cache_db_execute_sql(sql_manager.dbh, sql, NULL((void*)0)); |
| 3537 | } |
| 3538 | |
| 3539 | switch_cache_db_execute_sql(sql_manager.dbh, "create index alias1 on aliases (alias)", NULL((void*)0)); |
| 3540 | switch_cache_db_execute_sql(sql_manager.dbh, "create index tasks1 on tasks (hostname,task_id)", NULL((void*)0)); |
| 3541 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete1 on complete (a1,hostname)", NULL((void*)0)); |
| 3542 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete2 on complete (a2,hostname)", NULL((void*)0)); |
| 3543 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete3 on complete (a3,hostname)", NULL((void*)0)); |
| 3544 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete4 on complete (a4,hostname)", NULL((void*)0)); |
| 3545 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete5 on complete (a5,hostname)", NULL((void*)0)); |
| 3546 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete6 on complete (a6,hostname)", NULL((void*)0)); |
| 3547 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete7 on complete (a7,hostname)", NULL((void*)0)); |
| 3548 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete8 on complete (a8,hostname)", NULL((void*)0)); |
| 3549 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete9 on complete (a9,hostname)", NULL((void*)0)); |
| 3550 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete10 on complete (a10,hostname)", NULL((void*)0)); |
| 3551 | switch_cache_db_execute_sql(sql_manager.dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL((void*)0)); |
| 3552 | switch_cache_db_execute_sql(sql_manager.dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL((void*)0)); |
| 3553 | switch_cache_db_execute_sql(sql_manager.dbh, "create index channels1 on channels(hostname)", NULL((void*)0)); |
| 3554 | switch_cache_db_execute_sql(sql_manager.dbh, "create index calls1 on calls(hostname)", NULL((void*)0)); |
| 3555 | switch_cache_db_execute_sql(sql_manager.dbh, "create index chidx1 on channels (hostname)", NULL((void*)0)); |
| 3556 | switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex on channels (uuid, hostname)", NULL((void*)0)); |
| 3557 | switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex2 on channels (call_uuid)", NULL((void*)0)); |
| 3558 | switch_cache_db_execute_sql(sql_manager.dbh, "create index callsidx1 on calls (hostname)", NULL((void*)0)); |
| 3559 | switch_cache_db_execute_sql(sql_manager.dbh, "create index eruuindex on calls (caller_uuid, hostname)", NULL((void*)0)); |
| 3560 | switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex on calls (callee_uuid)", NULL((void*)0)); |
| 3561 | switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex2 on calls (call_uuid)", NULL((void*)0)); |
| 3562 | switch_cache_db_execute_sql(sql_manager.dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL((void*)0)); |
| 3563 | |
| 3564 | |
| 3565 | skip: |
| 3566 | |
| 3567 | if (sql_manager.manage) { |
| 3568 | #ifdef SWITCH_SQL_BIND_EVERY_EVENT |
| 3569 | switch_event_bind("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3570 | #else |
| 3571 | switch_event_bind("core_db", SWITCH_EVENT_ADD_SCHEDULE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3572 | switch_event_bind("core_db", SWITCH_EVENT_DEL_SCHEDULE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3573 | switch_event_bind("core_db", SWITCH_EVENT_EXE_SCHEDULE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3574 | switch_event_bind("core_db", SWITCH_EVENT_RE_SCHEDULE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3575 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_DESTROY, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3576 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_UUID, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3577 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_CREATE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3578 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_ANSWER, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3579 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3580 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_HOLD, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3581 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_UNHOLD, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3582 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_EXECUTE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3583 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_ORIGINATE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3584 | switch_event_bind("core_db", SWITCH_EVENT_CALL_UPDATE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3585 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_CALLSTATE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3586 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_STATE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3587 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_BRIDGE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3588 | switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_UNBRIDGE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3589 | switch_event_bind("core_db", SWITCH_EVENT_SHUTDOWN, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3590 | switch_event_bind("core_db", SWITCH_EVENT_LOG, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3591 | switch_event_bind("core_db", SWITCH_EVENT_MODULE_LOAD, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3592 | switch_event_bind("core_db", SWITCH_EVENT_MODULE_UNLOAD, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3593 | switch_event_bind("core_db", SWITCH_EVENT_CALL_SECURE, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3594 | switch_event_bind("core_db", SWITCH_EVENT_NAT, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3595 | switch_event_bind("core_db", SWITCH_EVENT_CODEC, SWITCH_EVENT_SUBCLASS_ANY((void*)0), core_event_handler, NULL((void*)0)); |
| 3596 | #endif |
| 3597 | |
| 3598 | switch_threadattr_create(&thd_attr, sql_manager.memory_pool); |
| 3599 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); |
| 3600 | switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); |
| 3601 | switch_core_sqldb_start_thread(); |
| 3602 | switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL((void*)0), sql_manager.memory_pool); |
| 3603 | |
| 3604 | } |
| 3605 | |
| 3606 | switch_cache_db_release_db_handle(&sql_manager.dbh); |
| 3607 | |
| 3608 | return SWITCH_STATUS_SUCCESS; |
| 3609 | } |
| 3610 | |
| 3611 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_sqldb_pause(void) |
| 3612 | { |
| 3613 | if (sql_manager.paused) { |
| 3614 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3614, ((void*)0), SWITCH_LOG_WARNING, "SQL is already paused.\n"); |
| 3615 | } |
| 3616 | sql_manager.paused = 1; |
| 3617 | } |
| 3618 | |
| 3619 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_sqldb_resume(void) |
| 3620 | { |
| 3621 | if (!sql_manager.paused) { |
| 3622 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3622, ((void*)0), SWITCH_LOG_WARNING, "SQL is already running.\n"); |
| 3623 | } |
| 3624 | sql_manager.paused = 0; |
| 3625 | } |
| 3626 | |
| 3627 | |
| 3628 | static void switch_core_sqldb_stop_thread(void) |
| 3629 | { |
| 3630 | switch_mutex_lock(sql_manager.ctl_mutex); |
| 3631 | if (sql_manager.manage) { |
| 3632 | if (sql_manager.qm) { |
| 3633 | switch_sql_queue_manager_destroy(&sql_manager.qm); |
| 3634 | } |
| 3635 | } else { |
| 3636 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3636, ((void*)0), SWITCH_LOG_ERROR, "SQL is not enabled\n"); |
| 3637 | } |
| 3638 | |
| 3639 | switch_mutex_unlock(sql_manager.ctl_mutex); |
| 3640 | } |
| 3641 | |
| 3642 | static void switch_core_sqldb_start_thread(void) |
| 3643 | { |
| 3644 | |
| 3645 | switch_mutex_lock(sql_manager.ctl_mutex); |
| 3646 | if (sql_manager.manage) { |
| 3647 | if (!sql_manager.qm) { |
| 3648 | char *dbname = runtime.odbc_dsn; |
| 3649 | |
| 3650 | if (zstr(dbname)_zstr(dbname)) { |
| 3651 | dbname = runtime.dbname; |
| 3652 | if (zstr(dbname)_zstr(dbname)) { |
| 3653 | dbname = "core"; |
| 3654 | } |
| 3655 | } |
| 3656 | |
| 3657 | switch_sql_queue_manager_init_name("CORE", |
| 3658 | &sql_manager.qm, |
| 3659 | 4, |
| 3660 | dbname, |
| 3661 | SWITCH_MAX_TRANS2000, |
| 3662 | runtime.core_db_pre_trans_execute, |
| 3663 | runtime.core_db_post_trans_execute, |
| 3664 | runtime.core_db_inner_pre_trans_execute, |
| 3665 | runtime.core_db_inner_post_trans_execute); |
| 3666 | |
| 3667 | } |
| 3668 | switch_sql_queue_manager_start(sql_manager.qm); |
| 3669 | } else { |
| 3670 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_sqldb.c", (const char *)__func__, 3670, ((void*)0), SWITCH_LOG_ERROR, "SQL is not enabled\n"); |
| 3671 | } |
| 3672 | switch_mutex_unlock(sql_manager.ctl_mutex); |
| 3673 | } |
| 3674 | |
| 3675 | void switch_core_sqldb_stop(void) |
| 3676 | { |
| 3677 | switch_status_t st; |
| 3678 | |
| 3679 | switch_event_unbind_callback(core_event_handler); |
| 3680 | |
| 3681 | if (sql_manager.db_thread && sql_manager.db_thread_running) { |
| 3682 | sql_manager.db_thread_running = -1; |
| 3683 | switch_thread_join(&st, sql_manager.db_thread); |
| 3684 | } |
| 3685 | |
| 3686 | switch_core_sqldb_stop_thread(); |
| 3687 | |
| 3688 | switch_cache_db_flush_handles(); |
| 3689 | sql_close(0); |
| 3690 | } |
| 3691 | |
| 3692 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_cache_db_status(switch_stream_handle_t *stream) |
| 3693 | { |
| 3694 | /* return some status info suitable for the cli */ |
| 3695 | switch_cache_db_handle_t *dbh = NULL((void*)0); |
| 3696 | switch_bool_t locked = SWITCH_FALSE; |
| 3697 | time_t now = switch_epoch_time_now(NULL((void*)0)); |
| 3698 | char cleankey_str[CACHE_DB_LEN256]; |
| 3699 | char *pos1 = NULL((void*)0); |
| 3700 | char *pos2 = NULL((void*)0); |
| 3701 | int count = 0, used = 0; |
| 3702 | |
| 3703 | switch_mutex_lock(sql_manager.dbh_mutex); |
| 3704 | |
| 3705 | for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) { |
| 3706 | char *needles[3]; |
| 3707 | time_t diff = 0; |
| 3708 | int i = 0; |
| 3709 | |
| 3710 | needles[0] = "pass=\""; |
| 3711 | needles[1] = "password="; |
| 3712 | needles[2] = "password='"; |
| 3713 | |
| 3714 | diff = now - dbh->last_used; |
| 3715 | |
| 3716 | if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) { |
| 3717 | switch_mutex_unlock(dbh->mutex); |
| 3718 | locked = SWITCH_FALSE; |
| 3719 | } else { |
| 3720 | locked = SWITCH_TRUE; |
| 3721 | } |
| 3722 | |
| 3723 | /* sanitize password */ |
| 3724 | memset(cleankey_str, 0, sizeof(cleankey_str)); |
| 3725 | for (i = 0; i < 3; i++) { |
| 3726 | if((pos1 = strstr(dbh->name, needles[i]))) { |
| 3727 | pos1 += strlen(needles[i]); |
| 3728 | |
| 3729 | if (!(pos2 = strstr(pos1, "\""))) { |
| 3730 | if (!(pos2 = strstr(pos1, "'"))) { |
| 3731 | if (!(pos2 = strstr(pos1, " "))) { |
| 3732 | pos2 = pos1 + strlen(pos1); |
| 3733 | } |
| 3734 | } |
| 3735 | } |
| 3736 | strncpy(cleankey_str, dbh->name, pos1 - dbh->name)__builtin_strncpy (cleankey_str, dbh->name, pos1 - dbh-> name); |
| 3737 | strcpy(&cleankey_str[pos1 - dbh->name], pos2); |
| 3738 | break; |
| 3739 | } |
| 3740 | } |
| 3741 | if (i == 3) { |
| 3742 | strncpy(cleankey_str, dbh->name, strlen(dbh->name))__builtin_strncpy (cleankey_str, dbh->name, strlen(dbh-> name)); |
| 3743 | } |
| 3744 | |
| 3745 | count++; |
| 3746 | |
| 3747 | if (dbh->use_count) { |
| 3748 | used++; |
| 3749 | } |
| 3750 | |
| 3751 | stream->write_function(stream, "%s\n\tType: %s\n\tLast used: %d\n\tTotal used: %ld\n\tFlags: %s, %s(%d)\n" |
| 3752 | "\tCreator: %s\n\tLast User: %s\n", |
| 3753 | cleankey_str, |
| 3754 | switch_cache_db_type_name(dbh->type), |
| 3755 | diff, |
| 3756 | dbh->total_used_count, |
| 3757 | locked ? "Locked" : "Unlocked", |
| 3758 | dbh->use_count ? "Attached" : "Detached", dbh->use_count, dbh->creator, dbh->last_user); |
| 3759 | } |
| 3760 | |
| 3761 | stream->write_function(stream, "%d total. %d in use.\n", count, used); |
| 3762 | |
| 3763 | switch_mutex_unlock(sql_manager.dbh_mutex); |
| 3764 | } |
| 3765 | |
| 3766 | SWITCH_DECLARE(char*)__attribute__((visibility("default"))) char*switch_sql_concat(void) |
| 3767 | { |
| 3768 | if(runtime.odbc_dbtype == DBTYPE_MSSQL) |
| 3769 | return "+"; |
| 3770 | |
| 3771 | return "||"; |
| 3772 | } |
| 3773 | |
| 3774 | /* For Emacs: |
| 3775 | * Local Variables: |
| 3776 | * mode:c |
| 3777 | * indent-tabs-mode:t |
| 3778 | * tab-width:4 |
| 3779 | * c-basic-offset:4 |
| 3780 | * End: |
| 3781 | * For VIM: |
| 3782 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: |
| 3783 | */ |