2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
17 #define SMART_STR_PREALLOC 256
20 #include <Zend/zend_interfaces.h>
21 #include <ext/standard/info.h>
22 #include <ext/standard/php_smart_str.h>
23 #include <ext/spl/spl_array.h>
24 #include <ext/raphf/php_raphf.h>
26 #include <libpq-events.h>
27 #include <libpq/libpq-fs.h>
32 typedef int STATUS
; /* SUCCESS/FAILURE */
34 static char *rtrim(char *e
) {
37 while (l
-- > 0 && e
[l
] == '\n') {
43 #define PHP_PQerrorMessage(c) rtrim(PQerrorMessage((c)))
44 #define PHP_PQresultErrorMessage(r) rtrim(PQresultErrorMessage((r)))
46 static int php_pqconn_event(PGEventId id
, void *e
, void *data
);
48 #define PHP_PQclear(_r) \
50 zval *_resinszv = PQresultInstanceData((_r), php_pqconn_event); \
51 if (!_resinszv) PQclear((_r)); \
55 ZEND_DECLARE_MODULE_GLOBALS(pq)
60 /* Remove comments and fill if you need to have entries in php.ini
62 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
63 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
68 /* {{{ php_pq_init_globals
70 /* Uncomment this function if you have INI entries
71 static void php_pq_init_globals(zend_pq_globals *pq_globals)
73 pq_globals->global_value = 0;
74 pq_globals->global_string = NULL;
79 static zend_class_entry
*php_pqconn_class_entry
;
80 static zend_class_entry
*php_pqtypes_class_entry
;
81 static zend_class_entry
*php_pqres_class_entry
;
82 static zend_class_entry
*php_pqstm_class_entry
;
83 static zend_class_entry
*php_pqtxn_class_entry
;
84 static zend_class_entry
*php_pqcancel_class_entry
;
85 static zend_class_entry
*php_pqevent_class_entry
;
86 static zend_class_entry
*php_pqlob_class_entry
;
87 static zend_class_entry
*php_pqcopy_class_entry
;
89 static zend_object_handlers php_pqconn_object_handlers
;
90 static zend_object_handlers php_pqtypes_object_handlers
;
91 static zend_object_handlers php_pqres_object_handlers
;
92 static zend_object_handlers php_pqstm_object_handlers
;
93 static zend_object_handlers php_pqtxn_object_handlers
;
94 static zend_object_handlers php_pqcancel_object_handlers
;
95 static zend_object_handlers php_pqevent_object_handlers
;
96 static zend_object_handlers php_pqlob_object_handlers
;
97 static zend_object_handlers php_pqcopy_object_handlers
;
99 typedef struct php_pq_callback
{
101 zend_fcall_info_cache fcc
;
105 typedef struct php_pq_object
{
107 zend_object_value zv
;
108 HashTable
*prophandler
;
112 #define PHP_PQCONN_ASYNC 0x01
113 #define PHP_PQCONN_PERSISTENT 0x02
115 typedef struct php_pqconn
{
117 int (*poller
)(PGconn
*);
118 php_resource_factory_t factory
;
120 HashTable eventhandlers
;
121 php_pq_callback_t onevent
;
122 unsigned unbuffered
:1;
125 typedef struct php_pqconn_object
{
127 zend_object_value zv
;
128 HashTable
*prophandler
;
129 php_pqconn_t
*intern
;
130 } php_pqconn_object_t
;
132 typedef struct php_pqtypes
{
134 php_pqconn_object_t
*conn
;
137 typedef struct php_pqtypes_object
{
139 zend_object_value zv
;
140 HashTable
*prophandler
;
141 php_pqtypes_t
*intern
;
142 } php_pqtypes_object_t
;
144 typedef struct php_pqconn_event_data
{
145 php_pqconn_object_t
*obj
;
149 } php_pqconn_event_data_t
;
151 typedef enum php_pqres_fetch
{
152 PHP_PQRES_FETCH_ARRAY
,
153 PHP_PQRES_FETCH_ASSOC
,
154 PHP_PQRES_FETCH_OBJECT
157 typedef struct php_pqres_iterator
{
158 zend_object_iterator zi
;
161 php_pqres_fetch_t fetch_type
;
162 } php_pqres_iterator_t
;
164 typedef struct php_pqres
{
166 php_pqres_iterator_t
*iter
;
170 typedef struct php_pqres_object
{
172 zend_object_value zv
;
173 HashTable
*prophandler
;
175 } php_pqres_object_t
;
177 typedef struct php_pqstm
{
178 php_pqconn_object_t
*conn
;
183 typedef struct php_pqstm_object
{
185 zend_object_value zv
;
186 HashTable
*prophandler
;
188 } php_pqstm_object_t
;
190 typedef enum php_pqtxn_isolation
{
191 PHP_PQTXN_READ_COMMITTED
,
192 PHP_PQTXN_REPEATABLE_READ
,
193 PHP_PQTXN_SERIALIZABLE
,
194 } php_pqtxn_isolation_t
;
196 typedef struct php_pqtxn
{
197 php_pqconn_object_t
*conn
;
198 php_pqtxn_isolation_t isolation
;
201 unsigned deferrable
:1;
204 typedef struct php_pqtxn_object
{
206 zend_object_value zv
;
207 HashTable
*prophandler
;
209 } php_pqtxn_object_t
;
211 typedef struct php_pqcancel
{
213 php_pqconn_object_t
*conn
;
216 typedef struct php_pqcancel_object
{
218 zend_object_value zv
;
219 HashTable
*prophandler
;
220 php_pqcancel_t
*intern
;
221 } php_pqcancel_object_t
;
223 typedef struct php_pqevent
{
224 php_pq_callback_t cb
;
225 php_pqconn_object_t
*conn
;
229 typedef struct php_pqevent_object
{
231 zend_object_value zv
;
232 HashTable
*prophandler
;
233 php_pqevent_t
*intern
;
234 } php_pqevent_object_t
;
236 typedef struct php_pqlob
{
239 php_pqtxn_object_t
*txn
;
242 typedef struct php_pqlob_object
{
244 zend_object_value zv
;
245 HashTable
*prophandler
;
247 } php_pqlob_object_t
;
249 typedef enum php_pqcopy_direction
{
250 PHP_PQCOPY_FROM_STDIN
,
252 } php_pqcopy_direction_t
;
254 typedef enum php_pqcopy_status
{
258 } php_pqcopy_status_t
;
260 typedef struct php_pqcopy
{
261 php_pqcopy_direction_t direction
;
264 php_pqconn_object_t
*conn
;
267 typedef struct php_pqcopy_object
{
269 zend_object_value zv
;
270 HashTable
*prophandler
;
271 php_pqcopy_t
*intern
;
272 } php_pqcopy_object_t
;
274 static HashTable php_pqconn_object_prophandlers
;
275 static HashTable php_pqtypes_object_prophandlers
;
276 static HashTable php_pqres_object_prophandlers
;
277 static HashTable php_pqstm_object_prophandlers
;
278 static HashTable php_pqtxn_object_prophandlers
;
279 static HashTable php_pqcancel_object_prophandlers
;
280 static HashTable php_pqevent_object_prophandlers
;
281 static HashTable php_pqlob_object_prophandlers
;
282 static HashTable php_pqcopy_object_prophandlers
;
284 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
286 typedef struct php_pq_object_prophandler
{
287 php_pq_object_prophandler_func_t read
;
288 php_pq_object_prophandler_func_t write
;
289 } php_pq_object_prophandler_t
;
291 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
293 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
295 php_pqres_iterator_t
*iter
;
296 zval
*prop
, *zfetch_type
;
298 iter
= ecalloc(1, sizeof(*iter
));
299 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
300 iter
->zi
.data
= object
;
303 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
304 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
305 convert_to_long_ex(&zfetch_type
);
307 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
308 if (zfetch_type
!= prop
) {
309 zval_ptr_dtor(&zfetch_type
);
311 if (Z_REFCOUNT_P(prop
)) {
312 zval_ptr_dtor(&prop
);
318 return (zend_object_iterator
*) iter
;
321 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
323 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
325 if (iter
->current_val
) {
326 zval_ptr_dtor(&iter
->current_val
);
327 iter
->current_val
= NULL
;
329 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
333 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
335 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
336 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
338 if (PQresultStatus(obj
->intern
->res
) != PGRES_TUPLES_OK
) {
341 if (PQntuples(obj
->intern
->res
) <= iter
->index
) {
348 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type
, zval
**data_ptr TSRMLS_DC
)
358 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
368 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
369 if (PQgetisnull(res
, row
, c
)) {
370 switch (fetch_type
) {
371 case PHP_PQRES_FETCH_OBJECT
:
372 add_property_null(data
, PQfname(res
, c
));
375 case PHP_PQRES_FETCH_ASSOC
:
376 add_assoc_null(data
, PQfname(res
, c
));
379 case PHP_PQRES_FETCH_ARRAY
:
380 add_index_null(data
, c
);
384 char *val
= PQgetvalue(res
, row
, c
);
385 int len
= PQgetlength(res
, row
, c
);
387 switch (fetch_type
) {
388 case PHP_PQRES_FETCH_OBJECT
:
389 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
392 case PHP_PQRES_FETCH_ASSOC
:
393 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
396 case PHP_PQRES_FETCH_ARRAY
:
397 add_index_stringl(data
, c
, val
, len
,1);
406 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
408 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
409 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
411 if (iter
->current_val
) {
412 zval_ptr_dtor(&iter
->current_val
);
414 iter
->current_val
= php_pqres_row_to_zval(obj
->intern
->res
, iter
->index
, iter
->fetch_type
, NULL TSRMLS_CC
);
415 *data_ptr
= &iter
->current_val
;
418 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
420 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
422 *key_num
= (ulong
) iter
->index
;
424 return HASH_KEY_IS_LONG
;
427 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
429 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
434 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
436 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
441 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
442 php_pqres_iterator_dtor
,
443 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
444 php_pqres_iterator_valid
,
445 /* fetch the item data for the current element */
446 php_pqres_iterator_current
,
447 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
448 php_pqres_iterator_key
,
449 /* step forwards to next element */
450 php_pqres_iterator_next
,
451 /* rewind to start of data (optional, may be NULL) */
452 php_pqres_iterator_rewind
,
453 /* invalidate current value/key (optional, may be NULL) */
457 static int php_pqres_count_elements(zval
*object
, long *count TSRMLS_DC
)
459 php_pqres_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
462 *count
= (long) PQntuples(obj
->intern
->res
);
469 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
471 switch (PQresultStatus(res
)) {
472 case PGRES_BAD_RESPONSE
:
473 case PGRES_NONFATAL_ERROR
:
474 case PGRES_FATAL_ERROR
:
475 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "%s", PHP_PQresultErrorMessage(res
));
482 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
483 if (cb
->fci
.size
> 0) {
484 zend_fcall_info_args_clear(&cb
->fci
, 1);
485 zval_ptr_dtor(&cb
->fci
.function_name
);
486 if (cb
->fci
.object_ptr
) {
487 zval_ptr_dtor(&cb
->fci
.object_ptr
);
493 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
495 Z_ADDREF_P(cb
->fci
.function_name
);
496 if (cb
->fci
.object_ptr
) {
497 Z_ADDREF_P(cb
->fci
.object_ptr
);
501 static void php_pq_object_to_zval(void *o
, zval
**zv TSRMLS_DC
)
503 php_pq_object_t
*obj
= o
;
509 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
511 (*zv
)->type
= IS_OBJECT
;
512 (*zv
)->value
.obj
= obj
->zv
;
515 static void php_pq_object_addref(void *o TSRMLS_DC
)
517 php_pq_object_t
*obj
= o
;
518 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
521 static void php_pq_object_delref(void *o TSRMLS_DC
)
523 php_pq_object_t
*obj
= o
;
524 zend_objects_store_del_ref_by_handle_ex(obj
->zv
.handle
, obj
->zv
.handlers TSRMLS_CC
);
527 static void php_pqconn_object_free(void *o TSRMLS_DC
)
529 php_pqconn_object_t
*obj
= o
;
532 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
533 php_resource_factory_dtor(&obj
->intern
->factory
);
534 php_pq_callback_dtor(&obj
->intern
->onevent
);
535 zend_hash_destroy(&obj
->intern
->listeners
);
536 zend_hash_destroy(&obj
->intern
->eventhandlers
);
540 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
544 static void php_pqtypes_object_free(void *o TSRMLS_DC
)
546 php_pqtypes_object_t
*obj
= o
;
549 zend_hash_destroy(&obj
->intern
->types
);
550 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
554 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
558 static void php_pqres_object_free(void *o TSRMLS_DC
)
560 php_pqres_object_t
*obj
= o
;
563 if (obj
->intern
->res
) {
564 zval
*res
= PQresultInstanceData(obj
->intern
->res
, php_pqconn_event
);
566 if (1 == Z_REFCOUNT_P(res
)) {
567 PQresultSetInstanceData(obj
->intern
->res
, php_pqconn_event
, NULL
);
571 PQclear(obj
->intern
->res
);
572 obj
->intern
->res
= NULL
;
576 if (obj
->intern
->iter
) {
577 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
578 obj
->intern
->iter
= NULL
;
581 zend_hash_destroy(&obj
->intern
->bound
);
586 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
590 static void php_pqstm_object_free(void *o TSRMLS_DC
)
592 php_pqstm_object_t
*obj
= o
;
595 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
596 efree(obj
->intern
->name
);
597 zend_hash_destroy(&obj
->intern
->bound
);
601 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
605 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
607 php_pqtxn_object_t
*obj
= o
;
610 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
614 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
618 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
620 php_pqcancel_object_t
*obj
= o
;
623 PQfreeCancel(obj
->intern
->cancel
);
624 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
628 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
632 static void php_pqevent_object_free(void *o TSRMLS_DC
)
634 php_pqevent_object_t
*obj
= o
;
637 php_pq_callback_dtor(&obj
->intern
->cb
);
638 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
639 efree(obj
->intern
->type
);
643 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
647 static void php_pqlob_object_free(void *o TSRMLS_DC
)
649 php_pqlob_object_t
*obj
= o
;
652 if (obj
->intern
->lofd
) {
653 lo_close(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
655 php_pq_object_delref(obj
->intern
->txn TSRMLS_CC
);
659 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
663 static void php_pqcopy_object_free(void *o TSRMLS_DC
)
665 php_pqcopy_object_t
*obj
= o
;
668 efree(obj
->intern
->expression
);
669 efree(obj
->intern
->options
);
670 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
674 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
678 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
680 php_pqconn_object_t
*o
;
682 o
= ecalloc(1, sizeof(*o
));
683 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
684 object_properties_init((zend_object
*) o
, ce
);
685 o
->prophandler
= &php_pqconn_object_prophandlers
;
695 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
696 o
->zv
.handlers
= &php_pqconn_object_handlers
;
701 static zend_object_value
php_pqtypes_create_object_ex(zend_class_entry
*ce
, php_pqtypes_t
*intern
, php_pqtypes_object_t
**ptr TSRMLS_DC
)
703 php_pqtypes_object_t
*o
;
705 o
= ecalloc(1, sizeof(*o
));
706 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
707 object_properties_init((zend_object
*) o
, ce
);
708 o
->prophandler
= &php_pqtypes_object_prophandlers
;
718 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtypes_object_free
, NULL TSRMLS_CC
);
719 o
->zv
.handlers
= &php_pqtypes_object_handlers
;
724 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, php_pqres_t
*intern
, php_pqres_object_t
**ptr TSRMLS_DC
)
726 php_pqres_object_t
*o
;
728 o
= ecalloc(1, sizeof(*o
));
729 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
730 object_properties_init((zend_object
*) o
, ce
);
731 o
->prophandler
= &php_pqres_object_prophandlers
;
741 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
742 o
->zv
.handlers
= &php_pqres_object_handlers
;
747 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*intern
, php_pqstm_object_t
**ptr TSRMLS_DC
)
749 php_pqstm_object_t
*o
;
751 o
= ecalloc(1, sizeof(*o
));
752 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
753 object_properties_init((zend_object
*) o
, ce
);
754 o
->prophandler
= &php_pqstm_object_prophandlers
;
764 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
765 o
->zv
.handlers
= &php_pqstm_object_handlers
;
770 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*intern
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
772 php_pqtxn_object_t
*o
;
774 o
= ecalloc(1, sizeof(*o
));
775 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
776 object_properties_init((zend_object
*) o
, ce
);
777 o
->prophandler
= &php_pqtxn_object_prophandlers
;
787 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
788 o
->zv
.handlers
= &php_pqtxn_object_handlers
;
793 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*intern
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
795 php_pqcancel_object_t
*o
;
797 o
= ecalloc(1, sizeof(*o
));
798 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
799 object_properties_init((zend_object
*) o
, ce
);
800 o
->prophandler
= &php_pqcancel_object_prophandlers
;
810 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
811 o
->zv
.handlers
= &php_pqcancel_object_handlers
;
816 static zend_object_value
php_pqevent_create_object_ex(zend_class_entry
*ce
, php_pqevent_t
*intern
, php_pqevent_object_t
**ptr TSRMLS_DC
)
818 php_pqevent_object_t
*o
;
820 o
= ecalloc(1, sizeof(*o
));
821 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
822 object_properties_init((zend_object
*) o
, ce
);
823 o
->prophandler
= &php_pqevent_object_prophandlers
;
833 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqevent_object_free
, NULL TSRMLS_CC
);
834 o
->zv
.handlers
= &php_pqevent_object_handlers
;
839 static zend_object_value
php_pqlob_create_object_ex(zend_class_entry
*ce
, php_pqlob_t
*intern
, php_pqlob_object_t
**ptr TSRMLS_DC
)
841 php_pqlob_object_t
*o
;
843 o
= ecalloc(1, sizeof(*o
));
844 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
845 object_properties_init((zend_object
*) o
, ce
);
846 o
->prophandler
= &php_pqlob_object_prophandlers
;
856 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqlob_object_free
, NULL TSRMLS_CC
);
857 o
->zv
.handlers
= &php_pqlob_object_handlers
;
862 static zend_object_value
php_pqcopy_create_object_ex(zend_class_entry
*ce
, php_pqcopy_t
*intern
, php_pqcopy_object_t
**ptr TSRMLS_DC
)
864 php_pqcopy_object_t
*o
;
866 o
= ecalloc(1, sizeof(*o
));
867 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
868 object_properties_init((zend_object
*) o
, ce
);
869 o
->prophandler
= &php_pqcopy_object_prophandlers
;
879 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcopy_object_free
, NULL TSRMLS_CC
);
880 o
->zv
.handlers
= &php_pqcopy_object_handlers
;
885 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
887 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
890 static zend_object_value
php_pqtypes_create_object(zend_class_entry
*class_type TSRMLS_DC
)
892 return php_pqtypes_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
895 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
897 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
900 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
902 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
905 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
907 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
910 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
912 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
915 static zend_object_value
php_pqevent_create_object(zend_class_entry
*class_type TSRMLS_DC
)
917 return php_pqevent_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
920 static zend_object_value
php_pqlob_create_object(zend_class_entry
*class_type TSRMLS_DC
)
922 return php_pqlob_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
925 static zend_object_value
php_pqcopy_create_object(zend_class_entry
*class_type TSRMLS_DC
)
927 return php_pqcopy_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
930 static int apply_ph_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
932 php_pq_object_prophandler_t
*ph
= p
;
933 HashTable
*ht
= va_arg(argv
, HashTable
*);
934 zval
**return_value
, *object
= va_arg(argv
, zval
*);
935 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
937 if (SUCCESS
== zend_hash_find(ht
, key
->arKey
, key
->nKeyLength
, (void *) &return_value
)) {
940 zval_ptr_dtor(return_value
);
941 MAKE_STD_ZVAL(*return_value
);
942 ZVAL_NULL(*return_value
);
944 ph
->read(object
, obj
, *return_value TSRMLS_CC
);
948 return ZEND_HASH_APPLY_KEEP
;
951 static int apply_pi_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
953 zend_property_info
*pi
= p
;
954 HashTable
*ht
= va_arg(argv
, HashTable
*);
955 zval
*object
= va_arg(argv
, zval
*);
956 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
957 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
959 if (1||!Z_REFCOUNT_P(property
)) {
960 Z_ADDREF_P(property
);
962 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
964 return ZEND_HASH_APPLY_KEEP
;
967 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
970 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
974 ZEND_INIT_SYMTABLE(ht
);
976 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_debug
, 3, ht
, object
, obj
);
977 zend_hash_apply_with_arguments(obj
->prophandler TSRMLS_CC
, apply_ph_to_debug
, 3, ht
, object
, obj
);
982 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
984 php_pqconn_object_t
*obj
= o
;
986 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
989 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
991 php_pqconn_object_t
*obj
= o
;
993 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
996 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
998 php_pqconn_object_t
*obj
= o
;
999 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
1002 RETVAL_STRING(error
, 1);
1008 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
1010 php_pq_callback_t
*listener
= p
;
1011 PGnotify
*nfy
= arg
;
1012 zval
*zpid
, *zchannel
, *zmessage
;
1014 MAKE_STD_ZVAL(zpid
);
1015 ZVAL_LONG(zpid
, nfy
->be_pid
);
1016 MAKE_STD_ZVAL(zchannel
);
1017 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
1018 MAKE_STD_ZVAL(zmessage
);
1019 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
1021 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
1022 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
1024 zval_ptr_dtor(&zchannel
);
1025 zval_ptr_dtor(&zmessage
);
1026 zval_ptr_dtor(&zpid
);
1028 return ZEND_HASH_APPLY_KEEP
;
1031 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1033 HashTable
*listeners
= p
;
1034 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
1036 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
1037 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
1040 return ZEND_HASH_APPLY_KEEP
;
1043 static void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
1047 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
1048 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
1053 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1055 php_pqconn_object_t
*obj
= o
;
1057 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
1060 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1062 php_pqconn_object_t
*obj
= o
;
1064 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
1067 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1069 php_pqconn_object_t
*obj
= o
;
1072 if (Z_TYPE_P(value
) != IS_STRING
) {
1073 convert_to_string_ex(&zenc
);
1076 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
1077 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
1080 if (zenc
!= value
) {
1081 zval_ptr_dtor(&zenc
);
1085 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1087 php_pqconn_object_t
*obj
= o
;
1089 RETVAL_BOOL(obj
->intern
->unbuffered
);
1092 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1094 php_pqconn_object_t
*obj
= o
;
1096 obj
->intern
->unbuffered
= zend_is_true(value
);
1099 static void php_pqconn_object_read_db(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1101 php_pqconn_object_t
*obj
= o
;
1102 char *db
= PQdb(obj
->intern
->conn
);
1105 RETVAL_STRING(db
, 1);
1107 RETVAL_EMPTY_STRING();
1111 static void php_pqconn_object_read_user(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1113 php_pqconn_object_t
*obj
= o
;
1114 char *user
= PQuser(obj
->intern
->conn
);
1117 RETVAL_STRING(user
, 1);
1119 RETVAL_EMPTY_STRING();
1123 static void php_pqconn_object_read_pass(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1125 php_pqconn_object_t
*obj
= o
;
1126 char *pass
= PQpass(obj
->intern
->conn
);
1129 RETVAL_STRING(pass
, 1);
1131 RETVAL_EMPTY_STRING();
1135 static void php_pqconn_object_read_host(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1137 php_pqconn_object_t
*obj
= o
;
1138 char *host
= PQhost(obj
->intern
->conn
);
1141 RETVAL_STRING(host
, 1);
1143 RETVAL_EMPTY_STRING();
1147 static void php_pqconn_object_read_port(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1149 php_pqconn_object_t
*obj
= o
;
1150 char *port
= PQport(obj
->intern
->conn
);
1153 RETVAL_STRING(port
, 1);
1155 RETVAL_EMPTY_STRING();
1159 static void php_pqconn_object_read_options(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1161 php_pqconn_object_t
*obj
= o
;
1162 char *options
= PQoptions(obj
->intern
->conn
);
1165 RETVAL_STRING(options
, 1);
1167 RETVAL_EMPTY_STRING();
1171 static void php_pqtypes_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1173 php_pqtypes_object_t
*obj
= o
;
1175 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1178 static int has_dimension(HashTable
*ht
, zval
*member
, char **key_str
, int *key_len
, long *index TSRMLS_DC
)
1183 switch (Z_TYPE_P(member
)) {
1185 convert_to_string_ex(&tmp
);
1188 if (!is_numeric_string(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
), &lval
, NULL
, 0)) {
1189 if (member
!= tmp
) {
1190 zval_ptr_dtor(&tmp
);
1193 *key_str
= estrndup(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
));
1195 *key_len
= Z_STRLEN_P(tmp
) + 1;
1198 return zend_hash_exists(ht
, Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
) + 1);
1202 lval
= Z_LVAL_P(member
);
1206 if (member
!= tmp
) {
1207 zval_ptr_dtor(&tmp
);
1212 return zend_hash_index_exists(ht
, lval
);
1215 static int php_pqtypes_object_has_dimension(zval
*object
, zval
*member
, int check_empty TSRMLS_DC
)
1217 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1218 char *key_str
= NULL
;
1223 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1226 if (key_str
&& key_len
) {
1227 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1229 return Z_TYPE_PP(data
) != IS_NULL
;
1233 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) data
)) {
1234 return Z_TYPE_PP(data
) != IS_NULL
;
1239 return has_dimension(&obj
->intern
->types
, member
, NULL
, NULL
, NULL TSRMLS_CC
);
1245 static zval
*php_pqtypes_object_read_dimension(zval
*object
, zval
*member
, int type TSRMLS_DC
)
1248 char *key_str
= NULL
;
1250 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1252 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1255 if (key_str
&& key_len
) {
1256 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1261 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1270 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1272 php_pqres_object_t
*obj
= o
;
1274 RETVAL_LONG(PQresultStatus(obj
->intern
->res
));
1277 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1279 php_pqres_object_t
*obj
= o
;
1280 char *error
= PHP_PQresultErrorMessage(obj
->intern
->res
);
1283 RETVAL_STRING(error
, 1);
1289 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1291 php_pqres_object_t
*obj
= o
;
1293 RETVAL_LONG(PQntuples(obj
->intern
->res
));
1296 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1298 php_pqres_object_t
*obj
= o
;
1300 RETVAL_LONG(PQnfields(obj
->intern
->res
));
1303 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1305 php_pqres_object_t
*obj
= o
;
1307 RETVAL_LONG(atoi(PQcmdTuples(obj
->intern
->res
)));
1310 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1312 php_pqres_object_t
*obj
= o
;
1314 if (obj
->intern
->iter
) {
1315 RETVAL_LONG(obj
->intern
->iter
->fetch_type
);
1317 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
1321 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1323 php_pqres_object_t
*obj
= o
;
1324 zval
*zfetch_type
= value
;
1326 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
1327 convert_to_long_ex(&zfetch_type
);
1330 if (!obj
->intern
->iter
) {
1331 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
1332 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
1334 obj
->intern
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
1336 if (zfetch_type
!= value
) {
1337 zval_ptr_dtor(&zfetch_type
);
1341 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1343 php_pqstm_object_t
*obj
= o
;
1345 RETVAL_STRING(obj
->intern
->name
, 1);
1348 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1350 php_pqstm_object_t
*obj
= o
;
1352 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1355 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1357 php_pqtxn_object_t
*obj
= o
;
1359 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1362 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1364 php_pqtxn_object_t
*obj
= o
;
1366 RETVAL_LONG(obj
->intern
->isolation
);
1369 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1371 php_pqtxn_object_t
*obj
= o
;
1373 RETVAL_LONG(obj
->intern
->readonly
);
1376 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1378 php_pqtxn_object_t
*obj
= o
;
1380 RETVAL_LONG(obj
->intern
->deferrable
);
1383 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1385 php_pqtxn_object_t
*obj
= o
;
1386 php_pqtxn_isolation_t orig
= obj
->intern
->isolation
;
1387 zval
*zisolation
= value
;
1390 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
1391 convert_to_long_ex(&zisolation
);
1394 switch ((obj
->intern
->isolation
= Z_LVAL_P(zisolation
))) {
1395 case PHP_PQTXN_READ_COMMITTED
:
1396 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ COMMITED");
1398 case PHP_PQTXN_REPEATABLE_READ
:
1399 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION REPEATABLE READ");
1401 case PHP_PQTXN_SERIALIZABLE
:
1402 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION SERIALIZABLE");
1405 obj
->intern
->isolation
= orig
;
1410 if (zisolation
!= value
) {
1411 zval_ptr_dtor(&zisolation
);
1415 php_pqres_success(res TSRMLS_CC
);
1420 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1422 php_pqtxn_object_t
*obj
= o
;
1425 if ((obj
->intern
->readonly
= zend_is_true(value
))) {
1426 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ ONLY");
1428 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ WRITE");
1432 php_pqres_success(res TSRMLS_CC
);
1437 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1439 php_pqtxn_object_t
*obj
= o
;
1442 if ((obj
->intern
->deferrable
= zend_is_true(value
))) {
1443 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION DEFERRABLE");
1445 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION NOT DEFERRABLE");
1449 php_pqres_success(res TSRMLS_CC
);
1454 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1456 php_pqcancel_object_t
*obj
= o
;
1458 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1461 static void php_pqevent_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1463 php_pqevent_object_t
*obj
= o
;
1465 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1468 static void php_pqevent_object_read_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1470 php_pqevent_object_t
*obj
= o
;
1472 RETVAL_STRING(obj
->intern
->type
, 1);
1475 static void php_pqlob_object_read_transaction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1477 php_pqlob_object_t
*obj
= o
;
1479 php_pq_object_to_zval(obj
->intern
->txn
, &return_value TSRMLS_CC
);
1482 static void php_pqlob_object_read_oid(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1484 php_pqlob_object_t
*obj
= o
;
1486 RETVAL_LONG(obj
->intern
->loid
);
1489 static void php_pqcopy_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1491 php_pqcopy_object_t
*obj
= o
;
1493 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1496 static void php_pqcopy_object_read_direction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1498 php_pqcopy_object_t
*obj
= o
;
1500 RETVAL_LONG(obj
->intern
->direction
);
1503 static void php_pqcopy_object_read_expression(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1505 php_pqcopy_object_t
*obj
= o
;
1507 RETURN_STRING(obj
->intern
->expression
, 1);
1510 static void php_pqcopy_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1512 php_pqcopy_object_t
*obj
= o
;
1514 RETURN_STRING(obj
->intern
->options
, 1);
1517 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
1518 while (ce
->parent
) {
1524 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
1526 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1527 php_pq_object_prophandler_t
*handler
;
1531 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1532 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1533 if (type
== BP_VAR_R
) {
1534 ALLOC_ZVAL(return_value
);
1535 Z_SET_REFCOUNT_P(return_value
, 0);
1536 Z_UNSET_ISREF_P(return_value
);
1538 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1540 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1541 return_value
= NULL
;
1544 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1547 return return_value
;
1550 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1552 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1553 php_pq_object_prophandler_t
*handler
;
1555 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1556 if (handler
->write
) {
1557 handler
->write(object
, obj
, value TSRMLS_CC
);
1560 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1564 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1566 zval
*zsocket
, zmember
;
1572 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1575 INIT_PZVAL(&zmember
);
1576 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1577 MAKE_STD_ZVAL(zsocket
);
1579 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
1580 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
1581 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1582 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1583 php_stream_to_zval(stream
, zsocket
);
1589 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1590 zval_ptr_dtor(&zsocket
);
1596 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1597 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1599 # define TSRMLS_DF(d)
1600 # define TSRMLS_CF(d)
1603 static int apply_event(void *p
, void *a TSRMLS_DC
)
1607 zval
*retval
= NULL
;
1609 zend_call_method_with_1_params(evh
, Z_OBJCE_PP(evh
), NULL
, "trigger", &retval
, args
);
1611 zval_ptr_dtor(&retval
);
1614 return ZEND_HASH_APPLY_KEEP
;
1617 static void php_pqconn_event_connreset(PGEventConnReset
*event
)
1619 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1625 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("reset"), (void *) &evhs
)) {
1626 zval
*args
, *connection
= NULL
;
1628 MAKE_STD_ZVAL(args
);
1630 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1631 add_next_index_zval(args
, connection
);
1632 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1633 zval_ptr_dtor(&args
);
1638 static zval
*result_instance_zval(PGresult
*res TSRMLS_DC
)
1640 zval
*rid
= PQresultInstanceData(res
, php_pqconn_event
);
1643 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
1647 ZEND_INIT_SYMTABLE(&r
->bound
);
1648 rid
->type
= IS_OBJECT
;
1649 rid
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
1651 PQresultSetInstanceData(res
, php_pqconn_event
, rid
);
1658 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
)
1660 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1666 /* event listener */
1667 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("result"), (void *) &evhs
)) {
1668 zval
*args
, *connection
= NULL
, *res
= result_instance_zval(event
->result TSRMLS_CC
);
1670 MAKE_STD_ZVAL(args
);
1672 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1673 add_next_index_zval(args
, connection
);
1674 add_next_index_zval(args
, res
);
1675 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1676 zval_ptr_dtor(&args
);
1679 /* async callback */
1680 if (data
->obj
->intern
->onevent
.fci
.size
> 0) {
1681 zval
*res
= result_instance_zval(event
->result TSRMLS_CC
);
1683 zend_fcall_info_argn(&data
->obj
->intern
->onevent
.fci TSRMLS_CC
, 1, &res
);
1684 zend_fcall_info_call(&data
->obj
->intern
->onevent
.fci
, &data
->obj
->intern
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1685 zval_ptr_dtor(&res
);
1690 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1693 case PGEVT_CONNRESET
:
1694 php_pqconn_event_connreset(e
);
1696 case PGEVT_RESULTCREATE
:
1697 php_pqconn_event_resultcreate(e
);
1706 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1708 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1716 static void php_pqconn_notice_recv(void *p
, const PGresult
*res
)
1718 php_pqconn_event_data_t
*data
= p
;
1724 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("notice"), (void *) &evhs
)) {
1725 zval
*args
, *connection
= NULL
;
1727 MAKE_STD_ZVAL(args
);
1729 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1730 add_next_index_zval(args
, connection
);
1731 add_next_index_string(args
, PHP_PQresultErrorMessage(res
), 1);
1732 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1733 zval_ptr_dtor(&args
);
1738 typedef struct php_pqconn_resource_factory_data
{
1741 } php_pqconn_resource_factory_data_t
;
1743 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
1745 php_pqconn_resource_factory_data_t
*o
= init_arg
;
1746 PGconn
*conn
= NULL
;;
1748 if (o
->flags
& PHP_PQCONN_ASYNC
) {
1749 conn
= PQconnectStart(o
->dsn
);
1751 conn
= PQconnectdb(o
->dsn
);
1755 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
1761 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
1763 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
1765 /* we don't care for anthing, except free'ing evdata */
1767 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
1768 memset(evdata
, 0, sizeof(*evdata
));
1775 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
1776 php_pqconn_resource_factory_ctor
,
1778 php_pqconn_resource_factory_dtor
1781 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1785 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1787 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
1788 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1);
1790 if (quoted_channel
) {
1794 spprintf(&cmd
, 0, "UNLISTEN %s", quoted_channel
);
1795 if ((res
= PQexec(obj
->intern
->conn
, cmd
))) {
1800 PQfreemem(quoted_channel
);
1803 return ZEND_HASH_APPLY_REMOVE
;
1806 static void php_pqconn_notice_ignore(void *p
, const PGresult
*res
)
1810 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1812 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
1817 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
1819 /* ignore notices */
1820 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
1822 /* cancel async queries */
1823 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
1824 PQcancel(cancel
, ZEND_STRL("retiring persistent connection"));
1825 PQfreeCancel(cancel
);
1827 /* clean up async results */
1828 while ((res
= PQgetResult(*handle
))) {
1832 /* clean up transaction & session */
1833 switch (PQtransactionStatus(*handle
)) {
1835 res
= PQexec(*handle
, "RESET ALL");
1838 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
1847 /* clean up notify listeners */
1848 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
1850 /* release instance data */
1851 memset(evdata
, 0, sizeof(*evdata
));
1856 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
1857 ZEND_ARG_INFO(0, dsn
)
1858 ZEND_ARG_INFO(0, async
)
1859 ZEND_END_ARG_INFO();
1860 static PHP_METHOD(pqconn
, __construct
) {
1861 zend_error_handling zeh
;
1866 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1867 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
)) {
1868 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1869 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
1870 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
1872 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
1874 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
1875 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
1877 if (flags
& PHP_PQCONN_PERSISTENT
) {
1878 php_persistent_handle_factory_t
*phf
= php_persistent_handle_concede(NULL
, ZEND_STRL("pq\\Connection"), dsn_str
, dsn_len
, php_pqconn_wakeup
, php_pqconn_retire TSRMLS_CC
);
1879 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
1881 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
1884 if (flags
& PHP_PQCONN_ASYNC
) {
1885 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
1888 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
1890 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
1891 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
1893 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
1894 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1897 zend_restore_error_handling(&zeh TSRMLS_CC
);
1900 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
1901 ZEND_END_ARG_INFO();
1902 static PHP_METHOD(pqconn
, reset
) {
1903 if (SUCCESS
== zend_parse_parameters_none()) {
1904 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1907 PQreset(obj
->intern
->conn
);
1909 if (CONNECTION_OK
== PQstatus(obj
->intern
->conn
)) {
1912 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1915 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1921 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
1922 ZEND_END_ARG_INFO();
1923 static PHP_METHOD(pqconn
, resetAsync
) {
1924 if (SUCCESS
== zend_parse_parameters_none()) {
1925 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1928 if (PQresetStart(obj
->intern
->conn
)) {
1929 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
1933 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1939 static void php_pqconn_add_listener(php_pqconn_object_t
*obj
, const char *channel_str
, size_t channel_len
, php_pq_callback_t
*listener TSRMLS_DC
)
1941 HashTable ht
, *existing_listeners
;
1943 php_pq_callback_addref(listener
);
1945 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
1946 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
1948 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
1949 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
1950 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
1954 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
1955 ZEND_ARG_INFO(0, channel
)
1956 ZEND_ARG_INFO(0, callable
)
1957 ZEND_END_ARG_INFO();
1958 static PHP_METHOD(pqconn
, listen
) {
1959 char *channel_str
= NULL
;
1960 int channel_len
= 0;
1961 php_pq_callback_t listener
;
1963 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
)) {
1964 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1966 obj
->intern
->poller
= PQconsumeInput
;
1969 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
1971 if (quoted_channel
) {
1975 spprintf(&cmd
, 0, "LISTEN %s", quoted_channel
);
1976 res
= PQexec(obj
->intern
->conn
, cmd
);
1979 PQfreemem(quoted_channel
);
1982 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1983 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
1990 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1994 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1996 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1999 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2005 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
2006 ZEND_ARG_INFO(0, channel
)
2007 ZEND_ARG_INFO(0, callable
)
2008 ZEND_END_ARG_INFO();
2009 static PHP_METHOD(pqconn
, listenAsync
) {
2010 char *channel_str
= NULL
;
2011 int channel_len
= 0;
2012 php_pq_callback_t listener
;
2014 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
)) {
2015 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2017 obj
->intern
->poller
= PQconsumeInput
;
2020 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2022 if (quoted_channel
) {
2025 obj
->intern
->poller
= PQconsumeInput
;
2027 spprintf(&cmd
, 0, "LISTEN %s", channel_str
);
2028 if (PQsendQuery(obj
->intern
->conn
, cmd
)) {
2029 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2032 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2037 PQfreemem(quoted_channel
);
2039 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2041 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2044 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2050 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
2051 ZEND_ARG_INFO(0, channel
)
2052 ZEND_ARG_INFO(0, message
)
2053 ZEND_END_ARG_INFO();
2054 static PHP_METHOD(pqconn
, notify
) {
2055 char *channel_str
, *message_str
;
2056 int channel_len
, message_len
;
2058 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
)) {
2059 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2063 char *params
[2] = {channel_str
, message_str
};
2065 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
2068 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2075 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2079 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2082 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2088 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
2089 ZEND_ARG_INFO(0, channel
)
2090 ZEND_ARG_INFO(0, message
)
2091 ZEND_END_ARG_INFO();
2092 static PHP_METHOD(pqconn
, notifyAsync
) {
2093 char *channel_str
, *message_str
;
2094 int channel_len
, message_len
;
2096 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
)) {
2097 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2100 char *params
[2] = {channel_str
, message_str
};
2102 obj
->intern
->poller
= PQconsumeInput
;
2104 if (PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
2107 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2111 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2114 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2120 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
2121 ZEND_END_ARG_INFO();
2122 static PHP_METHOD(pqconn
, poll
) {
2123 if (SUCCESS
== zend_parse_parameters_none()) {
2124 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2127 if (obj
->intern
->poller
) {
2128 if (obj
->intern
->poller
== PQconsumeInput
) {
2129 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
2130 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2133 RETURN_LONG(obj
->intern
->poller(obj
->intern
->conn
));
2136 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "No asynchronous operation active");
2139 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2145 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
2146 ZEND_ARG_INFO(0, query
)
2147 ZEND_END_ARG_INFO();
2148 static PHP_METHOD(pqconn
, exec
) {
2149 zend_error_handling zeh
;
2153 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2154 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
)) {
2155 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2158 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
2160 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2163 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2164 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2167 ZEND_INIT_SYMTABLE(&r
->bound
);
2168 return_value
->type
= IS_OBJECT
;
2169 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2172 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2175 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2178 zend_restore_error_handling(&zeh TSRMLS_CC
);
2181 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
2182 ZEND_END_ARG_INFO();
2183 static PHP_METHOD(pqconn
, getResult
) {
2184 if (SUCCESS
== zend_parse_parameters_none()) {
2185 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2188 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
2191 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2194 ZEND_INIT_SYMTABLE(&r
->bound
);
2195 return_value
->type
= IS_OBJECT
;
2196 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2201 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2207 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
2208 ZEND_ARG_INFO(0, query
)
2209 ZEND_ARG_INFO(0, callable
)
2210 ZEND_END_ARG_INFO();
2211 static PHP_METHOD(pqconn
, execAsync
) {
2212 zend_error_handling zeh
;
2213 php_pq_callback_t resolver
= {{0}};
2217 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2218 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
)) {
2219 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2222 php_pq_callback_dtor(&obj
->intern
->onevent
);
2223 if (resolver
.fci
.size
> 0) {
2224 obj
->intern
->onevent
= resolver
;
2225 php_pq_callback_addref(&obj
->intern
->onevent
);
2228 obj
->intern
->poller
= PQconsumeInput
;
2230 if (PQsendQuery(obj
->intern
->conn
, query_str
)) {
2231 if (obj
->intern
->unbuffered
) {
2232 if (!PQsetSingleRowMode(obj
->intern
->conn
)) {
2233 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2238 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2242 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2246 zend_restore_error_handling(&zeh TSRMLS_CC
);
2249 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
2254 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
2255 convert_to_long_ex(ztype
);
2258 **types
= Z_LVAL_PP(ztype
);
2261 if (*ztype
!= *(zval
**)p
) {
2262 zval_ptr_dtor(ztype
);
2264 return ZEND_HASH_APPLY_KEEP
;
2267 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
2273 params
= (char ***) va_arg(argv
, char ***);
2274 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
2276 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
2280 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
2281 convert_to_string_ex(zparam
);
2284 **params
= Z_STRVAL_PP(zparam
);
2287 if (*zparam
!= *(zval
**)p
) {
2288 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
2291 return ZEND_HASH_APPLY_KEEP
;
2294 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
2296 int count
= zend_hash_num_elements(ht
);
2303 /* +1 for when less types than params are specified */
2304 *types
= tmp
= ecalloc(count
+ 1, sizeof(**types
));
2305 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
2311 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
2313 int count
= zend_hash_num_elements(ht
);
2320 *params
= tmp
= ecalloc(count
, sizeof(char *));
2321 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
2327 static Oid *php_pq_ntypes_to_array(zend_bool fill, int argc, ...)
2330 Oid *oids = ecalloc(argc + 1, sizeof(*oids));
2333 va_start(argv, argc);
2334 for (i = 0; i < argc; ++i) {
2336 oids[i] = va_arg(argv, Oid);
2346 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
2347 ZEND_ARG_INFO(0, query
)
2348 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2349 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2350 ZEND_END_ARG_INFO();
2351 static PHP_METHOD(pqconn
, execParams
) {
2352 zend_error_handling zeh
;
2356 zval
*ztypes
= NULL
;
2358 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2359 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
)) {
2360 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2366 char **params
= NULL
;
2369 ZEND_INIT_SYMTABLE(&zdtor
);
2370 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2373 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2376 res
= PQexecParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
2378 zend_hash_destroy(&zdtor
);
2386 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2389 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2390 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2393 ZEND_INIT_SYMTABLE(&r
->bound
);
2394 return_value
->type
= IS_OBJECT
;
2395 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2398 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2402 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2406 zend_restore_error_handling(&zeh TSRMLS_CC
);
2409 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
2410 ZEND_ARG_INFO(0, query
)
2411 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2412 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2413 ZEND_ARG_INFO(0, callable
)
2414 ZEND_END_ARG_INFO();
2415 static PHP_METHOD(pqconn
, execParamsAsync
) {
2416 zend_error_handling zeh
;
2417 php_pq_callback_t resolver
= {{0}};
2421 zval
*ztypes
= NULL
;
2423 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2424 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
)) {
2425 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2430 char **params
= NULL
;
2433 ZEND_INIT_SYMTABLE(&zdtor
);
2434 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2437 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2440 php_pq_callback_dtor(&obj
->intern
->onevent
);
2441 if (resolver
.fci
.size
> 0) {
2442 obj
->intern
->onevent
= resolver
;
2443 php_pq_callback_addref(&obj
->intern
->onevent
);
2446 obj
->intern
->poller
= PQconsumeInput
;
2448 if (PQsendQueryParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
2449 if (obj
->intern
->unbuffered
) {
2450 if (!PQsetSingleRowMode(obj
->intern
->conn
)) {
2451 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2456 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2460 zend_hash_destroy(&zdtor
);
2468 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2471 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2475 zend_restore_error_handling(&zeh TSRMLS_CC
);
2478 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2486 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2490 count
= zend_hash_num_elements(typest
);
2491 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2494 res
= PQprepare(obj
->intern
->conn
, name
, query
, count
, types
);
2501 rv
= php_pqres_success(res TSRMLS_CC
);
2505 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2511 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
2512 ZEND_ARG_INFO(0, type
)
2513 ZEND_ARG_INFO(0, query
)
2514 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2515 ZEND_END_ARG_INFO();
2516 static PHP_METHOD(pqconn
, prepare
) {
2517 zend_error_handling zeh
;
2518 zval
*ztypes
= NULL
;
2519 char *name_str
, *query_str
;
2520 int name_len
, *query_len
;
2522 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2523 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
2524 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2527 if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2528 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2530 php_pq_object_addref(obj TSRMLS_CC
);
2532 stm
->name
= estrdup(name_str
);
2533 ZEND_INIT_SYMTABLE(&stm
->bound
);
2535 return_value
->type
= IS_OBJECT
;
2536 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2538 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2540 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2543 zend_restore_error_handling(&zeh TSRMLS_CC
);
2546 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2553 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2557 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2560 if (PQsendPrepare(obj
->intern
->conn
, name
, query
, count
, types
)) {
2561 if (obj
->intern
->unbuffered
) {
2562 if (!PQsetSingleRowMode(obj
->intern
->conn
)) {
2563 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2568 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2579 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
2580 ZEND_ARG_INFO(0, type
)
2581 ZEND_ARG_INFO(0, query
)
2582 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2583 ZEND_END_ARG_INFO();
2584 static PHP_METHOD(pqconn
, prepareAsync
) {
2585 zend_error_handling zeh
;
2586 zval
*ztypes
= NULL
;
2587 char *name_str
, *query_str
;
2588 int name_len
, *query_len
;
2590 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2591 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
2592 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2595 obj
->intern
->poller
= PQconsumeInput
;
2596 if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2597 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2599 php_pq_object_addref(obj TSRMLS_CC
);
2601 stm
->name
= estrdup(name_str
);
2602 ZEND_INIT_SYMTABLE(&stm
->bound
);
2604 return_value
->type
= IS_OBJECT
;
2605 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2607 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2609 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2612 zend_restore_error_handling(&zeh TSRMLS_CC
);
2615 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
2616 ZEND_ARG_INFO(0, string
)
2617 ZEND_END_ARG_INFO();
2618 static PHP_METHOD(pqconn
, quote
) {
2622 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2623 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2626 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
2629 RETVAL_STRING(quoted
, 1);
2632 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2636 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2642 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
2643 ZEND_ARG_INFO(0, type
)
2644 ZEND_END_ARG_INFO();
2645 static PHP_METHOD(pqconn
, quoteName
) {
2649 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2650 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2653 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
2656 RETVAL_STRING(quoted
, 1);
2659 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2663 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2669 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
2670 ZEND_ARG_INFO(0, bytea
)
2671 ZEND_END_ARG_INFO();
2672 static PHP_METHOD(pqconn
, escapeBytea
) {
2676 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2677 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2681 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
2684 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
2685 PQfreemem(escaped_str
);
2687 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2691 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2697 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
2698 ZEND_ARG_INFO(0, bytea
)
2699 ZEND_END_ARG_INFO();
2700 static PHP_METHOD(pqconn
, unescapeBytea
) {
2704 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2705 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2708 size_t unescaped_len
;
2709 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
2711 if (unescaped_str
) {
2712 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
2713 PQfreemem(unescaped_str
);
2715 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2719 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2725 static const char *isolation_level(long *isolation
) {
2726 switch (*isolation
) {
2727 case PHP_PQTXN_SERIALIZABLE
:
2728 return "SERIALIZABLE";
2729 case PHP_PQTXN_REPEATABLE_READ
:
2730 return "REPEATABLE READ";
2732 *isolation
= PHP_PQTXN_READ_COMMITTED
;
2734 case PHP_PQTXN_READ_COMMITTED
:
2735 return "READ COMMITTED";
2739 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2742 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2745 if (conn_obj
->intern
) {
2749 spprintf(&cmd
, 0, "START TRANSACTION ISOLATION LEVEL %s, READ %s, %s DEFERRABLE",
2750 isolation_level(&isolation
), readonly
? "ONLY" : "WRITE", deferrable
? "": "NOT");
2752 res
= PQexec(conn_obj
->intern
->conn
, cmd
);
2757 STATUS rv
= php_pqres_success(res TSRMLS_CC
);
2762 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2766 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2771 static STATUS
php_pqconn_start_transaction_async(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2774 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2777 if (conn_obj
->intern
->conn
) {
2780 spprintf(&cmd
, 0, "START TRANSACTION ISOLATION LEVEL %s, READ %s, %s DEFERRABLE",
2781 isolation_level(&isolation
), readonly
? "ONLY" : "WRITE", deferrable
? "": "NOT");
2783 if (PQsendQuery(conn_obj
->intern
->conn
, cmd
)) {
2784 conn_obj
->intern
->poller
= PQconsumeInput
;
2789 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2793 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2798 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
2799 ZEND_ARG_INFO(0, isolation
)
2800 ZEND_ARG_INFO(0, readonly
)
2801 ZEND_ARG_INFO(0, deferrable
)
2802 ZEND_END_ARG_INFO();
2803 static PHP_METHOD(pqconn
, startTransaction
) {
2804 zend_error_handling zeh
;
2805 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2806 zend_bool readonly
= 0, deferrable
= 0;
2808 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2809 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
)) {
2811 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2813 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2815 if (SUCCESS
== rv
) {
2816 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2818 php_pq_object_addref(obj TSRMLS_CC
);
2820 txn
->isolation
= isolation
;
2821 txn
->readonly
= readonly
;
2822 txn
->deferrable
= deferrable
;
2824 return_value
->type
= IS_OBJECT
;
2825 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
2828 zend_restore_error_handling(&zeh TSRMLS_CC
);
2832 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
2833 ZEND_ARG_INFO(0, isolation
)
2834 ZEND_ARG_INFO(0, readonly
)
2835 ZEND_ARG_INFO(0, deferrable
)
2836 ZEND_END_ARG_INFO();
2837 static PHP_METHOD(pqconn
, startTransactionAsync
) {
2838 zend_error_handling zeh
;
2839 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2840 zend_bool readonly
= 0, deferrable
= 0;
2842 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2843 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
)) {
2845 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2847 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2849 if (SUCCESS
== rv
) {
2850 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2852 php_pq_object_addref(obj TSRMLS_CC
);
2854 txn
->isolation
= isolation
;
2855 txn
->readonly
= readonly
;
2856 txn
->deferrable
= deferrable
;
2858 return_value
->type
= IS_OBJECT
;
2859 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
2862 zend_restore_error_handling(&zeh TSRMLS_CC
);
2865 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
2866 ZEND_ARG_INFO(0, stdio_stream
)
2867 ZEND_END_ARG_INFO();
2868 static PHP_METHOD(pqconn
, trace
) {
2869 zval
*zstream
= NULL
;
2871 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
2872 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2876 php_stream
*stream
= NULL
;
2878 php_stream_from_zval(stream
, &zstream
);
2880 if (SUCCESS
== php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
2881 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
2882 PQtrace(obj
->intern
->conn
, fp
);
2888 PQuntrace(obj
->intern
->conn
);
2892 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2898 static zend_function_entry php_pqconn_methods
[] = {
2899 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2900 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
2901 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
2902 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
2903 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
2904 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
2905 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
2906 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
2907 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
2908 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
2909 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
2910 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
2911 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
2912 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
2913 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
2914 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
2915 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
2916 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
2917 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
2918 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
2919 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
2920 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
2924 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct
, 0, 0, 1)
2925 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
2926 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
2927 ZEND_END_ARG_INFO();
2928 static PHP_METHOD(pqtypes
, __construct
) {
2929 zend_error_handling zeh
;
2930 zval
*zconn
, *znsp
= NULL
;
2932 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2933 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|a!", &zconn
, php_pqconn_class_entry
, &znsp
)) {
2934 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2936 if (conn_obj
->intern
) {
2937 zval
*retval
= NULL
;
2938 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2940 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
2941 obj
->intern
->conn
= conn_obj
;
2942 php_pq_object_addref(conn_obj TSRMLS_CC
);
2943 zend_hash_init(&obj
->intern
->types
, 300, NULL
, ZVAL_PTR_DTOR
, 0);
2946 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
, znsp
);
2948 zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
);
2951 zval_ptr_dtor(&retval
);
2954 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2957 zend_restore_error_handling(&zeh TSRMLS_CC
);
2960 #define PHP_PQ_TYPES_QUERY \
2961 "select t.oid, t.* " \
2962 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
2963 "where typisdefined " \
2965 #define PHP_PQ_OID_TEXT 25
2967 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh
, 0, 0, 0)
2968 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
2969 ZEND_END_ARG_INFO();
2970 static PHP_METHOD(pqtypes
, refresh
) {
2971 HashTable
*nsp
= NULL
;
2973 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|H/!", &nsp
)) {
2974 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2979 if (nsp
&& zend_hash_num_elements(nsp
)) {
2982 char **params
= NULL
;
2984 smart_str str
= {0};
2986 smart_str_appends(&str
, PHP_PQ_TYPES_QUERY
" and nspname in(");
2987 zend_hash_init(&zdtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
2988 count
= php_pq_params_to_array(nsp
, ¶ms
, &zdtor TSRMLS_CC
);
2989 oids
= ecalloc(count
+ 1, sizeof(*oids
));
2990 for (i
= 0; i
< count
; ++i
) {
2991 oids
[i
] = PHP_PQ_OID_TEXT
;
2993 smart_str_appendc(&str
, ',');
2995 smart_str_appendc(&str
, '$');
2996 smart_str_append_unsigned(&str
, i
+1);
2998 smart_str_appendc(&str
, ')');
3001 res
= PQexecParams(obj
->intern
->conn
->intern
->conn
, str
.c
, count
, oids
, (const char *const*) params
, NULL
, NULL
, 0);
3003 smart_str_free(&str
);
3006 zend_hash_destroy(&zdtor
);
3008 res
= PQexec(obj
->intern
->conn
->intern
->conn
, PHP_PQ_TYPES_QUERY
" and nspname in ('public', 'pg_catalog')");
3011 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3014 if (PGRES_TUPLES_OK
== PQresultStatus(res
)) {
3017 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
3018 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT
, NULL TSRMLS_CC
);
3019 long oid
= atol(PQgetvalue(res
, r
, 0 ));
3020 char *name
= PQgetvalue(res
, r
, 1);
3024 zend_hash_index_update(&obj
->intern
->types
, oid
, (void *) &row
, sizeof(zval
*), NULL
);
3025 zend_hash_add(&obj
->intern
->types
, name
, strlen(name
) + 1, (void *) &row
, sizeof(zval
*), NULL
);
3028 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types (%s)", PHP_PQresultErrorMessage(res
));
3032 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3036 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Types not initialized");
3041 static zend_function_entry php_pqtypes_methods
[] = {
3042 PHP_ME(pqtypes
, __construct
, ai_pqtypes_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3043 PHP_ME(pqtypes
, refresh
, ai_pqtypes_refresh
, ZEND_ACC_PUBLIC
)
3047 static STATUS
php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type
, zval
***row TSRMLS_DC
)
3050 php_pqres_fetch_t orig_fetch
;
3053 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3056 if (!obj
->intern
->iter
) {
3057 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
3058 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3060 orig_fetch
= obj
->intern
->iter
->fetch_type
;
3061 obj
->intern
->iter
->fetch_type
= fetch_type
;
3062 if (SUCCESS
== (rv
= obj
->intern
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
))) {
3063 obj
->intern
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->intern
->iter
, row TSRMLS_CC
);
3064 obj
->intern
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3066 obj
->intern
->iter
->fetch_type
= orig_fetch
;
3071 typedef struct php_pqres_col
{
3076 static STATUS
column_nn(php_pqres_object_t
*obj
, zval
*zcol
, php_pqres_col_t
*col TSRMLS_DC
)
3081 switch (Z_TYPE_P(zcol
)) {
3083 convert_to_string(zcol
);
3087 if (!is_numeric_string(Z_STRVAL_P(zcol
), Z_STRLEN_P(zcol
), &index
, NULL
, 0)) {
3088 name
= Z_STRVAL_P(zcol
);
3093 index
= Z_LVAL_P(zcol
);
3099 col
->num
= PQfnumber(obj
->intern
->res
, name
);
3101 col
->name
= PQfname(obj
->intern
->res
, index
);
3106 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column at index %ld", index
);
3109 if (col
->num
== -1) {
3110 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column with name '%s'", name
);
3116 static int compare_index(const void *lptr
, const void *rptr TSRMLS_DC
)
3118 const Bucket
*l
= *(const Bucket
**) lptr
;
3119 const Bucket
*r
= *(const Bucket
**) rptr
;
3130 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind
, 0, 0, 2)
3131 ZEND_ARG_INFO(0, col
)
3132 ZEND_ARG_INFO(1, ref
)
3133 ZEND_END_ARG_INFO();
3134 static PHP_METHOD(pqres
, bind
) {
3137 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z/z", &zcol
, &zref
)) {
3138 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3141 php_pqres_col_t col
;
3143 if (SUCCESS
== column_nn(obj
, zcol
, &col TSRMLS_CC
)) {
3145 if (SUCCESS
== zend_hash_index_update(&obj
->intern
->bound
, col
.num
, (void *) &zref
, sizeof(zval
*), NULL
)) {
3146 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3149 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to bind column %s@%d", col
.name
, col
.num
);
3156 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Result not initialized");
3162 static int apply_bound(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3164 zval
**zvalue
, **zbound
= p
;
3165 zval
**zrow
= va_arg(argv
, zval
**);
3167 if (SUCCESS
== zend_hash_index_find(Z_ARRVAL_PP(zrow
), key
->h
, (void *) &zvalue
)) {
3169 ZVAL_COPY_VALUE(*zbound
, *zvalue
);
3171 zval_ptr_dtor(zvalue
);
3172 Z_ADDREF_P(*zbound
);
3174 return ZEND_HASH_APPLY_KEEP
;
3176 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column ad index %lu", key
->h
);
3177 return ZEND_HASH_APPLY_STOP
;
3181 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound
, 0, 0, 0)
3182 ZEND_END_ARG_INFO();
3183 static PHP_METHOD(pqres
, fetchBound
) {
3184 zend_error_handling zeh
;
3186 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3187 if (SUCCESS
== zend_parse_parameters_none()) {
3188 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3193 if (SUCCESS
== php_pqres_iteration(getThis(), obj
, PHP_PQRES_FETCH_ARRAY
, &row TSRMLS_CC
)) {
3195 zend_hash_apply_with_arguments(&obj
->intern
->bound TSRMLS_CC
, apply_bound
, 1, row
);
3196 RETVAL_ZVAL(*row
, 1, 0);
3201 zend_restore_error_handling(&zeh TSRMLS_CC
);
3204 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
3205 ZEND_ARG_INFO(0, fetch_type
)
3206 ZEND_END_ARG_INFO();
3207 static PHP_METHOD(pqres
, fetchRow
) {
3208 zend_error_handling zeh
;
3209 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3210 long fetch_type
= -1;
3212 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3213 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
)) {
3217 if (fetch_type
== -1) {
3218 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3220 php_pqres_iteration(getThis(), obj
, fetch_type
, &row TSRMLS_CC
);
3223 RETVAL_ZVAL(*row
, 1, 0);
3226 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Result not initialized");
3229 zend_restore_error_handling(&zeh TSRMLS_CC
);
3232 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
3235 HashTable
*ht
= HASH_OF(row
);
3236 int count
= zend_hash_num_elements(ht
);
3239 zend_hash_internal_pointer_reset(ht
);
3241 zend_hash_move_forward(ht
);
3243 zend_hash_get_current_data(ht
, (void *) &data
);
3245 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
3250 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
3251 ZEND_ARG_INFO(0, col_num
)
3252 ZEND_END_ARG_INFO();
3253 static PHP_METHOD(pqres
, fetchCol
) {
3254 zend_error_handling zeh
;
3257 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3258 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
)) {
3259 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3264 php_pqres_iteration(getThis(), obj
, obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: 0, &row TSRMLS_CC
);
3267 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
3270 RETVAL_ZVAL(*col
, 1, 0);
3274 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Result not initialized");
3277 zend_restore_error_handling(&zeh TSRMLS_CC
);
3280 static int apply_to_col(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3283 php_pqres_object_t
*obj
= va_arg(argv
, php_pqres_object_t
*);
3284 php_pqres_col_t
*col
, **cols
= va_arg(argv
, php_pqres_col_t
**);
3285 STATUS
*rv
= va_arg(argv
, STATUS
*);
3288 if (SUCCESS
== column_nn(obj
, *c
, col TSRMLS_CC
)) {
3292 return ZEND_HASH_APPLY_STOP
;
3296 return ZEND_HASH_APPLY_KEEP
;
3299 static php_pqres_col_t
*php_pqres_convert_to_cols(php_pqres_object_t
*obj
, HashTable
*ht TSRMLS_DC
)
3301 php_pqres_col_t
*tmp
, *cols
= ecalloc(zend_hash_num_elements(ht
), sizeof(*cols
));
3302 STATUS rv
= SUCCESS
;
3305 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_col
, 2, obj
, &tmp
, &rv
);
3307 if (SUCCESS
== rv
) {
3315 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map
, 0, 0, 0)
3316 ZEND_ARG_INFO(0, keys
)
3317 ZEND_ARG_INFO(0, vals
)
3318 ZEND_ARG_INFO(0, fetch_type
)
3319 ZEND_END_ARG_INFO();
3320 static PHP_METHOD(pqres
, map
) {
3321 zend_error_handling zeh
;
3322 zval
*zkeys
= 0, *zvals
= 0;
3323 long fetch_type
= -1;
3326 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3327 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z/!z/!l", &zkeys
, &zvals
, &fetch_type
)) {
3328 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3332 php_pqres_col_t def
= {PQfname(obj
->intern
->res
, 0), 0}, *keys
= NULL
, *vals
= NULL
;
3335 convert_to_array(zkeys
);
3337 if ((ks
= zend_hash_num_elements(Z_ARRVAL_P(zkeys
)))) {
3338 keys
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zkeys
) TSRMLS_CC
);
3348 convert_to_array(zvals
);
3350 if ((vs
= zend_hash_num_elements(Z_ARRVAL_P(zvals
)))) {
3351 vals
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zvals
) TSRMLS_CC
);
3355 if (fetch_type
== -1) {
3356 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3363 switch (fetch_type
) {
3364 case PHP_PQRES_FETCH_ARRAY
:
3365 case PHP_PQRES_FETCH_ASSOC
:
3366 array_init(return_value
);
3368 case PHP_PQRES_FETCH_OBJECT
:
3369 object_init(return_value
);
3372 for (r
= 0, rows
= PQntuples(obj
->intern
->res
); r
< rows
; ++r
) {
3375 cur
= &return_value
;
3376 for (k
= 0; k
< ks
; ++k
) {
3377 char *key
= PQgetvalue(obj
->intern
->res
, r
, keys
[k
].num
);
3378 int len
= PQgetlength(obj
->intern
->res
, r
, keys
[k
].num
);
3380 if (SUCCESS
!= zend_symtable_find(HASH_OF(*cur
), key
, len
+ 1, (void *) &cur
)) {
3384 switch (fetch_type
) {
3385 case PHP_PQRES_FETCH_ARRAY
:
3386 case PHP_PQRES_FETCH_ASSOC
:
3389 case PHP_PQRES_FETCH_OBJECT
:
3393 if (SUCCESS
!= zend_symtable_update(HASH_OF(*cur
), key
, len
+ 1, (void *) &tmp
, sizeof(zval
*), (void *) &cur
)) {
3394 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to create map");
3400 for (v
= 0; v
< vs
; ++v
) {
3401 char *val
= PQgetvalue(obj
->intern
->res
, r
, vals
[v
].num
);
3402 int len
= PQgetlength(obj
->intern
->res
, r
, vals
[v
].num
);
3404 switch (fetch_type
) {
3405 case PHP_PQRES_FETCH_ARRAY
:
3406 add_index_stringl(*cur
, vals
[v
].num
, val
, len
, 1);
3408 case PHP_PQRES_FETCH_ASSOC
:
3409 add_assoc_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3411 case PHP_PQRES_FETCH_OBJECT
:
3412 add_property_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3417 php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, cur TSRMLS_CC
);
3423 if (keys
&& keys
!= &def
) {
3430 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Result not initialized");
3433 zend_restore_error_handling(&zeh TSRMLS_CC
);
3436 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count
, 0, 0, 0)
3437 ZEND_END_ARG_INFO();
3438 static PHP_METHOD(pqres
, count
) {
3439 if (SUCCESS
== zend_parse_parameters_none()) {
3442 if (SUCCESS
== php_pqres_count_elements(getThis(), &count TSRMLS_CC
)) {
3445 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Result not initialized");
3450 static zend_function_entry php_pqres_methods
[] = {
3451 PHP_ME(pqres
, bind
, ai_pqres_bind
, ZEND_ACC_PUBLIC
)
3452 PHP_ME(pqres
, fetchBound
, ai_pqres_fetch_bound
, ZEND_ACC_PUBLIC
)
3453 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
3454 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
3455 PHP_ME(pqres
, count
, ai_pqres_count
, ZEND_ACC_PUBLIC
)
3456 PHP_ME(pqres
, map
, ai_pqres_map
, ZEND_ACC_PUBLIC
)
3460 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
3461 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
3462 ZEND_ARG_INFO(0, type
)
3463 ZEND_ARG_INFO(0, query
)
3464 ZEND_ARG_ARRAY_INFO(0, types
, 1)
3465 ZEND_ARG_INFO(0, async
)
3466 ZEND_END_ARG_INFO();
3467 static PHP_METHOD(pqstm
, __construct
) {
3468 zend_error_handling zeh
;
3469 zval
*zconn
, *ztypes
= NULL
;
3470 char *name_str
, *query_str
;
3471 int name_len
, *query_len
;
3472 zend_bool async
= 0;
3474 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3475 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Oss|a/!b", &zconn
, php_pqconn_class_entry
, &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
, &async
)) {
3476 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3477 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3479 if (conn_obj
->intern
) {
3482 conn_obj
->intern
->poller
= PQconsumeInput
;
3483 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3485 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3486 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
3489 if (SUCCESS
== rv
) {
3490 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
3492 php_pq_object_addref(conn_obj TSRMLS_CC
);
3493 stm
->conn
= conn_obj
;
3494 stm
->name
= estrdup(name_str
);
3495 ZEND_INIT_SYMTABLE(&stm
->bound
);
3499 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
3502 zend_restore_error_handling(&zeh TSRMLS_CC
);
3504 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind
, 0, 0, 2)
3505 ZEND_ARG_INFO(0, param_no
)
3506 ZEND_ARG_INFO(1, param_ref
)
3507 ZEND_END_ARG_INFO();
3508 static PHP_METHOD(pqstm
, bind
) {
3512 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "lz", ¶m_no
, ¶m_ref
)) {
3513 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3516 Z_ADDREF_P(param_ref
);
3517 zend_hash_index_update(&obj
->intern
->bound
, param_no
, (void *) ¶m_ref
, sizeof(zval
*), NULL
);
3518 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3520 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
3525 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
3526 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3527 ZEND_END_ARG_INFO();
3528 static PHP_METHOD(pqstm
, exec
) {
3529 zend_error_handling zeh
;
3530 zval
*zparams
= NULL
;
3532 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3533 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
)) {
3534 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3537 if (obj
->intern
->conn
->intern
) {
3539 char **params
= NULL
;
3543 ZEND_INIT_SYMTABLE(&zdtor
);
3546 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3548 count
= php_pq_params_to_array(&obj
->intern
->bound
, ¶ms
, &zdtor TSRMLS_CC
);
3551 res
= PQexecPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
3556 zend_hash_destroy(&zdtor
);
3558 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3561 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3562 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
3565 ZEND_INIT_SYMTABLE(&r
->bound
);
3566 return_value
->type
= IS_OBJECT
;
3567 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
3570 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3573 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
3576 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
3579 zend_restore_error_handling(&zeh TSRMLS_CC
);
3582 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
3583 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3584 ZEND_ARG_INFO(0, callable
)
3585 ZEND_END_ARG_INFO();
3586 static PHP_METHOD(pqstm
, execAsync
) {
3587 zend_error_handling zeh
;
3588 zval
*zparams
= NULL
;
3589 php_pq_callback_t resolver
= {{0}};
3591 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3592 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
)) {
3593 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3596 if (obj
->intern
->conn
->intern
) {
3598 char **params
= NULL
;
3602 ZEND_INIT_SYMTABLE(&zdtor
);
3603 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3606 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
3607 if (resolver
.fci
.size
> 0) {
3608 obj
->intern
->conn
->intern
->onevent
= resolver
;
3609 php_pq_callback_addref(&obj
->intern
->conn
->intern
->onevent
);
3612 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3614 if (PQsendQueryPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
3615 if (obj
->intern
->conn
->intern
->unbuffered
) {
3616 if (!PQsetSingleRowMode(obj
->intern
->conn
->intern
->conn
)) {
3617 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3622 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3630 zend_hash_destroy(&zdtor
);
3633 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3636 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
3640 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
3644 zend_restore_error_handling(&zeh TSRMLS_CC
);
3647 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
3648 ZEND_END_ARG_INFO();
3649 static PHP_METHOD(pqstm
, desc
) {
3650 zend_error_handling zeh
;
3652 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3653 if (SUCCESS
== zend_parse_parameters_none()) {
3654 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3657 if (obj
->intern
->conn
->intern
) {
3658 PGresult
*res
= PQdescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
);
3660 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3663 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3666 array_init(return_value
);
3667 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
3668 add_next_index_long(return_value
, PQparamtype(res
, p
));
3672 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not describe statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3675 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
3678 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
3681 zend_restore_error_handling(&zeh TSRMLS_CC
);
3684 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async
, 0, 0, 0)
3685 ZEND_END_ARG_INFO();
3686 static PHP_METHOD(pqstm
, descAsync
) {
3687 zend_error_handling zeh
;
3689 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3690 if (SUCCESS
== zend_parse_parameters_none()) {
3691 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3695 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3697 if (PQsendDescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
)) {
3700 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not describe statement: %s", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3704 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3707 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Statement not initialized");
3711 zend_restore_error_handling(&zeh TSRMLS_CC
);
3715 static zend_function_entry php_pqstm_methods
[] = {
3716 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3717 PHP_ME(pqstm
, bind
, ai_pqstm_bind
, ZEND_ACC_PUBLIC
)
3718 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
3719 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
3720 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
3721 PHP_ME(pqstm
, descAsync
, ai_pqstm_desc_async
, ZEND_ACC_PUBLIC
)
3725 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
3726 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3727 ZEND_ARG_INFO(0, async
)
3728 ZEND_ARG_INFO(0, isolation
)
3729 ZEND_ARG_INFO(0, readonly
)
3730 ZEND_ARG_INFO(0, deferrable
)
3731 ZEND_END_ARG_INFO();
3732 static PHP_METHOD(pqtxn
, __construct
) {
3733 zend_error_handling zeh
;
3735 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3736 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
3738 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3739 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
)) {
3741 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3742 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3744 if (conn_obj
->intern
) {
3746 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3748 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3751 if (SUCCESS
== rv
) {
3752 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3754 php_pq_object_addref(conn_obj TSRMLS_CC
);
3755 obj
->intern
->conn
= conn_obj
;
3756 obj
->intern
->isolation
= isolation
;
3757 obj
->intern
->readonly
= readonly
;
3758 obj
->intern
->deferrable
= deferrable
;
3761 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
3764 zend_restore_error_handling(&zeh TSRMLS_CC
);
3767 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint
, 0, 0, 0)
3768 ZEND_END_ARG_INFO();
3769 static PHP_METHOD(pqtxn
, savepoint
) {
3770 zend_error_handling zeh
;
3772 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3773 if (SUCCESS
== zend_parse_parameters_none()) {
3774 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3780 spprintf(&cmd
, 0, "SAVEPOINT \"%u\"", ++obj
->intern
->savepoint
);
3781 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
);
3784 php_pqres_success(res TSRMLS_CC
);
3787 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to create %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3792 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
3795 zend_restore_error_handling(&zeh TSRMLS_CC
);
3798 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async
, 0, 0, 0)
3799 ZEND_END_ARG_INFO();
3800 static PHP_METHOD(pqtxn
, savepointAsync
) {
3801 zend_error_handling zeh
;
3803 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3804 if (SUCCESS
== zend_parse_parameters_none()) {
3805 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3810 spprintf(&cmd
, 0, "SAVEPOINT \"%u\"", ++obj
->intern
->savepoint
);
3811 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
)) {
3812 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to create %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3817 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
3820 zend_restore_error_handling(&zeh TSRMLS_CC
);
3823 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
3824 ZEND_END_ARG_INFO();
3825 static PHP_METHOD(pqtxn
, commit
) {
3826 zend_error_handling zeh
;
3828 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3829 if (SUCCESS
== zend_parse_parameters_none()) {
3830 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3835 if (obj
->intern
->savepoint
) {
3838 spprintf(&cmd
, 0, "RELEASE SAVEPOINT \"%u\"", obj
->intern
->savepoint
--);
3839 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
);
3842 php_pqres_success(res TSRMLS_CC
);
3845 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3850 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "COMMIT");
3853 php_pqres_success(res TSRMLS_CC
);
3856 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to commit transaction (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3860 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
3863 zend_restore_error_handling(&zeh TSRMLS_CC
);
3866 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
3867 ZEND_END_ARG_INFO();
3868 static PHP_METHOD(pqtxn
, commitAsync
) {
3869 zend_error_handling zeh
;
3871 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3872 if (SUCCESS
== zend_parse_parameters_none()) {
3873 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3876 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3878 if (obj
->intern
->savepoint
) {
3881 spprintf(&cmd
, 0, "RELEASE SAVEPOINT \"%u\"", obj
->intern
->savepoint
--);
3882 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
)) {
3883 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3888 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "COMMIT")) {
3889 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to commit transaction (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3893 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
3896 zend_restore_error_handling(&zeh TSRMLS_CC
);
3899 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
3900 ZEND_END_ARG_INFO();
3901 static PHP_METHOD(pqtxn
, rollback
) {
3902 zend_error_handling zeh
;
3904 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3905 if (SUCCESS
== zend_parse_parameters_none()) {
3906 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3911 if (obj
->intern
->savepoint
) {
3914 spprintf(&cmd
, 0, "ROLLBACK TO SAVEPOINT \"%u\"", obj
->intern
->savepoint
--);
3915 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
);
3918 php_pqres_success(res TSRMLS_CC
);
3921 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3926 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
3929 php_pqres_success(res TSRMLS_CC
);
3932 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to rollback transaction (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3936 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
3939 zend_restore_error_handling(&zeh TSRMLS_CC
);
3942 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
3943 ZEND_END_ARG_INFO();
3944 static PHP_METHOD(pqtxn
, rollbackAsync
) {
3945 zend_error_handling zeh
;
3947 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3948 if (SUCCESS
== zend_parse_parameters_none()) {
3949 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3952 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3954 if (obj
->intern
->savepoint
) {
3957 spprintf(&cmd
, 0, "ROLLBACK TO SAVEPOINT \"%u\"", obj
->intern
->savepoint
--);
3958 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
)) {
3959 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3964 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "ROLLBACK")) {
3965 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not rollback transaction (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3969 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
3972 zend_restore_error_handling(&zeh TSRMLS_CC
);
3975 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot
, 0, 0, 0)
3976 ZEND_END_ARG_INFO();
3977 static PHP_METHOD(pqtxn
, exportSnapshot
) {
3978 zend_error_handling zeh
;
3980 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3981 if (SUCCESS
== zend_parse_parameters_none()) {
3982 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3985 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()");
3988 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3989 RETVAL_STRING(PQgetvalue(res
, 0, 0), 1);
3994 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3997 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4000 zend_restore_error_handling(&zeh TSRMLS_CC
);
4003 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async
, 0, 0, 0)
4004 ZEND_END_ARG_INFO();
4005 static PHP_METHOD(pqtxn
, exportSnapshotAsync
) {
4006 zend_error_handling zeh
;
4008 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4009 if (SUCCESS
== zend_parse_parameters_none()) {
4010 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4013 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4015 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()")) {
4016 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4019 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4022 zend_restore_error_handling(&zeh TSRMLS_CC
);
4025 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot
, 0, 0, 1)
4026 ZEND_ARG_INFO(0, snapshot_id
)
4027 ZEND_END_ARG_INFO();
4028 static PHP_METHOD(pqtxn
, importSnapshot
) {
4029 zend_error_handling zeh
;
4033 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4034 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
)) {
4035 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4038 if (obj
->intern
->isolation
>= PHP_PQTXN_REPEATABLE_READ
) {
4039 char *cmd
, *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4042 spprintf(&cmd
, 0, "SET TRANSACTION SNAPSHOT %s", sid
);
4043 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
);
4046 php_pqres_success(res TSRMLS_CC
);
4049 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4052 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "A transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4055 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4058 zend_restore_error_handling(&zeh TSRMLS_CC
);
4061 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async
, 0, 0, 1)
4062 ZEND_ARG_INFO(0, snapshot_id
)
4063 ZEND_END_ARG_INFO();
4064 static PHP_METHOD(pqtxn
, importSnapshotAsync
) {
4065 zend_error_handling zeh
;
4069 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4070 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
)) {
4071 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4074 if (obj
->intern
->isolation
>= PHP_PQTXN_REPEATABLE_READ
) {
4075 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4079 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4081 spprintf(&cmd
, 0, "SET TRANSACTION SNAPSHOT %s", sid
);
4082 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
)) {
4083 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to %s (%s)", cmd
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4087 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4090 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "A transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4093 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4096 zend_restore_error_handling(&zeh TSRMLS_CC
);
4099 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob
, 0, 0, 1)
4100 ZEND_ARG_INFO(0, oid
)
4101 ZEND_ARG_INFO(0, mode
)
4102 ZEND_END_ARG_INFO();
4103 static PHP_METHOD(pqtxn
, openLOB
) {
4104 zend_error_handling zeh
;
4105 long mode
= INV_WRITE
|INV_READ
, loid
;
4107 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4108 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &loid
, &mode
)) {
4109 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4112 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4115 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4119 php_pq_object_addref(obj TSRMLS_CC
);
4122 return_value
->type
= IS_OBJECT
;
4123 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4125 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to open large object with mode '%s' (%s)",
4126 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4127 (mode
& INV_READ
? "r" :
4128 (mode
& INV_WRITE
? "w" : "-"))),
4129 PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
)
4133 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4136 zend_restore_error_handling(&zeh TSRMLS_CC
);
4139 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob
, 0, 0, 0)
4140 ZEND_ARG_INFO(0, mode
)
4141 ZEND_END_ARG_INFO();
4142 static PHP_METHOD(pqtxn
, createLOB
) {
4143 zend_error_handling zeh
;
4144 long mode
= INV_WRITE
|INV_READ
;
4146 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4147 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &mode
)) {
4148 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4151 Oid loid
= lo_creat(obj
->intern
->conn
->intern
->conn
, mode
);
4153 if (loid
!= InvalidOid
) {
4154 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4157 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4160 php_pq_object_addref(obj TSRMLS_CC
);
4163 return_value
->type
= IS_OBJECT
;
4164 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4166 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to open large object with mode '%s': %s",
4167 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4168 (mode
& INV_READ
? "r" :
4169 (mode
& INV_WRITE
? "w" : "-"))),
4170 PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
)
4174 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to create large object with mode '%s': %s",
4175 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4176 (mode
& INV_READ
? "r" :
4177 (mode
& INV_WRITE
? "w" : "-"))),
4178 PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
)
4182 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4185 zend_restore_error_handling(&zeh TSRMLS_CC
);
4188 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob
, 0, 0, 1)
4189 ZEND_ARG_INFO(0, oid
)
4190 ZEND_END_ARG_INFO();
4191 static PHP_METHOD(pqtxn
, unlinkLOB
) {
4194 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &loid
)) {
4195 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4198 if (1 == lo_unlink(obj
->intern
->conn
->intern
->conn
, loid
)) {
4201 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unlink LOB (oid=%ld): %s", loid
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4205 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4211 static zend_function_entry php_pqtxn_methods
[] = {
4212 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4213 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
4214 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
4215 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
4216 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
4217 PHP_ME(pqtxn
, savepoint
, ai_pqtxn_savepoint
, ZEND_ACC_PUBLIC
)
4218 PHP_ME(pqtxn
, savepointAsync
, ai_pqtxn_savepoint_async
, ZEND_ACC_PUBLIC
)
4219 PHP_ME(pqtxn
, exportSnapshot
, ai_pqtxn_export_snapshot
, ZEND_ACC_PUBLIC
)
4220 PHP_ME(pqtxn
, exportSnapshotAsync
, ai_pqtxn_export_snapshot_async
, ZEND_ACC_PUBLIC
)
4221 PHP_ME(pqtxn
, importSnapshot
, ai_pqtxn_import_snapshot
, ZEND_ACC_PUBLIC
)
4222 PHP_ME(pqtxn
, importSnapshotAsync
, ai_pqtxn_import_snapshot_async
, ZEND_ACC_PUBLIC
)
4223 PHP_ME(pqtxn
, openLOB
, ai_pqtxn_open_lob
, ZEND_ACC_PUBLIC
)
4224 PHP_ME(pqtxn
, createLOB
, ai_pqtxn_create_lob
, ZEND_ACC_PUBLIC
)
4225 PHP_ME(pqtxn
, unlinkLOB
, ai_pqtxn_unlink_lob
, ZEND_ACC_PUBLIC
)
4229 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
4230 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4231 ZEND_END_ARG_INFO();
4232 static PHP_METHOD(pqcancel
, __construct
) {
4233 zend_error_handling zeh
;
4236 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4237 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
)) {
4238 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4240 if (conn_obj
->intern
) {
4241 PGcancel
*cancel
= PQgetCancel(conn_obj
->intern
->conn
);
4244 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4246 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4247 obj
->intern
->cancel
= cancel
;
4248 php_pq_object_addref(conn_obj TSRMLS_CC
);
4249 obj
->intern
->conn
= conn_obj
;
4251 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not acquire cancel (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
4254 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
4257 zend_restore_error_handling(&zeh TSRMLS_CC
);
4260 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
4261 ZEND_END_ARG_INFO();
4262 static PHP_METHOD(pqcancel
, cancel
) {
4263 zend_error_handling zeh
;
4265 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4266 if (SUCCESS
== zend_parse_parameters_none()) {
4267 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4272 if (!PQcancel(obj
->intern
->cancel
, err
, sizeof(err
))) {
4273 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not request cancellation: %s", err
);
4276 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Cancel not initialized");
4279 zend_restore_error_handling(&zeh TSRMLS_CC
);
4282 static zend_function_entry php_pqcancel_methods
[] = {
4283 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4284 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
4288 static void php_pqconn_add_eventhandler(zval
*zconn
, php_pqconn_object_t
*conn_obj
, const char *type_str
, size_t type_len
, zval
*zevent TSRMLS_DC
)
4292 if (SUCCESS
== zend_hash_find(&conn_obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
4294 add_next_index_zval(*evhs
, zevent
);
4301 add_next_index_zval(evh
, zevent
);
4302 zend_hash_add(&conn_obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(zval
*), NULL
);
4306 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_construct
, 0, 0, 3)
4307 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4308 ZEND_ARG_INFO(0, type
)
4309 ZEND_ARG_INFO(0, callable
)
4310 ZEND_END_ARG_INFO();
4311 static PHP_METHOD(pqevent
, __construct
) {
4312 zend_error_handling zeh
;
4316 php_pq_callback_t cb
;
4318 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4319 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Osf", &zconn
, php_pqconn_class_entry
, &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
)) {
4320 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4322 if (conn_obj
->intern
) {
4323 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4325 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4326 php_pq_callback_addref(&cb
);
4327 obj
->intern
->cb
= cb
;
4328 php_pq_object_addref(conn_obj TSRMLS_CC
);
4329 obj
->intern
->conn
= conn_obj
;
4330 obj
->intern
->type
= estrdup(type_str
);
4332 php_pqconn_add_eventhandler(zconn
, conn_obj
, type_str
, type_len
, getThis() TSRMLS_CC
);
4335 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
4338 zend_restore_error_handling(&zeh TSRMLS_CC
);
4341 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_trigger
, 0, 0, 1)
4342 ZEND_ARG_ARRAY_INFO(0, args
, 1)
4343 ZEND_END_ARG_INFO();
4344 static PHP_METHOD(pqevent
, trigger
) {
4347 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a/", &args
)) {
4348 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4353 if (SUCCESS
== zend_fcall_info_call(&obj
->intern
->cb
.fci
, &obj
->intern
->cb
.fcc
, &rv
, args TSRMLS_CC
)) {
4355 RETVAL_ZVAL(rv
, 0, 1);
4361 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Event not initialized");
4367 static zend_function_entry php_pqevent_methods
[] = {
4368 PHP_ME(pqevent
, __construct
, ai_pqevent_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4369 PHP_ME(pqevent
, trigger
, ai_pqevent_trigger
, ZEND_ACC_PUBLIC
)
4373 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct
, 0, 0, 1)
4374 ZEND_ARG_OBJ_INFO(0, transaction
, pq
\\Transaction
, 0)
4375 ZEND_ARG_INFO(0, oid
)
4376 ZEND_ARG_INFO(0, mode
)
4377 ZEND_END_ARG_INFO();
4378 static PHP_METHOD(pqlob
, __construct
) {
4379 zend_error_handling zeh
;
4381 long mode
= INV_WRITE
|INV_READ
, loid
= InvalidOid
;
4383 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4384 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|ll", &ztxn
, php_pqtxn_class_entry
, &loid
, &mode
)) {
4385 php_pqtxn_object_t
*txn_obj
= zend_object_store_get_object(ztxn TSRMLS_CC
);
4387 if (txn_obj
->intern
) {
4389 if (loid
== InvalidOid
) {
4390 loid
= lo_creat(txn_obj
->intern
->conn
->intern
->conn
, mode
);
4393 if (loid
!= InvalidOid
) {
4394 int lofd
= lo_open(txn_obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4397 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4399 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4400 obj
->intern
->lofd
= lofd
;
4401 obj
->intern
->loid
= loid
;
4402 php_pq_object_addref(txn_obj TSRMLS_CC
);
4403 obj
->intern
->txn
= txn_obj
;
4405 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to open large object with mode '%s' (%s)",
4406 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4407 (mode
& INV_READ
? "r" :
4408 (mode
& INV_WRITE
? "w" : "-"))),
4409 PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
)
4413 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to create large object with mode '%s' (%s)",
4414 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4415 (mode
& INV_READ
? "r" :
4416 (mode
& INV_WRITE
? "w" : "-"))),
4417 PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
)
4421 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4424 zend_restore_error_handling(&zeh TSRMLS_CC
);
4427 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write
, 0, 0, 1)
4428 ZEND_ARG_INFO(0, data
)
4429 ZEND_END_ARG_INFO();
4430 static PHP_METHOD(pqlob
, write
) {
4434 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
)) {
4435 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4438 int written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, data_str
, data_len
);
4441 RETVAL_LONG(written
);
4443 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to write to LOB, oid=%d (%s)", obj
->intern
->loid
,
4444 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4448 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4454 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read
, 0, 0, 0)
4455 ZEND_ARG_INFO(0, length
)
4456 ZEND_ARG_INFO(1, read
)
4457 ZEND_END_ARG_INFO();
4458 static PHP_METHOD(pqlob
, read
) {
4459 long length
= 0x1000;
4462 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lz!", &length
, &zread
)) {
4463 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4466 char *buffer
= emalloc(length
+ 1);
4467 int read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4472 ZVAL_LONG(zread
, read
);
4474 buffer
[read
] = '\0';
4475 RETVAL_STRINGL(buffer
, read
, 0);
4478 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to read from LOB, oid=%d (%s)", obj
->intern
->loid
,
4479 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4484 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4490 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek
, 0, 0, 1)
4491 ZEND_ARG_INFO(0, offset
)
4492 ZEND_ARG_INFO(0, whence
)
4493 ZEND_END_ARG_INFO();
4494 static PHP_METHOD(pqlob
, seek
) {
4495 long offset
, whence
= SEEK_SET
;
4497 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &offset
, &whence
)) {
4498 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4501 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4503 if (position
>= 0) {
4504 RETVAL_LONG(position
);
4506 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to seek offset in LOB, oid=%d (%s)", obj
->intern
->loid
,
4507 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4511 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4517 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell
, 0, 0, 0)
4518 ZEND_END_ARG_INFO();
4519 static PHP_METHOD(pqlob
, tell
) {
4520 if (SUCCESS
== zend_parse_parameters_none()) {
4521 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4524 int position
= lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
4526 if (position
>= 0) {
4527 RETVAL_LONG(position
);
4529 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to tell offset in LOB (oid=%d): %s", obj
->intern
->loid
,
4530 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4534 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4540 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate
, 0, 0, 0)
4541 ZEND_ARG_INFO(0, length
)
4542 ZEND_END_ARG_INFO();
4543 static PHP_METHOD(pqlob
, truncate
) {
4546 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &length
)) {
4547 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4550 if (0 == lo_truncate(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, length
)) {
4553 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to truncate LOB (oid=%d): %s", obj
->intern
->loid
,
4554 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4558 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4564 static zend_function_entry php_pqlob_methods
[] = {
4565 PHP_ME(pqlob
, __construct
, ai_pqlob_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4566 PHP_ME(pqlob
, write
, ai_pqlob_write
, ZEND_ACC_PUBLIC
)
4567 PHP_ME(pqlob
, read
, ai_pqlob_read
, ZEND_ACC_PUBLIC
)
4568 PHP_ME(pqlob
, seek
, ai_pqlob_seek
, ZEND_ACC_PUBLIC
)
4569 PHP_ME(pqlob
, tell
, ai_pqlob_tell
, ZEND_ACC_PUBLIC
)
4570 PHP_ME(pqlob
, truncate
, ai_pqlob_truncate
, ZEND_ACC_PUBLIC
)
4574 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct
, 0, 0, 3)
4575 ZEND_ARG_OBJ_INFO(0, "connection", pq
\\Connection
, 0)
4576 ZEND_ARG_INFO(0, expression
)
4577 ZEND_ARG_INFO(0, direction
)
4578 ZEND_ARG_INFO(0, options
)
4579 ZEND_END_ARG_INFO();
4580 static PHP_METHOD(pqcopy
, __construct
) {
4581 zend_error_handling zeh
;
4583 char *expr_str
, *opt_str
= "";
4584 int expr_len
, opt_len
= 0;
4587 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4588 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Osl|s", &zconn
, php_pqconn_class_entry
, &expr_str
, &expr_len
, &direction
, &opt_str
, &opt_len
)) {
4589 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4591 if (conn_obj
->intern
) {
4594 switch (direction
) {
4595 case PHP_PQCOPY_FROM_STDIN
:
4596 spprintf(©
, 0, "COPY %s %s %s", expr_str
, "FROM STDIN", opt_str
);
4599 case PHP_PQCOPY_TO_STDOUT
:
4600 spprintf(©
, 0, "COPY %s %s %s", expr_str
, "TO STDOUT", opt_str
);
4604 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid COPY direction, expected one of FROM_STDIN (%d) TO_STDOUT (%d), got %ld",
4605 PHP_PQCOPY_FROM_STDIN
, PHP_PQCOPY_TO_STDOUT
, direction
);
4610 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4611 PGresult
*res
= PQexec(conn_obj
->intern
->conn
, copy
);
4615 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4616 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4617 obj
->intern
->direction
= direction
;
4618 obj
->intern
->expression
= estrdup(expr_str
);
4619 obj
->intern
->options
= estrdup(opt_str
);
4620 obj
->intern
->conn
= conn_obj
;
4621 php_pq_object_addref(conn_obj TSRMLS_CC
);
4627 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
4630 zend_restore_error_handling(&zeh TSRMLS_CC
);
4633 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put
, 0, 0, 1)
4634 ZEND_ARG_INFO(0, data
)
4635 ZEND_END_ARG_INFO();
4636 static PHP_METHOD(pqcopy
, put
) {
4637 zend_error_handling zeh
;
4641 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4642 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
)) {
4643 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4646 if (PHP_PQCOPY_FROM_STDIN
== obj
->intern
->direction
) {
4647 if (1 == PQputCopyData(obj
->intern
->conn
->intern
->conn
, data_str
, data_len
)) {
4650 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to send COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4653 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY was not initialized with FROM_STDIN");
4656 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY not initialized");
4659 zend_restore_error_handling(&zeh TSRMLS_CC
);
4662 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end
, 0, 0, 0)
4663 ZEND_ARG_INFO(0, error
)
4664 ZEND_END_ARG_INFO();
4665 static PHP_METHOD(pqcopy
, end
) {
4666 zend_error_handling zeh
;
4667 char *error_str
= NULL
;
4670 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4671 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &error_str
, &error_len
)) {
4672 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4675 if (PHP_PQCOPY_FROM_STDIN
== obj
->intern
->direction
) {
4676 if (1 == PQputCopyEnd(obj
->intern
->conn
->intern
->conn
, error_str
)) {
4677 PGresult
*res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
4680 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4686 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to get COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4689 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4692 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY was not initialized with FROM_STDIN");
4695 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY not initialized");
4698 zend_restore_error_handling(&zeh TSRMLS_CC
);
4701 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get
, 0, 0, 1)
4702 ZEND_ARG_INFO(1, data
)
4703 ZEND_END_ARG_INFO();
4704 static PHP_METHOD(pqcopy
, get
) {
4705 zend_error_handling zeh
;
4708 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4709 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
)) {
4710 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4711 char *buffer
= NULL
;
4714 if (PHP_PQCOPY_TO_STDOUT
== obj
->intern
->direction
) {
4716 int bytes
= PQgetCopyData(obj
->intern
->conn
->intern
->conn
, &buffer
, 0);
4720 res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
4723 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4729 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to get COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4734 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to get COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4740 ZVAL_STRINGL(zdata
, buffer
, bytes
, 1);
4742 ZVAL_EMPTY_STRING(zdata
);
4754 zend_restore_error_handling(&zeh TSRMLS_CC
);
4757 static zend_function_entry php_pqcopy_methods
[] = {
4758 PHP_ME(pqcopy
, __construct
, ai_pqcopy_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4759 PHP_ME(pqcopy
, put
, ai_pqcopy_put
, ZEND_ACC_PUBLIC
)
4760 PHP_ME(pqcopy
, end
, ai_pqcopy_end
, ZEND_ACC_PUBLIC
)
4761 PHP_ME(pqcopy
, get
, ai_pqcopy_get
, ZEND_ACC_PUBLIC
)
4765 /* {{{ PHP_MINIT_FUNCTION
4767 static PHP_MINIT_FUNCTION(pq
)
4769 zend_class_entry ce
= {0};
4770 php_pq_object_prophandler_t ph
= {0};
4772 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
4773 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
4774 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
4776 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
4777 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
4778 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
4779 php_pqconn_object_handlers
.clone_obj
= NULL
;
4780 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
4781 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
4783 zend_hash_init(&php_pqconn_object_prophandlers
, 13, NULL
, NULL
, 1);
4785 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
4786 ph
.read
= php_pqconn_object_read_status
;
4787 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
4789 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
4790 ph
.read
= php_pqconn_object_read_transaction_status
;
4791 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
4793 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4794 ph
.read
= NULL
; /* forward to std prophandler */
4795 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
4797 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4798 ph
.read
= php_pqconn_object_read_error_message
;
4799 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
4801 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
4802 ph
.read
= php_pqconn_object_read_busy
;
4803 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
4805 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4806 ph
.read
= php_pqconn_object_read_encoding
;
4807 ph
.write
= php_pqconn_object_write_encoding
;
4808 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
4811 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
4812 ph
.read
= php_pqconn_object_read_unbuffered
;
4813 ph
.write
= php_pqconn_object_write_unbuffered
;
4814 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
4817 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4818 ph
.read
= php_pqconn_object_read_db
;
4819 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
4821 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4822 ph
.read
= php_pqconn_object_read_user
;
4823 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
4825 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4826 ph
.read
= php_pqconn_object_read_pass
;
4827 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
4829 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4830 ph
.read
= php_pqconn_object_read_host
;
4831 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
4833 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4834 ph
.read
= php_pqconn_object_read_port
;
4835 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
4837 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4838 ph
.read
= php_pqconn_object_read_options
;
4839 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
4841 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
4842 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
4843 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
4844 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
4845 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
4846 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
4847 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
4848 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
4850 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
4851 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
4852 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
4853 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
4854 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
4856 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
4857 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
4858 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
4859 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
4861 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
4862 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
4863 memset(&ce
, 0, sizeof(ce
));
4864 INIT_NS_CLASS_ENTRY(ce
, "pq", "Types", php_pqtypes_methods
);
4865 php_pqtypes_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
4866 php_pqtypes_class_entry
->create_object
= php_pqtypes_create_object
;
4868 memcpy(&php_pqtypes_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
4869 php_pqtypes_object_handlers
.read_property
= php_pq_object_read_prop
;
4870 php_pqtypes_object_handlers
.write_property
= php_pq_object_write_prop
;
4871 php_pqtypes_object_handlers
.clone_obj
= NULL
;
4872 php_pqtypes_object_handlers
.get_property_ptr_ptr
= NULL
;
4873 php_pqtypes_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
4874 php_pqtypes_object_handlers
.has_dimension
= php_pqtypes_object_has_dimension
;
4875 php_pqtypes_object_handlers
.read_dimension
= php_pqtypes_object_read_dimension
;
4876 php_pqtypes_object_handlers
.unset_dimension
= NULL
;
4877 php_pqtypes_object_handlers
.write_dimension
= NULL
;
4879 zend_hash_init(&php_pqtypes_object_prophandlers
, 1, NULL
, NULL
, 1);
4881 zend_declare_property_null(php_pqtypes_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4882 ph
.read
= php_pqtypes_object_read_connection
;
4883 zend_hash_add(&php_pqtypes_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
4885 memset(&ce
, 0, sizeof(ce
));
4886 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
4887 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
4888 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
4889 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
4890 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
4891 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 2, zend_ce_traversable
, spl_ce_Countable
);
4893 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
4894 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
4895 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
4896 php_pqres_object_handlers
.clone_obj
= NULL
;
4897 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
4898 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
4899 php_pqres_object_handlers
.count_elements
= php_pqres_count_elements
;
4901 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
4903 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4904 ph
.read
= php_pqres_object_read_status
;
4905 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
4907 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4908 ph
.read
= php_pqres_object_read_error_message
;
4909 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
4911 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
4912 ph
.read
= php_pqres_object_read_num_rows
;
4913 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
4915 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
4916 ph
.read
= php_pqres_object_read_num_cols
;
4917 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
4919 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
4920 ph
.read
= php_pqres_object_read_affected_rows
;
4921 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
4923 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
4924 ph
.read
= php_pqres_object_read_fetch_type
;
4925 ph
.write
= php_pqres_object_write_fetch_type
;
4926 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
4929 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
4930 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
4931 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
4932 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
4933 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
4934 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
4935 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
4936 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
4937 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
4938 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
4940 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
4941 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
4942 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
4944 memset(&ce
, 0, sizeof(ce
));
4945 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
4946 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
4947 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
4949 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
4950 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
4951 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
4952 php_pqstm_object_handlers
.clone_obj
= NULL
;
4953 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
4954 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
4956 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
4958 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4959 ph
.read
= php_pqstm_object_read_name
;
4960 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
4962 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4963 ph
.read
= php_pqstm_object_read_connection
;
4964 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
4966 memset(&ce
, 0, sizeof(ce
));
4967 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
4968 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
4969 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
4971 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
4972 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
4973 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
4974 php_pqtxn_object_handlers
.clone_obj
= NULL
;
4975 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
4976 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
4978 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
4980 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4981 ph
.read
= php_pqtxn_object_read_connection
;
4982 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
4984 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4985 ph
.read
= php_pqtxn_object_read_isolation
;
4986 ph
.write
= php_pqtxn_object_write_isolation
;
4987 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
4989 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("readonly"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4990 ph
.read
= php_pqtxn_object_read_readonly
;
4991 ph
.write
= php_pqtxn_object_write_readonly
;
4992 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
4994 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4995 ph
.read
= php_pqtxn_object_read_deferrable
;
4996 ph
.write
= php_pqtxn_object_write_deferrable
;
4997 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
5000 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
5001 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
5002 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
5004 memset(&ce
, 0, sizeof(ce
));
5005 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
5006 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5007 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
5009 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5010 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
5011 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
5012 php_pqcancel_object_handlers
.clone_obj
= NULL
;
5013 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
5014 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5016 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
5018 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5019 ph
.read
= php_pqcancel_object_read_connection
;
5020 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5022 memset(&ce
, 0, sizeof(ce
));
5023 INIT_NS_CLASS_ENTRY(ce
, "pq", "Event", php_pqevent_methods
);
5024 php_pqevent_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5025 php_pqevent_class_entry
->create_object
= php_pqevent_create_object
;
5027 memcpy(&php_pqevent_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5028 php_pqevent_object_handlers
.read_property
= php_pq_object_read_prop
;
5029 php_pqevent_object_handlers
.write_property
= php_pq_object_write_prop
;
5030 php_pqevent_object_handlers
.clone_obj
= NULL
;
5031 php_pqevent_object_handlers
.get_property_ptr_ptr
= NULL
;
5032 php_pqevent_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5034 zend_hash_init(&php_pqevent_object_prophandlers
, 2, NULL
, NULL
, 1);
5036 zend_declare_property_null(php_pqevent_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5037 ph
.read
= php_pqevent_object_read_connection
;
5038 zend_hash_add(&php_pqevent_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5040 zend_declare_property_null(php_pqevent_class_entry
, ZEND_STRL("type"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5041 ph
.read
= php_pqevent_object_read_type
;
5042 zend_hash_add(&php_pqevent_object_prophandlers
, "type", sizeof("type"), (void *) &ph
, sizeof(ph
), NULL
);
5044 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
5045 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESULT"), ZEND_STRL("result") TSRMLS_CC
);
5046 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESET"), ZEND_STRL("reset") TSRMLS_CC
);
5048 memset(&ce
, 0, sizeof(ce
));
5049 INIT_NS_CLASS_ENTRY(ce
, "pq", "LOB", php_pqlob_methods
);
5050 php_pqlob_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5051 php_pqlob_class_entry
->create_object
= php_pqlob_create_object
;
5053 memcpy(&php_pqlob_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5054 php_pqlob_object_handlers
.read_property
= php_pq_object_read_prop
;
5055 php_pqlob_object_handlers
.write_property
= php_pq_object_write_prop
;
5056 php_pqlob_object_handlers
.clone_obj
= NULL
;
5057 php_pqlob_object_handlers
.get_property_ptr_ptr
= NULL
;
5058 php_pqlob_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5060 zend_hash_init(&php_pqlob_object_prophandlers
, 2, NULL
, NULL
, 1);
5062 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5063 ph
.read
= php_pqlob_object_read_transaction
;
5064 zend_hash_add(&php_pqlob_object_prophandlers
, "transaction", sizeof("transaction"), (void *) &ph
, sizeof(ph
), NULL
);
5066 zend_declare_property_long(php_pqlob_class_entry
, ZEND_STRL("oid"), InvalidOid
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5067 ph
.read
= php_pqlob_object_read_oid
;
5068 zend_hash_add(&php_pqlob_object_prophandlers
, "oid", sizeof("oid"), (void *) &ph
, sizeof(ph
), NULL
);
5070 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC
);
5071 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("R"), INV_READ TSRMLS_CC
);
5072 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("W"), INV_WRITE TSRMLS_CC
);
5073 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("RW"), INV_READ
|INV_WRITE TSRMLS_CC
);
5075 memset(&ce
, 0, sizeof(ce
));
5076 INIT_NS_CLASS_ENTRY(ce
, "pq", "COPY", php_pqcopy_methods
);
5077 php_pqcopy_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5078 php_pqcopy_class_entry
->create_object
= php_pqcopy_create_object
;
5080 memcpy(&php_pqcopy_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5081 php_pqcopy_object_handlers
.read_property
= php_pq_object_read_prop
;
5082 php_pqcopy_object_handlers
.write_property
= php_pq_object_write_prop
;
5083 php_pqcopy_object_handlers
.clone_obj
= NULL
;
5084 php_pqcopy_object_handlers
.get_property_ptr_ptr
= NULL
;
5085 php_pqcopy_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5087 zend_hash_init(&php_pqcopy_object_prophandlers
, 4, NULL
, NULL
, 1);
5089 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5090 ph
.read
= php_pqcopy_object_read_connection
;
5091 zend_hash_add(&php_pqcopy_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5093 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5094 ph
.read
= php_pqcopy_object_read_expression
;
5095 zend_hash_add(&php_pqcopy_object_prophandlers
, "expression", sizeof("expression"), (void *) &ph
, sizeof(ph
), NULL
);
5097 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5098 ph
.read
= php_pqcopy_object_read_direction
;
5099 zend_hash_add(&php_pqcopy_object_prophandlers
, "direction", sizeof("direction"), (void *) &ph
, sizeof(ph
), NULL
);
5101 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5102 ph
.read
= php_pqcopy_object_read_options
;
5103 zend_hash_add(&php_pqcopy_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5105 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC
);
5106 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC
);
5108 php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops
, NULL
, NULL TSRMLS_CC
);
5111 REGISTER_INI_ENTRIES();
5117 /* {{{ PHP_MSHUTDOWN_FUNCTION
5119 static PHP_MSHUTDOWN_FUNCTION(pq
)
5121 /* uncomment this line if you have INI entries
5122 UNREGISTER_INI_ENTRIES();
5124 php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL
, 0 TSRMLS_CC
);
5129 /* {{{ PHP_MINFO_FUNCTION
5131 static PHP_MINFO_FUNCTION(pq
)
5133 #ifdef HAVE_PQLIBVERSION
5136 char libpq_version
[10] = "pre-9.1";
5138 php_info_print_table_start();
5139 php_info_print_table_header(2, "PQ Support", "enabled");
5140 php_info_print_table_row(2, "Extension Version", PHP_PQ_EXT_VERSION
);
5141 php_info_print_table_end();
5143 php_info_print_table_start();
5144 php_info_print_table_header(2, "Used Library", "Version");
5145 #ifdef HAVE_PQLIBVERSION
5146 libpq_v
= PQlibVersion();
5147 slprintf(libpq_version
, sizeof(libpq_version
), "%d.%d.%d", libpq_v
/10000%100, libpq_v
/100%100, libpq_v
%100);
5149 php_info_print_table_row(2, "libpq", libpq_version
);
5150 php_info_print_table_end();
5152 /* Remove comments if you have entries in php.ini
5153 DISPLAY_INI_ENTRIES();
5158 const zend_function_entry pq_functions
[] = {
5162 static zend_module_dep pq_module_deps
[] = {
5163 ZEND_MOD_REQUIRED("raphf")
5164 ZEND_MOD_REQUIRED("spl")
5168 /* {{{ pq_module_entry
5170 zend_module_entry pq_module_entry
= {
5171 STANDARD_MODULE_HEADER_EX
,
5178 NULL
,/*PHP_RINIT(pq),*/
5179 NULL
,/*PHP_RSHUTDOWN(pq),*/
5182 STANDARD_MODULE_PROPERTIES
5186 #ifdef COMPILE_DL_PQ
5196 * vim600: noet sw=4 ts=4 fdm=marker
5197 * vim<600: noet sw=4 ts=4