oci8.c 123 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Stig Sæther Bakken <ssb@php.net> |
  16. | Thies C. Arntzen <thies@thieso.net> |
  17. | Maxim Maletsky <maxim@maxim.cx> |
  18. | |
  19. | Collection support by Andy Sautins <asautins@veripost.net> |
  20. | Temporary LOB support by David Benson <dbenson@mancala.com> |
  21. | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
  22. | |
  23. | Redesigned by: Antony Dovgal <antony@zend.com> |
  24. | Andi Gutmans <andi@zend.com> |
  25. | Wez Furlong <wez@omniti.com> |
  26. +----------------------------------------------------------------------+
  27. */
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include "php.h"
  32. #include "ext/standard/info.h"
  33. #include "php_ini.h"
  34. #include "ext/standard/php_smart_str.h"
  35. #if HAVE_OCI8
  36. /* PHP 5.2 is the minimum supported version for OCI8 2.0 */
  37. #if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 1)
  38. #error Use PHP OCI8 1.4 for your version of PHP
  39. #elif PHP_MAJOR_VERSION >= 7
  40. #error Use PHP OCI8 2.1 for your version of PHP
  41. #endif
  42. #include "php_oci8.h"
  43. #include "php_oci8_int.h"
  44. #include "zend_hash.h"
  45. #if defined(__PTRDIFF_TYPE__)
  46. # define OCI8_INT_TO_PTR(I) ((void*)(__PTRDIFF_TYPE__)(I))
  47. # define OCI8_PTR_TO_INT(P) ((int)(__PTRDIFF_TYPE__)(P))
  48. #elif !defined(__GNUC__)
  49. #define OCI8_INT_TO_PTR(I) ((void*)&((char*)0)[I])
  50. #define OCI8_PTR_TO_INT(P) ((int)(((char*)P)-(char*)0))
  51. #elif defined(HAVE_STDINT_H)
  52. #define OCI8_INT_TO_PTR(I) ((void*)(intptr_t)(I))
  53. #define OCI8_PTR_TO_INT(P) ((int)(intptr_t)(P))
  54. #else
  55. #define OCI8_INT_TO_PTR(I) ((void*)(I))
  56. #define OCI8_PTR_TO_INT(P) ((int)(P))
  57. #endif
  58. ZEND_DECLARE_MODULE_GLOBALS(oci)
  59. static PHP_GINIT_FUNCTION(oci);
  60. static PHP_GSHUTDOWN_FUNCTION(oci);
  61. /* Allow PHP 5.3 branch to be used in PECL for 5.x compatible builds */
  62. #ifndef Z_ADDREF_P
  63. #define Z_ADDREF_P(x) ZVAL_ADDREF(x)
  64. #endif
  65. /* For a user friendly message about environment setup */
  66. #if defined(PHP_WIN32)
  67. #define PHP_OCI8_LIB_PATH_MSG "PATH"
  68. #elif defined(__APPLE__)
  69. #define PHP_OCI8_LIB_PATH_MSG "DYLD_LIBRARY_PATH"
  70. #elif defined(_AIX)
  71. #define PHP_OCI8_LIB_PATH_MSG "LIBPATH"
  72. #elif defined(__hpux)
  73. #define PHP_OCI8_LIB_PATH_MSG "SHLIB_PATH"
  74. #else
  75. #define PHP_OCI8_LIB_PATH_MSG "LD_LIBRARY_PATH"
  76. #endif
  77. /* True globals, no need for thread safety */
  78. int le_connection;
  79. int le_pconnection;
  80. int le_statement;
  81. int le_descriptor;
  82. int le_psessionpool;
  83. int le_collection;
  84. zend_class_entry *oci_lob_class_entry_ptr;
  85. zend_class_entry *oci_coll_class_entry_ptr;
  86. #ifndef SQLT_BFILEE
  87. #define SQLT_BFILEE 114
  88. #endif
  89. #ifndef SQLT_CFILEE
  90. #define SQLT_CFILEE 115
  91. #endif
  92. #ifdef OCI_ERROR_MAXMSG_SIZE2
  93. /* Bigger size is defined from 11.2.0.3 onwards */
  94. #define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE2
  95. #else
  96. #define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE
  97. #endif
  98. #if ZEND_MODULE_API_NO > 20020429
  99. #define ONUPDATELONGFUNC OnUpdateLong
  100. #else
  101. #define ONUPDATELONGFUNC OnUpdateInt
  102. #endif
  103. #ifdef ZTS
  104. #define PHP_OCI_INIT_MODE (OCI_DEFAULT | OCI_OBJECT | OCI_THREADED | OCI_NO_MUTEX)
  105. #else
  106. #define PHP_OCI_INIT_MODE (OCI_DEFAULT | OCI_OBJECT)
  107. #endif
  108. /* {{{ static protos */
  109. static void php_oci_connection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
  110. static void php_oci_pconnection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
  111. static void php_oci_pconnection_list_np_dtor (zend_rsrc_list_entry * TSRMLS_DC);
  112. static void php_oci_statement_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
  113. static void php_oci_descriptor_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
  114. static void php_oci_spool_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC);
  115. static void php_oci_collection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
  116. static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC);
  117. static int php_oci_connection_ping(php_oci_connection * TSRMLS_DC);
  118. static int php_oci_connection_status(php_oci_connection * TSRMLS_DC);
  119. static int php_oci_connection_close(php_oci_connection * TSRMLS_DC);
  120. static void php_oci_spool_close(php_oci_spool *session_pool TSRMLS_DC);
  121. static OCIEnv *php_oci_create_env(ub2 charsetid TSRMLS_DC);
  122. static int php_oci_create_session(php_oci_connection *connection, php_oci_spool *session_pool, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC);
  123. static int php_oci_old_create_session(php_oci_connection *connection, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC);
  124. static php_oci_spool *php_oci_get_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, int charsetid TSRMLS_DC);
  125. static php_oci_spool *php_oci_create_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, char *hash_key, int hash_key_len, int charsetid TSRMLS_DC);
  126. static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TSRMLS_DC);
  127. /* }}} */
  128. /* {{{ dynamically loadable module stuff */
  129. #if defined(COMPILE_DL_OCI8) || defined(COMPILE_DL_OCI8_11G) || defined(COMPILE_DL_OCI8_12C)
  130. ZEND_GET_MODULE(oci8)
  131. #endif /* COMPILE_DL */
  132. /* }}} */
  133. #ifdef ZEND_ENGINE_2
  134. /* {{{ Function arginfo */
  135. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_define_by_name, 0, 0, 3)
  136. ZEND_ARG_INFO(0, statement_resource)
  137. ZEND_ARG_INFO(0, column_name)
  138. ZEND_ARG_INFO(1, variable)
  139. ZEND_ARG_INFO(0, type)
  140. ZEND_END_ARG_INFO()
  141. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_bind_by_name, 0, 0, 3)
  142. ZEND_ARG_INFO(0, statement_resource)
  143. ZEND_ARG_INFO(0, column_name)
  144. ZEND_ARG_INFO(1, variable)
  145. ZEND_ARG_INFO(0, maximum_length)
  146. ZEND_ARG_INFO(0, type)
  147. ZEND_END_ARG_INFO()
  148. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_bind_array_by_name, 0, 0, 4)
  149. ZEND_ARG_INFO(0, statement_resource)
  150. ZEND_ARG_INFO(0, column_name)
  151. ZEND_ARG_INFO(1, variable)
  152. ZEND_ARG_INFO(0, maximum_array_length)
  153. ZEND_ARG_INFO(0, maximum_item_length)
  154. ZEND_ARG_INFO(0, type)
  155. ZEND_END_ARG_INFO()
  156. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_free_descriptor, 0, 0, 1)
  157. ZEND_ARG_INFO(0, lob_descriptor)
  158. ZEND_END_ARG_INFO()
  159. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_save, 0, 0, 2)
  160. ZEND_ARG_INFO(0, lob_descriptor)
  161. ZEND_ARG_INFO(0, data)
  162. ZEND_ARG_INFO(0, offset)
  163. ZEND_END_ARG_INFO()
  164. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_import, 0, 0, 2)
  165. ZEND_ARG_INFO(0, lob_descriptor)
  166. ZEND_ARG_INFO(0, filename)
  167. ZEND_END_ARG_INFO()
  168. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_load, 0, 0, 1)
  169. ZEND_ARG_INFO(0, lob_descriptor)
  170. ZEND_END_ARG_INFO()
  171. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_read, 0, 0, 2)
  172. ZEND_ARG_INFO(0, lob_descriptor)
  173. ZEND_ARG_INFO(0, length)
  174. ZEND_END_ARG_INFO()
  175. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_eof, 0, 0, 1)
  176. ZEND_ARG_INFO(0, lob_descriptor)
  177. ZEND_END_ARG_INFO()
  178. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_tell, 0, 0, 1)
  179. ZEND_ARG_INFO(0, lob_descriptor)
  180. ZEND_END_ARG_INFO()
  181. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_rewind, 0, 0, 1)
  182. ZEND_ARG_INFO(0, lob_descriptor)
  183. ZEND_END_ARG_INFO()
  184. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_seek, 0, 0, 2)
  185. ZEND_ARG_INFO(0, lob_descriptor)
  186. ZEND_ARG_INFO(0, offset)
  187. ZEND_ARG_INFO(0, whence)
  188. ZEND_END_ARG_INFO()
  189. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_size, 0, 0, 1)
  190. ZEND_ARG_INFO(0, lob_descriptor)
  191. ZEND_END_ARG_INFO()
  192. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_write, 0, 0, 2)
  193. ZEND_ARG_INFO(0, lob_descriptor)
  194. ZEND_ARG_INFO(0, string)
  195. ZEND_ARG_INFO(0, length)
  196. ZEND_END_ARG_INFO()
  197. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_append, 0, 0, 2)
  198. ZEND_ARG_INFO(0, lob_descriptor_to)
  199. ZEND_ARG_INFO(0, lob_descriptor_from)
  200. ZEND_END_ARG_INFO()
  201. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_truncate, 0, 0, 1)
  202. ZEND_ARG_INFO(0, lob_descriptor)
  203. ZEND_ARG_INFO(0, length)
  204. ZEND_END_ARG_INFO()
  205. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_erase, 0, 0, 1)
  206. ZEND_ARG_INFO(0, lob_descriptor)
  207. ZEND_ARG_INFO(0, offset)
  208. ZEND_ARG_INFO(0, length)
  209. ZEND_END_ARG_INFO()
  210. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_flush, 0, 0, 1)
  211. ZEND_ARG_INFO(0, lob_descriptor)
  212. ZEND_ARG_INFO(0, flag)
  213. ZEND_END_ARG_INFO()
  214. ZEND_BEGIN_ARG_INFO_EX(arginfo_ocisetbufferinglob, 0, 0, 2)
  215. ZEND_ARG_INFO(0, lob_descriptor)
  216. ZEND_ARG_INFO(0, mode)
  217. ZEND_END_ARG_INFO()
  218. ZEND_BEGIN_ARG_INFO_EX(arginfo_ocigetbufferinglob, 0, 0, 1)
  219. ZEND_ARG_INFO(0, lob_descriptor)
  220. ZEND_END_ARG_INFO()
  221. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_copy, 0, 0, 2)
  222. ZEND_ARG_INFO(0, lob_descriptor_to)
  223. ZEND_ARG_INFO(0, lob_descriptor_from)
  224. ZEND_ARG_INFO(0, length)
  225. ZEND_END_ARG_INFO()
  226. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_is_equal, 0, 0, 2)
  227. ZEND_ARG_INFO(0, lob_descriptor)
  228. ZEND_ARG_INFO(0, lob_descriptor)
  229. ZEND_END_ARG_INFO()
  230. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_export, 0, 0, 2)
  231. ZEND_ARG_INFO(0, lob_descriptor)
  232. ZEND_ARG_INFO(0, filename)
  233. ZEND_ARG_INFO(0, start)
  234. ZEND_ARG_INFO(0, length)
  235. ZEND_END_ARG_INFO()
  236. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_descriptor, 0, 0, 1)
  237. ZEND_ARG_INFO(0, connection_resource)
  238. ZEND_ARG_INFO(0, type)
  239. ZEND_END_ARG_INFO()
  240. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_rollback, 0, 0, 1)
  241. ZEND_ARG_INFO(0, connection_resource)
  242. ZEND_END_ARG_INFO()
  243. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_commit, 0, 0, 1)
  244. ZEND_ARG_INFO(0, connection_resource)
  245. ZEND_END_ARG_INFO()
  246. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_name, 0, 0, 2)
  247. ZEND_ARG_INFO(0, statement_resource)
  248. ZEND_ARG_INFO(0, column_number_or_name)
  249. ZEND_END_ARG_INFO()
  250. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_size, 0, 0, 2)
  251. ZEND_ARG_INFO(0, statement_resource)
  252. ZEND_ARG_INFO(0, column_number_or_name)
  253. ZEND_END_ARG_INFO()
  254. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_scale, 0, 0, 2)
  255. ZEND_ARG_INFO(0, statement_resource)
  256. ZEND_ARG_INFO(0, column_number_or_name)
  257. ZEND_END_ARG_INFO()
  258. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_precision, 0, 0, 2)
  259. ZEND_ARG_INFO(0, statement_resource)
  260. ZEND_ARG_INFO(0, column_number_or_name)
  261. ZEND_END_ARG_INFO()
  262. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_type, 0, 0, 2)
  263. ZEND_ARG_INFO(0, statement_resource)
  264. ZEND_ARG_INFO(0, column_number_or_name)
  265. ZEND_END_ARG_INFO()
  266. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_type_raw, 0, 0, 2)
  267. ZEND_ARG_INFO(0, statement_resource)
  268. ZEND_ARG_INFO(0, column_number_or_name)
  269. ZEND_END_ARG_INFO()
  270. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_is_null, 0, 0, 2)
  271. ZEND_ARG_INFO(0, statement_resource)
  272. ZEND_ARG_INFO(0, column_number_or_name)
  273. ZEND_END_ARG_INFO()
  274. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_internal_debug, 0, 0, 1)
  275. ZEND_ARG_INFO(0, mode)
  276. ZEND_END_ARG_INFO()
  277. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_execute, 0, 0, 1)
  278. ZEND_ARG_INFO(0, statement_resource)
  279. ZEND_ARG_INFO(0, mode)
  280. ZEND_END_ARG_INFO()
  281. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_cancel, 0, 0, 1)
  282. ZEND_ARG_INFO(0, statement_resource)
  283. ZEND_END_ARG_INFO()
  284. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch, 0, 0, 1)
  285. ZEND_ARG_INFO(0, statement_resource)
  286. ZEND_END_ARG_INFO()
  287. ZEND_BEGIN_ARG_INFO_EX(arginfo_ocifetchinto, 0, 0, 2)
  288. ZEND_ARG_INFO(0, statement_resource)
  289. ZEND_ARG_INFO(1, result)
  290. ZEND_ARG_INFO(0, mode)
  291. ZEND_END_ARG_INFO()
  292. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_all, 0, 0, 2)
  293. ZEND_ARG_INFO(0, statement_resource)
  294. ZEND_ARG_INFO(1, output)
  295. ZEND_ARG_INFO(0, skip)
  296. ZEND_ARG_INFO(0, maximum_rows)
  297. ZEND_ARG_INFO(0, flags)
  298. ZEND_END_ARG_INFO()
  299. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_object, 0, 0, 1)
  300. ZEND_ARG_INFO(0, statement_resource)
  301. ZEND_END_ARG_INFO()
  302. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_row, 0, 0, 1)
  303. ZEND_ARG_INFO(0, statement_resource)
  304. ZEND_END_ARG_INFO()
  305. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_assoc, 0, 0, 1)
  306. ZEND_ARG_INFO(0, statement_resource)
  307. ZEND_END_ARG_INFO()
  308. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_array, 0, 0, 1)
  309. ZEND_ARG_INFO(0, statement_resource)
  310. ZEND_ARG_INFO(0, mode)
  311. ZEND_END_ARG_INFO()
  312. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_free_statement, 0, 0, 1)
  313. ZEND_ARG_INFO(0, statement_resource)
  314. ZEND_END_ARG_INFO()
  315. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_close, 0, 0, 1)
  316. ZEND_ARG_INFO(0, connection_resource)
  317. ZEND_END_ARG_INFO()
  318. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_connect, 0, 0, 2)
  319. ZEND_ARG_INFO(0, username)
  320. ZEND_ARG_INFO(0, password)
  321. ZEND_ARG_INFO(0, connection_string)
  322. ZEND_ARG_INFO(0, character_set)
  323. ZEND_ARG_INFO(0, session_mode)
  324. ZEND_END_ARG_INFO()
  325. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_connect, 0, 0, 2)
  326. ZEND_ARG_INFO(0, username)
  327. ZEND_ARG_INFO(0, password)
  328. ZEND_ARG_INFO(0, connection_string)
  329. ZEND_ARG_INFO(0, character_set)
  330. ZEND_ARG_INFO(0, session_mode)
  331. ZEND_END_ARG_INFO()
  332. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_pconnect, 0, 0, 2)
  333. ZEND_ARG_INFO(0, username)
  334. ZEND_ARG_INFO(0, password)
  335. ZEND_ARG_INFO(0, connection_string)
  336. ZEND_ARG_INFO(0, character_set)
  337. ZEND_ARG_INFO(0, session_mode)
  338. ZEND_END_ARG_INFO()
  339. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_error, 0, 0, 0)
  340. ZEND_ARG_INFO(0, connection_or_statement_resource)
  341. ZEND_END_ARG_INFO()
  342. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_num_fields, 0, 0, 1)
  343. ZEND_ARG_INFO(0, statement_resource)
  344. ZEND_END_ARG_INFO()
  345. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_parse, 0, 0, 2)
  346. ZEND_ARG_INFO(0, connection_resource)
  347. ZEND_ARG_INFO(0, sql_text)
  348. ZEND_END_ARG_INFO()
  349. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_get_implicit_resultset, 0, 0, 1)
  350. ZEND_ARG_INFO(0, statement_resource)
  351. ZEND_END_ARG_INFO()
  352. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_prefetch, 0, 0, 2)
  353. ZEND_ARG_INFO(0, statement_resource)
  354. ZEND_ARG_INFO(0, number_of_rows)
  355. ZEND_END_ARG_INFO()
  356. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_identifier, 0, 0, 2)
  357. ZEND_ARG_INFO(0, connection_resource)
  358. ZEND_ARG_INFO(0, client_identifier)
  359. ZEND_END_ARG_INFO()
  360. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_edition, 0, 0, 1)
  361. ZEND_ARG_INFO(0, edition_name)
  362. ZEND_END_ARG_INFO()
  363. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_module_name, 0, 0, 2)
  364. ZEND_ARG_INFO(0, connection_resource)
  365. ZEND_ARG_INFO(0, module_name)
  366. ZEND_END_ARG_INFO()
  367. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_action, 0, 0, 2)
  368. ZEND_ARG_INFO(0, connection_resource)
  369. ZEND_ARG_INFO(0, action)
  370. ZEND_END_ARG_INFO()
  371. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_info, 0, 0, 2)
  372. ZEND_ARG_INFO(0, connection_resource)
  373. ZEND_ARG_INFO(0, client_information)
  374. ZEND_END_ARG_INFO()
  375. #ifdef WAITIING_ORACLE_BUG_16695981_FIX
  376. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_db_operation, 0, 0, 2)
  377. ZEND_ARG_INFO(0, connection_resource)
  378. ZEND_ARG_INFO(0, action)
  379. ZEND_END_ARG_INFO()
  380. #endif
  381. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_password_change, 0, 0, 4)
  382. ZEND_ARG_INFO(0, connection_resource_or_connection_string)
  383. ZEND_ARG_INFO(0, username)
  384. ZEND_ARG_INFO(0, old_password)
  385. ZEND_ARG_INFO(0, new_password)
  386. ZEND_END_ARG_INFO()
  387. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_cursor, 0, 0, 1)
  388. ZEND_ARG_INFO(0, connection_resource)
  389. ZEND_END_ARG_INFO()
  390. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_result, 0, 0, 2)
  391. ZEND_ARG_INFO(0, statement_resource)
  392. ZEND_ARG_INFO(0, column_number_or_name)
  393. ZEND_END_ARG_INFO()
  394. ZEND_BEGIN_ARG_INFO(arginfo_oci_client_version, 0)
  395. ZEND_END_ARG_INFO()
  396. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_server_version, 0, 0, 1)
  397. ZEND_ARG_INFO(0, connection_resource)
  398. ZEND_END_ARG_INFO()
  399. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_statement_type, 0, 0, 1)
  400. ZEND_ARG_INFO(0, statement_resource)
  401. ZEND_END_ARG_INFO()
  402. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_num_rows, 0, 0, 1)
  403. ZEND_ARG_INFO(0, statement_resource)
  404. ZEND_END_ARG_INFO()
  405. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_free_collection, 0, 0, 1)
  406. ZEND_ARG_INFO(0, collection)
  407. ZEND_END_ARG_INFO()
  408. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_append, 0, 0, 2)
  409. ZEND_ARG_INFO(0, collection)
  410. ZEND_ARG_INFO(0, value)
  411. ZEND_END_ARG_INFO()
  412. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_get, 0, 0, 2)
  413. ZEND_ARG_INFO(0, collection)
  414. ZEND_ARG_INFO(0, index)
  415. ZEND_END_ARG_INFO()
  416. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_assign, 0, 0, 2)
  417. ZEND_ARG_INFO(0, collection_to)
  418. ZEND_ARG_INFO(0, collection_from)
  419. ZEND_END_ARG_INFO()
  420. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_assign, 0, 0, 3)
  421. ZEND_ARG_INFO(0, collection)
  422. ZEND_ARG_INFO(0, index)
  423. ZEND_ARG_INFO(0, value)
  424. ZEND_END_ARG_INFO()
  425. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_size, 0, 0, 1)
  426. ZEND_ARG_INFO(0, collection)
  427. ZEND_END_ARG_INFO()
  428. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_max, 0, 0, 1)
  429. ZEND_ARG_INFO(0, collection)
  430. ZEND_END_ARG_INFO()
  431. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_trim, 0, 0, 2)
  432. ZEND_ARG_INFO(0, collection)
  433. ZEND_ARG_INFO(0, number)
  434. ZEND_END_ARG_INFO()
  435. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_collection, 0, 0, 2)
  436. ZEND_ARG_INFO(0, connection_resource)
  437. ZEND_ARG_INFO(0, type_name)
  438. ZEND_ARG_INFO(0, schema_name)
  439. ZEND_END_ARG_INFO()
  440. /* }}} */
  441. /* {{{ LOB Method arginfo */
  442. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_save_method, 0, 0, 1)
  443. ZEND_ARG_INFO(0, data)
  444. ZEND_ARG_INFO(0, offset)
  445. ZEND_END_ARG_INFO()
  446. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_import_method, 0, 0, 1)
  447. ZEND_ARG_INFO(0, filename)
  448. ZEND_END_ARG_INFO()
  449. ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_load_method, 0)
  450. ZEND_END_ARG_INFO()
  451. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_read_method, 0, 0, 1)
  452. ZEND_ARG_INFO(0, length)
  453. ZEND_END_ARG_INFO()
  454. ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_eof_method, 0)
  455. ZEND_END_ARG_INFO()
  456. ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_tell_method, 0)
  457. ZEND_END_ARG_INFO()
  458. ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_rewind_method, 0)
  459. ZEND_END_ARG_INFO()
  460. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_seek_method, 0, 0, 1)
  461. ZEND_ARG_INFO(0, offset)
  462. ZEND_ARG_INFO(0, whence)
  463. ZEND_END_ARG_INFO()
  464. ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_size_method, 0)
  465. ZEND_END_ARG_INFO()
  466. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_write_method, 0, 0, 1)
  467. ZEND_ARG_INFO(0, string)
  468. ZEND_ARG_INFO(0, length)
  469. ZEND_END_ARG_INFO()
  470. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_append_method, 0, 0, 1)
  471. ZEND_ARG_INFO(0, lob_descriptor_from)
  472. ZEND_END_ARG_INFO()
  473. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_truncate_method, 0, 0, 0)
  474. ZEND_ARG_INFO(0, length)
  475. ZEND_END_ARG_INFO()
  476. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_erase_method, 0, 0, 0)
  477. ZEND_ARG_INFO(0, offset)
  478. ZEND_ARG_INFO(0, length)
  479. ZEND_END_ARG_INFO()
  480. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_flush_method, 0, 0, 0)
  481. ZEND_ARG_INFO(0, flag)
  482. ZEND_END_ARG_INFO()
  483. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_setbuffering_method, 0, 0, 1)
  484. ZEND_ARG_INFO(0, mode)
  485. ZEND_END_ARG_INFO()
  486. ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_getbuffering_method, 0)
  487. ZEND_END_ARG_INFO()
  488. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_export_method, 0, 0, 1)
  489. ZEND_ARG_INFO(0, filename)
  490. ZEND_ARG_INFO(0, start)
  491. ZEND_ARG_INFO(0, length)
  492. ZEND_END_ARG_INFO()
  493. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_write_temporary_method, 0, 0, 1)
  494. ZEND_ARG_INFO(0, data)
  495. ZEND_ARG_INFO(0, type)
  496. ZEND_END_ARG_INFO()
  497. ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_close_method, 0)
  498. ZEND_END_ARG_INFO()
  499. ZEND_BEGIN_ARG_INFO(arginfo_oci_free_descriptor_method, 0)
  500. ZEND_END_ARG_INFO()
  501. /* }}} */
  502. /* {{{ Collection Method arginfo */
  503. ZEND_BEGIN_ARG_INFO(arginfo_oci_collection_free_method, 0)
  504. ZEND_END_ARG_INFO()
  505. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_append_method, 0, 0, 1)
  506. ZEND_ARG_INFO(0, value)
  507. ZEND_END_ARG_INFO()
  508. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_get_method, 0, 0, 1)
  509. ZEND_ARG_INFO(0, index)
  510. ZEND_END_ARG_INFO()
  511. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_assign_method, 0, 0, 1)
  512. ZEND_ARG_INFO(0, collection_from)
  513. ZEND_END_ARG_INFO()
  514. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_assign_method, 0, 0, 2)
  515. ZEND_ARG_INFO(0, index)
  516. ZEND_ARG_INFO(0, value)
  517. ZEND_END_ARG_INFO()
  518. ZEND_BEGIN_ARG_INFO(arginfo_oci_collection_size_method, 0)
  519. ZEND_END_ARG_INFO()
  520. ZEND_BEGIN_ARG_INFO(arginfo_oci_collection_max_method, 0)
  521. ZEND_END_ARG_INFO()
  522. ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_trim_method, 0, 0, 1)
  523. ZEND_ARG_INFO(0, number)
  524. ZEND_END_ARG_INFO()
  525. /* }}} */
  526. #else /* ZEND_ENGINE_2 */
  527. /* {{{ Keep the old arginfo behavior when building with PHP 4 */
  528. static unsigned char arginfo_ocifetchinto[] = { 2, BYREF_NONE, BYREF_FORCE };
  529. static unsigned char arginfo_oci_fetch_all[] = { 2, BYREF_NONE, BYREF_FORCE };
  530. static unsigned char arginfo_oci_define_by_name[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
  531. static unsigned char arginfo_oci_bind_by_name[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
  532. static unsigned char arginfo_oci_bind_array_by_name[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
  533. #define arginfo_oci_free_descriptor NULL
  534. #define arginfo_oci_lob_save NULL
  535. #define arginfo_oci_lob_import NULL
  536. #define arginfo_oci_lob_load NULL
  537. #define arginfo_oci_lob_read NULL
  538. #define arginfo_oci_lob_eof NULL
  539. #define arginfo_oci_lob_tell NULL
  540. #define arginfo_oci_lob_rewind NULL
  541. #define arginfo_oci_lob_seek NULL
  542. #define arginfo_oci_lob_size NULL
  543. #define arginfo_oci_lob_write NULL
  544. #define arginfo_oci_lob_append NULL
  545. #define arginfo_oci_lob_truncate NULL
  546. #define arginfo_oci_lob_erase NULL
  547. #define arginfo_oci_lob_flush NULL
  548. #define arginfo_ocisetbufferinglob NULL
  549. #define arginfo_ocigetbufferinglob NULL
  550. #define arginfo_oci_lob_copy NULL
  551. #define arginfo_oci_lob_is_equal NULL
  552. #define arginfo_oci_lob_export NULL
  553. #define arginfo_oci_new_descriptor NULL
  554. #define arginfo_oci_rollback NULL
  555. #define arginfo_oci_commit NULL
  556. #define arginfo_oci_field_name NULL
  557. #define arginfo_oci_field_size NULL
  558. #define arginfo_oci_field_scale NULL
  559. #define arginfo_oci_field_precision NULL
  560. #define arginfo_oci_field_type NULL
  561. #define arginfo_oci_field_type_raw NULL
  562. #define arginfo_oci_field_is_null NULL
  563. #define arginfo_oci_internal_debug NULL
  564. #define arginfo_oci_execute NULL
  565. #define arginfo_oci_cancel NULL
  566. #define arginfo_oci_fetch NULL
  567. #define arginfo_oci_fetch_object NULL
  568. #define arginfo_oci_fetch_row NULL
  569. #define arginfo_oci_fetch_assoc NULL
  570. #define arginfo_oci_fetch_array NULL
  571. #define arginfo_oci_free_statement NULL
  572. #define arginfo_oci_close NULL
  573. #define arginfo_oci_new_connect NULL
  574. #define arginfo_oci_connect NULL
  575. #define arginfo_oci_pconnect NULL
  576. #define arginfo_oci_error NULL
  577. #define arginfo_oci_num_fields NULL
  578. #define arginfo_oci_parse NULL
  579. #define arginfo_oci_get_implicit_resultset NULL
  580. #define arginfo_oci_set_prefetch NULL
  581. #define arginfo_oci_set_client_identifier NULL
  582. #define arginfo_oci_set_edition NULL
  583. #define arginfo_oci_set_module_name NULL
  584. #define arginfo_oci_set_action NULL
  585. #define arginfo_oci_set_client_info NULL
  586. #ifdef WAITIING_ORACLE_BUG_16695981_FIX
  587. #define arginfo_oci_set_db_operation NULL
  588. #endif
  589. #define arginfo_oci_password_change NULL
  590. #define arginfo_oci_new_cursor NULL
  591. #define arginfo_oci_result NULL
  592. #define arginfo_oci_client_version NULL
  593. #define arginfo_oci_server_version NULL
  594. #define arginfo_oci_statement_type NULL
  595. #define arginfo_oci_num_rows NULL
  596. #define arginfo_oci_free_collection NULL
  597. #define arginfo_oci_collection_append NULL
  598. #define arginfo_oci_collection_element_get NULL
  599. #define arginfo_oci_collection_assign NULL
  600. #define arginfo_oci_collection_element_assign NULL
  601. #define arginfo_oci_collection_size NULL
  602. #define arginfo_oci_collection_max NULL
  603. #define arginfo_oci_collection_trim NULL
  604. #define arginfo_oci_new_collection NULL
  605. #define arginfo_oci_lob_size_method NULL
  606. #define arginfo_oci_lob_getbuffering_method NULL
  607. #define arginfo_oci_lob_close_method NULL
  608. #define arginfo_oci_lob_save_method NULL
  609. #define arginfo_oci_lob_import_method NULL
  610. #define arginfo_oci_lob_read_method NULL
  611. #define arginfo_oci_lob_seek_method NULL
  612. #define arginfo_oci_lob_write_method NULL
  613. #define arginfo_oci_lob_append_method NULL
  614. #define arginfo_oci_lob_truncate_method NULL
  615. #define arginfo_oci_lob_erase_method NULL
  616. #define arginfo_oci_lob_flush_method NULL
  617. #define arginfo_oci_lob_setbuffering_method NULL
  618. #define arginfo_oci_lob_export_method NULL
  619. #define arginfo_oci_lob_write_temporary_method NULL
  620. #define arginfo_oci_lob_load_method NULL
  621. #define arginfo_oci_lob_tell_method NULL
  622. #define arginfo_oci_lob_rewind_method NULL
  623. #define arginfo_oci_lob_eof_method NULL
  624. #define arginfo_oci_free_descriptor_method NULL
  625. #define arginfo_oci_collection_append_method NULL
  626. #define arginfo_oci_collection_element_get_method NULL
  627. #define arginfo_oci_collection_assign_method NULL
  628. #define arginfo_oci_collection_size_method NULL
  629. #define arginfo_oci_collection_element_assign_method NULL
  630. #define arginfo_oci_collection_max_method NULL
  631. #define arginfo_oci_collection_trim_method NULL
  632. #define arginfo_oci_collection_free_method NULL
  633. /* }}} */
  634. #endif /* ZEND_ENGINE_2 */
  635. /* {{{ extension function prototypes
  636. */
  637. PHP_FUNCTION(oci_bind_by_name);
  638. PHP_FUNCTION(oci_bind_array_by_name);
  639. PHP_FUNCTION(oci_define_by_name);
  640. PHP_FUNCTION(oci_field_is_null);
  641. PHP_FUNCTION(oci_field_name);
  642. PHP_FUNCTION(oci_field_size);
  643. PHP_FUNCTION(oci_field_scale);
  644. PHP_FUNCTION(oci_field_precision);
  645. PHP_FUNCTION(oci_field_type);
  646. PHP_FUNCTION(oci_field_type_raw);
  647. PHP_FUNCTION(oci_execute);
  648. PHP_FUNCTION(oci_fetch);
  649. PHP_FUNCTION(oci_cancel);
  650. PHP_FUNCTION(ocifetchinto);
  651. PHP_FUNCTION(oci_fetch_object);
  652. PHP_FUNCTION(oci_fetch_row);
  653. PHP_FUNCTION(oci_fetch_assoc);
  654. PHP_FUNCTION(oci_fetch_array);
  655. PHP_FUNCTION(ocifetchstatement);
  656. PHP_FUNCTION(oci_fetch_all);
  657. PHP_FUNCTION(oci_free_statement);
  658. PHP_FUNCTION(oci_internal_debug);
  659. PHP_FUNCTION(oci_close);
  660. PHP_FUNCTION(oci_connect);
  661. PHP_FUNCTION(oci_new_connect);
  662. PHP_FUNCTION(oci_pconnect);
  663. PHP_FUNCTION(oci_error);
  664. PHP_FUNCTION(oci_free_descriptor);
  665. PHP_FUNCTION(oci_commit);
  666. PHP_FUNCTION(oci_rollback);
  667. PHP_FUNCTION(oci_new_descriptor);
  668. PHP_FUNCTION(oci_num_fields);
  669. PHP_FUNCTION(oci_parse);
  670. PHP_FUNCTION(oci_get_implicit_resultset);
  671. PHP_FUNCTION(oci_new_cursor);
  672. PHP_FUNCTION(oci_result);
  673. PHP_FUNCTION(oci_client_version);
  674. PHP_FUNCTION(oci_server_version);
  675. PHP_FUNCTION(oci_statement_type);
  676. PHP_FUNCTION(oci_num_rows);
  677. PHP_FUNCTION(oci_set_prefetch);
  678. PHP_FUNCTION(oci_set_client_identifier);
  679. #ifdef WAITIING_ORACLE_BUG_16695981_FIX
  680. PHP_FUNCTION(oci_set_db_operation);
  681. #endif
  682. PHP_FUNCTION(oci_set_edition);
  683. PHP_FUNCTION(oci_set_module_name);
  684. PHP_FUNCTION(oci_set_action);
  685. PHP_FUNCTION(oci_set_client_info);
  686. PHP_FUNCTION(oci_password_change);
  687. PHP_FUNCTION(oci_lob_save);
  688. PHP_FUNCTION(oci_lob_import);
  689. PHP_FUNCTION(oci_lob_export);
  690. PHP_FUNCTION(oci_lob_load);
  691. PHP_FUNCTION(oci_lob_tell);
  692. PHP_FUNCTION(oci_lob_write);
  693. PHP_FUNCTION(oci_lob_append);
  694. PHP_FUNCTION(oci_lob_copy);
  695. PHP_FUNCTION(oci_lob_truncate);
  696. PHP_FUNCTION(oci_lob_erase);
  697. PHP_FUNCTION(oci_lob_flush);
  698. PHP_FUNCTION(ocisetbufferinglob);
  699. PHP_FUNCTION(ocigetbufferinglob);
  700. PHP_FUNCTION(oci_lob_is_equal);
  701. PHP_FUNCTION(oci_lob_rewind);
  702. PHP_FUNCTION(oci_lob_read);
  703. PHP_FUNCTION(oci_lob_eof);
  704. PHP_FUNCTION(oci_lob_seek);
  705. PHP_FUNCTION(oci_lob_size);
  706. PHP_FUNCTION(oci_lob_write_temporary);
  707. PHP_FUNCTION(oci_lob_close);
  708. PHP_FUNCTION(oci_new_collection);
  709. PHP_FUNCTION(oci_free_collection);
  710. PHP_FUNCTION(oci_collection_append);
  711. PHP_FUNCTION(oci_collection_element_get);
  712. PHP_FUNCTION(oci_collection_element_assign);
  713. PHP_FUNCTION(oci_collection_assign);
  714. PHP_FUNCTION(oci_collection_size);
  715. PHP_FUNCTION(oci_collection_max);
  716. PHP_FUNCTION(oci_collection_trim);
  717. /* }}} */
  718. /* {{{ extension definition structures
  719. */
  720. static
  721. #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) || (PHP_MAJOR_VERSION > 5)
  722. /* This "if" allows PECL builds from this file to be portable to older PHP releases */
  723. const
  724. #endif
  725. zend_function_entry php_oci_functions[] = {
  726. PHP_FE(oci_define_by_name, arginfo_oci_define_by_name)
  727. PHP_FE(oci_bind_by_name, arginfo_oci_bind_by_name)
  728. PHP_FE(oci_bind_array_by_name, arginfo_oci_bind_array_by_name)
  729. PHP_FE(oci_field_is_null, arginfo_oci_field_is_null)
  730. PHP_FE(oci_field_name, arginfo_oci_field_name)
  731. PHP_FE(oci_field_size, arginfo_oci_field_size)
  732. PHP_FE(oci_field_scale, arginfo_oci_field_scale)
  733. PHP_FE(oci_field_precision, arginfo_oci_field_precision)
  734. PHP_FE(oci_field_type, arginfo_oci_field_type)
  735. PHP_FE(oci_field_type_raw, arginfo_oci_field_type_raw)
  736. PHP_FE(oci_execute, arginfo_oci_execute)
  737. PHP_FE(oci_cancel, arginfo_oci_cancel)
  738. PHP_FE(oci_fetch, arginfo_oci_fetch)
  739. PHP_FE(oci_fetch_object, arginfo_oci_fetch_object)
  740. PHP_FE(oci_fetch_row, arginfo_oci_fetch_row)
  741. PHP_FE(oci_fetch_assoc, arginfo_oci_fetch_assoc)
  742. PHP_FE(oci_fetch_array, arginfo_oci_fetch_array)
  743. PHP_FE(ocifetchinto, arginfo_ocifetchinto)
  744. PHP_FE(oci_fetch_all, arginfo_oci_fetch_all)
  745. PHP_FE(oci_free_statement, arginfo_oci_free_statement)
  746. PHP_FE(oci_internal_debug, arginfo_oci_internal_debug)
  747. PHP_FE(oci_num_fields, arginfo_oci_num_fields)
  748. PHP_FE(oci_parse, arginfo_oci_parse)
  749. PHP_FE(oci_get_implicit_resultset, arginfo_oci_get_implicit_resultset)
  750. PHP_FE(oci_new_cursor, arginfo_oci_new_cursor)
  751. PHP_FE(oci_result, arginfo_oci_result)
  752. PHP_FE(oci_client_version, arginfo_oci_client_version)
  753. PHP_FE(oci_server_version, arginfo_oci_server_version)
  754. PHP_FE(oci_statement_type, arginfo_oci_statement_type)
  755. PHP_FE(oci_num_rows, arginfo_oci_num_rows)
  756. PHP_FE(oci_close, arginfo_oci_close)
  757. PHP_FE(oci_connect, arginfo_oci_connect)
  758. PHP_FE(oci_new_connect, arginfo_oci_new_connect)
  759. PHP_FE(oci_pconnect, arginfo_oci_pconnect)
  760. PHP_FE(oci_error, arginfo_oci_error)
  761. PHP_FE(oci_free_descriptor, arginfo_oci_free_descriptor)
  762. PHP_FE(oci_lob_save, arginfo_oci_lob_save)
  763. PHP_FE(oci_lob_import, arginfo_oci_lob_import)
  764. PHP_FE(oci_lob_size, arginfo_oci_lob_size)
  765. PHP_FE(oci_lob_load, arginfo_oci_lob_load)
  766. PHP_FE(oci_lob_read, arginfo_oci_lob_read)
  767. PHP_FE(oci_lob_eof, arginfo_oci_lob_eof)
  768. PHP_FE(oci_lob_tell, arginfo_oci_lob_tell)
  769. PHP_FE(oci_lob_truncate, arginfo_oci_lob_truncate)
  770. PHP_FE(oci_lob_erase, arginfo_oci_lob_erase)
  771. PHP_FE(oci_lob_flush, arginfo_oci_lob_flush)
  772. PHP_FE(ocisetbufferinglob, arginfo_ocisetbufferinglob)
  773. PHP_FE(ocigetbufferinglob, arginfo_ocigetbufferinglob)
  774. PHP_FE(oci_lob_is_equal, arginfo_oci_lob_is_equal)
  775. PHP_FE(oci_lob_rewind, arginfo_oci_lob_rewind)
  776. PHP_FE(oci_lob_write, arginfo_oci_lob_write)
  777. PHP_FE(oci_lob_append, arginfo_oci_lob_append)
  778. PHP_FE(oci_lob_copy, arginfo_oci_lob_copy)
  779. PHP_FE(oci_lob_export, arginfo_oci_lob_export)
  780. PHP_FE(oci_lob_seek, arginfo_oci_lob_seek)
  781. PHP_FE(oci_commit, arginfo_oci_commit)
  782. PHP_FE(oci_rollback, arginfo_oci_rollback)
  783. PHP_FE(oci_new_descriptor, arginfo_oci_new_descriptor)
  784. PHP_FE(oci_set_prefetch, arginfo_oci_set_prefetch)
  785. PHP_FE(oci_set_client_identifier, arginfo_oci_set_client_identifier)
  786. #ifdef WAITIING_ORACLE_BUG_16695981_FIX
  787. PHP_FE(oci_set_db_operation, arginfo_oci_set_db_operation)
  788. #endif
  789. PHP_FE(oci_set_edition, arginfo_oci_set_edition)
  790. PHP_FE(oci_set_module_name, arginfo_oci_set_module_name)
  791. PHP_FE(oci_set_action, arginfo_oci_set_action)
  792. PHP_FE(oci_set_client_info, arginfo_oci_set_client_info)
  793. PHP_FE(oci_password_change, arginfo_oci_password_change)
  794. PHP_FE(oci_free_collection, arginfo_oci_free_collection)
  795. PHP_FE(oci_collection_append, arginfo_oci_collection_append)
  796. PHP_FE(oci_collection_element_get, arginfo_oci_collection_element_get)
  797. PHP_FE(oci_collection_element_assign, arginfo_oci_collection_element_assign)
  798. PHP_FE(oci_collection_assign, arginfo_oci_collection_assign)
  799. PHP_FE(oci_collection_size, arginfo_oci_collection_size)
  800. PHP_FE(oci_collection_max, arginfo_oci_collection_max)
  801. PHP_FE(oci_collection_trim, arginfo_oci_collection_trim)
  802. PHP_FE(oci_new_collection, arginfo_oci_new_collection)
  803. PHP_FALIAS(oci_free_cursor, oci_free_statement, arginfo_oci_free_statement)
  804. PHP_FALIAS(ocifreecursor, oci_free_statement, arginfo_oci_free_statement)
  805. PHP_FALIAS(ocibindbyname, oci_bind_by_name, arginfo_oci_bind_by_name)
  806. PHP_FALIAS(ocidefinebyname, oci_define_by_name, arginfo_oci_define_by_name)
  807. PHP_FALIAS(ocicolumnisnull, oci_field_is_null, arginfo_oci_field_is_null)
  808. PHP_FALIAS(ocicolumnname, oci_field_name, arginfo_oci_field_name)
  809. PHP_FALIAS(ocicolumnsize, oci_field_size, arginfo_oci_field_size)
  810. PHP_FALIAS(ocicolumnscale, oci_field_scale, arginfo_oci_field_scale)
  811. PHP_FALIAS(ocicolumnprecision, oci_field_precision, arginfo_oci_field_precision)
  812. PHP_FALIAS(ocicolumntype, oci_field_type, arginfo_oci_field_type)
  813. PHP_FALIAS(ocicolumntyperaw, oci_field_type_raw, arginfo_oci_field_type_raw)
  814. PHP_FALIAS(ociexecute, oci_execute, arginfo_oci_execute)
  815. PHP_FALIAS(ocicancel, oci_cancel, arginfo_oci_cancel)
  816. PHP_FALIAS(ocifetch, oci_fetch, arginfo_oci_fetch)
  817. PHP_FALIAS(ocifetchstatement, oci_fetch_all, arginfo_oci_fetch_all)
  818. PHP_FALIAS(ocifreestatement, oci_free_statement, arginfo_oci_free_statement)
  819. PHP_FALIAS(ociinternaldebug, oci_internal_debug, arginfo_oci_internal_debug)
  820. PHP_FALIAS(ocinumcols, oci_num_fields, arginfo_oci_num_fields)
  821. PHP_FALIAS(ociparse, oci_parse, arginfo_oci_parse)
  822. PHP_FALIAS(ocinewcursor, oci_new_cursor, arginfo_oci_new_cursor)
  823. PHP_FALIAS(ociresult, oci_result, arginfo_oci_result)
  824. PHP_FALIAS(ociserverversion, oci_server_version, arginfo_oci_server_version)
  825. PHP_FALIAS(ocistatementtype, oci_statement_type, arginfo_oci_statement_type)
  826. PHP_FALIAS(ocirowcount, oci_num_rows, arginfo_oci_num_rows)
  827. PHP_FALIAS(ocilogoff, oci_close, arginfo_oci_close)
  828. PHP_FALIAS(ocilogon, oci_connect, arginfo_oci_connect)
  829. PHP_FALIAS(ocinlogon, oci_new_connect, arginfo_oci_new_connect)
  830. PHP_FALIAS(ociplogon, oci_pconnect, arginfo_oci_pconnect)
  831. PHP_FALIAS(ocierror, oci_error, arginfo_oci_error)
  832. PHP_FALIAS(ocifreedesc, oci_free_descriptor, arginfo_oci_free_descriptor)
  833. PHP_FALIAS(ocisavelob, oci_lob_save, arginfo_oci_lob_save)
  834. PHP_FALIAS(ocisavelobfile, oci_lob_import, arginfo_oci_lob_import)
  835. PHP_FALIAS(ociwritelobtofile, oci_lob_export, arginfo_oci_lob_export)
  836. PHP_FALIAS(ociloadlob, oci_lob_load, arginfo_oci_lob_load)
  837. PHP_FALIAS(ocicommit, oci_commit, arginfo_oci_commit)
  838. PHP_FALIAS(ocirollback, oci_rollback, arginfo_oci_rollback)
  839. PHP_FALIAS(ocinewdescriptor, oci_new_descriptor, arginfo_oci_new_descriptor)
  840. PHP_FALIAS(ocisetprefetch, oci_set_prefetch, arginfo_oci_set_prefetch)
  841. PHP_FALIAS(ocipasswordchange, oci_password_change, arginfo_oci_password_change)
  842. PHP_FALIAS(ocifreecollection, oci_free_collection, arginfo_oci_free_collection)
  843. PHP_FALIAS(ocinewcollection, oci_new_collection, arginfo_oci_new_collection)
  844. PHP_FALIAS(ocicollappend, oci_collection_append, arginfo_oci_collection_append)
  845. PHP_FALIAS(ocicollgetelem, oci_collection_element_get, arginfo_oci_collection_element_get)
  846. PHP_FALIAS(ocicollassignelem, oci_collection_element_assign, arginfo_oci_collection_element_assign)
  847. PHP_FALIAS(ocicollsize, oci_collection_size, arginfo_oci_collection_size)
  848. PHP_FALIAS(ocicollmax, oci_collection_max, arginfo_oci_collection_max)
  849. PHP_FALIAS(ocicolltrim, oci_collection_trim, arginfo_oci_collection_trim)
  850. #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION >= 7) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
  851. PHP_FE_END
  852. #else
  853. {NULL,NULL,NULL}
  854. #endif
  855. };
  856. static
  857. #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) || (PHP_MAJOR_VERSION > 5)
  858. /* This "if" allows PECL builds from this file to be portable to older PHP releases */
  859. const
  860. #endif
  861. zend_function_entry php_oci_lob_class_functions[] = {
  862. PHP_FALIAS(load, oci_lob_load, arginfo_oci_lob_load_method)
  863. PHP_FALIAS(tell, oci_lob_tell, arginfo_oci_lob_tell_method)
  864. PHP_FALIAS(truncate, oci_lob_truncate, arginfo_oci_lob_truncate_method)
  865. PHP_FALIAS(erase, oci_lob_erase, arginfo_oci_lob_erase_method)
  866. PHP_FALIAS(flush, oci_lob_flush, arginfo_oci_lob_flush_method)
  867. PHP_FALIAS(setbuffering,ocisetbufferinglob, arginfo_oci_lob_setbuffering_method)
  868. PHP_FALIAS(getbuffering,ocigetbufferinglob, arginfo_oci_lob_getbuffering_method)
  869. PHP_FALIAS(rewind, oci_lob_rewind, arginfo_oci_lob_rewind_method)
  870. PHP_FALIAS(read, oci_lob_read, arginfo_oci_lob_read_method)
  871. PHP_FALIAS(eof, oci_lob_eof, arginfo_oci_lob_eof_method)
  872. PHP_FALIAS(seek, oci_lob_seek, arginfo_oci_lob_seek_method)
  873. PHP_FALIAS(write, oci_lob_write, arginfo_oci_lob_write_method)
  874. PHP_FALIAS(append, oci_lob_append, arginfo_oci_lob_append_method)
  875. PHP_FALIAS(size, oci_lob_size, arginfo_oci_lob_size_method)
  876. PHP_FALIAS(writetofile, oci_lob_export, arginfo_oci_lob_export_method)
  877. PHP_FALIAS(export, oci_lob_export, arginfo_oci_lob_export_method)
  878. PHP_FALIAS(import, oci_lob_import, arginfo_oci_lob_import_method)
  879. PHP_FALIAS(writetemporary, oci_lob_write_temporary, arginfo_oci_lob_write_temporary_method)
  880. PHP_FALIAS(close, oci_lob_close, arginfo_oci_lob_close_method)
  881. PHP_FALIAS(save, oci_lob_save, arginfo_oci_lob_save_method)
  882. PHP_FALIAS(savefile, oci_lob_import, arginfo_oci_lob_import_method)
  883. PHP_FALIAS(free, oci_free_descriptor, arginfo_oci_free_descriptor_method)
  884. #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION >= 7) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
  885. PHP_FE_END
  886. #else
  887. {NULL,NULL,NULL}
  888. #endif
  889. };
  890. static
  891. #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) || (PHP_MAJOR_VERSION > 5)
  892. /* This "if" allows PECL builds from this file to be portable to older PHP releases */
  893. const
  894. #endif
  895. zend_function_entry php_oci_coll_class_functions[] = {
  896. PHP_FALIAS(append, oci_collection_append, arginfo_oci_collection_append_method)
  897. PHP_FALIAS(getelem, oci_collection_element_get, arginfo_oci_collection_element_get_method)
  898. PHP_FALIAS(assignelem, oci_collection_element_assign, arginfo_oci_collection_element_assign_method)
  899. PHP_FALIAS(assign, oci_collection_assign, arginfo_oci_collection_assign_method)
  900. PHP_FALIAS(size, oci_collection_size, arginfo_oci_collection_size_method)
  901. PHP_FALIAS(max, oci_collection_max, arginfo_oci_collection_max_method)
  902. PHP_FALIAS(trim, oci_collection_trim, arginfo_oci_collection_trim_method)
  903. PHP_FALIAS(free, oci_free_collection, arginfo_oci_collection_free_method)
  904. #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION >= 7) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
  905. PHP_FE_END
  906. #else
  907. {NULL,NULL,NULL}
  908. #endif
  909. };
  910. zend_module_entry oci8_module_entry = {
  911. STANDARD_MODULE_HEADER,
  912. "oci8", /* extension name */
  913. php_oci_functions, /* extension function list */
  914. PHP_MINIT(oci), /* extension-wide startup function */
  915. PHP_MSHUTDOWN(oci), /* extension-wide shutdown function */
  916. PHP_RINIT(oci), /* per-request startup function */
  917. PHP_RSHUTDOWN(oci), /* per-request shutdown function */
  918. PHP_MINFO(oci), /* information function */
  919. PHP_OCI8_VERSION,
  920. PHP_MODULE_GLOBALS(oci), /* globals descriptor */
  921. PHP_GINIT(oci), /* globals ctor */
  922. PHP_GSHUTDOWN(oci), /* globals dtor */
  923. NULL, /* post deactivate */
  924. STANDARD_MODULE_PROPERTIES_EX
  925. };
  926. /* }}} */
  927. /* {{{ PHP_INI */
  928. PHP_INI_BEGIN()
  929. STD_PHP_INI_ENTRY( "oci8.max_persistent", "-1", PHP_INI_SYSTEM, ONUPDATELONGFUNC, max_persistent, zend_oci_globals, oci_globals)
  930. STD_PHP_INI_ENTRY( "oci8.persistent_timeout", "-1", PHP_INI_SYSTEM, ONUPDATELONGFUNC, persistent_timeout, zend_oci_globals, oci_globals)
  931. STD_PHP_INI_ENTRY( "oci8.ping_interval", "60", PHP_INI_SYSTEM, ONUPDATELONGFUNC, ping_interval, zend_oci_globals, oci_globals)
  932. STD_PHP_INI_BOOLEAN("oci8.privileged_connect", "0", PHP_INI_SYSTEM, OnUpdateBool, privileged_connect, zend_oci_globals, oci_globals)
  933. STD_PHP_INI_ENTRY( "oci8.statement_cache_size", "20", PHP_INI_SYSTEM, ONUPDATELONGFUNC, statement_cache_size, zend_oci_globals, oci_globals)
  934. STD_PHP_INI_ENTRY( "oci8.default_prefetch", "100", PHP_INI_SYSTEM, ONUPDATELONGFUNC, default_prefetch, zend_oci_globals, oci_globals)
  935. STD_PHP_INI_BOOLEAN("oci8.old_oci_close_semantics", "0", PHP_INI_SYSTEM, OnUpdateBool, old_oci_close_semantics,zend_oci_globals, oci_globals)
  936. #if (OCI_MAJOR_VERSION >= 11)
  937. STD_PHP_INI_ENTRY( "oci8.connection_class", "", PHP_INI_ALL, OnUpdateString, connection_class, zend_oci_globals, oci_globals)
  938. #endif
  939. #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))
  940. STD_PHP_INI_BOOLEAN("oci8.events", "0", PHP_INI_SYSTEM, OnUpdateBool, events, zend_oci_globals, oci_globals)
  941. #endif
  942. PHP_INI_END()
  943. /* }}} */
  944. /* {{{ startup, shutdown and info functions
  945. */
  946. /* {{{ php_oci_init_global_handles()
  947. *
  948. * Initialize global handles only when they are needed
  949. */
  950. static void php_oci_init_global_handles(TSRMLS_D)
  951. {
  952. sword errstatus;
  953. sb4 ora_error_code = 0;
  954. text tmp_buf[OCI_ERROR_MAXMSG_SIZE]; /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */
  955. errstatus = OCIEnvNlsCreate(&OCI_G(env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, 0, 0);
  956. if (errstatus == OCI_ERROR) {
  957. #ifdef HAVE_OCI_INSTANT_CLIENT
  958. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that " PHP_OCI8_LIB_PATH_MSG " includes the directory with Oracle Instant Client libraries");
  959. #else
  960. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories");
  961. #endif
  962. if (OCI_G(env)
  963. && OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS
  964. && *tmp_buf) {
  965. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tmp_buf);
  966. }
  967. OCI_G(env) = NULL;
  968. OCI_G(err) = NULL;
  969. return;
  970. }
  971. errstatus = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL);
  972. if (errstatus == OCI_SUCCESS) {
  973. #if !defined(OCI_MAJOR_VERSION) || (OCI_MAJOR_VERSION < 11)
  974. /* This fixes PECL bug 15988 (sqlnet.ora not being read). The
  975. * root cause was fixed in Oracle 10.2.0.4 but there is no
  976. * compile time method to check for that precise patch level,
  977. * nor can it be guaranteed that runtime will use the same
  978. * patch level the code was compiled with. So, we do this
  979. * code for all non 11g versions.
  980. */
  981. OCICPool *cpoolh;
  982. ub4 cpoolmode = 0x80000000; /* Pass invalid mode to OCIConnectionPoolCreate */
  983. PHP_OCI_CALL(OCIHandleAlloc, (OCI_G(env), (dvoid **) &cpoolh, OCI_HTYPE_CPOOL, (size_t) 0, (dvoid **) 0));
  984. PHP_OCI_CALL(OCIConnectionPoolCreate, (OCI_G(env), OCI_G(err), cpoolh, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, NULL, 0, cpoolmode));
  985. PHP_OCI_CALL(OCIConnectionPoolDestroy, (cpoolh, OCI_G(err), OCI_DEFAULT));
  986. PHP_OCI_CALL(OCIHandleFree, (cpoolh, OCI_HTYPE_CPOOL));
  987. #endif
  988. } else {
  989. OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ERROR);
  990. if (ora_error_code) {
  991. int tmp_buf_len = strlen((char *)tmp_buf);
  992. if (tmp_buf_len > 0 && tmp_buf[tmp_buf_len - 1] == '\n') {
  993. tmp_buf[tmp_buf_len - 1] = '\0';
  994. }
  995. if (errstatus == OCI_SUCCESS_WITH_INFO) {
  996. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Initialization error: OCI_SUCCESS_WITH_INFO: %s", tmp_buf);
  997. } else {
  998. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Initialization error: OCI_ERROR: %s", tmp_buf);
  999. OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
  1000. OCI_G(env) = NULL;
  1001. OCI_G(err) = NULL;
  1002. }
  1003. }
  1004. }
  1005. }
  1006. /* }}} */
  1007. /* {{{ php_oci_cleanup_global_handles()
  1008. *
  1009. * Free global handles (if they were initialized before)
  1010. */
  1011. static void php_oci_cleanup_global_handles(TSRMLS_D)
  1012. {
  1013. if (OCI_G(err)) {
  1014. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ERROR));
  1015. OCI_G(err) = NULL;
  1016. }
  1017. if (OCI_G(env)) {
  1018. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV));
  1019. OCI_G(env) = NULL;
  1020. }
  1021. }
  1022. /* }}} */
  1023. /* {{{ PHP_GINIT_FUNCTION
  1024. *
  1025. * Zerofill globals during module init
  1026. */
  1027. static PHP_GINIT_FUNCTION(oci)
  1028. {
  1029. memset(oci_globals, 0, sizeof(zend_oci_globals));
  1030. }
  1031. /* }}} */
  1032. /* {{{ PHP_GSHUTDOWN_FUNCTION
  1033. *
  1034. * Called for thread shutdown in ZTS, after module shutdown for non-ZTS
  1035. */
  1036. static PHP_GSHUTDOWN_FUNCTION(oci)
  1037. {
  1038. php_oci_cleanup_global_handles(TSRMLS_C);
  1039. }
  1040. /* }}} */
  1041. PHP_MINIT_FUNCTION(oci)
  1042. {
  1043. zend_class_entry oci_lob_class_entry;
  1044. zend_class_entry oci_coll_class_entry;
  1045. REGISTER_INI_ENTRIES();
  1046. le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number);
  1047. le_connection = zend_register_list_destructors_ex(php_oci_connection_list_dtor, NULL, "oci8 connection", module_number);
  1048. le_pconnection = zend_register_list_destructors_ex(php_oci_pconnection_list_np_dtor, php_oci_pconnection_list_dtor, "oci8 persistent connection", module_number);
  1049. le_psessionpool = zend_register_list_destructors_ex(NULL, php_oci_spool_list_dtor, "oci8 persistent session pool", module_number);
  1050. le_descriptor = zend_register_list_destructors_ex(php_oci_descriptor_list_dtor, NULL, "oci8 descriptor", module_number);
  1051. le_collection = zend_register_list_destructors_ex(php_oci_collection_list_dtor, NULL, "oci8 collection", module_number);
  1052. INIT_CLASS_ENTRY(oci_lob_class_entry, "OCI-Lob", php_oci_lob_class_functions);
  1053. INIT_CLASS_ENTRY(oci_coll_class_entry, "OCI-Collection", php_oci_coll_class_functions);
  1054. oci_lob_class_entry_ptr = zend_register_internal_class(&oci_lob_class_entry TSRMLS_CC);
  1055. oci_coll_class_entry_ptr = zend_register_internal_class(&oci_coll_class_entry TSRMLS_CC);
  1056. /* thies@thieso.net 990203 i do not think that we will need all of them - just in here for completeness for now! */
  1057. REGISTER_LONG_CONSTANT("OCI_DEFAULT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT);
  1058. REGISTER_LONG_CONSTANT("OCI_SYSOPER",OCI_SYSOPER, CONST_CS | CONST_PERSISTENT);
  1059. REGISTER_LONG_CONSTANT("OCI_SYSDBA",OCI_SYSDBA, CONST_CS | CONST_PERSISTENT);
  1060. REGISTER_LONG_CONSTANT("OCI_CRED_EXT",PHP_OCI_CRED_EXT, CONST_CS | CONST_PERSISTENT);
  1061. REGISTER_LONG_CONSTANT("OCI_DESCRIBE_ONLY",OCI_DESCRIBE_ONLY, CONST_CS | CONST_PERSISTENT);
  1062. REGISTER_LONG_CONSTANT("OCI_COMMIT_ON_SUCCESS",OCI_COMMIT_ON_SUCCESS, CONST_CS | CONST_PERSISTENT);
  1063. REGISTER_LONG_CONSTANT("OCI_NO_AUTO_COMMIT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT);
  1064. REGISTER_LONG_CONSTANT("OCI_EXACT_FETCH",OCI_EXACT_FETCH, CONST_CS | CONST_PERSISTENT);
  1065. /* for $LOB->seek() */
  1066. REGISTER_LONG_CONSTANT("OCI_SEEK_SET",PHP_OCI_SEEK_SET, CONST_CS | CONST_PERSISTENT);
  1067. REGISTER_LONG_CONSTANT("OCI_SEEK_CUR",PHP_OCI_SEEK_CUR, CONST_CS | CONST_PERSISTENT);
  1068. REGISTER_LONG_CONSTANT("OCI_SEEK_END",PHP_OCI_SEEK_END, CONST_CS | CONST_PERSISTENT);
  1069. /* for $LOB->flush() */
  1070. REGISTER_LONG_CONSTANT("OCI_LOB_BUFFER_FREE",OCI_LOB_BUFFER_FREE, CONST_CS | CONST_PERSISTENT);
  1071. /* for OCIBindByName (real "oci" names + short "php" names */
  1072. REGISTER_LONG_CONSTANT("SQLT_BFILEE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
  1073. REGISTER_LONG_CONSTANT("SQLT_CFILEE",SQLT_CFILEE, CONST_CS | CONST_PERSISTENT);
  1074. REGISTER_LONG_CONSTANT("SQLT_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
  1075. REGISTER_LONG_CONSTANT("SQLT_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
  1076. REGISTER_LONG_CONSTANT("SQLT_RDD",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
  1077. REGISTER_LONG_CONSTANT("SQLT_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
  1078. REGISTER_LONG_CONSTANT("SQLT_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
  1079. REGISTER_LONG_CONSTANT("SQLT_RSET",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
  1080. REGISTER_LONG_CONSTANT("SQLT_AFC",SQLT_AFC, CONST_CS | CONST_PERSISTENT);
  1081. REGISTER_LONG_CONSTANT("SQLT_CHR",SQLT_CHR, CONST_CS | CONST_PERSISTENT);
  1082. REGISTER_LONG_CONSTANT("SQLT_VCS",SQLT_VCS, CONST_CS | CONST_PERSISTENT);
  1083. REGISTER_LONG_CONSTANT("SQLT_AVC",SQLT_AVC, CONST_CS | CONST_PERSISTENT);
  1084. REGISTER_LONG_CONSTANT("SQLT_STR",SQLT_STR, CONST_CS | CONST_PERSISTENT);
  1085. REGISTER_LONG_CONSTANT("SQLT_LVC",SQLT_LVC, CONST_CS | CONST_PERSISTENT);
  1086. REGISTER_LONG_CONSTANT("SQLT_FLT",SQLT_FLT, CONST_CS | CONST_PERSISTENT);
  1087. REGISTER_LONG_CONSTANT("SQLT_UIN",SQLT_UIN, CONST_CS | CONST_PERSISTENT);
  1088. REGISTER_LONG_CONSTANT("SQLT_LNG",SQLT_LNG, CONST_CS | CONST_PERSISTENT);
  1089. REGISTER_LONG_CONSTANT("SQLT_LBI",SQLT_LBI, CONST_CS | CONST_PERSISTENT);
  1090. REGISTER_LONG_CONSTANT("SQLT_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
  1091. REGISTER_LONG_CONSTANT("SQLT_ODT",SQLT_ODT, CONST_CS | CONST_PERSISTENT);
  1092. #if defined(HAVE_OCI_INSTANT_CLIENT) || (defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 10)
  1093. REGISTER_LONG_CONSTANT("SQLT_BDOUBLE",SQLT_BDOUBLE, CONST_CS | CONST_PERSISTENT);
  1094. REGISTER_LONG_CONSTANT("SQLT_BFLOAT",SQLT_BFLOAT, CONST_CS | CONST_PERSISTENT);
  1095. #endif
  1096. #if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
  1097. REGISTER_LONG_CONSTANT("SQLT_BOL",SQLT_BOL, CONST_CS | CONST_PERSISTENT);
  1098. #endif
  1099. REGISTER_LONG_CONSTANT("OCI_B_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
  1100. REGISTER_LONG_CONSTANT("SQLT_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
  1101. REGISTER_STRING_CONSTANT("OCI_SYSDATE","SYSDATE", CONST_CS | CONST_PERSISTENT);
  1102. REGISTER_LONG_CONSTANT("OCI_B_BFILE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
  1103. REGISTER_LONG_CONSTANT("OCI_B_CFILEE",SQLT_CFILEE, CONST_CS | CONST_PERSISTENT);
  1104. REGISTER_LONG_CONSTANT("OCI_B_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
  1105. REGISTER_LONG_CONSTANT("OCI_B_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
  1106. REGISTER_LONG_CONSTANT("OCI_B_ROWID",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
  1107. REGISTER_LONG_CONSTANT("OCI_B_CURSOR",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
  1108. REGISTER_LONG_CONSTANT("OCI_B_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
  1109. REGISTER_LONG_CONSTANT("OCI_B_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
  1110. REGISTER_LONG_CONSTANT("OCI_B_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
  1111. #if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
  1112. REGISTER_LONG_CONSTANT("OCI_B_BOL",SQLT_BOL, CONST_CS | CONST_PERSISTENT);
  1113. #endif
  1114. /* for OCIFetchStatement */
  1115. REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_COLUMN", PHP_OCI_FETCHSTATEMENT_BY_COLUMN, CONST_CS | CONST_PERSISTENT);
  1116. REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_ROW", PHP_OCI_FETCHSTATEMENT_BY_ROW, CONST_CS | CONST_PERSISTENT);
  1117. /* for OCIFetchInto & OCIResult */
  1118. REGISTER_LONG_CONSTANT("OCI_ASSOC",PHP_OCI_ASSOC, CONST_CS | CONST_PERSISTENT);
  1119. REGISTER_LONG_CONSTANT("OCI_NUM",PHP_OCI_NUM, CONST_CS | CONST_PERSISTENT);
  1120. REGISTER_LONG_CONSTANT("OCI_BOTH",PHP_OCI_BOTH, CONST_CS | CONST_PERSISTENT);
  1121. REGISTER_LONG_CONSTANT("OCI_RETURN_NULLS",PHP_OCI_RETURN_NULLS, CONST_CS | CONST_PERSISTENT);
  1122. REGISTER_LONG_CONSTANT("OCI_RETURN_LOBS",PHP_OCI_RETURN_LOBS, CONST_CS | CONST_PERSISTENT);
  1123. /* for OCINewDescriptor (real "oci" names + short "php" names */
  1124. REGISTER_LONG_CONSTANT("OCI_DTYPE_FILE",OCI_DTYPE_FILE, CONST_CS | CONST_PERSISTENT);
  1125. REGISTER_LONG_CONSTANT("OCI_DTYPE_LOB",OCI_DTYPE_LOB, CONST_CS | CONST_PERSISTENT);
  1126. REGISTER_LONG_CONSTANT("OCI_DTYPE_ROWID",OCI_DTYPE_ROWID, CONST_CS | CONST_PERSISTENT);
  1127. REGISTER_LONG_CONSTANT("OCI_D_FILE",OCI_DTYPE_FILE, CONST_CS | CONST_PERSISTENT);
  1128. REGISTER_LONG_CONSTANT("OCI_D_LOB",OCI_DTYPE_LOB, CONST_CS | CONST_PERSISTENT);
  1129. REGISTER_LONG_CONSTANT("OCI_D_ROWID",OCI_DTYPE_ROWID, CONST_CS | CONST_PERSISTENT);
  1130. /* for OCIWriteTemporaryLob */
  1131. REGISTER_LONG_CONSTANT("OCI_TEMP_CLOB",OCI_TEMP_CLOB, CONST_CS | CONST_PERSISTENT);
  1132. REGISTER_LONG_CONSTANT("OCI_TEMP_BLOB",OCI_TEMP_BLOB, CONST_CS | CONST_PERSISTENT);
  1133. return SUCCESS;
  1134. }
  1135. PHP_RINIT_FUNCTION(oci)
  1136. {
  1137. OCI_G(num_links) = OCI_G(num_persistent);
  1138. OCI_G(errcode) = 0;
  1139. OCI_G(edition) = NULL;
  1140. return SUCCESS;
  1141. }
  1142. PHP_MSHUTDOWN_FUNCTION(oci)
  1143. {
  1144. OCI_G(shutdown) = 1;
  1145. UNREGISTER_INI_ENTRIES();
  1146. return SUCCESS;
  1147. }
  1148. PHP_RSHUTDOWN_FUNCTION(oci)
  1149. {
  1150. /* Check persistent connections and do the necessary actions if needed. If persistent_helper is
  1151. * unable to process a pconnection because of a refcount, the processing would happen from
  1152. * np-destructor which is called when refcount goes to zero - php_oci_pconnection_list_np_dtor
  1153. */
  1154. zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
  1155. if (OCI_G(edition)) {
  1156. efree(OCI_G(edition));
  1157. }
  1158. return SUCCESS;
  1159. }
  1160. PHP_MINFO_FUNCTION(oci)
  1161. {
  1162. char buf[32];
  1163. #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))
  1164. char *ver;
  1165. #endif
  1166. php_info_print_table_start();
  1167. php_info_print_table_row(2, "OCI8 Support", "enabled");
  1168. #if defined(HAVE_OCI8_DTRACE)
  1169. php_info_print_table_row(2, "OCI8 DTrace Support", "enabled");
  1170. #else
  1171. php_info_print_table_row(2, "OCI8 DTrace Support", "disabled");
  1172. #endif
  1173. php_info_print_table_row(2, "OCI8 Version", PHP_OCI8_VERSION);
  1174. php_info_print_table_row(2, "Revision", "$Id$");
  1175. #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))
  1176. php_oci_client_get_version(&ver TSRMLS_CC);
  1177. php_info_print_table_row(2, "Oracle Run-time Client Library Version", ver);
  1178. efree(ver);
  1179. #else
  1180. php_info_print_table_row(2, "Oracle Run-time Client Library Version", "Unknown");
  1181. #endif
  1182. #if defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION)
  1183. snprintf(buf, sizeof(buf), "%d.%d", OCI_MAJOR_VERSION, OCI_MINOR_VERSION);
  1184. #elif defined(PHP_OCI8_ORACLE_VERSION)
  1185. snprintf(buf, sizeof(buf), "%s", PHP_OCI8_ORACLE_VERSION);
  1186. #else
  1187. snprintf(buf, sizeof(buf), "Unknown");
  1188. #endif
  1189. #if defined(HAVE_OCI_INSTANT_CLIENT)
  1190. php_info_print_table_row(2, "Oracle Compile-time Instant Client Version", buf);
  1191. #else
  1192. php_info_print_table_row(2, "Oracle Compile-time Version", buf);
  1193. #endif
  1194. #if !defined(PHP_WIN32) && !defined(HAVE_OCI_INSTANT_CLIENT)
  1195. #if defined(PHP_OCI8_DEF_DIR)
  1196. php_info_print_table_row(2, "Compile-time ORACLE_HOME", PHP_OCI8_DEF_DIR);
  1197. #endif
  1198. #if defined(PHP_OCI8_DEF_SHARED_LIBADD)
  1199. php_info_print_table_row(2, "Libraries Used", PHP_OCI8_DEF_SHARED_LIBADD);
  1200. #endif
  1201. #endif
  1202. php_info_print_table_end();
  1203. DISPLAY_INI_ENTRIES();
  1204. php_info_print_table_start();
  1205. php_info_print_table_header(2, "Statistics", "");
  1206. snprintf(buf, sizeof(buf), "%ld", OCI_G(num_persistent));
  1207. php_info_print_table_row(2, "Active Persistent Connections", buf);
  1208. snprintf(buf, sizeof(buf), "%ld", OCI_G(num_links));
  1209. php_info_print_table_row(2, "Active Connections", buf);
  1210. php_info_print_table_end();
  1211. }
  1212. /* }}} */
  1213. /* {{{ list destructors */
  1214. /* {{{ php_oci_connection_list_dtor()
  1215. *
  1216. * Non-persistent connection destructor
  1217. */
  1218. static void php_oci_connection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
  1219. {
  1220. php_oci_connection *connection = (php_oci_connection *)entry->ptr;
  1221. if (connection) {
  1222. php_oci_connection_close(connection TSRMLS_CC);
  1223. OCI_G(num_links)--;
  1224. }
  1225. }
  1226. /* }}} */
  1227. /* {{{ php_oci_pconnection_list_dtor()
  1228. *
  1229. * Persistent connection destructor
  1230. */
  1231. static void php_oci_pconnection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
  1232. {
  1233. php_oci_connection *connection = (php_oci_connection *)entry->ptr;
  1234. if (connection) {
  1235. php_oci_connection_close(connection TSRMLS_CC);
  1236. OCI_G(num_persistent)--;
  1237. OCI_G(num_links)--;
  1238. }
  1239. }
  1240. /* }}} */
  1241. /* {{{ php_oci_pconnection_list_np_dtor()
  1242. *
  1243. * Non-Persistent destructor for persistent connection - This gets invoked when
  1244. * the refcount of this goes to zero in the regular list
  1245. */
  1246. static void php_oci_pconnection_list_np_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
  1247. {
  1248. php_oci_connection *connection = (php_oci_connection *)entry->ptr;
  1249. zend_rsrc_list_entry *le;
  1250. /*
  1251. * We cannot get connection as NULL or as a stub in this function. This is the function that
  1252. * turns a pconnection to a stub
  1253. *
  1254. * If oci_password_change() changed the password of a persistent connection, close the
  1255. * connection and remove it from the persistent connection cache. This means subsequent scripts
  1256. * will be prevented from being able to present the old (now invalid) password to a usable
  1257. * connection to the database; they must use the new password.
  1258. *
  1259. * Check for conditions that warrant removal of the hash entry
  1260. */
  1261. if (!connection->is_open ||
  1262. connection->passwd_changed ||
  1263. (PG(connection_status) & PHP_CONNECTION_TIMEOUT) ||
  1264. OCI_G(in_call)) {
  1265. /* Remove the hash entry if present */
  1266. if ((zend_hash_find(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1, (void **) &le)== SUCCESS) && (le->type == le_pconnection) && (le->ptr == connection)) {
  1267. zend_hash_del(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1);
  1268. }
  1269. else {
  1270. php_oci_connection_close(connection TSRMLS_CC);
  1271. OCI_G(num_persistent)--;
  1272. }
  1273. #ifdef HAVE_OCI8_DTRACE
  1274. if (DTRACE_OCI8_CONNECT_P_DTOR_CLOSE_ENABLED()) {
  1275. DTRACE_OCI8_CONNECT_P_DTOR_CLOSE(connection);
  1276. }
  1277. #endif /* HAVE_OCI8_DTRACE */
  1278. } else {
  1279. /*
  1280. * Release the connection to underlying pool. We do this unconditionally so that
  1281. * out-of-scope pconnects are now consistent with oci_close and out-of-scope new connect
  1282. * semantics. With the PECL OCI 1.3.x extensions, we release pconnections when oci_close
  1283. * takes the refcount to zero.
  1284. *
  1285. * If oci_old_close_semantics is set, we artifically bump up the refcount and decremented
  1286. * only at request shutdown.
  1287. */
  1288. php_oci_connection_release(connection TSRMLS_CC);
  1289. #ifdef HAVE_OCI8_DTRACE
  1290. if (DTRACE_OCI8_CONNECT_P_DTOR_RELEASE_ENABLED()) {
  1291. DTRACE_OCI8_CONNECT_P_DTOR_RELEASE(connection);
  1292. }
  1293. #endif /* HAVE_OCI8_DTRACE */
  1294. }
  1295. }
  1296. /* }}} */
  1297. /* {{{ php_oci_statement_list_dtor()
  1298. *
  1299. * Statement destructor
  1300. */
  1301. static void php_oci_statement_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
  1302. {
  1303. php_oci_statement *statement = (php_oci_statement *)entry->ptr;
  1304. php_oci_statement_free(statement TSRMLS_CC);
  1305. }
  1306. /* }}} */
  1307. /* {{{ php_oci_descriptor_list_dtor()
  1308. *
  1309. * Descriptor destructor
  1310. */
  1311. static void php_oci_descriptor_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
  1312. {
  1313. php_oci_descriptor *descriptor = (php_oci_descriptor *)entry->ptr;
  1314. php_oci_lob_free(descriptor TSRMLS_CC);
  1315. }
  1316. /* }}} */
  1317. /* {{{ php_oci_collection_list_dtor()
  1318. *
  1319. * Collection destructor
  1320. */
  1321. static void php_oci_collection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
  1322. {
  1323. php_oci_collection *collection = (php_oci_collection *)entry->ptr;
  1324. php_oci_collection_close(collection TSRMLS_CC);
  1325. }
  1326. /* }}} */
  1327. /* }}} */
  1328. /* {{{ Hash Destructors */
  1329. /* {{{ php_oci_define_hash_dtor()
  1330. *
  1331. * Define hash destructor
  1332. */
  1333. void php_oci_define_hash_dtor(void *data)
  1334. {
  1335. php_oci_define *define = (php_oci_define *) data;
  1336. zval_ptr_dtor(&define->zval);
  1337. if (define->name) {
  1338. efree(define->name);
  1339. define->name = NULL;
  1340. }
  1341. }
  1342. /* }}} */
  1343. /* {{{ php_oci_bind_hash_dtor()
  1344. *
  1345. * Bind hash destructor
  1346. */
  1347. void php_oci_bind_hash_dtor(void *data)
  1348. {
  1349. php_oci_bind *bind = (php_oci_bind *) data;
  1350. if (bind->array.elements) {
  1351. efree(bind->array.elements);
  1352. }
  1353. if (bind->array.element_lengths) {
  1354. efree(bind->array.element_lengths);
  1355. }
  1356. if (bind->array.indicators) {
  1357. efree(bind->array.indicators);
  1358. }
  1359. zval_ptr_dtor(&bind->zval);
  1360. }
  1361. /* }}} */
  1362. /* {{{ php_oci_column_hash_dtor()
  1363. *
  1364. * Column hash destructor
  1365. */
  1366. void php_oci_column_hash_dtor(void *data)
  1367. {
  1368. php_oci_out_column *column = (php_oci_out_column *) data;
  1369. TSRMLS_FETCH();
  1370. if (column->stmtid) {
  1371. zend_list_delete(column->stmtid);
  1372. }
  1373. if (column->is_descr) {
  1374. zend_list_delete(column->descid);
  1375. }
  1376. if (column->data) {
  1377. efree(column->data);
  1378. }
  1379. if (column->name) {
  1380. efree(column->name);
  1381. }
  1382. }
  1383. /* }}} */
  1384. /* {{{ php_oci_descriptor_flush_hash_dtor()
  1385. *
  1386. * Flush descriptors on commit
  1387. */
  1388. void php_oci_descriptor_flush_hash_dtor(void *data)
  1389. {
  1390. php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
  1391. TSRMLS_FETCH();
  1392. if (descriptor && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) {
  1393. php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC);
  1394. descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
  1395. }
  1396. data = NULL;
  1397. }
  1398. /* }}} */
  1399. /* }}} */
  1400. /* {{{ php_oci_connection_descriptors_free()
  1401. *
  1402. * Free descriptors for a connection
  1403. */
  1404. void php_oci_connection_descriptors_free(php_oci_connection *connection TSRMLS_DC)
  1405. {
  1406. zend_hash_destroy(connection->descriptors);
  1407. efree(connection->descriptors);
  1408. connection->descriptors = NULL;
  1409. connection->descriptor_count = 0;
  1410. }
  1411. /* }}} */
  1412. /* {{{ php_oci_error()
  1413. *
  1414. * Fetch & print out error message if we get an error
  1415. * Returns an Oracle error number
  1416. */
  1417. sb4 php_oci_error(OCIError *err_p, sword errstatus TSRMLS_DC)
  1418. {
  1419. text *errbuf = (text *)NULL;
  1420. sb4 errcode = 0; /* Oracle error number */
  1421. switch (errstatus) {
  1422. case OCI_SUCCESS:
  1423. break;
  1424. case OCI_SUCCESS_WITH_INFO:
  1425. errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
  1426. if (errbuf) {
  1427. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", errbuf);
  1428. efree(errbuf);
  1429. } else {
  1430. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: failed to fetch error message");
  1431. }
  1432. break;
  1433. case OCI_NEED_DATA:
  1434. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NEED_DATA");
  1435. break;
  1436. case OCI_NO_DATA:
  1437. errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
  1438. if (errbuf) {
  1439. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf);
  1440. efree(errbuf);
  1441. } else {
  1442. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NO_DATA: failed to fetch error message");
  1443. }
  1444. break;
  1445. case OCI_ERROR:
  1446. errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
  1447. if (errbuf) {
  1448. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf);
  1449. efree(errbuf);
  1450. } else {
  1451. php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to fetch error message");
  1452. }
  1453. break;
  1454. case OCI_INVALID_HANDLE:
  1455. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_INVALID_HANDLE");
  1456. break;
  1457. case OCI_STILL_EXECUTING:
  1458. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_STILL_EXECUTING");
  1459. break;
  1460. case OCI_CONTINUE:
  1461. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CONTINUE");
  1462. break;
  1463. default:
  1464. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", errstatus);
  1465. break;
  1466. }
  1467. #ifdef HAVE_OCI8_DTRACE
  1468. if (DTRACE_OCI8_ERROR_ENABLED()) {
  1469. DTRACE_OCI8_ERROR((int)errstatus, (long)errcode);
  1470. }
  1471. #endif /* HAVE_OCI8_DTRACE */
  1472. return errcode;
  1473. }
  1474. /* }}} */
  1475. /* {{{ php_oci_fetch_errmsg()
  1476. *
  1477. * Fetch error message into the buffer from the error handle provided
  1478. */
  1479. sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf TSRMLS_DC)
  1480. {
  1481. sb4 error_code = 0;
  1482. text err_buf[PHP_OCI_ERRBUF_LEN];
  1483. memset(err_buf, 0, sizeof(err_buf));
  1484. PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, err_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR));
  1485. if (error_code) {
  1486. int err_buf_len = strlen((char *)err_buf);
  1487. if (err_buf_len && err_buf[err_buf_len - 1] == '\n') {
  1488. err_buf[err_buf_len - 1] = '\0';
  1489. }
  1490. if (err_buf_len && error_buf) {
  1491. *error_buf = NULL;
  1492. *error_buf = (text *)estrndup((char *)err_buf, err_buf_len);
  1493. }
  1494. }
  1495. return error_code;
  1496. }
  1497. /* }}} */
  1498. /* {{{ php_oci_fetch_sqltext_offset()
  1499. *
  1500. * Compute offset in the SQL statement
  1501. */
  1502. int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, ub2 *error_offset TSRMLS_DC)
  1503. {
  1504. sword errstatus;
  1505. *sqltext = NULL;
  1506. *error_offset = 0;
  1507. PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *) sqltext, (ub4 *)0, OCI_ATTR_STATEMENT, statement->err));
  1508. if (errstatus != OCI_SUCCESS) {
  1509. statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
  1510. PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
  1511. return 1;
  1512. }
  1513. PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)error_offset, (ub4 *)0, OCI_ATTR_PARSE_ERROR_OFFSET, statement->err));
  1514. if (errstatus != OCI_SUCCESS) {
  1515. statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
  1516. PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
  1517. return 1;
  1518. }
  1519. return 0;
  1520. }
  1521. /* }}} */
  1522. /* {{{ php_oci_do_connect()
  1523. *
  1524. * Connect wrapper
  1525. */
  1526. void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclusive)
  1527. {
  1528. php_oci_connection *connection;
  1529. char *username, *password;
  1530. char *dbname = NULL, *charset = NULL;
  1531. int username_len = 0, password_len = 0;
  1532. int dbname_len = 0, charset_len = 0;
  1533. long session_mode = OCI_DEFAULT;
  1534. /* if a fourth parameter is handed over, it is the charset identifier (but is only used in Oracle 9i+) */
  1535. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ssl", &username, &username_len, &password, &password_len, &dbname, &dbname_len, &charset, &charset_len, &session_mode) == FAILURE) {
  1536. return;
  1537. }
  1538. #ifdef HAVE_OCI8_DTRACE
  1539. if (DTRACE_OCI8_CONNECT_ENTRY_ENABLED()) {
  1540. DTRACE_OCI8_CONNECT_ENTRY(username, dbname, charset, session_mode, persistent, exclusive);
  1541. }
  1542. #endif /* HAVE_OCI8_DTRACE */
  1543. if (!charset_len) {
  1544. charset = NULL;
  1545. }
  1546. connection = php_oci_do_connect_ex(username, username_len, password, password_len, NULL, 0, dbname, dbname_len, charset, session_mode, persistent, exclusive TSRMLS_CC);
  1547. #ifdef HAVE_OCI8_DTRACE
  1548. if (DTRACE_OCI8_CONNECT_RETURN_ENABLED()) {
  1549. DTRACE_OCI8_CONNECT_RETURN(connection);
  1550. }
  1551. #endif /* HAVE_OCI8_DTRACE */
  1552. if (!connection) {
  1553. RETURN_FALSE;
  1554. }
  1555. RETURN_RESOURCE(connection->id);
  1556. }
  1557. /* }}} */
  1558. /* {{{ php_oci_do_connect_ex()
  1559. *
  1560. * The real connect function. Allocates all the resources needed, establishes the connection and
  1561. * returns the result handle (or NULL)
  1562. */
  1563. php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, char *dbname, int dbname_len, char *charset, long session_mode, int persistent, int exclusive TSRMLS_DC)
  1564. {
  1565. zend_rsrc_list_entry *le;
  1566. zend_rsrc_list_entry new_le;
  1567. php_oci_connection *connection = NULL;
  1568. smart_str hashed_details = {0};
  1569. time_t timestamp;
  1570. php_oci_spool *session_pool = NULL;
  1571. zend_bool use_spool = 1; /* Default is to use client-side session pool */
  1572. zend_bool ping_done = 0;
  1573. ub2 charsetid = 0;
  1574. ub2 charsetid_nls_lang = 0;
  1575. if (session_mode & ~(OCI_SYSOPER | OCI_SYSDBA | PHP_OCI_CRED_EXT)) {
  1576. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid session mode specified (%ld)", session_mode);
  1577. return NULL;
  1578. }
  1579. if (session_mode & (OCI_SYSOPER | OCI_SYSDBA | PHP_OCI_CRED_EXT)) {
  1580. if ((session_mode & OCI_SYSOPER) && (session_mode & OCI_SYSDBA)) {
  1581. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SYSDBA and OCI_SYSOPER cannot be used together");
  1582. return NULL;
  1583. }
  1584. if (session_mode & PHP_OCI_CRED_EXT) {
  1585. #ifdef PHP_WIN32
  1586. /* Disable external authentication on Windows as Impersonation is not yet handled.
  1587. * TODO: Re-enable this once OCI provides capability.
  1588. */
  1589. php_error_docref(NULL TSRMLS_CC, E_WARNING, "External Authentication is not supported on Windows");
  1590. return NULL;
  1591. #endif
  1592. if (username_len != 1 || username[0] != '/' || password_len != 0) {
  1593. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CRED_EXT can only be used with a username of \"/\" and a NULL password");
  1594. return NULL;
  1595. }
  1596. }
  1597. if (session_mode & (OCI_SYSOPER | OCI_SYSDBA)) {
  1598. /* Increase security by not caching privileged oci_pconnect() connections. The
  1599. * connection becomes equivalent to oci_connect() or oci_new_connect().
  1600. */
  1601. persistent = 0;
  1602. if (!OCI_G(privileged_connect)) {
  1603. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Privileged connect is disabled. Enable oci8.privileged_connect to be able to connect as SYSOPER or SYSDBA");
  1604. return NULL;
  1605. }
  1606. #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || (PHP_MAJOR_VERSION < 5)
  1607. /* Safe mode has been removed in PHP 5.4 */
  1608. if (PG(safe_mode)) {
  1609. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Privileged connect is disabled in Safe Mode");
  1610. return NULL;
  1611. }
  1612. #endif
  1613. }
  1614. }
  1615. /* Initialize global handles if they weren't initialized before */
  1616. if (OCI_G(env) == NULL) {
  1617. php_oci_init_global_handles(TSRMLS_C);
  1618. if (OCI_G(env) == NULL) {
  1619. return NULL;
  1620. }
  1621. }
  1622. /* We cannot use the new session create logic (OCISessionGet from
  1623. * client-side session pool) when privileged connect or password
  1624. * change is attempted or OCI_CRED_EXT mode is specified.
  1625. * TODO: Re-enable this when OCI provides support.
  1626. */
  1627. if ((session_mode & (OCI_SYSOPER | OCI_SYSDBA | PHP_OCI_CRED_EXT)) || (new_password_len)) {
  1628. use_spool = 0;
  1629. }
  1630. smart_str_appendl_ex(&hashed_details, "oci8***", sizeof("oci8***") - 1, 0);
  1631. smart_str_appendl_ex(&hashed_details, username, username_len, 0);
  1632. smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
  1633. /* DRCP: connection_class is an attribute of a connection */
  1634. if (OCI_G(connection_class)){
  1635. smart_str_appendl_ex(&hashed_details, OCI_G(connection_class), strlen(OCI_G(connection_class)), 0);
  1636. }
  1637. smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
  1638. /* Add edition attribute to the hash */
  1639. if (OCI_G(edition)){
  1640. smart_str_appendl_ex(&hashed_details, OCI_G(edition), strlen(OCI_G(edition)), 0);
  1641. }
  1642. smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
  1643. if (password_len) {
  1644. ulong password_hash;
  1645. password_hash = zend_inline_hash_func(password, password_len);
  1646. smart_str_append_unsigned_ex(&hashed_details, password_hash, 0);
  1647. }
  1648. smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
  1649. if (dbname) {
  1650. smart_str_appendl_ex(&hashed_details, dbname, dbname_len, 0);
  1651. }
  1652. smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
  1653. if (charset && *charset) {
  1654. PHP_OCI_CALL_RETURN(charsetid, OCINlsCharSetNameToId, (OCI_G(env), (CONST oratext *)charset));
  1655. if (!charsetid) {
  1656. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid character set name: %s", charset);
  1657. } else {
  1658. smart_str_append_unsigned_ex(&hashed_details, charsetid, 0);
  1659. }
  1660. }
  1661. /* use NLS_LANG if no or invalid charset specified */
  1662. if (!charsetid) {
  1663. size_t rsize = 0;
  1664. sword result;
  1665. PHP_OCI_CALL_RETURN(result, OCINlsEnvironmentVariableGet, (&charsetid_nls_lang, 0, OCI_NLS_CHARSET_ID, 0, &rsize));
  1666. if (result != OCI_SUCCESS) {
  1667. charsetid_nls_lang = 0;
  1668. }
  1669. smart_str_append_unsigned_ex(&hashed_details, charsetid_nls_lang, 0);
  1670. }
  1671. timestamp = time(NULL);
  1672. smart_str_append_unsigned_ex(&hashed_details, session_mode, 0);
  1673. smart_str_0(&hashed_details);
  1674. /* make it lowercase */
  1675. php_strtolower(hashed_details.c, hashed_details.len);
  1676. if (!exclusive && !new_password) {
  1677. zend_bool found = 0;
  1678. if (persistent && zend_hash_find(&EG(persistent_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
  1679. found = 1;
  1680. /* found */
  1681. if (le->type == le_pconnection) {
  1682. connection = (php_oci_connection *)le->ptr;
  1683. }
  1684. } else if (!persistent && zend_hash_find(&EG(regular_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
  1685. found = 1;
  1686. if (le->type == le_index_ptr) {
  1687. int type, link;
  1688. void *ptr;
  1689. link = OCI8_PTR_TO_INT(le->ptr);
  1690. ptr = zend_list_find(link,&type);
  1691. if (ptr && (type == le_connection)) {
  1692. connection = (php_oci_connection *)ptr;
  1693. }
  1694. }
  1695. }
  1696. #ifdef HAVE_OCI8_DTRACE
  1697. if (DTRACE_OCI8_CONNECT_LOOKUP_ENABLED()) {
  1698. DTRACE_OCI8_CONNECT_LOOKUP(connection, connection && connection->is_stub ? 1 : 0);
  1699. }
  1700. #endif /* HAVE_OCI8_DTRACE */
  1701. /* If we got a pconnection stub, then 'load'(OCISessionGet) the real connection from its
  1702. * private spool A connection is a stub if it is only a cached structure and the real
  1703. * connection is released to its underlying private session pool. We currently do not have
  1704. * stub support for non-persistent conns.
  1705. *
  1706. * TODO: put in negative code for non-persistent stubs
  1707. */
  1708. if (connection && connection->is_persistent && connection->is_stub) {
  1709. if (php_oci_create_session(connection, NULL, dbname, dbname_len, username, username_len, password, password_len, new_password, new_password_len, session_mode TSRMLS_CC)) {
  1710. smart_str_free_ex(&hashed_details, 0);
  1711. zend_hash_del(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1);
  1712. return NULL;
  1713. }
  1714. /* We do the ping in php_oci_create_session, no need to ping again below */
  1715. ping_done = 1;
  1716. }
  1717. if (connection) {
  1718. if (connection->is_open) {
  1719. /* found an open connection. now ping it */
  1720. if (connection->is_persistent) {
  1721. int rsrc_type;
  1722. /* Check connection liveness in the following order:
  1723. * 1) always check OCI_ATTR_SERVER_STATUS
  1724. * 2) see if it's time to ping it
  1725. * 3) ping it if needed
  1726. */
  1727. if (php_oci_connection_status(connection TSRMLS_CC)) {
  1728. /* Only ping if:
  1729. *
  1730. * 1) next_ping > 0, which means that ping_interval is not -1 (aka "Off")
  1731. *
  1732. * 2) current_timestamp > next_ping, which means "it's time to check if it's
  1733. * still alive"
  1734. */
  1735. if (!ping_done && (*(connection->next_pingp) > 0) && (timestamp >= *(connection->next_pingp)) && !php_oci_connection_ping(connection TSRMLS_CC)) {
  1736. /* server died */
  1737. } else {
  1738. php_oci_connection *tmp;
  1739. /* okay, the connection is open and the server is still alive */
  1740. connection->used_this_request = 1;
  1741. tmp = (php_oci_connection *)zend_list_find(connection->id, &rsrc_type);
  1742. if (tmp != NULL && rsrc_type == le_pconnection && strlen(tmp->hash_key) == hashed_details.len &&
  1743. memcmp(tmp->hash_key, hashed_details.c, hashed_details.len) == 0 && zend_list_addref(connection->id) == SUCCESS) {
  1744. /* do nothing */
  1745. } else {
  1746. PHP_OCI_REGISTER_RESOURCE(connection, le_pconnection);
  1747. /* Persistent connections: For old close semantics we artificially
  1748. * bump up the refcount to prevent the non-persistent destructor
  1749. * from getting called until request shutdown. The refcount is
  1750. * decremented in the persistent helper
  1751. */
  1752. if (OCI_G(old_oci_close_semantics)) {
  1753. zend_list_addref(connection->id);
  1754. }
  1755. }
  1756. smart_str_free_ex(&hashed_details, 0);
  1757. return connection;
  1758. }
  1759. }
  1760. /* server died */
  1761. } else {
  1762. /* we do not ping non-persistent connections */
  1763. smart_str_free_ex(&hashed_details, 0);
  1764. zend_list_addref(connection->id);
  1765. return connection;
  1766. }
  1767. } /* is_open is true? */
  1768. /* Server died - connection not usable. The is_open=true can also fall through to here,
  1769. * if ping fails
  1770. */
  1771. if (persistent){
  1772. int rsrc_type;
  1773. connection->is_open = 0;
  1774. connection->used_this_request = 1;
  1775. /* We have to do a hash_del but need to preserve the resource if there is a positive
  1776. * refcount. Set the data pointer in the list entry to NULL
  1777. */
  1778. if (connection == zend_list_find(connection->id, &rsrc_type) && rsrc_type == le_pconnection) {
  1779. le->ptr = NULL;
  1780. }
  1781. zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
  1782. } else {
  1783. /* We only remove the hash entry. The resource and the list entry with its pointer
  1784. * to the resource are still intact
  1785. */
  1786. zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
  1787. }
  1788. connection = NULL;
  1789. } else if (found) {
  1790. /* found something, but it's not a connection, delete it */
  1791. if (persistent) {
  1792. zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
  1793. } else {
  1794. zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
  1795. }
  1796. }
  1797. }
  1798. /* Check if we have reached max_persistent. If so, try to remove a few timed-out connections. As
  1799. * a last resort, return a non-persistent connection.
  1800. */
  1801. if (persistent) {
  1802. zend_bool alloc_non_persistent = 0;
  1803. if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) {
  1804. /* try to find an idle connection and kill it */
  1805. zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
  1806. if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) {
  1807. /* all persistent connactions are in use, fallback to non-persistent connection creation */
  1808. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Too many open persistent connections (%ld)", OCI_G(num_persistent));
  1809. alloc_non_persistent = 1;
  1810. }
  1811. }
  1812. if (alloc_non_persistent) {
  1813. connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
  1814. connection->hash_key = estrndup(hashed_details.c, hashed_details.len);
  1815. connection->is_persistent = 0;
  1816. #ifdef HAVE_OCI8_DTRACE
  1817. connection->client_id = NULL;
  1818. #endif
  1819. } else {
  1820. connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection));
  1821. if (connection == NULL) {
  1822. return NULL;
  1823. }
  1824. connection->hash_key = zend_strndup(hashed_details.c, hashed_details.len);
  1825. if (connection->hash_key == NULL) {
  1826. free(connection);
  1827. return NULL;
  1828. }
  1829. connection->is_persistent = 1;
  1830. #ifdef HAVE_OCI8_DTRACE
  1831. connection->client_id = NULL;
  1832. #endif
  1833. }
  1834. } else {
  1835. connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
  1836. connection->hash_key = estrndup(hashed_details.c, hashed_details.len);
  1837. connection->is_persistent = 0;
  1838. #ifdef HAVE_OCI8_DTRACE
  1839. connection->client_id = NULL;
  1840. #endif
  1841. }
  1842. /* {{{ Get the session pool that suits this connection request from the persistent list. This
  1843. * step is only for non-persistent connections as persistent connections have private session
  1844. * pools. Non-persistent conns use shared session pool to allow for optimizations such as
  1845. * caching the physical connection (for DRCP) even when the non-persistent php connection is
  1846. * destroyed.
  1847. *
  1848. * TODO: Unconditionally do this once OCI provides extended OCISessionGet capability
  1849. */
  1850. if (use_spool && !connection->is_persistent) {
  1851. if ((session_pool = php_oci_get_spool(username, username_len, password, password_len, dbname, dbname_len, charsetid ? charsetid:charsetid_nls_lang TSRMLS_CC))==NULL)
  1852. {
  1853. php_oci_connection_close(connection TSRMLS_CC);
  1854. smart_str_free_ex(&hashed_details, 0);
  1855. return NULL;
  1856. }
  1857. }
  1858. /* }}} */
  1859. connection->idle_expiry = (OCI_G(persistent_timeout) > 0) ? (timestamp + OCI_G(persistent_timeout)) : 0;
  1860. /* Mark password as unchanged by PHP during the duration of the database session */
  1861. connection->passwd_changed = 0;
  1862. smart_str_free_ex(&hashed_details, 0);
  1863. if (charsetid) {
  1864. connection->charset = charsetid;
  1865. } else {
  1866. connection->charset = charsetid_nls_lang;
  1867. }
  1868. /* Old session creation semantics when session pool cannot be used Eg: privileged
  1869. * connect/password change
  1870. */
  1871. if (!use_spool) {
  1872. if (php_oci_old_create_session(connection, dbname, dbname_len, username, username_len, password, password_len, new_password, new_password_len, session_mode TSRMLS_CC)) {
  1873. php_oci_connection_close(connection TSRMLS_CC);
  1874. return NULL;
  1875. }
  1876. } else {
  1877. /* create using the client-side session pool */
  1878. if (php_oci_create_session(connection, session_pool, dbname, dbname_len, username, username_len, password, password_len, new_password, new_password_len, session_mode TSRMLS_CC)) {
  1879. php_oci_connection_close(connection TSRMLS_CC);
  1880. return NULL;
  1881. }
  1882. }
  1883. /* Mark it as open */
  1884. connection->is_open = 1;
  1885. /* add to the appropriate hash */
  1886. if (connection->is_persistent) {
  1887. new_le.ptr = connection;
  1888. new_le.type = le_pconnection;
  1889. connection->used_this_request = 1;
  1890. PHP_OCI_REGISTER_RESOURCE(connection, le_pconnection);
  1891. /* Persistent connections: For old close semantics we artificially bump up the refcount to
  1892. * prevent the non-persistent destructor from getting called until request shutdown. The
  1893. * refcount is decremented in the persistent helper
  1894. */
  1895. if (OCI_G(old_oci_close_semantics)) {
  1896. zend_list_addref(connection->id);
  1897. }
  1898. zend_hash_update(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL);
  1899. OCI_G(num_persistent)++;
  1900. OCI_G(num_links)++;
  1901. } else if (!exclusive) {
  1902. PHP_OCI_REGISTER_RESOURCE(connection, le_connection);
  1903. new_le.ptr = OCI8_INT_TO_PTR(connection->id);
  1904. new_le.type = le_index_ptr;
  1905. zend_hash_update(&EG(regular_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL);
  1906. OCI_G(num_links)++;
  1907. } else {
  1908. PHP_OCI_REGISTER_RESOURCE(connection, le_connection);
  1909. OCI_G(num_links)++;
  1910. }
  1911. #ifdef HAVE_OCI8_DTRACE
  1912. if (DTRACE_OCI8_CONNECT_TYPE_ENABLED()) {
  1913. DTRACE_OCI8_CONNECT_TYPE(connection->is_persistent ? 1 : 0, exclusive ? 1 : 0, connection, OCI_G(num_persistent), OCI_G(num_links));
  1914. }
  1915. #endif /* HAVE_OCI8_DTRACE */
  1916. return connection;
  1917. }
  1918. /* }}} */
  1919. /* {{{ php_oci_connection_ping()
  1920. *
  1921. * Ping connection. Uses OCIPing() or OCIServerVersion() depending on the Oracle Client version
  1922. */
  1923. static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC)
  1924. {
  1925. sword errstatus;
  1926. #if (!((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))))
  1927. char version[256];
  1928. #endif
  1929. OCI_G(errcode) = 0; /* assume ping is successful */
  1930. /* Use OCIPing instead of OCIServerVersion. If OCIPing returns ORA-1010 (invalid OCI operation)
  1931. * such as from Pre-10.1 servers, the error is still from the server and we would have
  1932. * successfully performed a roundtrip and validated the connection. Use OCIServerVersion for
  1933. * Pre-10.2 clients
  1934. */
  1935. #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIPing available 10.2 onwards */
  1936. PHP_OCI_CALL_RETURN(errstatus, OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT));
  1937. #else
  1938. /* use good old OCIServerVersion() */
  1939. PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, OCI_G(err), (text *)version, sizeof(version), OCI_HTYPE_SVCCTX));
  1940. #endif
  1941. if (errstatus == OCI_SUCCESS) {
  1942. return 1;
  1943. } else {
  1944. sb4 error_code = 0;
  1945. text tmp_buf[OCI_ERROR_MAXMSG_SIZE];
  1946. /* Treat ORA-1010 as a successful Ping */
  1947. OCIErrorGet(OCI_G(err), (ub4)1, NULL, &error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ERROR);
  1948. if (error_code == 1010) {
  1949. return 1;
  1950. }
  1951. OCI_G(errcode) = error_code;
  1952. }
  1953. return 0;
  1954. }
  1955. /* }}} */
  1956. /* {{{ php_oci_connection_status()
  1957. *
  1958. * Check connection status (pre-ping check)
  1959. */
  1960. static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC)
  1961. {
  1962. ub4 ss = OCI_SERVER_NOT_CONNECTED;
  1963. sword errstatus;
  1964. /* get OCI_ATTR_SERVER_STATUS */
  1965. PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)connection->server, OCI_HTYPE_SERVER, (dvoid *)&ss, (ub4 *)0, OCI_ATTR_SERVER_STATUS, OCI_G(err)));
  1966. if (errstatus == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) {
  1967. return 1;
  1968. }
  1969. /* ignore errors here, just return failure */
  1970. return 0;
  1971. }
  1972. /* }}} */
  1973. /* {{{ php_oci_connection_rollback()
  1974. *
  1975. * Rollback connection
  1976. */
  1977. int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC)
  1978. {
  1979. sword errstatus;
  1980. PHP_OCI_CALL_RETURN(errstatus, OCITransRollback, (connection->svc, connection->err, (ub4) 0));
  1981. connection->rb_on_disconnect = 0;
  1982. if (errstatus != OCI_SUCCESS) {
  1983. connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
  1984. PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
  1985. return 1;
  1986. }
  1987. connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
  1988. return 0;
  1989. }
  1990. /* }}} */
  1991. /* {{{ php_oci_connection_commit()
  1992. *
  1993. * Commit connection
  1994. */
  1995. int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC)
  1996. {
  1997. sword errstatus;
  1998. PHP_OCI_CALL_RETURN(errstatus, OCITransCommit, (connection->svc, connection->err, (ub4) 0));
  1999. connection->rb_on_disconnect = 0;
  2000. if (errstatus != OCI_SUCCESS) {
  2001. connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
  2002. PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
  2003. return 1;
  2004. }
  2005. connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
  2006. return 0;
  2007. }
  2008. /* }}} */
  2009. /* {{{ php_oci_connection_close()
  2010. *
  2011. * Close the connection and free all its resources
  2012. */
  2013. static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC)
  2014. {
  2015. int result = 0;
  2016. zend_bool in_call_save = OCI_G(in_call);
  2017. #ifdef HAVE_OCI8_DTRACE
  2018. if (DTRACE_OCI8_CONNECTION_CLOSE_ENABLED()) {
  2019. DTRACE_OCI8_CONNECTION_CLOSE(connection);
  2020. }
  2021. #endif /* HAVE_OCI8_DTRACE */
  2022. if (!connection->is_stub) {
  2023. /* Release resources associated with connection */
  2024. php_oci_connection_release(connection TSRMLS_CC);
  2025. }
  2026. if (!connection->using_spool && connection->svc) {
  2027. PHP_OCI_CALL(OCISessionEnd, (connection->svc, connection->err, connection->session, (ub4) 0));
  2028. }
  2029. if (connection->err) {
  2030. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->err, (ub4) OCI_HTYPE_ERROR));
  2031. }
  2032. if (connection->authinfo) {
  2033. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->authinfo, (ub4) OCI_HTYPE_AUTHINFO));
  2034. }
  2035. /* No Handlefrees for session pool connections */
  2036. if (!connection->using_spool) {
  2037. if (connection->session) {
  2038. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->session, OCI_HTYPE_SESSION));
  2039. }
  2040. if (connection->is_attached) {
  2041. PHP_OCI_CALL(OCIServerDetach, (connection->server, OCI_G(err), OCI_DEFAULT));
  2042. }
  2043. if (connection->svc) {
  2044. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX));
  2045. }
  2046. if (connection->server) {
  2047. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->server, (ub4) OCI_HTYPE_SERVER));
  2048. }
  2049. if (connection->env) {
  2050. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->env, OCI_HTYPE_ENV));
  2051. }
  2052. } else if (connection->private_spool) {
  2053. /* Keep this as the last member to be freed, as there are dependencies
  2054. * (like env) on the session pool
  2055. */
  2056. php_oci_spool_close(connection->private_spool TSRMLS_CC);
  2057. }
  2058. if (connection->hash_key) {
  2059. pefree(connection->hash_key, connection->is_persistent);
  2060. }
  2061. #ifdef HAVE_OCI8_DTRACE
  2062. if (connection->client_id) {
  2063. pefree(connection->client_id, connection->is_persistent);
  2064. }
  2065. #endif /* HAVE_OCI8_DTRACE */
  2066. pefree(connection, connection->is_persistent);
  2067. connection = NULL;
  2068. OCI_G(in_call) = in_call_save;
  2069. return result;
  2070. }
  2071. /* }}} */
  2072. /* {{{ php_oci_connection_release()
  2073. *
  2074. * Release the connection's resources. This involves freeing descriptors and rolling back
  2075. * transactions, setting timeout-related parameters etc. For session-pool using connections, the
  2076. * underlying connection is released to its session pool.
  2077. */
  2078. int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC)
  2079. {
  2080. int result = 0;
  2081. zend_bool in_call_save = OCI_G(in_call);
  2082. time_t timestamp = time(NULL);
  2083. if (connection->is_stub) {
  2084. return 0;
  2085. }
  2086. if (connection->descriptors) {
  2087. php_oci_connection_descriptors_free(connection TSRMLS_CC);
  2088. }
  2089. if (connection->svc) {
  2090. /* rollback outstanding transactions */
  2091. if (connection->rb_on_disconnect) {
  2092. if (php_oci_connection_rollback(connection TSRMLS_CC)) {
  2093. /* rollback failed */
  2094. result = 1;
  2095. }
  2096. }
  2097. }
  2098. if (OCI_G(persistent_timeout) > 0) {
  2099. connection->idle_expiry = timestamp + OCI_G(persistent_timeout);
  2100. }
  2101. /* We may have half-cooked connections to clean up */
  2102. if (connection->next_pingp) {
  2103. if (OCI_G(ping_interval) >= 0) {
  2104. *(connection->next_pingp) = timestamp + OCI_G(ping_interval);
  2105. } else {
  2106. /* ping_interval is -1 */
  2107. *(connection->next_pingp) = 0;
  2108. }
  2109. }
  2110. /* Release the session (stubs are filtered out at the beginning)*/
  2111. if (connection->using_spool) {
  2112. ub4 rlsMode = OCI_DEFAULT;
  2113. if (result) {
  2114. rlsMode |= OCI_SESSRLS_DROPSESS;
  2115. }
  2116. /* Sessions for non-persistent connections should be dropped. For 11 and above, the session
  2117. * pool has its own mechanism for doing so for purity NEW connections. We need to do so
  2118. * explicitly for 10.2 and earlier.
  2119. */
  2120. #if (!(OCI_MAJOR_VERSION >= 11))
  2121. if (!connection->is_persistent) {
  2122. rlsMode |= OCI_SESSRLS_DROPSESS;
  2123. }
  2124. #endif
  2125. if (connection->svc) {
  2126. PHP_OCI_CALL(OCISessionRelease, (connection->svc, connection->err, NULL,
  2127. 0, rlsMode));
  2128. }
  2129. /* It no longer has relation with the database session. However authinfo and env are
  2130. * cached
  2131. */
  2132. connection->svc = NULL;
  2133. connection->server = NULL;
  2134. connection->session = NULL;
  2135. connection->is_attached = connection->is_open = connection->rb_on_disconnect = connection->used_this_request = 0;
  2136. connection->is_stub = 1;
  2137. /* Cut the link between the connection structure and the time_t structure allocated within
  2138. * the OCI session
  2139. */
  2140. connection->next_pingp = NULL;
  2141. #ifdef HAVE_OCI8_DTRACE
  2142. if (connection->client_id) {
  2143. pefree(connection->client_id, connection->is_persistent);
  2144. connection->client_id = NULL;
  2145. }
  2146. #endif /* HAVE_OCI8_DTRACE */
  2147. }
  2148. OCI_G(in_call) = in_call_save;
  2149. return result;
  2150. }
  2151. /* }}} */
  2152. /* {{{ php_oci_password_change()
  2153. *
  2154. * Change password for the user with the username given
  2155. */
  2156. int php_oci_password_change(php_oci_connection *connection, char *user, int user_len, char *pass_old, int pass_old_len, char *pass_new, int pass_new_len TSRMLS_DC)
  2157. {
  2158. sword errstatus;
  2159. PHP_OCI_CALL_RETURN(errstatus, OCIPasswordChange, (connection->svc, connection->err, (text *)user, user_len, (text *)pass_old, pass_old_len, (text *)pass_new, pass_new_len, OCI_DEFAULT));
  2160. if (errstatus != OCI_SUCCESS) {
  2161. connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
  2162. PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
  2163. return 1;
  2164. }
  2165. connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
  2166. connection->passwd_changed = 1;
  2167. return 0;
  2168. }
  2169. /* }}} */
  2170. /* {{{ php_oci_client_get_version()
  2171. *
  2172. * Get Oracle client library version
  2173. */
  2174. void php_oci_client_get_version(char **version TSRMLS_DC)
  2175. {
  2176. char version_buff[256];
  2177. #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIClientVersion only available 10.2 onwards */
  2178. sword major_version = 0;
  2179. sword minor_version = 0;
  2180. sword update_num = 0;
  2181. sword patch_num = 0;
  2182. sword port_update_num = 0;
  2183. PHP_OCI_CALL(OCIClientVersion, (&major_version, &minor_version, &update_num, &patch_num, &port_update_num));
  2184. snprintf(version_buff, sizeof(version_buff), "%d.%d.%d.%d.%d", major_version, minor_version, update_num, patch_num, port_update_num);
  2185. #else
  2186. memcpy(version_buff, "Unknown", sizeof("Unknown"));
  2187. #endif
  2188. *version = estrdup(version_buff);
  2189. }
  2190. /* }}} */
  2191. /* {{{ php_oci_server_get_version()
  2192. *
  2193. * Get Oracle server version
  2194. */
  2195. int php_oci_server_get_version(php_oci_connection *connection, char **version TSRMLS_DC)
  2196. {
  2197. sword errstatus;
  2198. char version_buff[256];
  2199. PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX));
  2200. if (errstatus != OCI_SUCCESS) {
  2201. connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
  2202. PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
  2203. return 1;
  2204. }
  2205. *version = estrdup(version_buff);
  2206. return 0;
  2207. }
  2208. /* }}} */
  2209. /* {{{ php_oci_column_to_zval()
  2210. *
  2211. * Convert php_oci_out_column struct into zval
  2212. */
  2213. int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode TSRMLS_DC)
  2214. {
  2215. php_oci_descriptor *descriptor;
  2216. ub4 lob_length;
  2217. int column_size;
  2218. char *lob_buffer;
  2219. int lob_fetch_status;
  2220. if (column->indicator == -1) { /* column is NULL */
  2221. ZVAL_NULL(value);
  2222. return 0;
  2223. }
  2224. if (column->is_cursor) { /* REFCURSOR -> simply return the statement id */
  2225. ZVAL_RESOURCE(value, column->stmtid);
  2226. zend_list_addref(column->stmtid);
  2227. } else if (column->is_descr) {
  2228. if (column->data_type != SQLT_RDD) {
  2229. int rsrc_type;
  2230. /* reset descriptor's length */
  2231. descriptor = (php_oci_descriptor *) zend_list_find(column->descid, &rsrc_type);
  2232. if (!descriptor || rsrc_type != le_descriptor) {
  2233. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find LOB descriptor #%d", column->descid);
  2234. return 1;
  2235. }
  2236. descriptor->lob_size = -1;
  2237. descriptor->lob_current_position = 0;
  2238. descriptor->buffering = 0;
  2239. }
  2240. if (column->data_type != SQLT_RDD && (mode & PHP_OCI_RETURN_LOBS)) {
  2241. /* PHP_OCI_RETURN_LOBS means that we want the content of the LOB back instead of the locator */
  2242. if (column->chunk_size)
  2243. descriptor->chunk_size = column->chunk_size;
  2244. lob_fetch_status = php_oci_lob_read(descriptor, -1, 0, &lob_buffer, &lob_length TSRMLS_CC);
  2245. if (descriptor->chunk_size) /* Cache the chunk_size to avoid recalling OCILobGetChunkSize */
  2246. column->chunk_size = descriptor->chunk_size;
  2247. php_oci_temp_lob_close(descriptor TSRMLS_CC);
  2248. if (lob_fetch_status) {
  2249. ZVAL_FALSE(value);
  2250. return 1;
  2251. } else {
  2252. if (lob_length > 0) {
  2253. ZVAL_STRINGL(value, lob_buffer, lob_length, 0);
  2254. } else {
  2255. ZVAL_EMPTY_STRING(value);
  2256. }
  2257. return 0;
  2258. }
  2259. } else {
  2260. /* return the locator */
  2261. object_init_ex(value, oci_lob_class_entry_ptr);
  2262. add_property_resource(value, "descriptor", column->descid);
  2263. zend_list_addref(column->descid);
  2264. }
  2265. } else {
  2266. switch (column->retcode) {
  2267. case 0:
  2268. /* intact value */
  2269. if (column->piecewise) {
  2270. column_size = column->retlen4;
  2271. } else {
  2272. column_size = column->retlen;
  2273. }
  2274. break;
  2275. default:
  2276. ZVAL_FALSE(value);
  2277. return 0;
  2278. }
  2279. ZVAL_STRINGL(value, column->data, column_size, 1);
  2280. }
  2281. return 0;
  2282. }
  2283. /* }}} */
  2284. /* {{{ php_oci_fetch_row()
  2285. *
  2286. * Fetch the next row from the given statement
  2287. * Has logic for Oracle 12c Implicit Result Sets
  2288. */
  2289. void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args)
  2290. {
  2291. zval *z_statement, *array;
  2292. php_oci_statement *statement; /* statement that will be fetched from */
  2293. #if (OCI_MAJOR_VERSION >= 12)
  2294. php_oci_statement *invokedstatement; /* statement this function was invoked with */
  2295. #endif /* OCI_MAJOR_VERSION */
  2296. php_oci_out_column *column;
  2297. ub4 nrows = 1;
  2298. int i;
  2299. long fetch_mode = 0;
  2300. if (expected_args > 2) {
  2301. /* only for ocifetchinto BC */
  2302. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|l", &z_statement, &array, &fetch_mode) == FAILURE) {
  2303. return;
  2304. }
  2305. if (ZEND_NUM_ARGS() == 2) {
  2306. fetch_mode = mode;
  2307. }
  2308. } else if (expected_args == 2) {
  2309. /* only for oci_fetch_array() */
  2310. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_statement, &fetch_mode) == FAILURE) {
  2311. return;
  2312. }
  2313. if (ZEND_NUM_ARGS() == 1) {
  2314. fetch_mode = mode;
  2315. }
  2316. } else {
  2317. /* for all oci_fetch_*() */
  2318. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
  2319. return;
  2320. }
  2321. fetch_mode = mode;
  2322. }
  2323. if (!(fetch_mode & PHP_OCI_NUM) && !(fetch_mode & PHP_OCI_ASSOC)) {
  2324. /* none of the modes present, use the default one */
  2325. if (mode & PHP_OCI_ASSOC) {
  2326. fetch_mode |= PHP_OCI_ASSOC;
  2327. }
  2328. if (mode & PHP_OCI_NUM) {
  2329. fetch_mode |= PHP_OCI_NUM;
  2330. }
  2331. }
  2332. #if (OCI_MAJOR_VERSION < 12)
  2333. PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
  2334. if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
  2335. RETURN_FALSE; /* end of fetch */
  2336. }
  2337. #else /* OCI_MAJOR_VERSION */
  2338. PHP_OCI_ZVAL_TO_STATEMENT(z_statement, invokedstatement);
  2339. if (invokedstatement->impres_flag == PHP_OCI_IMPRES_NO_CHILDREN ||
  2340. invokedstatement->impres_flag == PHP_OCI_IMPRES_IS_CHILD) {
  2341. /* Already know there are no Implicit Result Sets */
  2342. statement = invokedstatement;
  2343. } else if (invokedstatement->impres_flag == PHP_OCI_IMPRES_HAS_CHILDREN) {
  2344. /* Previously saw an Implicit Result Set in an earlier invocation of php_oci_fetch_row */
  2345. statement = (php_oci_statement *)invokedstatement->impres_child_stmt;
  2346. } else {
  2347. sword errstatus;
  2348. /* Check for an Implicit Result Set on this statement handle */
  2349. PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)invokedstatement->stmt, OCI_HTYPE_STMT,
  2350. (dvoid *) &invokedstatement->impres_count,
  2351. (ub4 *)NULL, OCI_ATTR_IMPLICIT_RESULT_COUNT, invokedstatement->err));
  2352. if (errstatus) {
  2353. RETURN_FALSE;
  2354. }
  2355. if (invokedstatement->impres_count > 0) {
  2356. /* Make it so the fetch occurs on the first Implicit Result Set */
  2357. statement = php_oci_get_implicit_resultset(invokedstatement TSRMLS_CC);
  2358. if (!statement || php_oci_statement_execute(statement, (ub4)OCI_DEFAULT TSRMLS_CC))
  2359. RETURN_FALSE;
  2360. invokedstatement->impres_count--;
  2361. invokedstatement->impres_child_stmt = (struct php_oci_statement *)statement;
  2362. invokedstatement->impres_flag = PHP_OCI_IMPRES_HAS_CHILDREN;
  2363. } else {
  2364. statement = invokedstatement; /* didn't find Implicit Result Sets */
  2365. invokedstatement->impres_flag = PHP_OCI_IMPRES_NO_CHILDREN; /* Don't bother checking again */
  2366. }
  2367. }
  2368. if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
  2369. /* End of fetch */
  2370. if (invokedstatement->impres_count > 0) {
  2371. /* Check next Implicit Result Set */
  2372. statement = php_oci_get_implicit_resultset(invokedstatement TSRMLS_CC);
  2373. if (!statement || php_oci_statement_execute(statement, (ub4)OCI_DEFAULT TSRMLS_CC))
  2374. RETURN_FALSE;
  2375. invokedstatement->impres_count--;
  2376. invokedstatement->impres_child_stmt = (struct php_oci_statement *)statement;
  2377. if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
  2378. /* End of all fetches */
  2379. RETURN_FALSE;
  2380. }
  2381. } else {
  2382. RETURN_FALSE;
  2383. }
  2384. }
  2385. #endif /* OCI_MAJOR_VERSION */
  2386. array_init(return_value);
  2387. for (i = 0; i < statement->ncolumns; i++) {
  2388. column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
  2389. if (column == NULL) {
  2390. continue;
  2391. }
  2392. if ((column->indicator == -1) && ((fetch_mode & PHP_OCI_RETURN_NULLS) == 0)) {
  2393. continue;
  2394. }
  2395. if (!(column->indicator == -1)) {
  2396. zval *element;
  2397. MAKE_STD_ZVAL(element);
  2398. php_oci_column_to_zval(column, element, fetch_mode TSRMLS_CC);
  2399. if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
  2400. add_index_zval(return_value, i, element);
  2401. }
  2402. if (fetch_mode & PHP_OCI_ASSOC) {
  2403. if (fetch_mode & PHP_OCI_NUM) {
  2404. Z_ADDREF_P(element);
  2405. }
  2406. add_assoc_zval(return_value, column->name, element);
  2407. }
  2408. } else {
  2409. if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
  2410. add_index_null(return_value, i);
  2411. }
  2412. if (fetch_mode & PHP_OCI_ASSOC) {
  2413. add_assoc_null(return_value, column->name);
  2414. }
  2415. }
  2416. }
  2417. if (expected_args > 2) {
  2418. /* Only for ocifetchinto BC. In all other cases we return array, not long */
  2419. REPLACE_ZVAL_VALUE(&array, return_value, 1); /* copy return_value to given reference */
  2420. zval_dtor(return_value);
  2421. RETURN_LONG(statement->ncolumns);
  2422. }
  2423. }
  2424. /* }}} */
  2425. /* {{{ php_oci_persistent_helper()
  2426. *
  2427. * Helper function to close/rollback persistent connections at the end of request. A return value of
  2428. * 1 indicates that the connection is to be destroyed
  2429. */
  2430. static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
  2431. {
  2432. time_t timestamp;
  2433. php_oci_connection *connection;
  2434. timestamp = time(NULL);
  2435. /* Persistent connection stubs are also counted as they have private session pools */
  2436. if (le->type == le_pconnection) {
  2437. connection = (php_oci_connection *)le->ptr;
  2438. if (!connection->used_this_request && OCI_G(persistent_timeout) != -1) {
  2439. #ifdef HAVE_OCI8_DTRACE
  2440. if (DTRACE_OCI8_CONNECT_EXPIRY_ENABLED()) {
  2441. DTRACE_OCI8_CONNECT_EXPIRY(connection, connection->is_stub ? 1 : 0, (long)connection->idle_expiry, (long)timestamp);
  2442. }
  2443. #endif /* HAVE_OCI8_DTRACE */
  2444. if (connection->idle_expiry < timestamp) {
  2445. /* connection has timed out */
  2446. return ZEND_HASH_APPLY_REMOVE;
  2447. }
  2448. }
  2449. }
  2450. return ZEND_HASH_APPLY_KEEP;
  2451. }
  2452. /* }}} */
  2453. /* {{{ php_oci_create_spool()
  2454. *
  2455. * Create(alloc + Init) Session pool for the given dbname and charsetid
  2456. */
  2457. static php_oci_spool *php_oci_create_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, char *hash_key, int hash_key_len, int charsetid TSRMLS_DC)
  2458. {
  2459. php_oci_spool *session_pool = NULL;
  2460. zend_bool iserror = 0;
  2461. ub4 poolmode = OCI_DEFAULT; /* Mode to be passed to OCISessionPoolCreate */
  2462. OCIAuthInfo *spoolAuth = NULL;
  2463. sword errstatus;
  2464. /* Allocate sessionpool out of persistent memory */
  2465. session_pool = (php_oci_spool *) calloc(1, sizeof(php_oci_spool));
  2466. if (session_pool == NULL) {
  2467. iserror = 1;
  2468. goto exit_create_spool;
  2469. }
  2470. /* Populate key if passed */
  2471. if (hash_key_len) {
  2472. session_pool->spool_hash_key = zend_strndup(hash_key, hash_key_len);
  2473. if (session_pool->spool_hash_key == NULL) {
  2474. iserror = 1;
  2475. goto exit_create_spool;
  2476. }
  2477. }
  2478. /* Create the session pool's env */
  2479. if (!(session_pool->env = php_oci_create_env(charsetid TSRMLS_CC))) {
  2480. iserror = 1;
  2481. goto exit_create_spool;
  2482. }
  2483. /* Allocate the pool handle */
  2484. PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (session_pool->env, (dvoid **) &session_pool->poolh, OCI_HTYPE_SPOOL, (size_t) 0, (dvoid **) 0));
  2485. if (errstatus != OCI_SUCCESS) {
  2486. OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
  2487. iserror = 1;
  2488. goto exit_create_spool;
  2489. }
  2490. /* Allocate the session pool error handle - This only for use in the destructor, as there is a
  2491. * generic bug which can free up the OCI_G(err) variable before destroying connections. We
  2492. * cannot use this for other roundtrip calls as there is no way the user can access this error
  2493. */
  2494. PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, ((dvoid *) session_pool->env, (dvoid **)&(session_pool->err), (ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0));
  2495. if (errstatus != OCI_SUCCESS) {
  2496. OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
  2497. iserror = 1;
  2498. goto exit_create_spool;
  2499. }
  2500. /* Disable RLB as we mostly have single-connection pools */
  2501. #if (OCI_MAJOR_VERSION > 10)
  2502. poolmode = OCI_SPC_NO_RLB | OCI_SPC_HOMOGENEOUS;
  2503. #else
  2504. poolmode = OCI_SPC_HOMOGENEOUS;
  2505. #endif
  2506. #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2)))
  2507. /* {{{ Allocate auth handle for session pool */
  2508. PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (session_pool->env, (dvoid **)&(spoolAuth), OCI_HTYPE_AUTHINFO, 0, NULL));
  2509. if (errstatus != OCI_SUCCESS) {
  2510. OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
  2511. iserror = 1;
  2512. goto exit_create_spool;
  2513. }
  2514. /* }}} */
  2515. /* {{{ Set the edition attribute on the auth handle */
  2516. if (OCI_G(edition)) {
  2517. PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) OCI_G(edition), (ub4)(strlen(OCI_G(edition))), (ub4)OCI_ATTR_EDITION, OCI_G(err)));
  2518. if (errstatus != OCI_SUCCESS) {
  2519. OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
  2520. iserror = 1;
  2521. goto exit_create_spool;
  2522. }
  2523. }
  2524. /* }}} */
  2525. /* {{{ Set the driver name attribute on the auth handle */
  2526. PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err)));
  2527. if (errstatus != OCI_SUCCESS) {
  2528. OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
  2529. iserror = 1;
  2530. goto exit_create_spool;
  2531. }
  2532. /* }}} */
  2533. /* {{{ Set the auth handle on the session pool */
  2534. PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) (session_pool->poolh),(ub4) OCI_HTYPE_SPOOL, (dvoid *) spoolAuth, (ub4)0, (ub4)OCI_ATTR_SPOOL_AUTH, OCI_G(err)));
  2535. if (errstatus != OCI_SUCCESS) {
  2536. OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
  2537. iserror = 1;
  2538. goto exit_create_spool;
  2539. }
  2540. /* }}} */
  2541. #endif
  2542. /* Create the homogeneous session pool - We have different session pools for every different
  2543. * username, password, charset and dbname.
  2544. */
  2545. PHP_OCI_CALL_RETURN(errstatus, OCISessionPoolCreate,(session_pool->env, OCI_G(err), session_pool->poolh, (OraText **)&session_pool->poolname, &session_pool->poolname_len, (OraText *)dbname, (ub4)dbname_len, 0, UB4MAXVAL, 1,(OraText *)username, (ub4)username_len, (OraText *)password,(ub4)password_len, poolmode));
  2546. if (errstatus != OCI_SUCCESS) {
  2547. OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
  2548. iserror = 1;
  2549. }
  2550. exit_create_spool:
  2551. if (iserror && session_pool) {
  2552. php_oci_spool_close(session_pool TSRMLS_CC);
  2553. session_pool = NULL;
  2554. }
  2555. if (spoolAuth) {
  2556. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO));
  2557. }
  2558. #ifdef HAVE_OCI8_DTRACE
  2559. if (DTRACE_OCI8_SESSPOOL_CREATE_ENABLED()) {
  2560. DTRACE_OCI8_SESSPOOL_CREATE(session_pool);
  2561. }
  2562. #endif /* HAVE_OCI8_DTRACE */
  2563. return session_pool;
  2564. }
  2565. /* }}} */
  2566. /* {{{ php_oci_get_spool()
  2567. *
  2568. * Get Session pool for the given dbname and charsetid from the persistent list. Function called for
  2569. * non-persistent connections.
  2570. */
  2571. static php_oci_spool *php_oci_get_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, int charsetid TSRMLS_DC)
  2572. {
  2573. smart_str spool_hashed_details = {0};
  2574. php_oci_spool *session_pool = NULL;
  2575. zend_rsrc_list_entry spool_le = {0};
  2576. zend_rsrc_list_entry *spool_out_le = NULL;
  2577. zend_bool iserror = 0;
  2578. /* {{{ Create the spool hash key */
  2579. smart_str_appendl_ex(&spool_hashed_details, "oci8spool***", sizeof("oci8spool***") - 1, 0);
  2580. smart_str_appendl_ex(&spool_hashed_details, username, username_len, 0);
  2581. smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
  2582. /* Add edition attribute to the hash */
  2583. if (OCI_G(edition)){
  2584. smart_str_appendl_ex(&spool_hashed_details, OCI_G(edition), strlen(OCI_G(edition)), 0);
  2585. }
  2586. smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
  2587. if (password_len) {
  2588. ulong password_hash;
  2589. password_hash = zend_inline_hash_func(password, password_len);
  2590. smart_str_append_unsigned_ex(&spool_hashed_details, password_hash, 0);
  2591. }
  2592. smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
  2593. if (dbname_len) {
  2594. smart_str_appendl_ex(&spool_hashed_details, dbname, dbname_len, 0);
  2595. }
  2596. smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
  2597. smart_str_append_unsigned_ex(&spool_hashed_details, charsetid, 0);
  2598. /* Session Pool Hash Key : oci8spool***username**edition**hashedpassword**dbname**charset */
  2599. smart_str_0(&spool_hashed_details);
  2600. php_strtolower(spool_hashed_details.c, spool_hashed_details.len);
  2601. /* }}} */
  2602. if (zend_hash_find(&EG(persistent_list),spool_hashed_details.c, spool_hashed_details.len+1, (void **)&spool_out_le) == FAILURE) {
  2603. session_pool = php_oci_create_spool(username, username_len, password, password_len, dbname, dbname_len, spool_hashed_details.c, spool_hashed_details.len, charsetid TSRMLS_CC);
  2604. if (session_pool == NULL) {
  2605. iserror = 1;
  2606. goto exit_get_spool;
  2607. }
  2608. spool_le.ptr = session_pool;
  2609. spool_le.type = le_psessionpool;
  2610. PHP_OCI_REGISTER_RESOURCE(session_pool, le_psessionpool);
  2611. zend_hash_update(&EG(persistent_list), session_pool->spool_hash_key, strlen(session_pool->spool_hash_key)+1,(void *)&spool_le, sizeof(zend_rsrc_list_entry),NULL);
  2612. } else if (spool_out_le->type == le_psessionpool &&
  2613. strlen(((php_oci_spool *)(spool_out_le->ptr))->spool_hash_key) == spool_hashed_details.len &&
  2614. memcmp(((php_oci_spool *)(spool_out_le->ptr))->spool_hash_key, spool_hashed_details.c, spool_hashed_details.len) == 0) {
  2615. /* retrieve the cached session pool */
  2616. session_pool = (php_oci_spool *)(spool_out_le->ptr);
  2617. }
  2618. exit_get_spool:
  2619. smart_str_free_ex(&spool_hashed_details, 0);
  2620. if (iserror && session_pool) {
  2621. php_oci_spool_close(session_pool TSRMLS_CC);
  2622. session_pool = NULL;
  2623. }
  2624. return session_pool;
  2625. }
  2626. /* }}} */
  2627. /* {{{ php_oci_create_env()
  2628. *
  2629. * Create the OCI environment choosing the correct function for the OCI version
  2630. */
  2631. static OCIEnv *php_oci_create_env(ub2 charsetid TSRMLS_DC)
  2632. {
  2633. OCIEnv *retenv = NULL;
  2634. /* create an environment using the character set id */
  2635. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIEnvNlsCreate, (&retenv, OCI_G(events) ? PHP_OCI_INIT_MODE | OCI_EVENTS : PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, charsetid, charsetid));
  2636. if (OCI_G(errcode) != OCI_SUCCESS) {
  2637. sb4 ora_error_code = 0;
  2638. text ora_msg_buf[OCI_ERROR_MAXMSG_SIZE]; /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */
  2639. #ifdef HAVE_OCI_INSTANT_CLIENT
  2640. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that " PHP_OCI8_LIB_PATH_MSG " includes the directory with Oracle Instant Client libraries");
  2641. #else
  2642. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories");
  2643. #endif
  2644. if (retenv
  2645. && OCIErrorGet(retenv, (ub4)1, NULL, &ora_error_code, ora_msg_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS
  2646. && *ora_msg_buf) {
  2647. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ora_msg_buf);
  2648. }
  2649. return NULL;
  2650. }
  2651. return retenv;
  2652. }
  2653. /* }}} */
  2654. /* {{{ php_oci_old_create_session()
  2655. *
  2656. * This function is to be deprecated in future in favour of OCISessionGet which is used in
  2657. * php_oci_do_connect_ex
  2658. */
  2659. static int php_oci_old_create_session(php_oci_connection *connection, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC)
  2660. {
  2661. ub4 statement_cache_size = (OCI_G(statement_cache_size) > 0) ? OCI_G(statement_cache_size) : 0;
  2662. /* Create the OCI environment separate for each connection */
  2663. if (!(connection->env = php_oci_create_env(connection->charset TSRMLS_CC))) {
  2664. return 1;
  2665. }
  2666. /* {{{ Allocate our server handle */
  2667. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->server), OCI_HTYPE_SERVER, 0, NULL));
  2668. if (OCI_G(errcode) != OCI_SUCCESS) {
  2669. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2670. return 1;
  2671. }
  2672. /* }}} */
  2673. /* {{{ Attach to the server */
  2674. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerAttach, (connection->server, OCI_G(err), (text *)dbname, dbname_len, (ub4) OCI_DEFAULT));
  2675. if (OCI_G(errcode) != OCI_SUCCESS) {
  2676. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2677. return 1;
  2678. }
  2679. /* }}} */
  2680. connection->is_attached = 1;
  2681. /* {{{ Allocate our session handle */
  2682. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->session), OCI_HTYPE_SESSION, 0, NULL));
  2683. if (OCI_G(errcode) != OCI_SUCCESS) {
  2684. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2685. return 1;
  2686. }
  2687. /* }}} */
  2688. /* {{{ Allocate our private error-handle */
  2689. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->err), OCI_HTYPE_ERROR, 0, NULL));
  2690. if (OCI_G(errcode) != OCI_SUCCESS) {
  2691. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2692. return 1;
  2693. }
  2694. /* }}} */
  2695. /* {{{ Allocate our service-context */
  2696. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->svc), OCI_HTYPE_SVCCTX, 0, NULL));
  2697. if (OCI_G(errcode) != OCI_SUCCESS) {
  2698. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2699. return 1;
  2700. }
  2701. /* }}} */
  2702. /* {{{ Set the username */
  2703. if (username) {
  2704. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) username, (ub4) username_len, (ub4) OCI_ATTR_USERNAME, OCI_G(err)));
  2705. if (OCI_G(errcode) != OCI_SUCCESS) {
  2706. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2707. return 1;
  2708. }
  2709. }
  2710. /* }}} */
  2711. /* {{{ Set the password */
  2712. if (password) {
  2713. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) password, (ub4) password_len, (ub4) OCI_ATTR_PASSWORD, OCI_G(err)));
  2714. if (OCI_G(errcode) != OCI_SUCCESS) {
  2715. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2716. return 1;
  2717. }
  2718. }
  2719. /* }}} */
  2720. /* {{{ Set the edition attribute on the session handle */
  2721. #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2)))
  2722. if (OCI_G(edition)) {
  2723. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(edition), (ub4) (strlen(OCI_G(edition))), (ub4) OCI_ATTR_EDITION, OCI_G(err)));
  2724. if (OCI_G(errcode) != OCI_SUCCESS) {
  2725. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2726. return 1;
  2727. }
  2728. }
  2729. #endif
  2730. /* }}} */
  2731. /* {{{ Set the driver name attribute on the session handle */
  2732. #if (OCI_MAJOR_VERSION >= 11)
  2733. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err)));
  2734. if (OCI_G(errcode) != OCI_SUCCESS) {
  2735. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2736. return 1;
  2737. }
  2738. #endif
  2739. /* }}} */
  2740. /* {{{ Set the server handle in the service handle */
  2741. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->server, 0, OCI_ATTR_SERVER, OCI_G(err)));
  2742. if (OCI_G(errcode) != OCI_SUCCESS) {
  2743. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2744. return 1;
  2745. }
  2746. /* }}} */
  2747. /* {{{ Set the authentication handle in the service handle */
  2748. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->session, 0, OCI_ATTR_SESSION, OCI_G(err)));
  2749. if (OCI_G(errcode) != OCI_SUCCESS) {
  2750. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2751. return 1;
  2752. }
  2753. /* }}} */
  2754. if (new_password) {
  2755. /* {{{ Try to change password if new one was provided */
  2756. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIPasswordChange, (connection->svc, OCI_G(err), (text *)username, username_len, (text *)password, password_len, (text *)new_password, new_password_len, OCI_AUTH));
  2757. if (OCI_G(errcode) != OCI_SUCCESS) {
  2758. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2759. return 1;
  2760. }
  2761. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->session), (ub4 *)0, OCI_ATTR_SESSION, OCI_G(err)));
  2762. if (OCI_G(errcode) != OCI_SUCCESS) {
  2763. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2764. return 1;
  2765. }
  2766. /* }}} */
  2767. } else {
  2768. /* {{{ start the session */
  2769. ub4 cred_type = OCI_CRED_RDBMS;
  2770. /* Extract the overloaded session_mode parameter into valid Oracle credential and session mode values */
  2771. if (session_mode & PHP_OCI_CRED_EXT) {
  2772. cred_type = OCI_CRED_EXT;
  2773. session_mode ^= PHP_OCI_CRED_EXT;
  2774. }
  2775. session_mode |= OCI_STMT_CACHE;
  2776. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) cred_type, (ub4) session_mode));
  2777. if (OCI_G(errcode) != OCI_SUCCESS) {
  2778. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2779. /* OCISessionBegin returns OCI_SUCCESS_WITH_INFO when
  2780. * user's password has expired, but is still usable.
  2781. */
  2782. if (OCI_G(errcode) != OCI_SUCCESS_WITH_INFO) {
  2783. return 1;
  2784. }
  2785. }
  2786. /* }}} */
  2787. }
  2788. /* Brand new connection: Init and update the next_ping in the connection */
  2789. if (php_oci_ping_init(connection, OCI_G(err) TSRMLS_CC) != OCI_SUCCESS) {
  2790. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2791. return 1;
  2792. }
  2793. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX, (ub4 *) &statement_cache_size, 0, (ub4) OCI_ATTR_STMTCACHESIZE, OCI_G(err)));
  2794. if (OCI_G(errcode) != OCI_SUCCESS) {
  2795. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2796. return 1;
  2797. }
  2798. /* Successfully created session */
  2799. return 0;
  2800. }
  2801. /* }}} */
  2802. /* {{{ php_oci_create_session()
  2803. *
  2804. * Create session using client-side session pool - new norm
  2805. */
  2806. static int php_oci_create_session(php_oci_connection *connection, php_oci_spool *session_pool, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC)
  2807. {
  2808. php_oci_spool *actual_spool = NULL;
  2809. #if (OCI_MAJOR_VERSION > 10)
  2810. ub4 purity = -2; /* Illegal value to initialize */
  2811. #endif
  2812. time_t timestamp = time(NULL);
  2813. ub4 statement_cache_size = (OCI_G(statement_cache_size) > 0) ? OCI_G(statement_cache_size) : 0;
  2814. /* Persistent connections have private session pools */
  2815. if (connection->is_persistent && !connection->private_spool &&
  2816. !(connection->private_spool = php_oci_create_spool(username, username_len, password, password_len, dbname, dbname_len, NULL, 0, connection->charset TSRMLS_CC))) {
  2817. return 1;
  2818. }
  2819. actual_spool = (connection->is_persistent) ? (connection->private_spool) : (session_pool);
  2820. connection->env = actual_spool->env;
  2821. /* Do this upfront so that connection close on an error would know that this is a session pool
  2822. * connection. Failure to do this would result in crashes in error scenarios
  2823. */
  2824. if (!connection->using_spool) {
  2825. connection->using_spool = 1;
  2826. }
  2827. #ifdef HAVE_OCI8_DTRACE
  2828. if (DTRACE_OCI8_SESSPOOL_TYPE_ENABLED()) {
  2829. DTRACE_OCI8_SESSPOOL_TYPE(session_pool ? 1 : 0, session_pool ? session_pool : connection->private_spool);
  2830. }
  2831. #endif /* HAVE_OCI8_DTRACE */
  2832. /* The passed in "connection" can be a cached stub from plist or freshly created. In the former
  2833. * case, we do not have to allocate any handles
  2834. */
  2835. if (!connection->err) {
  2836. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->err), OCI_HTYPE_ERROR, 0, NULL));
  2837. if (OCI_G(errcode) != OCI_SUCCESS) {
  2838. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2839. return 1;
  2840. }
  2841. }
  2842. /* {{{ Allocate and initialize the connection-private authinfo handle if not allocated yet */
  2843. if (!connection->authinfo) {
  2844. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->authinfo), OCI_HTYPE_AUTHINFO, 0, NULL));
  2845. if (OCI_G(errcode) != OCI_SUCCESS) {
  2846. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2847. return 1;
  2848. }
  2849. /* Set the Connection class and purity if OCI client version >= 11g */
  2850. #if (OCI_MAJOR_VERSION > 10)
  2851. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->authinfo,(ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(connection_class), (ub4)(strlen(OCI_G(connection_class))), (ub4)OCI_ATTR_CONNECTION_CLASS, OCI_G(err)));
  2852. if (OCI_G(errcode) != OCI_SUCCESS) {
  2853. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2854. return 1;
  2855. }
  2856. if (connection->is_persistent)
  2857. purity = OCI_ATTR_PURITY_SELF;
  2858. else
  2859. purity = OCI_ATTR_PURITY_NEW;
  2860. PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) connection->authinfo,(ub4) OCI_HTYPE_AUTHINFO, (dvoid *) &purity, (ub4)0, (ub4)OCI_ATTR_PURITY, OCI_G(err)));
  2861. if (OCI_G(errcode) != OCI_SUCCESS) {
  2862. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2863. return 1;
  2864. }
  2865. #endif
  2866. }
  2867. /* }}} */
  2868. /* {{{ Debug statements */
  2869. #ifdef HAVE_OCI8_DTRACE
  2870. if (DTRACE_OCI8_SESSPOOL_STATS_ENABLED()) {
  2871. ub4 numfree = 0, numbusy = 0, numopen = 0;
  2872. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numopen, (ub4 *)0, OCI_ATTR_SPOOL_OPEN_COUNT, OCI_G(err)));
  2873. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numbusy, (ub4 *)0, OCI_ATTR_SPOOL_BUSY_COUNT, OCI_G(err)));
  2874. numfree = numopen - numbusy; /* number of free connections in the pool */
  2875. DTRACE_OCI8_SESSPOOL_STATS(numfree, numbusy, numopen);
  2876. }
  2877. #endif /* HAVE_OCI8_DTRACE */
  2878. /* }}} */
  2879. /* Ping loop: Ping and loop till we get a good connection. When a database instance goes
  2880. * down, it can leave several bad connections that need to be flushed out before getting a
  2881. * good one. In non-RAC, we always get a brand new connection at the end of the loop and in
  2882. * RAC, we can get a good connection from a different instance before flushing out all bad
  2883. * ones. We do not need to ping brand new connections.
  2884. */
  2885. do {
  2886. /* Continue to use the global error handle as the connection is closed when an error occurs */
  2887. PHP_OCI_CALL_RETURN(OCI_G(errcode),OCISessionGet, (connection->env, OCI_G(err), &(connection->svc), (OCIAuthInfo *)connection->authinfo, (OraText *)actual_spool->poolname, (ub4)actual_spool->poolname_len, NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL));
  2888. if (OCI_G(errcode) != OCI_SUCCESS) {
  2889. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2890. /* Session creation returns OCI_SUCCESS_WITH_INFO when user's password has expired, but
  2891. * is still usable.
  2892. */
  2893. if (OCI_G(errcode) != OCI_SUCCESS_WITH_INFO) {
  2894. return 1;
  2895. }
  2896. }
  2897. /* {{{ Populate the session and server fields of the connection */
  2898. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->server), (ub4 *)0, OCI_ATTR_SERVER, OCI_G(err)));
  2899. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->session), (ub4 *)0, OCI_ATTR_SESSION, OCI_G(err)));
  2900. /* }}} */
  2901. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIContextGetValue, (connection->session, OCI_G(err), (ub1 *)"NEXT_PING", (ub1)sizeof("NEXT_PING"), (void **)&(connection->next_pingp)));
  2902. if (OCI_G(errcode) != OCI_SUCCESS) {
  2903. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2904. return 1;
  2905. }
  2906. if (!(connection->next_pingp)){
  2907. /* This is a brand new connection, we need not ping, but have to initialize ping */
  2908. if (php_oci_ping_init(connection, OCI_G(err) TSRMLS_CC) != OCI_SUCCESS) {
  2909. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2910. return 1;
  2911. }
  2912. } else if ((*(connection->next_pingp) > 0) && (timestamp >= *(connection->next_pingp))) {
  2913. if (php_oci_connection_ping(connection TSRMLS_CC)) {
  2914. /* Got a good connection - update next_ping and get out of ping loop */
  2915. *(connection->next_pingp) = timestamp + OCI_G(ping_interval);
  2916. } else {
  2917. /* Bad connection - remove from pool */
  2918. PHP_OCI_CALL(OCISessionRelease, (connection->svc, connection->err, NULL,0, (ub4) OCI_SESSRLS_DROPSESS));
  2919. connection->svc = NULL;
  2920. connection->server = NULL;
  2921. connection->session = NULL;
  2922. }
  2923. } /* If ping applicable */
  2924. } while (!(connection->svc));
  2925. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX, (ub4 *) &statement_cache_size, 0, (ub4) OCI_ATTR_STMTCACHESIZE, OCI_G(err)));
  2926. if (OCI_G(errcode) != OCI_SUCCESS) {
  2927. php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
  2928. return 1;
  2929. }
  2930. /* Session is now taken from the session pool and attached and open */
  2931. connection->is_stub = 0;
  2932. connection->is_attached = connection->is_open = 1;
  2933. return 0;
  2934. }
  2935. /* }}} */
  2936. /* {{{ php_oci_spool_list_dtor()
  2937. *
  2938. * Session pool destructor function
  2939. */
  2940. static void php_oci_spool_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
  2941. {
  2942. php_oci_spool *session_pool = (php_oci_spool *)entry->ptr;
  2943. if (session_pool) {
  2944. php_oci_spool_close(session_pool TSRMLS_CC);
  2945. }
  2946. return;
  2947. }
  2948. /* }}} */
  2949. /* {{{ php_oci_spool_close()
  2950. *
  2951. * Destroys the OCI Session Pool
  2952. */
  2953. static void php_oci_spool_close(php_oci_spool *session_pool TSRMLS_DC)
  2954. {
  2955. if (session_pool->poolname_len) {
  2956. PHP_OCI_CALL(OCISessionPoolDestroy, ((dvoid *) session_pool->poolh,
  2957. (dvoid *) session_pool->err, OCI_SPD_FORCE));
  2958. }
  2959. if (session_pool->poolh) {
  2960. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) session_pool->poolh, OCI_HTYPE_SPOOL));
  2961. }
  2962. if (session_pool->err) {
  2963. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) session_pool->err, OCI_HTYPE_ERROR));
  2964. }
  2965. if (session_pool->env) {
  2966. PHP_OCI_CALL(OCIHandleFree, ((dvoid *) session_pool->env, OCI_HTYPE_ENV));
  2967. }
  2968. if (session_pool->spool_hash_key) {
  2969. free(session_pool->spool_hash_key);
  2970. }
  2971. free(session_pool);
  2972. }
  2973. /* }}} */
  2974. /* {{{ php_oci_ping_init()
  2975. *
  2976. * Initializes the next_ping time as a context value in the connection. We now use
  2977. * OCIContext{Get,Set}Value to store the next_ping because we need to support ping for
  2978. * non-persistent DRCP connections
  2979. */
  2980. static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TSRMLS_DC)
  2981. {
  2982. time_t *next_pingp = NULL;
  2983. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIContextGetValue, (connection->session, errh, (ub1 *)"NEXT_PING", (ub1)sizeof("NEXT_PING"), (void **)&next_pingp));
  2984. if (OCI_G(errcode) != OCI_SUCCESS) {
  2985. return OCI_G(errcode);
  2986. }
  2987. /* This must be a brand-new connection. Allocate memory for the ping */
  2988. if (!next_pingp) {
  2989. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIMemoryAlloc, (connection->session, errh, (void **)&next_pingp, OCI_DURATION_SESSION, sizeof(time_t), OCI_MEMORY_CLEARED));
  2990. if (OCI_G(errcode) != OCI_SUCCESS) {
  2991. return OCI_G(errcode);
  2992. }
  2993. }
  2994. if (OCI_G(ping_interval) >= 0) {
  2995. time_t timestamp = time(NULL);
  2996. *next_pingp = timestamp + OCI_G(ping_interval);
  2997. } else {
  2998. *next_pingp = 0;
  2999. }
  3000. /* Set the new ping value into the connection */
  3001. PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIContextSetValue, (connection->session, errh, OCI_DURATION_SESSION, (ub1 *)"NEXT_PING", (ub1)sizeof("NEXT_PING"), next_pingp));
  3002. if (OCI_G(errcode) != OCI_SUCCESS) {
  3003. OCIMemoryFree(connection->session, errh, next_pingp);
  3004. return OCI_G(errcode);
  3005. }
  3006. /* Cache the pointer so we do not have to do OCIContextGetValue repeatedly */
  3007. connection->next_pingp = next_pingp;
  3008. return OCI_SUCCESS;
  3009. }
  3010. /* }}} */
  3011. /* {{{ php_oci_dtrace_check_connection()
  3012. *
  3013. * DTrace output for connections that may have become invalid and marked for reopening
  3014. */
  3015. void php_oci_dtrace_check_connection(php_oci_connection *connection, sb4 errcode, ub4 serverStatus)
  3016. {
  3017. #ifdef HAVE_OCI8_DTRACE
  3018. if (DTRACE_OCI8_CHECK_CONNECTION_ENABLED()) {
  3019. DTRACE_OCI8_CHECK_CONNECTION(connection, connection->client_id, connection->is_open ? 1 : 0, (long)errcode, (unsigned long)serverStatus);
  3020. }
  3021. #endif /* HAVE_OCI8_DTRACE */
  3022. }
  3023. /* }}} */
  3024. #endif /* HAVE_OCI8 */
  3025. /*
  3026. * Local variables:
  3027. * tab-width: 4
  3028. * c-basic-offset: 4
  3029. * End:
  3030. * vim600: noet sw=4 ts=4 fdm=marker
  3031. * vim<600: noet sw=4 ts=4
  3032. */