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 php_pqres_object_t *_o = PQresultInstanceData((_r), php_pqconn_event); \
54 php_pq_object_delref(_o TSRMLS_CC); \
61 ZEND_DECLARE_MODULE_GLOBALS(pq)
66 /* Remove comments and fill if you need to have entries in php.ini
68 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
69 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
74 /* {{{ php_pq_init_globals
76 /* Uncomment this function if you have INI entries
77 static void php_pq_init_globals(zend_pq_globals *pq_globals)
79 pq_globals->global_value = 0;
80 pq_globals->global_string = NULL;
85 static zend_class_entry
*php_pqconn_class_entry
;
86 static zend_class_entry
*php_pqtypes_class_entry
;
87 static zend_class_entry
*php_pqres_class_entry
;
88 static zend_class_entry
*php_pqstm_class_entry
;
89 static zend_class_entry
*php_pqtxn_class_entry
;
90 static zend_class_entry
*php_pqcancel_class_entry
;
91 static zend_class_entry
*php_pqlob_class_entry
;
92 static zend_class_entry
*php_pqcopy_class_entry
;
94 typedef enum php_pqexc_type
{
106 static zend_class_entry
*php_pqexc_interface_class_entry
;
107 static zend_class_entry
*php_pqexc_invalid_argument_class_entry
;
108 static zend_class_entry
*php_pqexc_runtime_class_entry
;
109 static zend_class_entry
*php_pqexc_bad_methodcall_class_entry
;
110 static zend_class_entry
*php_pqexc_domain_class_entry
;
112 static zend_class_entry
*exce(php_pqexc_type_t type
)
116 case EX_INVALID_ARGUMENT
:
117 return php_pqexc_invalid_argument_class_entry
;
119 case EX_CONNECTION_FAILED
:
122 return php_pqexc_runtime_class_entry
;
123 case EX_UNINITIALIZED
:
124 case EX_BAD_METHODCALL
:
125 return php_pqexc_bad_methodcall_class_entry
;
128 return php_pqexc_domain_class_entry
;
132 static zval
*throw_exce(php_pqexc_type_t type TSRMLS_DC
, const char *fmt
, ...)
139 vspprintf(&msg
, 0, fmt
, argv
);
142 zexc
= zend_throw_exception(exce(type
), msg
, type TSRMLS_CC
);
148 static zend_object_handlers php_pqconn_object_handlers
;
149 static zend_object_handlers php_pqtypes_object_handlers
;
150 static zend_object_handlers php_pqres_object_handlers
;
151 static zend_object_handlers php_pqstm_object_handlers
;
152 static zend_object_handlers php_pqtxn_object_handlers
;
153 static zend_object_handlers php_pqcancel_object_handlers
;
154 static zend_object_handlers php_pqlob_object_handlers
;
155 static zend_object_handlers php_pqcopy_object_handlers
;
157 typedef struct php_pq_callback
{
159 zend_fcall_info_cache fcc
;
163 typedef struct php_pq_object
{
165 zend_object_value zv
;
166 HashTable
*prophandler
;
170 #define PHP_PQCONN_ASYNC 0x01
171 #define PHP_PQCONN_PERSISTENT 0x02
173 typedef struct php_pqconn
{
175 int (*poller
)(PGconn
*);
176 php_resource_factory_t factory
;
178 HashTable eventhandlers
;
179 php_pq_callback_t onevent
;
180 unsigned unbuffered
:1;
183 typedef struct php_pqconn_object
{
185 zend_object_value zv
;
186 HashTable
*prophandler
;
187 php_pqconn_t
*intern
;
188 } php_pqconn_object_t
;
190 typedef struct php_pqtypes
{
192 php_pqconn_object_t
*conn
;
195 typedef struct php_pqtypes_object
{
197 zend_object_value zv
;
198 HashTable
*prophandler
;
199 php_pqtypes_t
*intern
;
200 } php_pqtypes_object_t
;
202 typedef struct php_pqconn_event_data
{
203 php_pqconn_object_t
*obj
;
207 } php_pqconn_event_data_t
;
209 typedef enum php_pqres_fetch
{
210 PHP_PQRES_FETCH_ARRAY
,
211 PHP_PQRES_FETCH_ASSOC
,
212 PHP_PQRES_FETCH_OBJECT
215 typedef struct php_pqres_iterator
{
216 zend_object_iterator zi
;
219 php_pqres_fetch_t fetch_type
;
220 } php_pqres_iterator_t
;
222 typedef struct php_pqres
{
224 php_pqres_iterator_t
*iter
;
228 typedef struct php_pqres_object
{
230 zend_object_value zv
;
231 HashTable
*prophandler
;
233 } php_pqres_object_t
;
235 typedef struct php_pqstm
{
236 php_pqconn_object_t
*conn
;
241 typedef struct php_pqstm_object
{
243 zend_object_value zv
;
244 HashTable
*prophandler
;
246 } php_pqstm_object_t
;
248 typedef enum php_pqtxn_isolation
{
249 PHP_PQTXN_READ_COMMITTED
,
250 PHP_PQTXN_REPEATABLE_READ
,
251 PHP_PQTXN_SERIALIZABLE
,
252 } php_pqtxn_isolation_t
;
254 typedef struct php_pqtxn
{
255 php_pqconn_object_t
*conn
;
256 php_pqtxn_isolation_t isolation
;
260 unsigned deferrable
:1;
263 typedef struct php_pqtxn_object
{
265 zend_object_value zv
;
266 HashTable
*prophandler
;
268 } php_pqtxn_object_t
;
270 typedef struct php_pqcancel
{
272 php_pqconn_object_t
*conn
;
275 typedef struct php_pqcancel_object
{
277 zend_object_value zv
;
278 HashTable
*prophandler
;
279 php_pqcancel_t
*intern
;
280 } php_pqcancel_object_t
;
282 typedef struct php_pqevent
{
283 php_pq_callback_t cb
;
288 typedef struct php_pqevent_object
{
290 zend_object_value zv
;
291 HashTable
*prophandler
;
292 php_pqevent_t
*intern
;
293 } php_pqevent_object_t
;
295 typedef struct php_pqlob
{
298 php_pqtxn_object_t
*txn
;
301 typedef struct php_pqlob_object
{
303 zend_object_value zv
;
304 HashTable
*prophandler
;
306 } php_pqlob_object_t
;
308 typedef enum php_pqcopy_direction
{
309 PHP_PQCOPY_FROM_STDIN
,
311 } php_pqcopy_direction_t
;
313 typedef enum php_pqcopy_status
{
317 } php_pqcopy_status_t
;
319 typedef struct php_pqcopy
{
320 php_pqcopy_direction_t direction
;
323 php_pqconn_object_t
*conn
;
326 typedef struct php_pqcopy_object
{
328 zend_object_value zv
;
329 HashTable
*prophandler
;
330 php_pqcopy_t
*intern
;
331 } php_pqcopy_object_t
;
333 static HashTable php_pqconn_object_prophandlers
;
334 static HashTable php_pqtypes_object_prophandlers
;
335 static HashTable php_pqres_object_prophandlers
;
336 static HashTable php_pqstm_object_prophandlers
;
337 static HashTable php_pqtxn_object_prophandlers
;
338 static HashTable php_pqcancel_object_prophandlers
;
339 static HashTable php_pqlob_object_prophandlers
;
340 static HashTable php_pqcopy_object_prophandlers
;
342 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
344 typedef struct php_pq_object_prophandler
{
345 php_pq_object_prophandler_func_t read
;
346 php_pq_object_prophandler_func_t write
;
347 } php_pq_object_prophandler_t
;
349 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
351 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
353 php_pqres_iterator_t
*iter
;
354 zval
*prop
, *zfetch_type
;
356 iter
= ecalloc(1, sizeof(*iter
));
357 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
358 iter
->zi
.data
= object
;
361 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
362 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
363 convert_to_long_ex(&zfetch_type
);
365 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
366 if (zfetch_type
!= prop
) {
367 zval_ptr_dtor(&zfetch_type
);
369 if (Z_REFCOUNT_P(prop
)) {
370 zval_ptr_dtor(&prop
);
376 return (zend_object_iterator
*) iter
;
379 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
381 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
383 if (iter
->current_val
) {
384 zval_ptr_dtor(&iter
->current_val
);
385 iter
->current_val
= NULL
;
387 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
391 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
393 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
394 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
396 switch (PQresultStatus(obj
->intern
->res
)) {
397 case PGRES_TUPLES_OK
:
398 case PGRES_SINGLE_TUPLE
:
399 if (PQntuples(obj
->intern
->res
) <= iter
->index
) {
410 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type
, zval
**data_ptr TSRMLS_DC
)
420 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
430 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
431 if (PQgetisnull(res
, row
, c
)) {
432 switch (fetch_type
) {
433 case PHP_PQRES_FETCH_OBJECT
:
434 add_property_null(data
, PQfname(res
, c
));
437 case PHP_PQRES_FETCH_ASSOC
:
438 add_assoc_null(data
, PQfname(res
, c
));
441 case PHP_PQRES_FETCH_ARRAY
:
442 add_index_null(data
, c
);
446 char *val
= PQgetvalue(res
, row
, c
);
447 int len
= PQgetlength(res
, row
, c
);
449 switch (fetch_type
) {
450 case PHP_PQRES_FETCH_OBJECT
:
451 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
454 case PHP_PQRES_FETCH_ASSOC
:
455 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
458 case PHP_PQRES_FETCH_ARRAY
:
459 add_index_stringl(data
, c
, val
, len
,1);
468 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
470 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
471 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
473 if (iter
->current_val
) {
474 zval_ptr_dtor(&iter
->current_val
);
476 iter
->current_val
= php_pqres_row_to_zval(obj
->intern
->res
, iter
->index
, iter
->fetch_type
, NULL TSRMLS_CC
);
477 *data_ptr
= &iter
->current_val
;
480 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
482 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
484 *key_num
= (ulong
) iter
->index
;
486 return HASH_KEY_IS_LONG
;
489 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
491 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
496 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
498 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
503 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
504 php_pqres_iterator_dtor
,
505 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
506 php_pqres_iterator_valid
,
507 /* fetch the item data for the current element */
508 php_pqres_iterator_current
,
509 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
510 php_pqres_iterator_key
,
511 /* step forwards to next element */
512 php_pqres_iterator_next
,
513 /* rewind to start of data (optional, may be NULL) */
514 php_pqres_iterator_rewind
,
515 /* invalidate current value/key (optional, may be NULL) */
519 static int php_pqres_count_elements(zval
*object
, long *count TSRMLS_DC
)
521 php_pqres_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
526 *count
= (long) PQntuples(obj
->intern
->res
);
531 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
535 switch (PQresultStatus(res
)) {
536 case PGRES_BAD_RESPONSE
:
537 case PGRES_NONFATAL_ERROR
:
538 case PGRES_FATAL_ERROR
:
539 zexc
= throw_exce(EX_SQL TSRMLS_CC
, "%s", PHP_PQresultErrorMessage(res
));
540 zend_update_property_string(php_pqexc_domain_class_entry
, zexc
, ZEND_STRL("sqlstate"), PQresultErrorField(res
, PG_DIAG_SQLSTATE
) TSRMLS_CC
);
547 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
548 if (cb
->fci
.size
> 0) {
549 zend_fcall_info_args_clear(&cb
->fci
, 1);
550 zval_ptr_dtor(&cb
->fci
.function_name
);
551 if (cb
->fci
.object_ptr
) {
552 zval_ptr_dtor(&cb
->fci
.object_ptr
);
558 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
560 Z_ADDREF_P(cb
->fci
.function_name
);
561 if (cb
->fci
.object_ptr
) {
562 Z_ADDREF_P(cb
->fci
.object_ptr
);
567 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC)
571 if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
572 zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
577 static ulong
php_pqconn_add_eventhandler(php_pqconn_object_t
*obj
, const char *type_str
, size_t type_len
, php_pq_callback_t
*cb TSRMLS_DC
)
582 if (SUCCESS
!= zend_hash_find(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
585 zend_hash_init(&evh
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
586 zend_hash_add(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(evh
), (void *) &evhs
);
589 php_pq_callback_addref(cb
);
590 h
= zend_hash_next_free_element(evhs
);
591 zend_hash_index_update(evhs
, h
, (void *) cb
, sizeof(*cb
), NULL
);
596 static void php_pq_object_to_zval(void *o
, zval
**zv TSRMLS_DC
)
598 php_pq_object_t
*obj
= o
;
604 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
606 (*zv
)->type
= IS_OBJECT
;
607 (*zv
)->value
.obj
= obj
->zv
;
610 static void php_pq_object_to_zval_no_addref(void *o
, zval
**zv TSRMLS_DC
)
612 php_pq_object_t
*obj
= o
;
620 (*zv
)->type
= IS_OBJECT
;
621 (*zv
)->value
.obj
= obj
->zv
;
624 static void php_pq_object_addref(void *o TSRMLS_DC
)
626 php_pq_object_t
*obj
= o
;
627 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
630 static void php_pq_object_delref(void *o TSRMLS_DC
)
632 php_pq_object_t
*obj
= o
;
633 zend_objects_store_del_ref_by_handle_ex(obj
->zv
.handle
, obj
->zv
.handlers TSRMLS_CC
);
636 static void php_pqconn_object_free(void *o TSRMLS_DC
)
638 php_pqconn_object_t
*obj
= o
;
640 fprintf(stderr
, "FREE conn(#%d) %p\n", obj
->zv
.handle
, obj
);
643 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
644 php_resource_factory_dtor(&obj
->intern
->factory
);
645 php_pq_callback_dtor(&obj
->intern
->onevent
);
646 zend_hash_destroy(&obj
->intern
->listeners
);
647 zend_hash_destroy(&obj
->intern
->eventhandlers
);
651 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
655 static void php_pqtypes_object_free(void *o TSRMLS_DC
)
657 php_pqtypes_object_t
*obj
= o
;
659 fprintf(stderr
, "FREE types(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
662 zend_hash_destroy(&obj
->intern
->types
);
663 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
667 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
671 static void php_pqres_object_free(void *o TSRMLS_DC
)
673 php_pqres_object_t
*obj
= o
;
675 fprintf(stderr
, "FREE res(#%d) %p\n", obj
->zv
.handle
, obj
);
678 if (obj
->intern
->res
) {
679 PQresultSetInstanceData(obj
->intern
->res
, php_pqconn_event
, NULL
);
680 PQclear(obj
->intern
->res
);
681 obj
->intern
->res
= NULL
;
684 if (obj
->intern
->iter
) {
685 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
686 obj
->intern
->iter
= NULL
;
689 zend_hash_destroy(&obj
->intern
->bound
);
694 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
698 static void php_pqstm_object_free(void *o TSRMLS_DC
)
700 php_pqstm_object_t
*obj
= o
;
702 fprintf(stderr
, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
705 char *quoted_name
= PQescapeIdentifier(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, strlen(obj
->intern
->name
));
707 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
713 smart_str_appends(&cmd
, "DEALLOCATE ");
714 smart_str_appends(&cmd
, quoted_name
);
716 PQfreemem(quoted_name
);
718 if ((res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
))) {
721 smart_str_free(&cmd
);
724 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
725 efree(obj
->intern
->name
);
726 zend_hash_destroy(&obj
->intern
->bound
);
730 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
734 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
736 php_pqtxn_object_t
*obj
= o
;
738 fprintf(stderr
, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
741 if (obj
->intern
->open
) {
742 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
748 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
752 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
756 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
758 php_pqcancel_object_t
*obj
= o
;
760 fprintf(stderr
, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
763 PQfreeCancel(obj
->intern
->cancel
);
764 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
768 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
772 static void php_pqlob_object_free(void *o TSRMLS_DC
)
774 php_pqlob_object_t
*obj
= o
;
776 fprintf(stderr
, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->txn
->zv
.handle
, obj
->intern
->txn
);
779 if (obj
->intern
->lofd
) {
780 lo_close(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
782 php_pq_object_delref(obj
->intern
->txn TSRMLS_CC
);
786 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
790 static void php_pqcopy_object_free(void *o TSRMLS_DC
)
792 php_pqcopy_object_t
*obj
= o
;
794 fprintf(stderr
, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
797 efree(obj
->intern
->expression
);
798 efree(obj
->intern
->options
);
799 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
803 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
807 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
809 php_pqconn_object_t
*o
;
811 o
= ecalloc(1, sizeof(*o
));
812 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
813 object_properties_init((zend_object
*) o
, ce
);
814 o
->prophandler
= &php_pqconn_object_prophandlers
;
824 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
825 o
->zv
.handlers
= &php_pqconn_object_handlers
;
830 static zend_object_value
php_pqtypes_create_object_ex(zend_class_entry
*ce
, php_pqtypes_t
*intern
, php_pqtypes_object_t
**ptr TSRMLS_DC
)
832 php_pqtypes_object_t
*o
;
834 o
= ecalloc(1, sizeof(*o
));
835 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
836 object_properties_init((zend_object
*) o
, ce
);
837 o
->prophandler
= &php_pqtypes_object_prophandlers
;
847 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtypes_object_free
, NULL TSRMLS_CC
);
848 o
->zv
.handlers
= &php_pqtypes_object_handlers
;
853 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, php_pqres_t
*intern
, php_pqres_object_t
**ptr TSRMLS_DC
)
855 php_pqres_object_t
*o
;
857 o
= ecalloc(1, sizeof(*o
));
858 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
859 object_properties_init((zend_object
*) o
, ce
);
860 o
->prophandler
= &php_pqres_object_prophandlers
;
870 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
871 o
->zv
.handlers
= &php_pqres_object_handlers
;
876 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*intern
, php_pqstm_object_t
**ptr TSRMLS_DC
)
878 php_pqstm_object_t
*o
;
880 o
= ecalloc(1, sizeof(*o
));
881 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
882 object_properties_init((zend_object
*) o
, ce
);
883 o
->prophandler
= &php_pqstm_object_prophandlers
;
893 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
894 o
->zv
.handlers
= &php_pqstm_object_handlers
;
899 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*intern
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
901 php_pqtxn_object_t
*o
;
903 o
= ecalloc(1, sizeof(*o
));
904 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
905 object_properties_init((zend_object
*) o
, ce
);
906 o
->prophandler
= &php_pqtxn_object_prophandlers
;
916 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
917 o
->zv
.handlers
= &php_pqtxn_object_handlers
;
922 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*intern
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
924 php_pqcancel_object_t
*o
;
926 o
= ecalloc(1, sizeof(*o
));
927 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
928 object_properties_init((zend_object
*) o
, ce
);
929 o
->prophandler
= &php_pqcancel_object_prophandlers
;
939 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
940 o
->zv
.handlers
= &php_pqcancel_object_handlers
;
945 static zend_object_value
php_pqlob_create_object_ex(zend_class_entry
*ce
, php_pqlob_t
*intern
, php_pqlob_object_t
**ptr TSRMLS_DC
)
947 php_pqlob_object_t
*o
;
949 o
= ecalloc(1, sizeof(*o
));
950 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
951 object_properties_init((zend_object
*) o
, ce
);
952 o
->prophandler
= &php_pqlob_object_prophandlers
;
962 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqlob_object_free
, NULL TSRMLS_CC
);
963 o
->zv
.handlers
= &php_pqlob_object_handlers
;
968 static zend_object_value
php_pqcopy_create_object_ex(zend_class_entry
*ce
, php_pqcopy_t
*intern
, php_pqcopy_object_t
**ptr TSRMLS_DC
)
970 php_pqcopy_object_t
*o
;
972 o
= ecalloc(1, sizeof(*o
));
973 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
974 object_properties_init((zend_object
*) o
, ce
);
975 o
->prophandler
= &php_pqcopy_object_prophandlers
;
985 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcopy_object_free
, NULL TSRMLS_CC
);
986 o
->zv
.handlers
= &php_pqcopy_object_handlers
;
991 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
993 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
996 static zend_object_value
php_pqtypes_create_object(zend_class_entry
*class_type TSRMLS_DC
)
998 return php_pqtypes_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1001 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1003 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1006 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1008 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1011 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1013 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1016 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1018 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1021 static zend_object_value
php_pqlob_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1023 return php_pqlob_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1026 static zend_object_value
php_pqcopy_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1028 return php_pqcopy_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1031 static int apply_pi_to_ht(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1033 zend_property_info
*pi
= p
;
1034 HashTable
*ht
= va_arg(argv
, HashTable
*);
1035 zval
*object
= va_arg(argv
, zval
*);
1036 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
1037 int addref
= va_arg(argv
, int);
1038 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
1041 Z_ADDREF_P(property
);
1043 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
1045 return ZEND_HASH_APPLY_KEEP
;
1048 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
1051 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1054 ALLOC_HASHTABLE(ht
);
1055 ZEND_INIT_SYMTABLE(ht
);
1057 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_ht
, 4, ht
, object
, obj
, 1);
1062 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1064 php_pqconn_object_t
*obj
= o
;
1066 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
1069 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1071 php_pqconn_object_t
*obj
= o
;
1073 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
1076 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1078 php_pqconn_object_t
*obj
= o
;
1079 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
1082 RETVAL_STRING(error
, 1);
1088 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
1090 php_pq_callback_t
*listener
= p
;
1091 PGnotify
*nfy
= arg
;
1092 zval
*zpid
, *zchannel
, *zmessage
;
1094 MAKE_STD_ZVAL(zpid
);
1095 ZVAL_LONG(zpid
, nfy
->be_pid
);
1096 MAKE_STD_ZVAL(zchannel
);
1097 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
1098 MAKE_STD_ZVAL(zmessage
);
1099 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
1101 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
1102 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
1104 zval_ptr_dtor(&zchannel
);
1105 zval_ptr_dtor(&zmessage
);
1106 zval_ptr_dtor(&zpid
);
1108 return ZEND_HASH_APPLY_KEEP
;
1111 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1113 HashTable
*listeners
= p
;
1114 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
1116 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
1117 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
1120 return ZEND_HASH_APPLY_KEEP
;
1123 static void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
1127 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
1128 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
1133 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1135 php_pqconn_object_t
*obj
= o
;
1137 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
1140 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1142 php_pqconn_object_t
*obj
= o
;
1144 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
1147 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1149 php_pqconn_object_t
*obj
= o
;
1152 if (Z_TYPE_P(value
) != IS_STRING
) {
1153 if (Z_REFCOUNT_P(value
) > 1) {
1156 ZVAL_ZVAL(tmp
, zenc
, 1, 0);
1157 convert_to_string(tmp
);
1160 convert_to_string_ex(&zenc
);
1164 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
1165 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
1168 if (zenc
!= value
) {
1169 zval_ptr_dtor(&zenc
);
1173 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1175 php_pqconn_object_t
*obj
= o
;
1177 RETVAL_BOOL(obj
->intern
->unbuffered
);
1180 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1182 php_pqconn_object_t
*obj
= o
;
1184 obj
->intern
->unbuffered
= zend_is_true(value
);
1187 static void php_pqconn_object_read_db(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1189 php_pqconn_object_t
*obj
= o
;
1190 char *db
= PQdb(obj
->intern
->conn
);
1193 RETVAL_STRING(db
, 1);
1195 RETVAL_EMPTY_STRING();
1199 static void php_pqconn_object_read_user(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1201 php_pqconn_object_t
*obj
= o
;
1202 char *user
= PQuser(obj
->intern
->conn
);
1205 RETVAL_STRING(user
, 1);
1207 RETVAL_EMPTY_STRING();
1211 static void php_pqconn_object_read_pass(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1213 php_pqconn_object_t
*obj
= o
;
1214 char *pass
= PQpass(obj
->intern
->conn
);
1217 RETVAL_STRING(pass
, 1);
1219 RETVAL_EMPTY_STRING();
1223 static void php_pqconn_object_read_host(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1225 php_pqconn_object_t
*obj
= o
;
1226 char *host
= PQhost(obj
->intern
->conn
);
1229 RETVAL_STRING(host
, 1);
1231 RETVAL_EMPTY_STRING();
1235 static void php_pqconn_object_read_port(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1237 php_pqconn_object_t
*obj
= o
;
1238 char *port
= PQport(obj
->intern
->conn
);
1241 RETVAL_STRING(port
, 1);
1243 RETVAL_EMPTY_STRING();
1247 static void php_pqconn_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1249 php_pqconn_object_t
*obj
= o
;
1250 char *options
= PQoptions(obj
->intern
->conn
);
1253 RETVAL_STRING(options
, 1);
1255 RETVAL_EMPTY_STRING();
1259 static void php_pqconn_object_read_event_handlers(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1261 php_pqconn_object_t
*obj
= o
;
1263 array_init(return_value
);
1264 zend_hash_copy(Z_ARRVAL_P(return_value
), &obj
->intern
->eventhandlers
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
1267 static void php_pqtypes_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1269 php_pqtypes_object_t
*obj
= o
;
1271 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1274 static int has_dimension(HashTable
*ht
, zval
*member
, char **key_str
, int *key_len
, ulong
*index TSRMLS_DC
)
1279 switch (Z_TYPE_P(member
)) {
1281 convert_to_string_ex(&tmp
);
1284 if (!is_numeric_string(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
), &lval
, NULL
, 0)) {
1285 int exists
= zend_hash_exists(ht
, Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
) + 1);
1288 *key_str
= estrndup(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
));
1290 *key_len
= Z_STRLEN_P(tmp
) + 1;
1293 if (member
!= tmp
) {
1294 zval_ptr_dtor(&tmp
);
1301 lval
= Z_LVAL_P(member
);
1305 if (member
!= tmp
) {
1306 zval_ptr_dtor(&tmp
);
1311 return zend_hash_index_exists(ht
, lval
);
1314 static int php_pqtypes_object_has_dimension(zval
*object
, zval
*member
, int check_empty TSRMLS_DC
)
1316 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1317 char *key_str
= NULL
;
1322 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1325 if (key_str
&& key_len
) {
1326 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1328 return Z_TYPE_PP(data
) != IS_NULL
;
1332 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1333 return Z_TYPE_PP(data
) != IS_NULL
;
1341 return has_dimension(&obj
->intern
->types
, member
, NULL
, NULL
, NULL TSRMLS_CC
);
1347 static zval
*php_pqtypes_object_read_dimension(zval
*object
, zval
*member
, int type TSRMLS_DC
)
1350 char *key_str
= NULL
;
1352 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1354 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1357 if (key_str
&& key_len
) {
1358 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1363 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1375 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1377 php_pqres_object_t
*obj
= o
;
1379 RETVAL_LONG(PQresultStatus(obj
->intern
->res
));
1382 static void php_pqres_object_read_status_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1384 php_pqres_object_t
*obj
= o
;
1386 RETVAL_STRING(PQresStatus(PQresultStatus(obj
->intern
->res
))+sizeof("PGRES"), 1);
1389 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1391 php_pqres_object_t
*obj
= o
;
1392 char *error
= PHP_PQresultErrorMessage(obj
->intern
->res
);
1395 RETVAL_STRING(error
, 1);
1401 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1403 php_pqres_object_t
*obj
= o
;
1405 RETVAL_LONG(PQntuples(obj
->intern
->res
));
1408 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1410 php_pqres_object_t
*obj
= o
;
1412 RETVAL_LONG(PQnfields(obj
->intern
->res
));
1415 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1417 php_pqres_object_t
*obj
= o
;
1419 RETVAL_LONG(atoi(PQcmdTuples(obj
->intern
->res
)));
1422 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1424 php_pqres_object_t
*obj
= o
;
1426 if (obj
->intern
->iter
) {
1427 RETVAL_LONG(obj
->intern
->iter
->fetch_type
);
1429 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
1433 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1435 php_pqres_object_t
*obj
= o
;
1436 zval
*zfetch_type
= value
;
1438 if (Z_TYPE_P(value
) != IS_LONG
) {
1439 if (Z_REFCOUNT_P(value
) > 1) {
1442 ZVAL_ZVAL(tmp
, zfetch_type
, 1, 0);
1443 convert_to_long(tmp
);
1446 convert_to_long_ex(&zfetch_type
);
1450 if (!obj
->intern
->iter
) {
1451 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
1452 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
1454 obj
->intern
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
1456 if (zfetch_type
!= value
) {
1457 zval_ptr_dtor(&zfetch_type
);
1461 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1463 php_pqstm_object_t
*obj
= o
;
1465 RETVAL_STRING(obj
->intern
->name
, 1);
1468 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1470 php_pqstm_object_t
*obj
= o
;
1472 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1475 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1477 php_pqtxn_object_t
*obj
= o
;
1479 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1482 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1484 php_pqtxn_object_t
*obj
= o
;
1486 RETVAL_LONG(obj
->intern
->isolation
);
1489 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1491 php_pqtxn_object_t
*obj
= o
;
1493 RETVAL_BOOL(obj
->intern
->readonly
);
1496 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1498 php_pqtxn_object_t
*obj
= o
;
1500 RETVAL_BOOL(obj
->intern
->deferrable
);
1503 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1505 php_pqtxn_object_t
*obj
= o
;
1506 php_pqtxn_isolation_t orig
= obj
->intern
->isolation
;
1507 zval
*zisolation
= value
;
1510 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
1511 if (Z_REFCOUNT_P(value
) > 1) {
1514 ZVAL_ZVAL(tmp
, zisolation
, 1, 0);
1515 convert_to_long(tmp
);
1518 convert_to_long_ex(&zisolation
);
1522 switch ((obj
->intern
->isolation
= Z_LVAL_P(zisolation
))) {
1523 case PHP_PQTXN_READ_COMMITTED
:
1524 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL READ COMMITED");
1526 case PHP_PQTXN_REPEATABLE_READ
:
1527 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
1529 case PHP_PQTXN_SERIALIZABLE
:
1530 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
1533 obj
->intern
->isolation
= orig
;
1538 if (zisolation
!= value
) {
1539 zval_ptr_dtor(&zisolation
);
1543 php_pqres_success(res TSRMLS_CC
);
1548 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1550 php_pqtxn_object_t
*obj
= o
;
1553 if ((obj
->intern
->readonly
= zend_is_true(value
))) {
1554 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ ONLY");
1556 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ WRITE");
1560 php_pqres_success(res TSRMLS_CC
);
1565 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1567 php_pqtxn_object_t
*obj
= o
;
1570 if ((obj
->intern
->deferrable
= zend_is_true(value
))) {
1571 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION DEFERRABLE");
1573 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION NOT DEFERRABLE");
1577 php_pqres_success(res TSRMLS_CC
);
1582 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1584 php_pqcancel_object_t
*obj
= o
;
1586 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1589 static void php_pqlob_object_read_transaction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1591 php_pqlob_object_t
*obj
= o
;
1593 php_pq_object_to_zval(obj
->intern
->txn
, &return_value TSRMLS_CC
);
1596 static void php_pqlob_object_read_oid(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1598 php_pqlob_object_t
*obj
= o
;
1600 RETVAL_LONG(obj
->intern
->loid
);
1603 static void php_pqcopy_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1605 php_pqcopy_object_t
*obj
= o
;
1607 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1610 static void php_pqcopy_object_read_direction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1612 php_pqcopy_object_t
*obj
= o
;
1614 RETVAL_LONG(obj
->intern
->direction
);
1617 static void php_pqcopy_object_read_expression(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1619 php_pqcopy_object_t
*obj
= o
;
1621 RETURN_STRING(obj
->intern
->expression
, 1);
1624 static void php_pqcopy_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1626 php_pqcopy_object_t
*obj
= o
;
1628 RETURN_STRING(obj
->intern
->options
, 1);
1631 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
1632 while (ce
->parent
) {
1638 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
1640 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1641 php_pq_object_prophandler_t
*handler
;
1645 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1646 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1647 if (type
== BP_VAR_R
) {
1648 ALLOC_ZVAL(return_value
);
1649 Z_SET_REFCOUNT_P(return_value
, 0);
1650 Z_UNSET_ISREF_P(return_value
);
1652 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1654 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1655 return_value
= NULL
;
1658 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1661 return return_value
;
1664 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1666 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1667 php_pq_object_prophandler_t
*handler
;
1669 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1670 if (handler
->write
) {
1671 handler
->write(object
, obj
, value TSRMLS_CC
);
1674 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1678 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1680 zval
*zsocket
, zmember
;
1686 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1689 INIT_PZVAL(&zmember
);
1690 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1691 MAKE_STD_ZVAL(zsocket
);
1693 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
1694 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
1695 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1696 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1697 php_stream_to_zval(stream
, zsocket
);
1703 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1704 zval_ptr_dtor(&zsocket
);
1710 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1711 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1713 # define TSRMLS_DF(d)
1714 # define TSRMLS_CF(d)
1717 static int apply_event(void *p
, void *a TSRMLS_DC
)
1719 php_pq_callback_t
*cb
= p
;
1721 zval
*retval
= NULL
;
1723 zend_fcall_info_args(&cb
->fci
, args TSRMLS_CC
);
1724 zend_fcall_info_call(&cb
->fci
, &cb
->fcc
, &retval
, NULL TSRMLS_CC
);
1726 zval_ptr_dtor(&retval
);
1729 return ZEND_HASH_APPLY_KEEP
;
1732 static void php_pqconn_event_connreset(PGEventConnReset
*event
)
1734 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1740 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("reset"), (void *) &evhs
)) {
1741 zval
*args
, *connection
= NULL
;
1743 MAKE_STD_ZVAL(args
);
1745 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1746 add_next_index_zval(args
, connection
);
1747 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1748 zval_ptr_dtor(&args
);
1753 static void php_pqres_init_instance_data(PGresult
*res
, php_pqres_object_t
**ptr TSRMLS_DC
)
1755 php_pqres_object_t
*obj
;
1756 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
1759 ZEND_INIT_SYMTABLE(&r
->bound
);
1760 php_pqres_create_object_ex(php_pqres_class_entry
, r
, &obj TSRMLS_CC
);
1762 PQresultSetInstanceData(res
, php_pqconn_event
, obj
);
1769 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
)
1771 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1774 php_pqres_object_t
*obj
;
1778 php_pqres_init_instance_data(event
->result
, &obj TSRMLS_CC
);
1780 /* event listener */
1781 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("result"), (void *) &evhs
)) {
1782 zval
*args
, *connection
= NULL
, *res
= NULL
;
1784 MAKE_STD_ZVAL(args
);
1786 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1787 add_next_index_zval(args
, connection
);
1788 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1789 add_next_index_zval(args
, res
);
1790 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1791 zval_ptr_dtor(&args
);
1794 /* async callback */
1795 if (data
->obj
->intern
->onevent
.fci
.size
> 0) {
1798 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1799 zend_fcall_info_argn(&data
->obj
->intern
->onevent
.fci TSRMLS_CC
, 1, &res
);
1800 zend_fcall_info_call(&data
->obj
->intern
->onevent
.fci
, &data
->obj
->intern
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1801 zval_ptr_dtor(&res
);
1807 static void php_pqconn_event_resultdestroy(PGEventResultDestroy
*event
)
1809 php_pqres_object_t
*obj
= PQresultInstanceData(event
->result
, php_pqconn_event
);
1812 obj
->intern
->res
= NULL
;
1816 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1819 case PGEVT_CONNRESET
:
1820 php_pqconn_event_connreset(e
);
1822 case PGEVT_RESULTCREATE
:
1823 php_pqconn_event_resultcreate(e
);
1825 case PGEVT_RESULTDESTROY
:
1826 php_pqconn_event_resultdestroy(e
);
1835 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1837 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1845 static void php_pqconn_notice_recv(void *p
, const PGresult
*res
)
1847 php_pqconn_event_data_t
*data
= p
;
1853 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("notice"), (void *) &evhs
)) {
1854 zval
*args
, *connection
= NULL
;
1856 MAKE_STD_ZVAL(args
);
1858 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1859 add_next_index_zval(args
, connection
);
1860 add_next_index_string(args
, PHP_PQresultErrorMessage(res
), 1);
1861 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1862 zval_ptr_dtor(&args
);
1867 typedef struct php_pqconn_resource_factory_data
{
1870 } php_pqconn_resource_factory_data_t
;
1872 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
1874 php_pqconn_resource_factory_data_t
*o
= init_arg
;
1875 PGconn
*conn
= NULL
;;
1877 if (o
->flags
& PHP_PQCONN_ASYNC
) {
1878 conn
= PQconnectStart(o
->dsn
);
1880 conn
= PQconnectdb(o
->dsn
);
1884 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
1890 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
1892 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
1894 /* we don't care for anything, except free'ing evdata */
1896 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
1897 memset(evdata
, 0, sizeof(*evdata
));
1904 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
1905 php_pqconn_resource_factory_ctor
,
1907 php_pqconn_resource_factory_dtor
1910 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1912 // FIXME: ping server
1915 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1917 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
1918 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1);
1920 if (quoted_channel
) {
1924 spprintf(&cmd
, 0, "UNLISTEN %s", quoted_channel
);
1925 if ((res
= PQexec(obj
->intern
->conn
, cmd
))) {
1930 PQfreemem(quoted_channel
);
1933 return ZEND_HASH_APPLY_REMOVE
;
1936 static void php_pqconn_notice_ignore(void *p
, const PGresult
*res
)
1940 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1942 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
1947 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
1949 /* ignore notices */
1950 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
1952 /* cancel async queries */
1953 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
1954 char err
[256] = {0};
1956 PQcancel(cancel
, err
, sizeof(err
));
1957 PQfreeCancel(cancel
);
1959 /* clean up async results */
1960 while ((res
= PQgetResult(*handle
))) {
1964 /* clean up transaction & session */
1965 switch (PQtransactionStatus(*handle
)) {
1967 res
= PQexec(*handle
, "RESET ALL");
1970 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
1979 /* clean up notify listeners */
1980 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
1982 /* release instance data */
1983 memset(evdata
, 0, sizeof(*evdata
));
1988 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
1989 ZEND_ARG_INFO(0, dsn
)
1990 ZEND_ARG_INFO(0, async
)
1991 ZEND_END_ARG_INFO();
1992 static PHP_METHOD(pqconn
, __construct
) {
1993 zend_error_handling zeh
;
1999 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2000 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
);
2001 zend_restore_error_handling(&zeh TSRMLS_CC
);
2003 if (SUCCESS
== rv
) {
2004 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2007 throw_exce(EX_BAD_METHODCALL TSRMLS_CC
, "pq\\Connection already initialized");
2009 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
2010 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
2012 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
2014 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
2015 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
2017 if (flags
& PHP_PQCONN_PERSISTENT
) {
2018 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
);
2019 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
2021 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
2024 if (flags
& PHP_PQCONN_ASYNC
) {
2025 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
2028 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
2030 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
2031 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
2033 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
2034 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2040 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
2041 ZEND_END_ARG_INFO();
2042 static PHP_METHOD(pqconn
, reset
) {
2043 zend_error_handling zeh
;
2046 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2047 rv
= zend_parse_parameters_none();
2048 zend_restore_error_handling(&zeh TSRMLS_CC
);
2050 if (SUCCESS
== rv
) {
2051 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2054 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2056 PQreset(obj
->intern
->conn
);
2058 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
2059 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2062 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2067 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
2068 ZEND_END_ARG_INFO();
2069 static PHP_METHOD(pqconn
, resetAsync
) {
2070 zend_error_handling zeh
;
2073 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2074 rv
= zend_parse_parameters_none();
2075 zend_restore_error_handling(&zeh TSRMLS_CC
);
2077 if (SUCCESS
== rv
) {
2078 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2081 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2083 if (!PQresetStart(obj
->intern
->conn
)) {
2084 throw_exce(EX_IO TSRMLS_CC
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2086 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
2089 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2094 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
)
2096 HashTable ht
, *existing_listeners
;
2098 php_pq_callback_addref(listener
);
2100 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
2101 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
2103 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
2104 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
2105 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
2109 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
2110 ZEND_ARG_INFO(0, channel
)
2111 ZEND_ARG_INFO(0, callable
)
2112 ZEND_END_ARG_INFO();
2113 static PHP_METHOD(pqconn
, listen
) {
2114 zend_error_handling zeh
;
2115 char *channel_str
= NULL
;
2116 int channel_len
= 0;
2117 php_pq_callback_t listener
;
2120 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2121 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2122 zend_restore_error_handling(&zeh TSRMLS_CC
);
2124 if (SUCCESS
== rv
) {
2125 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2128 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2130 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2132 if (!quoted_channel
) {
2133 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2136 smart_str cmd
= {0};
2138 smart_str_appends(&cmd
, "LISTEN ");
2139 smart_str_appends(&cmd
, quoted_channel
);
2142 res
= PQexec(obj
->intern
->conn
, cmd
.c
);
2144 smart_str_free(&cmd
);
2145 PQfreemem(quoted_channel
);
2148 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2150 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2151 obj
->intern
->poller
= PQconsumeInput
;
2152 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2157 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2163 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
2164 ZEND_ARG_INFO(0, channel
)
2165 ZEND_ARG_INFO(0, callable
)
2166 ZEND_END_ARG_INFO();
2167 static PHP_METHOD(pqconn
, listenAsync
) {
2168 zend_error_handling zeh
;
2169 char *channel_str
= NULL
;
2170 int channel_len
= 0;
2171 php_pq_callback_t listener
;
2174 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2175 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2176 zend_restore_error_handling(&zeh TSRMLS_CC
);
2178 if (SUCCESS
== rv
) {
2179 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2182 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2184 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2186 if (!quoted_channel
) {
2187 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2189 smart_str cmd
= {0};
2191 smart_str_appends(&cmd
, "LISTEN ");
2192 smart_str_appends(&cmd
, quoted_channel
);
2195 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
2196 throw_exce(EX_IO TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2198 obj
->intern
->poller
= PQconsumeInput
;
2199 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2202 smart_str_free(&cmd
);
2203 PQfreemem(quoted_channel
);
2204 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2210 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
2211 ZEND_ARG_INFO(0, channel
)
2212 ZEND_ARG_INFO(0, message
)
2213 ZEND_END_ARG_INFO();
2214 static PHP_METHOD(pqconn
, notify
) {
2215 zend_error_handling zeh
;
2216 char *channel_str
, *message_str
;
2217 int channel_len
, message_len
;
2220 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2221 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2222 zend_restore_error_handling(&zeh TSRMLS_CC
);
2224 if (SUCCESS
== rv
) {
2225 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2228 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2231 char *params
[2] = {channel_str
, message_str
};
2233 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
2236 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2238 php_pqres_success(res TSRMLS_CC
);
2242 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2247 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
2248 ZEND_ARG_INFO(0, channel
)
2249 ZEND_ARG_INFO(0, message
)
2250 ZEND_END_ARG_INFO();
2251 static PHP_METHOD(pqconn
, notifyAsync
) {
2252 zend_error_handling zeh
;
2253 char *channel_str
, *message_str
;
2254 int channel_len
, message_len
;
2257 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2258 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2259 zend_restore_error_handling(&zeh TSRMLS_CC
);
2261 if (SUCCESS
== rv
) {
2262 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2265 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2267 char *params
[2] = {channel_str
, message_str
};
2269 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
2270 throw_exce(EX_IO TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2272 obj
->intern
->poller
= PQconsumeInput
;
2275 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2280 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
2281 ZEND_END_ARG_INFO();
2282 static PHP_METHOD(pqconn
, poll
) {
2283 zend_error_handling zeh
;
2286 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2287 rv
= zend_parse_parameters_none();
2288 zend_restore_error_handling(&zeh TSRMLS_CC
);
2290 if (SUCCESS
== rv
) {
2291 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2294 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2295 } else if (!obj
->intern
->poller
) {
2296 throw_exce(EX_RUNTIME TSRMLS_CC
, "No asynchronous operation active");
2298 if (obj
->intern
->poller
== PQconsumeInput
) {
2299 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
2301 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
2303 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2308 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
2309 ZEND_ARG_INFO(0, query
)
2310 ZEND_END_ARG_INFO();
2311 static PHP_METHOD(pqconn
, exec
) {
2312 zend_error_handling zeh
;
2317 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2318 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
);
2319 zend_restore_error_handling(&zeh TSRMLS_CC
);
2321 if (SUCCESS
== rv
) {
2322 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2325 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2327 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
2330 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2331 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2332 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2337 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2342 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
2343 ZEND_END_ARG_INFO();
2344 static PHP_METHOD(pqconn
, getResult
) {
2345 zend_error_handling zeh
;
2348 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2349 rv
= zend_parse_parameters_none();
2350 zend_restore_error_handling(&zeh TSRMLS_CC
);
2352 if (SUCCESS
== rv
) {
2353 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2356 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connectio not initialized");
2358 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
2363 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2366 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2371 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
2372 ZEND_ARG_INFO(0, query
)
2373 ZEND_ARG_INFO(0, callable
)
2374 ZEND_END_ARG_INFO();
2375 static PHP_METHOD(pqconn
, execAsync
) {
2376 zend_error_handling zeh
;
2377 php_pq_callback_t resolver
= {{0}};
2382 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2383 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
2384 zend_restore_error_handling(&zeh TSRMLS_CC
);
2386 if (SUCCESS
== rv
) {
2387 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2390 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2391 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
2392 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2393 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2394 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2396 obj
->intern
->poller
= PQconsumeInput
;
2397 php_pq_callback_dtor(&obj
->intern
->onevent
);
2398 if (resolver
.fci
.size
> 0) {
2399 obj
->intern
->onevent
= resolver
;
2400 php_pq_callback_addref(&obj
->intern
->onevent
);
2402 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2407 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
2412 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
2413 convert_to_long_ex(ztype
);
2416 **types
= Z_LVAL_PP(ztype
);
2419 if (*ztype
!= *(zval
**)p
) {
2420 zval_ptr_dtor(ztype
);
2422 return ZEND_HASH_APPLY_KEEP
;
2425 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
2431 params
= (char ***) va_arg(argv
, char ***);
2432 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
2434 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
2438 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
2439 convert_to_string_ex(zparam
);
2442 **params
= Z_STRVAL_PP(zparam
);
2445 if (*zparam
!= *(zval
**)p
) {
2446 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
2449 return ZEND_HASH_APPLY_KEEP
;
2452 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
2454 int count
= zend_hash_num_elements(ht
);
2461 /* +1 for when less types than params are specified */
2462 *types
= tmp
= ecalloc(count
+ 1, sizeof(**types
));
2463 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
2469 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
2471 int count
= zend_hash_num_elements(ht
);
2478 *params
= tmp
= ecalloc(count
, sizeof(char *));
2479 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
2485 static Oid *php_pq_ntypes_to_array(zend_bool fill, int argc, ...)
2488 Oid *oids = ecalloc(argc + 1, sizeof(*oids));
2491 va_start(argv, argc);
2492 for (i = 0; i < argc; ++i) {
2494 oids[i] = va_arg(argv, Oid);
2504 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
2505 ZEND_ARG_INFO(0, query
)
2506 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2507 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2508 ZEND_END_ARG_INFO();
2509 static PHP_METHOD(pqconn
, execParams
) {
2510 zend_error_handling zeh
;
2514 zval
*ztypes
= NULL
;
2517 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2518 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
2519 zend_restore_error_handling(&zeh TSRMLS_CC
);
2521 if (SUCCESS
== rv
) {
2522 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2525 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2530 char **params
= NULL
;
2533 ZEND_INIT_SYMTABLE(&zdtor
);
2534 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2537 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2540 res
= PQexecParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
2542 zend_hash_destroy(&zdtor
);
2551 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2553 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2554 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2559 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2565 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
2566 ZEND_ARG_INFO(0, query
)
2567 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2568 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2569 ZEND_ARG_INFO(0, callable
)
2570 ZEND_END_ARG_INFO();
2571 static PHP_METHOD(pqconn
, execParamsAsync
) {
2572 zend_error_handling zeh
;
2573 php_pq_callback_t resolver
= {{0}};
2577 zval
*ztypes
= NULL
;
2580 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2581 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
2582 zend_restore_error_handling(&zeh TSRMLS_CC
);
2584 if (SUCCESS
== rv
) {
2585 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2588 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2592 char **params
= NULL
;
2595 ZEND_INIT_SYMTABLE(&zdtor
);
2596 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2599 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2602 if (!PQsendQueryParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
2603 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2604 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2605 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2607 obj
->intern
->poller
= PQconsumeInput
;
2608 php_pq_callback_dtor(&obj
->intern
->onevent
);
2609 if (resolver
.fci
.size
> 0) {
2610 obj
->intern
->onevent
= resolver
;
2611 php_pq_callback_addref(&obj
->intern
->onevent
);
2613 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2616 zend_hash_destroy(&zdtor
);
2625 zend_restore_error_handling(&zeh TSRMLS_CC
);
2628 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2636 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2640 count
= zend_hash_num_elements(typest
);
2641 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2644 res
= PQprepare(obj
->intern
->conn
, name
, query
, count
, types
);
2652 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2654 rv
= php_pqres_success(res TSRMLS_CC
);
2656 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2662 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
2663 ZEND_ARG_INFO(0, type
)
2664 ZEND_ARG_INFO(0, query
)
2665 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2666 ZEND_END_ARG_INFO();
2667 static PHP_METHOD(pqconn
, prepare
) {
2668 zend_error_handling zeh
;
2669 zval
*ztypes
= NULL
;
2670 char *name_str
, *query_str
;
2671 int name_len
, *query_len
;
2674 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2675 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2676 zend_restore_error_handling(&zeh TSRMLS_CC
);
2678 if (SUCCESS
== rv
) {
2679 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2682 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2683 } else if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2684 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2686 php_pq_object_addref(obj TSRMLS_CC
);
2688 stm
->name
= estrdup(name_str
);
2689 ZEND_INIT_SYMTABLE(&stm
->bound
);
2691 return_value
->type
= IS_OBJECT
;
2692 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2697 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2704 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2708 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2711 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, count
, types
)) {
2713 throw_exce(EX_IO TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2714 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2716 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2719 obj
->intern
->poller
= PQconsumeInput
;
2720 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2730 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
2731 ZEND_ARG_INFO(0, type
)
2732 ZEND_ARG_INFO(0, query
)
2733 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2734 ZEND_END_ARG_INFO();
2735 static PHP_METHOD(pqconn
, prepareAsync
) {
2736 zend_error_handling zeh
;
2737 zval
*ztypes
= NULL
;
2738 char *name_str
, *query_str
;
2739 int name_len
, *query_len
;
2742 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2743 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2744 zend_restore_error_handling(&zeh TSRMLS_CC
);
2746 if (SUCCESS
== rv
) {
2747 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2750 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2751 } else if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2752 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2754 php_pq_object_addref(obj TSRMLS_CC
);
2756 stm
->name
= estrdup(name_str
);
2757 ZEND_INIT_SYMTABLE(&stm
->bound
);
2759 return_value
->type
= IS_OBJECT
;
2760 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2765 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
2766 ZEND_ARG_INFO(0, string
)
2767 ZEND_END_ARG_INFO();
2768 static PHP_METHOD(pqconn
, quote
) {
2772 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2773 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2776 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2778 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
2781 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2784 RETVAL_STRING(quoted
, 1);
2791 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
2792 ZEND_ARG_INFO(0, type
)
2793 ZEND_END_ARG_INFO();
2794 static PHP_METHOD(pqconn
, quoteName
) {
2798 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2799 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2802 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2804 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
2807 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2810 RETVAL_STRING(quoted
, 1);
2817 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
2818 ZEND_ARG_INFO(0, bytea
)
2819 ZEND_END_ARG_INFO();
2820 static PHP_METHOD(pqconn
, escapeBytea
) {
2824 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2825 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2828 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2831 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
2834 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2837 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
2838 PQfreemem(escaped_str
);
2844 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
2845 ZEND_ARG_INFO(0, bytea
)
2846 ZEND_END_ARG_INFO();
2847 static PHP_METHOD(pqconn
, unescapeBytea
) {
2851 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2852 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2855 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2857 size_t unescaped_len
;
2858 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
2860 if (!unescaped_str
) {
2861 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2864 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
2865 PQfreemem(unescaped_str
);
2871 static const char *isolation_level(long *isolation
) {
2872 switch (*isolation
) {
2873 case PHP_PQTXN_SERIALIZABLE
:
2874 return "SERIALIZABLE";
2875 case PHP_PQTXN_REPEATABLE_READ
:
2876 return "REPEATABLE READ";
2878 *isolation
= PHP_PQTXN_READ_COMMITTED
;
2880 case PHP_PQTXN_READ_COMMITTED
:
2881 return "READ COMMITTED";
2885 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2887 STATUS rv
= FAILURE
;
2890 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2893 if (!conn_obj
->intern
) {
2894 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2897 smart_str cmd
= {0};
2898 const char *il
= isolation_level(&isolation
);
2900 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2901 smart_str_appends(&cmd
, il
);
2902 smart_str_appends(&cmd
, ", READ ");
2903 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2904 smart_str_appends(&cmd
, ",");
2905 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
2906 smart_str_appends(&cmd
, " DEFERRABLE");
2909 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
2912 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2914 rv
= php_pqres_success(res TSRMLS_CC
);
2916 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2919 smart_str_free(&cmd
);
2925 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
)
2927 STATUS rv
= FAILURE
;
2930 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2933 if (!conn_obj
->intern
) {
2934 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2936 smart_str cmd
= {0};
2937 const char *il
= isolation_level(&isolation
);
2939 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2940 smart_str_appends(&cmd
, il
);
2941 smart_str_appends(&cmd
, ", READ ");
2942 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2943 smart_str_appends(&cmd
, ",");
2944 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
2945 smart_str_appends(&cmd
, " DEFERRABLE");
2948 if (!PQsendQuery(conn_obj
->intern
->conn
, cmd
.c
)) {
2949 throw_exce(EX_IO TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2952 conn_obj
->intern
->poller
= PQconsumeInput
;
2953 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2956 smart_str_free(&cmd
);
2962 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
2963 ZEND_ARG_INFO(0, isolation
)
2964 ZEND_ARG_INFO(0, readonly
)
2965 ZEND_ARG_INFO(0, deferrable
)
2966 ZEND_END_ARG_INFO();
2967 static PHP_METHOD(pqconn
, startTransaction
) {
2968 zend_error_handling zeh
;
2969 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2970 zend_bool readonly
= 0, deferrable
= 0;
2973 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2974 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
2975 zend_restore_error_handling(&zeh TSRMLS_CC
);
2977 if (SUCCESS
== rv
) {
2978 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2980 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2982 if (SUCCESS
== rv
) {
2983 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2985 php_pq_object_addref(obj TSRMLS_CC
);
2988 txn
->isolation
= isolation
;
2989 txn
->readonly
= readonly
;
2990 txn
->deferrable
= deferrable
;
2992 return_value
->type
= IS_OBJECT
;
2993 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
2998 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
2999 ZEND_ARG_INFO(0, isolation
)
3000 ZEND_ARG_INFO(0, readonly
)
3001 ZEND_ARG_INFO(0, deferrable
)
3002 ZEND_END_ARG_INFO();
3003 static PHP_METHOD(pqconn
, startTransactionAsync
) {
3004 zend_error_handling zeh
;
3005 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3006 zend_bool readonly
= 0, deferrable
= 0;
3009 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3010 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
3011 zend_restore_error_handling(&zeh TSRMLS_CC
);
3012 if (SUCCESS
== rv
) {
3013 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3015 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3017 if (SUCCESS
== rv
) {
3018 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
3020 php_pq_object_addref(obj TSRMLS_CC
);
3022 txn
->isolation
= isolation
;
3023 txn
->readonly
= readonly
;
3024 txn
->deferrable
= deferrable
;
3026 return_value
->type
= IS_OBJECT
;
3027 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3032 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
3033 ZEND_ARG_INFO(0, stdio_stream
)
3034 ZEND_END_ARG_INFO();
3035 static PHP_METHOD(pqconn
, trace
) {
3036 zval
*zstream
= NULL
;
3038 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
3039 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3042 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3045 PQuntrace(obj
->intern
->conn
);
3049 php_stream
*stream
= NULL
;
3051 php_stream_from_zval(stream
, &zstream
);
3053 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
3056 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
3057 PQtrace(obj
->intern
->conn
, fp
);
3065 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on
, 0, 0, 2)
3066 ZEND_ARG_INFO(0, type
)
3067 ZEND_ARG_INFO(0, callable
)
3068 ZEND_END_ARG_INFO();
3069 static PHP_METHOD(pqconn
, on
) {
3070 zend_error_handling zeh
;
3073 php_pq_callback_t cb
;
3076 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3077 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
3078 zend_restore_error_handling(&zeh TSRMLS_CC
);
3080 if (SUCCESS
== rv
) {
3081 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3084 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3086 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3088 RETVAL_LONG(php_pqconn_add_eventhandler(obj
, type_str
, type_len
, &cb TSRMLS_CC
));
3093 static zend_function_entry php_pqconn_methods
[] = {
3094 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3095 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
3096 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
3097 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
3098 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
3099 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
3100 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
3101 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
3102 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
3103 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
3104 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
3105 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
3106 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
3107 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
3108 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
3109 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
3110 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
3111 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
3112 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
3113 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
3114 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
3115 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
3116 PHP_ME(pqconn
, on
, ai_pqconn_on
, ZEND_ACC_PUBLIC
)
3120 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct
, 0, 0, 1)
3121 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3122 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3123 ZEND_END_ARG_INFO();
3124 static PHP_METHOD(pqtypes
, __construct
) {
3125 zend_error_handling zeh
;
3126 zval
*zconn
, *znsp
= NULL
;
3129 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3130 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|a!", &zconn
, php_pqconn_class_entry
, &znsp
);
3131 zend_restore_error_handling(&zeh TSRMLS_CC
);
3133 if (SUCCESS
== rv
) {
3134 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3136 if (!conn_obj
->intern
) {
3137 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3139 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3140 zval
*retval
= NULL
;
3142 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3143 obj
->intern
->conn
= conn_obj
;
3144 php_pq_object_addref(conn_obj TSRMLS_CC
);
3145 zend_hash_init(&obj
->intern
->types
, 300, NULL
, ZVAL_PTR_DTOR
, 0);
3148 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
, znsp
);
3150 zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
);
3154 zval_ptr_dtor(&retval
);
3160 #define PHP_PQ_TYPES_QUERY \
3161 "select t.oid, t.* " \
3162 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
3163 "where typisdefined " \
3165 #define PHP_PQ_OID_TEXT 25
3167 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh
, 0, 0, 0)
3168 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3169 ZEND_END_ARG_INFO();
3170 static PHP_METHOD(pqtypes
, refresh
) {
3171 HashTable
*nsp
= NULL
;
3172 zend_error_handling zeh
;
3175 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3176 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|H/!", &nsp
);
3177 zend_restore_error_handling(&zeh TSRMLS_CC
);
3179 if (SUCCESS
== rv
) {
3180 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3183 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Types not initialized");
3187 if (!nsp
|| !zend_hash_num_elements(nsp
)) {
3188 res
= PQexec(obj
->intern
->conn
->intern
->conn
, PHP_PQ_TYPES_QUERY
" and nspname in ('public', 'pg_catalog')");
3192 char **params
= NULL
;
3194 smart_str str
= {0};
3196 smart_str_appends(&str
, PHP_PQ_TYPES_QUERY
" and nspname in(");
3197 zend_hash_init(&zdtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
3198 count
= php_pq_params_to_array(nsp
, ¶ms
, &zdtor TSRMLS_CC
);
3199 oids
= ecalloc(count
+ 1, sizeof(*oids
));
3200 for (i
= 0; i
< count
; ++i
) {
3201 oids
[i
] = PHP_PQ_OID_TEXT
;
3203 smart_str_appendc(&str
, ',');
3205 smart_str_appendc(&str
, '$');
3206 smart_str_append_unsigned(&str
, i
+1);
3208 smart_str_appendc(&str
, ')');
3211 res
= PQexecParams(obj
->intern
->conn
->intern
->conn
, str
.c
, count
, oids
, (const char *const*) params
, NULL
, NULL
, 0);
3213 smart_str_free(&str
);
3216 zend_hash_destroy(&zdtor
);
3220 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3222 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3225 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
3226 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT
, NULL TSRMLS_CC
);
3227 long oid
= atol(PQgetvalue(res
, r
, 0 ));
3228 char *name
= PQgetvalue(res
, r
, 1);
3232 zend_hash_index_update(&obj
->intern
->types
, oid
, (void *) &row
, sizeof(zval
*), NULL
);
3233 zend_hash_add(&obj
->intern
->types
, name
, strlen(name
) + 1, (void *) &row
, sizeof(zval
*), NULL
);
3238 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3244 static zend_function_entry php_pqtypes_methods
[] = {
3245 PHP_ME(pqtypes
, __construct
, ai_pqtypes_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3246 PHP_ME(pqtypes
, refresh
, ai_pqtypes_refresh
, ZEND_ACC_PUBLIC
)
3250 static STATUS
php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type
, zval
***row TSRMLS_DC
)
3253 php_pqres_fetch_t orig_fetch
;
3256 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3259 if (!obj
->intern
->iter
) {
3260 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
3261 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3263 orig_fetch
= obj
->intern
->iter
->fetch_type
;
3264 obj
->intern
->iter
->fetch_type
= fetch_type
;
3265 if (SUCCESS
== (rv
= obj
->intern
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
))) {
3266 obj
->intern
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->intern
->iter
, row TSRMLS_CC
);
3267 obj
->intern
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3269 obj
->intern
->iter
->fetch_type
= orig_fetch
;
3274 typedef struct php_pqres_col
{
3279 static STATUS
column_nn(php_pqres_object_t
*obj
, zval
*zcol
, php_pqres_col_t
*col TSRMLS_DC
)
3284 switch (Z_TYPE_P(zcol
)) {
3286 convert_to_string(zcol
);
3290 if (!is_numeric_string(Z_STRVAL_P(zcol
), Z_STRLEN_P(zcol
), &index
, NULL
, 0)) {
3291 name
= Z_STRVAL_P(zcol
);
3296 index
= Z_LVAL_P(zcol
);
3302 col
->num
= PQfnumber(obj
->intern
->res
, name
);
3304 col
->name
= PQfname(obj
->intern
->res
, index
);
3309 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column at index %ld", index
);
3312 if (col
->num
== -1) {
3313 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column with name '%s'", name
);
3319 static int compare_index(const void *lptr
, const void *rptr TSRMLS_DC
)
3321 const Bucket
*l
= *(const Bucket
**) lptr
;
3322 const Bucket
*r
= *(const Bucket
**) rptr
;
3333 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind
, 0, 0, 2)
3334 ZEND_ARG_INFO(0, col
)
3335 ZEND_ARG_INFO(1, ref
)
3336 ZEND_END_ARG_INFO();
3337 static PHP_METHOD(pqres
, bind
) {
3340 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z/z", &zcol
, &zref
)) {
3341 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3344 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3346 php_pqres_col_t col
;
3348 if (SUCCESS
!= column_nn(obj
, zcol
, &col TSRMLS_CC
)) {
3353 if (SUCCESS
!= zend_hash_index_update(&obj
->intern
->bound
, col
.num
, (void *) &zref
, sizeof(zval
*), NULL
)) {
3354 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to bind column %s@%d", col
.name
, col
.num
);
3357 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3365 static int apply_bound(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3367 zval
**zvalue
, **zbound
= p
;
3368 zval
**zrow
= va_arg(argv
, zval
**);
3369 STATUS
*rv
= va_arg(argv
, STATUS
*);
3371 if (SUCCESS
!= zend_hash_index_find(Z_ARRVAL_PP(zrow
), key
->h
, (void *) &zvalue
)) {
3372 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column ad index %lu", key
->h
);
3374 return ZEND_HASH_APPLY_STOP
;
3377 ZVAL_COPY_VALUE(*zbound
, *zvalue
);
3379 zval_ptr_dtor(zvalue
);
3380 Z_ADDREF_P(*zbound
);
3383 return ZEND_HASH_APPLY_KEEP
;
3387 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound
, 0, 0, 0)
3388 ZEND_END_ARG_INFO();
3389 static PHP_METHOD(pqres
, fetchBound
) {
3390 zend_error_handling zeh
;
3393 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3394 rv
= zend_parse_parameters_none();
3395 zend_restore_error_handling(&zeh TSRMLS_CC
);
3397 if (SUCCESS
== rv
) {
3398 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3401 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3405 if (SUCCESS
== php_pqres_iteration(getThis(), obj
, PHP_PQRES_FETCH_ARRAY
, &row TSRMLS_CC
) && row
) {
3406 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3407 zend_hash_apply_with_arguments(&obj
->intern
->bound TSRMLS_CC
, apply_bound
, 2, row
, &rv
);
3408 zend_restore_error_handling(&zeh TSRMLS_CC
);
3410 if (SUCCESS
!= rv
) {
3413 RETVAL_ZVAL(*row
, 1, 0);
3420 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
3421 ZEND_ARG_INFO(0, fetch_type
)
3422 ZEND_END_ARG_INFO();
3423 static PHP_METHOD(pqres
, fetchRow
) {
3424 zend_error_handling zeh
;
3425 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3426 long fetch_type
= -1;
3429 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3430 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3431 zend_restore_error_handling(&zeh TSRMLS_CC
);
3433 if (SUCCESS
== rv
) {
3435 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3439 if (fetch_type
== -1) {
3440 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3443 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3444 php_pqres_iteration(getThis(), obj
, fetch_type
, &row TSRMLS_CC
);
3445 zend_restore_error_handling(&zeh TSRMLS_CC
);
3448 RETVAL_ZVAL(*row
, 1, 0);
3454 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
3457 HashTable
*ht
= HASH_OF(row
);
3458 int count
= zend_hash_num_elements(ht
);
3461 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
3463 zend_hash_internal_pointer_reset(ht
);
3465 zend_hash_move_forward(ht
);
3467 zend_hash_get_current_data(ht
, (void *) &data
);
3472 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
3473 ZEND_ARG_INFO(0, col_num
)
3474 ZEND_END_ARG_INFO();
3475 static PHP_METHOD(pqres
, fetchCol
) {
3476 zend_error_handling zeh
;
3480 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3481 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
);
3482 zend_restore_error_handling(&zeh TSRMLS_CC
);
3484 if (SUCCESS
== rv
) {
3485 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3488 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3492 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3493 php_pqres_iteration(getThis(), obj
, obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: 0, &row TSRMLS_CC
);
3495 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
3498 RETVAL_ZVAL(*col
, 1, 0);
3501 zend_restore_error_handling(&zeh TSRMLS_CC
);
3506 static int apply_to_col(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3509 php_pqres_object_t
*obj
= va_arg(argv
, php_pqres_object_t
*);
3510 php_pqres_col_t
*col
, **cols
= va_arg(argv
, php_pqres_col_t
**);
3511 STATUS
*rv
= va_arg(argv
, STATUS
*);
3515 if (SUCCESS
!= column_nn(obj
, *c
, col TSRMLS_CC
)) {
3517 return ZEND_HASH_APPLY_STOP
;
3521 return ZEND_HASH_APPLY_KEEP
;
3525 static php_pqres_col_t
*php_pqres_convert_to_cols(php_pqres_object_t
*obj
, HashTable
*ht TSRMLS_DC
)
3527 php_pqres_col_t
*tmp
, *cols
= ecalloc(zend_hash_num_elements(ht
), sizeof(*cols
));
3528 STATUS rv
= SUCCESS
;
3531 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_col
, 2, obj
, &tmp
, &rv
);
3533 if (SUCCESS
== rv
) {
3541 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map
, 0, 0, 0)
3542 ZEND_ARG_INFO(0, keys
)
3543 ZEND_ARG_INFO(0, vals
)
3544 ZEND_ARG_INFO(0, fetch_type
)
3545 ZEND_END_ARG_INFO();
3546 static PHP_METHOD(pqres
, map
) {
3547 zend_error_handling zeh
;
3548 zval
*zkeys
= 0, *zvals
= 0;
3549 long fetch_type
= -1;
3552 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3553 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z/!z/!l", &zkeys
, &zvals
, &fetch_type
);
3554 zend_restore_error_handling(&zeh TSRMLS_CC
);
3556 if (SUCCESS
== rv
) {
3557 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3560 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3563 php_pqres_col_t def
= {PQfname(obj
->intern
->res
, 0), 0}, *keys
= NULL
, *vals
= NULL
;
3566 convert_to_array(zkeys
);
3568 if ((ks
= zend_hash_num_elements(Z_ARRVAL_P(zkeys
)))) {
3569 keys
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zkeys
) TSRMLS_CC
);
3579 convert_to_array(zvals
);
3581 if ((vs
= zend_hash_num_elements(Z_ARRVAL_P(zvals
)))) {
3582 vals
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zvals
) TSRMLS_CC
);
3586 if (fetch_type
== -1) {
3587 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3594 switch (fetch_type
) {
3595 case PHP_PQRES_FETCH_ARRAY
:
3596 case PHP_PQRES_FETCH_ASSOC
:
3597 array_init(return_value
);
3599 case PHP_PQRES_FETCH_OBJECT
:
3600 object_init(return_value
);
3603 for (r
= 0, rows
= PQntuples(obj
->intern
->res
); r
< rows
; ++r
) {
3606 cur
= &return_value
;
3607 for (k
= 0; k
< ks
; ++k
) {
3608 char *key
= PQgetvalue(obj
->intern
->res
, r
, keys
[k
].num
);
3609 int len
= PQgetlength(obj
->intern
->res
, r
, keys
[k
].num
);
3611 if (SUCCESS
!= zend_symtable_find(HASH_OF(*cur
), key
, len
+ 1, (void *) &cur
)) {
3615 switch (fetch_type
) {
3616 case PHP_PQRES_FETCH_ARRAY
:
3617 case PHP_PQRES_FETCH_ASSOC
:
3620 case PHP_PQRES_FETCH_OBJECT
:
3624 if (SUCCESS
!= zend_symtable_update(HASH_OF(*cur
), key
, len
+ 1, (void *) &tmp
, sizeof(zval
*), (void *) &cur
)) {
3625 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create map");
3631 for (v
= 0; v
< vs
; ++v
) {
3632 char *val
= PQgetvalue(obj
->intern
->res
, r
, vals
[v
].num
);
3633 int len
= PQgetlength(obj
->intern
->res
, r
, vals
[v
].num
);
3635 switch (fetch_type
) {
3636 case PHP_PQRES_FETCH_ARRAY
:
3637 add_index_stringl(*cur
, vals
[v
].num
, val
, len
, 1);
3639 case PHP_PQRES_FETCH_ASSOC
:
3640 add_assoc_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3642 case PHP_PQRES_FETCH_OBJECT
:
3643 add_property_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3648 php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, cur TSRMLS_CC
);
3654 if (keys
&& keys
!= &def
) {
3664 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all
, 0, 0, 0)
3665 ZEND_ARG_INFO(0, fetch_type
)
3666 ZEND_END_ARG_INFO();
3667 static PHP_METHOD(pqres
, fetchAll
) {
3668 zend_error_handling zeh
;
3669 long fetch_type
= -1;
3672 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3673 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3674 zend_restore_error_handling(&zeh TSRMLS_CC
);
3676 if (SUCCESS
== rv
) {
3677 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3679 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3681 int r
, rows
= PQntuples(obj
->intern
->res
);
3683 if (fetch_type
== -1) {
3684 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3687 array_init(return_value
);
3688 for (r
= 0; r
< rows
; ++r
) {
3689 add_next_index_zval(return_value
, php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, NULL TSRMLS_CC
));
3695 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count
, 0, 0, 0)
3696 ZEND_END_ARG_INFO();
3697 static PHP_METHOD(pqres
, count
) {
3698 if (SUCCESS
== zend_parse_parameters_none()) {
3701 if (SUCCESS
!= php_pqres_count_elements(getThis(), &count TSRMLS_CC
)) {
3702 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3709 static zend_function_entry php_pqres_methods
[] = {
3710 PHP_ME(pqres
, bind
, ai_pqres_bind
, ZEND_ACC_PUBLIC
)
3711 PHP_ME(pqres
, fetchBound
, ai_pqres_fetch_bound
, ZEND_ACC_PUBLIC
)
3712 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
3713 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
3714 PHP_ME(pqres
, fetchAll
, ai_pqres_fetch_all
, ZEND_ACC_PUBLIC
)
3715 PHP_ME(pqres
, count
, ai_pqres_count
, ZEND_ACC_PUBLIC
)
3716 PHP_ME(pqres
, map
, ai_pqres_map
, ZEND_ACC_PUBLIC
)
3720 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
3721 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
3722 ZEND_ARG_INFO(0, type
)
3723 ZEND_ARG_INFO(0, query
)
3724 ZEND_ARG_ARRAY_INFO(0, types
, 1)
3725 ZEND_ARG_INFO(0, async
)
3726 ZEND_END_ARG_INFO();
3727 static PHP_METHOD(pqstm
, __construct
) {
3728 zend_error_handling zeh
;
3729 zval
*zconn
, *ztypes
= NULL
;
3730 char *name_str
, *query_str
;
3731 int name_len
, *query_len
;
3732 zend_bool async
= 0;
3735 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3736 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
);
3737 zend_restore_error_handling(&zeh TSRMLS_CC
);
3739 if (SUCCESS
== rv
) {
3740 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3741 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3743 if (!conn_obj
->intern
) {
3744 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3747 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3749 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3752 if (SUCCESS
== rv
) {
3753 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
3755 php_pq_object_addref(conn_obj TSRMLS_CC
);
3756 stm
->conn
= conn_obj
;
3757 stm
->name
= estrdup(name_str
);
3758 ZEND_INIT_SYMTABLE(&stm
->bound
);
3764 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind
, 0, 0, 2)
3765 ZEND_ARG_INFO(0, param_no
)
3766 ZEND_ARG_INFO(1, param_ref
)
3767 ZEND_END_ARG_INFO();
3768 static PHP_METHOD(pqstm
, bind
) {
3772 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "lz", ¶m_no
, ¶m_ref
)) {
3773 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3776 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3778 Z_ADDREF_P(param_ref
);
3779 zend_hash_index_update(&obj
->intern
->bound
, param_no
, (void *) ¶m_ref
, sizeof(zval
*), NULL
);
3780 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3785 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
3786 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3787 ZEND_END_ARG_INFO();
3788 static PHP_METHOD(pqstm
, exec
) {
3789 zend_error_handling zeh
;
3790 zval
*zparams
= NULL
;
3793 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3794 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
);
3795 zend_restore_error_handling(&zeh TSRMLS_CC
);
3797 if (SUCCESS
== rv
) {
3798 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3801 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3804 char **params
= NULL
;
3808 ZEND_INIT_SYMTABLE(&zdtor
);
3811 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3813 count
= php_pq_params_to_array(&obj
->intern
->bound
, ¶ms
, &zdtor TSRMLS_CC
);
3816 res
= PQexecPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
3821 zend_hash_destroy(&zdtor
);
3824 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3825 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3826 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
3827 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3833 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
3834 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3835 ZEND_ARG_INFO(0, callable
)
3836 ZEND_END_ARG_INFO();
3837 static PHP_METHOD(pqstm
, execAsync
) {
3838 zend_error_handling zeh
;
3839 zval
*zparams
= NULL
;
3840 php_pq_callback_t resolver
= {{0}};
3843 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3844 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
);
3845 zend_restore_error_handling(&zeh TSRMLS_CC
);
3847 if (SUCCESS
== rv
) {
3848 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3851 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3854 char **params
= NULL
;
3858 ZEND_INIT_SYMTABLE(&zdtor
);
3859 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3862 if (!PQsendQueryPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
3863 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3864 } else if (obj
->intern
->conn
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
->intern
->conn
)) {
3865 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3867 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
3868 if (resolver
.fci
.size
> 0) {
3869 obj
->intern
->conn
->intern
->onevent
= resolver
;
3870 php_pq_callback_addref(&obj
->intern
->conn
->intern
->onevent
);
3872 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3879 zend_hash_destroy(&zdtor
);
3882 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3887 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
3888 ZEND_END_ARG_INFO();
3889 static PHP_METHOD(pqstm
, desc
) {
3890 zend_error_handling zeh
;
3893 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3894 rv
= zend_parse_parameters_none();
3895 zend_restore_error_handling(&zeh TSRMLS_CC
);
3897 if (SUCCESS
== rv
) {
3898 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3901 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3903 PGresult
*res
= PQdescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
);
3906 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3908 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3911 array_init(return_value
);
3912 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
3913 add_next_index_long(return_value
, PQparamtype(res
, p
));
3917 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3923 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async
, 0, 0, 0)
3924 ZEND_END_ARG_INFO();
3925 static PHP_METHOD(pqstm
, descAsync
) {
3926 zend_error_handling zeh
;
3929 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3930 rv
= zend_parse_parameters_none();
3931 zend_restore_error_handling(&zeh TSRMLS_CC
);
3933 if (SUCCESS
== rv
) {
3934 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3937 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3938 } else if (!PQsendDescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
)) {
3939 throw_exce(EX_IO TSRMLS_CC
, "Failed to describe statement: %s", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3941 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3942 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3947 static zend_function_entry php_pqstm_methods
[] = {
3948 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3949 PHP_ME(pqstm
, bind
, ai_pqstm_bind
, ZEND_ACC_PUBLIC
)
3950 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
3951 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
3952 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
3953 PHP_ME(pqstm
, descAsync
, ai_pqstm_desc_async
, ZEND_ACC_PUBLIC
)
3957 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
3958 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3959 ZEND_ARG_INFO(0, async
)
3960 ZEND_ARG_INFO(0, isolation
)
3961 ZEND_ARG_INFO(0, readonly
)
3962 ZEND_ARG_INFO(0, deferrable
)
3963 ZEND_END_ARG_INFO();
3964 static PHP_METHOD(pqtxn
, __construct
) {
3965 zend_error_handling zeh
;
3967 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3968 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
3971 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3972 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
);
3973 zend_restore_error_handling(&zeh TSRMLS_CC
);
3975 if (SUCCESS
== rv
) {
3976 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3978 if (!conn_obj
->intern
) {
3979 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3982 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3984 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3987 if (SUCCESS
== rv
) {
3988 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3990 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3992 php_pq_object_addref(conn_obj TSRMLS_CC
);
3993 obj
->intern
->conn
= conn_obj
;
3994 obj
->intern
->open
= 1;
3995 obj
->intern
->isolation
= isolation
;
3996 obj
->intern
->readonly
= readonly
;
3997 obj
->intern
->deferrable
= deferrable
;
4003 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint
, 0, 0, 0)
4004 ZEND_END_ARG_INFO();
4005 static PHP_METHOD(pqtxn
, savepoint
) {
4006 zend_error_handling zeh
;
4009 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4010 rv
= zend_parse_parameters_none();
4011 zend_restore_error_handling(&zeh TSRMLS_CC
);
4013 if (SUCCESS
== rv
) {
4014 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4017 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4018 } else if (!obj
->intern
->open
) {
4019 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4022 smart_str cmd
= {0};
4024 smart_str_appends(&cmd
, "SAVEPOINT \"");
4025 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4026 smart_str_appends(&cmd
, "\"");
4029 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4032 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4034 php_pqres_success(res TSRMLS_CC
);
4038 smart_str_free(&cmd
);
4043 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async
, 0, 0, 0)
4044 ZEND_END_ARG_INFO();
4045 static PHP_METHOD(pqtxn
, savepointAsync
) {
4046 zend_error_handling zeh
;
4049 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4050 rv
= zend_parse_parameters_none();
4051 zend_restore_error_handling(&zeh TSRMLS_CC
);
4053 if (SUCCESS
== rv
) {
4054 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4057 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4058 } else if (!obj
->intern
->open
) {
4059 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4061 smart_str cmd
= {0};
4063 smart_str_appends(&cmd
, "SAVEPOINT \"");
4064 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4065 smart_str_appends(&cmd
, "\"");
4068 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4069 throw_exce(EX_IO TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4072 smart_str_free(&cmd
);
4077 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
4078 ZEND_END_ARG_INFO();
4079 static PHP_METHOD(pqtxn
, commit
) {
4080 zend_error_handling zeh
;
4083 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4084 rv
= zend_parse_parameters_none();
4085 zend_restore_error_handling(&zeh TSRMLS_CC
);
4087 if (SUCCESS
== rv
) {
4088 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4091 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transacation not initialized");
4092 } else if (!obj
->intern
->open
) {
4093 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transacation already closed");
4096 smart_str cmd
= {0};
4098 if (!obj
->intern
->savepoint
) {
4099 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4101 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4102 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4103 smart_str_appends(&cmd
, "\"");
4106 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4110 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4112 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4114 obj
->intern
->open
= 0;
4120 smart_str_free(&cmd
);
4121 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4126 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
4127 ZEND_END_ARG_INFO();
4128 static PHP_METHOD(pqtxn
, commitAsync
) {
4129 zend_error_handling zeh
;
4132 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4133 rv
= zend_parse_parameters_none();
4134 zend_restore_error_handling(&zeh TSRMLS_CC
);
4136 if (SUCCESS
== rv
) {
4137 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4140 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4141 } else if (!obj
->intern
->open
) {
4142 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4145 smart_str cmd
= {0};
4147 if (!obj
->intern
->savepoint
) {
4148 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4150 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4151 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4152 smart_str_appends(&cmd
, "\"");
4155 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4159 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commmit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4162 obj
->intern
->open
= 0;
4164 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4165 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4168 smart_str_free(&cmd
);
4173 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
4174 ZEND_END_ARG_INFO();
4175 static PHP_METHOD(pqtxn
, rollback
) {
4176 zend_error_handling zeh
;
4179 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4180 rv
= zend_parse_parameters_none();
4181 zend_restore_error_handling(&zeh TSRMLS_CC
);
4183 if (SUCCESS
== rv
) {
4184 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4187 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4188 } else if (!obj
->intern
->open
) {
4189 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4192 smart_str cmd
= {0};
4194 if (!obj
->intern
->savepoint
) {
4195 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4197 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4198 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4199 smart_str_appends(&cmd
, "\"");
4202 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4206 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4208 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4210 obj
->intern
->open
= 0;
4216 smart_str_free(&cmd
);
4217 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4222 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
4223 ZEND_END_ARG_INFO();
4224 static PHP_METHOD(pqtxn
, rollbackAsync
) {
4225 zend_error_handling zeh
;
4228 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4229 rv
= zend_parse_parameters_none();
4230 zend_restore_error_handling(&zeh TSRMLS_CC
);
4232 if (SUCCESS
== rv
) {
4233 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4236 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4237 } else if (!obj
->intern
->open
) {
4238 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4241 smart_str cmd
= {0};
4243 if (!obj
->intern
->savepoint
) {
4244 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4246 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4247 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4248 smart_str_appends(&cmd
, "\"");
4251 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4255 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4258 obj
->intern
->open
= 0;
4260 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4263 smart_str_free(&cmd
);
4264 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4269 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot
, 0, 0, 0)
4270 ZEND_END_ARG_INFO();
4271 static PHP_METHOD(pqtxn
, exportSnapshot
) {
4272 zend_error_handling zeh
;
4275 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4276 rv
= zend_parse_parameters_none();
4277 zend_restore_error_handling(&zeh TSRMLS_CC
);
4279 if (SUCCESS
== rv
) {
4280 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4283 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4285 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()");
4288 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4290 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4291 RETVAL_STRING(PQgetvalue(res
, 0, 0), 1);
4297 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4302 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async
, 0, 0, 0)
4303 ZEND_END_ARG_INFO();
4304 static PHP_METHOD(pqtxn
, exportSnapshotAsync
) {
4305 zend_error_handling zeh
;
4308 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4309 rv
= zend_parse_parameters_none();
4310 zend_restore_error_handling(&zeh TSRMLS_CC
);
4312 if (SUCCESS
== rv
) {
4313 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4316 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4317 } else if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()")) {
4318 throw_exce(EX_IO TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4320 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4321 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4326 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot
, 0, 0, 1)
4327 ZEND_ARG_INFO(0, snapshot_id
)
4328 ZEND_END_ARG_INFO();
4329 static PHP_METHOD(pqtxn
, importSnapshot
) {
4330 zend_error_handling zeh
;
4335 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4336 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4337 zend_restore_error_handling(&zeh TSRMLS_CC
);
4339 if (SUCCESS
== rv
) {
4340 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4343 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4344 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4345 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4347 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4350 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4353 smart_str cmd
= {0};
4355 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4356 smart_str_appends(&cmd
, sid
);
4359 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4362 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4364 php_pqres_success(res TSRMLS_CC
);
4368 smart_str_free(&cmd
);
4369 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4375 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async
, 0, 0, 1)
4376 ZEND_ARG_INFO(0, snapshot_id
)
4377 ZEND_END_ARG_INFO();
4378 static PHP_METHOD(pqtxn
, importSnapshotAsync
) {
4379 zend_error_handling zeh
;
4384 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4385 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4386 zend_restore_error_handling(&zeh TSRMLS_CC
);
4388 if (SUCCESS
== rv
) {
4389 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4392 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4393 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4394 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4396 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4399 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4401 smart_str cmd
= {0};
4403 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4404 smart_str_appends(&cmd
, sid
);
4407 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4408 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4410 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4413 smart_str_free(&cmd
);
4414 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4420 static const char *strmode(long mode
)
4422 switch (mode
& (INV_READ
|INV_WRITE
)) {
4423 case INV_READ
|INV_WRITE
:
4434 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob
, 0, 0, 1)
4435 ZEND_ARG_INFO(0, oid
)
4436 ZEND_ARG_INFO(0, mode
)
4437 ZEND_END_ARG_INFO();
4438 static PHP_METHOD(pqtxn
, openLOB
) {
4439 zend_error_handling zeh
;
4440 long mode
= INV_WRITE
|INV_READ
, loid
;
4443 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4444 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &loid
, &mode
);
4445 zend_restore_error_handling(&zeh TSRMLS_CC
);
4447 if (SUCCESS
== rv
) {
4448 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4451 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4453 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4456 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%ld with mode '%s' (%s)", loid
, strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4458 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4462 php_pq_object_addref(obj TSRMLS_CC
);
4465 return_value
->type
= IS_OBJECT
;
4466 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4469 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4474 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob
, 0, 0, 0)
4475 ZEND_ARG_INFO(0, mode
)
4476 ZEND_END_ARG_INFO();
4477 static PHP_METHOD(pqtxn
, createLOB
) {
4478 zend_error_handling zeh
;
4479 long mode
= INV_WRITE
|INV_READ
;
4482 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4483 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &mode
);
4484 zend_restore_error_handling(&zeh TSRMLS_CC
);
4486 if (SUCCESS
== rv
) {
4487 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4490 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4492 Oid loid
= lo_creat(obj
->intern
->conn
->intern
->conn
, mode
);
4494 if (loid
== InvalidOid
) {
4495 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create large object with mode '%s' (%s)", strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4497 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4500 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%ld with mode '%s': %s", loid
, strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4502 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4506 php_pq_object_addref(obj TSRMLS_CC
);
4509 return_value
->type
= IS_OBJECT
;
4510 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4514 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4519 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob
, 0, 0, 1)
4520 ZEND_ARG_INFO(0, oid
)
4521 ZEND_END_ARG_INFO();
4522 static PHP_METHOD(pqtxn
, unlinkLOB
) {
4523 zend_error_handling zeh
;
4527 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4528 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &loid
);
4529 zend_restore_error_handling(&zeh TSRMLS_CC
);
4531 if (SUCCESS
== rv
) {
4532 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4535 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4537 int rc
= lo_unlink(obj
->intern
->conn
->intern
->conn
, loid
);
4540 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to unlink LOB (oid=%ld): %s", loid
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4543 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4548 static zend_function_entry php_pqtxn_methods
[] = {
4549 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4550 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
4551 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
4552 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
4553 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
4554 PHP_ME(pqtxn
, savepoint
, ai_pqtxn_savepoint
, ZEND_ACC_PUBLIC
)
4555 PHP_ME(pqtxn
, savepointAsync
, ai_pqtxn_savepoint_async
, ZEND_ACC_PUBLIC
)
4556 PHP_ME(pqtxn
, exportSnapshot
, ai_pqtxn_export_snapshot
, ZEND_ACC_PUBLIC
)
4557 PHP_ME(pqtxn
, exportSnapshotAsync
, ai_pqtxn_export_snapshot_async
, ZEND_ACC_PUBLIC
)
4558 PHP_ME(pqtxn
, importSnapshot
, ai_pqtxn_import_snapshot
, ZEND_ACC_PUBLIC
)
4559 PHP_ME(pqtxn
, importSnapshotAsync
, ai_pqtxn_import_snapshot_async
, ZEND_ACC_PUBLIC
)
4560 PHP_ME(pqtxn
, openLOB
, ai_pqtxn_open_lob
, ZEND_ACC_PUBLIC
)
4561 PHP_ME(pqtxn
, createLOB
, ai_pqtxn_create_lob
, ZEND_ACC_PUBLIC
)
4562 PHP_ME(pqtxn
, unlinkLOB
, ai_pqtxn_unlink_lob
, ZEND_ACC_PUBLIC
)
4566 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
4567 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4568 ZEND_END_ARG_INFO();
4569 static PHP_METHOD(pqcancel
, __construct
) {
4570 zend_error_handling zeh
;
4574 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4575 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
);
4576 zend_restore_error_handling(&zeh TSRMLS_CC
);
4578 if (SUCCESS
== rv
) {
4579 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4581 if (!conn_obj
->intern
) {
4582 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4584 PGcancel
*cancel
= PQgetCancel(conn_obj
->intern
->conn
);
4587 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
4589 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4591 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4592 obj
->intern
->cancel
= cancel
;
4593 php_pq_object_addref(conn_obj TSRMLS_CC
);
4594 obj
->intern
->conn
= conn_obj
;
4600 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
4601 ZEND_END_ARG_INFO();
4602 static PHP_METHOD(pqcancel
, cancel
) {
4603 zend_error_handling zeh
;
4606 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4607 rv
= zend_parse_parameters_none();
4608 zend_restore_error_handling(&zeh TSRMLS_CC
);
4610 if (SUCCESS
== rv
) {
4611 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4614 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Cancel not initialized");
4616 char err
[256] = {0};
4618 if (!PQcancel(obj
->intern
->cancel
, err
, sizeof(err
))) {
4619 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to request cancellation (%s)", err
);
4625 static zend_function_entry php_pqcancel_methods
[] = {
4626 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4627 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
4631 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct
, 0, 0, 1)
4632 ZEND_ARG_OBJ_INFO(0, transaction
, pq
\\Transaction
, 0)
4633 ZEND_ARG_INFO(0, oid
)
4634 ZEND_ARG_INFO(0, mode
)
4635 ZEND_END_ARG_INFO();
4636 static PHP_METHOD(pqlob
, __construct
) {
4637 zend_error_handling zeh
;
4639 long mode
= INV_WRITE
|INV_READ
, loid
= InvalidOid
;
4642 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4643 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|ll", &ztxn
, php_pqtxn_class_entry
, &loid
, &mode
);
4644 zend_restore_error_handling(&zeh TSRMLS_CC
);
4646 if (SUCCESS
== rv
) {
4647 php_pqtxn_object_t
*txn_obj
= zend_object_store_get_object(ztxn TSRMLS_CC
);
4649 if (!txn_obj
->intern
) {
4650 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4651 } else if (!txn_obj
->intern
->open
) {
4652 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transation already closed");
4654 if (loid
== InvalidOid
) {
4655 loid
= lo_creat(txn_obj
->intern
->conn
->intern
->conn
, mode
);
4658 if (loid
== InvalidOid
) {
4659 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create large object with mode '%s' (%s)", strmode(mode
), PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
));
4661 int lofd
= lo_open(txn_obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4664 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%ld with mode '%s' (%s)", loid
, strmode(mode
), PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
));
4666 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4668 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4669 obj
->intern
->lofd
= lofd
;
4670 obj
->intern
->loid
= loid
;
4671 php_pq_object_addref(txn_obj TSRMLS_CC
);
4672 obj
->intern
->txn
= txn_obj
;
4676 php_pqconn_notify_listeners(txn_obj
->intern
->conn TSRMLS_CC
);
4681 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write
, 0, 0, 1)
4682 ZEND_ARG_INFO(0, data
)
4683 ZEND_END_ARG_INFO();
4684 static PHP_METHOD(pqlob
, write
) {
4685 zend_error_handling zeh
;
4690 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4691 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4692 zend_restore_error_handling(&zeh TSRMLS_CC
);
4694 if (SUCCESS
== rv
) {
4695 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4698 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4700 int written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, data_str
, data_len
);
4703 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to write to LOB with oid=%ld (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4705 RETVAL_LONG(written
);
4708 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4713 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read
, 0, 0, 0)
4714 ZEND_ARG_INFO(0, length
)
4715 ZEND_ARG_INFO(1, read
)
4716 ZEND_END_ARG_INFO();
4717 static PHP_METHOD(pqlob
, read
) {
4718 zend_error_handling zeh
;
4719 long length
= 0x1000;
4723 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4724 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lz!", &length
, &zread
);
4725 zend_restore_error_handling(&zeh TSRMLS_CC
);
4727 if (SUCCESS
== rv
) {
4728 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4731 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4733 char *buffer
= emalloc(length
+ 1);
4734 int read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4738 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to read from LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4742 ZVAL_LONG(zread
, read
);
4744 buffer
[read
] = '\0';
4745 RETVAL_STRINGL(buffer
, read
, 0);
4748 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4753 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek
, 0, 0, 1)
4754 ZEND_ARG_INFO(0, offset
)
4755 ZEND_ARG_INFO(0, whence
)
4756 ZEND_END_ARG_INFO();
4757 static PHP_METHOD(pqlob
, seek
) {
4758 zend_error_handling zeh
;
4759 long offset
, whence
= SEEK_SET
;
4762 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4763 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &offset
, &whence
);
4764 zend_restore_error_handling(&zeh TSRMLS_CC
);
4766 if (SUCCESS
== rv
) {
4767 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4770 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4772 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4775 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to seek offset in LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4777 RETVAL_LONG(position
);
4780 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4785 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell
, 0, 0, 0)
4786 ZEND_END_ARG_INFO();
4787 static PHP_METHOD(pqlob
, tell
) {
4788 zend_error_handling zeh
;
4791 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4792 rv
= zend_parse_parameters_none();
4793 zend_restore_error_handling(&zeh TSRMLS_CC
);
4795 if (SUCCESS
== rv
) {
4796 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4799 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4801 int position
= lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
4804 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to tell offset in LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4806 RETVAL_LONG(position
);
4809 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4814 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate
, 0, 0, 0)
4815 ZEND_ARG_INFO(0, length
)
4816 ZEND_END_ARG_INFO();
4817 static PHP_METHOD(pqlob
, truncate
) {
4818 zend_error_handling zeh
;
4822 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4823 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &length
);
4824 zend_restore_error_handling(&zeh TSRMLS_CC
);
4826 if (SUCCESS
== rv
) {
4827 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4830 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4832 int rc
= lo_truncate(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, length
);
4835 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to truncate LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4838 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4843 static zend_function_entry php_pqlob_methods
[] = {
4844 PHP_ME(pqlob
, __construct
, ai_pqlob_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4845 PHP_ME(pqlob
, write
, ai_pqlob_write
, ZEND_ACC_PUBLIC
)
4846 PHP_ME(pqlob
, read
, ai_pqlob_read
, ZEND_ACC_PUBLIC
)
4847 PHP_ME(pqlob
, seek
, ai_pqlob_seek
, ZEND_ACC_PUBLIC
)
4848 PHP_ME(pqlob
, tell
, ai_pqlob_tell
, ZEND_ACC_PUBLIC
)
4849 PHP_ME(pqlob
, truncate
, ai_pqlob_truncate
, ZEND_ACC_PUBLIC
)
4853 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct
, 0, 0, 3)
4854 ZEND_ARG_OBJ_INFO(0, "connection", pq
\\Connection
, 0)
4855 ZEND_ARG_INFO(0, expression
)
4856 ZEND_ARG_INFO(0, direction
)
4857 ZEND_ARG_INFO(0, options
)
4858 ZEND_END_ARG_INFO();
4859 static PHP_METHOD(pqcopy
, __construct
) {
4860 zend_error_handling zeh
;
4862 char *expr_str
, *opt_str
= "";
4863 int expr_len
, opt_len
= 0;
4867 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4868 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Osl|s", &zconn
, php_pqconn_class_entry
, &expr_str
, &expr_len
, &direction
, &opt_str
, &opt_len
);
4869 zend_restore_error_handling(&zeh TSRMLS_CC
);
4871 if (SUCCESS
== rv
) {
4872 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4874 if (!conn_obj
->intern
) {
4875 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4877 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4878 smart_str cmd
= {0};
4881 smart_str_appends(&cmd
, "COPY ");
4882 smart_str_appendl(&cmd
, expr_str
, expr_len
);
4884 switch (direction
) {
4885 case PHP_PQCOPY_FROM_STDIN
:
4886 smart_str_appends(&cmd
, " FROM STDIN ");
4888 case PHP_PQCOPY_TO_STDOUT
:
4889 smart_str_appends(&cmd
, " TO STDOUT ");
4892 throw_exce(EX_RUNTIME TSRMLS_CC
, "Invalid COPY direction, expected one of FROM_STDIN (%d) TO_STDOUT (%d), got %ld", PHP_PQCOPY_FROM_STDIN
, PHP_PQCOPY_TO_STDOUT
, direction
);
4893 smart_str_free(&cmd
);
4896 smart_str_appendl(&cmd
, opt_str
, opt_len
);
4899 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
4902 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4904 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4905 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4906 obj
->intern
->direction
= direction
;
4907 obj
->intern
->expression
= estrdup(expr_str
);
4908 obj
->intern
->options
= estrdup(opt_str
);
4909 obj
->intern
->conn
= conn_obj
;
4910 php_pq_object_addref(conn_obj TSRMLS_CC
);
4916 smart_str_free(&cmd
);
4917 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4922 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put
, 0, 0, 1)
4923 ZEND_ARG_INFO(0, data
)
4924 ZEND_END_ARG_INFO();
4925 static PHP_METHOD(pqcopy
, put
) {
4926 zend_error_handling zeh
;
4931 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4932 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4933 zend_restore_error_handling(&zeh TSRMLS_CC
);
4935 if (SUCCESS
== rv
) {
4936 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4939 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
4940 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
4941 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not initialized with FROM_STDIN");
4943 if (1 != PQputCopyData(obj
->intern
->conn
->intern
->conn
, data_str
, data_len
)) {
4944 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4946 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4951 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end
, 0, 0, 0)
4952 ZEND_ARG_INFO(0, error
)
4953 ZEND_END_ARG_INFO();
4954 static PHP_METHOD(pqcopy
, end
) {
4955 zend_error_handling zeh
;
4956 char *error_str
= NULL
;
4960 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4961 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &error_str
, &error_len
);
4962 zend_restore_error_handling(&zeh TSRMLS_CC
);
4964 if (SUCCESS
== rv
) {
4965 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4968 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY not intitialized");
4969 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
4970 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intitialized with FROM_STDIN");
4972 if (1 != PQputCopyEnd(obj
->intern
->conn
->intern
->conn
, error_str
)) {
4973 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4975 PGresult
*res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
4978 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4980 php_pqres_success(res TSRMLS_CC
);
4985 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4990 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get
, 0, 0, 1)
4991 ZEND_ARG_INFO(1, data
)
4992 ZEND_END_ARG_INFO();
4993 static PHP_METHOD(pqcopy
, get
) {
4994 zend_error_handling zeh
;
4998 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4999 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
);
5000 zend_restore_error_handling(&zeh TSRMLS_CC
);
5002 if (SUCCESS
== rv
) {
5003 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5006 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
5007 } else if (obj
->intern
->direction
!= PHP_PQCOPY_TO_STDOUT
) {
5008 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intialized with TO_STDOUT");
5011 char *buffer
= NULL
;
5012 int bytes
= PQgetCopyData(obj
->intern
->conn
->intern
->conn
, &buffer
, 0);
5016 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5020 res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
5023 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5025 php_pqres_success(res TSRMLS_CC
);
5034 ZVAL_STRINGL(zdata
, buffer
, bytes
, 1);
5036 ZVAL_EMPTY_STRING(zdata
);
5049 static zend_function_entry php_pqcopy_methods
[] = {
5050 PHP_ME(pqcopy
, __construct
, ai_pqcopy_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
5051 PHP_ME(pqcopy
, put
, ai_pqcopy_put
, ZEND_ACC_PUBLIC
)
5052 PHP_ME(pqcopy
, end
, ai_pqcopy_end
, ZEND_ACC_PUBLIC
)
5053 PHP_ME(pqcopy
, get
, ai_pqcopy_get
, ZEND_ACC_PUBLIC
)
5057 static zend_function_entry php_pqexc_methods
[] = {
5061 /* {{{ PHP_MINIT_FUNCTION
5063 static PHP_MINIT_FUNCTION(pq
)
5065 zend_class_entry ce
= {0};
5066 php_pq_object_prophandler_t ph
= {0};
5068 INIT_NS_CLASS_ENTRY(ce
, "pq", "Exception", php_pqexc_methods
);
5069 php_pqexc_interface_class_entry
= zend_register_internal_interface(&ce TSRMLS_CC
);
5071 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT TSRMLS_CC
);
5072 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("RUNTIME"), EX_RUNTIME TSRMLS_CC
);
5073 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("CONNECTION_FAILED"), EX_CONNECTION_FAILED TSRMLS_CC
);
5074 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("IO"), EX_IO TSRMLS_CC
);
5075 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("ESCAPE"), EX_ESCAPE TSRMLS_CC
);
5076 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("BAD_METHODCALL"), EX_BAD_METHODCALL TSRMLS_CC
);
5077 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("UNINITIALIZED"), EX_UNINITIALIZED TSRMLS_CC
);
5078 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("DOMAIN"), EX_DOMAIN TSRMLS_CC
);
5079 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("SQL"), EX_SQL TSRMLS_CC
);
5081 memset(&ce
, 0, sizeof(ce
));
5082 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "InvalidArgumentException", php_pqexc_methods
);
5083 php_pqexc_invalid_argument_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_InvalidArgumentException
, "InvalidArgumentException" TSRMLS_CC
);
5084 zend_class_implements(php_pqexc_invalid_argument_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5086 memset(&ce
, 0, sizeof(ce
));
5087 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "RuntimeException", php_pqexc_methods
);
5088 php_pqexc_runtime_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_RuntimeException
, "RuntimeException" TSRMLS_CC
);
5089 zend_class_implements(php_pqexc_runtime_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5091 memset(&ce
, 0, sizeof(ce
));
5092 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "BadMethodCallException", php_pqexc_methods
);
5093 php_pqexc_bad_methodcall_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_BadMethodCallException
, "BadMethodCallException" TSRMLS_CC
);
5094 zend_class_implements(php_pqexc_bad_methodcall_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5096 memset(&ce
, 0, sizeof(ce
));
5097 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "DomainException", php_pqexc_methods
);
5098 php_pqexc_domain_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_DomainException
, "DomainException" TSRMLS_CC
);
5099 zend_class_implements(php_pqexc_domain_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5100 zend_declare_property_null(php_pqexc_domain_class_entry
, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5102 memset(&ce
, 0, sizeof(ce
));
5103 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
5104 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5105 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
5107 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5108 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
5109 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
5110 php_pqconn_object_handlers
.clone_obj
= NULL
;
5111 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
5112 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5114 zend_hash_init(&php_pqconn_object_prophandlers
, 14, NULL
, NULL
, 1);
5116 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5117 ph
.read
= php_pqconn_object_read_status
;
5118 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5120 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5121 ph
.read
= php_pqconn_object_read_transaction_status
;
5122 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
5124 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5125 ph
.read
= NULL
; /* forward to std prophandler */
5126 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
5128 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5129 ph
.read
= php_pqconn_object_read_error_message
;
5130 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5132 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5133 ph
.read
= php_pqconn_object_read_busy
;
5134 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
5136 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5137 ph
.read
= php_pqconn_object_read_encoding
;
5138 ph
.write
= php_pqconn_object_write_encoding
;
5139 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
5142 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5143 ph
.read
= php_pqconn_object_read_unbuffered
;
5144 ph
.write
= php_pqconn_object_write_unbuffered
;
5145 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
5148 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5149 ph
.read
= php_pqconn_object_read_db
;
5150 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
5152 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5153 ph
.read
= php_pqconn_object_read_user
;
5154 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
5156 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5157 ph
.read
= php_pqconn_object_read_pass
;
5158 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
5160 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5161 ph
.read
= php_pqconn_object_read_host
;
5162 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
5164 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5165 ph
.read
= php_pqconn_object_read_port
;
5166 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
5168 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5169 ph
.read
= php_pqconn_object_read_options
;
5170 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5172 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5173 ph
.read
= php_pqconn_object_read_event_handlers
;
5174 zend_hash_add(&php_pqconn_object_prophandlers
, "eventHandlers", sizeof("eventHandlers"), (void *) &ph
, sizeof(ph
), NULL
);
5176 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
5177 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
5178 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
5179 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
5180 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
5181 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
5182 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
5183 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
5185 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
5186 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
5187 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
5188 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
5189 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
5191 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
5192 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
5193 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
5194 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
5196 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
5197 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result") TSRMLS_CC
);
5198 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset") TSRMLS_CC
);
5200 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
5201 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
5203 memset(&ce
, 0, sizeof(ce
));
5204 INIT_NS_CLASS_ENTRY(ce
, "pq", "Types", php_pqtypes_methods
);
5205 php_pqtypes_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5206 php_pqtypes_class_entry
->create_object
= php_pqtypes_create_object
;
5208 memcpy(&php_pqtypes_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5209 php_pqtypes_object_handlers
.read_property
= php_pq_object_read_prop
;
5210 php_pqtypes_object_handlers
.write_property
= php_pq_object_write_prop
;
5211 php_pqtypes_object_handlers
.clone_obj
= NULL
;
5212 php_pqtypes_object_handlers
.get_property_ptr_ptr
= NULL
;
5213 php_pqtypes_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5214 php_pqtypes_object_handlers
.has_dimension
= php_pqtypes_object_has_dimension
;
5215 php_pqtypes_object_handlers
.read_dimension
= php_pqtypes_object_read_dimension
;
5216 php_pqtypes_object_handlers
.unset_dimension
= NULL
;
5217 php_pqtypes_object_handlers
.write_dimension
= NULL
;
5219 zend_hash_init(&php_pqtypes_object_prophandlers
, 1, NULL
, NULL
, 1);
5221 zend_declare_property_null(php_pqtypes_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5222 ph
.read
= php_pqtypes_object_read_connection
;
5223 zend_hash_add(&php_pqtypes_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5225 memset(&ce
, 0, sizeof(ce
));
5226 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
5227 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5228 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
5229 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
5230 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
5231 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 2, zend_ce_traversable
, spl_ce_Countable
);
5233 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5234 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
5235 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
5236 php_pqres_object_handlers
.clone_obj
= NULL
;
5237 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
5238 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5239 php_pqres_object_handlers
.count_elements
= php_pqres_count_elements
;
5241 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
5243 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5244 ph
.read
= php_pqres_object_read_status
;
5245 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5247 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5248 ph
.read
= php_pqres_object_read_status_message
;
5249 zend_hash_add(&php_pqres_object_prophandlers
, "statusMessage", sizeof("statusMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5251 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5252 ph
.read
= php_pqres_object_read_error_message
;
5253 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5255 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5256 ph
.read
= php_pqres_object_read_num_rows
;
5257 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
5259 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5260 ph
.read
= php_pqres_object_read_num_cols
;
5261 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
5263 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5264 ph
.read
= php_pqres_object_read_affected_rows
;
5265 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
5267 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5268 ph
.read
= php_pqres_object_read_fetch_type
;
5269 ph
.write
= php_pqres_object_write_fetch_type
;
5270 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
5273 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
5274 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
5275 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
5276 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
5277 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
5278 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
5279 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
5280 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
5281 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
5282 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
5284 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
5285 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
5286 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
5288 memset(&ce
, 0, sizeof(ce
));
5289 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
5290 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5291 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
5293 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5294 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
5295 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
5296 php_pqstm_object_handlers
.clone_obj
= NULL
;
5297 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
5298 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5300 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
5302 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5303 ph
.read
= php_pqstm_object_read_name
;
5304 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
5306 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5307 ph
.read
= php_pqstm_object_read_connection
;
5308 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5310 memset(&ce
, 0, sizeof(ce
));
5311 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
5312 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5313 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
5315 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5316 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
5317 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
5318 php_pqtxn_object_handlers
.clone_obj
= NULL
;
5319 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
5320 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5322 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
5324 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5325 ph
.read
= php_pqtxn_object_read_connection
;
5326 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5328 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5329 ph
.read
= php_pqtxn_object_read_isolation
;
5330 ph
.write
= php_pqtxn_object_write_isolation
;
5331 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
5333 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5334 ph
.read
= php_pqtxn_object_read_readonly
;
5335 ph
.write
= php_pqtxn_object_write_readonly
;
5336 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
5338 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5339 ph
.read
= php_pqtxn_object_read_deferrable
;
5340 ph
.write
= php_pqtxn_object_write_deferrable
;
5341 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
5344 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
5345 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
5346 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
5348 memset(&ce
, 0, sizeof(ce
));
5349 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
5350 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5351 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
5353 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5354 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
5355 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
5356 php_pqcancel_object_handlers
.clone_obj
= NULL
;
5357 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
5358 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5360 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
5362 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5363 ph
.read
= php_pqcancel_object_read_connection
;
5364 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5366 memset(&ce
, 0, sizeof(ce
));
5367 INIT_NS_CLASS_ENTRY(ce
, "pq", "LOB", php_pqlob_methods
);
5368 php_pqlob_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5369 php_pqlob_class_entry
->create_object
= php_pqlob_create_object
;
5371 memcpy(&php_pqlob_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5372 php_pqlob_object_handlers
.read_property
= php_pq_object_read_prop
;
5373 php_pqlob_object_handlers
.write_property
= php_pq_object_write_prop
;
5374 php_pqlob_object_handlers
.clone_obj
= NULL
;
5375 php_pqlob_object_handlers
.get_property_ptr_ptr
= NULL
;
5376 php_pqlob_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5378 zend_hash_init(&php_pqlob_object_prophandlers
, 2, NULL
, NULL
, 1);
5380 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5381 ph
.read
= php_pqlob_object_read_transaction
;
5382 zend_hash_add(&php_pqlob_object_prophandlers
, "transaction", sizeof("transaction"), (void *) &ph
, sizeof(ph
), NULL
);
5384 zend_declare_property_long(php_pqlob_class_entry
, ZEND_STRL("oid"), InvalidOid
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5385 ph
.read
= php_pqlob_object_read_oid
;
5386 zend_hash_add(&php_pqlob_object_prophandlers
, "oid", sizeof("oid"), (void *) &ph
, sizeof(ph
), NULL
);
5388 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC
);
5389 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("R"), INV_READ TSRMLS_CC
);
5390 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("W"), INV_WRITE TSRMLS_CC
);
5391 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("RW"), INV_READ
|INV_WRITE TSRMLS_CC
);
5393 memset(&ce
, 0, sizeof(ce
));
5394 INIT_NS_CLASS_ENTRY(ce
, "pq", "COPY", php_pqcopy_methods
);
5395 php_pqcopy_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5396 php_pqcopy_class_entry
->create_object
= php_pqcopy_create_object
;
5398 memcpy(&php_pqcopy_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5399 php_pqcopy_object_handlers
.read_property
= php_pq_object_read_prop
;
5400 php_pqcopy_object_handlers
.write_property
= php_pq_object_write_prop
;
5401 php_pqcopy_object_handlers
.clone_obj
= NULL
;
5402 php_pqcopy_object_handlers
.get_property_ptr_ptr
= NULL
;
5403 php_pqcopy_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5405 zend_hash_init(&php_pqcopy_object_prophandlers
, 4, NULL
, NULL
, 1);
5407 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5408 ph
.read
= php_pqcopy_object_read_connection
;
5409 zend_hash_add(&php_pqcopy_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5411 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5412 ph
.read
= php_pqcopy_object_read_expression
;
5413 zend_hash_add(&php_pqcopy_object_prophandlers
, "expression", sizeof("expression"), (void *) &ph
, sizeof(ph
), NULL
);
5415 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5416 ph
.read
= php_pqcopy_object_read_direction
;
5417 zend_hash_add(&php_pqcopy_object_prophandlers
, "direction", sizeof("direction"), (void *) &ph
, sizeof(ph
), NULL
);
5419 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5420 ph
.read
= php_pqcopy_object_read_options
;
5421 zend_hash_add(&php_pqcopy_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5423 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC
);
5424 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC
);
5426 php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops
, NULL
, NULL TSRMLS_CC
);
5429 REGISTER_INI_ENTRIES();
5435 /* {{{ PHP_MSHUTDOWN_FUNCTION
5437 static PHP_MSHUTDOWN_FUNCTION(pq
)
5439 /* uncomment this line if you have INI entries
5440 UNREGISTER_INI_ENTRIES();
5442 php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL
, 0 TSRMLS_CC
);
5447 /* {{{ PHP_MINFO_FUNCTION
5449 static PHP_MINFO_FUNCTION(pq
)
5451 #ifdef HAVE_PQLIBVERSION
5454 char libpq_version
[10] = "pre-9.1";
5456 php_info_print_table_start();
5457 php_info_print_table_header(2, "PQ Support", "enabled");
5458 php_info_print_table_row(2, "Extension Version", PHP_PQ_EXT_VERSION
);
5459 php_info_print_table_end();
5461 php_info_print_table_start();
5462 php_info_print_table_header(2, "Used Library", "Version");
5463 #ifdef HAVE_PQLIBVERSION
5464 libpq_v
= PQlibVersion();
5465 slprintf(libpq_version
, sizeof(libpq_version
), "%d.%d.%d", libpq_v
/10000%100, libpq_v
/100%100, libpq_v
%100);
5467 php_info_print_table_row(2, "libpq", libpq_version
);
5468 php_info_print_table_end();
5470 /* Remove comments if you have entries in php.ini
5471 DISPLAY_INI_ENTRIES();
5476 const zend_function_entry pq_functions
[] = {
5480 static zend_module_dep pq_module_deps
[] = {
5481 ZEND_MOD_REQUIRED("raphf")
5482 ZEND_MOD_REQUIRED("spl")
5486 /* {{{ pq_module_entry
5488 zend_module_entry pq_module_entry
= {
5489 STANDARD_MODULE_HEADER_EX
,
5496 NULL
,/*PHP_RINIT(pq),*/
5497 NULL
,/*PHP_RSHUTDOWN(pq),*/
5500 STANDARD_MODULE_PROPERTIES
5504 #ifdef COMPILE_DL_PQ
5514 * vim600: noet sw=4 ts=4 fdm=marker
5515 * vim<600: noet sw=4 ts=4