PageRenderTime 73ms CodeModel.GetById 30ms RepoModel.GetById 2ms app.codeStats 1ms

/ext/pgsql/pgsql.c

http://github.com/infusion/PHP
C | 6330 lines | 5037 code | 741 blank | 552 comment | 1239 complexity | a99ae90c7c8f1934bda9e456bfaa4fab MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2011 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: Zeev Suraski <zeev@zend.com> |
  16. | Jouni Ahto <jouni.ahto@exdec.fi> |
  17. | Yasuo Ohgaki <yohgaki@php.net> |
  18. | Youichi Iwakiri <yiwakiri@st.rim.or.jp> (pg_copy_*) |
  19. | Chris Kings-Lynne <chriskl@php.net> (v3 protocol) |
  20. +----------------------------------------------------------------------+
  21. */
  22. /* $Id: pgsql.c 306939 2011-01-01 02:19:59Z felipe $ */
  23. #include <stdlib.h>
  24. #define PHP_PGSQL_PRIVATE 1
  25. #ifdef HAVE_CONFIG_H
  26. #include "config.h"
  27. #endif
  28. #define SMART_STR_PREALLOC 512
  29. #include "php.h"
  30. #include "php_ini.h"
  31. #include "ext/standard/php_standard.h"
  32. #include "ext/standard/php_smart_str.h"
  33. #include "ext/ereg/php_regex.h"
  34. #undef PACKAGE_BUGREPORT
  35. #undef PACKAGE_NAME
  36. #undef PACKAGE_STRING
  37. #undef PACKAGE_TARNAME
  38. #undef PACKAGE_VERSION
  39. #include "php_pgsql.h"
  40. #include "php_globals.h"
  41. #include "zend_exceptions.h"
  42. #if HAVE_PGSQL
  43. #ifndef InvalidOid
  44. #define InvalidOid ((Oid) 0)
  45. #endif
  46. #define PGSQL_ASSOC 1<<0
  47. #define PGSQL_NUM 1<<1
  48. #define PGSQL_BOTH (PGSQL_ASSOC|PGSQL_NUM)
  49. #define PGSQL_STATUS_LONG 1
  50. #define PGSQL_STATUS_STRING 2
  51. #define PGSQL_MAX_LENGTH_OF_LONG 30
  52. #define PGSQL_MAX_LENGTH_OF_DOUBLE 60
  53. #define PGSQL_RETURN_OID(oid) do { \
  54. if (oid > LONG_MAX) { \
  55. smart_str s = {0}; \
  56. smart_str_append_unsigned(&s, oid); \
  57. smart_str_0(&s); \
  58. RETURN_STRINGL(s.c, s.len, 0); \
  59. } \
  60. RETURN_LONG((long)oid); \
  61. } while(0)
  62. #if HAVE_PQSETNONBLOCKING
  63. #define PQ_SETNONBLOCKING(pg_link, flag) PQsetnonblocking(pg_link, flag)
  64. #else
  65. #define PQ_SETNONBLOCKING(pg_link, flag) 0
  66. #endif
  67. #define CHECK_DEFAULT_LINK(x) if ((x) == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No PostgreSQL link opened yet"); }
  68. #ifndef HAVE_PQFREEMEM
  69. #define PQfreemem free
  70. #endif
  71. ZEND_DECLARE_MODULE_GLOBALS(pgsql)
  72. static PHP_GINIT_FUNCTION(pgsql);
  73. /* {{{ arginfo */
  74. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1)
  75. ZEND_ARG_INFO(0, connection_string)
  76. ZEND_ARG_INFO(0, connect_type)
  77. ZEND_ARG_INFO(0, host)
  78. ZEND_ARG_INFO(0, port)
  79. ZEND_ARG_INFO(0, options)
  80. ZEND_ARG_INFO(0, tty)
  81. ZEND_ARG_INFO(0, database)
  82. ZEND_END_ARG_INFO()
  83. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_pconnect, 0, 0, 1)
  84. ZEND_ARG_INFO(0, connection_string)
  85. ZEND_ARG_INFO(0, host)
  86. ZEND_ARG_INFO(0, port)
  87. ZEND_ARG_INFO(0, options)
  88. ZEND_ARG_INFO(0, tty)
  89. ZEND_ARG_INFO(0, database)
  90. ZEND_END_ARG_INFO()
  91. #if HAVE_PQPARAMETERSTATUS
  92. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_parameter_status, 0, 0, 1)
  93. ZEND_ARG_INFO(0, connection)
  94. ZEND_ARG_INFO(0, param_name)
  95. ZEND_END_ARG_INFO()
  96. #endif
  97. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_close, 0, 0, 0)
  98. ZEND_ARG_INFO(0, connection)
  99. ZEND_END_ARG_INFO()
  100. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_dbname, 0, 0, 0)
  101. ZEND_ARG_INFO(0, connection)
  102. ZEND_END_ARG_INFO()
  103. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_error, 0, 0, 0)
  104. ZEND_ARG_INFO(0, connection)
  105. ZEND_END_ARG_INFO()
  106. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_options, 0, 0, 0)
  107. ZEND_ARG_INFO(0, connection)
  108. ZEND_END_ARG_INFO()
  109. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_port, 0, 0, 0)
  110. ZEND_ARG_INFO(0, connection)
  111. ZEND_END_ARG_INFO()
  112. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_tty, 0, 0, 0)
  113. ZEND_ARG_INFO(0, connection)
  114. ZEND_END_ARG_INFO()
  115. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_host, 0, 0, 0)
  116. ZEND_ARG_INFO(0, connection)
  117. ZEND_END_ARG_INFO()
  118. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_version, 0, 0, 0)
  119. ZEND_ARG_INFO(0, connection)
  120. ZEND_END_ARG_INFO()
  121. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_ping, 0, 0, 0)
  122. ZEND_ARG_INFO(0, connection)
  123. ZEND_END_ARG_INFO()
  124. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query, 0, 0, 0)
  125. ZEND_ARG_INFO(0, connection)
  126. ZEND_ARG_INFO(0, query)
  127. ZEND_END_ARG_INFO()
  128. #if HAVE_PQEXECPARAMS
  129. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query_params, 0, 0, 0)
  130. ZEND_ARG_INFO(0, connection)
  131. ZEND_ARG_INFO(0, query)
  132. ZEND_ARG_INFO(0, params)
  133. ZEND_END_ARG_INFO()
  134. #endif
  135. #if HAVE_PQPREPARE
  136. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_prepare, 0, 0, 0)
  137. ZEND_ARG_INFO(0, connection)
  138. ZEND_ARG_INFO(0, stmtname)
  139. ZEND_ARG_INFO(0, query)
  140. ZEND_END_ARG_INFO()
  141. #endif
  142. #if HAVE_PQEXECPREPARED
  143. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_execute, 0, 0, 0)
  144. ZEND_ARG_INFO(0, connection)
  145. ZEND_ARG_INFO(0, stmtname)
  146. ZEND_ARG_INFO(0, params)
  147. ZEND_END_ARG_INFO()
  148. #endif
  149. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_num_rows, 0, 0, 1)
  150. ZEND_ARG_INFO(0, result)
  151. ZEND_END_ARG_INFO()
  152. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_num_fields, 0, 0, 1)
  153. ZEND_ARG_INFO(0, result)
  154. ZEND_END_ARG_INFO()
  155. #if HAVE_PQCMDTUPLES
  156. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_affected_rows, 0, 0, 1)
  157. ZEND_ARG_INFO(0, result)
  158. ZEND_END_ARG_INFO()
  159. #endif
  160. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_notice, 0, 0, 1)
  161. ZEND_ARG_INFO(0, connection)
  162. ZEND_END_ARG_INFO()
  163. #ifdef HAVE_PQFTABLE
  164. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_table, 0, 0, 2)
  165. ZEND_ARG_INFO(0, result)
  166. ZEND_ARG_INFO(0, field_number)
  167. ZEND_ARG_INFO(0, oid_only)
  168. ZEND_END_ARG_INFO()
  169. #endif
  170. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_name, 0, 0, 2)
  171. ZEND_ARG_INFO(0, result)
  172. ZEND_ARG_INFO(0, field_number)
  173. ZEND_END_ARG_INFO()
  174. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_size, 0, 0, 2)
  175. ZEND_ARG_INFO(0, result)
  176. ZEND_ARG_INFO(0, field_number)
  177. ZEND_END_ARG_INFO()
  178. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_type, 0, 0, 2)
  179. ZEND_ARG_INFO(0, result)
  180. ZEND_ARG_INFO(0, field_number)
  181. ZEND_END_ARG_INFO()
  182. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_type_oid, 0, 0, 2)
  183. ZEND_ARG_INFO(0, result)
  184. ZEND_ARG_INFO(0, field_number)
  185. ZEND_END_ARG_INFO()
  186. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_num, 0, 0, 2)
  187. ZEND_ARG_INFO(0, result)
  188. ZEND_ARG_INFO(0, field_name)
  189. ZEND_END_ARG_INFO()
  190. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_result, 0, 0, 1)
  191. ZEND_ARG_INFO(0, result)
  192. ZEND_ARG_INFO(0, row_number)
  193. ZEND_ARG_INFO(0, field_name)
  194. ZEND_END_ARG_INFO()
  195. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_row, 0, 0, 1)
  196. ZEND_ARG_INFO(0, result)
  197. ZEND_ARG_INFO(0, row)
  198. ZEND_ARG_INFO(0, result_type)
  199. ZEND_END_ARG_INFO()
  200. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_assoc, 0, 0, 1)
  201. ZEND_ARG_INFO(0, result)
  202. ZEND_ARG_INFO(0, row)
  203. ZEND_END_ARG_INFO()
  204. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_array, 0, 0, 1)
  205. ZEND_ARG_INFO(0, result)
  206. ZEND_ARG_INFO(0, row)
  207. ZEND_ARG_INFO(0, result_type)
  208. ZEND_END_ARG_INFO()
  209. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_object, 0, 0, 1)
  210. ZEND_ARG_INFO(0, result)
  211. ZEND_ARG_INFO(0, row)
  212. ZEND_ARG_INFO(0, class_name)
  213. ZEND_ARG_INFO(0, l)
  214. ZEND_ARG_INFO(0, ctor_params)
  215. ZEND_END_ARG_INFO()
  216. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 1)
  217. ZEND_ARG_INFO(0, result)
  218. ZEND_END_ARG_INFO()
  219. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all_columns, 0, 0, 1)
  220. ZEND_ARG_INFO(0, result)
  221. ZEND_ARG_INFO(0, column_number)
  222. ZEND_END_ARG_INFO()
  223. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_seek, 0, 0, 2)
  224. ZEND_ARG_INFO(0, result)
  225. ZEND_ARG_INFO(0, offset)
  226. ZEND_END_ARG_INFO()
  227. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_prtlen, 0, 0, 1)
  228. ZEND_ARG_INFO(0, result)
  229. ZEND_ARG_INFO(0, row)
  230. ZEND_ARG_INFO(0, field_name_or_number)
  231. ZEND_END_ARG_INFO()
  232. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_is_null, 0, 0, 1)
  233. ZEND_ARG_INFO(0, result)
  234. ZEND_ARG_INFO(0, row)
  235. ZEND_ARG_INFO(0, field_name_or_number)
  236. ZEND_END_ARG_INFO()
  237. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_free_result, 0, 0, 1)
  238. ZEND_ARG_INFO(0, result)
  239. ZEND_END_ARG_INFO()
  240. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_oid, 0, 0, 1)
  241. ZEND_ARG_INFO(0, result)
  242. ZEND_END_ARG_INFO()
  243. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_trace, 0, 0, 1)
  244. ZEND_ARG_INFO(0, filename)
  245. ZEND_ARG_INFO(0, mode)
  246. ZEND_ARG_INFO(0, connection)
  247. ZEND_END_ARG_INFO()
  248. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_untrace, 0, 0, 0)
  249. ZEND_ARG_INFO(0, connection)
  250. ZEND_END_ARG_INFO()
  251. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_create, 0, 0, 0)
  252. ZEND_ARG_INFO(0, connection)
  253. ZEND_ARG_INFO(0, large_object_id)
  254. ZEND_END_ARG_INFO()
  255. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_unlink, 0, 0, 0)
  256. ZEND_ARG_INFO(0, connection)
  257. ZEND_ARG_INFO(0, large_object_oid)
  258. ZEND_END_ARG_INFO()
  259. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_open, 0, 0, 0)
  260. ZEND_ARG_INFO(0, connection)
  261. ZEND_ARG_INFO(0, large_object_oid)
  262. ZEND_ARG_INFO(0, mode)
  263. ZEND_END_ARG_INFO()
  264. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_close, 0, 0, 1)
  265. ZEND_ARG_INFO(0, large_object)
  266. ZEND_END_ARG_INFO()
  267. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_read, 0, 0, 1)
  268. ZEND_ARG_INFO(0, large_object)
  269. ZEND_ARG_INFO(0, len)
  270. ZEND_END_ARG_INFO()
  271. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_write, 0, 0, 2)
  272. ZEND_ARG_INFO(0, large_object)
  273. ZEND_ARG_INFO(0, buf)
  274. ZEND_ARG_INFO(0, len)
  275. ZEND_END_ARG_INFO()
  276. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_read_all, 0, 0, 1)
  277. ZEND_ARG_INFO(0, large_object)
  278. ZEND_END_ARG_INFO()
  279. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_import, 0, 0, 0)
  280. ZEND_ARG_INFO(0, connection)
  281. ZEND_ARG_INFO(0, filename)
  282. ZEND_ARG_INFO(0, large_object_oid)
  283. ZEND_END_ARG_INFO()
  284. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_export, 0, 0, 0)
  285. ZEND_ARG_INFO(0, connection)
  286. ZEND_ARG_INFO(0, objoid)
  287. ZEND_ARG_INFO(0, filename)
  288. ZEND_END_ARG_INFO()
  289. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_seek, 0, 0, 2)
  290. ZEND_ARG_INFO(0, large_object)
  291. ZEND_ARG_INFO(0, offset)
  292. ZEND_ARG_INFO(0, whence)
  293. ZEND_END_ARG_INFO()
  294. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_tell, 0, 0, 1)
  295. ZEND_ARG_INFO(0, large_object)
  296. ZEND_END_ARG_INFO()
  297. #if HAVE_PQSETERRORVERBOSITY
  298. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_error_verbosity, 0, 0, 0)
  299. ZEND_ARG_INFO(0, connection)
  300. ZEND_ARG_INFO(0, verbosity)
  301. ZEND_END_ARG_INFO()
  302. #endif
  303. #if HAVE_PQCLIENTENCODING
  304. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_client_encoding, 0, 0, 0)
  305. ZEND_ARG_INFO(0, connection)
  306. ZEND_ARG_INFO(0, encoding)
  307. ZEND_END_ARG_INFO()
  308. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_client_encoding, 0, 0, 0)
  309. ZEND_ARG_INFO(0, connection)
  310. ZEND_END_ARG_INFO()
  311. #endif
  312. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_end_copy, 0, 0, 0)
  313. ZEND_ARG_INFO(0, connection)
  314. ZEND_END_ARG_INFO()
  315. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_put_line, 0, 0, 0)
  316. ZEND_ARG_INFO(0, connection)
  317. ZEND_ARG_INFO(0, query)
  318. ZEND_END_ARG_INFO()
  319. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_copy_to, 0, 0, 2)
  320. ZEND_ARG_INFO(0, connection)
  321. ZEND_ARG_INFO(0, table_name)
  322. ZEND_ARG_INFO(0, delimiter)
  323. ZEND_ARG_INFO(0, null_as)
  324. ZEND_END_ARG_INFO()
  325. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_copy_from, 0, 0, 3)
  326. ZEND_ARG_INFO(0, connection)
  327. ZEND_ARG_INFO(0, table_name)
  328. ZEND_ARG_INFO(0, rows)
  329. ZEND_ARG_INFO(0, delimiter)
  330. ZEND_ARG_INFO(0, null_as)
  331. ZEND_END_ARG_INFO()
  332. #if HAVE_PQESCAPE
  333. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_string, 0, 0, 0)
  334. ZEND_ARG_INFO(0, connection)
  335. ZEND_ARG_INFO(0, data)
  336. ZEND_END_ARG_INFO()
  337. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_bytea, 0, 0, 0)
  338. ZEND_ARG_INFO(0, connection)
  339. ZEND_ARG_INFO(0, data)
  340. ZEND_END_ARG_INFO()
  341. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_unescape_bytea, 0, 0, 1)
  342. ZEND_ARG_INFO(0, data)
  343. ZEND_END_ARG_INFO()
  344. #endif
  345. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error, 0, 0, 1)
  346. ZEND_ARG_INFO(0, result)
  347. ZEND_END_ARG_INFO()
  348. #if HAVE_PQRESULTERRORFIELD
  349. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error_field, 0, 0, 2)
  350. ZEND_ARG_INFO(0, result)
  351. ZEND_ARG_INFO(0, fieldcode)
  352. ZEND_END_ARG_INFO()
  353. #endif
  354. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_status, 0, 0, 1)
  355. ZEND_ARG_INFO(0, connection)
  356. ZEND_END_ARG_INFO()
  357. #if HAVE_PGTRANSACTIONSTATUS
  358. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_transaction_status, 0, 0, 1)
  359. ZEND_ARG_INFO(0, connection)
  360. ZEND_END_ARG_INFO()
  361. #endif
  362. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_reset, 0, 0, 1)
  363. ZEND_ARG_INFO(0, connection)
  364. ZEND_END_ARG_INFO()
  365. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_cancel_query, 0, 0, 1)
  366. ZEND_ARG_INFO(0, connection)
  367. ZEND_END_ARG_INFO()
  368. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_busy, 0, 0, 1)
  369. ZEND_ARG_INFO(0, connection)
  370. ZEND_END_ARG_INFO()
  371. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_query, 0, 0, 2)
  372. ZEND_ARG_INFO(0, connection)
  373. ZEND_ARG_INFO(0, query)
  374. ZEND_END_ARG_INFO()
  375. #if HAVE_PQSENDQUERYPARAMS
  376. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_query_params, 0, 0, 3)
  377. ZEND_ARG_INFO(0, connection)
  378. ZEND_ARG_INFO(0, query)
  379. ZEND_ARG_INFO(0, params)
  380. ZEND_END_ARG_INFO()
  381. #endif
  382. #if HAVE_PQSENDPREPARE
  383. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_prepare, 0, 0, 3)
  384. ZEND_ARG_INFO(0, connection)
  385. ZEND_ARG_INFO(0, stmtname)
  386. ZEND_ARG_INFO(0, query)
  387. ZEND_END_ARG_INFO()
  388. #endif
  389. #if HAVE_PQSENDQUERYPREPARED
  390. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_execute, 0, 0, 3)
  391. ZEND_ARG_INFO(0, connection)
  392. ZEND_ARG_INFO(0, stmtname)
  393. ZEND_ARG_INFO(0, params)
  394. ZEND_END_ARG_INFO()
  395. #endif
  396. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_result, 0, 0, 1)
  397. ZEND_ARG_INFO(0, connection)
  398. ZEND_END_ARG_INFO()
  399. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_status, 0, 0, 1)
  400. ZEND_ARG_INFO(0, result)
  401. ZEND_ARG_INFO(0, result_type)
  402. ZEND_END_ARG_INFO()
  403. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_notify, 0, 0, 0)
  404. ZEND_ARG_INFO(0, connection)
  405. ZEND_ARG_INFO(0, e)
  406. ZEND_END_ARG_INFO()
  407. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_pid, 0, 0, 0)
  408. ZEND_ARG_INFO(0, connection)
  409. ZEND_END_ARG_INFO()
  410. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_meta_data, 0, 0, 2)
  411. ZEND_ARG_INFO(0, db)
  412. ZEND_ARG_INFO(0, table)
  413. ZEND_END_ARG_INFO()
  414. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_convert, 0, 0, 3)
  415. ZEND_ARG_INFO(0, db)
  416. ZEND_ARG_INFO(0, table)
  417. ZEND_ARG_INFO(0, values)
  418. ZEND_ARG_INFO(0, options)
  419. ZEND_END_ARG_INFO()
  420. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_insert, 0, 0, 3)
  421. ZEND_ARG_INFO(0, db)
  422. ZEND_ARG_INFO(0, table)
  423. ZEND_ARG_INFO(0, values)
  424. ZEND_ARG_INFO(0, options)
  425. ZEND_END_ARG_INFO()
  426. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_update, 0, 0, 4)
  427. ZEND_ARG_INFO(0, db)
  428. ZEND_ARG_INFO(0, table)
  429. ZEND_ARG_INFO(0, fields)
  430. ZEND_ARG_INFO(0, ids)
  431. ZEND_ARG_INFO(0, options)
  432. ZEND_END_ARG_INFO()
  433. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_delete, 0, 0, 3)
  434. ZEND_ARG_INFO(0, db)
  435. ZEND_ARG_INFO(0, table)
  436. ZEND_ARG_INFO(0, ids)
  437. ZEND_ARG_INFO(0, options)
  438. ZEND_END_ARG_INFO()
  439. ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_select, 0, 0, 3)
  440. ZEND_ARG_INFO(0, db)
  441. ZEND_ARG_INFO(0, table)
  442. ZEND_ARG_INFO(0, ids)
  443. ZEND_ARG_INFO(0, options)
  444. ZEND_END_ARG_INFO()
  445. /* }}} */
  446. /* {{{ pgsql_functions[]
  447. */
  448. const zend_function_entry pgsql_functions[] = {
  449. /* connection functions */
  450. PHP_FE(pg_connect, arginfo_pg_connect)
  451. PHP_FE(pg_pconnect, arginfo_pg_pconnect)
  452. PHP_FE(pg_close, arginfo_pg_close)
  453. PHP_FE(pg_connection_status, arginfo_pg_connection_status)
  454. PHP_FE(pg_connection_busy, arginfo_pg_connection_busy)
  455. PHP_FE(pg_connection_reset, arginfo_pg_connection_reset)
  456. PHP_FE(pg_host, arginfo_pg_host)
  457. PHP_FE(pg_dbname, arginfo_pg_dbname)
  458. PHP_FE(pg_port, arginfo_pg_port)
  459. PHP_FE(pg_tty, arginfo_pg_tty)
  460. PHP_FE(pg_options, arginfo_pg_options)
  461. PHP_FE(pg_version, arginfo_pg_version)
  462. PHP_FE(pg_ping, arginfo_pg_ping)
  463. #if HAVE_PQPARAMETERSTATUS
  464. PHP_FE(pg_parameter_status, arginfo_pg_parameter_status)
  465. #endif
  466. #if HAVE_PGTRANSACTIONSTATUS
  467. PHP_FE(pg_transaction_status, arginfo_pg_transaction_status)
  468. #endif
  469. /* query functions */
  470. PHP_FE(pg_query, arginfo_pg_query)
  471. #if HAVE_PQEXECPARAMS
  472. PHP_FE(pg_query_params, arginfo_pg_query_params)
  473. #endif
  474. #if HAVE_PQPREPARE
  475. PHP_FE(pg_prepare, arginfo_pg_prepare)
  476. #endif
  477. #if HAVE_PQEXECPREPARED
  478. PHP_FE(pg_execute, arginfo_pg_execute)
  479. #endif
  480. PHP_FE(pg_send_query, arginfo_pg_send_query)
  481. #if HAVE_PQSENDQUERYPARAMS
  482. PHP_FE(pg_send_query_params, arginfo_pg_send_query_params)
  483. #endif
  484. #if HAVE_PQSENDPREPARE
  485. PHP_FE(pg_send_prepare, arginfo_pg_send_prepare)
  486. #endif
  487. #if HAVE_PQSENDQUERYPREPARED
  488. PHP_FE(pg_send_execute, arginfo_pg_send_execute)
  489. #endif
  490. PHP_FE(pg_cancel_query, arginfo_pg_cancel_query)
  491. /* result functions */
  492. PHP_FE(pg_fetch_result, arginfo_pg_fetch_result)
  493. PHP_FE(pg_fetch_row, arginfo_pg_fetch_row)
  494. PHP_FE(pg_fetch_assoc, arginfo_pg_fetch_assoc)
  495. PHP_FE(pg_fetch_array, arginfo_pg_fetch_array)
  496. PHP_FE(pg_fetch_object, arginfo_pg_fetch_object)
  497. PHP_FE(pg_fetch_all, arginfo_pg_fetch_all)
  498. PHP_FE(pg_fetch_all_columns, arginfo_pg_fetch_all_columns)
  499. #if HAVE_PQCMDTUPLES
  500. PHP_FE(pg_affected_rows,arginfo_pg_affected_rows)
  501. #endif
  502. PHP_FE(pg_get_result, arginfo_pg_get_result)
  503. PHP_FE(pg_result_seek, arginfo_pg_result_seek)
  504. PHP_FE(pg_result_status,arginfo_pg_result_status)
  505. PHP_FE(pg_free_result, arginfo_pg_free_result)
  506. PHP_FE(pg_last_oid, arginfo_pg_last_oid)
  507. PHP_FE(pg_num_rows, arginfo_pg_num_rows)
  508. PHP_FE(pg_num_fields, arginfo_pg_num_fields)
  509. PHP_FE(pg_field_name, arginfo_pg_field_name)
  510. PHP_FE(pg_field_num, arginfo_pg_field_num)
  511. PHP_FE(pg_field_size, arginfo_pg_field_size)
  512. PHP_FE(pg_field_type, arginfo_pg_field_type)
  513. PHP_FE(pg_field_type_oid, arginfo_pg_field_type_oid)
  514. PHP_FE(pg_field_prtlen, arginfo_pg_field_prtlen)
  515. PHP_FE(pg_field_is_null,arginfo_pg_field_is_null)
  516. #ifdef HAVE_PQFTABLE
  517. PHP_FE(pg_field_table, arginfo_pg_field_table)
  518. #endif
  519. /* async message function */
  520. PHP_FE(pg_get_notify, arginfo_pg_get_notify)
  521. PHP_FE(pg_get_pid, arginfo_pg_get_pid)
  522. /* error message functions */
  523. PHP_FE(pg_result_error, arginfo_pg_result_error)
  524. #if HAVE_PQRESULTERRORFIELD
  525. PHP_FE(pg_result_error_field, arginfo_pg_result_error_field)
  526. #endif
  527. PHP_FE(pg_last_error, arginfo_pg_last_error)
  528. PHP_FE(pg_last_notice, arginfo_pg_last_notice)
  529. /* copy functions */
  530. PHP_FE(pg_put_line, arginfo_pg_put_line)
  531. PHP_FE(pg_end_copy, arginfo_pg_end_copy)
  532. PHP_FE(pg_copy_to, arginfo_pg_copy_to)
  533. PHP_FE(pg_copy_from, arginfo_pg_copy_from)
  534. /* debug functions */
  535. PHP_FE(pg_trace, arginfo_pg_trace)
  536. PHP_FE(pg_untrace, arginfo_pg_untrace)
  537. /* large object functions */
  538. PHP_FE(pg_lo_create, arginfo_pg_lo_create)
  539. PHP_FE(pg_lo_unlink, arginfo_pg_lo_unlink)
  540. PHP_FE(pg_lo_open, arginfo_pg_lo_open)
  541. PHP_FE(pg_lo_close, arginfo_pg_lo_close)
  542. PHP_FE(pg_lo_read, arginfo_pg_lo_read)
  543. PHP_FE(pg_lo_write, arginfo_pg_lo_write)
  544. PHP_FE(pg_lo_read_all, arginfo_pg_lo_read_all)
  545. PHP_FE(pg_lo_import, arginfo_pg_lo_import)
  546. PHP_FE(pg_lo_export, arginfo_pg_lo_export)
  547. PHP_FE(pg_lo_seek, arginfo_pg_lo_seek)
  548. PHP_FE(pg_lo_tell, arginfo_pg_lo_tell)
  549. /* utility functions */
  550. #if HAVE_PQESCAPE
  551. PHP_FE(pg_escape_string, arginfo_pg_escape_string)
  552. PHP_FE(pg_escape_bytea, arginfo_pg_escape_bytea)
  553. PHP_FE(pg_unescape_bytea, arginfo_pg_unescape_bytea)
  554. #endif
  555. #if HAVE_PQSETERRORVERBOSITY
  556. PHP_FE(pg_set_error_verbosity, arginfo_pg_set_error_verbosity)
  557. #endif
  558. #if HAVE_PQCLIENTENCODING
  559. PHP_FE(pg_client_encoding, arginfo_pg_client_encoding)
  560. PHP_FE(pg_set_client_encoding, arginfo_pg_set_client_encoding)
  561. #endif
  562. /* misc function */
  563. PHP_FE(pg_meta_data, arginfo_pg_meta_data)
  564. PHP_FE(pg_convert, arginfo_pg_convert)
  565. PHP_FE(pg_insert, arginfo_pg_insert)
  566. PHP_FE(pg_update, arginfo_pg_update)
  567. PHP_FE(pg_delete, arginfo_pg_delete)
  568. PHP_FE(pg_select, arginfo_pg_select)
  569. /* aliases for downwards compatibility */
  570. PHP_FALIAS(pg_exec, pg_query, arginfo_pg_query)
  571. PHP_FALIAS(pg_getlastoid, pg_last_oid, arginfo_pg_last_oid)
  572. #if HAVE_PQCMDTUPLES
  573. PHP_FALIAS(pg_cmdtuples, pg_affected_rows, arginfo_pg_affected_rows)
  574. #endif
  575. PHP_FALIAS(pg_errormessage, pg_last_error, arginfo_pg_last_error)
  576. PHP_FALIAS(pg_numrows, pg_num_rows, arginfo_pg_num_rows)
  577. PHP_FALIAS(pg_numfields, pg_num_fields, arginfo_pg_num_fields)
  578. PHP_FALIAS(pg_fieldname, pg_field_name, arginfo_pg_field_name)
  579. PHP_FALIAS(pg_fieldsize, pg_field_size, arginfo_pg_field_size)
  580. PHP_FALIAS(pg_fieldtype, pg_field_type, arginfo_pg_field_type)
  581. PHP_FALIAS(pg_fieldnum, pg_field_num, arginfo_pg_field_num)
  582. PHP_FALIAS(pg_fieldprtlen, pg_field_prtlen, arginfo_pg_field_prtlen)
  583. PHP_FALIAS(pg_fieldisnull, pg_field_is_null, arginfo_pg_field_is_null)
  584. PHP_FALIAS(pg_freeresult, pg_free_result, arginfo_pg_free_result)
  585. PHP_FALIAS(pg_result, pg_fetch_result, arginfo_pg_get_result)
  586. PHP_FALIAS(pg_loreadall, pg_lo_read_all, arginfo_pg_lo_read_all)
  587. PHP_FALIAS(pg_locreate, pg_lo_create, arginfo_pg_lo_create)
  588. PHP_FALIAS(pg_lounlink, pg_lo_unlink, arginfo_pg_lo_unlink)
  589. PHP_FALIAS(pg_loopen, pg_lo_open, arginfo_pg_lo_open)
  590. PHP_FALIAS(pg_loclose, pg_lo_close, arginfo_pg_lo_close)
  591. PHP_FALIAS(pg_loread, pg_lo_read, arginfo_pg_lo_read)
  592. PHP_FALIAS(pg_lowrite, pg_lo_write, arginfo_pg_lo_write)
  593. PHP_FALIAS(pg_loimport, pg_lo_import, arginfo_pg_lo_import)
  594. PHP_FALIAS(pg_loexport, pg_lo_export, arginfo_pg_lo_export)
  595. #if HAVE_PQCLIENTENCODING
  596. PHP_FALIAS(pg_clientencoding, pg_client_encoding, arginfo_pg_client_encoding)
  597. PHP_FALIAS(pg_setclientencoding, pg_set_client_encoding, arginfo_pg_set_client_encoding)
  598. #endif
  599. {NULL, NULL, NULL}
  600. };
  601. /* }}} */
  602. /* {{{ pgsql_module_entry
  603. */
  604. zend_module_entry pgsql_module_entry = {
  605. STANDARD_MODULE_HEADER,
  606. "pgsql",
  607. pgsql_functions,
  608. PHP_MINIT(pgsql),
  609. PHP_MSHUTDOWN(pgsql),
  610. PHP_RINIT(pgsql),
  611. PHP_RSHUTDOWN(pgsql),
  612. PHP_MINFO(pgsql),
  613. NO_VERSION_YET,
  614. PHP_MODULE_GLOBALS(pgsql),
  615. PHP_GINIT(pgsql),
  616. NULL,
  617. NULL,
  618. STANDARD_MODULE_PROPERTIES_EX
  619. };
  620. /* }}} */
  621. #ifdef COMPILE_DL_PGSQL
  622. ZEND_GET_MODULE(pgsql)
  623. #endif
  624. static int le_link, le_plink, le_result, le_lofp, le_string;
  625. /* {{{ _php_pgsql_trim_message */
  626. static char * _php_pgsql_trim_message(const char *message, int *len)
  627. {
  628. register int i = strlen(message)-1;
  629. if (i>1 && (message[i-1] == '\r' || message[i-1] == '\n') && message[i] == '.') {
  630. --i;
  631. }
  632. while (i>0 && (message[i] == '\r' || message[i] == '\n')) {
  633. --i;
  634. }
  635. ++i;
  636. if (len) {
  637. *len = i;
  638. }
  639. return estrndup(message, i);
  640. }
  641. /* }}} */
  642. /* {{{ _php_pgsql_trim_result */
  643. static inline char * _php_pgsql_trim_result(PGconn * pgsql, char **buf)
  644. {
  645. return *buf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
  646. }
  647. /* }}} */
  648. #define PQErrorMessageTrim(pgsql, buf) _php_pgsql_trim_result(pgsql, buf)
  649. #define PHP_PQ_ERROR(text, pgsql) { \
  650. char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \
  651. php_error_docref(NULL TSRMLS_CC, E_WARNING, text, msgbuf); \
  652. efree(msgbuf); \
  653. } \
  654. /* {{{ php_pgsql_set_default_link
  655. */
  656. static void php_pgsql_set_default_link(int id TSRMLS_DC)
  657. {
  658. zend_list_addref(id);
  659. if (PGG(default_link) != -1) {
  660. zend_list_delete(PGG(default_link));
  661. }
  662. PGG(default_link) = id;
  663. }
  664. /* }}} */
  665. /* {{{ _close_pgsql_link
  666. */
  667. static void _close_pgsql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  668. {
  669. PGconn *link = (PGconn *)rsrc->ptr;
  670. PGresult *res;
  671. while ((res = PQgetResult(link))) {
  672. PQclear(res);
  673. }
  674. PQfinish(link);
  675. PGG(num_links)--;
  676. }
  677. /* }}} */
  678. /* {{{ _close_pgsql_plink
  679. */
  680. static void _close_pgsql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  681. {
  682. PGconn *link = (PGconn *)rsrc->ptr;
  683. PGresult *res;
  684. while ((res = PQgetResult(link))) {
  685. PQclear(res);
  686. }
  687. PQfinish(link);
  688. PGG(num_persistent)--;
  689. PGG(num_links)--;
  690. }
  691. /* }}} */
  692. /* {{{ _php_pgsql_notice_handler
  693. */
  694. static void _php_pgsql_notice_handler(void *resource_id, const char *message)
  695. {
  696. php_pgsql_notice *notice;
  697. TSRMLS_FETCH();
  698. if (! PGG(ignore_notices)) {
  699. notice = (php_pgsql_notice *)emalloc(sizeof(php_pgsql_notice));
  700. notice->message = _php_pgsql_trim_message(message, &notice->len);
  701. if (PGG(log_notices)) {
  702. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", notice->message);
  703. }
  704. zend_hash_index_update(&PGG(notices), (ulong)resource_id, (void **)&notice, sizeof(php_pgsql_notice *), NULL);
  705. }
  706. }
  707. /* }}} */
  708. #define PHP_PGSQL_NOTICE_PTR_DTOR (void (*)(void *))_php_pgsql_notice_ptr_dtor
  709. /* {{{ _php_pgsql_notice_dtor
  710. */
  711. static void _php_pgsql_notice_ptr_dtor(void **ptr)
  712. {
  713. php_pgsql_notice *notice = (php_pgsql_notice *)*ptr;
  714. if (notice) {
  715. efree(notice->message);
  716. efree(notice);
  717. notice = NULL;
  718. }
  719. }
  720. /* }}} */
  721. /* {{{ _rollback_transactions
  722. */
  723. static int _rollback_transactions(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  724. {
  725. PGconn *link;
  726. PGresult *res;
  727. int orig;
  728. if (Z_TYPE_P(rsrc) != le_plink)
  729. return 0;
  730. link = (PGconn *) rsrc->ptr;
  731. if (PQ_SETNONBLOCKING(link, 0)) {
  732. php_error_docref("ref.pgsql" TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
  733. return -1;
  734. }
  735. while ((res = PQgetResult(link))) {
  736. PQclear(res);
  737. }
  738. #if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
  739. if ((PQprotocolVersion(link) >= 3 && PQtransactionStatus(link) != PQTRANS_IDLE) || PQprotocolVersion(link) < 3)
  740. #endif
  741. {
  742. orig = PGG(ignore_notices);
  743. PGG(ignore_notices) = 1;
  744. #if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
  745. res = PQexec(link,"ROLLBACK;");
  746. #else
  747. res = PQexec(link,"BEGIN;");
  748. PQclear(res);
  749. res = PQexec(link,"ROLLBACK;");
  750. #endif
  751. PQclear(res);
  752. PGG(ignore_notices) = orig;
  753. }
  754. return 0;
  755. }
  756. /* }}} */
  757. /* {{{ _free_ptr
  758. */
  759. static void _free_ptr(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  760. {
  761. pgLofp *lofp = (pgLofp *)rsrc->ptr;
  762. efree(lofp);
  763. }
  764. /* }}} */
  765. /* {{{ _free_result
  766. */
  767. static void _free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  768. {
  769. pgsql_result_handle *pg_result = (pgsql_result_handle *)rsrc->ptr;
  770. PQclear(pg_result->result);
  771. efree(pg_result);
  772. }
  773. /* }}} */
  774. /* {{{ PHP_INI
  775. */
  776. PHP_INI_BEGIN()
  777. STD_PHP_INI_BOOLEAN( "pgsql.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_persistent, zend_pgsql_globals, pgsql_globals)
  778. STD_PHP_INI_ENTRY_EX("pgsql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_pgsql_globals, pgsql_globals, display_link_numbers)
  779. STD_PHP_INI_ENTRY_EX("pgsql.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_pgsql_globals, pgsql_globals, display_link_numbers)
  780. STD_PHP_INI_BOOLEAN( "pgsql.auto_reset_persistent", "0", PHP_INI_SYSTEM, OnUpdateBool, auto_reset_persistent, zend_pgsql_globals, pgsql_globals)
  781. STD_PHP_INI_BOOLEAN( "pgsql.ignore_notice", "0", PHP_INI_ALL, OnUpdateBool, ignore_notices, zend_pgsql_globals, pgsql_globals)
  782. STD_PHP_INI_BOOLEAN( "pgsql.log_notice", "0", PHP_INI_ALL, OnUpdateBool, log_notices, zend_pgsql_globals, pgsql_globals)
  783. PHP_INI_END()
  784. /* }}} */
  785. /* {{{ PHP_GINIT_FUNCTION
  786. */
  787. static PHP_GINIT_FUNCTION(pgsql)
  788. {
  789. memset(pgsql_globals, 0, sizeof(zend_pgsql_globals));
  790. /* Initilize notice message hash at MINIT only */
  791. zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, PHP_PGSQL_NOTICE_PTR_DTOR, 1, 0);
  792. }
  793. /* }}} */
  794. /* {{{ PHP_MINIT_FUNCTION
  795. */
  796. PHP_MINIT_FUNCTION(pgsql)
  797. {
  798. REGISTER_INI_ENTRIES();
  799. le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number);
  800. le_plink = zend_register_list_destructors_ex(NULL, _close_pgsql_plink, "pgsql link persistent", module_number);
  801. le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number);
  802. le_lofp = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql large object", module_number);
  803. le_string = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql string", module_number);
  804. /* For connection option */
  805. REGISTER_LONG_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_CS | CONST_PERSISTENT);
  806. /* For pg_fetch_array() */
  807. REGISTER_LONG_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
  808. REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT);
  809. REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT);
  810. /* For pg_connection_status() */
  811. REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT);
  812. REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT);
  813. #if HAVE_PGTRANSACTIONSTATUS
  814. /* For pg_transaction_status() */
  815. REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_IDLE", PQTRANS_IDLE, CONST_CS | CONST_PERSISTENT);
  816. REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_ACTIVE", PQTRANS_ACTIVE, CONST_CS | CONST_PERSISTENT);
  817. REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INTRANS", PQTRANS_INTRANS, CONST_CS | CONST_PERSISTENT);
  818. REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INERROR", PQTRANS_INERROR, CONST_CS | CONST_PERSISTENT);
  819. REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_UNKNOWN", PQTRANS_UNKNOWN, CONST_CS | CONST_PERSISTENT);
  820. #endif
  821. #if HAVE_PQSETERRORVERBOSITY
  822. /* For pg_set_error_verbosity() */
  823. REGISTER_LONG_CONSTANT("PGSQL_ERRORS_TERSE", PQERRORS_TERSE, CONST_CS | CONST_PERSISTENT);
  824. REGISTER_LONG_CONSTANT("PGSQL_ERRORS_DEFAULT", PQERRORS_DEFAULT, CONST_CS | CONST_PERSISTENT);
  825. REGISTER_LONG_CONSTANT("PGSQL_ERRORS_VERBOSE", PQERRORS_VERBOSE, CONST_CS | CONST_PERSISTENT);
  826. #endif
  827. /* For lo_seek() */
  828. REGISTER_LONG_CONSTANT("PGSQL_SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
  829. REGISTER_LONG_CONSTANT("PGSQL_SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
  830. REGISTER_LONG_CONSTANT("PGSQL_SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
  831. /* For pg_result_status() return value type */
  832. REGISTER_LONG_CONSTANT("PGSQL_STATUS_LONG", PGSQL_STATUS_LONG, CONST_CS | CONST_PERSISTENT);
  833. REGISTER_LONG_CONSTANT("PGSQL_STATUS_STRING", PGSQL_STATUS_STRING, CONST_CS | CONST_PERSISTENT);
  834. /* For pg_result_status() return value */
  835. REGISTER_LONG_CONSTANT("PGSQL_EMPTY_QUERY", PGRES_EMPTY_QUERY, CONST_CS | CONST_PERSISTENT);
  836. REGISTER_LONG_CONSTANT("PGSQL_COMMAND_OK", PGRES_COMMAND_OK, CONST_CS | CONST_PERSISTENT);
  837. REGISTER_LONG_CONSTANT("PGSQL_TUPLES_OK", PGRES_TUPLES_OK, CONST_CS | CONST_PERSISTENT);
  838. REGISTER_LONG_CONSTANT("PGSQL_COPY_OUT", PGRES_COPY_OUT, CONST_CS | CONST_PERSISTENT);
  839. REGISTER_LONG_CONSTANT("PGSQL_COPY_IN", PGRES_COPY_IN, CONST_CS | CONST_PERSISTENT);
  840. REGISTER_LONG_CONSTANT("PGSQL_BAD_RESPONSE", PGRES_BAD_RESPONSE, CONST_CS | CONST_PERSISTENT);
  841. REGISTER_LONG_CONSTANT("PGSQL_NONFATAL_ERROR", PGRES_NONFATAL_ERROR, CONST_CS | CONST_PERSISTENT);
  842. REGISTER_LONG_CONSTANT("PGSQL_FATAL_ERROR", PGRES_FATAL_ERROR, CONST_CS | CONST_PERSISTENT);
  843. #if HAVE_PQRESULTERRORFIELD
  844. /* For pg_result_error_field() field codes */
  845. REGISTER_LONG_CONSTANT("PGSQL_DIAG_SEVERITY", PG_DIAG_SEVERITY, CONST_CS | CONST_PERSISTENT);
  846. REGISTER_LONG_CONSTANT("PGSQL_DIAG_SQLSTATE", PG_DIAG_SQLSTATE, CONST_CS | CONST_PERSISTENT);
  847. REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_PRIMARY", PG_DIAG_MESSAGE_PRIMARY, CONST_CS | CONST_PERSISTENT);
  848. REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_DETAIL", PG_DIAG_MESSAGE_DETAIL, CONST_CS | CONST_PERSISTENT);
  849. REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_HINT", PG_DIAG_MESSAGE_HINT, CONST_CS | CONST_PERSISTENT);
  850. REGISTER_LONG_CONSTANT("PGSQL_DIAG_STATEMENT_POSITION", PG_DIAG_STATEMENT_POSITION, CONST_CS | CONST_PERSISTENT);
  851. #ifdef PG_DIAG_INTERNAL_POSITION
  852. REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_POSITION", PG_DIAG_INTERNAL_POSITION, CONST_CS | CONST_PERSISTENT);
  853. #endif
  854. #ifdef PG_DIAG_INTERNAL_QUERY
  855. REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_QUERY", PG_DIAG_INTERNAL_QUERY, CONST_CS | CONST_PERSISTENT);
  856. #endif
  857. REGISTER_LONG_CONSTANT("PGSQL_DIAG_CONTEXT", PG_DIAG_CONTEXT, CONST_CS | CONST_PERSISTENT);
  858. REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FILE", PG_DIAG_SOURCE_FILE, CONST_CS | CONST_PERSISTENT);
  859. REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_LINE", PG_DIAG_SOURCE_LINE, CONST_CS | CONST_PERSISTENT);
  860. REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FUNCTION", PG_DIAG_SOURCE_FUNCTION, CONST_CS | CONST_PERSISTENT);
  861. #endif
  862. /* pg_convert options */
  863. REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_DEFAULT", PGSQL_CONV_IGNORE_DEFAULT, CONST_CS | CONST_PERSISTENT);
  864. REGISTER_LONG_CONSTANT("PGSQL_CONV_FORCE_NULL", PGSQL_CONV_FORCE_NULL, CONST_CS | CONST_PERSISTENT);
  865. REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_NOT_NULL", PGSQL_CONV_IGNORE_NOT_NULL, CONST_CS | CONST_PERSISTENT);
  866. /* pg_insert/update/delete/select options */
  867. REGISTER_LONG_CONSTANT("PGSQL_DML_NO_CONV", PGSQL_DML_NO_CONV, CONST_CS | CONST_PERSISTENT);
  868. REGISTER_LONG_CONSTANT("PGSQL_DML_EXEC", PGSQL_DML_EXEC, CONST_CS | CONST_PERSISTENT);
  869. REGISTER_LONG_CONSTANT("PGSQL_DML_ASYNC", PGSQL_DML_ASYNC, CONST_CS | CONST_PERSISTENT);
  870. REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT);
  871. return SUCCESS;
  872. }
  873. /* }}} */
  874. /* {{{ PHP_MSHUTDOWN_FUNCTION
  875. */
  876. PHP_MSHUTDOWN_FUNCTION(pgsql)
  877. {
  878. UNREGISTER_INI_ENTRIES();
  879. zend_hash_destroy(&PGG(notices));
  880. return SUCCESS;
  881. }
  882. /* }}} */
  883. /* {{{ PHP_RINIT_FUNCTION
  884. */
  885. PHP_RINIT_FUNCTION(pgsql)
  886. {
  887. PGG(default_link)=-1;
  888. PGG(num_links) = PGG(num_persistent);
  889. return SUCCESS;
  890. }
  891. /* }}} */
  892. /* {{{ PHP_RSHUTDOWN_FUNCTION
  893. */
  894. PHP_RSHUTDOWN_FUNCTION(pgsql)
  895. {
  896. /* clean up notice messages */
  897. zend_hash_clean(&PGG(notices));
  898. /* clean up persistent connection */
  899. zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions TSRMLS_CC);
  900. return SUCCESS;
  901. }
  902. /* }}} */
  903. /* {{{ PHP_MINFO_FUNCTION
  904. */
  905. PHP_MINFO_FUNCTION(pgsql)
  906. {
  907. char buf[256];
  908. php_info_print_table_start();
  909. php_info_print_table_header(2, "PostgreSQL Support", "enabled");
  910. #if HAVE_PG_CONFIG_H
  911. php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION);
  912. #ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
  913. php_info_print_table_row(2, "Multibyte character support", "enabled");
  914. #else
  915. php_info_print_table_row(2, "Multibyte character support", "disabled");
  916. #endif
  917. #ifdef USE_SSL
  918. php_info_print_table_row(2, "SSL support", "enabled");
  919. #else
  920. php_info_print_table_row(2, "SSL support", "disabled");
  921. #endif
  922. #endif /* HAVE_PG_CONFIG_H */
  923. snprintf(buf, sizeof(buf), "%ld", PGG(num_persistent));
  924. php_info_print_table_row(2, "Active Persistent Links", buf);
  925. snprintf(buf, sizeof(buf), "%ld", PGG(num_links));
  926. php_info_print_table_row(2, "Active Links", buf);
  927. php_info_print_table_end();
  928. DISPLAY_INI_ENTRIES();
  929. }
  930. /* }}} */
  931. /* {{{ php_pgsql_do_connect
  932. */
  933. static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
  934. {
  935. char *host=NULL,*port=NULL,*options=NULL,*tty=NULL,*dbname=NULL,*connstring=NULL;
  936. PGconn *pgsql;
  937. smart_str str = {0};
  938. zval **args[5];
  939. int i, connect_type = 0;
  940. PGresult *pg_result;
  941. if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 5
  942. || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
  943. WRONG_PARAM_COUNT;
  944. }
  945. smart_str_appends(&str, "pgsql");
  946. for (i = 0; i < ZEND_NUM_ARGS(); i++) {
  947. /* make sure that the PGSQL_CONNECT_FORCE_NEW bit is not part of the hash so that subsequent connections
  948. * can re-use this connection. Bug #39979
  949. */
  950. if (i == 1 && ZEND_NUM_ARGS() == 2 && Z_TYPE_PP(args[i]) == IS_LONG) {
  951. if (Z_LVAL_PP(args[1]) == PGSQL_CONNECT_FORCE_NEW) {
  952. continue;
  953. } else if (Z_LVAL_PP(args[1]) & PGSQL_CONNECT_FORCE_NEW) {
  954. smart_str_append_long(&str, Z_LVAL_PP(args[1]) ^ PGSQL_CONNECT_FORCE_NEW);
  955. }
  956. }
  957. convert_to_string_ex(args[i]);
  958. smart_str_appendc(&str, '_');
  959. smart_str_appendl(&str, Z_STRVAL_PP(args[i]), Z_STRLEN_PP(args[i]));
  960. }
  961. smart_str_0(&str);
  962. if (ZEND_NUM_ARGS() == 1) { /* new style, using connection string */
  963. connstring = Z_STRVAL_PP(args[0]);
  964. } else if (ZEND_NUM_ARGS() == 2 ) { /* Safe to add conntype_option, since 2 args was illegal */
  965. connstring = Z_STRVAL_PP(args[0]);
  966. convert_to_long_ex(args[1]);
  967. connect_type = Z_LVAL_PP(args[1]);
  968. } else {
  969. host = Z_STRVAL_PP(args[0]);
  970. port = Z_STRVAL_PP(args[1]);
  971. dbname = Z_STRVAL_PP(args[ZEND_NUM_ARGS()-1]);
  972. switch (ZEND_NUM_ARGS()) {
  973. case 5:
  974. tty = Z_STRVAL_PP(args[3]);
  975. /* fall through */
  976. case 4:
  977. options = Z_STRVAL_PP(args[2]);
  978. break;
  979. }
  980. }
  981. if (persistent && PGG(allow_persistent)) {
  982. zend_rsrc_list_entry *le;
  983. /* try to find if we already have this link in our persistent list */
  984. if (zend_hash_find(&EG(persistent_list), str.c, str.len+1, (void **) &le)==FAILURE) { /* we don't */
  985. zend_rsrc_list_entry new_le;
  986. if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) {
  987. php_error_docref(NULL TSRMLS_CC, E_WARNING,
  988. "Cannot create new link. Too many open links (%ld)", PGG(num_links));
  989. goto err;
  990. }
  991. if (PGG(max_persistent)!=-1 && PGG(num_persistent)>=PGG(max_persistent)) {
  992. php_error_docref(NULL TSRMLS_CC, E_WARNING,
  993. "Cannot create new link. Too many open persistent links (%ld)", PGG(num_persistent));
  994. goto err;
  995. }
  996. /* create the link */
  997. if (connstring) {
  998. pgsql=PQconnectdb(connstring);
  999. } else {
  1000. pgsql=PQsetdb(host,port,options,tty,dbname);
  1001. }
  1002. if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
  1003. PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql)
  1004. if (pgsql) {
  1005. PQfinish(pgsql);
  1006. }
  1007. goto err;
  1008. }
  1009. /* hash it up */
  1010. Z_TYPE(new_le) = le_plink;
  1011. new_le.ptr = pgsql;
  1012. if (zend_hash_update(&EG(persistent_list), str.c, str.len+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
  1013. goto err;
  1014. }
  1015. PGG(num_links)++;
  1016. PGG(num_persistent)++;
  1017. } else { /* we do */
  1018. if (Z_TYPE_P(le) != le_plink) {
  1019. RETURN_FALSE;
  1020. }
  1021. /* ensure that the link did not die */
  1022. if (PGG(auto_reset_persistent) & 1) {
  1023. /* need to send & get something from backend to
  1024. make sure we catch CONNECTION_BAD everytime */
  1025. PGresult *pg_result;
  1026. pg_result = PQexec(le->ptr, "select 1");
  1027. PQclear(pg_result);
  1028. }
  1029. if (PQstatus(le->ptr)==CONNECTION_BAD) { /* the link died */
  1030. if (le->ptr == NULL) {
  1031. if (connstring) {
  1032. le->ptr=PQconnectdb(connstring);
  1033. } else {
  1034. le->ptr=PQsetdb(host,port,options,tty,dbname);
  1035. }
  1036. }
  1037. else {
  1038. PQreset(le->ptr);
  1039. }
  1040. if (le->ptr==NULL || PQstatus(le->ptr)==CONNECTION_BAD) {
  1041. php_error_docref(NULL TSRMLS_CC, E_WARNING,"PostgreSQL link lost, unable to reconnect");
  1042. zend_hash_del(&EG(persistent_list),str.c,str.len+1);
  1043. goto err;
  1044. }
  1045. }
  1046. pgsql = (PGconn *) le->ptr;
  1047. #if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
  1048. if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 7.2) {
  1049. #else
  1050. if (atof(PG_VERSION) >= 7.2) {
  1051. #endif
  1052. pg_result = PQexec(pgsql, "RESET ALL;");
  1053. PQclear(pg_result);
  1054. }
  1055. }
  1056. ZEND_REGISTER_RESOURCE(return_value, pgsql, le_plink);
  1057. } else { /* Non persistent connection */
  1058. zend_rsrc_list_entry *index_ptr,new_index_ptr;
  1059. /* first we check the hash for the hashed_details key. if it exists,
  1060. * it should point us to the right offset where the actual pgsql link sits.
  1061. * if it doesn't, open a new pgsql link, add it to the resource list,
  1062. * and add a pointer to it with hashed_details as the key.
  1063. */
  1064. if (!(connect_type & PGSQL_CONNECT_FORCE_NEW)
  1065. && zend_hash_find(&EG(regular_list),str.c,str.len+1,(void **) &index_ptr)==SUCCESS) {
  1066. int type;
  1067. ulong link;
  1068. void *ptr;
  1069. if (Z_TYPE_P(index_ptr) != le_index_ptr) {
  1070. RETURN_FALSE;
  1071. }
  1072. link = (ulong) index_ptr->ptr;
  1073. ptr = zend_list_find(link,&type); /* check if the link is still there */
  1074. if (ptr && (type==le_link || type==le_plink)) {
  1075. Z_LVAL_P(return_value) = link;
  1076. zend_list_addref(link);
  1077. php_pgsql_set_default_link(link TSRMLS_CC);
  1078. Z_TYPE_P(return_value) = IS_RESOURCE;
  1079. goto cleanup;
  1080. } else {
  1081. zend_hash_del(&EG(regular_list),str.c,str.len+1);
  1082. }
  1083. }
  1084. if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) {
  1085. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", PGG(num_links));
  1086. goto err;
  1087. }
  1088. if (connstring) {
  1089. pgsql = PQconnectdb(connstring);
  1090. } else {
  1091. pgsql = PQsetdb(host,port,options,tty,dbname);
  1092. }
  1093. if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
  1094. PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql);
  1095. if (pgsql) {
  1096. PQfinish(pgsql);
  1097. }
  1098. goto err;
  1099. }
  1100. /* add it to the list */
  1101. ZEND_REGISTER_RESOURCE(return_value, pgsql, le_link);
  1102. /* add it to the hash */
  1103. new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
  1104. Z_TYPE(new_index_ptr) = le_index_ptr;
  1105. if (zend_hash_update(&EG(regular_list),str.c,str.len+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
  1106. goto err;
  1107. }
  1108. PGG(num_links)++;
  1109. }
  1110. /* set notice processer */
  1111. if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_RESOURCE) {
  1112. PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)Z_RESVAL_P(return_value));
  1113. }
  1114. php_pgsql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
  1115. cleanup:
  1116. smart_str_free(&str);
  1117. return;
  1118. err:
  1119. smart_str_free(&str);
  1120. RETURN_FALSE;
  1121. }
  1122. /* }}} */
  1123. #if 0
  1124. /* {{{ php_pgsql_get_default_link
  1125. */
  1126. static int php_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
  1127. {
  1128. if (PGG(default_link)==-1) { /* no link opened yet, implicitly open one */
  1129. ht = 0;
  1130. php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
  1131. }
  1132. return PGG(default_link);
  1133. }
  1134. /* }}} */
  1135. #endif
  1136. /* {{{ proto resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database)
  1137. Open a PostgreSQL connection */
  1138. PHP_FUNCTION(pg_connect)
  1139. {
  1140. php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
  1141. }
  1142. /* }}} */
  1143. /* {{{ proto resource pg_pconnect(string connection_string | [string host, string port [, string options [, string tty,]]] string database)
  1144. Open a persistent PostgreSQL connection */
  1145. PHP_FUNCTION(pg_pconnect)
  1146. {
  1147. php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
  1148. }
  1149. /* }}} */
  1150. /* {{{ proto bool pg_close([resource connection])
  1151. Close a PostgreSQL connection */
  1152. PHP_FUNCTION(pg_close)
  1153. {
  1154. zval *pgsql_link = NULL;
  1155. int id = -1, argc = ZEND_NUM_ARGS();
  1156. PGconn *pgsql;
  1157. if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) {
  1158. return;
  1159. }
  1160. if (argc == 0) {
  1161. id = PGG(default_link);
  1162. CHECK_DEFAULT_LINK(id);
  1163. }
  1164. if (pgsql_link == NULL && id == -1) {
  1165. RETURN_FALSE;
  1166. }
  1167. ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
  1168. if (id==-1) { /* explicit resource number */
  1169. zend_list_delete(Z_RESVAL_P(pgsql_link));
  1170. }
  1171. if (id!=-1
  1172. || (pgsql_link && Z_RESVAL_P(pgsql_link)==PGG(default_link))) {
  1173. zend_list_delete(PGG(default_link));
  1174. PGG(default_link) = -1;
  1175. }
  1176. RETURN_TRUE;
  1177. }
  1178. /* }}} */
  1179. #define PHP_PG_DBNAME 1
  1180. #define PHP_PG_ERROR_MESSAGE 2
  1181. #define PHP_PG_OPTIONS 3
  1182. #define PHP_PG_PORT 4
  1183. #define PHP_PG_TTY 5
  1184. #define PHP_PG_HOST 6
  1185. #define PHP_PG_VERSION 7
  1186. /* {{{ php_pgsql_get_link_info
  1187. */
  1188. static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
  1189. {
  1190. zval *pgsql_link = NULL;
  1191. int id = -1, argc = ZEND_NUM_ARGS();
  1192. PGconn *pgsql;
  1193. char *msgbuf;
  1194. if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) {
  1195. return;
  1196. }
  1197. if (argc == 0) {
  1198. id = PGG(default_link);
  1199. CHECK_DEFAULT_LINK(id);
  1200. }
  1201. if (pgsql_link == NULL && id == -1) {
  1202. RETURN_FALSE;
  1203. }
  1204. ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
  1205. switch(entry_type) {
  1206. case PHP_PG_DBNAME:
  1207. Z_STRVAL_P(return_value) = PQdb(pgsql);
  1208. break;
  1209. case PHP_PG_ERROR_MESSAGE:
  1210. RETURN_STRING(PQErrorMessageTrim(pgsql, &msgbuf), 0);
  1211. return;
  1212. case PHP_PG_OPTIONS:
  1213. Z_STRVAL_P(return_value) = PQoptions(pgsql);
  1214. break;
  1215. case PHP_PG_PORT:
  1216. Z_STRVAL_P(return_value) = PQport(pgsql);
  1217. break;
  1218. case PHP_PG_TTY:
  1219. Z_STRVAL_P(return_value) = PQtty(pgsql);
  1220. break;
  1221. case PHP_PG_HOST:
  1222. Z_STRVAL_P(return_value) = PQhost(pgsql);
  1223. break;
  1224. case PHP_PG_VERSION:
  1225. array_init(return_value);
  1226. add_assoc_string(return_value, "client", PG_VERSION, 1);
  1227. #if HAVE_PQPROTOCOLVERSION
  1228. add_assoc_long(return_value, "protocol", PQprotocolVersion(pgsql));
  1229. #if HAVE_PQPARAMETERSTATUS
  1230. if (PQprotocolVersion(pgsql) >= 3) {
  1231. add_assoc_string(return_value, "server", (char*)PQparameterStatus(pgsql, "server_version"), 1);
  1232. }
  1233. #endif
  1234. #endif
  1235. return;
  1236. default:
  1237. RETURN_FALSE;
  1238. }
  1239. if (Z_STRVAL_P(return_value)) {
  1240. Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
  1241. Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value));
  1242. } else {
  1243. Z_STRLEN_P(return_value) = 0;
  1244. Z_STRVAL_P(return_value) = (char *) estrdup("");
  1245. }
  1246. Z_TYPE_P(return_value) = IS_STRING;
  1247. }
  1248. /* }}} */
  1249. /* {{{ proto string pg_dbname([resource connection])
  1250. Get the database name */
  1251. PHP_FUNCTION(pg_dbname)
  1252. {
  1253. php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_DBNAME);
  1254. }
  1255. /* }}} */
  1256. /* {{{ proto string pg_last_error([resource connection])
  1257. Get the error message string */
  1258. PHP_FUNCTION(pg_last_error)
  1259. {
  1260. php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_ERROR_MESSAGE);
  1261. }
  1262. /* }}} */
  1263. /* {{{ proto string pg_options([resource connection])
  1264. Get the options associated with the connection */
  1265. PHP_FUNCTION(pg_options)
  1266. {
  1267. php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_OPTIONS);
  1268. }
  1269. /* }}} */
  1270. /* {{{ proto int pg_port([resource connection])
  1271. Return the port number associated with the connection */
  1272. PHP_FUNCTION(pg_port)
  1273. {
  1274. php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_PORT);
  1275. }
  1276. /* }}} */
  1277. /* {{{ proto string pg_tty([resource connection])
  1278. Return the tty name associated with the connection */
  1279. PHP_FUNCTION(pg_tty)
  1280. {
  1281. php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_TTY);
  1282. }
  1283. /* }}} */
  1284. /* {{{ proto string pg_host([resource connection])
  1285. Returns the host name associated with the connection */
  1286. PHP_FUNCTION(pg_host)
  1287. {
  1288. php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_HOST);
  1289. }
  1290. /* }}} */
  1291. /* {{{ proto array pg_version([resource connection])
  1292. Returns an array with client, protocol and server version (when available) */
  1293. PHP_FUNCTION(pg_version)
  1294. {
  1295. php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_VERSION);
  1296. }
  1297. /* }}} */
  1298. #if HAVE_PQPARAMETERSTATUS
  1299. /* {{{ proto string|false pg_parameter_status([resource connection,] string param_name)
  1300. Returns the value of a server parameter */
  1301. PHP_FUNCTION(pg_parameter_status)
  1302. {
  1303. zval *pgsql_link;
  1304. int id;
  1305. PGconn *pgsql;
  1306. char *param;
  1307. int len;
  1308. if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &param, &len) == SUCCESS) {
  1309. id = -1;
  1310. } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &param, &len) == SUCCESS) {
  1311. pgsql_link = NULL;
  1312. id = PGG(default_link);
  1313. } else {
  1314. RETURN_FALSE;
  1315. }
  1316. if (pgsql_link == NULL && id == -1) {
  1317. RETURN_FALSE;
  1318. }
  1319. ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
  1320. param = (char*)PQparameterStatus(pgsql, param);
  1321. if (param) {
  1322. RETURN_STRING(param, 1);
  1323. } else {
  1324. RETURN_FALSE;
  1325. }
  1326. }
  1327. /* }}} */
  1328. #endif
  1329. /* {{{ proto bool pg_ping([resource connection])
  1330. Ping database. If connection is bad, try to reconnect. */
  1331. PHP_FUNCTION(pg_ping)
  1332. {
  1333. zval *pgsql_link;
  1334. int id;
  1335. PGconn *pgsql;
  1336. PGresult *res;
  1337. if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == SUCCESS) {
  1338. id = -1;
  1339. } else {
  1340. pgsql_link = NULL;
  1341. id = PGG(default_link);
  1342. }
  1343. if (pgsql_link == NULL && id == -1) {
  1344. RETURN_FALSE;
  1345. }
  1346. ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
  1347. /* ping connection */
  1348. res = PQexec(pgsql, "SELECT 1;");
  1349. PQclear(res);
  1350. /* check status. */
  1351. if (PQstatus(pgsql) == CONNECTION_OK)
  1352. RETURN_TRUE;
  1353. /* reset connection if it's broken */
  1354. PQreset(pgsql);
  1355. if (PQstatus(pgsql) == CONNECTION_OK) {
  1356. RETURN_TRUE;
  1357. }
  1358. RETURN_FALSE;
  1359. }
  1360. /* }}} */
  1361. /* {{{ proto resource pg_query([resource connection,] string query)
  1362. Execute a query */
  1363. PHP_FUNCTION(pg_query)
  1364. {
  1365. zval *pgsql_link = NULL;
  1366. char *query;
  1367. int id = -1, query_len, argc = ZEND_NUM_ARGS();
  1368. int leftover = 0;
  1369. PGconn *pgsql;
  1370. PGresult *pgsql_result;
  1371. ExecStatusType status;
  1372. pgsql_result_handle *pg_result;
  1373. if (argc == 1) {
  1374. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query, &query_len) == FAILURE) {
  1375. return;
  1376. }
  1377. id = PGG(default_link);
  1378. CHECK_DEFAULT_LINK(id);
  1379. } else {
  1380. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &query, &query_len) == FAILURE) {
  1381. return;
  1382. }
  1383. }
  1384. if (pgsql_link == NULL && id == -1) {
  1385. RETURN_FALSE;
  1386. }
  1387. ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
  1388. if (PQ_SETNONBLOCKING(pgsql, 0)) {
  1389. php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode");
  1390. RETURN_FALSE;
  1391. }
  1392. while ((pgsql_result = PQgetResult(pgsql))) {
  1393. PQclear(pgsql_result);
  1394. leftover = 1;
  1395. }
  1396. if (leftover) {
  1397. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first");
  1398. }
  1399. pgsql_result = PQexec(pgsql, query);
  1400. if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) {
  1401. PQclear(pgsql_result);
  1402. PQreset(pgsql);
  1403. pgsql_result = PQexec(pgsql, query);
  1404. }
  1405. if (pgsql_result) {
  1406. status = PQresultStatus(pgsql_result);
  1407. } else {
  1408. status = (ExecStatusType) PQstatus(pgsql);
  1409. }
  1410. switch (status) {
  1411. case PGRES_EMPTY_QUERY:
  1412. case PGRES_BAD_RESPONSE:
  1413. case PGRES_NONFATAL_ERROR:
  1414. case PGRES_FATAL_ERROR:
  1415. PHP_PQ_ERROR("Query failed: %s", pgsql);
  1416. PQclear(pgsql_result);
  1417. RETURN_FALSE;
  1418. break;
  1419. case PGRES_COMMAND_OK: /* successful command that did not return rows */
  1420. default:
  1421. if (pgsql_result) {
  1422. pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
  1423. pg_result->conn = pgsql;
  1424. pg_result->result = pgsql_result;
  1425. pg_result->row = 0;
  1426. ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);
  1427. } else {
  1428. PQclear(pgsql_result);
  1429. RETURN_FALSE;
  1430. }
  1431. break;
  1432. }
  1433. }
  1434. /* }}} */
  1435. #if HAVE_PQEXECPARAMS || HAVE_PQEXECPREPARED || HAVE_PQSENDQUERYPARAMS || HAVE_PQSENDQUERYPREPARED
  1436. /* {{{ _php_pgsql_free_params */
  1437. static void _php_pgsql_free_params(char **params, int num_params)
  1438. {
  1439. if (num_params > 0) {
  1440. int i;
  1441. for (i = 0; i < num_params; i++) {
  1442. if (params[i]) {
  1443. efree(params[i]);
  1444. }
  1445. }
  1446. efree(params);
  1447. }
  1448. }
  1449. /* }}} */
  1450. #endif
  1451. #if HAVE_PQEXECPARAMS
  1452. /* {{{ proto resource pg_query_params([resource connection,] string query, array params)
  1453. Execute a query */
  1454. PHP_FUNCTION(pg_query_params)
  1455. {
  1456. zval *pgsql_link = NULL;
  1457. zval *pv_param_arr, **tmp;
  1458. ch

Large files files are truncated, but you can click here to view the full file