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 if (PQntuples(res
) > row
) {
431 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
432 if (PQgetisnull(res
, row
, c
)) {
433 switch (fetch_type
) {
434 case PHP_PQRES_FETCH_OBJECT
:
435 add_property_null(data
, PQfname(res
, c
));
438 case PHP_PQRES_FETCH_ASSOC
:
439 add_assoc_null(data
, PQfname(res
, c
));
442 case PHP_PQRES_FETCH_ARRAY
:
443 add_index_null(data
, c
);
447 char *val
= PQgetvalue(res
, row
, c
);
448 int len
= PQgetlength(res
, row
, c
);
450 switch (fetch_type
) {
451 case PHP_PQRES_FETCH_OBJECT
:
452 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
455 case PHP_PQRES_FETCH_ASSOC
:
456 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
459 case PHP_PQRES_FETCH_ARRAY
:
460 add_index_stringl(data
, c
, val
, len
,1);
470 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
472 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
473 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
475 if (!iter
->current_val
) {
476 iter
->current_val
= php_pqres_row_to_zval(obj
->intern
->res
, iter
->index
, iter
->fetch_type
, NULL TSRMLS_CC
);
478 *data_ptr
= &iter
->current_val
;
481 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
483 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
485 *key_num
= (ulong
) iter
->index
;
487 return HASH_KEY_IS_LONG
;
490 static void php_pqres_iterator_invalidate(zend_object_iterator
*i TSRMLS_DC
)
492 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
494 if (iter
->current_val
) {
495 zval_ptr_dtor(&iter
->current_val
);
496 iter
->current_val
= NULL
;
500 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
502 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
504 php_pqres_iterator_invalidate(i TSRMLS_CC
);
508 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
510 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
512 php_pqres_iterator_invalidate(i TSRMLS_CC
);
516 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
517 php_pqres_iterator_dtor
,
518 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
519 php_pqres_iterator_valid
,
520 /* fetch the item data for the current element */
521 php_pqres_iterator_current
,
522 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
523 php_pqres_iterator_key
,
524 /* step forwards to next element */
525 php_pqres_iterator_next
,
526 /* rewind to start of data (optional, may be NULL) */
527 php_pqres_iterator_rewind
,
528 /* invalidate current value/key (optional, may be NULL) */
529 php_pqres_iterator_invalidate
532 static int php_pqres_count_elements(zval
*object
, long *count TSRMLS_DC
)
534 php_pqres_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
539 *count
= (long) PQntuples(obj
->intern
->res
);
544 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
548 switch (PQresultStatus(res
)) {
549 case PGRES_BAD_RESPONSE
:
550 case PGRES_NONFATAL_ERROR
:
551 case PGRES_FATAL_ERROR
:
552 zexc
= throw_exce(EX_SQL TSRMLS_CC
, "%s", PHP_PQresultErrorMessage(res
));
553 zend_update_property_string(php_pqexc_domain_class_entry
, zexc
, ZEND_STRL("sqlstate"), PQresultErrorField(res
, PG_DIAG_SQLSTATE
) TSRMLS_CC
);
560 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
561 if (cb
->fci
.size
> 0) {
562 zend_fcall_info_args_clear(&cb
->fci
, 1);
563 zval_ptr_dtor(&cb
->fci
.function_name
);
564 if (cb
->fci
.object_ptr
) {
565 zval_ptr_dtor(&cb
->fci
.object_ptr
);
571 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
573 Z_ADDREF_P(cb
->fci
.function_name
);
574 if (cb
->fci
.object_ptr
) {
575 Z_ADDREF_P(cb
->fci
.object_ptr
);
580 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC)
584 if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
585 zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
590 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
)
595 if (SUCCESS
!= zend_hash_find(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
598 zend_hash_init(&evh
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
599 zend_hash_add(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(evh
), (void *) &evhs
);
602 php_pq_callback_addref(cb
);
603 h
= zend_hash_next_free_element(evhs
);
604 zend_hash_index_update(evhs
, h
, (void *) cb
, sizeof(*cb
), NULL
);
609 static void php_pq_object_to_zval(void *o
, zval
**zv TSRMLS_DC
)
611 php_pq_object_t
*obj
= o
;
617 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
619 (*zv
)->type
= IS_OBJECT
;
620 (*zv
)->value
.obj
= obj
->zv
;
623 static void php_pq_object_to_zval_no_addref(void *o
, zval
**zv TSRMLS_DC
)
625 php_pq_object_t
*obj
= o
;
633 (*zv
)->type
= IS_OBJECT
;
634 (*zv
)->value
.obj
= obj
->zv
;
637 static void php_pq_object_addref(void *o TSRMLS_DC
)
639 php_pq_object_t
*obj
= o
;
640 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
643 static void php_pq_object_delref(void *o TSRMLS_DC
)
645 php_pq_object_t
*obj
= o
;
646 zend_objects_store_del_ref_by_handle_ex(obj
->zv
.handle
, obj
->zv
.handlers TSRMLS_CC
);
649 static void php_pqconn_object_free(void *o TSRMLS_DC
)
651 php_pqconn_object_t
*obj
= o
;
653 fprintf(stderr
, "FREE conn(#%d) %p\n", obj
->zv
.handle
, obj
);
656 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
657 php_resource_factory_dtor(&obj
->intern
->factory
);
658 php_pq_callback_dtor(&obj
->intern
->onevent
);
659 zend_hash_destroy(&obj
->intern
->listeners
);
660 zend_hash_destroy(&obj
->intern
->eventhandlers
);
664 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
668 static void php_pqtypes_object_free(void *o TSRMLS_DC
)
670 php_pqtypes_object_t
*obj
= o
;
672 fprintf(stderr
, "FREE types(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
675 zend_hash_destroy(&obj
->intern
->types
);
676 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
680 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
684 static void php_pqres_object_free(void *o TSRMLS_DC
)
686 php_pqres_object_t
*obj
= o
;
688 fprintf(stderr
, "FREE res(#%d) %p\n", obj
->zv
.handle
, obj
);
691 if (obj
->intern
->res
) {
692 PQresultSetInstanceData(obj
->intern
->res
, php_pqconn_event
, NULL
);
693 PQclear(obj
->intern
->res
);
694 obj
->intern
->res
= NULL
;
697 if (obj
->intern
->iter
) {
698 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
699 obj
->intern
->iter
= NULL
;
702 zend_hash_destroy(&obj
->intern
->bound
);
707 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
711 static void php_pqstm_object_free(void *o TSRMLS_DC
)
713 php_pqstm_object_t
*obj
= o
;
715 fprintf(stderr
, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
718 char *quoted_name
= PQescapeIdentifier(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, strlen(obj
->intern
->name
));
720 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
726 smart_str_appends(&cmd
, "DEALLOCATE ");
727 smart_str_appends(&cmd
, quoted_name
);
729 PQfreemem(quoted_name
);
731 if ((res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
))) {
734 smart_str_free(&cmd
);
737 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
738 efree(obj
->intern
->name
);
739 zend_hash_destroy(&obj
->intern
->bound
);
743 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
747 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
749 php_pqtxn_object_t
*obj
= o
;
751 fprintf(stderr
, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
754 if (obj
->intern
->open
) {
755 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
761 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
765 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
769 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
771 php_pqcancel_object_t
*obj
= o
;
773 fprintf(stderr
, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
776 PQfreeCancel(obj
->intern
->cancel
);
777 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
781 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
785 static void php_pqlob_object_free(void *o TSRMLS_DC
)
787 php_pqlob_object_t
*obj
= o
;
789 fprintf(stderr
, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->txn
->zv
.handle
, obj
->intern
->txn
);
792 if (obj
->intern
->lofd
) {
793 lo_close(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
795 php_pq_object_delref(obj
->intern
->txn TSRMLS_CC
);
799 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
803 static void php_pqcopy_object_free(void *o TSRMLS_DC
)
805 php_pqcopy_object_t
*obj
= o
;
807 fprintf(stderr
, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
810 efree(obj
->intern
->expression
);
811 efree(obj
->intern
->options
);
812 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
816 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
820 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
822 php_pqconn_object_t
*o
;
824 o
= ecalloc(1, sizeof(*o
));
825 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
826 object_properties_init((zend_object
*) o
, ce
);
827 o
->prophandler
= &php_pqconn_object_prophandlers
;
837 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
838 o
->zv
.handlers
= &php_pqconn_object_handlers
;
843 static zend_object_value
php_pqtypes_create_object_ex(zend_class_entry
*ce
, php_pqtypes_t
*intern
, php_pqtypes_object_t
**ptr TSRMLS_DC
)
845 php_pqtypes_object_t
*o
;
847 o
= ecalloc(1, sizeof(*o
));
848 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
849 object_properties_init((zend_object
*) o
, ce
);
850 o
->prophandler
= &php_pqtypes_object_prophandlers
;
860 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtypes_object_free
, NULL TSRMLS_CC
);
861 o
->zv
.handlers
= &php_pqtypes_object_handlers
;
866 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, php_pqres_t
*intern
, php_pqres_object_t
**ptr TSRMLS_DC
)
868 php_pqres_object_t
*o
;
870 o
= ecalloc(1, sizeof(*o
));
871 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
872 object_properties_init((zend_object
*) o
, ce
);
873 o
->prophandler
= &php_pqres_object_prophandlers
;
883 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
884 o
->zv
.handlers
= &php_pqres_object_handlers
;
889 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*intern
, php_pqstm_object_t
**ptr TSRMLS_DC
)
891 php_pqstm_object_t
*o
;
893 o
= ecalloc(1, sizeof(*o
));
894 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
895 object_properties_init((zend_object
*) o
, ce
);
896 o
->prophandler
= &php_pqstm_object_prophandlers
;
906 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
907 o
->zv
.handlers
= &php_pqstm_object_handlers
;
912 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*intern
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
914 php_pqtxn_object_t
*o
;
916 o
= ecalloc(1, sizeof(*o
));
917 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
918 object_properties_init((zend_object
*) o
, ce
);
919 o
->prophandler
= &php_pqtxn_object_prophandlers
;
929 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
930 o
->zv
.handlers
= &php_pqtxn_object_handlers
;
935 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*intern
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
937 php_pqcancel_object_t
*o
;
939 o
= ecalloc(1, sizeof(*o
));
940 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
941 object_properties_init((zend_object
*) o
, ce
);
942 o
->prophandler
= &php_pqcancel_object_prophandlers
;
952 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
953 o
->zv
.handlers
= &php_pqcancel_object_handlers
;
958 static zend_object_value
php_pqlob_create_object_ex(zend_class_entry
*ce
, php_pqlob_t
*intern
, php_pqlob_object_t
**ptr TSRMLS_DC
)
960 php_pqlob_object_t
*o
;
962 o
= ecalloc(1, sizeof(*o
));
963 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
964 object_properties_init((zend_object
*) o
, ce
);
965 o
->prophandler
= &php_pqlob_object_prophandlers
;
975 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqlob_object_free
, NULL TSRMLS_CC
);
976 o
->zv
.handlers
= &php_pqlob_object_handlers
;
981 static zend_object_value
php_pqcopy_create_object_ex(zend_class_entry
*ce
, php_pqcopy_t
*intern
, php_pqcopy_object_t
**ptr TSRMLS_DC
)
983 php_pqcopy_object_t
*o
;
985 o
= ecalloc(1, sizeof(*o
));
986 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
987 object_properties_init((zend_object
*) o
, ce
);
988 o
->prophandler
= &php_pqcopy_object_prophandlers
;
998 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcopy_object_free
, NULL TSRMLS_CC
);
999 o
->zv
.handlers
= &php_pqcopy_object_handlers
;
1004 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1006 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1009 static zend_object_value
php_pqtypes_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1011 return php_pqtypes_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1014 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1016 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1019 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1021 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1024 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1026 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1029 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1031 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1034 static zend_object_value
php_pqlob_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1036 return php_pqlob_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1039 static zend_object_value
php_pqcopy_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1041 return php_pqcopy_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1044 static int apply_pi_to_ht(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1046 zend_property_info
*pi
= p
;
1047 HashTable
*ht
= va_arg(argv
, HashTable
*);
1048 zval
*object
= va_arg(argv
, zval
*);
1049 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
1050 int addref
= va_arg(argv
, int);
1051 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
1054 Z_ADDREF_P(property
);
1056 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
1058 return ZEND_HASH_APPLY_KEEP
;
1061 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
1064 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1067 ALLOC_HASHTABLE(ht
);
1068 ZEND_INIT_SYMTABLE(ht
);
1070 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_ht
, 4, ht
, object
, obj
, 1);
1075 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1077 php_pqconn_object_t
*obj
= o
;
1079 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
1082 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1084 php_pqconn_object_t
*obj
= o
;
1086 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
1089 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1091 php_pqconn_object_t
*obj
= o
;
1092 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
1095 RETVAL_STRING(error
, 1);
1101 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
1103 php_pq_callback_t
*listener
= p
;
1104 PGnotify
*nfy
= arg
;
1105 zval
*zpid
, *zchannel
, *zmessage
;
1107 MAKE_STD_ZVAL(zpid
);
1108 ZVAL_LONG(zpid
, nfy
->be_pid
);
1109 MAKE_STD_ZVAL(zchannel
);
1110 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
1111 MAKE_STD_ZVAL(zmessage
);
1112 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
1114 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
1115 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
1117 zval_ptr_dtor(&zchannel
);
1118 zval_ptr_dtor(&zmessage
);
1119 zval_ptr_dtor(&zpid
);
1121 return ZEND_HASH_APPLY_KEEP
;
1124 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1126 HashTable
*listeners
= p
;
1127 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
1129 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
1130 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
1133 return ZEND_HASH_APPLY_KEEP
;
1136 static void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
1140 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
1141 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
1146 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1148 php_pqconn_object_t
*obj
= o
;
1150 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
1153 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1155 php_pqconn_object_t
*obj
= o
;
1157 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
1160 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1162 php_pqconn_object_t
*obj
= o
;
1165 if (Z_TYPE_P(value
) != IS_STRING
) {
1166 if (Z_REFCOUNT_P(value
) > 1) {
1169 ZVAL_ZVAL(tmp
, zenc
, 1, 0);
1170 convert_to_string(tmp
);
1173 convert_to_string_ex(&zenc
);
1177 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
1178 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
1181 if (zenc
!= value
) {
1182 zval_ptr_dtor(&zenc
);
1186 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1188 php_pqconn_object_t
*obj
= o
;
1190 RETVAL_BOOL(obj
->intern
->unbuffered
);
1193 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1195 php_pqconn_object_t
*obj
= o
;
1197 obj
->intern
->unbuffered
= zend_is_true(value
);
1200 static void php_pqconn_object_read_db(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1202 php_pqconn_object_t
*obj
= o
;
1203 char *db
= PQdb(obj
->intern
->conn
);
1206 RETVAL_STRING(db
, 1);
1208 RETVAL_EMPTY_STRING();
1212 static void php_pqconn_object_read_user(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1214 php_pqconn_object_t
*obj
= o
;
1215 char *user
= PQuser(obj
->intern
->conn
);
1218 RETVAL_STRING(user
, 1);
1220 RETVAL_EMPTY_STRING();
1224 static void php_pqconn_object_read_pass(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1226 php_pqconn_object_t
*obj
= o
;
1227 char *pass
= PQpass(obj
->intern
->conn
);
1230 RETVAL_STRING(pass
, 1);
1232 RETVAL_EMPTY_STRING();
1236 static void php_pqconn_object_read_host(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1238 php_pqconn_object_t
*obj
= o
;
1239 char *host
= PQhost(obj
->intern
->conn
);
1242 RETVAL_STRING(host
, 1);
1244 RETVAL_EMPTY_STRING();
1248 static void php_pqconn_object_read_port(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1250 php_pqconn_object_t
*obj
= o
;
1251 char *port
= PQport(obj
->intern
->conn
);
1254 RETVAL_STRING(port
, 1);
1256 RETVAL_EMPTY_STRING();
1260 static void php_pqconn_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1262 php_pqconn_object_t
*obj
= o
;
1263 char *options
= PQoptions(obj
->intern
->conn
);
1266 RETVAL_STRING(options
, 1);
1268 RETVAL_EMPTY_STRING();
1272 static void php_pqconn_object_read_event_handlers(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1274 php_pqconn_object_t
*obj
= o
;
1276 array_init(return_value
);
1277 zend_hash_copy(Z_ARRVAL_P(return_value
), &obj
->intern
->eventhandlers
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
1280 static void php_pqtypes_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1282 php_pqtypes_object_t
*obj
= o
;
1284 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1287 static int has_dimension(HashTable
*ht
, zval
*member
, char **key_str
, int *key_len
, ulong
*index TSRMLS_DC
)
1292 switch (Z_TYPE_P(member
)) {
1294 convert_to_string_ex(&tmp
);
1297 if (!is_numeric_string(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
), &lval
, NULL
, 0)) {
1298 int exists
= zend_hash_exists(ht
, Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
) + 1);
1301 *key_str
= estrndup(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
));
1303 *key_len
= Z_STRLEN_P(tmp
) + 1;
1306 if (member
!= tmp
) {
1307 zval_ptr_dtor(&tmp
);
1314 lval
= Z_LVAL_P(member
);
1318 if (member
!= tmp
) {
1319 zval_ptr_dtor(&tmp
);
1324 return zend_hash_index_exists(ht
, lval
);
1327 static int php_pqtypes_object_has_dimension(zval
*object
, zval
*member
, int check_empty TSRMLS_DC
)
1329 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1330 char *key_str
= NULL
;
1335 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1338 if (key_str
&& key_len
) {
1339 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1341 return Z_TYPE_PP(data
) != IS_NULL
;
1345 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1346 return Z_TYPE_PP(data
) != IS_NULL
;
1354 return has_dimension(&obj
->intern
->types
, member
, NULL
, NULL
, NULL TSRMLS_CC
);
1360 static zval
*php_pqtypes_object_read_dimension(zval
*object
, zval
*member
, int type TSRMLS_DC
)
1363 char *key_str
= NULL
;
1365 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1367 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1370 if (key_str
&& key_len
) {
1371 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1376 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1388 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1390 php_pqres_object_t
*obj
= o
;
1392 RETVAL_LONG(PQresultStatus(obj
->intern
->res
));
1395 static void php_pqres_object_read_status_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1397 php_pqres_object_t
*obj
= o
;
1399 RETVAL_STRING(PQresStatus(PQresultStatus(obj
->intern
->res
))+sizeof("PGRES"), 1);
1402 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1404 php_pqres_object_t
*obj
= o
;
1405 char *error
= PHP_PQresultErrorMessage(obj
->intern
->res
);
1408 RETVAL_STRING(error
, 1);
1414 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1416 php_pqres_object_t
*obj
= o
;
1418 RETVAL_LONG(PQntuples(obj
->intern
->res
));
1421 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1423 php_pqres_object_t
*obj
= o
;
1425 RETVAL_LONG(PQnfields(obj
->intern
->res
));
1428 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1430 php_pqres_object_t
*obj
= o
;
1432 RETVAL_LONG(atoi(PQcmdTuples(obj
->intern
->res
)));
1435 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1437 php_pqres_object_t
*obj
= o
;
1439 if (obj
->intern
->iter
) {
1440 RETVAL_LONG(obj
->intern
->iter
->fetch_type
);
1442 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
1446 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1448 php_pqres_object_t
*obj
= o
;
1449 zval
*zfetch_type
= value
;
1451 if (Z_TYPE_P(value
) != IS_LONG
) {
1452 if (Z_REFCOUNT_P(value
) > 1) {
1455 ZVAL_ZVAL(tmp
, zfetch_type
, 1, 0);
1456 convert_to_long(tmp
);
1459 convert_to_long_ex(&zfetch_type
);
1463 if (!obj
->intern
->iter
) {
1464 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
1465 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
1467 obj
->intern
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
1469 if (zfetch_type
!= value
) {
1470 zval_ptr_dtor(&zfetch_type
);
1474 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1476 php_pqstm_object_t
*obj
= o
;
1478 RETVAL_STRING(obj
->intern
->name
, 1);
1481 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1483 php_pqstm_object_t
*obj
= o
;
1485 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1488 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1490 php_pqtxn_object_t
*obj
= o
;
1492 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1495 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1497 php_pqtxn_object_t
*obj
= o
;
1499 RETVAL_LONG(obj
->intern
->isolation
);
1502 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1504 php_pqtxn_object_t
*obj
= o
;
1506 RETVAL_BOOL(obj
->intern
->readonly
);
1509 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1511 php_pqtxn_object_t
*obj
= o
;
1513 RETVAL_BOOL(obj
->intern
->deferrable
);
1516 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1518 php_pqtxn_object_t
*obj
= o
;
1519 php_pqtxn_isolation_t orig
= obj
->intern
->isolation
;
1520 zval
*zisolation
= value
;
1523 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
1524 if (Z_REFCOUNT_P(value
) > 1) {
1527 ZVAL_ZVAL(tmp
, zisolation
, 1, 0);
1528 convert_to_long(tmp
);
1531 convert_to_long_ex(&zisolation
);
1535 switch ((obj
->intern
->isolation
= Z_LVAL_P(zisolation
))) {
1536 case PHP_PQTXN_READ_COMMITTED
:
1537 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL READ COMMITED");
1539 case PHP_PQTXN_REPEATABLE_READ
:
1540 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
1542 case PHP_PQTXN_SERIALIZABLE
:
1543 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
1546 obj
->intern
->isolation
= orig
;
1551 if (zisolation
!= value
) {
1552 zval_ptr_dtor(&zisolation
);
1556 php_pqres_success(res TSRMLS_CC
);
1561 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1563 php_pqtxn_object_t
*obj
= o
;
1566 if ((obj
->intern
->readonly
= zend_is_true(value
))) {
1567 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ ONLY");
1569 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ WRITE");
1573 php_pqres_success(res TSRMLS_CC
);
1578 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1580 php_pqtxn_object_t
*obj
= o
;
1583 if ((obj
->intern
->deferrable
= zend_is_true(value
))) {
1584 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION DEFERRABLE");
1586 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION NOT DEFERRABLE");
1590 php_pqres_success(res TSRMLS_CC
);
1595 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1597 php_pqcancel_object_t
*obj
= o
;
1599 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1602 static void php_pqlob_object_read_transaction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1604 php_pqlob_object_t
*obj
= o
;
1606 php_pq_object_to_zval(obj
->intern
->txn
, &return_value TSRMLS_CC
);
1609 static void php_pqlob_object_read_oid(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1611 php_pqlob_object_t
*obj
= o
;
1613 RETVAL_LONG(obj
->intern
->loid
);
1616 static void php_pqcopy_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1618 php_pqcopy_object_t
*obj
= o
;
1620 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1623 static void php_pqcopy_object_read_direction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1625 php_pqcopy_object_t
*obj
= o
;
1627 RETVAL_LONG(obj
->intern
->direction
);
1630 static void php_pqcopy_object_read_expression(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1632 php_pqcopy_object_t
*obj
= o
;
1634 RETURN_STRING(obj
->intern
->expression
, 1);
1637 static void php_pqcopy_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1639 php_pqcopy_object_t
*obj
= o
;
1641 RETURN_STRING(obj
->intern
->options
, 1);
1644 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
1645 while (ce
->parent
) {
1651 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
1653 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1654 php_pq_object_prophandler_t
*handler
;
1658 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1659 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1660 if (type
== BP_VAR_R
) {
1661 ALLOC_ZVAL(return_value
);
1662 Z_SET_REFCOUNT_P(return_value
, 0);
1663 Z_UNSET_ISREF_P(return_value
);
1665 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1667 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1668 return_value
= NULL
;
1671 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1674 return return_value
;
1677 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1679 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1680 php_pq_object_prophandler_t
*handler
;
1682 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1683 if (handler
->write
) {
1684 handler
->write(object
, obj
, value TSRMLS_CC
);
1687 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1691 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1693 zval
*zsocket
, zmember
;
1699 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1702 INIT_PZVAL(&zmember
);
1703 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1704 MAKE_STD_ZVAL(zsocket
);
1706 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
1707 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
1708 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1709 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1710 php_stream_to_zval(stream
, zsocket
);
1716 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1717 zval_ptr_dtor(&zsocket
);
1723 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1724 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1726 # define TSRMLS_DF(d)
1727 # define TSRMLS_CF(d)
1730 static int apply_event(void *p
, void *a TSRMLS_DC
)
1732 php_pq_callback_t
*cb
= p
;
1734 zval
*retval
= NULL
;
1736 zend_fcall_info_args(&cb
->fci
, args TSRMLS_CC
);
1737 zend_fcall_info_call(&cb
->fci
, &cb
->fcc
, &retval
, NULL TSRMLS_CC
);
1739 zval_ptr_dtor(&retval
);
1742 return ZEND_HASH_APPLY_KEEP
;
1745 static void php_pqconn_event_connreset(PGEventConnReset
*event
)
1747 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1753 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("reset"), (void *) &evhs
)) {
1754 zval
*args
, *connection
= NULL
;
1756 MAKE_STD_ZVAL(args
);
1758 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1759 add_next_index_zval(args
, connection
);
1760 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1761 zval_ptr_dtor(&args
);
1766 static void php_pqres_init_instance_data(PGresult
*res
, php_pqres_object_t
**ptr TSRMLS_DC
)
1768 php_pqres_object_t
*obj
;
1769 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
1772 ZEND_INIT_SYMTABLE(&r
->bound
);
1773 php_pqres_create_object_ex(php_pqres_class_entry
, r
, &obj TSRMLS_CC
);
1775 PQresultSetInstanceData(res
, php_pqconn_event
, obj
);
1782 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
)
1784 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1787 php_pqres_object_t
*obj
;
1791 php_pqres_init_instance_data(event
->result
, &obj TSRMLS_CC
);
1793 /* event listener */
1794 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("result"), (void *) &evhs
)) {
1795 zval
*args
, *connection
= NULL
, *res
= NULL
;
1797 MAKE_STD_ZVAL(args
);
1799 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1800 add_next_index_zval(args
, connection
);
1801 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1802 add_next_index_zval(args
, res
);
1803 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1804 zval_ptr_dtor(&args
);
1807 /* async callback */
1808 if (data
->obj
->intern
->onevent
.fci
.size
> 0) {
1811 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1812 zend_fcall_info_argn(&data
->obj
->intern
->onevent
.fci TSRMLS_CC
, 1, &res
);
1813 zend_fcall_info_call(&data
->obj
->intern
->onevent
.fci
, &data
->obj
->intern
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1814 zval_ptr_dtor(&res
);
1820 static void php_pqconn_event_resultdestroy(PGEventResultDestroy
*event
)
1822 php_pqres_object_t
*obj
= PQresultInstanceData(event
->result
, php_pqconn_event
);
1825 obj
->intern
->res
= NULL
;
1829 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1832 case PGEVT_CONNRESET
:
1833 php_pqconn_event_connreset(e
);
1835 case PGEVT_RESULTCREATE
:
1836 php_pqconn_event_resultcreate(e
);
1838 case PGEVT_RESULTDESTROY
:
1839 php_pqconn_event_resultdestroy(e
);
1848 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1850 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1858 static void php_pqconn_notice_recv(void *p
, const PGresult
*res
)
1860 php_pqconn_event_data_t
*data
= p
;
1866 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("notice"), (void *) &evhs
)) {
1867 zval
*args
, *connection
= NULL
;
1869 MAKE_STD_ZVAL(args
);
1871 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1872 add_next_index_zval(args
, connection
);
1873 add_next_index_string(args
, PHP_PQresultErrorMessage(res
), 1);
1874 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1875 zval_ptr_dtor(&args
);
1880 typedef struct php_pqconn_resource_factory_data
{
1883 } php_pqconn_resource_factory_data_t
;
1885 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
1887 php_pqconn_resource_factory_data_t
*o
= init_arg
;
1888 PGconn
*conn
= NULL
;;
1890 if (o
->flags
& PHP_PQCONN_ASYNC
) {
1891 conn
= PQconnectStart(o
->dsn
);
1893 conn
= PQconnectdb(o
->dsn
);
1897 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
1903 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
1905 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
1907 /* we don't care for anything, except free'ing evdata */
1909 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
1910 memset(evdata
, 0, sizeof(*evdata
));
1917 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
1918 php_pqconn_resource_factory_ctor
,
1920 php_pqconn_resource_factory_dtor
1923 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1925 // FIXME: ping server
1928 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1930 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
1931 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1);
1933 if (quoted_channel
) {
1937 spprintf(&cmd
, 0, "UNLISTEN %s", quoted_channel
);
1938 if ((res
= PQexec(obj
->intern
->conn
, cmd
))) {
1943 PQfreemem(quoted_channel
);
1946 return ZEND_HASH_APPLY_REMOVE
;
1949 static void php_pqconn_notice_ignore(void *p
, const PGresult
*res
)
1953 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1955 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
1960 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
1962 /* ignore notices */
1963 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
1965 /* cancel async queries */
1966 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
1967 char err
[256] = {0};
1969 PQcancel(cancel
, err
, sizeof(err
));
1970 PQfreeCancel(cancel
);
1972 /* clean up async results */
1973 while ((res
= PQgetResult(*handle
))) {
1977 /* clean up transaction & session */
1978 switch (PQtransactionStatus(*handle
)) {
1980 res
= PQexec(*handle
, "RESET ALL");
1983 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
1992 /* clean up notify listeners */
1993 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
1995 /* release instance data */
1996 memset(evdata
, 0, sizeof(*evdata
));
2001 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
2002 ZEND_ARG_INFO(0, dsn
)
2003 ZEND_ARG_INFO(0, async
)
2004 ZEND_END_ARG_INFO();
2005 static PHP_METHOD(pqconn
, __construct
) {
2006 zend_error_handling zeh
;
2012 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2013 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
);
2014 zend_restore_error_handling(&zeh TSRMLS_CC
);
2016 if (SUCCESS
== rv
) {
2017 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2020 throw_exce(EX_BAD_METHODCALL TSRMLS_CC
, "pq\\Connection already initialized");
2022 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
2023 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
2025 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
2027 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
2028 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
2030 if (flags
& PHP_PQCONN_PERSISTENT
) {
2031 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
);
2032 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
2034 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
2037 if (flags
& PHP_PQCONN_ASYNC
) {
2038 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
2041 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
2043 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
2044 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
2046 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
2047 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2053 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
2054 ZEND_END_ARG_INFO();
2055 static PHP_METHOD(pqconn
, reset
) {
2056 zend_error_handling zeh
;
2059 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2060 rv
= zend_parse_parameters_none();
2061 zend_restore_error_handling(&zeh TSRMLS_CC
);
2063 if (SUCCESS
== rv
) {
2064 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2067 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2069 PQreset(obj
->intern
->conn
);
2071 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
2072 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2075 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2080 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
2081 ZEND_END_ARG_INFO();
2082 static PHP_METHOD(pqconn
, resetAsync
) {
2083 zend_error_handling zeh
;
2086 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2087 rv
= zend_parse_parameters_none();
2088 zend_restore_error_handling(&zeh TSRMLS_CC
);
2090 if (SUCCESS
== rv
) {
2091 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2094 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2096 if (!PQresetStart(obj
->intern
->conn
)) {
2097 throw_exce(EX_IO TSRMLS_CC
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2099 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
2102 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2107 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
)
2109 HashTable ht
, *existing_listeners
;
2111 php_pq_callback_addref(listener
);
2113 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
2114 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
2116 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
2117 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
2118 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
2122 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
2123 ZEND_ARG_INFO(0, channel
)
2124 ZEND_ARG_INFO(0, callable
)
2125 ZEND_END_ARG_INFO();
2126 static PHP_METHOD(pqconn
, listen
) {
2127 zend_error_handling zeh
;
2128 char *channel_str
= NULL
;
2129 int channel_len
= 0;
2130 php_pq_callback_t listener
;
2133 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2134 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2135 zend_restore_error_handling(&zeh TSRMLS_CC
);
2137 if (SUCCESS
== rv
) {
2138 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2141 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2143 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2145 if (!quoted_channel
) {
2146 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2149 smart_str cmd
= {0};
2151 smart_str_appends(&cmd
, "LISTEN ");
2152 smart_str_appends(&cmd
, quoted_channel
);
2155 res
= PQexec(obj
->intern
->conn
, cmd
.c
);
2157 smart_str_free(&cmd
);
2158 PQfreemem(quoted_channel
);
2161 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2163 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2164 obj
->intern
->poller
= PQconsumeInput
;
2165 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2170 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2176 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
2177 ZEND_ARG_INFO(0, channel
)
2178 ZEND_ARG_INFO(0, callable
)
2179 ZEND_END_ARG_INFO();
2180 static PHP_METHOD(pqconn
, listenAsync
) {
2181 zend_error_handling zeh
;
2182 char *channel_str
= NULL
;
2183 int channel_len
= 0;
2184 php_pq_callback_t listener
;
2187 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2188 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2189 zend_restore_error_handling(&zeh TSRMLS_CC
);
2191 if (SUCCESS
== rv
) {
2192 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2195 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2197 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2199 if (!quoted_channel
) {
2200 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2202 smart_str cmd
= {0};
2204 smart_str_appends(&cmd
, "LISTEN ");
2205 smart_str_appends(&cmd
, quoted_channel
);
2208 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
2209 throw_exce(EX_IO TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2211 obj
->intern
->poller
= PQconsumeInput
;
2212 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2215 smart_str_free(&cmd
);
2216 PQfreemem(quoted_channel
);
2217 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2223 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
2224 ZEND_ARG_INFO(0, channel
)
2225 ZEND_ARG_INFO(0, message
)
2226 ZEND_END_ARG_INFO();
2227 static PHP_METHOD(pqconn
, notify
) {
2228 zend_error_handling zeh
;
2229 char *channel_str
, *message_str
;
2230 int channel_len
, message_len
;
2233 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2234 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2235 zend_restore_error_handling(&zeh TSRMLS_CC
);
2237 if (SUCCESS
== rv
) {
2238 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2241 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2244 char *params
[2] = {channel_str
, message_str
};
2246 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
2249 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2251 php_pqres_success(res TSRMLS_CC
);
2255 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2260 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
2261 ZEND_ARG_INFO(0, channel
)
2262 ZEND_ARG_INFO(0, message
)
2263 ZEND_END_ARG_INFO();
2264 static PHP_METHOD(pqconn
, notifyAsync
) {
2265 zend_error_handling zeh
;
2266 char *channel_str
, *message_str
;
2267 int channel_len
, message_len
;
2270 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2271 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2272 zend_restore_error_handling(&zeh TSRMLS_CC
);
2274 if (SUCCESS
== rv
) {
2275 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2278 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2280 char *params
[2] = {channel_str
, message_str
};
2282 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
2283 throw_exce(EX_IO TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2285 obj
->intern
->poller
= PQconsumeInput
;
2288 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2293 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
2294 ZEND_END_ARG_INFO();
2295 static PHP_METHOD(pqconn
, poll
) {
2296 zend_error_handling zeh
;
2299 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2300 rv
= zend_parse_parameters_none();
2301 zend_restore_error_handling(&zeh TSRMLS_CC
);
2303 if (SUCCESS
== rv
) {
2304 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2307 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2308 } else if (!obj
->intern
->poller
) {
2309 throw_exce(EX_RUNTIME TSRMLS_CC
, "No asynchronous operation active");
2311 if (obj
->intern
->poller
== PQconsumeInput
) {
2312 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
2314 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
2316 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2321 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
2322 ZEND_ARG_INFO(0, query
)
2323 ZEND_END_ARG_INFO();
2324 static PHP_METHOD(pqconn
, exec
) {
2325 zend_error_handling zeh
;
2330 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2331 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
);
2332 zend_restore_error_handling(&zeh TSRMLS_CC
);
2334 if (SUCCESS
== rv
) {
2335 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2338 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2340 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
2343 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2344 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2345 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2350 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2355 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
2356 ZEND_END_ARG_INFO();
2357 static PHP_METHOD(pqconn
, getResult
) {
2358 zend_error_handling zeh
;
2361 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2362 rv
= zend_parse_parameters_none();
2363 zend_restore_error_handling(&zeh TSRMLS_CC
);
2365 if (SUCCESS
== rv
) {
2366 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2369 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2371 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
2376 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2379 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2384 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
2385 ZEND_ARG_INFO(0, query
)
2386 ZEND_ARG_INFO(0, callable
)
2387 ZEND_END_ARG_INFO();
2388 static PHP_METHOD(pqconn
, execAsync
) {
2389 zend_error_handling zeh
;
2390 php_pq_callback_t resolver
= {{0}};
2395 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2396 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
2397 zend_restore_error_handling(&zeh TSRMLS_CC
);
2399 if (SUCCESS
== rv
) {
2400 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2403 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2404 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
2405 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2406 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2407 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2409 obj
->intern
->poller
= PQconsumeInput
;
2410 php_pq_callback_dtor(&obj
->intern
->onevent
);
2411 if (resolver
.fci
.size
> 0) {
2412 obj
->intern
->onevent
= resolver
;
2413 php_pq_callback_addref(&obj
->intern
->onevent
);
2415 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2420 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
2425 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
2426 convert_to_long_ex(ztype
);
2429 **types
= Z_LVAL_PP(ztype
);
2432 if (*ztype
!= *(zval
**)p
) {
2433 zval_ptr_dtor(ztype
);
2435 return ZEND_HASH_APPLY_KEEP
;
2438 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
2444 params
= (char ***) va_arg(argv
, char ***);
2445 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
2447 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
2451 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
2452 convert_to_string_ex(zparam
);
2455 **params
= Z_STRVAL_PP(zparam
);
2458 if (*zparam
!= *(zval
**)p
) {
2459 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
2462 return ZEND_HASH_APPLY_KEEP
;
2465 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
2467 int count
= zend_hash_num_elements(ht
);
2474 /* +1 for when less types than params are specified */
2475 *types
= tmp
= ecalloc(count
+ 1, sizeof(**types
));
2476 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
2482 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
2484 int count
= zend_hash_num_elements(ht
);
2491 *params
= tmp
= ecalloc(count
, sizeof(char *));
2492 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
2498 static Oid *php_pq_ntypes_to_array(zend_bool fill, int argc, ...)
2501 Oid *oids = ecalloc(argc + 1, sizeof(*oids));
2504 va_start(argv, argc);
2505 for (i = 0; i < argc; ++i) {
2507 oids[i] = va_arg(argv, Oid);
2517 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
2518 ZEND_ARG_INFO(0, query
)
2519 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2520 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2521 ZEND_END_ARG_INFO();
2522 static PHP_METHOD(pqconn
, execParams
) {
2523 zend_error_handling zeh
;
2527 zval
*ztypes
= NULL
;
2530 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2531 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
2532 zend_restore_error_handling(&zeh TSRMLS_CC
);
2534 if (SUCCESS
== rv
) {
2535 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2538 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2543 char **params
= NULL
;
2546 ZEND_INIT_SYMTABLE(&zdtor
);
2547 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2550 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2553 res
= PQexecParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
2555 zend_hash_destroy(&zdtor
);
2564 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2566 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2567 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2572 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2578 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
2579 ZEND_ARG_INFO(0, query
)
2580 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2581 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2582 ZEND_ARG_INFO(0, callable
)
2583 ZEND_END_ARG_INFO();
2584 static PHP_METHOD(pqconn
, execParamsAsync
) {
2585 zend_error_handling zeh
;
2586 php_pq_callback_t resolver
= {{0}};
2590 zval
*ztypes
= NULL
;
2593 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2594 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
2595 zend_restore_error_handling(&zeh TSRMLS_CC
);
2597 if (SUCCESS
== rv
) {
2598 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2601 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2605 char **params
= NULL
;
2608 ZEND_INIT_SYMTABLE(&zdtor
);
2609 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2612 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2615 if (!PQsendQueryParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
2616 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2617 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2618 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2620 obj
->intern
->poller
= PQconsumeInput
;
2621 php_pq_callback_dtor(&obj
->intern
->onevent
);
2622 if (resolver
.fci
.size
> 0) {
2623 obj
->intern
->onevent
= resolver
;
2624 php_pq_callback_addref(&obj
->intern
->onevent
);
2626 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2629 zend_hash_destroy(&zdtor
);
2638 zend_restore_error_handling(&zeh TSRMLS_CC
);
2641 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2649 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2653 count
= zend_hash_num_elements(typest
);
2654 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2657 res
= PQprepare(obj
->intern
->conn
, name
, query
, count
, types
);
2665 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2667 rv
= php_pqres_success(res TSRMLS_CC
);
2669 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2675 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
2676 ZEND_ARG_INFO(0, type
)
2677 ZEND_ARG_INFO(0, query
)
2678 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2679 ZEND_END_ARG_INFO();
2680 static PHP_METHOD(pqconn
, prepare
) {
2681 zend_error_handling zeh
;
2682 zval
*ztypes
= NULL
;
2683 char *name_str
, *query_str
;
2684 int name_len
, *query_len
;
2687 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2688 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2689 zend_restore_error_handling(&zeh TSRMLS_CC
);
2691 if (SUCCESS
== rv
) {
2692 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2695 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2696 } else if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2697 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2699 php_pq_object_addref(obj TSRMLS_CC
);
2701 stm
->name
= estrdup(name_str
);
2702 ZEND_INIT_SYMTABLE(&stm
->bound
);
2704 return_value
->type
= IS_OBJECT
;
2705 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2710 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2717 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2721 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2724 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, count
, types
)) {
2726 throw_exce(EX_IO TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2727 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2729 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2732 obj
->intern
->poller
= PQconsumeInput
;
2733 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2743 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
2744 ZEND_ARG_INFO(0, type
)
2745 ZEND_ARG_INFO(0, query
)
2746 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2747 ZEND_END_ARG_INFO();
2748 static PHP_METHOD(pqconn
, prepareAsync
) {
2749 zend_error_handling zeh
;
2750 zval
*ztypes
= NULL
;
2751 char *name_str
, *query_str
;
2752 int name_len
, *query_len
;
2755 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2756 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2757 zend_restore_error_handling(&zeh TSRMLS_CC
);
2759 if (SUCCESS
== rv
) {
2760 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2763 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2764 } else if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2765 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2767 php_pq_object_addref(obj TSRMLS_CC
);
2769 stm
->name
= estrdup(name_str
);
2770 ZEND_INIT_SYMTABLE(&stm
->bound
);
2772 return_value
->type
= IS_OBJECT
;
2773 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2778 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
2779 ZEND_ARG_INFO(0, string
)
2780 ZEND_END_ARG_INFO();
2781 static PHP_METHOD(pqconn
, quote
) {
2785 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2786 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2789 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2791 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
2794 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2797 RETVAL_STRING(quoted
, 1);
2804 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
2805 ZEND_ARG_INFO(0, type
)
2806 ZEND_END_ARG_INFO();
2807 static PHP_METHOD(pqconn
, quoteName
) {
2811 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2812 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2815 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2817 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
2820 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2823 RETVAL_STRING(quoted
, 1);
2830 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
2831 ZEND_ARG_INFO(0, bytea
)
2832 ZEND_END_ARG_INFO();
2833 static PHP_METHOD(pqconn
, escapeBytea
) {
2837 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2838 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2841 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2844 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
2847 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2850 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
2851 PQfreemem(escaped_str
);
2857 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
2858 ZEND_ARG_INFO(0, bytea
)
2859 ZEND_END_ARG_INFO();
2860 static PHP_METHOD(pqconn
, unescapeBytea
) {
2864 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2865 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2868 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2870 size_t unescaped_len
;
2871 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
2873 if (!unescaped_str
) {
2874 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2877 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
2878 PQfreemem(unescaped_str
);
2884 static const char *isolation_level(long *isolation
) {
2885 switch (*isolation
) {
2886 case PHP_PQTXN_SERIALIZABLE
:
2887 return "SERIALIZABLE";
2888 case PHP_PQTXN_REPEATABLE_READ
:
2889 return "REPEATABLE READ";
2891 *isolation
= PHP_PQTXN_READ_COMMITTED
;
2893 case PHP_PQTXN_READ_COMMITTED
:
2894 return "READ COMMITTED";
2898 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2900 STATUS rv
= FAILURE
;
2903 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2906 if (!conn_obj
->intern
) {
2907 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2910 smart_str cmd
= {0};
2911 const char *il
= isolation_level(&isolation
);
2913 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2914 smart_str_appends(&cmd
, il
);
2915 smart_str_appends(&cmd
, ", READ ");
2916 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2917 smart_str_appends(&cmd
, ",");
2918 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
2919 smart_str_appends(&cmd
, " DEFERRABLE");
2922 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
2925 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2927 rv
= php_pqres_success(res TSRMLS_CC
);
2929 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2932 smart_str_free(&cmd
);
2938 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
)
2940 STATUS rv
= FAILURE
;
2943 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2946 if (!conn_obj
->intern
) {
2947 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2949 smart_str cmd
= {0};
2950 const char *il
= isolation_level(&isolation
);
2952 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2953 smart_str_appends(&cmd
, il
);
2954 smart_str_appends(&cmd
, ", READ ");
2955 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2956 smart_str_appends(&cmd
, ",");
2957 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
2958 smart_str_appends(&cmd
, " DEFERRABLE");
2961 if (!PQsendQuery(conn_obj
->intern
->conn
, cmd
.c
)) {
2962 throw_exce(EX_IO TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2965 conn_obj
->intern
->poller
= PQconsumeInput
;
2966 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2969 smart_str_free(&cmd
);
2975 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
2976 ZEND_ARG_INFO(0, isolation
)
2977 ZEND_ARG_INFO(0, readonly
)
2978 ZEND_ARG_INFO(0, deferrable
)
2979 ZEND_END_ARG_INFO();
2980 static PHP_METHOD(pqconn
, startTransaction
) {
2981 zend_error_handling zeh
;
2982 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2983 zend_bool readonly
= 0, deferrable
= 0;
2986 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2987 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
2988 zend_restore_error_handling(&zeh TSRMLS_CC
);
2990 if (SUCCESS
== rv
) {
2991 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2993 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2995 if (SUCCESS
== rv
) {
2996 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2998 php_pq_object_addref(obj TSRMLS_CC
);
3001 txn
->isolation
= isolation
;
3002 txn
->readonly
= readonly
;
3003 txn
->deferrable
= deferrable
;
3005 return_value
->type
= IS_OBJECT
;
3006 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3011 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
3012 ZEND_ARG_INFO(0, isolation
)
3013 ZEND_ARG_INFO(0, readonly
)
3014 ZEND_ARG_INFO(0, deferrable
)
3015 ZEND_END_ARG_INFO();
3016 static PHP_METHOD(pqconn
, startTransactionAsync
) {
3017 zend_error_handling zeh
;
3018 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3019 zend_bool readonly
= 0, deferrable
= 0;
3022 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3023 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
3024 zend_restore_error_handling(&zeh TSRMLS_CC
);
3025 if (SUCCESS
== rv
) {
3026 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3028 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3030 if (SUCCESS
== rv
) {
3031 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
3033 php_pq_object_addref(obj TSRMLS_CC
);
3035 txn
->isolation
= isolation
;
3036 txn
->readonly
= readonly
;
3037 txn
->deferrable
= deferrable
;
3039 return_value
->type
= IS_OBJECT
;
3040 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3045 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
3046 ZEND_ARG_INFO(0, stdio_stream
)
3047 ZEND_END_ARG_INFO();
3048 static PHP_METHOD(pqconn
, trace
) {
3049 zval
*zstream
= NULL
;
3051 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
3052 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3055 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3058 PQuntrace(obj
->intern
->conn
);
3062 php_stream
*stream
= NULL
;
3064 php_stream_from_zval(stream
, &zstream
);
3066 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
3069 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
3070 PQtrace(obj
->intern
->conn
, fp
);
3078 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on
, 0, 0, 2)
3079 ZEND_ARG_INFO(0, type
)
3080 ZEND_ARG_INFO(0, callable
)
3081 ZEND_END_ARG_INFO();
3082 static PHP_METHOD(pqconn
, on
) {
3083 zend_error_handling zeh
;
3086 php_pq_callback_t cb
;
3089 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3090 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
3091 zend_restore_error_handling(&zeh TSRMLS_CC
);
3093 if (SUCCESS
== rv
) {
3094 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3097 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3099 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3101 RETVAL_LONG(php_pqconn_add_eventhandler(obj
, type_str
, type_len
, &cb TSRMLS_CC
));
3106 static zend_function_entry php_pqconn_methods
[] = {
3107 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3108 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
3109 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
3110 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
3111 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
3112 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
3113 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
3114 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
3115 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
3116 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
3117 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
3118 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
3119 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
3120 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
3121 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
3122 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
3123 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
3124 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
3125 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
3126 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
3127 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
3128 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
3129 PHP_ME(pqconn
, on
, ai_pqconn_on
, ZEND_ACC_PUBLIC
)
3133 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct
, 0, 0, 1)
3134 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3135 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3136 ZEND_END_ARG_INFO();
3137 static PHP_METHOD(pqtypes
, __construct
) {
3138 zend_error_handling zeh
;
3139 zval
*zconn
, *znsp
= NULL
;
3142 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3143 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|a!", &zconn
, php_pqconn_class_entry
, &znsp
);
3144 zend_restore_error_handling(&zeh TSRMLS_CC
);
3146 if (SUCCESS
== rv
) {
3147 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3149 if (!conn_obj
->intern
) {
3150 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3152 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3153 zval
*retval
= NULL
;
3155 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3156 obj
->intern
->conn
= conn_obj
;
3157 php_pq_object_addref(conn_obj TSRMLS_CC
);
3158 zend_hash_init(&obj
->intern
->types
, 300, NULL
, ZVAL_PTR_DTOR
, 0);
3161 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
, znsp
);
3163 zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
);
3167 zval_ptr_dtor(&retval
);
3173 #define PHP_PQ_TYPES_QUERY \
3174 "select t.oid, t.* " \
3175 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
3176 "where typisdefined " \
3178 #define PHP_PQ_OID_TEXT 25
3180 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh
, 0, 0, 0)
3181 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3182 ZEND_END_ARG_INFO();
3183 static PHP_METHOD(pqtypes
, refresh
) {
3184 HashTable
*nsp
= NULL
;
3185 zend_error_handling zeh
;
3188 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3189 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|H/!", &nsp
);
3190 zend_restore_error_handling(&zeh TSRMLS_CC
);
3192 if (SUCCESS
== rv
) {
3193 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3196 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Types not initialized");
3200 if (!nsp
|| !zend_hash_num_elements(nsp
)) {
3201 res
= PQexec(obj
->intern
->conn
->intern
->conn
, PHP_PQ_TYPES_QUERY
" and nspname in ('public', 'pg_catalog')");
3205 char **params
= NULL
;
3207 smart_str str
= {0};
3209 smart_str_appends(&str
, PHP_PQ_TYPES_QUERY
" and nspname in(");
3210 zend_hash_init(&zdtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
3211 count
= php_pq_params_to_array(nsp
, ¶ms
, &zdtor TSRMLS_CC
);
3212 oids
= ecalloc(count
+ 1, sizeof(*oids
));
3213 for (i
= 0; i
< count
; ++i
) {
3214 oids
[i
] = PHP_PQ_OID_TEXT
;
3216 smart_str_appendc(&str
, ',');
3218 smart_str_appendc(&str
, '$');
3219 smart_str_append_unsigned(&str
, i
+1);
3221 smart_str_appendc(&str
, ')');
3224 res
= PQexecParams(obj
->intern
->conn
->intern
->conn
, str
.c
, count
, oids
, (const char *const*) params
, NULL
, NULL
, 0);
3226 smart_str_free(&str
);
3229 zend_hash_destroy(&zdtor
);
3233 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3235 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3238 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
3239 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT
, NULL TSRMLS_CC
);
3240 long oid
= atol(PQgetvalue(res
, r
, 0 ));
3241 char *name
= PQgetvalue(res
, r
, 1);
3245 zend_hash_index_update(&obj
->intern
->types
, oid
, (void *) &row
, sizeof(zval
*), NULL
);
3246 zend_hash_add(&obj
->intern
->types
, name
, strlen(name
) + 1, (void *) &row
, sizeof(zval
*), NULL
);
3251 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3257 static zend_function_entry php_pqtypes_methods
[] = {
3258 PHP_ME(pqtypes
, __construct
, ai_pqtypes_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3259 PHP_ME(pqtypes
, refresh
, ai_pqtypes_refresh
, ZEND_ACC_PUBLIC
)
3263 static STATUS
php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type
, zval
***row TSRMLS_DC
)
3266 php_pqres_fetch_t orig_fetch
;
3269 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3272 if (obj
->intern
->iter
) {
3273 obj
->intern
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3275 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
3276 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3278 orig_fetch
= obj
->intern
->iter
->fetch_type
;
3279 obj
->intern
->iter
->fetch_type
= fetch_type
;
3280 if (SUCCESS
== (rv
= obj
->intern
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
))) {
3281 obj
->intern
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->intern
->iter
, row TSRMLS_CC
);
3283 obj
->intern
->iter
->fetch_type
= orig_fetch
;
3288 typedef struct php_pqres_col
{
3293 static STATUS
column_nn(php_pqres_object_t
*obj
, zval
*zcol
, php_pqres_col_t
*col TSRMLS_DC
)
3298 switch (Z_TYPE_P(zcol
)) {
3300 convert_to_string(zcol
);
3304 if (!is_numeric_string(Z_STRVAL_P(zcol
), Z_STRLEN_P(zcol
), &index
, NULL
, 0)) {
3305 name
= Z_STRVAL_P(zcol
);
3310 index
= Z_LVAL_P(zcol
);
3316 col
->num
= PQfnumber(obj
->intern
->res
, name
);
3318 col
->name
= PQfname(obj
->intern
->res
, index
);
3323 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column at index %ld", index
);
3326 if (col
->num
== -1) {
3327 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column with name '%s'", name
);
3333 static int compare_index(const void *lptr
, const void *rptr TSRMLS_DC
)
3335 const Bucket
*l
= *(const Bucket
**) lptr
;
3336 const Bucket
*r
= *(const Bucket
**) rptr
;
3347 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind
, 0, 0, 2)
3348 ZEND_ARG_INFO(0, col
)
3349 ZEND_ARG_INFO(1, ref
)
3350 ZEND_END_ARG_INFO();
3351 static PHP_METHOD(pqres
, bind
) {
3354 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z/z", &zcol
, &zref
)) {
3355 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3358 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3360 php_pqres_col_t col
;
3362 if (SUCCESS
!= column_nn(obj
, zcol
, &col TSRMLS_CC
)) {
3367 if (SUCCESS
!= zend_hash_index_update(&obj
->intern
->bound
, col
.num
, (void *) &zref
, sizeof(zval
*), NULL
)) {
3368 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to bind column %s@%d", col
.name
, col
.num
);
3371 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3379 static int apply_bound(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3381 zval
**zvalue
, **zbound
= p
;
3382 zval
**zrow
= va_arg(argv
, zval
**);
3383 STATUS
*rv
= va_arg(argv
, STATUS
*);
3385 if (SUCCESS
!= zend_hash_index_find(Z_ARRVAL_PP(zrow
), key
->h
, (void *) &zvalue
)) {
3386 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column ad index %lu", key
->h
);
3388 return ZEND_HASH_APPLY_STOP
;
3391 ZVAL_COPY_VALUE(*zbound
, *zvalue
);
3393 zval_ptr_dtor(zvalue
);
3394 Z_ADDREF_P(*zbound
);
3397 return ZEND_HASH_APPLY_KEEP
;
3401 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound
, 0, 0, 0)
3402 ZEND_END_ARG_INFO();
3403 static PHP_METHOD(pqres
, fetchBound
) {
3404 zend_error_handling zeh
;
3407 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3408 rv
= zend_parse_parameters_none();
3409 zend_restore_error_handling(&zeh TSRMLS_CC
);
3411 if (SUCCESS
== rv
) {
3412 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3415 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3419 if (SUCCESS
== php_pqres_iteration(getThis(), obj
, PHP_PQRES_FETCH_ARRAY
, &row TSRMLS_CC
) && row
) {
3420 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3421 zend_hash_apply_with_arguments(&obj
->intern
->bound TSRMLS_CC
, apply_bound
, 2, row
, &rv
);
3422 zend_restore_error_handling(&zeh TSRMLS_CC
);
3424 if (SUCCESS
!= rv
) {
3427 RETVAL_ZVAL(*row
, 1, 0);
3434 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
3435 ZEND_ARG_INFO(0, fetch_type
)
3436 ZEND_END_ARG_INFO();
3437 static PHP_METHOD(pqres
, fetchRow
) {
3438 zend_error_handling zeh
;
3439 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3440 long fetch_type
= -1;
3443 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3444 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3445 zend_restore_error_handling(&zeh TSRMLS_CC
);
3447 if (SUCCESS
== rv
) {
3449 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3453 if (fetch_type
== -1) {
3454 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3457 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3458 php_pqres_iteration(getThis(), obj
, fetch_type
, &row TSRMLS_CC
);
3459 zend_restore_error_handling(&zeh TSRMLS_CC
);
3462 RETVAL_ZVAL(*row
, 1, 0);
3468 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
3471 HashTable
*ht
= HASH_OF(row
);
3472 int count
= zend_hash_num_elements(ht
);
3475 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
3477 zend_hash_internal_pointer_reset(ht
);
3479 zend_hash_move_forward(ht
);
3481 zend_hash_get_current_data(ht
, (void *) &data
);
3486 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
3487 ZEND_ARG_INFO(0, col_num
)
3488 ZEND_END_ARG_INFO();
3489 static PHP_METHOD(pqres
, fetchCol
) {
3490 zend_error_handling zeh
;
3494 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3495 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
);
3496 zend_restore_error_handling(&zeh TSRMLS_CC
);
3498 if (SUCCESS
== rv
) {
3499 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3502 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3506 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3507 php_pqres_iteration(getThis(), obj
, obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: 0, &row TSRMLS_CC
);
3509 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
3512 RETVAL_ZVAL(*col
, 1, 0);
3515 zend_restore_error_handling(&zeh TSRMLS_CC
);
3520 static int apply_to_col(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3523 php_pqres_object_t
*obj
= va_arg(argv
, php_pqres_object_t
*);
3524 php_pqres_col_t
*col
, **cols
= va_arg(argv
, php_pqres_col_t
**);
3525 STATUS
*rv
= va_arg(argv
, STATUS
*);
3529 if (SUCCESS
!= column_nn(obj
, *c
, col TSRMLS_CC
)) {
3531 return ZEND_HASH_APPLY_STOP
;
3535 return ZEND_HASH_APPLY_KEEP
;
3539 static php_pqres_col_t
*php_pqres_convert_to_cols(php_pqres_object_t
*obj
, HashTable
*ht TSRMLS_DC
)
3541 php_pqres_col_t
*tmp
, *cols
= ecalloc(zend_hash_num_elements(ht
), sizeof(*cols
));
3542 STATUS rv
= SUCCESS
;
3545 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_col
, 2, obj
, &tmp
, &rv
);
3547 if (SUCCESS
== rv
) {
3555 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map
, 0, 0, 0)
3556 ZEND_ARG_INFO(0, keys
)
3557 ZEND_ARG_INFO(0, vals
)
3558 ZEND_ARG_INFO(0, fetch_type
)
3559 ZEND_END_ARG_INFO();
3560 static PHP_METHOD(pqres
, map
) {
3561 zend_error_handling zeh
;
3562 zval
*zkeys
= 0, *zvals
= 0;
3563 long fetch_type
= -1;
3566 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3567 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z/!z/!l", &zkeys
, &zvals
, &fetch_type
);
3568 zend_restore_error_handling(&zeh TSRMLS_CC
);
3570 if (SUCCESS
== rv
) {
3571 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3574 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3577 php_pqres_col_t def
= {PQfname(obj
->intern
->res
, 0), 0}, *keys
= NULL
, *vals
= NULL
;
3580 convert_to_array(zkeys
);
3582 if ((ks
= zend_hash_num_elements(Z_ARRVAL_P(zkeys
)))) {
3583 keys
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zkeys
) TSRMLS_CC
);
3593 convert_to_array(zvals
);
3595 if ((vs
= zend_hash_num_elements(Z_ARRVAL_P(zvals
)))) {
3596 vals
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zvals
) TSRMLS_CC
);
3600 if (fetch_type
== -1) {
3601 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3608 switch (fetch_type
) {
3609 case PHP_PQRES_FETCH_ARRAY
:
3610 case PHP_PQRES_FETCH_ASSOC
:
3611 array_init(return_value
);
3613 case PHP_PQRES_FETCH_OBJECT
:
3614 object_init(return_value
);
3617 for (r
= 0, rows
= PQntuples(obj
->intern
->res
); r
< rows
; ++r
) {
3620 cur
= &return_value
;
3621 for (k
= 0; k
< ks
; ++k
) {
3622 char *key
= PQgetvalue(obj
->intern
->res
, r
, keys
[k
].num
);
3623 int len
= PQgetlength(obj
->intern
->res
, r
, keys
[k
].num
);
3625 if (SUCCESS
!= zend_symtable_find(HASH_OF(*cur
), key
, len
+ 1, (void *) &cur
)) {
3629 switch (fetch_type
) {
3630 case PHP_PQRES_FETCH_ARRAY
:
3631 case PHP_PQRES_FETCH_ASSOC
:
3634 case PHP_PQRES_FETCH_OBJECT
:
3638 if (SUCCESS
!= zend_symtable_update(HASH_OF(*cur
), key
, len
+ 1, (void *) &tmp
, sizeof(zval
*), (void *) &cur
)) {
3639 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create map");
3645 for (v
= 0; v
< vs
; ++v
) {
3646 char *val
= PQgetvalue(obj
->intern
->res
, r
, vals
[v
].num
);
3647 int len
= PQgetlength(obj
->intern
->res
, r
, vals
[v
].num
);
3649 switch (fetch_type
) {
3650 case PHP_PQRES_FETCH_ARRAY
:
3651 add_index_stringl(*cur
, vals
[v
].num
, val
, len
, 1);
3653 case PHP_PQRES_FETCH_ASSOC
:
3654 add_assoc_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3656 case PHP_PQRES_FETCH_OBJECT
:
3657 add_property_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3662 php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, cur TSRMLS_CC
);
3668 if (keys
&& keys
!= &def
) {
3678 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all
, 0, 0, 0)
3679 ZEND_ARG_INFO(0, fetch_type
)
3680 ZEND_END_ARG_INFO();
3681 static PHP_METHOD(pqres
, fetchAll
) {
3682 zend_error_handling zeh
;
3683 long fetch_type
= -1;
3686 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3687 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3688 zend_restore_error_handling(&zeh TSRMLS_CC
);
3690 if (SUCCESS
== rv
) {
3691 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3693 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3695 int r
, rows
= PQntuples(obj
->intern
->res
);
3697 if (fetch_type
== -1) {
3698 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3701 array_init(return_value
);
3702 for (r
= 0; r
< rows
; ++r
) {
3703 add_next_index_zval(return_value
, php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, NULL TSRMLS_CC
));
3709 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count
, 0, 0, 0)
3710 ZEND_END_ARG_INFO();
3711 static PHP_METHOD(pqres
, count
) {
3712 if (SUCCESS
== zend_parse_parameters_none()) {
3715 if (SUCCESS
!= php_pqres_count_elements(getThis(), &count TSRMLS_CC
)) {
3716 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3723 static zend_function_entry php_pqres_methods
[] = {
3724 PHP_ME(pqres
, bind
, ai_pqres_bind
, ZEND_ACC_PUBLIC
)
3725 PHP_ME(pqres
, fetchBound
, ai_pqres_fetch_bound
, ZEND_ACC_PUBLIC
)
3726 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
3727 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
3728 PHP_ME(pqres
, fetchAll
, ai_pqres_fetch_all
, ZEND_ACC_PUBLIC
)
3729 PHP_ME(pqres
, count
, ai_pqres_count
, ZEND_ACC_PUBLIC
)
3730 PHP_ME(pqres
, map
, ai_pqres_map
, ZEND_ACC_PUBLIC
)
3734 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
3735 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
3736 ZEND_ARG_INFO(0, type
)
3737 ZEND_ARG_INFO(0, query
)
3738 ZEND_ARG_ARRAY_INFO(0, types
, 1)
3739 ZEND_ARG_INFO(0, async
)
3740 ZEND_END_ARG_INFO();
3741 static PHP_METHOD(pqstm
, __construct
) {
3742 zend_error_handling zeh
;
3743 zval
*zconn
, *ztypes
= NULL
;
3744 char *name_str
, *query_str
;
3745 int name_len
, *query_len
;
3746 zend_bool async
= 0;
3749 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3750 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
);
3751 zend_restore_error_handling(&zeh TSRMLS_CC
);
3753 if (SUCCESS
== rv
) {
3754 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3755 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3757 if (!conn_obj
->intern
) {
3758 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3761 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3763 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3766 if (SUCCESS
== rv
) {
3767 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
3769 php_pq_object_addref(conn_obj TSRMLS_CC
);
3770 stm
->conn
= conn_obj
;
3771 stm
->name
= estrdup(name_str
);
3772 ZEND_INIT_SYMTABLE(&stm
->bound
);
3778 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind
, 0, 0, 2)
3779 ZEND_ARG_INFO(0, param_no
)
3780 ZEND_ARG_INFO(1, param_ref
)
3781 ZEND_END_ARG_INFO();
3782 static PHP_METHOD(pqstm
, bind
) {
3786 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "lz", ¶m_no
, ¶m_ref
)) {
3787 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3790 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3792 Z_ADDREF_P(param_ref
);
3793 zend_hash_index_update(&obj
->intern
->bound
, param_no
, (void *) ¶m_ref
, sizeof(zval
*), NULL
);
3794 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3799 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
3800 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3801 ZEND_END_ARG_INFO();
3802 static PHP_METHOD(pqstm
, exec
) {
3803 zend_error_handling zeh
;
3804 zval
*zparams
= NULL
;
3807 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3808 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
);
3809 zend_restore_error_handling(&zeh TSRMLS_CC
);
3811 if (SUCCESS
== rv
) {
3812 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3815 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3818 char **params
= NULL
;
3822 ZEND_INIT_SYMTABLE(&zdtor
);
3825 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3827 count
= php_pq_params_to_array(&obj
->intern
->bound
, ¶ms
, &zdtor TSRMLS_CC
);
3830 res
= PQexecPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
3835 zend_hash_destroy(&zdtor
);
3838 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3839 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3840 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
3841 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3847 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
3848 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3849 ZEND_ARG_INFO(0, callable
)
3850 ZEND_END_ARG_INFO();
3851 static PHP_METHOD(pqstm
, execAsync
) {
3852 zend_error_handling zeh
;
3853 zval
*zparams
= NULL
;
3854 php_pq_callback_t resolver
= {{0}};
3857 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3858 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
);
3859 zend_restore_error_handling(&zeh TSRMLS_CC
);
3861 if (SUCCESS
== rv
) {
3862 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3865 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3868 char **params
= NULL
;
3872 ZEND_INIT_SYMTABLE(&zdtor
);
3873 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3876 if (!PQsendQueryPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
3877 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3878 } else if (obj
->intern
->conn
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
->intern
->conn
)) {
3879 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3881 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
3882 if (resolver
.fci
.size
> 0) {
3883 obj
->intern
->conn
->intern
->onevent
= resolver
;
3884 php_pq_callback_addref(&obj
->intern
->conn
->intern
->onevent
);
3886 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3893 zend_hash_destroy(&zdtor
);
3896 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3901 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
3902 ZEND_END_ARG_INFO();
3903 static PHP_METHOD(pqstm
, desc
) {
3904 zend_error_handling zeh
;
3907 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3908 rv
= zend_parse_parameters_none();
3909 zend_restore_error_handling(&zeh TSRMLS_CC
);
3911 if (SUCCESS
== rv
) {
3912 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3915 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3917 PGresult
*res
= PQdescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
);
3920 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3922 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3925 array_init(return_value
);
3926 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
3927 add_next_index_long(return_value
, PQparamtype(res
, p
));
3931 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3937 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async
, 0, 0, 0)
3938 ZEND_END_ARG_INFO();
3939 static PHP_METHOD(pqstm
, descAsync
) {
3940 zend_error_handling zeh
;
3943 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3944 rv
= zend_parse_parameters_none();
3945 zend_restore_error_handling(&zeh TSRMLS_CC
);
3947 if (SUCCESS
== rv
) {
3948 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3951 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3952 } else if (!PQsendDescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
)) {
3953 throw_exce(EX_IO TSRMLS_CC
, "Failed to describe statement: %s", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3955 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3956 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3961 static zend_function_entry php_pqstm_methods
[] = {
3962 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3963 PHP_ME(pqstm
, bind
, ai_pqstm_bind
, ZEND_ACC_PUBLIC
)
3964 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
3965 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
3966 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
3967 PHP_ME(pqstm
, descAsync
, ai_pqstm_desc_async
, ZEND_ACC_PUBLIC
)
3971 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
3972 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3973 ZEND_ARG_INFO(0, async
)
3974 ZEND_ARG_INFO(0, isolation
)
3975 ZEND_ARG_INFO(0, readonly
)
3976 ZEND_ARG_INFO(0, deferrable
)
3977 ZEND_END_ARG_INFO();
3978 static PHP_METHOD(pqtxn
, __construct
) {
3979 zend_error_handling zeh
;
3981 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3982 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
3985 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3986 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
);
3987 zend_restore_error_handling(&zeh TSRMLS_CC
);
3989 if (SUCCESS
== rv
) {
3990 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3992 if (!conn_obj
->intern
) {
3993 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3996 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3998 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
4001 if (SUCCESS
== rv
) {
4002 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4004 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4006 php_pq_object_addref(conn_obj TSRMLS_CC
);
4007 obj
->intern
->conn
= conn_obj
;
4008 obj
->intern
->open
= 1;
4009 obj
->intern
->isolation
= isolation
;
4010 obj
->intern
->readonly
= readonly
;
4011 obj
->intern
->deferrable
= deferrable
;
4017 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint
, 0, 0, 0)
4018 ZEND_END_ARG_INFO();
4019 static PHP_METHOD(pqtxn
, savepoint
) {
4020 zend_error_handling zeh
;
4023 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4024 rv
= zend_parse_parameters_none();
4025 zend_restore_error_handling(&zeh TSRMLS_CC
);
4027 if (SUCCESS
== rv
) {
4028 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4031 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4032 } else if (!obj
->intern
->open
) {
4033 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4036 smart_str cmd
= {0};
4038 smart_str_appends(&cmd
, "SAVEPOINT \"");
4039 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4040 smart_str_appends(&cmd
, "\"");
4043 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4046 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4048 php_pqres_success(res TSRMLS_CC
);
4052 smart_str_free(&cmd
);
4057 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async
, 0, 0, 0)
4058 ZEND_END_ARG_INFO();
4059 static PHP_METHOD(pqtxn
, savepointAsync
) {
4060 zend_error_handling zeh
;
4063 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4064 rv
= zend_parse_parameters_none();
4065 zend_restore_error_handling(&zeh TSRMLS_CC
);
4067 if (SUCCESS
== rv
) {
4068 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4071 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4072 } else if (!obj
->intern
->open
) {
4073 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4075 smart_str cmd
= {0};
4077 smart_str_appends(&cmd
, "SAVEPOINT \"");
4078 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4079 smart_str_appends(&cmd
, "\"");
4082 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4083 throw_exce(EX_IO TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4086 smart_str_free(&cmd
);
4091 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
4092 ZEND_END_ARG_INFO();
4093 static PHP_METHOD(pqtxn
, commit
) {
4094 zend_error_handling zeh
;
4097 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4098 rv
= zend_parse_parameters_none();
4099 zend_restore_error_handling(&zeh TSRMLS_CC
);
4101 if (SUCCESS
== rv
) {
4102 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4105 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transacation not initialized");
4106 } else if (!obj
->intern
->open
) {
4107 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transacation already closed");
4110 smart_str cmd
= {0};
4112 if (!obj
->intern
->savepoint
) {
4113 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4115 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4116 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4117 smart_str_appends(&cmd
, "\"");
4120 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4124 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4126 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4128 obj
->intern
->open
= 0;
4134 smart_str_free(&cmd
);
4135 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4140 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
4141 ZEND_END_ARG_INFO();
4142 static PHP_METHOD(pqtxn
, commitAsync
) {
4143 zend_error_handling zeh
;
4146 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4147 rv
= zend_parse_parameters_none();
4148 zend_restore_error_handling(&zeh TSRMLS_CC
);
4150 if (SUCCESS
== rv
) {
4151 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4154 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4155 } else if (!obj
->intern
->open
) {
4156 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4159 smart_str cmd
= {0};
4161 if (!obj
->intern
->savepoint
) {
4162 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4164 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4165 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4166 smart_str_appends(&cmd
, "\"");
4169 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4173 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commmit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4176 obj
->intern
->open
= 0;
4178 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4179 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4182 smart_str_free(&cmd
);
4187 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
4188 ZEND_END_ARG_INFO();
4189 static PHP_METHOD(pqtxn
, rollback
) {
4190 zend_error_handling zeh
;
4193 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4194 rv
= zend_parse_parameters_none();
4195 zend_restore_error_handling(&zeh TSRMLS_CC
);
4197 if (SUCCESS
== rv
) {
4198 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4201 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4202 } else if (!obj
->intern
->open
) {
4203 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4206 smart_str cmd
= {0};
4208 if (!obj
->intern
->savepoint
) {
4209 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4211 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4212 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4213 smart_str_appends(&cmd
, "\"");
4216 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4220 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4222 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4224 obj
->intern
->open
= 0;
4230 smart_str_free(&cmd
);
4231 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4236 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
4237 ZEND_END_ARG_INFO();
4238 static PHP_METHOD(pqtxn
, rollbackAsync
) {
4239 zend_error_handling zeh
;
4242 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4243 rv
= zend_parse_parameters_none();
4244 zend_restore_error_handling(&zeh TSRMLS_CC
);
4246 if (SUCCESS
== rv
) {
4247 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4250 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4251 } else if (!obj
->intern
->open
) {
4252 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4255 smart_str cmd
= {0};
4257 if (!obj
->intern
->savepoint
) {
4258 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4260 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4261 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4262 smart_str_appends(&cmd
, "\"");
4265 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4269 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4272 obj
->intern
->open
= 0;
4274 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4277 smart_str_free(&cmd
);
4278 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4283 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot
, 0, 0, 0)
4284 ZEND_END_ARG_INFO();
4285 static PHP_METHOD(pqtxn
, exportSnapshot
) {
4286 zend_error_handling zeh
;
4289 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4290 rv
= zend_parse_parameters_none();
4291 zend_restore_error_handling(&zeh TSRMLS_CC
);
4293 if (SUCCESS
== rv
) {
4294 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4297 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4299 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()");
4302 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4304 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4305 RETVAL_STRING(PQgetvalue(res
, 0, 0), 1);
4311 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4316 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async
, 0, 0, 0)
4317 ZEND_END_ARG_INFO();
4318 static PHP_METHOD(pqtxn
, exportSnapshotAsync
) {
4319 zend_error_handling zeh
;
4322 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4323 rv
= zend_parse_parameters_none();
4324 zend_restore_error_handling(&zeh TSRMLS_CC
);
4326 if (SUCCESS
== rv
) {
4327 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4330 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4331 } else if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()")) {
4332 throw_exce(EX_IO TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4334 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4335 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4340 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot
, 0, 0, 1)
4341 ZEND_ARG_INFO(0, snapshot_id
)
4342 ZEND_END_ARG_INFO();
4343 static PHP_METHOD(pqtxn
, importSnapshot
) {
4344 zend_error_handling zeh
;
4349 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4350 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4351 zend_restore_error_handling(&zeh TSRMLS_CC
);
4353 if (SUCCESS
== rv
) {
4354 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4357 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4358 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4359 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4361 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4364 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4367 smart_str cmd
= {0};
4369 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4370 smart_str_appends(&cmd
, sid
);
4373 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4376 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4378 php_pqres_success(res TSRMLS_CC
);
4382 smart_str_free(&cmd
);
4383 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4389 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async
, 0, 0, 1)
4390 ZEND_ARG_INFO(0, snapshot_id
)
4391 ZEND_END_ARG_INFO();
4392 static PHP_METHOD(pqtxn
, importSnapshotAsync
) {
4393 zend_error_handling zeh
;
4398 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4399 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4400 zend_restore_error_handling(&zeh TSRMLS_CC
);
4402 if (SUCCESS
== rv
) {
4403 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4406 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4407 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4408 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4410 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4413 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4415 smart_str cmd
= {0};
4417 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4418 smart_str_appends(&cmd
, sid
);
4421 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4422 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4424 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4427 smart_str_free(&cmd
);
4428 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4434 static const char *strmode(long mode
)
4436 switch (mode
& (INV_READ
|INV_WRITE
)) {
4437 case INV_READ
|INV_WRITE
:
4448 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob
, 0, 0, 1)
4449 ZEND_ARG_INFO(0, oid
)
4450 ZEND_ARG_INFO(0, mode
)
4451 ZEND_END_ARG_INFO();
4452 static PHP_METHOD(pqtxn
, openLOB
) {
4453 zend_error_handling zeh
;
4454 long mode
= INV_WRITE
|INV_READ
, loid
;
4457 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4458 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &loid
, &mode
);
4459 zend_restore_error_handling(&zeh TSRMLS_CC
);
4461 if (SUCCESS
== rv
) {
4462 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4465 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4467 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4470 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
));
4472 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4476 php_pq_object_addref(obj TSRMLS_CC
);
4479 return_value
->type
= IS_OBJECT
;
4480 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4483 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4488 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob
, 0, 0, 0)
4489 ZEND_ARG_INFO(0, mode
)
4490 ZEND_END_ARG_INFO();
4491 static PHP_METHOD(pqtxn
, createLOB
) {
4492 zend_error_handling zeh
;
4493 long mode
= INV_WRITE
|INV_READ
;
4496 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4497 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &mode
);
4498 zend_restore_error_handling(&zeh TSRMLS_CC
);
4500 if (SUCCESS
== rv
) {
4501 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4504 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4506 Oid loid
= lo_creat(obj
->intern
->conn
->intern
->conn
, mode
);
4508 if (loid
== InvalidOid
) {
4509 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create large object with mode '%s' (%s)", strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4511 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4514 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
));
4516 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4520 php_pq_object_addref(obj TSRMLS_CC
);
4523 return_value
->type
= IS_OBJECT
;
4524 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4528 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4533 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob
, 0, 0, 1)
4534 ZEND_ARG_INFO(0, oid
)
4535 ZEND_END_ARG_INFO();
4536 static PHP_METHOD(pqtxn
, unlinkLOB
) {
4537 zend_error_handling zeh
;
4541 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4542 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &loid
);
4543 zend_restore_error_handling(&zeh TSRMLS_CC
);
4545 if (SUCCESS
== rv
) {
4546 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4549 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4551 int rc
= lo_unlink(obj
->intern
->conn
->intern
->conn
, loid
);
4554 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to unlink LOB (oid=%ld): %s", loid
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4557 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4562 static zend_function_entry php_pqtxn_methods
[] = {
4563 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4564 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
4565 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
4566 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
4567 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
4568 PHP_ME(pqtxn
, savepoint
, ai_pqtxn_savepoint
, ZEND_ACC_PUBLIC
)
4569 PHP_ME(pqtxn
, savepointAsync
, ai_pqtxn_savepoint_async
, ZEND_ACC_PUBLIC
)
4570 PHP_ME(pqtxn
, exportSnapshot
, ai_pqtxn_export_snapshot
, ZEND_ACC_PUBLIC
)
4571 PHP_ME(pqtxn
, exportSnapshotAsync
, ai_pqtxn_export_snapshot_async
, ZEND_ACC_PUBLIC
)
4572 PHP_ME(pqtxn
, importSnapshot
, ai_pqtxn_import_snapshot
, ZEND_ACC_PUBLIC
)
4573 PHP_ME(pqtxn
, importSnapshotAsync
, ai_pqtxn_import_snapshot_async
, ZEND_ACC_PUBLIC
)
4574 PHP_ME(pqtxn
, openLOB
, ai_pqtxn_open_lob
, ZEND_ACC_PUBLIC
)
4575 PHP_ME(pqtxn
, createLOB
, ai_pqtxn_create_lob
, ZEND_ACC_PUBLIC
)
4576 PHP_ME(pqtxn
, unlinkLOB
, ai_pqtxn_unlink_lob
, ZEND_ACC_PUBLIC
)
4580 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
4581 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4582 ZEND_END_ARG_INFO();
4583 static PHP_METHOD(pqcancel
, __construct
) {
4584 zend_error_handling zeh
;
4588 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4589 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
);
4590 zend_restore_error_handling(&zeh TSRMLS_CC
);
4592 if (SUCCESS
== rv
) {
4593 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4595 if (!conn_obj
->intern
) {
4596 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4598 PGcancel
*cancel
= PQgetCancel(conn_obj
->intern
->conn
);
4601 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
4603 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4605 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4606 obj
->intern
->cancel
= cancel
;
4607 php_pq_object_addref(conn_obj TSRMLS_CC
);
4608 obj
->intern
->conn
= conn_obj
;
4614 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
4615 ZEND_END_ARG_INFO();
4616 static PHP_METHOD(pqcancel
, cancel
) {
4617 zend_error_handling zeh
;
4620 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4621 rv
= zend_parse_parameters_none();
4622 zend_restore_error_handling(&zeh TSRMLS_CC
);
4624 if (SUCCESS
== rv
) {
4625 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4628 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Cancel not initialized");
4630 char err
[256] = {0};
4632 if (!PQcancel(obj
->intern
->cancel
, err
, sizeof(err
))) {
4633 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to request cancellation (%s)", err
);
4639 static zend_function_entry php_pqcancel_methods
[] = {
4640 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4641 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
4645 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct
, 0, 0, 1)
4646 ZEND_ARG_OBJ_INFO(0, transaction
, pq
\\Transaction
, 0)
4647 ZEND_ARG_INFO(0, oid
)
4648 ZEND_ARG_INFO(0, mode
)
4649 ZEND_END_ARG_INFO();
4650 static PHP_METHOD(pqlob
, __construct
) {
4651 zend_error_handling zeh
;
4653 long mode
= INV_WRITE
|INV_READ
, loid
= InvalidOid
;
4656 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4657 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|ll", &ztxn
, php_pqtxn_class_entry
, &loid
, &mode
);
4658 zend_restore_error_handling(&zeh TSRMLS_CC
);
4660 if (SUCCESS
== rv
) {
4661 php_pqtxn_object_t
*txn_obj
= zend_object_store_get_object(ztxn TSRMLS_CC
);
4663 if (!txn_obj
->intern
) {
4664 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4665 } else if (!txn_obj
->intern
->open
) {
4666 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transation already closed");
4668 if (loid
== InvalidOid
) {
4669 loid
= lo_creat(txn_obj
->intern
->conn
->intern
->conn
, mode
);
4672 if (loid
== InvalidOid
) {
4673 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
));
4675 int lofd
= lo_open(txn_obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4678 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
));
4680 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4682 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4683 obj
->intern
->lofd
= lofd
;
4684 obj
->intern
->loid
= loid
;
4685 php_pq_object_addref(txn_obj TSRMLS_CC
);
4686 obj
->intern
->txn
= txn_obj
;
4690 php_pqconn_notify_listeners(txn_obj
->intern
->conn TSRMLS_CC
);
4695 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write
, 0, 0, 1)
4696 ZEND_ARG_INFO(0, data
)
4697 ZEND_END_ARG_INFO();
4698 static PHP_METHOD(pqlob
, write
) {
4699 zend_error_handling zeh
;
4704 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4705 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4706 zend_restore_error_handling(&zeh TSRMLS_CC
);
4708 if (SUCCESS
== rv
) {
4709 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4712 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4714 int written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, data_str
, data_len
);
4717 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
));
4719 RETVAL_LONG(written
);
4722 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4727 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read
, 0, 0, 0)
4728 ZEND_ARG_INFO(0, length
)
4729 ZEND_ARG_INFO(1, read
)
4730 ZEND_END_ARG_INFO();
4731 static PHP_METHOD(pqlob
, read
) {
4732 zend_error_handling zeh
;
4733 long length
= 0x1000;
4737 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4738 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lz!", &length
, &zread
);
4739 zend_restore_error_handling(&zeh TSRMLS_CC
);
4741 if (SUCCESS
== rv
) {
4742 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4745 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4747 char *buffer
= emalloc(length
+ 1);
4748 int read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4752 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
));
4756 ZVAL_LONG(zread
, read
);
4758 buffer
[read
] = '\0';
4759 RETVAL_STRINGL(buffer
, read
, 0);
4762 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4767 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek
, 0, 0, 1)
4768 ZEND_ARG_INFO(0, offset
)
4769 ZEND_ARG_INFO(0, whence
)
4770 ZEND_END_ARG_INFO();
4771 static PHP_METHOD(pqlob
, seek
) {
4772 zend_error_handling zeh
;
4773 long offset
, whence
= SEEK_SET
;
4776 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4777 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &offset
, &whence
);
4778 zend_restore_error_handling(&zeh TSRMLS_CC
);
4780 if (SUCCESS
== rv
) {
4781 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4784 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4786 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4789 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
));
4791 RETVAL_LONG(position
);
4794 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4799 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell
, 0, 0, 0)
4800 ZEND_END_ARG_INFO();
4801 static PHP_METHOD(pqlob
, tell
) {
4802 zend_error_handling zeh
;
4805 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4806 rv
= zend_parse_parameters_none();
4807 zend_restore_error_handling(&zeh TSRMLS_CC
);
4809 if (SUCCESS
== rv
) {
4810 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4813 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4815 int position
= lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
4818 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
));
4820 RETVAL_LONG(position
);
4823 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4828 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate
, 0, 0, 0)
4829 ZEND_ARG_INFO(0, length
)
4830 ZEND_END_ARG_INFO();
4831 static PHP_METHOD(pqlob
, truncate
) {
4832 zend_error_handling zeh
;
4836 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4837 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &length
);
4838 zend_restore_error_handling(&zeh TSRMLS_CC
);
4840 if (SUCCESS
== rv
) {
4841 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4844 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4846 int rc
= lo_truncate(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, length
);
4849 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
));
4852 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4857 static zend_function_entry php_pqlob_methods
[] = {
4858 PHP_ME(pqlob
, __construct
, ai_pqlob_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4859 PHP_ME(pqlob
, write
, ai_pqlob_write
, ZEND_ACC_PUBLIC
)
4860 PHP_ME(pqlob
, read
, ai_pqlob_read
, ZEND_ACC_PUBLIC
)
4861 PHP_ME(pqlob
, seek
, ai_pqlob_seek
, ZEND_ACC_PUBLIC
)
4862 PHP_ME(pqlob
, tell
, ai_pqlob_tell
, ZEND_ACC_PUBLIC
)
4863 PHP_ME(pqlob
, truncate
, ai_pqlob_truncate
, ZEND_ACC_PUBLIC
)
4867 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct
, 0, 0, 3)
4868 ZEND_ARG_OBJ_INFO(0, "connection", pq
\\Connection
, 0)
4869 ZEND_ARG_INFO(0, expression
)
4870 ZEND_ARG_INFO(0, direction
)
4871 ZEND_ARG_INFO(0, options
)
4872 ZEND_END_ARG_INFO();
4873 static PHP_METHOD(pqcopy
, __construct
) {
4874 zend_error_handling zeh
;
4876 char *expr_str
, *opt_str
= "";
4877 int expr_len
, opt_len
= 0;
4881 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4882 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
);
4883 zend_restore_error_handling(&zeh TSRMLS_CC
);
4885 if (SUCCESS
== rv
) {
4886 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4888 if (!conn_obj
->intern
) {
4889 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4891 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4892 smart_str cmd
= {0};
4895 smart_str_appends(&cmd
, "COPY ");
4896 smart_str_appendl(&cmd
, expr_str
, expr_len
);
4898 switch (direction
) {
4899 case PHP_PQCOPY_FROM_STDIN
:
4900 smart_str_appends(&cmd
, " FROM STDIN ");
4902 case PHP_PQCOPY_TO_STDOUT
:
4903 smart_str_appends(&cmd
, " TO STDOUT ");
4906 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
);
4907 smart_str_free(&cmd
);
4910 smart_str_appendl(&cmd
, opt_str
, opt_len
);
4913 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
4916 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4918 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4919 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4920 obj
->intern
->direction
= direction
;
4921 obj
->intern
->expression
= estrdup(expr_str
);
4922 obj
->intern
->options
= estrdup(opt_str
);
4923 obj
->intern
->conn
= conn_obj
;
4924 php_pq_object_addref(conn_obj TSRMLS_CC
);
4930 smart_str_free(&cmd
);
4931 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4936 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put
, 0, 0, 1)
4937 ZEND_ARG_INFO(0, data
)
4938 ZEND_END_ARG_INFO();
4939 static PHP_METHOD(pqcopy
, put
) {
4940 zend_error_handling zeh
;
4945 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4946 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4947 zend_restore_error_handling(&zeh TSRMLS_CC
);
4949 if (SUCCESS
== rv
) {
4950 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4953 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
4954 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
4955 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not initialized with FROM_STDIN");
4957 if (1 != PQputCopyData(obj
->intern
->conn
->intern
->conn
, data_str
, data_len
)) {
4958 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4960 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4965 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end
, 0, 0, 0)
4966 ZEND_ARG_INFO(0, error
)
4967 ZEND_END_ARG_INFO();
4968 static PHP_METHOD(pqcopy
, end
) {
4969 zend_error_handling zeh
;
4970 char *error_str
= NULL
;
4974 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4975 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &error_str
, &error_len
);
4976 zend_restore_error_handling(&zeh TSRMLS_CC
);
4978 if (SUCCESS
== rv
) {
4979 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4982 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY not intitialized");
4983 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
4984 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intitialized with FROM_STDIN");
4986 if (1 != PQputCopyEnd(obj
->intern
->conn
->intern
->conn
, error_str
)) {
4987 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4989 PGresult
*res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
4992 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4994 php_pqres_success(res TSRMLS_CC
);
4999 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5004 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get
, 0, 0, 1)
5005 ZEND_ARG_INFO(1, data
)
5006 ZEND_END_ARG_INFO();
5007 static PHP_METHOD(pqcopy
, get
) {
5008 zend_error_handling zeh
;
5012 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5013 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
);
5014 zend_restore_error_handling(&zeh TSRMLS_CC
);
5016 if (SUCCESS
== rv
) {
5017 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5020 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
5021 } else if (obj
->intern
->direction
!= PHP_PQCOPY_TO_STDOUT
) {
5022 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intialized with TO_STDOUT");
5025 char *buffer
= NULL
;
5026 int bytes
= PQgetCopyData(obj
->intern
->conn
->intern
->conn
, &buffer
, 0);
5030 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5034 res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
5037 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5039 php_pqres_success(res TSRMLS_CC
);
5048 ZVAL_STRINGL(zdata
, buffer
, bytes
, 1);
5050 ZVAL_EMPTY_STRING(zdata
);
5063 static zend_function_entry php_pqcopy_methods
[] = {
5064 PHP_ME(pqcopy
, __construct
, ai_pqcopy_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
5065 PHP_ME(pqcopy
, put
, ai_pqcopy_put
, ZEND_ACC_PUBLIC
)
5066 PHP_ME(pqcopy
, end
, ai_pqcopy_end
, ZEND_ACC_PUBLIC
)
5067 PHP_ME(pqcopy
, get
, ai_pqcopy_get
, ZEND_ACC_PUBLIC
)
5071 static zend_function_entry php_pqexc_methods
[] = {
5075 /* {{{ PHP_MINIT_FUNCTION
5077 static PHP_MINIT_FUNCTION(pq
)
5079 zend_class_entry ce
= {0};
5080 php_pq_object_prophandler_t ph
= {0};
5082 INIT_NS_CLASS_ENTRY(ce
, "pq", "Exception", php_pqexc_methods
);
5083 php_pqexc_interface_class_entry
= zend_register_internal_interface(&ce TSRMLS_CC
);
5085 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT TSRMLS_CC
);
5086 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("RUNTIME"), EX_RUNTIME TSRMLS_CC
);
5087 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("CONNECTION_FAILED"), EX_CONNECTION_FAILED TSRMLS_CC
);
5088 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("IO"), EX_IO TSRMLS_CC
);
5089 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("ESCAPE"), EX_ESCAPE TSRMLS_CC
);
5090 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("BAD_METHODCALL"), EX_BAD_METHODCALL TSRMLS_CC
);
5091 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("UNINITIALIZED"), EX_UNINITIALIZED TSRMLS_CC
);
5092 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("DOMAIN"), EX_DOMAIN TSRMLS_CC
);
5093 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("SQL"), EX_SQL TSRMLS_CC
);
5095 memset(&ce
, 0, sizeof(ce
));
5096 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "InvalidArgumentException", php_pqexc_methods
);
5097 php_pqexc_invalid_argument_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_InvalidArgumentException
, "InvalidArgumentException" TSRMLS_CC
);
5098 zend_class_implements(php_pqexc_invalid_argument_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5100 memset(&ce
, 0, sizeof(ce
));
5101 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "RuntimeException", php_pqexc_methods
);
5102 php_pqexc_runtime_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_RuntimeException
, "RuntimeException" TSRMLS_CC
);
5103 zend_class_implements(php_pqexc_runtime_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5105 memset(&ce
, 0, sizeof(ce
));
5106 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "BadMethodCallException", php_pqexc_methods
);
5107 php_pqexc_bad_methodcall_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_BadMethodCallException
, "BadMethodCallException" TSRMLS_CC
);
5108 zend_class_implements(php_pqexc_bad_methodcall_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5110 memset(&ce
, 0, sizeof(ce
));
5111 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "DomainException", php_pqexc_methods
);
5112 php_pqexc_domain_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_DomainException
, "DomainException" TSRMLS_CC
);
5113 zend_class_implements(php_pqexc_domain_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5114 zend_declare_property_null(php_pqexc_domain_class_entry
, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5116 memset(&ce
, 0, sizeof(ce
));
5117 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
5118 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5119 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
5121 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5122 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
5123 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
5124 php_pqconn_object_handlers
.clone_obj
= NULL
;
5125 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
5126 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5128 zend_hash_init(&php_pqconn_object_prophandlers
, 14, NULL
, NULL
, 1);
5130 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5131 ph
.read
= php_pqconn_object_read_status
;
5132 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5134 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5135 ph
.read
= php_pqconn_object_read_transaction_status
;
5136 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
5138 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5139 ph
.read
= NULL
; /* forward to std prophandler */
5140 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
5142 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5143 ph
.read
= php_pqconn_object_read_error_message
;
5144 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5146 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5147 ph
.read
= php_pqconn_object_read_busy
;
5148 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
5150 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5151 ph
.read
= php_pqconn_object_read_encoding
;
5152 ph
.write
= php_pqconn_object_write_encoding
;
5153 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
5156 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5157 ph
.read
= php_pqconn_object_read_unbuffered
;
5158 ph
.write
= php_pqconn_object_write_unbuffered
;
5159 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
5162 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5163 ph
.read
= php_pqconn_object_read_db
;
5164 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
5166 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5167 ph
.read
= php_pqconn_object_read_user
;
5168 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
5170 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5171 ph
.read
= php_pqconn_object_read_pass
;
5172 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
5174 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5175 ph
.read
= php_pqconn_object_read_host
;
5176 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
5178 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5179 ph
.read
= php_pqconn_object_read_port
;
5180 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
5182 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5183 ph
.read
= php_pqconn_object_read_options
;
5184 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5186 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5187 ph
.read
= php_pqconn_object_read_event_handlers
;
5188 zend_hash_add(&php_pqconn_object_prophandlers
, "eventHandlers", sizeof("eventHandlers"), (void *) &ph
, sizeof(ph
), NULL
);
5190 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
5191 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
5192 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
5193 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
5194 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
5195 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
5196 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
5197 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
5199 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
5200 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
5201 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
5202 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
5203 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
5205 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
5206 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
5207 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
5208 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
5210 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
5211 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result") TSRMLS_CC
);
5212 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset") TSRMLS_CC
);
5214 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
5215 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
5217 memset(&ce
, 0, sizeof(ce
));
5218 INIT_NS_CLASS_ENTRY(ce
, "pq", "Types", php_pqtypes_methods
);
5219 php_pqtypes_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5220 php_pqtypes_class_entry
->create_object
= php_pqtypes_create_object
;
5222 memcpy(&php_pqtypes_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5223 php_pqtypes_object_handlers
.read_property
= php_pq_object_read_prop
;
5224 php_pqtypes_object_handlers
.write_property
= php_pq_object_write_prop
;
5225 php_pqtypes_object_handlers
.clone_obj
= NULL
;
5226 php_pqtypes_object_handlers
.get_property_ptr_ptr
= NULL
;
5227 php_pqtypes_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5228 php_pqtypes_object_handlers
.has_dimension
= php_pqtypes_object_has_dimension
;
5229 php_pqtypes_object_handlers
.read_dimension
= php_pqtypes_object_read_dimension
;
5230 php_pqtypes_object_handlers
.unset_dimension
= NULL
;
5231 php_pqtypes_object_handlers
.write_dimension
= NULL
;
5233 zend_hash_init(&php_pqtypes_object_prophandlers
, 1, NULL
, NULL
, 1);
5235 zend_declare_property_null(php_pqtypes_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5236 ph
.read
= php_pqtypes_object_read_connection
;
5237 zend_hash_add(&php_pqtypes_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5239 memset(&ce
, 0, sizeof(ce
));
5240 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
5241 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5242 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
5243 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
5244 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
5245 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 2, zend_ce_traversable
, spl_ce_Countable
);
5247 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5248 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
5249 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
5250 php_pqres_object_handlers
.clone_obj
= NULL
;
5251 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
5252 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5253 php_pqres_object_handlers
.count_elements
= php_pqres_count_elements
;
5255 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
5257 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5258 ph
.read
= php_pqres_object_read_status
;
5259 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5261 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5262 ph
.read
= php_pqres_object_read_status_message
;
5263 zend_hash_add(&php_pqres_object_prophandlers
, "statusMessage", sizeof("statusMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5265 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5266 ph
.read
= php_pqres_object_read_error_message
;
5267 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5269 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5270 ph
.read
= php_pqres_object_read_num_rows
;
5271 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
5273 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5274 ph
.read
= php_pqres_object_read_num_cols
;
5275 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
5277 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5278 ph
.read
= php_pqres_object_read_affected_rows
;
5279 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
5281 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5282 ph
.read
= php_pqres_object_read_fetch_type
;
5283 ph
.write
= php_pqres_object_write_fetch_type
;
5284 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
5287 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
5288 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
5289 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
5290 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
5291 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
5292 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
5293 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
5294 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
5295 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
5296 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
5298 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
5299 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
5300 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
5302 memset(&ce
, 0, sizeof(ce
));
5303 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
5304 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5305 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
5307 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5308 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
5309 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
5310 php_pqstm_object_handlers
.clone_obj
= NULL
;
5311 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
5312 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5314 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
5316 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5317 ph
.read
= php_pqstm_object_read_name
;
5318 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
5320 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5321 ph
.read
= php_pqstm_object_read_connection
;
5322 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5324 memset(&ce
, 0, sizeof(ce
));
5325 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
5326 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5327 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
5329 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5330 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
5331 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
5332 php_pqtxn_object_handlers
.clone_obj
= NULL
;
5333 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
5334 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5336 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
5338 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5339 ph
.read
= php_pqtxn_object_read_connection
;
5340 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5342 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5343 ph
.read
= php_pqtxn_object_read_isolation
;
5344 ph
.write
= php_pqtxn_object_write_isolation
;
5345 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
5347 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5348 ph
.read
= php_pqtxn_object_read_readonly
;
5349 ph
.write
= php_pqtxn_object_write_readonly
;
5350 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
5352 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5353 ph
.read
= php_pqtxn_object_read_deferrable
;
5354 ph
.write
= php_pqtxn_object_write_deferrable
;
5355 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
5358 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
5359 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
5360 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
5362 memset(&ce
, 0, sizeof(ce
));
5363 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
5364 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5365 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
5367 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5368 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
5369 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
5370 php_pqcancel_object_handlers
.clone_obj
= NULL
;
5371 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
5372 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5374 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
5376 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5377 ph
.read
= php_pqcancel_object_read_connection
;
5378 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5380 memset(&ce
, 0, sizeof(ce
));
5381 INIT_NS_CLASS_ENTRY(ce
, "pq", "LOB", php_pqlob_methods
);
5382 php_pqlob_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5383 php_pqlob_class_entry
->create_object
= php_pqlob_create_object
;
5385 memcpy(&php_pqlob_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5386 php_pqlob_object_handlers
.read_property
= php_pq_object_read_prop
;
5387 php_pqlob_object_handlers
.write_property
= php_pq_object_write_prop
;
5388 php_pqlob_object_handlers
.clone_obj
= NULL
;
5389 php_pqlob_object_handlers
.get_property_ptr_ptr
= NULL
;
5390 php_pqlob_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5392 zend_hash_init(&php_pqlob_object_prophandlers
, 2, NULL
, NULL
, 1);
5394 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5395 ph
.read
= php_pqlob_object_read_transaction
;
5396 zend_hash_add(&php_pqlob_object_prophandlers
, "transaction", sizeof("transaction"), (void *) &ph
, sizeof(ph
), NULL
);
5398 zend_declare_property_long(php_pqlob_class_entry
, ZEND_STRL("oid"), InvalidOid
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5399 ph
.read
= php_pqlob_object_read_oid
;
5400 zend_hash_add(&php_pqlob_object_prophandlers
, "oid", sizeof("oid"), (void *) &ph
, sizeof(ph
), NULL
);
5402 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC
);
5403 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("R"), INV_READ TSRMLS_CC
);
5404 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("W"), INV_WRITE TSRMLS_CC
);
5405 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("RW"), INV_READ
|INV_WRITE TSRMLS_CC
);
5407 memset(&ce
, 0, sizeof(ce
));
5408 INIT_NS_CLASS_ENTRY(ce
, "pq", "COPY", php_pqcopy_methods
);
5409 php_pqcopy_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5410 php_pqcopy_class_entry
->create_object
= php_pqcopy_create_object
;
5412 memcpy(&php_pqcopy_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5413 php_pqcopy_object_handlers
.read_property
= php_pq_object_read_prop
;
5414 php_pqcopy_object_handlers
.write_property
= php_pq_object_write_prop
;
5415 php_pqcopy_object_handlers
.clone_obj
= NULL
;
5416 php_pqcopy_object_handlers
.get_property_ptr_ptr
= NULL
;
5417 php_pqcopy_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5419 zend_hash_init(&php_pqcopy_object_prophandlers
, 4, NULL
, NULL
, 1);
5421 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5422 ph
.read
= php_pqcopy_object_read_connection
;
5423 zend_hash_add(&php_pqcopy_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5425 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5426 ph
.read
= php_pqcopy_object_read_expression
;
5427 zend_hash_add(&php_pqcopy_object_prophandlers
, "expression", sizeof("expression"), (void *) &ph
, sizeof(ph
), NULL
);
5429 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5430 ph
.read
= php_pqcopy_object_read_direction
;
5431 zend_hash_add(&php_pqcopy_object_prophandlers
, "direction", sizeof("direction"), (void *) &ph
, sizeof(ph
), NULL
);
5433 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5434 ph
.read
= php_pqcopy_object_read_options
;
5435 zend_hash_add(&php_pqcopy_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5437 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC
);
5438 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC
);
5440 php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops
, NULL
, NULL TSRMLS_CC
);
5443 REGISTER_INI_ENTRIES();
5449 /* {{{ PHP_MSHUTDOWN_FUNCTION
5451 static PHP_MSHUTDOWN_FUNCTION(pq
)
5453 /* uncomment this line if you have INI entries
5454 UNREGISTER_INI_ENTRIES();
5456 php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL
, 0 TSRMLS_CC
);
5461 /* {{{ PHP_MINFO_FUNCTION
5463 static PHP_MINFO_FUNCTION(pq
)
5465 #ifdef HAVE_PQLIBVERSION
5468 char libpq_version
[10] = "pre-9.1";
5470 php_info_print_table_start();
5471 php_info_print_table_header(2, "PQ Support", "enabled");
5472 php_info_print_table_row(2, "Extension Version", PHP_PQ_EXT_VERSION
);
5473 php_info_print_table_end();
5475 php_info_print_table_start();
5476 php_info_print_table_header(2, "Used Library", "Version");
5477 #ifdef HAVE_PQLIBVERSION
5478 libpq_v
= PQlibVersion();
5479 slprintf(libpq_version
, sizeof(libpq_version
), "%d.%d.%d", libpq_v
/10000%100, libpq_v
/100%100, libpq_v
%100);
5481 php_info_print_table_row(2, "libpq", libpq_version
);
5482 php_info_print_table_end();
5484 /* Remove comments if you have entries in php.ini
5485 DISPLAY_INI_ENTRIES();
5490 const zend_function_entry pq_functions
[] = {
5494 static zend_module_dep pq_module_deps
[] = {
5495 ZEND_MOD_REQUIRED("raphf")
5496 ZEND_MOD_REQUIRED("spl")
5500 /* {{{ pq_module_entry
5502 zend_module_entry pq_module_entry
= {
5503 STANDARD_MODULE_HEADER_EX
,
5510 NULL
,/*PHP_RINIT(pq),*/
5511 NULL
,/*PHP_RSHUTDOWN(pq),*/
5514 STANDARD_MODULE_PROPERTIES
5518 #ifdef COMPILE_DL_PQ
5528 * vim600: noet sw=4 ts=4 fdm=marker
5529 * vim<600: noet sw=4 ts=4