interbase.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480
  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: Jouni Ahto <jouni.ahto@exdec.fi> |
  16. | Andrew Avdeev <andy@rsc.mv.ru> |
  17. | Ard Biesheuvel <a.k.biesheuvel@ewi.tudelft.nl> |
  18. +----------------------------------------------------------------------+
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #define _GNU_SOURCE
  24. #include "php.h"
  25. #if HAVE_IBASE
  26. #include "php_ini.h"
  27. #include "ext/standard/php_standard.h"
  28. #include "ext/standard/md5.h"
  29. #include "php_interbase.h"
  30. #include "php_ibase_includes.h"
  31. #include "SAPI.h"
  32. #include <time.h>
  33. #define ROLLBACK 0
  34. #define COMMIT 1
  35. #define RETAIN 2
  36. #define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } }
  37. ZEND_DECLARE_MODULE_GLOBALS(ibase)
  38. static PHP_GINIT_FUNCTION(ibase);
  39. /* {{{ arginfo */
  40. ZEND_BEGIN_ARG_INFO(arginfo_ibase_errmsg, 0)
  41. ZEND_END_ARG_INFO()
  42. ZEND_BEGIN_ARG_INFO(arginfo_ibase_errcode, 0)
  43. ZEND_END_ARG_INFO()
  44. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_connect, 0, 0, 1)
  45. ZEND_ARG_INFO(0, database)
  46. ZEND_ARG_INFO(0, username)
  47. ZEND_ARG_INFO(0, password)
  48. ZEND_ARG_INFO(0, charset)
  49. ZEND_ARG_INFO(0, buffers)
  50. ZEND_ARG_INFO(0, dialect)
  51. ZEND_ARG_INFO(0, role)
  52. ZEND_END_ARG_INFO()
  53. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_pconnect, 0, 0, 1)
  54. ZEND_ARG_INFO(0, database)
  55. ZEND_ARG_INFO(0, username)
  56. ZEND_ARG_INFO(0, password)
  57. ZEND_ARG_INFO(0, charset)
  58. ZEND_ARG_INFO(0, buffers)
  59. ZEND_ARG_INFO(0, dialect)
  60. ZEND_ARG_INFO(0, role)
  61. ZEND_END_ARG_INFO()
  62. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_close, 0, 0, 0)
  63. ZEND_ARG_INFO(0, link_identifier)
  64. ZEND_END_ARG_INFO()
  65. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_drop_db, 0, 0, 0)
  66. ZEND_ARG_INFO(0, link_identifier)
  67. ZEND_END_ARG_INFO()
  68. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_trans, 0, 0, 0)
  69. ZEND_ARG_INFO(0, trans_args)
  70. ZEND_ARG_INFO(0, link_identifier)
  71. ZEND_ARG_INFO(0, trans_args)
  72. ZEND_ARG_INFO(0, link_identifier)
  73. ZEND_END_ARG_INFO()
  74. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_commit, 0, 0, 1)
  75. ZEND_ARG_INFO(0, link_identifier)
  76. ZEND_END_ARG_INFO()
  77. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_rollback, 0, 0, 1)
  78. ZEND_ARG_INFO(0, link_identifier)
  79. ZEND_END_ARG_INFO()
  80. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_commit_ret, 0, 0, 1)
  81. ZEND_ARG_INFO(0, link_identifier)
  82. ZEND_END_ARG_INFO()
  83. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_rollback_ret, 0, 0, 1)
  84. ZEND_ARG_INFO(0, link_identifier)
  85. ZEND_END_ARG_INFO()
  86. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_gen_id, 0, 0, 1)
  87. ZEND_ARG_INFO(0, generator)
  88. ZEND_ARG_INFO(0, increment)
  89. ZEND_ARG_INFO(0, link_identifier)
  90. ZEND_END_ARG_INFO()
  91. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_create, 0, 0, 0)
  92. ZEND_ARG_INFO(0, link_identifier)
  93. ZEND_END_ARG_INFO()
  94. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_open, 0, 0, 0)
  95. ZEND_ARG_INFO(0, link_identifier)
  96. ZEND_ARG_INFO(0, blob_id)
  97. ZEND_END_ARG_INFO()
  98. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_add, 0, 0, 2)
  99. ZEND_ARG_INFO(0, blob_handle)
  100. ZEND_ARG_INFO(0, data)
  101. ZEND_END_ARG_INFO()
  102. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_get, 0, 0, 2)
  103. ZEND_ARG_INFO(0, blob_handle)
  104. ZEND_ARG_INFO(0, len)
  105. ZEND_END_ARG_INFO()
  106. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_close, 0, 0, 1)
  107. ZEND_ARG_INFO(0, blob_handle)
  108. ZEND_END_ARG_INFO()
  109. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_cancel, 0, 0, 1)
  110. ZEND_ARG_INFO(0, blob_handle)
  111. ZEND_END_ARG_INFO()
  112. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_info, 0, 0, 0)
  113. ZEND_ARG_INFO(0, link_identifier)
  114. ZEND_ARG_INFO(0, blob_id)
  115. ZEND_END_ARG_INFO()
  116. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_echo, 0, 0, 0)
  117. ZEND_ARG_INFO(0, link_identifier)
  118. ZEND_ARG_INFO(0, blob_id)
  119. ZEND_END_ARG_INFO()
  120. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_import, 0, 0, 0)
  121. ZEND_ARG_INFO(0, link_identifier)
  122. ZEND_ARG_INFO(0, file)
  123. ZEND_END_ARG_INFO()
  124. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_query, 0, 0, 0)
  125. ZEND_ARG_INFO(0, link_identifier)
  126. ZEND_ARG_INFO(0, link_identifier)
  127. ZEND_ARG_INFO(0, query)
  128. ZEND_ARG_INFO(0, bind_arg)
  129. ZEND_ARG_INFO(0, bind_arg)
  130. ZEND_END_ARG_INFO()
  131. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_affected_rows, 0, 0, 0)
  132. ZEND_ARG_INFO(0, link_identifier)
  133. ZEND_END_ARG_INFO()
  134. #if abies_0
  135. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_rows, 0, 0, 1)
  136. ZEND_ARG_INFO(0, result_identifier)
  137. ZEND_END_ARG_INFO()
  138. #endif
  139. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_row, 0, 0, 1)
  140. ZEND_ARG_INFO(0, result)
  141. ZEND_ARG_INFO(0, fetch_flags)
  142. ZEND_END_ARG_INFO()
  143. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_assoc, 0, 0, 1)
  144. ZEND_ARG_INFO(0, result)
  145. ZEND_ARG_INFO(0, fetch_flags)
  146. ZEND_END_ARG_INFO()
  147. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_object, 0, 0, 1)
  148. ZEND_ARG_INFO(0, result)
  149. ZEND_ARG_INFO(0, fetch_flags)
  150. ZEND_END_ARG_INFO()
  151. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_name_result, 0, 0, 2)
  152. ZEND_ARG_INFO(0, result)
  153. ZEND_ARG_INFO(0, name)
  154. ZEND_END_ARG_INFO()
  155. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_result, 0, 0, 1)
  156. ZEND_ARG_INFO(0, result)
  157. ZEND_END_ARG_INFO()
  158. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_prepare, 0, 0, 0)
  159. ZEND_ARG_INFO(0, link_identifier)
  160. ZEND_ARG_INFO(0, query)
  161. ZEND_END_ARG_INFO()
  162. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_execute, 0, 0, 1)
  163. ZEND_ARG_INFO(0, query)
  164. ZEND_ARG_INFO(0, bind_arg)
  165. ZEND_ARG_INFO(0, bind_arg)
  166. ZEND_END_ARG_INFO()
  167. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_query, 0, 0, 1)
  168. ZEND_ARG_INFO(0, query)
  169. ZEND_END_ARG_INFO()
  170. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_fields, 0, 0, 1)
  171. ZEND_ARG_INFO(0, query_result)
  172. ZEND_END_ARG_INFO()
  173. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_field_info, 0, 0, 2)
  174. ZEND_ARG_INFO(0, query_result)
  175. ZEND_ARG_INFO(0, field_number)
  176. ZEND_END_ARG_INFO()
  177. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_params, 0, 0, 1)
  178. ZEND_ARG_INFO(0, query)
  179. ZEND_END_ARG_INFO()
  180. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_param_info, 0, 0, 2)
  181. ZEND_ARG_INFO(0, query)
  182. ZEND_ARG_INFO(0, field_number)
  183. ZEND_END_ARG_INFO()
  184. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_add_user, 0, 0, 3)
  185. ZEND_ARG_INFO(0, service_handle)
  186. ZEND_ARG_INFO(0, user_name)
  187. ZEND_ARG_INFO(0, password)
  188. ZEND_ARG_INFO(0, first_name)
  189. ZEND_ARG_INFO(0, middle_name)
  190. ZEND_ARG_INFO(0, last_name)
  191. ZEND_END_ARG_INFO()
  192. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_modify_user, 0, 0, 3)
  193. ZEND_ARG_INFO(0, service_handle)
  194. ZEND_ARG_INFO(0, user_name)
  195. ZEND_ARG_INFO(0, password)
  196. ZEND_ARG_INFO(0, first_name)
  197. ZEND_ARG_INFO(0, middle_name)
  198. ZEND_ARG_INFO(0, last_name)
  199. ZEND_END_ARG_INFO()
  200. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_delete_user, 0, 0, 3)
  201. ZEND_ARG_INFO(0, service_handle)
  202. ZEND_ARG_INFO(0, user_name)
  203. ZEND_ARG_INFO(0, password)
  204. ZEND_ARG_INFO(0, first_name)
  205. ZEND_ARG_INFO(0, middle_name)
  206. ZEND_ARG_INFO(0, last_name)
  207. ZEND_END_ARG_INFO()
  208. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_service_attach, 0, 0, 3)
  209. ZEND_ARG_INFO(0, host)
  210. ZEND_ARG_INFO(0, dba_username)
  211. ZEND_ARG_INFO(0, dba_password)
  212. ZEND_END_ARG_INFO()
  213. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_service_detach, 0, 0, 1)
  214. ZEND_ARG_INFO(0, service_handle)
  215. ZEND_END_ARG_INFO()
  216. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_backup, 0, 0, 3)
  217. ZEND_ARG_INFO(0, service_handle)
  218. ZEND_ARG_INFO(0, source_db)
  219. ZEND_ARG_INFO(0, dest_file)
  220. ZEND_ARG_INFO(0, options)
  221. ZEND_ARG_INFO(0, verbose)
  222. ZEND_END_ARG_INFO()
  223. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_restore, 0, 0, 3)
  224. ZEND_ARG_INFO(0, service_handle)
  225. ZEND_ARG_INFO(0, source_file)
  226. ZEND_ARG_INFO(0, dest_db)
  227. ZEND_ARG_INFO(0, options)
  228. ZEND_ARG_INFO(0, verbose)
  229. ZEND_END_ARG_INFO()
  230. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_maintain_db, 0, 0, 3)
  231. ZEND_ARG_INFO(0, service_handle)
  232. ZEND_ARG_INFO(0, db)
  233. ZEND_ARG_INFO(0, action)
  234. ZEND_ARG_INFO(0, argument)
  235. ZEND_END_ARG_INFO()
  236. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_db_info, 0, 0, 3)
  237. ZEND_ARG_INFO(0, service_handle)
  238. ZEND_ARG_INFO(0, db)
  239. ZEND_ARG_INFO(0, action)
  240. ZEND_ARG_INFO(0, argument)
  241. ZEND_END_ARG_INFO()
  242. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_server_info, 0, 0, 2)
  243. ZEND_ARG_INFO(0, service_handle)
  244. ZEND_ARG_INFO(0, action)
  245. ZEND_END_ARG_INFO()
  246. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_wait_event, 0, 0, 1)
  247. ZEND_ARG_INFO(0, link_identifier)
  248. ZEND_ARG_INFO(0, event)
  249. ZEND_ARG_INFO(0, event2)
  250. ZEND_END_ARG_INFO()
  251. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_set_event_handler, 0, 0, 2)
  252. ZEND_ARG_INFO(0, link_identifier)
  253. ZEND_ARG_INFO(0, handler)
  254. ZEND_ARG_INFO(0, event)
  255. ZEND_ARG_INFO(0, event2)
  256. ZEND_END_ARG_INFO()
  257. ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_event_handler, 0, 0, 1)
  258. ZEND_ARG_INFO(0, event)
  259. ZEND_END_ARG_INFO()
  260. /* }}} */
  261. /* {{{ extension definition structures */
  262. const zend_function_entry ibase_functions[] = {
  263. PHP_FE(ibase_connect, arginfo_ibase_connect)
  264. PHP_FE(ibase_pconnect, arginfo_ibase_pconnect)
  265. PHP_FE(ibase_close, arginfo_ibase_close)
  266. PHP_FE(ibase_drop_db, arginfo_ibase_drop_db)
  267. PHP_FE(ibase_query, arginfo_ibase_query)
  268. PHP_FE(ibase_fetch_row, arginfo_ibase_fetch_row)
  269. PHP_FE(ibase_fetch_assoc, arginfo_ibase_fetch_assoc)
  270. PHP_FE(ibase_fetch_object, arginfo_ibase_fetch_object)
  271. PHP_FE(ibase_free_result, arginfo_ibase_free_result)
  272. PHP_FE(ibase_name_result, arginfo_ibase_name_result)
  273. PHP_FE(ibase_prepare, arginfo_ibase_prepare)
  274. PHP_FE(ibase_execute, arginfo_ibase_execute)
  275. PHP_FE(ibase_free_query, arginfo_ibase_free_query)
  276. PHP_FE(ibase_gen_id, arginfo_ibase_gen_id)
  277. PHP_FE(ibase_num_fields, arginfo_ibase_num_fields)
  278. PHP_FE(ibase_num_params, arginfo_ibase_num_params)
  279. #if abies_0
  280. PHP_FE(ibase_num_rows, arginfo_ibase_num_rows)
  281. #endif
  282. PHP_FE(ibase_affected_rows, arginfo_ibase_affected_rows)
  283. PHP_FE(ibase_field_info, arginfo_ibase_field_info)
  284. PHP_FE(ibase_param_info, arginfo_ibase_param_info)
  285. PHP_FE(ibase_trans, arginfo_ibase_trans)
  286. PHP_FE(ibase_commit, arginfo_ibase_commit)
  287. PHP_FE(ibase_rollback, arginfo_ibase_rollback)
  288. PHP_FE(ibase_commit_ret, arginfo_ibase_commit_ret)
  289. PHP_FE(ibase_rollback_ret, arginfo_ibase_rollback_ret)
  290. PHP_FE(ibase_blob_info, arginfo_ibase_blob_info)
  291. PHP_FE(ibase_blob_create, arginfo_ibase_blob_create)
  292. PHP_FE(ibase_blob_add, arginfo_ibase_blob_add)
  293. PHP_FE(ibase_blob_cancel, arginfo_ibase_blob_cancel)
  294. PHP_FE(ibase_blob_close, arginfo_ibase_blob_close)
  295. PHP_FE(ibase_blob_open, arginfo_ibase_blob_open)
  296. PHP_FE(ibase_blob_get, arginfo_ibase_blob_get)
  297. PHP_FE(ibase_blob_echo, arginfo_ibase_blob_echo)
  298. PHP_FE(ibase_blob_import, arginfo_ibase_blob_import)
  299. PHP_FE(ibase_errmsg, arginfo_ibase_errmsg)
  300. PHP_FE(ibase_errcode, arginfo_ibase_errcode)
  301. PHP_FE(ibase_add_user, arginfo_ibase_add_user)
  302. PHP_FE(ibase_modify_user, arginfo_ibase_modify_user)
  303. PHP_FE(ibase_delete_user, arginfo_ibase_delete_user)
  304. PHP_FE(ibase_service_attach, arginfo_ibase_service_attach)
  305. PHP_FE(ibase_service_detach, arginfo_ibase_service_detach)
  306. PHP_FE(ibase_backup, arginfo_ibase_backup)
  307. PHP_FE(ibase_restore, arginfo_ibase_restore)
  308. PHP_FE(ibase_maintain_db, arginfo_ibase_maintain_db)
  309. PHP_FE(ibase_db_info, arginfo_ibase_db_info)
  310. PHP_FE(ibase_server_info, arginfo_ibase_server_info)
  311. PHP_FE(ibase_wait_event, arginfo_ibase_wait_event)
  312. PHP_FE(ibase_set_event_handler, arginfo_ibase_set_event_handler)
  313. PHP_FE(ibase_free_event_handler, arginfo_ibase_free_event_handler)
  314. /**
  315. * These aliases are provided in order to maintain forward compatibility. As Firebird
  316. * and InterBase are developed independently, functionality might be different between
  317. * the two branches in future versions.
  318. * Firebird users should use the aliases, so future InterBase-specific changes will
  319. * not affect their code
  320. */
  321. PHP_FALIAS(fbird_connect, ibase_connect, arginfo_ibase_connect)
  322. PHP_FALIAS(fbird_pconnect, ibase_pconnect, arginfo_ibase_pconnect)
  323. PHP_FALIAS(fbird_close, ibase_close, arginfo_ibase_close)
  324. PHP_FALIAS(fbird_drop_db, ibase_drop_db, arginfo_ibase_drop_db)
  325. PHP_FALIAS(fbird_query, ibase_query, arginfo_ibase_query)
  326. PHP_FALIAS(fbird_fetch_row, ibase_fetch_row, arginfo_ibase_fetch_row)
  327. PHP_FALIAS(fbird_fetch_assoc, ibase_fetch_assoc, arginfo_ibase_fetch_assoc)
  328. PHP_FALIAS(fbird_fetch_object, ibase_fetch_object, arginfo_ibase_fetch_object)
  329. PHP_FALIAS(fbird_free_result, ibase_free_result, arginfo_ibase_free_result)
  330. PHP_FALIAS(fbird_name_result, ibase_name_result, arginfo_ibase_name_result)
  331. PHP_FALIAS(fbird_prepare, ibase_prepare, arginfo_ibase_prepare)
  332. PHP_FALIAS(fbird_execute, ibase_execute, arginfo_ibase_execute)
  333. PHP_FALIAS(fbird_free_query, ibase_free_query, arginfo_ibase_free_query)
  334. PHP_FALIAS(fbird_gen_id, ibase_gen_id, arginfo_ibase_gen_id)
  335. PHP_FALIAS(fbird_num_fields, ibase_num_fields, arginfo_ibase_num_fields)
  336. PHP_FALIAS(fbird_num_params, ibase_num_params, arginfo_ibase_num_params)
  337. #if abies_0
  338. PHP_FALIAS(fbird_num_rows, ibase_num_rows, arginfo_ibase_num_rows)
  339. #endif
  340. PHP_FALIAS(fbird_affected_rows, ibase_affected_rows, arginfo_ibase_affected_rows)
  341. PHP_FALIAS(fbird_field_info, ibase_field_info, arginfo_ibase_field_info)
  342. PHP_FALIAS(fbird_param_info, ibase_param_info, arginfo_ibase_param_info)
  343. PHP_FALIAS(fbird_trans, ibase_trans, arginfo_ibase_trans)
  344. PHP_FALIAS(fbird_commit, ibase_commit, arginfo_ibase_commit)
  345. PHP_FALIAS(fbird_rollback, ibase_rollback, arginfo_ibase_rollback)
  346. PHP_FALIAS(fbird_commit_ret, ibase_commit_ret, arginfo_ibase_commit_ret)
  347. PHP_FALIAS(fbird_rollback_ret, ibase_rollback_ret, arginfo_ibase_rollback_ret)
  348. PHP_FALIAS(fbird_blob_info, ibase_blob_info, arginfo_ibase_blob_info)
  349. PHP_FALIAS(fbird_blob_create, ibase_blob_create, arginfo_ibase_blob_create)
  350. PHP_FALIAS(fbird_blob_add, ibase_blob_add, arginfo_ibase_blob_add)
  351. PHP_FALIAS(fbird_blob_cancel, ibase_blob_cancel, arginfo_ibase_blob_cancel)
  352. PHP_FALIAS(fbird_blob_close, ibase_blob_close, arginfo_ibase_blob_close)
  353. PHP_FALIAS(fbird_blob_open, ibase_blob_open, arginfo_ibase_blob_open)
  354. PHP_FALIAS(fbird_blob_get, ibase_blob_get, arginfo_ibase_blob_get)
  355. PHP_FALIAS(fbird_blob_echo, ibase_blob_echo, arginfo_ibase_blob_echo)
  356. PHP_FALIAS(fbird_blob_import, ibase_blob_import, arginfo_ibase_blob_import)
  357. PHP_FALIAS(fbird_errmsg, ibase_errmsg, arginfo_ibase_errmsg)
  358. PHP_FALIAS(fbird_errcode, ibase_errcode, arginfo_ibase_errcode)
  359. PHP_FALIAS(fbird_add_user, ibase_add_user, arginfo_ibase_add_user)
  360. PHP_FALIAS(fbird_modify_user, ibase_modify_user, arginfo_ibase_modify_user)
  361. PHP_FALIAS(fbird_delete_user, ibase_delete_user, arginfo_ibase_delete_user)
  362. PHP_FALIAS(fbird_service_attach, ibase_service_attach, arginfo_ibase_service_attach)
  363. PHP_FALIAS(fbird_service_detach, ibase_service_detach, arginfo_ibase_service_detach)
  364. PHP_FALIAS(fbird_backup, ibase_backup, arginfo_ibase_backup)
  365. PHP_FALIAS(fbird_restore, ibase_restore, arginfo_ibase_restore)
  366. PHP_FALIAS(fbird_maintain_db, ibase_maintain_db, arginfo_ibase_maintain_db)
  367. PHP_FALIAS(fbird_db_info, ibase_db_info, arginfo_ibase_db_info)
  368. PHP_FALIAS(fbird_server_info, ibase_server_info, arginfo_ibase_server_info)
  369. PHP_FALIAS(fbird_wait_event, ibase_wait_event, arginfo_ibase_wait_event)
  370. PHP_FALIAS(fbird_set_event_handler, ibase_set_event_handler, arginfo_ibase_set_event_handler)
  371. PHP_FALIAS(fbird_free_event_handler, ibase_free_event_handler, arginfo_ibase_free_event_handler)
  372. PHP_FE_END
  373. };
  374. zend_module_entry ibase_module_entry = {
  375. STANDARD_MODULE_HEADER,
  376. "interbase",
  377. ibase_functions,
  378. PHP_MINIT(ibase),
  379. PHP_MSHUTDOWN(ibase),
  380. NULL,
  381. PHP_RSHUTDOWN(ibase),
  382. PHP_MINFO(ibase),
  383. NO_VERSION_YET,
  384. PHP_MODULE_GLOBALS(ibase),
  385. PHP_GINIT(ibase),
  386. NULL,
  387. NULL,
  388. STANDARD_MODULE_PROPERTIES_EX
  389. };
  390. #ifdef COMPILE_DL_INTERBASE
  391. ZEND_GET_MODULE(ibase)
  392. #endif
  393. /* True globals, no need for thread safety */
  394. int le_link, le_plink, le_trans;
  395. /* }}} */
  396. /* error handling ---------------------------- */
  397. /* {{{ proto string ibase_errmsg(void)
  398. Return error message */
  399. PHP_FUNCTION(ibase_errmsg)
  400. {
  401. if (zend_parse_parameters_none() == FAILURE) {
  402. return;
  403. }
  404. if (IBG(sql_code) != 0) {
  405. RETURN_STRING(IBG(errmsg), 1);
  406. }
  407. RETURN_FALSE;
  408. }
  409. /* }}} */
  410. /* {{{ proto int ibase_errcode(void)
  411. Return error code */
  412. PHP_FUNCTION(ibase_errcode)
  413. {
  414. if (zend_parse_parameters_none() == FAILURE) {
  415. return;
  416. }
  417. if (IBG(sql_code) != 0) {
  418. RETURN_LONG(IBG(sql_code));
  419. }
  420. RETURN_FALSE;
  421. }
  422. /* }}} */
  423. /* print interbase error and save it for ibase_errmsg() */
  424. void _php_ibase_error(TSRMLS_D) /* {{{ */
  425. {
  426. char *s = IBG(errmsg);
  427. ISC_STATUS *statusp = IB_STATUS;
  428. IBG(sql_code) = isc_sqlcode(IB_STATUS);
  429. while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) {
  430. strcat(IBG(errmsg), " ");
  431. s = IBG(errmsg) + strlen(IBG(errmsg));
  432. }
  433. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
  434. }
  435. /* }}} */
  436. /* print php interbase module error and save it for ibase_errmsg() */
  437. void _php_ibase_module_error(char *msg TSRMLS_DC, ...) /* {{{ */
  438. {
  439. va_list ap;
  440. #ifdef ZTS
  441. va_start(ap, TSRMLS_C);
  442. #else
  443. va_start(ap, msg);
  444. #endif
  445. /* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */
  446. vsnprintf(IBG(errmsg), MAX_ERRMSG, msg, ap);
  447. va_end(ap);
  448. IBG(sql_code) = -999; /* no SQL error */
  449. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
  450. }
  451. /* }}} */
  452. /* {{{ internal macros, functions and structures */
  453. typedef struct {
  454. isc_db_handle *db_ptr;
  455. long tpb_len;
  456. char *tpb_ptr;
  457. } ISC_TEB;
  458. /* }}} */
  459. /* Fill ib_link and trans with the correct database link and transaction. */
  460. void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
  461. zval **link_id, ibase_db_link **ib_link, ibase_trans **trans)
  462. {
  463. int type;
  464. IBDEBUG("Transaction or database link?");
  465. if (zend_list_find(Z_LVAL_PP(link_id), &type)) {
  466. if (type == le_trans) {
  467. /* Transaction resource: make sure it refers to one link only, then
  468. fetch it; database link is stored in ib_trans->db_link[]. */
  469. IBDEBUG("Type is le_trans");
  470. ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans);
  471. if ((*trans)->link_cnt > 1) {
  472. _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections."
  473. TSRMLS_CC);
  474. return;
  475. }
  476. *ib_link = (*trans)->db_link[0];
  477. return;
  478. }
  479. }
  480. IBDEBUG("Type is le_[p]link or id not found");
  481. /* Database link resource, use default transaction. */
  482. *trans = NULL;
  483. ZEND_FETCH_RESOURCE2(*ib_link, ibase_db_link *, link_id, -1, LE_LINK, le_link, le_plink);
  484. }
  485. /* }}} */
  486. /* destructors ---------------------- */
  487. static void _php_ibase_commit_link(ibase_db_link *link TSRMLS_DC) /* {{{ */
  488. {
  489. unsigned short i = 0, j;
  490. ibase_tr_list *l;
  491. ibase_event *e;
  492. IBDEBUG("Checking transactions to close...");
  493. for (l = link->tr_list; l != NULL; ++i) {
  494. ibase_tr_list *p = l;
  495. if (p->trans != NULL) {
  496. if (i == 0) {
  497. if (p->trans->handle != NULL) {
  498. IBDEBUG("Committing default transaction...");
  499. if (isc_commit_transaction(IB_STATUS, &p->trans->handle)) {
  500. _php_ibase_error(TSRMLS_C);
  501. }
  502. }
  503. efree(p->trans); /* default transaction is not a registered resource: clean up */
  504. } else {
  505. if (p->trans->handle != NULL) {
  506. /* non-default trans might have been rolled back by other call of this dtor */
  507. IBDEBUG("Rolling back other transactions...");
  508. if (isc_rollback_transaction(IB_STATUS, &p->trans->handle)) {
  509. _php_ibase_error(TSRMLS_C);
  510. }
  511. }
  512. /* set this link pointer to NULL in the transaction */
  513. for (j = 0; j < p->trans->link_cnt; ++j) {
  514. if (p->trans->db_link[j] == link) {
  515. p->trans->db_link[j] = NULL;
  516. break;
  517. }
  518. }
  519. }
  520. }
  521. l = l->next;
  522. efree(p);
  523. }
  524. link->tr_list = NULL;
  525. for (e = link->event_head; e; e = e->event_next) {
  526. _php_ibase_free_event(e TSRMLS_CC);
  527. e->link = NULL;
  528. }
  529. }
  530. /* }}} */
  531. static void php_ibase_commit_link_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
  532. {
  533. ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
  534. _php_ibase_commit_link(link TSRMLS_CC);
  535. }
  536. /* }}} */
  537. static void _php_ibase_close_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
  538. {
  539. ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
  540. _php_ibase_commit_link(link TSRMLS_CC);
  541. if (link->handle != NULL) {
  542. IBDEBUG("Closing normal link...");
  543. isc_detach_database(IB_STATUS, &link->handle);
  544. }
  545. IBG(num_links)--;
  546. efree(link);
  547. }
  548. /* }}} */
  549. static void _php_ibase_close_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
  550. {
  551. ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
  552. _php_ibase_commit_link(link TSRMLS_CC);
  553. IBDEBUG("Closing permanent link...");
  554. if (link->handle != NULL) {
  555. isc_detach_database(IB_STATUS, &link->handle);
  556. }
  557. IBG(num_persistent)--;
  558. IBG(num_links)--;
  559. free(link);
  560. }
  561. /* }}} */
  562. static void _php_ibase_free_trans(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
  563. {
  564. ibase_trans *trans = (ibase_trans *)rsrc->ptr;
  565. unsigned short i;
  566. IBDEBUG("Cleaning up transaction resource...");
  567. if (trans->handle != NULL) {
  568. IBDEBUG("Rolling back unhandled transaction...");
  569. if (isc_rollback_transaction(IB_STATUS, &trans->handle)) {
  570. _php_ibase_error(TSRMLS_C);
  571. }
  572. }
  573. /* now remove this transaction from all the connection-transaction lists */
  574. for (i = 0; i < trans->link_cnt; ++i) {
  575. if (trans->db_link[i] != NULL) {
  576. ibase_tr_list **l;
  577. for (l = &trans->db_link[i]->tr_list; *l != NULL; l = &(*l)->next) {
  578. if ( (*l)->trans == trans) {
  579. ibase_tr_list *p = *l;
  580. *l = p->next;
  581. efree(p);
  582. break;
  583. }
  584. }
  585. }
  586. }
  587. efree(trans);
  588. }
  589. /* }}} */
  590. /* TODO this function should be part of either Zend or PHP API */
  591. static PHP_INI_DISP(php_ibase_password_displayer_cb)
  592. {
  593. TSRMLS_FETCH();
  594. if ((type == PHP_INI_DISPLAY_ORIG && ini_entry->orig_value)
  595. || (type == PHP_INI_DISPLAY_ACTIVE && ini_entry->value)) {
  596. PUTS("********");
  597. } else if (!sapi_module.phpinfo_as_text) {
  598. PUTS("<i>no value</i>");
  599. } else {
  600. PUTS("no value");
  601. }
  602. }
  603. /* {{{ startup, shutdown and info functions */
  604. PHP_INI_BEGIN()
  605. PHP_INI_ENTRY_EX("ibase.allow_persistent", "1", PHP_INI_SYSTEM, NULL, zend_ini_boolean_displayer_cb)
  606. PHP_INI_ENTRY_EX("ibase.max_persistent", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
  607. PHP_INI_ENTRY_EX("ibase.max_links", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
  608. PHP_INI_ENTRY("ibase.default_db", NULL, PHP_INI_SYSTEM, NULL)
  609. PHP_INI_ENTRY("ibase.default_user", NULL, PHP_INI_ALL, NULL)
  610. PHP_INI_ENTRY_EX("ibase.default_password", NULL, PHP_INI_ALL, NULL, php_ibase_password_displayer_cb)
  611. PHP_INI_ENTRY("ibase.default_charset", NULL, PHP_INI_ALL, NULL)
  612. PHP_INI_ENTRY("ibase.timestampformat", IB_DEF_DATE_FMT " " IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
  613. PHP_INI_ENTRY("ibase.dateformat", IB_DEF_DATE_FMT, PHP_INI_ALL, NULL)
  614. PHP_INI_ENTRY("ibase.timeformat", IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
  615. PHP_INI_END()
  616. static PHP_GINIT_FUNCTION(ibase)
  617. {
  618. ibase_globals->num_persistent = ibase_globals->num_links = 0;
  619. ibase_globals->sql_code = *ibase_globals->errmsg = 0;
  620. ibase_globals->default_link = -1;
  621. }
  622. PHP_MINIT_FUNCTION(ibase)
  623. {
  624. REGISTER_INI_ENTRIES();
  625. le_link = zend_register_list_destructors_ex(_php_ibase_close_link, NULL, LE_LINK, module_number);
  626. le_plink = zend_register_list_destructors_ex(php_ibase_commit_link_rsrc, _php_ibase_close_plink, LE_PLINK, module_number);
  627. le_trans = zend_register_list_destructors_ex(_php_ibase_free_trans, NULL, LE_TRANS, module_number);
  628. REGISTER_LONG_CONSTANT("IBASE_DEFAULT", PHP_IBASE_DEFAULT, CONST_PERSISTENT);
  629. REGISTER_LONG_CONSTANT("IBASE_CREATE", PHP_IBASE_CREATE, CONST_PERSISTENT);
  630. REGISTER_LONG_CONSTANT("IBASE_TEXT", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT); /* deprecated, for BC only */
  631. REGISTER_LONG_CONSTANT("IBASE_FETCH_BLOBS", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT);
  632. REGISTER_LONG_CONSTANT("IBASE_FETCH_ARRAYS", PHP_IBASE_FETCH_ARRAYS, CONST_PERSISTENT);
  633. REGISTER_LONG_CONSTANT("IBASE_UNIXTIME", PHP_IBASE_UNIXTIME, CONST_PERSISTENT);
  634. /* transactions */
  635. REGISTER_LONG_CONSTANT("IBASE_WRITE", PHP_IBASE_WRITE, CONST_PERSISTENT);
  636. REGISTER_LONG_CONSTANT("IBASE_READ", PHP_IBASE_READ, CONST_PERSISTENT);
  637. REGISTER_LONG_CONSTANT("IBASE_COMMITTED", PHP_IBASE_COMMITTED, CONST_PERSISTENT);
  638. REGISTER_LONG_CONSTANT("IBASE_CONSISTENCY", PHP_IBASE_CONSISTENCY, CONST_PERSISTENT);
  639. REGISTER_LONG_CONSTANT("IBASE_CONCURRENCY", PHP_IBASE_CONCURRENCY, CONST_PERSISTENT);
  640. REGISTER_LONG_CONSTANT("IBASE_REC_VERSION", PHP_IBASE_REC_VERSION, CONST_PERSISTENT);
  641. REGISTER_LONG_CONSTANT("IBASE_REC_NO_VERSION", PHP_IBASE_REC_NO_VERSION, CONST_PERSISTENT);
  642. REGISTER_LONG_CONSTANT("IBASE_NOWAIT", PHP_IBASE_NOWAIT, CONST_PERSISTENT);
  643. REGISTER_LONG_CONSTANT("IBASE_WAIT", PHP_IBASE_WAIT, CONST_PERSISTENT);
  644. php_ibase_query_minit(INIT_FUNC_ARGS_PASSTHRU);
  645. php_ibase_blobs_minit(INIT_FUNC_ARGS_PASSTHRU);
  646. php_ibase_events_minit(INIT_FUNC_ARGS_PASSTHRU);
  647. php_ibase_service_minit(INIT_FUNC_ARGS_PASSTHRU);
  648. return SUCCESS;
  649. }
  650. PHP_MSHUTDOWN_FUNCTION(ibase)
  651. {
  652. #ifndef PHP_WIN32
  653. /**
  654. * When the Interbase client API library libgds.so is first loaded, it registers a call to
  655. * gds__cleanup() with atexit(), in order to clean up after itself when the process exits.
  656. * This means that the library is called at process shutdown, and cannot be unloaded beforehand.
  657. * PHP tries to unload modules after every request [dl()'ed modules], and right before the
  658. * process shuts down [modules loaded from php.ini]. This results in a segfault for this module.
  659. * By NULLing the dlopen() handle in the module entry, Zend omits the call to dlclose(),
  660. * ensuring that the module will remain present until the process exits. However, the functions
  661. * and classes exported by the module will not be available until the module is 'reloaded'.
  662. * When reloaded, dlopen() will return the handle of the already loaded module. The module will
  663. * be unloaded automatically when the process exits.
  664. */
  665. zend_module_entry *ibase_entry;
  666. if (SUCCESS == zend_hash_find(&module_registry, ibase_module_entry.name,
  667. strlen(ibase_module_entry.name) +1, (void*) &ibase_entry)) {
  668. ibase_entry->handle = NULL;
  669. }
  670. #endif
  671. UNREGISTER_INI_ENTRIES();
  672. return SUCCESS;
  673. }
  674. PHP_RSHUTDOWN_FUNCTION(ibase)
  675. {
  676. IBG(num_links) = IBG(num_persistent);
  677. IBG(default_link)= -1;
  678. RESET_ERRMSG;
  679. return SUCCESS;
  680. }
  681. PHP_MINFO_FUNCTION(ibase)
  682. {
  683. char tmp[64], *s;
  684. php_info_print_table_start();
  685. php_info_print_table_row(2, "Firebird/InterBase Support",
  686. #ifdef COMPILE_DL_INTERBASE
  687. "dynamic");
  688. #else
  689. "static");
  690. #endif
  691. #ifdef FB_API_VER
  692. snprintf( (s = tmp), sizeof(tmp), "Firebird API version %d", FB_API_VER);
  693. #elif (SQLDA_CURRENT_VERSION > 1)
  694. s = "Interbase 7.0 and up";
  695. #elif !defined(DSC_null)
  696. s = "Interbase 6";
  697. #else
  698. s = "Firebird 1.0";
  699. #endif
  700. php_info_print_table_row(2, "Compile-time Client Library Version", s);
  701. #if defined(__GNUC__) || defined(PHP_WIN32)
  702. do {
  703. info_func_t info_func = NULL;
  704. #ifdef __GNUC__
  705. info_func = (info_func_t)dlsym(RTLD_DEFAULT, "isc_get_client_version");
  706. #else
  707. HMODULE l = GetModuleHandle("fbclient");
  708. if (!l && !(l = GetModuleHandle("gds32"))) {
  709. break;
  710. }
  711. info_func = (info_func_t)GetProcAddress(l, "isc_get_client_version");
  712. #endif
  713. if (info_func) {
  714. info_func(s = tmp);
  715. } else {
  716. s = "Firebird 1.0/Interbase 6";
  717. }
  718. php_info_print_table_row(2, "Run-time Client Library Version", s);
  719. } while (0);
  720. #endif
  721. php_info_print_table_end();
  722. DISPLAY_INI_ENTRIES();
  723. }
  724. /* }}} */
  725. enum connect_args { DB = 0, USER = 1, PASS = 2, CSET = 3, ROLE = 4, BUF = 0, DLECT = 1, SYNC = 2 };
  726. static char const dpb_args[] = {
  727. 0, isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name, 0
  728. };
  729. int _php_ibase_attach_db(char **args, int *len, long *largs, isc_db_handle *db TSRMLS_DC)
  730. {
  731. short i, dpb_len, buf_len = 257-2; /* version byte at the front, and a null at the end */
  732. char dpb_buffer[257] = { isc_dpb_version1, 0 }, *dpb;
  733. dpb = dpb_buffer + 1;
  734. for (i = 0; i < sizeof(dpb_args); ++i) {
  735. if (dpb_args[i] && args[i] && len[i] && buf_len > 0) {
  736. dpb_len = slprintf(dpb, buf_len, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]);
  737. dpb += dpb_len;
  738. buf_len -= dpb_len;
  739. }
  740. }
  741. if (largs[BUF] && buf_len > 0) {
  742. dpb_len = slprintf(dpb, buf_len, "%c\2%c%c", isc_dpb_num_buffers,
  743. (char)(largs[BUF] >> 8), (char)(largs[BUF] & 0xff));
  744. dpb += dpb_len;
  745. buf_len -= dpb_len;
  746. }
  747. if (largs[SYNC] && buf_len > 0) {
  748. dpb_len = slprintf(dpb, buf_len, "%c\1%c", isc_dpb_force_write, largs[SYNC] == isc_spb_prp_wm_sync ? 1 : 0);
  749. dpb += dpb_len;
  750. buf_len -= dpb_len;
  751. }
  752. if (isc_attach_database(IB_STATUS, (short)len[DB], args[DB], db, (short)(dpb-dpb_buffer), dpb_buffer)) {
  753. _php_ibase_error(TSRMLS_C);
  754. return FAILURE;
  755. }
  756. return SUCCESS;
  757. }
  758. /* }}} */
  759. static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* {{{ */
  760. {
  761. char *c, hash[16], *args[] = { NULL, NULL, NULL, NULL, NULL };
  762. int i, len[] = { 0, 0, 0, 0, 0 };
  763. long largs[] = { 0, 0, 0 };
  764. PHP_MD5_CTX hash_context;
  765. zend_rsrc_list_entry new_index_ptr, *le;
  766. isc_db_handle db_handle = NULL;
  767. ibase_db_link *ib_link;
  768. RESET_ERRMSG;
  769. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssllsl",
  770. &args[DB], &len[DB], &args[USER], &len[USER], &args[PASS], &len[PASS],
  771. &args[CSET], &len[CSET], &largs[BUF], &largs[DLECT], &args[ROLE], &len[ROLE],
  772. &largs[SYNC])) {
  773. RETURN_FALSE;
  774. }
  775. /* restrict to the server/db in the .ini if in safe mode */
  776. if ((!len[DB] || PG(sql_safe_mode)) && (c = INI_STR("ibase.default_db"))) {
  777. args[DB] = c;
  778. len[DB] = strlen(c);
  779. }
  780. if (!len[USER] && (c = INI_STR("ibase.default_user"))) {
  781. args[USER] = c;
  782. len[USER] = strlen(c);
  783. }
  784. if (!len[PASS] && (c = INI_STR("ibase.default_password"))) {
  785. args[PASS] = c;
  786. len[PASS] = strlen(c);
  787. }
  788. if (!len[CSET] && (c = INI_STR("ibase.default_charset"))) {
  789. args[CSET] = c;
  790. len[CSET] = strlen(c);
  791. }
  792. /* don't want usernames and passwords floating around */
  793. PHP_MD5Init(&hash_context);
  794. for (i = 0; i < sizeof(args)/sizeof(char*); ++i) {
  795. PHP_MD5Update(&hash_context,args[i],len[i]);
  796. }
  797. for (i = 0; i < sizeof(largs)/sizeof(long); ++i) {
  798. PHP_MD5Update(&hash_context,(char*)&largs[i],sizeof(long));
  799. }
  800. PHP_MD5Final(hash, &hash_context);
  801. /* try to reuse a connection */
  802. if (SUCCESS == zend_hash_find(&EG(regular_list), hash, sizeof(hash), (void *) &le)) {
  803. long xlink;
  804. int type;
  805. if (Z_TYPE_P(le) != le_index_ptr) {
  806. RETURN_FALSE;
  807. }
  808. xlink = (long) le->ptr;
  809. if (zend_list_find(xlink, &type) && ((!persistent && type == le_link) || type == le_plink)) {
  810. zend_list_addref(xlink);
  811. RETURN_RESOURCE(IBG(default_link) = xlink);
  812. } else {
  813. zend_hash_del(&EG(regular_list), hash, sizeof(hash));
  814. }
  815. }
  816. /* ... or a persistent one */
  817. switch (zend_hash_find(&EG(persistent_list), hash, sizeof(hash), (void *) &le)) {
  818. long l;
  819. static char info[] = { isc_info_base_level, isc_info_end };
  820. char result[8];
  821. ISC_STATUS status[20];
  822. case SUCCESS:
  823. if (Z_TYPE_P(le) != le_plink) {
  824. RETURN_FALSE;
  825. }
  826. /* check if connection has timed out */
  827. ib_link = (ibase_db_link *) le->ptr;
  828. if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) {
  829. ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
  830. break;
  831. }
  832. zend_hash_del(&EG(persistent_list), hash, sizeof(hash));
  833. default:
  834. /* no link found, so we have to open one */
  835. if ((l = INI_INT("ibase.max_links")) != -1 && IBG(num_links) >= l) {
  836. _php_ibase_module_error("Too many open links (%ld)" TSRMLS_CC, IBG(num_links));
  837. RETURN_FALSE;
  838. }
  839. /* create the ib_link */
  840. if (FAILURE == _php_ibase_attach_db(args, len, largs, &db_handle TSRMLS_CC)) {
  841. RETURN_FALSE;
  842. }
  843. /* use non-persistent if allowed number of persistent links is exceeded */
  844. if (!persistent || ((l = INI_INT("ibase.max_persistent") != -1) && IBG(num_persistent) >= l)) {
  845. ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
  846. ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
  847. } else {
  848. zend_rsrc_list_entry new_le;
  849. ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
  850. if (!ib_link) {
  851. RETURN_FALSE;
  852. }
  853. /* hash it up */
  854. Z_TYPE(new_le) = le_plink;
  855. new_le.ptr = ib_link;
  856. if (FAILURE == zend_hash_update(&EG(persistent_list), hash, sizeof(hash),
  857. (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)) {
  858. free(ib_link);
  859. RETURN_FALSE;
  860. }
  861. ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
  862. ++IBG(num_persistent);
  863. }
  864. ib_link->handle = db_handle;
  865. ib_link->dialect = largs[DLECT] ? (unsigned short)largs[DLECT] : SQL_DIALECT_CURRENT;
  866. ib_link->tr_list = NULL;
  867. ib_link->event_head = NULL;
  868. ++IBG(num_links);
  869. }
  870. /* add it to the hash */
  871. new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
  872. Z_TYPE(new_index_ptr) = le_index_ptr;
  873. if (FAILURE == zend_hash_update(&EG(regular_list), hash, sizeof(hash),
  874. (void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)) {
  875. RETURN_FALSE;
  876. }
  877. zend_list_addref(IBG(default_link) = Z_LVAL_P(return_value));
  878. }
  879. /* }}} */
  880. /* {{{ proto resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
  881. Open a connection to an InterBase database */
  882. PHP_FUNCTION(ibase_connect)
  883. {
  884. _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  885. }
  886. /* }}} */
  887. /* {{{ proto resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
  888. Open a persistent connection to an InterBase database */
  889. PHP_FUNCTION(ibase_pconnect)
  890. {
  891. _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INI_INT("ibase.allow_persistent"));
  892. }
  893. /* }}} */
  894. /* {{{ proto bool ibase_close([resource link_identifier])
  895. Close an InterBase connection */
  896. PHP_FUNCTION(ibase_close)
  897. {
  898. zval *link_arg = NULL;
  899. ibase_db_link *ib_link;
  900. int link_id;
  901. RESET_ERRMSG;
  902. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
  903. return;
  904. }
  905. if (ZEND_NUM_ARGS() == 0) {
  906. link_id = IBG(default_link);
  907. CHECK_LINK(link_id);
  908. IBG(default_link) = -1;
  909. } else {
  910. link_id = Z_RESVAL_P(link_arg);
  911. }
  912. ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
  913. zend_list_delete(link_id);
  914. RETURN_TRUE;
  915. }
  916. /* }}} */
  917. /* {{{ proto bool ibase_drop_db([resource link_identifier])
  918. Drop an InterBase database */
  919. PHP_FUNCTION(ibase_drop_db)
  920. {
  921. zval *link_arg = NULL;
  922. ibase_db_link *ib_link;
  923. ibase_tr_list *l;
  924. int link_id;
  925. RESET_ERRMSG;
  926. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
  927. return;
  928. }
  929. if (ZEND_NUM_ARGS() == 0) {
  930. link_id = IBG(default_link);
  931. CHECK_LINK(link_id);
  932. IBG(default_link) = -1;
  933. } else {
  934. link_id = Z_RESVAL_P(link_arg);
  935. }
  936. ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
  937. if (isc_drop_database(IB_STATUS, &ib_link->handle)) {
  938. _php_ibase_error(TSRMLS_C);
  939. RETURN_FALSE;
  940. }
  941. /* isc_drop_database() doesn't invalidate the transaction handles */
  942. for (l = ib_link->tr_list; l != NULL; l = l->next) {
  943. if (l->trans != NULL) l->trans->handle = NULL;
  944. }
  945. zend_list_delete(link_id);
  946. RETURN_TRUE;
  947. }
  948. /* }}} */
  949. /* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier [, ... ], int trans_args [, resource link_identifier [, ... ]] [, ...]]])
  950. Start a transaction over one or several databases */
  951. #define TPB_MAX_SIZE (8*sizeof(char))
  952. PHP_FUNCTION(ibase_trans)
  953. {
  954. unsigned short i, link_cnt = 0, tpb_len = 0;
  955. int argn;
  956. char last_tpb[TPB_MAX_SIZE];
  957. ibase_db_link **ib_link = NULL;
  958. ibase_trans *ib_trans;
  959. isc_tr_handle tr_handle = NULL;
  960. ISC_STATUS result;
  961. RESET_ERRMSG;
  962. argn = ZEND_NUM_ARGS();
  963. /* (1+argn) is an upper bound for the number of links this trans connects to */
  964. ib_link = (ibase_db_link **) safe_emalloc(sizeof(ibase_db_link *),1+argn,0);
  965. if (argn > 0) {
  966. long trans_argl = 0;
  967. char *tpb;
  968. ISC_TEB *teb;
  969. zval ***args = NULL;
  970. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argn) == FAILURE) {
  971. efree(args);
  972. efree(ib_link);
  973. RETURN_FALSE;
  974. }
  975. teb = (ISC_TEB *) safe_emalloc(sizeof(ISC_TEB),argn,0);
  976. tpb = (char *) safe_emalloc(TPB_MAX_SIZE,argn,0);
  977. /* enumerate all the arguments: assume every non-resource argument
  978. specifies modifiers for the link ids that follow it */
  979. for (i = 0; i < argn; ++i) {
  980. if (Z_TYPE_PP(args[i]) == IS_RESOURCE) {
  981. if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, args[i], -1, LE_LINK, le_link, le_plink)) {
  982. efree(teb);
  983. efree(tpb);
  984. efree(ib_link);
  985. efree(args);
  986. RETURN_FALSE;
  987. }
  988. /* copy the most recent modifier string into tbp[] */
  989. memcpy(&tpb[TPB_MAX_SIZE * link_cnt], last_tpb, TPB_MAX_SIZE);
  990. /* add a database handle to the TEB with the most recently specified set of modifiers */
  991. teb[link_cnt].db_ptr = &ib_link[link_cnt]->handle;
  992. teb[link_cnt].tpb_len = tpb_len;
  993. teb[link_cnt].tpb_ptr = &tpb[TPB_MAX_SIZE * link_cnt];
  994. ++link_cnt;
  995. } else {
  996. tpb_len = 0;
  997. convert_to_long_ex(args[i]);
  998. trans_argl = Z_LVAL_PP(args[i]);
  999. if (trans_argl != PHP_IBASE_DEFAULT) {
  1000. last_tpb[tpb_len++] = isc_tpb_version3;
  1001. /* access mode */
  1002. if (PHP_IBASE_READ == (trans_argl & PHP_IBASE_READ)) {
  1003. last_tpb[tpb_len++] = isc_tpb_read;
  1004. } else if (PHP_IBASE_WRITE == (trans_argl & PHP_IBASE_WRITE)) {
  1005. last_tpb[tpb_len++] = isc_tpb_write;
  1006. }
  1007. /* isolation level */
  1008. if (PHP_IBASE_COMMITTED == (trans_argl & PHP_IBASE_COMMITTED)) {
  1009. last_tpb[tpb_len++] = isc_tpb_read_committed;
  1010. if (PHP_IBASE_REC_VERSION == (trans_argl & PHP_IBASE_REC_VERSION)) {
  1011. last_tpb[tpb_len++] = isc_tpb_rec_version;
  1012. } else if (PHP_IBASE_REC_NO_VERSION == (trans_argl & PHP_IBASE_REC_NO_VERSION)) {
  1013. last_tpb[tpb_len++] = isc_tpb_no_rec_version;
  1014. }
  1015. } else if (PHP_IBASE_CONSISTENCY == (trans_argl & PHP_IBASE_CONSISTENCY)) {
  1016. last_tpb[tpb_len++] = isc_tpb_consistency;
  1017. } else if (PHP_IBASE_CONCURRENCY == (trans_argl & PHP_IBASE_CONCURRENCY)) {
  1018. last_tpb[tpb_len++] = isc_tpb_concurrency;
  1019. }
  1020. /* lock resolution */
  1021. if (PHP_IBASE_NOWAIT == (trans_argl & PHP_IBASE_NOWAIT)) {
  1022. last_tpb[tpb_len++] = isc_tpb_nowait;
  1023. } else if (PHP_IBASE_WAIT == (trans_argl & PHP_IBASE_WAIT)) {
  1024. last_tpb[tpb_len++] = isc_tpb_wait;
  1025. }
  1026. }
  1027. }
  1028. }
  1029. if (link_cnt > 0) {
  1030. result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb);
  1031. }
  1032. efree(args);
  1033. efree(tpb);
  1034. efree(teb);
  1035. }
  1036. if (link_cnt == 0) {
  1037. link_cnt = 1;
  1038. if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[0], ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink)) {
  1039. efree(ib_link);
  1040. RETURN_FALSE;
  1041. }
  1042. result = isc_start_transaction(IB_STATUS, &tr_handle, 1, &ib_link[0]->handle, tpb_len, last_tpb);
  1043. }
  1044. /* start the transaction */
  1045. if (result) {
  1046. _php_ibase_error(TSRMLS_C);
  1047. efree(ib_link);
  1048. RETURN_FALSE;
  1049. }
  1050. /* register the transaction in our own data structures */
  1051. ib_trans = (ibase_trans *) safe_emalloc(link_cnt-1, sizeof(ibase_db_link *), sizeof(ibase_trans));
  1052. ib_trans->handle = tr_handle;
  1053. ib_trans->link_cnt = link_cnt;
  1054. ib_trans->affected_rows = 0;
  1055. for (i = 0; i < link_cnt; ++i) {
  1056. ibase_tr_list **l;
  1057. ib_trans->db_link[i] = ib_link[i];
  1058. /* the first item in the connection-transaction list is reserved for the default transaction */
  1059. if (ib_link[i]->tr_list == NULL) {
  1060. ib_link[i]->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
  1061. ib_link[i]->tr_list->trans = NULL;
  1062. ib_link[i]->tr_list->next = NULL;
  1063. }
  1064. /* link the transaction into the connection-transaction list */
  1065. for (l = &ib_link[i]->tr_list; *l != NULL; l = &(*l)->next);
  1066. *l = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
  1067. (*l)->trans = ib_trans;
  1068. (*l)->next = NULL;
  1069. }
  1070. efree(ib_link);
  1071. ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);
  1072. }
  1073. /* }}} */
  1074. int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans TSRMLS_DC) /* {{{ */
  1075. {
  1076. if (ib_link == NULL) {
  1077. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid database link");
  1078. return FAILURE;
  1079. }
  1080. /* the first item in the connection-transaction list is reserved for the default transaction */
  1081. if (ib_link->tr_list == NULL) {
  1082. ib_link->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
  1083. ib_link->tr_list->trans = NULL;
  1084. ib_link->tr_list->next = NULL;
  1085. }
  1086. if (*trans == NULL) {
  1087. ibase_trans *tr = ib_link->tr_list->trans;
  1088. if (tr == NULL) {
  1089. tr = (ibase_trans *) emalloc(sizeof(ibase_trans));
  1090. tr->handle = NULL;
  1091. tr->link_cnt = 1;
  1092. tr->affected_rows = 0;
  1093. tr->db_link[0] = ib_link;
  1094. ib_link->tr_list->trans = tr;
  1095. }
  1096. if (tr->handle == NULL) {
  1097. if (isc_start_transaction(IB_STATUS, &tr->handle, 1, &ib_link->handle, 0, NULL)) {
  1098. _php_ibase_error(TSRMLS_C);
  1099. return FAILURE;
  1100. }
  1101. }
  1102. *trans = tr;
  1103. }
  1104. return SUCCESS;
  1105. }
  1106. /* }}} */
  1107. static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{{ */
  1108. {
  1109. ibase_trans *trans = NULL;
  1110. int res_id = 0;
  1111. ISC_STATUS result;
  1112. ibase_db_link *ib_link;
  1113. zval *arg = NULL;
  1114. int type;
  1115. RESET_ERRMSG;
  1116. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg) == FAILURE) {
  1117. return;
  1118. }
  1119. if (ZEND_NUM_ARGS() == 0) {
  1120. ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
  1121. if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
  1122. /* this link doesn't have a default transaction */
  1123. _php_ibase_module_error("Default link has no default transaction" TSRMLS_CC);
  1124. RETURN_FALSE;
  1125. }
  1126. trans = ib_link->tr_list->trans;
  1127. } else {
  1128. /* one id was passed, could be db or trans id */
  1129. if (zend_list_find(Z_RESVAL_P(arg), &type) && type == le_trans) {
  1130. ZEND_FETCH_RESOURCE(trans, ibase_trans *, &arg, -1, LE_TRANS, le_trans);
  1131. res_id = Z_RESVAL_P(arg);
  1132. } else {
  1133. ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &arg, -1, LE_LINK, le_link, le_plink);
  1134. if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
  1135. /* this link doesn't have a default transaction */
  1136. _php_ibase_module_error("Link has no default transaction" TSRMLS_CC);
  1137. RETURN_FALSE;
  1138. }
  1139. trans = ib_link->tr_list->trans;
  1140. }
  1141. }
  1142. switch (commit) {
  1143. default: /* == case ROLLBACK: */
  1144. result = isc_rollback_transaction(IB_STATUS, &trans->handle);
  1145. break;
  1146. case COMMIT:
  1147. result = isc_commit_transaction(IB_STATUS, &trans->handle);
  1148. break;
  1149. case (ROLLBACK | RETAIN):
  1150. result = isc_rollback_retaining(IB_STATUS, &trans->handle);
  1151. break;
  1152. case (COMMIT | RETAIN):
  1153. result = isc_commit_retaining(IB_STATUS, &trans->handle);
  1154. break;
  1155. }
  1156. if (result) {
  1157. _php_ibase_error(TSRMLS_C);
  1158. RETURN_FALSE;
  1159. }
  1160. /* Don't try to destroy implicitly opened transaction from list... */
  1161. if ((commit & RETAIN) == 0 && res_id != 0) {
  1162. zend_list_delete(res_id);
  1163. }
  1164. RETURN_TRUE;
  1165. }
  1166. /* }}} */
  1167. /* {{{ proto bool ibase_commit( resource link_identifier )
  1168. Commit transaction */
  1169. PHP_FUNCTION(ibase_commit)
  1170. {
  1171. _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT);
  1172. }
  1173. /* }}} */
  1174. /* {{{ proto bool ibase_rollback( resource link_identifier )
  1175. Rollback transaction */
  1176. PHP_FUNCTION(ibase_rollback)
  1177. {
  1178. _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK);
  1179. }
  1180. /* }}} */
  1181. /* {{{ proto bool ibase_commit_ret( resource link_identifier )
  1182. Commit transaction and retain the transaction context */
  1183. PHP_FUNCTION(ibase_commit_ret)
  1184. {
  1185. _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT | RETAIN);
  1186. }
  1187. /* }}} */
  1188. /* {{{ proto bool ibase_rollback_ret( resource link_identifier )
  1189. Rollback transaction and retain the transaction context */
  1190. PHP_FUNCTION(ibase_rollback_ret)
  1191. {
  1192. _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK | RETAIN);
  1193. }
  1194. /* }}} */
  1195. /* {{{ proto int ibase_gen_id(string generator [, int increment [, resource link_identifier ]])
  1196. Increments the named generator and returns its new value */
  1197. PHP_FUNCTION(ibase_gen_id)
  1198. {
  1199. zval *link = NULL;
  1200. char query[128], *generator;
  1201. int gen_len;
  1202. long inc = 1;
  1203. ibase_db_link *ib_link;
  1204. ibase_trans *trans = NULL;
  1205. XSQLDA out_sqlda;
  1206. ISC_INT64 result;
  1207. RESET_ERRMSG;
  1208. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &generator, &gen_len,
  1209. &inc, &link)) {
  1210. RETURN_FALSE;
  1211. }
  1212. if (gen_len > 31) {
  1213. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid generator name");
  1214. RETURN_FALSE;
  1215. }
  1216. PHP_IBASE_LINK_TRANS(link, ib_link, trans);
  1217. snprintf(query, sizeof(query), "SELECT GEN_ID(%s,%ld) FROM rdb$database", generator, inc);
  1218. /* allocate a minimal descriptor area */
  1219. out_sqlda.sqln = out_sqlda.sqld = 1;
  1220. out_sqlda.version = SQLDA_CURRENT_VERSION;
  1221. /* allocate the field for the result */
  1222. out_sqlda.sqlvar[0].sqltype = SQL_INT64;
  1223. out_sqlda.sqlvar[0].sqlscale = 0;
  1224. out_sqlda.sqlvar[0].sqllen = sizeof(result);
  1225. out_sqlda.sqlvar[0].sqldata = (void*) &result;
  1226. /* execute the query */
  1227. if (isc_dsql_exec_immed2(IB_STATUS, &ib_link->handle, &trans->handle, 0, query,
  1228. SQL_DIALECT_CURRENT, NULL, &out_sqlda)) {
  1229. _php_ibase_error(TSRMLS_C);
  1230. RETURN_FALSE;
  1231. }
  1232. /* don't return the generator value as a string unless it doesn't fit in a long */
  1233. #if SIZEOF_LONG < 8
  1234. if (result < LONG_MIN || result > LONG_MAX) {
  1235. char *res;
  1236. int l;
  1237. l = spprintf(&res, 0, "%" LL_MASK "d", result);
  1238. RETURN_STRINGL(res, l, 0);
  1239. }
  1240. #endif
  1241. RETURN_LONG((long)result);
  1242. }
  1243. /* }}} */
  1244. #endif /* HAVE_IBASE */
  1245. /*
  1246. * Local variables:
  1247. * tab-width: 4
  1248. * c-basic-offset: 4
  1249. * End:
  1250. * vim600: sw=4 ts=4 fdm=marker
  1251. * vim<600: sw=4 ts=4
  1252. */