switch_core_sqldb.c 125 KB

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