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