Bug Summary

File:src/switch_core_sqldb.c
Location:line 420, column 4
Description:Value stored to 'db_name' is never read

Annotated Source Code

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
41struct 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
59static 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
76static void switch_core_sqldb_start_thread(void);
77static void switch_core_sqldb_stop_thread(void);
78
79static 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
93static 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
116static 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
137static 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*/
183SWITCH_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
211static 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
285SWITCH_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
290SWITCH_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
296SWITCH_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
328SWITCH_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
334SWITCH_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
383SWITCH_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
539static 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**/
604static 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
665SWITCH_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
687SWITCH_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
709SWITCH_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
733SWITCH_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
800SWITCH_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
838SWITCH_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
1021struct helper {
1022 switch_core_db_event_callback_func_t callback;
1023 void *pdata;
1024};
1025
1026static 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
1041SWITCH_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
1094SWITCH_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
1160SWITCH_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
1209SWITCH_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 */
1285SWITCH_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
1365static 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
1389static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, void *obj);
1390
1391struct 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
1415static 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
1442static 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
1454struct 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
1466static 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
1503static 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
1539SWITCH_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
1549SWITCH_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
1560SWITCH_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
1570SWITCH_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
1583static 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
1602SWITCH_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
1612SWITCH_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
1628SWITCH_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
1641SWITCH_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
1674SWITCH_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
1690SWITCH_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
1717SWITCH_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
1759SWITCH_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
1833SWITCH_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
1888static 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
2031static 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
2143static 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
2193static 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
2636static 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
2652static 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
2660static 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
2701static 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
2711static 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
2722static 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
2731static 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
2740static 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
2758static 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
2829static 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
2839static 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
2892SWITCH_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
2927static 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
3026SWITCH_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
3106SWITCH_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
3119SWITCH_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
3133SWITCH_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
3171SWITCH_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
3221SWITCH_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
3276SWITCH_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
3297SWITCH_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
3321switch_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
3611SWITCH_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
3619SWITCH_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
3628static 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
3642static 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
3675void 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
3692SWITCH_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
3766SWITCH_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 */