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 <Zend/zend_exceptions.h>
22 #include <ext/standard/info.h>
23 #include <ext/standard/php_smart_str.h>
24 #include <ext/spl/spl_array.h>
25 #include <ext/spl/spl_exceptions.h>
26 #include <ext/raphf/php_raphf.h>
28 #include <libpq-events.h>
29 #include <libpq/libpq-fs.h>
34 typedef int STATUS
; /* SUCCESS/FAILURE */
36 static char *rtrim(char *e
) {
39 while (l
-- > 0 && e
[l
] == '\n') {
45 #define PHP_PQerrorMessage(c) rtrim(PQerrorMessage((c)))
46 #define PHP_PQresultErrorMessage(r) rtrim(PQresultErrorMessage((r)))
48 static int php_pqconn_event(PGEventId id
, void *e
, void *data
);
50 #define PHP_PQclear(_r) \
52 zval *_resinszv = PQresultInstanceData((_r), php_pqconn_event); \
53 if (!_resinszv) PQclear((_r)); \
57 ZEND_DECLARE_MODULE_GLOBALS(pq)
62 /* Remove comments and fill if you need to have entries in php.ini
64 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
65 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
70 /* {{{ php_pq_init_globals
72 /* Uncomment this function if you have INI entries
73 static void php_pq_init_globals(zend_pq_globals *pq_globals)
75 pq_globals->global_value = 0;
76 pq_globals->global_string = NULL;
81 static zend_class_entry
*php_pqconn_class_entry
;
82 static zend_class_entry
*php_pqtypes_class_entry
;
83 static zend_class_entry
*php_pqres_class_entry
;
84 static zend_class_entry
*php_pqstm_class_entry
;
85 static zend_class_entry
*php_pqtxn_class_entry
;
86 static zend_class_entry
*php_pqcancel_class_entry
;
87 static zend_class_entry
*php_pqevent_class_entry
;
88 static zend_class_entry
*php_pqlob_class_entry
;
89 static zend_class_entry
*php_pqcopy_class_entry
;
91 typedef enum php_pqexc_type
{
99 static zend_class_entry
*php_pqexc_interface_class_entry
;
100 static zend_class_entry
*php_pqexc_default_class_entry
;
101 static zend_class_entry
*php_pqexc_invalid_argument_class_entry
;
102 static zend_class_entry
*php_pqexc_runtime_class_entry
;
103 static zend_class_entry
*php_pqexc_bad_methodcall_class_entry
;
105 static zend_class_entry
*exce(php_pqexc_type_t type
)
110 return php_pqexc_default_class_entry
;
111 case EX_INVALID_ARGUMENT
:
112 return php_pqexc_invalid_argument_class_entry
;
114 case EX_CONNECTION_FAILED
:
115 return php_pqexc_runtime_class_entry
;
116 case EX_BAD_METHODCALL
:
117 return php_pqexc_bad_methodcall_class_entry
;
121 static zend_object_handlers php_pqconn_object_handlers
;
122 static zend_object_handlers php_pqtypes_object_handlers
;
123 static zend_object_handlers php_pqres_object_handlers
;
124 static zend_object_handlers php_pqstm_object_handlers
;
125 static zend_object_handlers php_pqtxn_object_handlers
;
126 static zend_object_handlers php_pqcancel_object_handlers
;
127 static zend_object_handlers php_pqevent_object_handlers
;
128 static zend_object_handlers php_pqlob_object_handlers
;
129 static zend_object_handlers php_pqcopy_object_handlers
;
131 typedef struct php_pq_callback
{
133 zend_fcall_info_cache fcc
;
137 typedef struct php_pq_object
{
139 zend_object_value zv
;
140 HashTable
*prophandler
;
144 #define PHP_PQCONN_ASYNC 0x01
145 #define PHP_PQCONN_PERSISTENT 0x02
147 typedef struct php_pqconn
{
149 int (*poller
)(PGconn
*);
150 php_resource_factory_t factory
;
152 HashTable eventhandlers
;
153 php_pq_callback_t onevent
;
154 unsigned unbuffered
:1;
157 typedef struct php_pqconn_object
{
159 zend_object_value zv
;
160 HashTable
*prophandler
;
161 php_pqconn_t
*intern
;
162 } php_pqconn_object_t
;
164 typedef struct php_pqtypes
{
166 php_pqconn_object_t
*conn
;
169 typedef struct php_pqtypes_object
{
171 zend_object_value zv
;
172 HashTable
*prophandler
;
173 php_pqtypes_t
*intern
;
174 } php_pqtypes_object_t
;
176 typedef struct php_pqconn_event_data
{
177 php_pqconn_object_t
*obj
;
181 } php_pqconn_event_data_t
;
183 typedef enum php_pqres_fetch
{
184 PHP_PQRES_FETCH_ARRAY
,
185 PHP_PQRES_FETCH_ASSOC
,
186 PHP_PQRES_FETCH_OBJECT
189 typedef struct php_pqres_iterator
{
190 zend_object_iterator zi
;
193 php_pqres_fetch_t fetch_type
;
194 } php_pqres_iterator_t
;
196 typedef struct php_pqres
{
198 php_pqres_iterator_t
*iter
;
202 typedef struct php_pqres_object
{
204 zend_object_value zv
;
205 HashTable
*prophandler
;
207 } php_pqres_object_t
;
209 typedef struct php_pqstm
{
210 php_pqconn_object_t
*conn
;
215 typedef struct php_pqstm_object
{
217 zend_object_value zv
;
218 HashTable
*prophandler
;
220 } php_pqstm_object_t
;
222 typedef enum php_pqtxn_isolation
{
223 PHP_PQTXN_READ_COMMITTED
,
224 PHP_PQTXN_REPEATABLE_READ
,
225 PHP_PQTXN_SERIALIZABLE
,
226 } php_pqtxn_isolation_t
;
228 typedef struct php_pqtxn
{
229 php_pqconn_object_t
*conn
;
230 php_pqtxn_isolation_t isolation
;
234 unsigned deferrable
:1;
237 typedef struct php_pqtxn_object
{
239 zend_object_value zv
;
240 HashTable
*prophandler
;
242 } php_pqtxn_object_t
;
244 typedef struct php_pqcancel
{
246 php_pqconn_object_t
*conn
;
249 typedef struct php_pqcancel_object
{
251 zend_object_value zv
;
252 HashTable
*prophandler
;
253 php_pqcancel_t
*intern
;
254 } php_pqcancel_object_t
;
256 typedef struct php_pqevent
{
257 php_pq_callback_t cb
;
258 php_pqconn_object_t
*conn
;
262 typedef struct php_pqevent_object
{
264 zend_object_value zv
;
265 HashTable
*prophandler
;
266 php_pqevent_t
*intern
;
267 } php_pqevent_object_t
;
269 typedef struct php_pqlob
{
272 php_pqtxn_object_t
*txn
;
275 typedef struct php_pqlob_object
{
277 zend_object_value zv
;
278 HashTable
*prophandler
;
280 } php_pqlob_object_t
;
282 typedef enum php_pqcopy_direction
{
283 PHP_PQCOPY_FROM_STDIN
,
285 } php_pqcopy_direction_t
;
287 typedef enum php_pqcopy_status
{
291 } php_pqcopy_status_t
;
293 typedef struct php_pqcopy
{
294 php_pqcopy_direction_t direction
;
297 php_pqconn_object_t
*conn
;
300 typedef struct php_pqcopy_object
{
302 zend_object_value zv
;
303 HashTable
*prophandler
;
304 php_pqcopy_t
*intern
;
305 } php_pqcopy_object_t
;
307 static HashTable php_pqconn_object_prophandlers
;
308 static HashTable php_pqtypes_object_prophandlers
;
309 static HashTable php_pqres_object_prophandlers
;
310 static HashTable php_pqstm_object_prophandlers
;
311 static HashTable php_pqtxn_object_prophandlers
;
312 static HashTable php_pqcancel_object_prophandlers
;
313 static HashTable php_pqevent_object_prophandlers
;
314 static HashTable php_pqlob_object_prophandlers
;
315 static HashTable php_pqcopy_object_prophandlers
;
317 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
319 typedef struct php_pq_object_prophandler
{
320 php_pq_object_prophandler_func_t read
;
321 php_pq_object_prophandler_func_t write
;
322 } php_pq_object_prophandler_t
;
324 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
326 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
328 php_pqres_iterator_t
*iter
;
329 zval
*prop
, *zfetch_type
;
331 iter
= ecalloc(1, sizeof(*iter
));
332 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
333 iter
->zi
.data
= object
;
336 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
337 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
338 convert_to_long_ex(&zfetch_type
);
340 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
341 if (zfetch_type
!= prop
) {
342 zval_ptr_dtor(&zfetch_type
);
344 if (Z_REFCOUNT_P(prop
)) {
345 zval_ptr_dtor(&prop
);
351 return (zend_object_iterator
*) iter
;
354 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
356 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
358 if (iter
->current_val
) {
359 zval_ptr_dtor(&iter
->current_val
);
360 iter
->current_val
= NULL
;
362 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
366 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
368 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
369 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
371 if (PQresultStatus(obj
->intern
->res
) != PGRES_TUPLES_OK
) {
374 if (PQntuples(obj
->intern
->res
) <= iter
->index
) {
381 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type
, zval
**data_ptr TSRMLS_DC
)
391 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
401 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
402 if (PQgetisnull(res
, row
, c
)) {
403 switch (fetch_type
) {
404 case PHP_PQRES_FETCH_OBJECT
:
405 add_property_null(data
, PQfname(res
, c
));
408 case PHP_PQRES_FETCH_ASSOC
:
409 add_assoc_null(data
, PQfname(res
, c
));
412 case PHP_PQRES_FETCH_ARRAY
:
413 add_index_null(data
, c
);
417 char *val
= PQgetvalue(res
, row
, c
);
418 int len
= PQgetlength(res
, row
, c
);
420 switch (fetch_type
) {
421 case PHP_PQRES_FETCH_OBJECT
:
422 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
425 case PHP_PQRES_FETCH_ASSOC
:
426 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
429 case PHP_PQRES_FETCH_ARRAY
:
430 add_index_stringl(data
, c
, val
, len
,1);
439 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
441 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
442 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
444 if (iter
->current_val
) {
445 zval_ptr_dtor(&iter
->current_val
);
447 iter
->current_val
= php_pqres_row_to_zval(obj
->intern
->res
, iter
->index
, iter
->fetch_type
, NULL TSRMLS_CC
);
448 *data_ptr
= &iter
->current_val
;
451 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
453 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
455 *key_num
= (ulong
) iter
->index
;
457 return HASH_KEY_IS_LONG
;
460 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
462 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
467 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
469 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
474 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
475 php_pqres_iterator_dtor
,
476 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
477 php_pqres_iterator_valid
,
478 /* fetch the item data for the current element */
479 php_pqres_iterator_current
,
480 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
481 php_pqres_iterator_key
,
482 /* step forwards to next element */
483 php_pqres_iterator_next
,
484 /* rewind to start of data (optional, may be NULL) */
485 php_pqres_iterator_rewind
,
486 /* invalidate current value/key (optional, may be NULL) */
490 static int php_pqres_count_elements(zval
*object
, long *count TSRMLS_DC
)
492 php_pqres_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
497 *count
= (long) PQntuples(obj
->intern
->res
);
502 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
504 switch (PQresultStatus(res
)) {
505 case PGRES_BAD_RESPONSE
:
506 case PGRES_NONFATAL_ERROR
:
507 case PGRES_FATAL_ERROR
:
508 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "%s", PHP_PQresultErrorMessage(res
));
515 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
516 if (cb
->fci
.size
> 0) {
517 zend_fcall_info_args_clear(&cb
->fci
, 1);
518 zval_ptr_dtor(&cb
->fci
.function_name
);
519 if (cb
->fci
.object_ptr
) {
520 zval_ptr_dtor(&cb
->fci
.object_ptr
);
526 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
528 Z_ADDREF_P(cb
->fci
.function_name
);
529 if (cb
->fci
.object_ptr
) {
530 Z_ADDREF_P(cb
->fci
.object_ptr
);
534 static void php_pq_object_to_zval(void *o
, zval
**zv TSRMLS_DC
)
536 php_pq_object_t
*obj
= o
;
542 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
544 (*zv
)->type
= IS_OBJECT
;
545 (*zv
)->value
.obj
= obj
->zv
;
548 static void php_pq_object_addref(void *o TSRMLS_DC
)
550 php_pq_object_t
*obj
= o
;
551 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
554 static void php_pq_object_delref(void *o TSRMLS_DC
)
556 php_pq_object_t
*obj
= o
;
557 zend_objects_store_del_ref_by_handle_ex(obj
->zv
.handle
, obj
->zv
.handlers TSRMLS_CC
);
560 static void php_pqconn_object_free(void *o TSRMLS_DC
)
562 php_pqconn_object_t
*obj
= o
;
565 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
566 php_resource_factory_dtor(&obj
->intern
->factory
);
567 php_pq_callback_dtor(&obj
->intern
->onevent
);
568 zend_hash_destroy(&obj
->intern
->listeners
);
569 zend_hash_destroy(&obj
->intern
->eventhandlers
);
573 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
577 static void php_pqtypes_object_free(void *o TSRMLS_DC
)
579 php_pqtypes_object_t
*obj
= o
;
582 zend_hash_destroy(&obj
->intern
->types
);
583 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
587 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
591 static void php_pqres_object_free(void *o TSRMLS_DC
)
593 php_pqres_object_t
*obj
= o
;
596 if (obj
->intern
->res
) {
597 zval
*res
= PQresultInstanceData(obj
->intern
->res
, php_pqconn_event
);
599 if (1 == Z_REFCOUNT_P(res
)) {
600 PQresultSetInstanceData(obj
->intern
->res
, php_pqconn_event
, NULL
);
604 PQclear(obj
->intern
->res
);
605 obj
->intern
->res
= NULL
;
609 if (obj
->intern
->iter
) {
610 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
611 obj
->intern
->iter
= NULL
;
614 zend_hash_destroy(&obj
->intern
->bound
);
619 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
623 static void php_pqstm_object_free(void *o TSRMLS_DC
)
625 php_pqstm_object_t
*obj
= o
;
628 char *quoted_name
= PQescapeIdentifier(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, strlen(obj
->intern
->name
));
630 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
636 smart_str_appends(&cmd
, "DEALLOCATE ");
637 smart_str_appends(&cmd
, quoted_name
);
639 PQfreemem(quoted_name
);
641 if ((res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
))) {
644 smart_str_free(&cmd
);
647 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
648 efree(obj
->intern
->name
);
649 zend_hash_destroy(&obj
->intern
->bound
);
653 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
657 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
659 php_pqtxn_object_t
*obj
= o
;
662 if (obj
->intern
->open
) {
663 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
669 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
673 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
677 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
679 php_pqcancel_object_t
*obj
= o
;
682 PQfreeCancel(obj
->intern
->cancel
);
683 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
687 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
691 static void php_pqevent_object_free(void *o TSRMLS_DC
)
693 php_pqevent_object_t
*obj
= o
;
696 php_pq_callback_dtor(&obj
->intern
->cb
);
697 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
698 efree(obj
->intern
->type
);
702 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
706 static void php_pqlob_object_free(void *o TSRMLS_DC
)
708 php_pqlob_object_t
*obj
= o
;
711 if (obj
->intern
->lofd
) {
712 lo_close(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
714 php_pq_object_delref(obj
->intern
->txn TSRMLS_CC
);
718 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
722 static void php_pqcopy_object_free(void *o TSRMLS_DC
)
724 php_pqcopy_object_t
*obj
= o
;
727 efree(obj
->intern
->expression
);
728 efree(obj
->intern
->options
);
729 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
733 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
737 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
739 php_pqconn_object_t
*o
;
741 o
= ecalloc(1, sizeof(*o
));
742 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
743 object_properties_init((zend_object
*) o
, ce
);
744 o
->prophandler
= &php_pqconn_object_prophandlers
;
754 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
755 o
->zv
.handlers
= &php_pqconn_object_handlers
;
760 static zend_object_value
php_pqtypes_create_object_ex(zend_class_entry
*ce
, php_pqtypes_t
*intern
, php_pqtypes_object_t
**ptr TSRMLS_DC
)
762 php_pqtypes_object_t
*o
;
764 o
= ecalloc(1, sizeof(*o
));
765 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
766 object_properties_init((zend_object
*) o
, ce
);
767 o
->prophandler
= &php_pqtypes_object_prophandlers
;
777 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtypes_object_free
, NULL TSRMLS_CC
);
778 o
->zv
.handlers
= &php_pqtypes_object_handlers
;
783 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, php_pqres_t
*intern
, php_pqres_object_t
**ptr TSRMLS_DC
)
785 php_pqres_object_t
*o
;
787 o
= ecalloc(1, sizeof(*o
));
788 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
789 object_properties_init((zend_object
*) o
, ce
);
790 o
->prophandler
= &php_pqres_object_prophandlers
;
800 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
801 o
->zv
.handlers
= &php_pqres_object_handlers
;
806 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*intern
, php_pqstm_object_t
**ptr TSRMLS_DC
)
808 php_pqstm_object_t
*o
;
810 o
= ecalloc(1, sizeof(*o
));
811 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
812 object_properties_init((zend_object
*) o
, ce
);
813 o
->prophandler
= &php_pqstm_object_prophandlers
;
823 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
824 o
->zv
.handlers
= &php_pqstm_object_handlers
;
829 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*intern
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
831 php_pqtxn_object_t
*o
;
833 o
= ecalloc(1, sizeof(*o
));
834 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
835 object_properties_init((zend_object
*) o
, ce
);
836 o
->prophandler
= &php_pqtxn_object_prophandlers
;
846 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
847 o
->zv
.handlers
= &php_pqtxn_object_handlers
;
852 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*intern
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
854 php_pqcancel_object_t
*o
;
856 o
= ecalloc(1, sizeof(*o
));
857 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
858 object_properties_init((zend_object
*) o
, ce
);
859 o
->prophandler
= &php_pqcancel_object_prophandlers
;
869 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
870 o
->zv
.handlers
= &php_pqcancel_object_handlers
;
875 static zend_object_value
php_pqevent_create_object_ex(zend_class_entry
*ce
, php_pqevent_t
*intern
, php_pqevent_object_t
**ptr TSRMLS_DC
)
877 php_pqevent_object_t
*o
;
879 o
= ecalloc(1, sizeof(*o
));
880 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
881 object_properties_init((zend_object
*) o
, ce
);
882 o
->prophandler
= &php_pqevent_object_prophandlers
;
892 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqevent_object_free
, NULL TSRMLS_CC
);
893 o
->zv
.handlers
= &php_pqevent_object_handlers
;
898 static zend_object_value
php_pqlob_create_object_ex(zend_class_entry
*ce
, php_pqlob_t
*intern
, php_pqlob_object_t
**ptr TSRMLS_DC
)
900 php_pqlob_object_t
*o
;
902 o
= ecalloc(1, sizeof(*o
));
903 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
904 object_properties_init((zend_object
*) o
, ce
);
905 o
->prophandler
= &php_pqlob_object_prophandlers
;
915 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqlob_object_free
, NULL TSRMLS_CC
);
916 o
->zv
.handlers
= &php_pqlob_object_handlers
;
921 static zend_object_value
php_pqcopy_create_object_ex(zend_class_entry
*ce
, php_pqcopy_t
*intern
, php_pqcopy_object_t
**ptr TSRMLS_DC
)
923 php_pqcopy_object_t
*o
;
925 o
= ecalloc(1, sizeof(*o
));
926 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
927 object_properties_init((zend_object
*) o
, ce
);
928 o
->prophandler
= &php_pqcopy_object_prophandlers
;
938 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcopy_object_free
, NULL TSRMLS_CC
);
939 o
->zv
.handlers
= &php_pqcopy_object_handlers
;
944 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
946 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
949 static zend_object_value
php_pqtypes_create_object(zend_class_entry
*class_type TSRMLS_DC
)
951 return php_pqtypes_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
954 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
956 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
959 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
961 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
964 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
966 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
969 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
971 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
974 static zend_object_value
php_pqevent_create_object(zend_class_entry
*class_type TSRMLS_DC
)
976 return php_pqevent_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
979 static zend_object_value
php_pqlob_create_object(zend_class_entry
*class_type TSRMLS_DC
)
981 return php_pqlob_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
984 static zend_object_value
php_pqcopy_create_object(zend_class_entry
*class_type TSRMLS_DC
)
986 return php_pqcopy_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
989 static int apply_ph_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
991 php_pq_object_prophandler_t
*ph
= p
;
992 HashTable
*ht
= va_arg(argv
, HashTable
*);
993 zval
**return_value
, *object
= va_arg(argv
, zval
*);
994 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
996 if (SUCCESS
== zend_hash_find(ht
, key
->arKey
, key
->nKeyLength
, (void *) &return_value
)) {
999 zval_ptr_dtor(return_value
);
1000 MAKE_STD_ZVAL(*return_value
);
1001 ZVAL_NULL(*return_value
);
1003 ph
->read(object
, obj
, *return_value TSRMLS_CC
);
1007 return ZEND_HASH_APPLY_KEEP
;
1010 static int apply_pi_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1012 zend_property_info
*pi
= p
;
1013 HashTable
*ht
= va_arg(argv
, HashTable
*);
1014 zval
*object
= va_arg(argv
, zval
*);
1015 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
1016 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
1018 if (1||!Z_REFCOUNT_P(property
)) {
1019 Z_ADDREF_P(property
);
1021 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
1023 return ZEND_HASH_APPLY_KEEP
;
1026 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
1029 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1032 ALLOC_HASHTABLE(ht
);
1033 ZEND_INIT_SYMTABLE(ht
);
1035 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_debug
, 3, ht
, object
, obj
);
1036 zend_hash_apply_with_arguments(obj
->prophandler TSRMLS_CC
, apply_ph_to_debug
, 3, ht
, object
, obj
);
1041 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1043 php_pqconn_object_t
*obj
= o
;
1045 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
1048 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1050 php_pqconn_object_t
*obj
= o
;
1052 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
1055 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1057 php_pqconn_object_t
*obj
= o
;
1058 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
1061 RETVAL_STRING(error
, 1);
1067 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
1069 php_pq_callback_t
*listener
= p
;
1070 PGnotify
*nfy
= arg
;
1071 zval
*zpid
, *zchannel
, *zmessage
;
1073 MAKE_STD_ZVAL(zpid
);
1074 ZVAL_LONG(zpid
, nfy
->be_pid
);
1075 MAKE_STD_ZVAL(zchannel
);
1076 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
1077 MAKE_STD_ZVAL(zmessage
);
1078 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
1080 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
1081 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
1083 zval_ptr_dtor(&zchannel
);
1084 zval_ptr_dtor(&zmessage
);
1085 zval_ptr_dtor(&zpid
);
1087 return ZEND_HASH_APPLY_KEEP
;
1090 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1092 HashTable
*listeners
= p
;
1093 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
1095 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
1096 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
1099 return ZEND_HASH_APPLY_KEEP
;
1102 static void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
1106 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
1107 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
1112 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1114 php_pqconn_object_t
*obj
= o
;
1116 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
1119 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1121 php_pqconn_object_t
*obj
= o
;
1123 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
1126 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1128 php_pqconn_object_t
*obj
= o
;
1131 if (Z_TYPE_P(value
) != IS_STRING
) {
1132 convert_to_string_ex(&zenc
);
1135 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
1136 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
1139 if (zenc
!= value
) {
1140 zval_ptr_dtor(&zenc
);
1144 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1146 php_pqconn_object_t
*obj
= o
;
1148 RETVAL_BOOL(obj
->intern
->unbuffered
);
1151 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1153 php_pqconn_object_t
*obj
= o
;
1155 obj
->intern
->unbuffered
= zend_is_true(value
);
1158 static void php_pqconn_object_read_db(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1160 php_pqconn_object_t
*obj
= o
;
1161 char *db
= PQdb(obj
->intern
->conn
);
1164 RETVAL_STRING(db
, 1);
1166 RETVAL_EMPTY_STRING();
1170 static void php_pqconn_object_read_user(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1172 php_pqconn_object_t
*obj
= o
;
1173 char *user
= PQuser(obj
->intern
->conn
);
1176 RETVAL_STRING(user
, 1);
1178 RETVAL_EMPTY_STRING();
1182 static void php_pqconn_object_read_pass(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1184 php_pqconn_object_t
*obj
= o
;
1185 char *pass
= PQpass(obj
->intern
->conn
);
1188 RETVAL_STRING(pass
, 1);
1190 RETVAL_EMPTY_STRING();
1194 static void php_pqconn_object_read_host(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1196 php_pqconn_object_t
*obj
= o
;
1197 char *host
= PQhost(obj
->intern
->conn
);
1200 RETVAL_STRING(host
, 1);
1202 RETVAL_EMPTY_STRING();
1206 static void php_pqconn_object_read_port(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1208 php_pqconn_object_t
*obj
= o
;
1209 char *port
= PQport(obj
->intern
->conn
);
1212 RETVAL_STRING(port
, 1);
1214 RETVAL_EMPTY_STRING();
1218 static void php_pqconn_object_read_options(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1220 php_pqconn_object_t
*obj
= o
;
1221 char *options
= PQoptions(obj
->intern
->conn
);
1224 RETVAL_STRING(options
, 1);
1226 RETVAL_EMPTY_STRING();
1230 static void php_pqtypes_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1232 php_pqtypes_object_t
*obj
= o
;
1234 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1237 static int has_dimension(HashTable
*ht
, zval
*member
, char **key_str
, int *key_len
, long *index TSRMLS_DC
)
1242 switch (Z_TYPE_P(member
)) {
1244 convert_to_string_ex(&tmp
);
1247 if (!is_numeric_string(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
), &lval
, NULL
, 0)) {
1248 if (member
!= tmp
) {
1249 zval_ptr_dtor(&tmp
);
1252 *key_str
= estrndup(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
));
1254 *key_len
= Z_STRLEN_P(tmp
) + 1;
1257 return zend_hash_exists(ht
, Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
) + 1);
1261 lval
= Z_LVAL_P(member
);
1265 if (member
!= tmp
) {
1266 zval_ptr_dtor(&tmp
);
1271 return zend_hash_index_exists(ht
, lval
);
1274 static int php_pqtypes_object_has_dimension(zval
*object
, zval
*member
, int check_empty TSRMLS_DC
)
1276 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1277 char *key_str
= NULL
;
1282 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1285 if (key_str
&& key_len
) {
1286 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1288 return Z_TYPE_PP(data
) != IS_NULL
;
1292 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) data
)) {
1293 return Z_TYPE_PP(data
) != IS_NULL
;
1298 return has_dimension(&obj
->intern
->types
, member
, NULL
, NULL
, NULL TSRMLS_CC
);
1304 static zval
*php_pqtypes_object_read_dimension(zval
*object
, zval
*member
, int type TSRMLS_DC
)
1307 char *key_str
= NULL
;
1309 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1311 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1314 if (key_str
&& key_len
) {
1315 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1320 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1329 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1331 php_pqres_object_t
*obj
= o
;
1333 RETVAL_LONG(PQresultStatus(obj
->intern
->res
));
1336 static void php_pqres_object_read_status_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1338 php_pqres_object_t
*obj
= o
;
1340 RETVAL_STRING(PQresStatus(PQresultStatus(obj
->intern
->res
))+sizeof("PGRES"), 1);
1343 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1345 php_pqres_object_t
*obj
= o
;
1346 char *error
= PHP_PQresultErrorMessage(obj
->intern
->res
);
1349 RETVAL_STRING(error
, 1);
1355 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1357 php_pqres_object_t
*obj
= o
;
1359 RETVAL_LONG(PQntuples(obj
->intern
->res
));
1362 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1364 php_pqres_object_t
*obj
= o
;
1366 RETVAL_LONG(PQnfields(obj
->intern
->res
));
1369 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1371 php_pqres_object_t
*obj
= o
;
1373 RETVAL_LONG(atoi(PQcmdTuples(obj
->intern
->res
)));
1376 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1378 php_pqres_object_t
*obj
= o
;
1380 if (obj
->intern
->iter
) {
1381 RETVAL_LONG(obj
->intern
->iter
->fetch_type
);
1383 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
1387 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1389 php_pqres_object_t
*obj
= o
;
1390 zval
*zfetch_type
= value
;
1392 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
1393 convert_to_long_ex(&zfetch_type
);
1396 if (!obj
->intern
->iter
) {
1397 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
1398 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
1400 obj
->intern
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
1402 if (zfetch_type
!= value
) {
1403 zval_ptr_dtor(&zfetch_type
);
1407 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1409 php_pqstm_object_t
*obj
= o
;
1411 RETVAL_STRING(obj
->intern
->name
, 1);
1414 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1416 php_pqstm_object_t
*obj
= o
;
1418 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1421 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1423 php_pqtxn_object_t
*obj
= o
;
1425 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1428 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1430 php_pqtxn_object_t
*obj
= o
;
1432 RETVAL_LONG(obj
->intern
->isolation
);
1435 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1437 php_pqtxn_object_t
*obj
= o
;
1439 RETVAL_LONG(obj
->intern
->readonly
);
1442 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1444 php_pqtxn_object_t
*obj
= o
;
1446 RETVAL_LONG(obj
->intern
->deferrable
);
1449 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1451 php_pqtxn_object_t
*obj
= o
;
1452 php_pqtxn_isolation_t orig
= obj
->intern
->isolation
;
1453 zval
*zisolation
= value
;
1456 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
1457 convert_to_long_ex(&zisolation
);
1460 switch ((obj
->intern
->isolation
= Z_LVAL_P(zisolation
))) {
1461 case PHP_PQTXN_READ_COMMITTED
:
1462 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ COMMITED");
1464 case PHP_PQTXN_REPEATABLE_READ
:
1465 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION REPEATABLE READ");
1467 case PHP_PQTXN_SERIALIZABLE
:
1468 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION SERIALIZABLE");
1471 obj
->intern
->isolation
= orig
;
1476 if (zisolation
!= value
) {
1477 zval_ptr_dtor(&zisolation
);
1481 php_pqres_success(res TSRMLS_CC
);
1486 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1488 php_pqtxn_object_t
*obj
= o
;
1491 if ((obj
->intern
->readonly
= zend_is_true(value
))) {
1492 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ ONLY");
1494 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ WRITE");
1498 php_pqres_success(res TSRMLS_CC
);
1503 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1505 php_pqtxn_object_t
*obj
= o
;
1508 if ((obj
->intern
->deferrable
= zend_is_true(value
))) {
1509 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION DEFERRABLE");
1511 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION NOT DEFERRABLE");
1515 php_pqres_success(res TSRMLS_CC
);
1520 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1522 php_pqcancel_object_t
*obj
= o
;
1524 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1527 static void php_pqevent_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1529 php_pqevent_object_t
*obj
= o
;
1531 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1534 static void php_pqevent_object_read_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1536 php_pqevent_object_t
*obj
= o
;
1538 RETVAL_STRING(obj
->intern
->type
, 1);
1541 static void php_pqlob_object_read_transaction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1543 php_pqlob_object_t
*obj
= o
;
1545 php_pq_object_to_zval(obj
->intern
->txn
, &return_value TSRMLS_CC
);
1548 static void php_pqlob_object_read_oid(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1550 php_pqlob_object_t
*obj
= o
;
1552 RETVAL_LONG(obj
->intern
->loid
);
1555 static void php_pqcopy_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1557 php_pqcopy_object_t
*obj
= o
;
1559 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1562 static void php_pqcopy_object_read_direction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1564 php_pqcopy_object_t
*obj
= o
;
1566 RETVAL_LONG(obj
->intern
->direction
);
1569 static void php_pqcopy_object_read_expression(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1571 php_pqcopy_object_t
*obj
= o
;
1573 RETURN_STRING(obj
->intern
->expression
, 1);
1576 static void php_pqcopy_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1578 php_pqcopy_object_t
*obj
= o
;
1580 RETURN_STRING(obj
->intern
->options
, 1);
1583 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
1584 while (ce
->parent
) {
1590 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
1592 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1593 php_pq_object_prophandler_t
*handler
;
1597 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1598 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1599 if (type
== BP_VAR_R
) {
1600 ALLOC_ZVAL(return_value
);
1601 Z_SET_REFCOUNT_P(return_value
, 0);
1602 Z_UNSET_ISREF_P(return_value
);
1604 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1606 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1607 return_value
= NULL
;
1610 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1613 return return_value
;
1616 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1618 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1619 php_pq_object_prophandler_t
*handler
;
1621 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1622 if (handler
->write
) {
1623 handler
->write(object
, obj
, value TSRMLS_CC
);
1626 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1630 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1632 zval
*zsocket
, zmember
;
1638 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1641 INIT_PZVAL(&zmember
);
1642 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1643 MAKE_STD_ZVAL(zsocket
);
1645 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
1646 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
1647 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1648 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1649 php_stream_to_zval(stream
, zsocket
);
1655 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1656 zval_ptr_dtor(&zsocket
);
1662 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1663 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1665 # define TSRMLS_DF(d)
1666 # define TSRMLS_CF(d)
1669 static int apply_event(void *p
, void *a TSRMLS_DC
)
1673 zval
*retval
= NULL
;
1675 zend_call_method_with_1_params(evh
, Z_OBJCE_PP(evh
), NULL
, "trigger", &retval
, args
);
1677 zval_ptr_dtor(&retval
);
1680 return ZEND_HASH_APPLY_KEEP
;
1683 static void php_pqconn_event_connreset(PGEventConnReset
*event
)
1685 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1691 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("reset"), (void *) &evhs
)) {
1692 zval
*args
, *connection
= NULL
;
1694 MAKE_STD_ZVAL(args
);
1696 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1697 add_next_index_zval(args
, connection
);
1698 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1699 zval_ptr_dtor(&args
);
1704 static zval
*result_instance_zval(PGresult
*res TSRMLS_DC
)
1706 zval
*rid
= PQresultInstanceData(res
, php_pqconn_event
);
1709 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
1713 ZEND_INIT_SYMTABLE(&r
->bound
);
1714 rid
->type
= IS_OBJECT
;
1715 rid
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
1717 PQresultSetInstanceData(res
, php_pqconn_event
, rid
);
1724 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
)
1726 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1732 /* event listener */
1733 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("result"), (void *) &evhs
)) {
1734 zval
*args
, *connection
= NULL
, *res
= result_instance_zval(event
->result TSRMLS_CC
);
1736 MAKE_STD_ZVAL(args
);
1738 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1739 add_next_index_zval(args
, connection
);
1740 add_next_index_zval(args
, res
);
1741 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1742 zval_ptr_dtor(&args
);
1745 /* async callback */
1746 if (data
->obj
->intern
->onevent
.fci
.size
> 0) {
1747 zval
*res
= result_instance_zval(event
->result TSRMLS_CC
);
1749 zend_fcall_info_argn(&data
->obj
->intern
->onevent
.fci TSRMLS_CC
, 1, &res
);
1750 zend_fcall_info_call(&data
->obj
->intern
->onevent
.fci
, &data
->obj
->intern
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1751 zval_ptr_dtor(&res
);
1756 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1759 case PGEVT_CONNRESET
:
1760 php_pqconn_event_connreset(e
);
1762 case PGEVT_RESULTCREATE
:
1763 php_pqconn_event_resultcreate(e
);
1772 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1774 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1782 static void php_pqconn_notice_recv(void *p
, const PGresult
*res
)
1784 php_pqconn_event_data_t
*data
= p
;
1790 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("notice"), (void *) &evhs
)) {
1791 zval
*args
, *connection
= NULL
;
1793 MAKE_STD_ZVAL(args
);
1795 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1796 add_next_index_zval(args
, connection
);
1797 add_next_index_string(args
, PHP_PQresultErrorMessage(res
), 1);
1798 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1799 zval_ptr_dtor(&args
);
1804 typedef struct php_pqconn_resource_factory_data
{
1807 } php_pqconn_resource_factory_data_t
;
1809 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
1811 php_pqconn_resource_factory_data_t
*o
= init_arg
;
1812 PGconn
*conn
= NULL
;;
1814 if (o
->flags
& PHP_PQCONN_ASYNC
) {
1815 conn
= PQconnectStart(o
->dsn
);
1817 conn
= PQconnectdb(o
->dsn
);
1821 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
1827 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
1829 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
1831 /* we don't care for anything, except free'ing evdata */
1833 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
1834 memset(evdata
, 0, sizeof(*evdata
));
1841 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
1842 php_pqconn_resource_factory_ctor
,
1844 php_pqconn_resource_factory_dtor
1847 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1849 // FIXME: ping server
1852 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1854 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
1855 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1);
1857 if (quoted_channel
) {
1861 spprintf(&cmd
, 0, "UNLISTEN %s", quoted_channel
);
1862 if ((res
= PQexec(obj
->intern
->conn
, cmd
))) {
1867 PQfreemem(quoted_channel
);
1870 return ZEND_HASH_APPLY_REMOVE
;
1873 static void php_pqconn_notice_ignore(void *p
, const PGresult
*res
)
1877 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1879 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
1884 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
1886 /* ignore notices */
1887 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
1889 /* cancel async queries */
1890 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
1891 PQcancel(cancel
, ZEND_STRL("retiring persistent connection"));
1892 PQfreeCancel(cancel
);
1894 /* clean up async results */
1895 while ((res
= PQgetResult(*handle
))) {
1899 /* clean up transaction & session */
1900 switch (PQtransactionStatus(*handle
)) {
1902 res
= PQexec(*handle
, "RESET ALL");
1905 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
1914 /* clean up notify listeners */
1915 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
1917 /* release instance data */
1918 memset(evdata
, 0, sizeof(*evdata
));
1923 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
1924 ZEND_ARG_INFO(0, dsn
)
1925 ZEND_ARG_INFO(0, async
)
1926 ZEND_END_ARG_INFO();
1927 static PHP_METHOD(pqconn
, __construct
) {
1928 zend_error_handling zeh
;
1934 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1935 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
);
1936 zend_restore_error_handling(&zeh TSRMLS_CC
);
1938 if (SUCCESS
== rv
) {
1939 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1942 zend_throw_exception_ex(exce(EX_BAD_METHODCALL
), EX_BAD_METHODCALL TSRMLS_CC
, "pq\\Connection already initialized");
1944 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
1945 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
1947 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
1949 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
1950 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
1952 if (flags
& PHP_PQCONN_PERSISTENT
) {
1953 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
);
1954 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
1956 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
1959 if (flags
& PHP_PQCONN_ASYNC
) {
1960 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
1963 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
1965 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
1966 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
1968 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
1969 zend_throw_exception_ex(exce(EX_CONNECTION_FAILED
), EX_CONNECTION_FAILED TSRMLS_CC
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1975 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
1976 ZEND_END_ARG_INFO();
1977 static PHP_METHOD(pqconn
, reset
) {
1978 if (SUCCESS
== zend_parse_parameters_none()) {
1979 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1982 PQreset(obj
->intern
->conn
);
1984 if (CONNECTION_OK
== PQstatus(obj
->intern
->conn
)) {
1987 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1990 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1996 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
1997 ZEND_END_ARG_INFO();
1998 static PHP_METHOD(pqconn
, resetAsync
) {
1999 if (SUCCESS
== zend_parse_parameters_none()) {
2000 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2003 if (PQresetStart(obj
->intern
->conn
)) {
2004 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
2008 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2014 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
)
2016 HashTable ht
, *existing_listeners
;
2018 php_pq_callback_addref(listener
);
2020 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
2021 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
2023 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
2024 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
2025 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
2029 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
2030 ZEND_ARG_INFO(0, channel
)
2031 ZEND_ARG_INFO(0, callable
)
2032 ZEND_END_ARG_INFO();
2033 static PHP_METHOD(pqconn
, listen
) {
2034 char *channel_str
= NULL
;
2035 int channel_len
= 0;
2036 php_pq_callback_t listener
;
2038 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
)) {
2039 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2042 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2044 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2046 if (!quoted_channel
) {
2047 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2051 smart_str cmd
= {0};
2053 smart_str_appends(&cmd
, "LISTEN ");
2054 smart_str_appends(&cmd
, quoted_channel
);
2057 res
= PQexec(obj
->intern
->conn
, cmd
.c
);
2059 smart_str_free(&cmd
);
2060 PQfreemem(quoted_channel
);
2063 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2066 if (SUCCESS
!= php_pqres_success(res TSRMLS_CC
)) {
2069 obj
->intern
->poller
= PQconsumeInput
;
2070 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2076 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2082 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
2083 ZEND_ARG_INFO(0, channel
)
2084 ZEND_ARG_INFO(0, callable
)
2085 ZEND_END_ARG_INFO();
2086 static PHP_METHOD(pqconn
, listenAsync
) {
2087 char *channel_str
= NULL
;
2088 int channel_len
= 0;
2089 php_pq_callback_t listener
;
2091 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
)) {
2092 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2095 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2097 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2099 if (!quoted_channel
) {
2100 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2102 smart_str cmd
= {0};
2104 smart_str_appends(&cmd
, "LISTEN ");
2105 smart_str_appends(&cmd
, quoted_channel
);
2108 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
2109 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2112 obj
->intern
->poller
= PQconsumeInput
;
2113 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2117 smart_str_free(&cmd
);
2118 PQfreemem(quoted_channel
);
2124 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
2125 ZEND_ARG_INFO(0, channel
)
2126 ZEND_ARG_INFO(0, message
)
2127 ZEND_END_ARG_INFO();
2128 static PHP_METHOD(pqconn
, notify
) {
2129 char *channel_str
, *message_str
;
2130 int channel_len
, message_len
;
2132 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
)) {
2133 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2136 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2139 char *params
[2] = {channel_str
, message_str
};
2141 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
2144 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2147 if (SUCCESS
!= php_pqres_success(res TSRMLS_CC
)) {
2155 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2160 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
2161 ZEND_ARG_INFO(0, channel
)
2162 ZEND_ARG_INFO(0, message
)
2163 ZEND_END_ARG_INFO();
2164 static PHP_METHOD(pqconn
, notifyAsync
) {
2165 char *channel_str
, *message_str
;
2166 int channel_len
, message_len
;
2168 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
)) {
2169 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2172 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2174 char *params
[2] = {channel_str
, message_str
};
2176 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
2177 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2180 obj
->intern
->poller
= PQconsumeInput
;
2184 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2189 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
2190 ZEND_END_ARG_INFO();
2191 static PHP_METHOD(pqconn
, poll
) {
2192 if (SUCCESS
== zend_parse_parameters_none()) {
2193 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2196 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2197 } else if (!obj
->intern
->poller
) {
2198 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "No asynchronous operation active");
2199 } else if (obj
->intern
->poller
== PQconsumeInput
) {
2200 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
2202 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
2204 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2208 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
2209 ZEND_ARG_INFO(0, query
)
2210 ZEND_END_ARG_INFO();
2211 static PHP_METHOD(pqconn
, exec
) {
2212 zend_error_handling zeh
;
2217 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2218 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
);
2219 zend_restore_error_handling(&zeh TSRMLS_CC
);
2221 if (SUCCESS
== rv
) {
2222 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2225 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2227 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
2230 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2231 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2232 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2235 ZEND_INIT_SYMTABLE(&r
->bound
);
2236 return_value
->type
= IS_OBJECT
;
2237 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2240 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2245 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
2246 ZEND_END_ARG_INFO();
2247 static PHP_METHOD(pqconn
, getResult
) {
2248 if (SUCCESS
== zend_parse_parameters_none()) {
2249 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2252 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connectio not initialized");
2254 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
2259 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2262 ZEND_INIT_SYMTABLE(&r
->bound
);
2263 return_value
->type
= IS_OBJECT
;
2264 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2267 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2272 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
2273 ZEND_ARG_INFO(0, query
)
2274 ZEND_ARG_INFO(0, callable
)
2275 ZEND_END_ARG_INFO();
2276 static PHP_METHOD(pqconn
, execAsync
) {
2277 zend_error_handling zeh
;
2278 php_pq_callback_t resolver
= {{0}};
2283 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2284 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
2285 zend_restore_error_handling(&zeh TSRMLS_CC
);
2287 if (SUCCESS
== rv
) {
2288 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2291 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2292 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
2293 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2294 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2295 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to request unbuffered result handling (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2297 obj
->intern
->poller
= PQconsumeInput
;
2298 php_pq_callback_dtor(&obj
->intern
->onevent
);
2299 if (resolver
.fci
.size
> 0) {
2300 obj
->intern
->onevent
= resolver
;
2301 php_pq_callback_addref(&obj
->intern
->onevent
);
2303 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2308 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
2313 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
2314 convert_to_long_ex(ztype
);
2317 **types
= Z_LVAL_PP(ztype
);
2320 if (*ztype
!= *(zval
**)p
) {
2321 zval_ptr_dtor(ztype
);
2323 return ZEND_HASH_APPLY_KEEP
;
2326 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
2332 params
= (char ***) va_arg(argv
, char ***);
2333 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
2335 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
2339 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
2340 convert_to_string_ex(zparam
);
2343 **params
= Z_STRVAL_PP(zparam
);
2346 if (*zparam
!= *(zval
**)p
) {
2347 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
2350 return ZEND_HASH_APPLY_KEEP
;
2353 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
2355 int count
= zend_hash_num_elements(ht
);
2362 /* +1 for when less types than params are specified */
2363 *types
= tmp
= ecalloc(count
+ 1, sizeof(**types
));
2364 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
2370 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
2372 int count
= zend_hash_num_elements(ht
);
2379 *params
= tmp
= ecalloc(count
, sizeof(char *));
2380 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
2386 static Oid *php_pq_ntypes_to_array(zend_bool fill, int argc, ...)
2389 Oid *oids = ecalloc(argc + 1, sizeof(*oids));
2392 va_start(argv, argc);
2393 for (i = 0; i < argc; ++i) {
2395 oids[i] = va_arg(argv, Oid);
2405 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
2406 ZEND_ARG_INFO(0, query
)
2407 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2408 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2409 ZEND_END_ARG_INFO();
2410 static PHP_METHOD(pqconn
, execParams
) {
2411 zend_error_handling zeh
;
2415 zval
*ztypes
= NULL
;
2418 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2419 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
2420 zend_restore_error_handling(&zeh TSRMLS_CC
);
2422 if (SUCCESS
== rv
) {
2423 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2426 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2431 char **params
= NULL
;
2434 ZEND_INIT_SYMTABLE(&zdtor
);
2435 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2438 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2441 res
= PQexecParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
2443 zend_hash_destroy(&zdtor
);
2452 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2454 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2455 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2458 ZEND_INIT_SYMTABLE(&r
->bound
);
2459 return_value
->type
= IS_OBJECT
;
2460 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2463 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2469 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
2470 ZEND_ARG_INFO(0, query
)
2471 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2472 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2473 ZEND_ARG_INFO(0, callable
)
2474 ZEND_END_ARG_INFO();
2475 static PHP_METHOD(pqconn
, execParamsAsync
) {
2476 zend_error_handling zeh
;
2477 php_pq_callback_t resolver
= {{0}};
2481 zval
*ztypes
= NULL
;
2484 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2485 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
2486 zend_restore_error_handling(&zeh TSRMLS_CC
);
2488 if (SUCCESS
== rv
) {
2489 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2492 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2496 char **params
= NULL
;
2499 ZEND_INIT_SYMTABLE(&zdtor
);
2500 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2503 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2506 if (!PQsendQueryParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
2507 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2508 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2509 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2511 obj
->intern
->poller
= PQconsumeInput
;
2512 php_pq_callback_dtor(&obj
->intern
->onevent
);
2513 if (resolver
.fci
.size
> 0) {
2514 obj
->intern
->onevent
= resolver
;
2515 php_pq_callback_addref(&obj
->intern
->onevent
);
2517 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2520 zend_hash_destroy(&zdtor
);
2529 zend_restore_error_handling(&zeh TSRMLS_CC
);
2532 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2540 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2544 count
= zend_hash_num_elements(typest
);
2545 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2548 res
= PQprepare(obj
->intern
->conn
, name
, query
, count
, types
);
2556 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2558 rv
= php_pqres_success(res TSRMLS_CC
);
2560 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2566 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
2567 ZEND_ARG_INFO(0, type
)
2568 ZEND_ARG_INFO(0, query
)
2569 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2570 ZEND_END_ARG_INFO();
2571 static PHP_METHOD(pqconn
, prepare
) {
2572 zend_error_handling zeh
;
2573 zval
*ztypes
= NULL
;
2574 char *name_str
, *query_str
;
2575 int name_len
, *query_len
;
2578 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2579 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2580 zend_restore_error_handling(&zeh TSRMLS_CC
);
2582 if (SUCCESS
== rv
) {
2583 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2586 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2587 } else if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2588 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2590 php_pq_object_addref(obj TSRMLS_CC
);
2592 stm
->name
= estrdup(name_str
);
2593 ZEND_INIT_SYMTABLE(&stm
->bound
);
2595 return_value
->type
= IS_OBJECT
;
2596 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2601 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2608 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2612 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2615 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, count
, types
)) {
2617 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2618 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2620 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2623 obj
->intern
->poller
= PQconsumeInput
;
2624 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2634 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
2635 ZEND_ARG_INFO(0, type
)
2636 ZEND_ARG_INFO(0, query
)
2637 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2638 ZEND_END_ARG_INFO();
2639 static PHP_METHOD(pqconn
, prepareAsync
) {
2640 zend_error_handling zeh
;
2641 zval
*ztypes
= NULL
;
2642 char *name_str
, *query_str
;
2643 int name_len
, *query_len
;
2646 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2647 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2648 zend_restore_error_handling(&zeh TSRMLS_CC
);
2650 if (SUCCESS
== rv
) {
2651 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2654 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2655 } else if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2656 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2658 php_pq_object_addref(obj TSRMLS_CC
);
2660 stm
->name
= estrdup(name_str
);
2661 ZEND_INIT_SYMTABLE(&stm
->bound
);
2663 return_value
->type
= IS_OBJECT
;
2664 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2669 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
2670 ZEND_ARG_INFO(0, string
)
2671 ZEND_END_ARG_INFO();
2672 static PHP_METHOD(pqconn
, quote
) {
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
);
2680 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2682 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
2685 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2688 RETVAL_STRING(quoted
, 1);
2695 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
2696 ZEND_ARG_INFO(0, type
)
2697 ZEND_END_ARG_INFO();
2698 static PHP_METHOD(pqconn
, quoteName
) {
2702 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2703 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2706 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2708 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
2711 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2714 RETVAL_STRING(quoted
, 1);
2721 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
2722 ZEND_ARG_INFO(0, bytea
)
2723 ZEND_END_ARG_INFO();
2724 static PHP_METHOD(pqconn
, escapeBytea
) {
2728 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2729 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2732 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2735 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
2738 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2741 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
2742 PQfreemem(escaped_str
);
2748 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
2749 ZEND_ARG_INFO(0, bytea
)
2750 ZEND_END_ARG_INFO();
2751 static PHP_METHOD(pqconn
, unescapeBytea
) {
2755 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2756 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2759 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2761 size_t unescaped_len
;
2762 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
2764 if (!unescaped_str
) {
2765 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2768 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
2769 PQfreemem(unescaped_str
);
2775 static const char *isolation_level(long *isolation
) {
2776 switch (*isolation
) {
2777 case PHP_PQTXN_SERIALIZABLE
:
2778 return "SERIALIZABLE";
2779 case PHP_PQTXN_REPEATABLE_READ
:
2780 return "REPEATABLE READ";
2782 *isolation
= PHP_PQTXN_READ_COMMITTED
;
2784 case PHP_PQTXN_READ_COMMITTED
:
2785 return "READ COMMITTED";
2789 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2791 STATUS rv
= FAILURE
;
2794 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2797 if (!conn_obj
->intern
) {
2798 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2801 smart_str cmd
= {0};
2802 const char *il
= isolation_level(&isolation
);
2804 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2805 smart_str_appends(&cmd
, il
);
2806 smart_str_appends(&cmd
, ", READ ");
2807 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2808 smart_str_appends(&cmd
, ",");
2809 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
2810 smart_str_appends(&cmd
, " DEFERRABLE");
2813 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
2816 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2818 rv
= php_pqres_success(res TSRMLS_CC
);
2820 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2823 smart_str_free(&cmd
);
2829 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
)
2831 STATUS rv
= FAILURE
;
2834 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2837 if (!conn_obj
->intern
) {
2838 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2840 smart_str cmd
= {0};
2841 const char *il
= isolation_level(&isolation
);
2843 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2844 smart_str_appends(&cmd
, il
);
2845 smart_str_appends(&cmd
, ", READ ");
2846 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2847 smart_str_appends(&cmd
, ",");
2848 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
2849 smart_str_appends(&cmd
, " DEFERRABLE");
2852 if (!PQsendQuery(conn_obj
->intern
->conn
, cmd
.c
)) {
2853 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2856 conn_obj
->intern
->poller
= PQconsumeInput
;
2857 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2860 smart_str_free(&cmd
);
2866 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
2867 ZEND_ARG_INFO(0, isolation
)
2868 ZEND_ARG_INFO(0, readonly
)
2869 ZEND_ARG_INFO(0, deferrable
)
2870 ZEND_END_ARG_INFO();
2871 static PHP_METHOD(pqconn
, startTransaction
) {
2872 zend_error_handling zeh
;
2873 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2874 zend_bool readonly
= 0, deferrable
= 0;
2877 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2878 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
2879 zend_restore_error_handling(&zeh TSRMLS_CC
);
2881 if (SUCCESS
== rv
) {
2882 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2884 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2886 if (SUCCESS
== rv
) {
2887 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2889 php_pq_object_addref(obj TSRMLS_CC
);
2892 txn
->isolation
= isolation
;
2893 txn
->readonly
= readonly
;
2894 txn
->deferrable
= deferrable
;
2896 return_value
->type
= IS_OBJECT
;
2897 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
2903 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
2904 ZEND_ARG_INFO(0, isolation
)
2905 ZEND_ARG_INFO(0, readonly
)
2906 ZEND_ARG_INFO(0, deferrable
)
2907 ZEND_END_ARG_INFO();
2908 static PHP_METHOD(pqconn
, startTransactionAsync
) {
2909 zend_error_handling zeh
;
2910 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2911 zend_bool readonly
= 0, deferrable
= 0;
2914 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2915 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
2916 zend_restore_error_handling(&zeh TSRMLS_CC
);
2917 if (SUCCESS
== rv
) {
2918 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2920 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2922 if (SUCCESS
== rv
) {
2923 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2925 php_pq_object_addref(obj TSRMLS_CC
);
2927 txn
->isolation
= isolation
;
2928 txn
->readonly
= readonly
;
2929 txn
->deferrable
= deferrable
;
2931 return_value
->type
= IS_OBJECT
;
2932 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
2937 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
2938 ZEND_ARG_INFO(0, stdio_stream
)
2939 ZEND_END_ARG_INFO();
2940 static PHP_METHOD(pqconn
, trace
) {
2941 zval
*zstream
= NULL
;
2943 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
2944 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2947 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
2950 PQuntrace(obj
->intern
->conn
);
2954 php_stream
*stream
= NULL
;
2956 php_stream_from_zval(stream
, &zstream
);
2958 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
2961 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
2962 PQtrace(obj
->intern
->conn
, fp
);
2970 static zend_function_entry php_pqconn_methods
[] = {
2971 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2972 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
2973 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
2974 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
2975 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
2976 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
2977 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
2978 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
2979 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
2980 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
2981 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
2982 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
2983 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
2984 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
2985 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
2986 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
2987 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
2988 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
2989 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
2990 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
2991 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
2992 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
2996 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct
, 0, 0, 1)
2997 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
2998 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
2999 ZEND_END_ARG_INFO();
3000 static PHP_METHOD(pqtypes
, __construct
) {
3001 zend_error_handling zeh
;
3002 zval
*zconn
, *znsp
= NULL
;
3005 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3006 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|a!", &zconn
, php_pqconn_class_entry
, &znsp
);
3007 zend_restore_error_handling(&zeh TSRMLS_CC
);
3009 if (SUCCESS
== rv
) {
3010 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3012 if (!conn_obj
->intern
) {
3013 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
3015 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3016 zval
*retval
= NULL
;
3018 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3019 obj
->intern
->conn
= conn_obj
;
3020 php_pq_object_addref(conn_obj TSRMLS_CC
);
3021 zend_hash_init(&obj
->intern
->types
, 300, NULL
, ZVAL_PTR_DTOR
, 0);
3023 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3025 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
, znsp
);
3027 zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
);
3029 zend_restore_error_handling(&zeh TSRMLS_CC
);
3032 zval_ptr_dtor(&retval
);
3038 #define PHP_PQ_TYPES_QUERY \
3039 "select t.oid, t.* " \
3040 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
3041 "where typisdefined " \
3043 #define PHP_PQ_OID_TEXT 25
3045 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh
, 0, 0, 0)
3046 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3047 ZEND_END_ARG_INFO();
3048 static PHP_METHOD(pqtypes
, refresh
) {
3049 HashTable
*nsp
= NULL
;
3050 zend_error_handling zeh
;
3053 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3054 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|H/!", &nsp
);
3055 zend_restore_error_handling(&zeh TSRMLS_CC
);
3057 if (SUCCESS
== rv
) {
3058 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3061 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Types not initialized");
3065 if (!nsp
|| !zend_hash_num_elements(nsp
)) {
3066 res
= PQexec(obj
->intern
->conn
->intern
->conn
, PHP_PQ_TYPES_QUERY
" and nspname in ('public', 'pg_catalog')");
3070 char **params
= NULL
;
3072 smart_str str
= {0};
3074 smart_str_appends(&str
, PHP_PQ_TYPES_QUERY
" and nspname in(");
3075 zend_hash_init(&zdtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
3076 count
= php_pq_params_to_array(nsp
, ¶ms
, &zdtor TSRMLS_CC
);
3077 oids
= ecalloc(count
+ 1, sizeof(*oids
));
3078 for (i
= 0; i
< count
; ++i
) {
3079 oids
[i
] = PHP_PQ_OID_TEXT
;
3081 smart_str_appendc(&str
, ',');
3083 smart_str_appendc(&str
, '$');
3084 smart_str_append_unsigned(&str
, i
+1);
3086 smart_str_appendc(&str
, ')');
3089 res
= PQexecParams(obj
->intern
->conn
->intern
->conn
, str
.c
, count
, oids
, (const char *const*) params
, NULL
, NULL
, 0);
3091 smart_str_free(&str
);
3094 zend_hash_destroy(&zdtor
);
3098 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3100 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3103 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
3104 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT
, NULL TSRMLS_CC
);
3105 long oid
= atol(PQgetvalue(res
, r
, 0 ));
3106 char *name
= PQgetvalue(res
, r
, 1);
3110 zend_hash_index_update(&obj
->intern
->types
, oid
, (void *) &row
, sizeof(zval
*), NULL
);
3111 zend_hash_add(&obj
->intern
->types
, name
, strlen(name
) + 1, (void *) &row
, sizeof(zval
*), NULL
);
3116 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3122 static zend_function_entry php_pqtypes_methods
[] = {
3123 PHP_ME(pqtypes
, __construct
, ai_pqtypes_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3124 PHP_ME(pqtypes
, refresh
, ai_pqtypes_refresh
, ZEND_ACC_PUBLIC
)
3128 static STATUS
php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type
, zval
***row TSRMLS_DC
)
3131 php_pqres_fetch_t orig_fetch
;
3134 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3137 if (!obj
->intern
->iter
) {
3138 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
3139 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3141 orig_fetch
= obj
->intern
->iter
->fetch_type
;
3142 obj
->intern
->iter
->fetch_type
= fetch_type
;
3143 if (SUCCESS
== (rv
= obj
->intern
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
))) {
3144 obj
->intern
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->intern
->iter
, row TSRMLS_CC
);
3145 obj
->intern
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3147 obj
->intern
->iter
->fetch_type
= orig_fetch
;
3152 typedef struct php_pqres_col
{
3157 static STATUS
column_nn(php_pqres_object_t
*obj
, zval
*zcol
, php_pqres_col_t
*col TSRMLS_DC
)
3162 switch (Z_TYPE_P(zcol
)) {
3164 convert_to_string(zcol
);
3168 if (!is_numeric_string(Z_STRVAL_P(zcol
), Z_STRLEN_P(zcol
), &index
, NULL
, 0)) {
3169 name
= Z_STRVAL_P(zcol
);
3174 index
= Z_LVAL_P(zcol
);
3180 col
->num
= PQfnumber(obj
->intern
->res
, name
);
3182 col
->name
= PQfname(obj
->intern
->res
, index
);
3187 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column at index %ld", index
);
3190 if (col
->num
== -1) {
3191 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column with name '%s'", name
);
3197 static int compare_index(const void *lptr
, const void *rptr TSRMLS_DC
)
3199 const Bucket
*l
= *(const Bucket
**) lptr
;
3200 const Bucket
*r
= *(const Bucket
**) rptr
;
3211 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind
, 0, 0, 2)
3212 ZEND_ARG_INFO(0, col
)
3213 ZEND_ARG_INFO(1, ref
)
3214 ZEND_END_ARG_INFO();
3215 static PHP_METHOD(pqres
, bind
) {
3218 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z/z", &zcol
, &zref
)) {
3219 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3222 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Result not initialized");
3224 php_pqres_col_t col
;
3226 if (SUCCESS
!= column_nn(obj
, zcol
, &col TSRMLS_CC
)) {
3231 if (SUCCESS
!= zend_hash_index_update(&obj
->intern
->bound
, col
.num
, (void *) &zref
, sizeof(zval
*), NULL
)) {
3232 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to bind column %s@%d", col
.name
, col
.num
);
3235 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3243 static int apply_bound(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3245 zval
**zvalue
, **zbound
= p
;
3246 zval
**zrow
= va_arg(argv
, zval
**);
3247 STATUS
*rv
= va_arg(argv
, STATUS
*);
3249 if (SUCCESS
!= zend_hash_index_find(Z_ARRVAL_PP(zrow
), key
->h
, (void *) &zvalue
)) {
3250 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column ad index %lu", key
->h
);
3252 return ZEND_HASH_APPLY_STOP
;
3255 ZVAL_COPY_VALUE(*zbound
, *zvalue
);
3257 zval_ptr_dtor(zvalue
);
3258 Z_ADDREF_P(*zbound
);
3261 return ZEND_HASH_APPLY_KEEP
;
3265 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound
, 0, 0, 0)
3266 ZEND_END_ARG_INFO();
3267 static PHP_METHOD(pqres
, fetchBound
) {
3268 zend_error_handling zeh
;
3271 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3272 rv
= zend_parse_parameters_none();
3273 zend_restore_error_handling(&zeh TSRMLS_CC
);
3275 if (SUCCESS
== rv
) {
3276 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3279 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Result not initialized");
3283 if (SUCCESS
== php_pqres_iteration(getThis(), obj
, PHP_PQRES_FETCH_ARRAY
, &row TSRMLS_CC
) && row
) {
3284 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3285 zend_hash_apply_with_arguments(&obj
->intern
->bound TSRMLS_CC
, apply_bound
, 2, row
, &rv
);
3286 zend_restore_error_handling(&zeh TSRMLS_CC
);
3288 if (SUCCESS
!= rv
) {
3291 RETVAL_ZVAL(*row
, 1, 0);
3298 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
3299 ZEND_ARG_INFO(0, fetch_type
)
3300 ZEND_END_ARG_INFO();
3301 static PHP_METHOD(pqres
, fetchRow
) {
3302 zend_error_handling zeh
;
3303 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3304 long fetch_type
= -1;
3307 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3308 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3309 zend_restore_error_handling(&zeh TSRMLS_CC
);
3311 if (SUCCESS
== rv
) {
3313 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Result not initialized");
3317 if (fetch_type
== -1) {
3318 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3321 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3322 php_pqres_iteration(getThis(), obj
, fetch_type
, &row TSRMLS_CC
);
3323 zend_restore_error_handling(&zeh TSRMLS_CC
);
3326 RETVAL_ZVAL(*row
, 1, 0);
3332 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
3335 HashTable
*ht
= HASH_OF(row
);
3336 int count
= zend_hash_num_elements(ht
);
3339 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
3341 zend_hash_internal_pointer_reset(ht
);
3343 zend_hash_move_forward(ht
);
3345 zend_hash_get_current_data(ht
, (void *) &data
);
3350 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
3351 ZEND_ARG_INFO(0, col_num
)
3352 ZEND_END_ARG_INFO();
3353 static PHP_METHOD(pqres
, fetchCol
) {
3354 zend_error_handling zeh
;
3358 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3359 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
);
3360 zend_restore_error_handling(&zeh TSRMLS_CC
);
3362 if (SUCCESS
== rv
) {
3363 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3366 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Result not initialized");
3370 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3371 php_pqres_iteration(getThis(), obj
, obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: 0, &row TSRMLS_CC
);
3373 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
3376 RETVAL_ZVAL(*col
, 1, 0);
3379 zend_restore_error_handling(&zeh TSRMLS_CC
);
3384 static int apply_to_col(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3387 php_pqres_object_t
*obj
= va_arg(argv
, php_pqres_object_t
*);
3388 php_pqres_col_t
*col
, **cols
= va_arg(argv
, php_pqres_col_t
**);
3389 STATUS
*rv
= va_arg(argv
, STATUS
*);
3393 if (SUCCESS
!= column_nn(obj
, *c
, col TSRMLS_CC
)) {
3395 return ZEND_HASH_APPLY_STOP
;
3399 return ZEND_HASH_APPLY_KEEP
;
3403 static php_pqres_col_t
*php_pqres_convert_to_cols(php_pqres_object_t
*obj
, HashTable
*ht TSRMLS_DC
)
3405 php_pqres_col_t
*tmp
, *cols
= ecalloc(zend_hash_num_elements(ht
), sizeof(*cols
));
3406 STATUS rv
= SUCCESS
;
3409 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_col
, 2, obj
, &tmp
, &rv
);
3411 if (SUCCESS
== rv
) {
3419 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map
, 0, 0, 0)
3420 ZEND_ARG_INFO(0, keys
)
3421 ZEND_ARG_INFO(0, vals
)
3422 ZEND_ARG_INFO(0, fetch_type
)
3423 ZEND_END_ARG_INFO();
3424 static PHP_METHOD(pqres
, map
) {
3425 zend_error_handling zeh
;
3426 zval
*zkeys
= 0, *zvals
= 0;
3427 long fetch_type
= -1;
3430 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3431 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z/!z/!l", &zkeys
, &zvals
, &fetch_type
);
3432 zend_restore_error_handling(&zeh TSRMLS_CC
);
3434 if (SUCCESS
== rv
) {
3435 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3438 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Result not initialized");
3441 php_pqres_col_t def
= {PQfname(obj
->intern
->res
, 0), 0}, *keys
= NULL
, *vals
= NULL
;
3444 convert_to_array(zkeys
);
3446 if ((ks
= zend_hash_num_elements(Z_ARRVAL_P(zkeys
)))) {
3447 keys
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zkeys
) TSRMLS_CC
);
3457 convert_to_array(zvals
);
3459 if ((vs
= zend_hash_num_elements(Z_ARRVAL_P(zvals
)))) {
3460 vals
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zvals
) TSRMLS_CC
);
3464 if (fetch_type
== -1) {
3465 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3472 switch (fetch_type
) {
3473 case PHP_PQRES_FETCH_ARRAY
:
3474 case PHP_PQRES_FETCH_ASSOC
:
3475 array_init(return_value
);
3477 case PHP_PQRES_FETCH_OBJECT
:
3478 object_init(return_value
);
3481 for (r
= 0, rows
= PQntuples(obj
->intern
->res
); r
< rows
; ++r
) {
3484 cur
= &return_value
;
3485 for (k
= 0; k
< ks
; ++k
) {
3486 char *key
= PQgetvalue(obj
->intern
->res
, r
, keys
[k
].num
);
3487 int len
= PQgetlength(obj
->intern
->res
, r
, keys
[k
].num
);
3489 if (SUCCESS
!= zend_symtable_find(HASH_OF(*cur
), key
, len
+ 1, (void *) &cur
)) {
3493 switch (fetch_type
) {
3494 case PHP_PQRES_FETCH_ARRAY
:
3495 case PHP_PQRES_FETCH_ASSOC
:
3498 case PHP_PQRES_FETCH_OBJECT
:
3502 if (SUCCESS
!= zend_symtable_update(HASH_OF(*cur
), key
, len
+ 1, (void *) &tmp
, sizeof(zval
*), (void *) &cur
)) {
3503 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to create map");
3509 for (v
= 0; v
< vs
; ++v
) {
3510 char *val
= PQgetvalue(obj
->intern
->res
, r
, vals
[v
].num
);
3511 int len
= PQgetlength(obj
->intern
->res
, r
, vals
[v
].num
);
3513 switch (fetch_type
) {
3514 case PHP_PQRES_FETCH_ARRAY
:
3515 add_index_stringl(*cur
, vals
[v
].num
, val
, len
, 1);
3517 case PHP_PQRES_FETCH_ASSOC
:
3518 add_assoc_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3520 case PHP_PQRES_FETCH_OBJECT
:
3521 add_property_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3526 php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, cur TSRMLS_CC
);
3532 if (keys
&& keys
!= &def
) {
3542 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count
, 0, 0, 0)
3543 ZEND_END_ARG_INFO();
3544 static PHP_METHOD(pqres
, count
) {
3545 if (SUCCESS
== zend_parse_parameters_none()) {
3548 if (SUCCESS
!= php_pqres_count_elements(getThis(), &count TSRMLS_CC
)) {
3549 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Result not initialized");
3556 static zend_function_entry php_pqres_methods
[] = {
3557 PHP_ME(pqres
, bind
, ai_pqres_bind
, ZEND_ACC_PUBLIC
)
3558 PHP_ME(pqres
, fetchBound
, ai_pqres_fetch_bound
, ZEND_ACC_PUBLIC
)
3559 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
3560 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
3561 PHP_ME(pqres
, count
, ai_pqres_count
, ZEND_ACC_PUBLIC
)
3562 PHP_ME(pqres
, map
, ai_pqres_map
, ZEND_ACC_PUBLIC
)
3566 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
3567 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
3568 ZEND_ARG_INFO(0, type
)
3569 ZEND_ARG_INFO(0, query
)
3570 ZEND_ARG_ARRAY_INFO(0, types
, 1)
3571 ZEND_ARG_INFO(0, async
)
3572 ZEND_END_ARG_INFO();
3573 static PHP_METHOD(pqstm
, __construct
) {
3574 zend_error_handling zeh
;
3575 zval
*zconn
, *ztypes
= NULL
;
3576 char *name_str
, *query_str
;
3577 int name_len
, *query_len
;
3578 zend_bool async
= 0;
3581 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3582 rv
= 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
);
3583 zend_restore_error_handling(&zeh TSRMLS_CC
);
3585 if (SUCCESS
== rv
) {
3586 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3587 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3589 if (!conn_obj
->intern
) {
3590 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
3593 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3595 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3598 if (SUCCESS
== rv
) {
3599 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
3601 php_pq_object_addref(conn_obj TSRMLS_CC
);
3602 stm
->conn
= conn_obj
;
3603 stm
->name
= estrdup(name_str
);
3604 ZEND_INIT_SYMTABLE(&stm
->bound
);
3610 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind
, 0, 0, 2)
3611 ZEND_ARG_INFO(0, param_no
)
3612 ZEND_ARG_INFO(1, param_ref
)
3613 ZEND_END_ARG_INFO();
3614 static PHP_METHOD(pqstm
, bind
) {
3618 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "lz", ¶m_no
, ¶m_ref
)) {
3619 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3622 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Statement not initialized");
3624 Z_ADDREF_P(param_ref
);
3625 zend_hash_index_update(&obj
->intern
->bound
, param_no
, (void *) ¶m_ref
, sizeof(zval
*), NULL
);
3626 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3631 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
3632 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3633 ZEND_END_ARG_INFO();
3634 static PHP_METHOD(pqstm
, exec
) {
3635 zend_error_handling zeh
;
3636 zval
*zparams
= NULL
;
3639 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3640 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
);
3641 zend_restore_error_handling(&zeh TSRMLS_CC
);
3643 if (SUCCESS
== rv
) {
3644 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3647 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Statement not initialized");
3650 char **params
= NULL
;
3654 ZEND_INIT_SYMTABLE(&zdtor
);
3657 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3659 count
= php_pq_params_to_array(&obj
->intern
->bound
, ¶ms
, &zdtor TSRMLS_CC
);
3662 res
= PQexecPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
3667 zend_hash_destroy(&zdtor
);
3670 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3671 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3672 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
3675 ZEND_INIT_SYMTABLE(&r
->bound
);
3676 return_value
->type
= IS_OBJECT
;
3677 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
3679 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3685 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
3686 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3687 ZEND_ARG_INFO(0, callable
)
3688 ZEND_END_ARG_INFO();
3689 static PHP_METHOD(pqstm
, execAsync
) {
3690 zend_error_handling zeh
;
3691 zval
*zparams
= NULL
;
3692 php_pq_callback_t resolver
= {{0}};
3695 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3696 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
);
3697 zend_restore_error_handling(&zeh TSRMLS_CC
);
3699 if (SUCCESS
== rv
) {
3700 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3703 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Statement not initialized");
3706 char **params
= NULL
;
3710 ZEND_INIT_SYMTABLE(&zdtor
);
3711 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3714 if (!PQsendQueryPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
3715 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3716 } else if (obj
->intern
->conn
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
->intern
->conn
)) {
3717 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3719 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
3720 if (resolver
.fci
.size
> 0) {
3721 obj
->intern
->conn
->intern
->onevent
= resolver
;
3722 php_pq_callback_addref(&obj
->intern
->conn
->intern
->onevent
);
3724 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3731 zend_hash_destroy(&zdtor
);
3734 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3739 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
3740 ZEND_END_ARG_INFO();
3741 static PHP_METHOD(pqstm
, desc
) {
3742 zend_error_handling zeh
;
3745 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3746 rv
= zend_parse_parameters_none();
3747 zend_restore_error_handling(&zeh TSRMLS_CC
);
3749 if (SUCCESS
== rv
) {
3750 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3753 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Statement not initialized");
3755 PGresult
*res
= PQdescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
);
3758 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3760 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3763 array_init(return_value
);
3764 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
3765 add_next_index_long(return_value
, PQparamtype(res
, p
));
3769 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3775 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async
, 0, 0, 0)
3776 ZEND_END_ARG_INFO();
3777 static PHP_METHOD(pqstm
, descAsync
) {
3778 zend_error_handling zeh
;
3781 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3782 rv
= zend_parse_parameters_none();
3783 zend_restore_error_handling(&zeh TSRMLS_CC
);
3785 if (SUCCESS
== rv
) {
3786 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3789 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Statement not initialized");
3790 } else if (!PQsendDescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
)) {
3791 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to describe statement: %s", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3793 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3794 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3799 static zend_function_entry php_pqstm_methods
[] = {
3800 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3801 PHP_ME(pqstm
, bind
, ai_pqstm_bind
, ZEND_ACC_PUBLIC
)
3802 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
3803 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
3804 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
3805 PHP_ME(pqstm
, descAsync
, ai_pqstm_desc_async
, ZEND_ACC_PUBLIC
)
3809 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
3810 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3811 ZEND_ARG_INFO(0, async
)
3812 ZEND_ARG_INFO(0, isolation
)
3813 ZEND_ARG_INFO(0, readonly
)
3814 ZEND_ARG_INFO(0, deferrable
)
3815 ZEND_END_ARG_INFO();
3816 static PHP_METHOD(pqtxn
, __construct
) {
3817 zend_error_handling zeh
;
3819 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3820 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
3823 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3824 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
);
3825 zend_restore_error_handling(&zeh TSRMLS_CC
);
3827 if (SUCCESS
== rv
) {
3828 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3830 if (!conn_obj
->intern
) {
3831 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Connection not initialized");
3834 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3836 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3839 if (SUCCESS
== rv
) {
3840 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3842 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3844 php_pq_object_addref(conn_obj TSRMLS_CC
);
3845 obj
->intern
->conn
= conn_obj
;
3846 obj
->intern
->open
= 1;
3847 obj
->intern
->isolation
= isolation
;
3848 obj
->intern
->readonly
= readonly
;
3849 obj
->intern
->deferrable
= deferrable
;
3855 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint
, 0, 0, 0)
3856 ZEND_END_ARG_INFO();
3857 static PHP_METHOD(pqtxn
, savepoint
) {
3858 zend_error_handling zeh
;
3861 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3862 rv
= zend_parse_parameters_none();
3863 zend_restore_error_handling(&zeh TSRMLS_CC
);
3865 if (SUCCESS
== rv
) {
3866 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3869 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
3870 } else if (!obj
->intern
->open
) {
3871 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
3874 smart_str cmd
= {0};
3876 smart_str_appends(&cmd
, "SAVEPOINT \"");
3877 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
3878 smart_str_appends(&cmd
, "\"");
3881 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
3884 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3886 php_pqres_success(res TSRMLS_CC
);
3890 smart_str_free(&cmd
);
3895 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async
, 0, 0, 0)
3896 ZEND_END_ARG_INFO();
3897 static PHP_METHOD(pqtxn
, savepointAsync
) {
3898 zend_error_handling zeh
;
3901 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3902 rv
= zend_parse_parameters_none();
3903 zend_restore_error_handling(&zeh TSRMLS_CC
);
3905 if (SUCCESS
== rv
) {
3906 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3909 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
3910 } else if (!obj
->intern
->open
) {
3911 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
3913 smart_str cmd
= {0};
3915 smart_str_appends(&cmd
, "SAVEPOINT \"");
3916 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
3917 smart_str_appends(&cmd
, "\"");
3920 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
3921 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3924 smart_str_free(&cmd
);
3929 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
3930 ZEND_END_ARG_INFO();
3931 static PHP_METHOD(pqtxn
, commit
) {
3932 zend_error_handling zeh
;
3935 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3936 rv
= zend_parse_parameters_none();
3937 zend_restore_error_handling(&zeh TSRMLS_CC
);
3939 if (SUCCESS
== rv
) {
3940 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3943 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transacation not initialized");
3944 } else if (!obj
->intern
->open
) {
3945 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transacation already closed");
3948 smart_str cmd
= {0};
3950 if (!obj
->intern
->savepoint
) {
3951 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "COMMIT");
3953 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
3954 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
3955 smart_str_appends(&cmd
, "\"");
3958 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
3962 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3964 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3966 obj
->intern
->open
= 0;
3972 smart_str_free(&cmd
);
3973 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3978 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
3979 ZEND_END_ARG_INFO();
3980 static PHP_METHOD(pqtxn
, commitAsync
) {
3981 zend_error_handling zeh
;
3984 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
3985 rv
= zend_parse_parameters_none();
3986 zend_restore_error_handling(&zeh TSRMLS_CC
);
3988 if (SUCCESS
== rv
) {
3989 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3992 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
3993 } else if (!obj
->intern
->open
) {
3994 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
3997 smart_str cmd
= {0};
3999 if (!obj
->intern
->savepoint
) {
4000 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4002 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4003 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4004 smart_str_appends(&cmd
, "\"");
4007 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4011 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commmit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4014 obj
->intern
->open
= 0;
4016 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4017 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4020 smart_str_free(&cmd
);
4025 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
4026 ZEND_END_ARG_INFO();
4027 static PHP_METHOD(pqtxn
, rollback
) {
4028 zend_error_handling zeh
;
4031 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4032 rv
= zend_parse_parameters_none();
4033 zend_restore_error_handling(&zeh TSRMLS_CC
);
4035 if (SUCCESS
== rv
) {
4036 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4039 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
4040 } else if (!obj
->intern
->open
) {
4041 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4044 smart_str cmd
= {0};
4046 if (!obj
->intern
->savepoint
) {
4047 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4049 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4050 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4051 smart_str_appends(&cmd
, "\"");
4054 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4058 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4060 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4062 obj
->intern
->open
= 0;
4068 smart_str_free(&cmd
);
4069 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4074 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
4075 ZEND_END_ARG_INFO();
4076 static PHP_METHOD(pqtxn
, rollbackAsync
) {
4077 zend_error_handling zeh
;
4080 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4081 rv
= zend_parse_parameters_none();
4082 zend_restore_error_handling(&zeh TSRMLS_CC
);
4084 if (SUCCESS
== rv
) {
4085 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4088 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
4089 } else if (!obj
->intern
->open
) {
4090 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4093 smart_str cmd
= {0};
4095 if (!obj
->intern
->savepoint
) {
4096 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4098 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4099 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4100 smart_str_appends(&cmd
, "\"");
4103 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4107 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4110 obj
->intern
->open
= 0;
4112 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4115 smart_str_free(&cmd
);
4116 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4121 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot
, 0, 0, 0)
4122 ZEND_END_ARG_INFO();
4123 static PHP_METHOD(pqtxn
, exportSnapshot
) {
4124 zend_error_handling zeh
;
4127 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4128 rv
= zend_parse_parameters_none();
4129 zend_restore_error_handling(&zeh TSRMLS_CC
);
4131 if (SUCCESS
== rv
) {
4132 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4135 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
4137 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()");
4140 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4142 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4143 RETVAL_STRING(PQgetvalue(res
, 0, 0), 1);
4149 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4154 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async
, 0, 0, 0)
4155 ZEND_END_ARG_INFO();
4156 static PHP_METHOD(pqtxn
, exportSnapshotAsync
) {
4157 zend_error_handling zeh
;
4160 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4161 rv
= zend_parse_parameters_none();
4162 zend_restore_error_handling(&zeh TSRMLS_CC
);
4164 if (SUCCESS
== rv
) {
4165 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4168 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
4169 } else if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()")) {
4170 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4172 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4173 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4178 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot
, 0, 0, 1)
4179 ZEND_ARG_INFO(0, snapshot_id
)
4180 ZEND_END_ARG_INFO();
4181 static PHP_METHOD(pqtxn
, importSnapshot
) {
4182 zend_error_handling zeh
;
4187 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4188 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4189 zend_restore_error_handling(&zeh TSRMLS_CC
);
4191 if (SUCCESS
== rv
) {
4192 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4195 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
4196 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4197 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4199 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4202 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4205 smart_str cmd
= {0};
4207 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4208 smart_str_appends(&cmd
, sid
);
4211 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4214 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4216 php_pqres_success(res TSRMLS_CC
);
4220 smart_str_free(&cmd
);
4221 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4227 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async
, 0, 0, 1)
4228 ZEND_ARG_INFO(0, snapshot_id
)
4229 ZEND_END_ARG_INFO();
4230 static PHP_METHOD(pqtxn
, importSnapshotAsync
) {
4231 zend_error_handling zeh
;
4236 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4237 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4238 zend_restore_error_handling(&zeh TSRMLS_CC
);
4240 if (SUCCESS
== rv
) {
4241 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4244 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction not initialized");
4245 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4246 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4248 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4251 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4253 smart_str cmd
= {0};
4255 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4256 smart_str_appends(&cmd
, sid
);
4259 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4260 zend_throw_exception_ex(exce(EX_RUNTIME
), EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4262 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4265 smart_str_free(&cmd
);
4266 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4272 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob
, 0, 0, 1)
4273 ZEND_ARG_INFO(0, oid
)
4274 ZEND_ARG_INFO(0, mode
)
4275 ZEND_END_ARG_INFO();
4276 static PHP_METHOD(pqtxn
, openLOB
) {
4277 zend_error_handling zeh
;
4278 long mode
= INV_WRITE
|INV_READ
, loid
;
4280 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4281 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &loid
, &mode
)) {
4282 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4285 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4288 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4292 php_pq_object_addref(obj TSRMLS_CC
);
4295 return_value
->type
= IS_OBJECT
;
4296 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4298 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to open large object with mode '%s' (%s)",
4299 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4300 (mode
& INV_READ
? "r" :
4301 (mode
& INV_WRITE
? "w" : "-"))),
4302 PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
)
4306 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4309 zend_restore_error_handling(&zeh TSRMLS_CC
);
4312 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob
, 0, 0, 0)
4313 ZEND_ARG_INFO(0, mode
)
4314 ZEND_END_ARG_INFO();
4315 static PHP_METHOD(pqtxn
, createLOB
) {
4316 zend_error_handling zeh
;
4317 long mode
= INV_WRITE
|INV_READ
;
4319 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4320 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &mode
)) {
4321 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4324 Oid loid
= lo_creat(obj
->intern
->conn
->intern
->conn
, mode
);
4326 if (loid
!= InvalidOid
) {
4327 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4330 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4333 php_pq_object_addref(obj TSRMLS_CC
);
4336 return_value
->type
= IS_OBJECT
;
4337 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4339 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to open large object with mode '%s': %s",
4340 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4341 (mode
& INV_READ
? "r" :
4342 (mode
& INV_WRITE
? "w" : "-"))),
4343 PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
)
4347 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to create large object with mode '%s': %s",
4348 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4349 (mode
& INV_READ
? "r" :
4350 (mode
& INV_WRITE
? "w" : "-"))),
4351 PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
)
4355 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4358 zend_restore_error_handling(&zeh TSRMLS_CC
);
4361 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob
, 0, 0, 1)
4362 ZEND_ARG_INFO(0, oid
)
4363 ZEND_END_ARG_INFO();
4364 static PHP_METHOD(pqtxn
, unlinkLOB
) {
4367 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &loid
)) {
4368 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4371 if (1 == lo_unlink(obj
->intern
->conn
->intern
->conn
, loid
)) {
4374 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unlink LOB (oid=%ld): %s", loid
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4378 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4384 static zend_function_entry php_pqtxn_methods
[] = {
4385 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4386 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
4387 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
4388 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
4389 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
4390 PHP_ME(pqtxn
, savepoint
, ai_pqtxn_savepoint
, ZEND_ACC_PUBLIC
)
4391 PHP_ME(pqtxn
, savepointAsync
, ai_pqtxn_savepoint_async
, ZEND_ACC_PUBLIC
)
4392 PHP_ME(pqtxn
, exportSnapshot
, ai_pqtxn_export_snapshot
, ZEND_ACC_PUBLIC
)
4393 PHP_ME(pqtxn
, exportSnapshotAsync
, ai_pqtxn_export_snapshot_async
, ZEND_ACC_PUBLIC
)
4394 PHP_ME(pqtxn
, importSnapshot
, ai_pqtxn_import_snapshot
, ZEND_ACC_PUBLIC
)
4395 PHP_ME(pqtxn
, importSnapshotAsync
, ai_pqtxn_import_snapshot_async
, ZEND_ACC_PUBLIC
)
4396 PHP_ME(pqtxn
, openLOB
, ai_pqtxn_open_lob
, ZEND_ACC_PUBLIC
)
4397 PHP_ME(pqtxn
, createLOB
, ai_pqtxn_create_lob
, ZEND_ACC_PUBLIC
)
4398 PHP_ME(pqtxn
, unlinkLOB
, ai_pqtxn_unlink_lob
, ZEND_ACC_PUBLIC
)
4402 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
4403 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4404 ZEND_END_ARG_INFO();
4405 static PHP_METHOD(pqcancel
, __construct
) {
4406 zend_error_handling zeh
;
4409 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4410 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
)) {
4411 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4413 if (conn_obj
->intern
) {
4414 PGcancel
*cancel
= PQgetCancel(conn_obj
->intern
->conn
);
4417 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4419 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4420 obj
->intern
->cancel
= cancel
;
4421 php_pq_object_addref(conn_obj TSRMLS_CC
);
4422 obj
->intern
->conn
= conn_obj
;
4424 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
4427 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
4430 zend_restore_error_handling(&zeh TSRMLS_CC
);
4433 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
4434 ZEND_END_ARG_INFO();
4435 static PHP_METHOD(pqcancel
, cancel
) {
4436 zend_error_handling zeh
;
4438 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4439 if (SUCCESS
== zend_parse_parameters_none()) {
4440 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4445 if (!PQcancel(obj
->intern
->cancel
, err
, sizeof(err
))) {
4446 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to request cancellation: %s", err
);
4449 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Cancel not initialized");
4452 zend_restore_error_handling(&zeh TSRMLS_CC
);
4455 static zend_function_entry php_pqcancel_methods
[] = {
4456 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4457 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
4461 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
)
4465 if (SUCCESS
== zend_hash_find(&conn_obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
4467 add_next_index_zval(*evhs
, zevent
);
4474 add_next_index_zval(evh
, zevent
);
4475 zend_hash_add(&conn_obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(zval
*), NULL
);
4479 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_construct
, 0, 0, 3)
4480 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4481 ZEND_ARG_INFO(0, type
)
4482 ZEND_ARG_INFO(0, callable
)
4483 ZEND_END_ARG_INFO();
4484 static PHP_METHOD(pqevent
, __construct
) {
4485 zend_error_handling zeh
;
4489 php_pq_callback_t cb
;
4491 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4492 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Osf", &zconn
, php_pqconn_class_entry
, &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
)) {
4493 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4495 if (conn_obj
->intern
) {
4496 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4498 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4499 php_pq_callback_addref(&cb
);
4500 obj
->intern
->cb
= cb
;
4501 php_pq_object_addref(conn_obj TSRMLS_CC
);
4502 obj
->intern
->conn
= conn_obj
;
4503 obj
->intern
->type
= estrdup(type_str
);
4505 php_pqconn_add_eventhandler(zconn
, conn_obj
, type_str
, type_len
, getThis() TSRMLS_CC
);
4508 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
4511 zend_restore_error_handling(&zeh TSRMLS_CC
);
4514 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_trigger
, 0, 0, 1)
4515 ZEND_ARG_ARRAY_INFO(0, args
, 1)
4516 ZEND_END_ARG_INFO();
4517 static PHP_METHOD(pqevent
, trigger
) {
4520 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a/", &args
)) {
4521 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4526 if (SUCCESS
== zend_fcall_info_call(&obj
->intern
->cb
.fci
, &obj
->intern
->cb
.fcc
, &rv
, args TSRMLS_CC
)) {
4528 RETVAL_ZVAL(rv
, 0, 1);
4534 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Event not initialized");
4540 static zend_function_entry php_pqevent_methods
[] = {
4541 PHP_ME(pqevent
, __construct
, ai_pqevent_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4542 PHP_ME(pqevent
, trigger
, ai_pqevent_trigger
, ZEND_ACC_PUBLIC
)
4546 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct
, 0, 0, 1)
4547 ZEND_ARG_OBJ_INFO(0, transaction
, pq
\\Transaction
, 0)
4548 ZEND_ARG_INFO(0, oid
)
4549 ZEND_ARG_INFO(0, mode
)
4550 ZEND_END_ARG_INFO();
4551 static PHP_METHOD(pqlob
, __construct
) {
4552 zend_error_handling zeh
;
4554 long mode
= INV_WRITE
|INV_READ
, loid
= InvalidOid
;
4556 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4557 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|ll", &ztxn
, php_pqtxn_class_entry
, &loid
, &mode
)) {
4558 php_pqtxn_object_t
*txn_obj
= zend_object_store_get_object(ztxn TSRMLS_CC
);
4560 if (txn_obj
->intern
) {
4562 if (loid
== InvalidOid
) {
4563 loid
= lo_creat(txn_obj
->intern
->conn
->intern
->conn
, mode
);
4566 if (loid
!= InvalidOid
) {
4567 int lofd
= lo_open(txn_obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4570 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4572 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4573 obj
->intern
->lofd
= lofd
;
4574 obj
->intern
->loid
= loid
;
4575 php_pq_object_addref(txn_obj TSRMLS_CC
);
4576 obj
->intern
->txn
= txn_obj
;
4578 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to open large object with mode '%s' (%s)",
4579 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4580 (mode
& INV_READ
? "r" :
4581 (mode
& INV_WRITE
? "w" : "-"))),
4582 PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
)
4586 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to create large object with mode '%s' (%s)",
4587 (mode
& (INV_READ
|INV_WRITE
) ? "rw" :
4588 (mode
& INV_READ
? "r" :
4589 (mode
& INV_WRITE
? "w" : "-"))),
4590 PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
)
4594 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
4597 zend_restore_error_handling(&zeh TSRMLS_CC
);
4600 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write
, 0, 0, 1)
4601 ZEND_ARG_INFO(0, data
)
4602 ZEND_END_ARG_INFO();
4603 static PHP_METHOD(pqlob
, write
) {
4607 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
)) {
4608 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4611 int written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, data_str
, data_len
);
4614 RETVAL_LONG(written
);
4616 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to write to LOB, oid=%d (%s)", obj
->intern
->loid
,
4617 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4621 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4627 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read
, 0, 0, 0)
4628 ZEND_ARG_INFO(0, length
)
4629 ZEND_ARG_INFO(1, read
)
4630 ZEND_END_ARG_INFO();
4631 static PHP_METHOD(pqlob
, read
) {
4632 long length
= 0x1000;
4635 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lz!", &length
, &zread
)) {
4636 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4639 char *buffer
= emalloc(length
+ 1);
4640 int read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4645 ZVAL_LONG(zread
, read
);
4647 buffer
[read
] = '\0';
4648 RETVAL_STRINGL(buffer
, read
, 0);
4651 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to read from LOB, oid=%d (%s)", obj
->intern
->loid
,
4652 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4657 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4663 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek
, 0, 0, 1)
4664 ZEND_ARG_INFO(0, offset
)
4665 ZEND_ARG_INFO(0, whence
)
4666 ZEND_END_ARG_INFO();
4667 static PHP_METHOD(pqlob
, seek
) {
4668 long offset
, whence
= SEEK_SET
;
4670 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &offset
, &whence
)) {
4671 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4674 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4676 if (position
>= 0) {
4677 RETVAL_LONG(position
);
4679 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to seek offset in LOB, oid=%d (%s)", obj
->intern
->loid
,
4680 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4684 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4690 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell
, 0, 0, 0)
4691 ZEND_END_ARG_INFO();
4692 static PHP_METHOD(pqlob
, tell
) {
4693 if (SUCCESS
== zend_parse_parameters_none()) {
4694 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4697 int position
= lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
4699 if (position
>= 0) {
4700 RETVAL_LONG(position
);
4702 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to tell offset in LOB (oid=%d): %s", obj
->intern
->loid
,
4703 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4707 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4713 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate
, 0, 0, 0)
4714 ZEND_ARG_INFO(0, length
)
4715 ZEND_END_ARG_INFO();
4716 static PHP_METHOD(pqlob
, truncate
) {
4719 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &length
)) {
4720 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4723 if (0 == lo_truncate(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, length
)) {
4726 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to truncate LOB (oid=%d): %s", obj
->intern
->loid
,
4727 PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4731 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\LOB not initialized");
4737 static zend_function_entry php_pqlob_methods
[] = {
4738 PHP_ME(pqlob
, __construct
, ai_pqlob_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4739 PHP_ME(pqlob
, write
, ai_pqlob_write
, ZEND_ACC_PUBLIC
)
4740 PHP_ME(pqlob
, read
, ai_pqlob_read
, ZEND_ACC_PUBLIC
)
4741 PHP_ME(pqlob
, seek
, ai_pqlob_seek
, ZEND_ACC_PUBLIC
)
4742 PHP_ME(pqlob
, tell
, ai_pqlob_tell
, ZEND_ACC_PUBLIC
)
4743 PHP_ME(pqlob
, truncate
, ai_pqlob_truncate
, ZEND_ACC_PUBLIC
)
4747 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct
, 0, 0, 3)
4748 ZEND_ARG_OBJ_INFO(0, "connection", pq
\\Connection
, 0)
4749 ZEND_ARG_INFO(0, expression
)
4750 ZEND_ARG_INFO(0, direction
)
4751 ZEND_ARG_INFO(0, options
)
4752 ZEND_END_ARG_INFO();
4753 static PHP_METHOD(pqcopy
, __construct
) {
4754 zend_error_handling zeh
;
4756 char *expr_str
, *opt_str
= "";
4757 int expr_len
, opt_len
= 0;
4760 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4761 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
)) {
4762 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4764 if (conn_obj
->intern
) {
4767 switch (direction
) {
4768 case PHP_PQCOPY_FROM_STDIN
:
4769 spprintf(©
, 0, "COPY %s %s %s", expr_str
, "FROM STDIN", opt_str
);
4772 case PHP_PQCOPY_TO_STDOUT
:
4773 spprintf(©
, 0, "COPY %s %s %s", expr_str
, "TO STDOUT", opt_str
);
4777 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid COPY direction, expected one of FROM_STDIN (%d) TO_STDOUT (%d), got %ld",
4778 PHP_PQCOPY_FROM_STDIN
, PHP_PQCOPY_TO_STDOUT
, direction
);
4783 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4784 PGresult
*res
= PQexec(conn_obj
->intern
->conn
, copy
);
4788 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4789 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4790 obj
->intern
->direction
= direction
;
4791 obj
->intern
->expression
= estrdup(expr_str
);
4792 obj
->intern
->options
= estrdup(opt_str
);
4793 obj
->intern
->conn
= conn_obj
;
4794 php_pq_object_addref(conn_obj TSRMLS_CC
);
4800 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
4803 zend_restore_error_handling(&zeh TSRMLS_CC
);
4806 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put
, 0, 0, 1)
4807 ZEND_ARG_INFO(0, data
)
4808 ZEND_END_ARG_INFO();
4809 static PHP_METHOD(pqcopy
, put
) {
4810 zend_error_handling zeh
;
4814 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4815 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
)) {
4816 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4819 if (PHP_PQCOPY_FROM_STDIN
== obj
->intern
->direction
) {
4820 if (1 == PQputCopyData(obj
->intern
->conn
->intern
->conn
, data_str
, data_len
)) {
4823 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to send COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4826 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY was not initialized with FROM_STDIN");
4829 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY not initialized");
4832 zend_restore_error_handling(&zeh TSRMLS_CC
);
4835 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end
, 0, 0, 0)
4836 ZEND_ARG_INFO(0, error
)
4837 ZEND_END_ARG_INFO();
4838 static PHP_METHOD(pqcopy
, end
) {
4839 zend_error_handling zeh
;
4840 char *error_str
= NULL
;
4843 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4844 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &error_str
, &error_len
)) {
4845 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4848 if (PHP_PQCOPY_FROM_STDIN
== obj
->intern
->direction
) {
4849 if (1 == PQputCopyEnd(obj
->intern
->conn
->intern
->conn
, error_str
)) {
4850 PGresult
*res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
4853 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4859 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to get COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4862 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4865 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY was not initialized with FROM_STDIN");
4868 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\COPY not initialized");
4871 zend_restore_error_handling(&zeh TSRMLS_CC
);
4874 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get
, 0, 0, 1)
4875 ZEND_ARG_INFO(1, data
)
4876 ZEND_END_ARG_INFO();
4877 static PHP_METHOD(pqcopy
, get
) {
4878 zend_error_handling zeh
;
4881 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
4882 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
)) {
4883 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4884 char *buffer
= NULL
;
4887 if (PHP_PQCOPY_TO_STDOUT
== obj
->intern
->direction
) {
4889 int bytes
= PQgetCopyData(obj
->intern
->conn
->intern
->conn
, &buffer
, 0);
4893 res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
4896 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4902 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to get COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4907 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to get COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4913 ZVAL_STRINGL(zdata
, buffer
, bytes
, 1);
4915 ZVAL_EMPTY_STRING(zdata
);
4927 zend_restore_error_handling(&zeh TSRMLS_CC
);
4930 static zend_function_entry php_pqcopy_methods
[] = {
4931 PHP_ME(pqcopy
, __construct
, ai_pqcopy_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4932 PHP_ME(pqcopy
, put
, ai_pqcopy_put
, ZEND_ACC_PUBLIC
)
4933 PHP_ME(pqcopy
, end
, ai_pqcopy_end
, ZEND_ACC_PUBLIC
)
4934 PHP_ME(pqcopy
, get
, ai_pqcopy_get
, ZEND_ACC_PUBLIC
)
4938 static zend_function_entry php_pqexc_methods
[] = {
4942 /* {{{ PHP_MINIT_FUNCTION
4944 static PHP_MINIT_FUNCTION(pq
)
4946 zend_class_entry ce
= {0};
4947 php_pq_object_prophandler_t ph
= {0};
4949 INIT_NS_CLASS_ENTRY(ce
, "pq", "Exception", php_pqexc_methods
);
4950 php_pqexc_interface_class_entry
= zend_register_internal_interface(&ce TSRMLS_CC
);
4952 memset(&ce
, 0, sizeof(ce
));
4953 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "Exception", php_pqexc_methods
);
4954 php_pqexc_default_class_entry
= zend_register_internal_class_ex(&ce
, zend_exception_get_default(TSRMLS_C
), "Exception" TSRMLS_CC
);
4955 zend_class_implements(php_pqexc_default_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
4957 memset(&ce
, 0, sizeof(ce
));
4958 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "InvalidArgument", php_pqexc_methods
);
4959 php_pqexc_invalid_argument_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_InvalidArgumentException
, "InvalidArgumentException" TSRMLS_CC
);
4960 zend_class_implements(php_pqexc_invalid_argument_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
4962 memset(&ce
, 0, sizeof(ce
));
4963 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "Runtime", php_pqexc_methods
);
4964 php_pqexc_runtime_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_RuntimeException
, "RuntimeException" TSRMLS_CC
);
4965 zend_class_implements(php_pqexc_runtime_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
4967 memset(&ce
, 0, sizeof(ce
));
4968 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "BadMethodCall", php_pqexc_methods
);
4969 php_pqexc_bad_methodcall_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_BadMethodCallException
, "BadMethodCallException" TSRMLS_CC
);
4970 zend_class_implements(php_pqexc_bad_methodcall_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
4972 memset(&ce
, 0, sizeof(ce
));
4973 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
4974 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
4975 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
4977 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
4978 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
4979 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
4980 php_pqconn_object_handlers
.clone_obj
= NULL
;
4981 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
4982 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
4984 zend_hash_init(&php_pqconn_object_prophandlers
, 13, NULL
, NULL
, 1);
4986 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
4987 ph
.read
= php_pqconn_object_read_status
;
4988 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
4990 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
4991 ph
.read
= php_pqconn_object_read_transaction_status
;
4992 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
4994 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4995 ph
.read
= NULL
; /* forward to std prophandler */
4996 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
4998 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
4999 ph
.read
= php_pqconn_object_read_error_message
;
5000 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5002 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5003 ph
.read
= php_pqconn_object_read_busy
;
5004 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
5006 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5007 ph
.read
= php_pqconn_object_read_encoding
;
5008 ph
.write
= php_pqconn_object_write_encoding
;
5009 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
5012 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5013 ph
.read
= php_pqconn_object_read_unbuffered
;
5014 ph
.write
= php_pqconn_object_write_unbuffered
;
5015 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
5018 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5019 ph
.read
= php_pqconn_object_read_db
;
5020 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
5022 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5023 ph
.read
= php_pqconn_object_read_user
;
5024 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
5026 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5027 ph
.read
= php_pqconn_object_read_pass
;
5028 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
5030 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5031 ph
.read
= php_pqconn_object_read_host
;
5032 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
5034 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5035 ph
.read
= php_pqconn_object_read_port
;
5036 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
5038 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5039 ph
.read
= php_pqconn_object_read_options
;
5040 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5042 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
5043 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
5044 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
5045 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
5046 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
5047 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
5048 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
5049 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
5051 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
5052 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
5053 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
5054 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
5055 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
5057 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
5058 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
5059 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
5060 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
5062 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
5063 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
5064 memset(&ce
, 0, sizeof(ce
));
5065 INIT_NS_CLASS_ENTRY(ce
, "pq", "Types", php_pqtypes_methods
);
5066 php_pqtypes_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5067 php_pqtypes_class_entry
->create_object
= php_pqtypes_create_object
;
5069 memcpy(&php_pqtypes_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5070 php_pqtypes_object_handlers
.read_property
= php_pq_object_read_prop
;
5071 php_pqtypes_object_handlers
.write_property
= php_pq_object_write_prop
;
5072 php_pqtypes_object_handlers
.clone_obj
= NULL
;
5073 php_pqtypes_object_handlers
.get_property_ptr_ptr
= NULL
;
5074 php_pqtypes_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5075 php_pqtypes_object_handlers
.has_dimension
= php_pqtypes_object_has_dimension
;
5076 php_pqtypes_object_handlers
.read_dimension
= php_pqtypes_object_read_dimension
;
5077 php_pqtypes_object_handlers
.unset_dimension
= NULL
;
5078 php_pqtypes_object_handlers
.write_dimension
= NULL
;
5080 zend_hash_init(&php_pqtypes_object_prophandlers
, 1, NULL
, NULL
, 1);
5082 zend_declare_property_null(php_pqtypes_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5083 ph
.read
= php_pqtypes_object_read_connection
;
5084 zend_hash_add(&php_pqtypes_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5086 memset(&ce
, 0, sizeof(ce
));
5087 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
5088 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5089 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
5090 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
5091 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
5092 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 2, zend_ce_traversable
, spl_ce_Countable
);
5094 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5095 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
5096 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
5097 php_pqres_object_handlers
.clone_obj
= NULL
;
5098 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
5099 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5100 php_pqres_object_handlers
.count_elements
= php_pqres_count_elements
;
5102 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
5104 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5105 ph
.read
= php_pqres_object_read_status
;
5106 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5108 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5109 ph
.read
= php_pqres_object_read_status_message
;
5110 zend_hash_add(&php_pqres_object_prophandlers
, "statusMessage", sizeof("statusMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5112 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5113 ph
.read
= php_pqres_object_read_error_message
;
5114 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5116 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5117 ph
.read
= php_pqres_object_read_num_rows
;
5118 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
5120 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5121 ph
.read
= php_pqres_object_read_num_cols
;
5122 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
5124 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5125 ph
.read
= php_pqres_object_read_affected_rows
;
5126 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
5128 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5129 ph
.read
= php_pqres_object_read_fetch_type
;
5130 ph
.write
= php_pqres_object_write_fetch_type
;
5131 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
5134 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
5135 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
5136 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
5137 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
5138 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
5139 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
5140 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
5141 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
5142 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
5143 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
5145 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
5146 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
5147 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
5149 memset(&ce
, 0, sizeof(ce
));
5150 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
5151 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5152 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
5154 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5155 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
5156 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
5157 php_pqstm_object_handlers
.clone_obj
= NULL
;
5158 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
5159 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5161 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
5163 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5164 ph
.read
= php_pqstm_object_read_name
;
5165 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
5167 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5168 ph
.read
= php_pqstm_object_read_connection
;
5169 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5171 memset(&ce
, 0, sizeof(ce
));
5172 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
5173 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5174 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
5176 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5177 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
5178 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
5179 php_pqtxn_object_handlers
.clone_obj
= NULL
;
5180 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
5181 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5183 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
5185 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5186 ph
.read
= php_pqtxn_object_read_connection
;
5187 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5189 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5190 ph
.read
= php_pqtxn_object_read_isolation
;
5191 ph
.write
= php_pqtxn_object_write_isolation
;
5192 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
5194 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("readonly"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5195 ph
.read
= php_pqtxn_object_read_readonly
;
5196 ph
.write
= php_pqtxn_object_write_readonly
;
5197 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
5199 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5200 ph
.read
= php_pqtxn_object_read_deferrable
;
5201 ph
.write
= php_pqtxn_object_write_deferrable
;
5202 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
5205 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
5206 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
5207 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
5209 memset(&ce
, 0, sizeof(ce
));
5210 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
5211 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5212 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
5214 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5215 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
5216 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
5217 php_pqcancel_object_handlers
.clone_obj
= NULL
;
5218 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
5219 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5221 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
5223 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5224 ph
.read
= php_pqcancel_object_read_connection
;
5225 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5227 memset(&ce
, 0, sizeof(ce
));
5228 INIT_NS_CLASS_ENTRY(ce
, "pq", "Event", php_pqevent_methods
);
5229 php_pqevent_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5230 php_pqevent_class_entry
->create_object
= php_pqevent_create_object
;
5232 memcpy(&php_pqevent_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5233 php_pqevent_object_handlers
.read_property
= php_pq_object_read_prop
;
5234 php_pqevent_object_handlers
.write_property
= php_pq_object_write_prop
;
5235 php_pqevent_object_handlers
.clone_obj
= NULL
;
5236 php_pqevent_object_handlers
.get_property_ptr_ptr
= NULL
;
5237 php_pqevent_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5239 zend_hash_init(&php_pqevent_object_prophandlers
, 2, NULL
, NULL
, 1);
5241 zend_declare_property_null(php_pqevent_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5242 ph
.read
= php_pqevent_object_read_connection
;
5243 zend_hash_add(&php_pqevent_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5245 zend_declare_property_null(php_pqevent_class_entry
, ZEND_STRL("type"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5246 ph
.read
= php_pqevent_object_read_type
;
5247 zend_hash_add(&php_pqevent_object_prophandlers
, "type", sizeof("type"), (void *) &ph
, sizeof(ph
), NULL
);
5249 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
5250 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESULT"), ZEND_STRL("result") TSRMLS_CC
);
5251 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESET"), ZEND_STRL("reset") TSRMLS_CC
);
5253 memset(&ce
, 0, sizeof(ce
));
5254 INIT_NS_CLASS_ENTRY(ce
, "pq", "LOB", php_pqlob_methods
);
5255 php_pqlob_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5256 php_pqlob_class_entry
->create_object
= php_pqlob_create_object
;
5258 memcpy(&php_pqlob_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5259 php_pqlob_object_handlers
.read_property
= php_pq_object_read_prop
;
5260 php_pqlob_object_handlers
.write_property
= php_pq_object_write_prop
;
5261 php_pqlob_object_handlers
.clone_obj
= NULL
;
5262 php_pqlob_object_handlers
.get_property_ptr_ptr
= NULL
;
5263 php_pqlob_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5265 zend_hash_init(&php_pqlob_object_prophandlers
, 2, NULL
, NULL
, 1);
5267 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5268 ph
.read
= php_pqlob_object_read_transaction
;
5269 zend_hash_add(&php_pqlob_object_prophandlers
, "transaction", sizeof("transaction"), (void *) &ph
, sizeof(ph
), NULL
);
5271 zend_declare_property_long(php_pqlob_class_entry
, ZEND_STRL("oid"), InvalidOid
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5272 ph
.read
= php_pqlob_object_read_oid
;
5273 zend_hash_add(&php_pqlob_object_prophandlers
, "oid", sizeof("oid"), (void *) &ph
, sizeof(ph
), NULL
);
5275 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC
);
5276 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("R"), INV_READ TSRMLS_CC
);
5277 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("W"), INV_WRITE TSRMLS_CC
);
5278 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("RW"), INV_READ
|INV_WRITE TSRMLS_CC
);
5280 memset(&ce
, 0, sizeof(ce
));
5281 INIT_NS_CLASS_ENTRY(ce
, "pq", "COPY", php_pqcopy_methods
);
5282 php_pqcopy_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5283 php_pqcopy_class_entry
->create_object
= php_pqcopy_create_object
;
5285 memcpy(&php_pqcopy_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5286 php_pqcopy_object_handlers
.read_property
= php_pq_object_read_prop
;
5287 php_pqcopy_object_handlers
.write_property
= php_pq_object_write_prop
;
5288 php_pqcopy_object_handlers
.clone_obj
= NULL
;
5289 php_pqcopy_object_handlers
.get_property_ptr_ptr
= NULL
;
5290 php_pqcopy_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5292 zend_hash_init(&php_pqcopy_object_prophandlers
, 4, NULL
, NULL
, 1);
5294 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5295 ph
.read
= php_pqcopy_object_read_connection
;
5296 zend_hash_add(&php_pqcopy_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5298 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5299 ph
.read
= php_pqcopy_object_read_expression
;
5300 zend_hash_add(&php_pqcopy_object_prophandlers
, "expression", sizeof("expression"), (void *) &ph
, sizeof(ph
), NULL
);
5302 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5303 ph
.read
= php_pqcopy_object_read_direction
;
5304 zend_hash_add(&php_pqcopy_object_prophandlers
, "direction", sizeof("direction"), (void *) &ph
, sizeof(ph
), NULL
);
5306 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5307 ph
.read
= php_pqcopy_object_read_options
;
5308 zend_hash_add(&php_pqcopy_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5310 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC
);
5311 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC
);
5313 php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops
, NULL
, NULL TSRMLS_CC
);
5316 REGISTER_INI_ENTRIES();
5322 /* {{{ PHP_MSHUTDOWN_FUNCTION
5324 static PHP_MSHUTDOWN_FUNCTION(pq
)
5326 /* uncomment this line if you have INI entries
5327 UNREGISTER_INI_ENTRIES();
5329 php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL
, 0 TSRMLS_CC
);
5334 /* {{{ PHP_MINFO_FUNCTION
5336 static PHP_MINFO_FUNCTION(pq
)
5338 #ifdef HAVE_PQLIBVERSION
5341 char libpq_version
[10] = "pre-9.1";
5343 php_info_print_table_start();
5344 php_info_print_table_header(2, "PQ Support", "enabled");
5345 php_info_print_table_row(2, "Extension Version", PHP_PQ_EXT_VERSION
);
5346 php_info_print_table_end();
5348 php_info_print_table_start();
5349 php_info_print_table_header(2, "Used Library", "Version");
5350 #ifdef HAVE_PQLIBVERSION
5351 libpq_v
= PQlibVersion();
5352 slprintf(libpq_version
, sizeof(libpq_version
), "%d.%d.%d", libpq_v
/10000%100, libpq_v
/100%100, libpq_v
%100);
5354 php_info_print_table_row(2, "libpq", libpq_version
);
5355 php_info_print_table_end();
5357 /* Remove comments if you have entries in php.ini
5358 DISPLAY_INI_ENTRIES();
5363 const zend_function_entry pq_functions
[] = {
5367 static zend_module_dep pq_module_deps
[] = {
5368 ZEND_MOD_REQUIRED("raphf")
5369 ZEND_MOD_REQUIRED("spl")
5373 /* {{{ pq_module_entry
5375 zend_module_entry pq_module_entry
= {
5376 STANDARD_MODULE_HEADER_EX
,
5383 NULL
,/*PHP_RINIT(pq),*/
5384 NULL
,/*PHP_RSHUTDOWN(pq),*/
5387 STANDARD_MODULE_PROPERTIES
5391 #ifdef COMPILE_DL_PQ
5401 * vim600: noet sw=4 ts=4 fdm=marker
5402 * vim<600: noet sw=4 ts=4