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_pqevent_class_entry
;
92 static zend_class_entry
*php_pqlob_class_entry
;
93 static zend_class_entry
*php_pqcopy_class_entry
;
95 typedef enum php_pqexc_type
{
107 static zend_class_entry
*php_pqexc_interface_class_entry
;
108 static zend_class_entry
*php_pqexc_invalid_argument_class_entry
;
109 static zend_class_entry
*php_pqexc_runtime_class_entry
;
110 static zend_class_entry
*php_pqexc_bad_methodcall_class_entry
;
111 static zend_class_entry
*php_pqexc_domain_class_entry
;
113 static zend_class_entry
*exce(php_pqexc_type_t type
)
117 case EX_INVALID_ARGUMENT
:
118 return php_pqexc_invalid_argument_class_entry
;
120 case EX_CONNECTION_FAILED
:
123 return php_pqexc_runtime_class_entry
;
124 case EX_UNINITIALIZED
:
125 case EX_BAD_METHODCALL
:
126 return php_pqexc_bad_methodcall_class_entry
;
129 return php_pqexc_domain_class_entry
;
133 static zval
*throw_exce(php_pqexc_type_t type TSRMLS_DC
, const char *fmt
, ...)
140 vspprintf(&msg
, 0, fmt
, argv
);
143 zexc
= zend_throw_exception(exce(type
), msg
, type TSRMLS_CC
);
149 static zend_object_handlers php_pqconn_object_handlers
;
150 static zend_object_handlers php_pqtypes_object_handlers
;
151 static zend_object_handlers php_pqres_object_handlers
;
152 static zend_object_handlers php_pqstm_object_handlers
;
153 static zend_object_handlers php_pqtxn_object_handlers
;
154 static zend_object_handlers php_pqcancel_object_handlers
;
155 static zend_object_handlers php_pqevent_object_handlers
;
156 static zend_object_handlers php_pqlob_object_handlers
;
157 static zend_object_handlers php_pqcopy_object_handlers
;
159 typedef struct php_pq_callback
{
161 zend_fcall_info_cache fcc
;
165 typedef struct php_pq_object
{
167 zend_object_value zv
;
168 HashTable
*prophandler
;
172 #define PHP_PQCONN_ASYNC 0x01
173 #define PHP_PQCONN_PERSISTENT 0x02
175 typedef struct php_pqconn
{
177 int (*poller
)(PGconn
*);
178 php_resource_factory_t factory
;
180 HashTable eventhandlers
;
181 php_pq_callback_t onevent
;
182 unsigned unbuffered
:1;
185 typedef struct php_pqconn_object
{
187 zend_object_value zv
;
188 HashTable
*prophandler
;
189 php_pqconn_t
*intern
;
190 } php_pqconn_object_t
;
192 typedef struct php_pqtypes
{
194 php_pqconn_object_t
*conn
;
197 typedef struct php_pqtypes_object
{
199 zend_object_value zv
;
200 HashTable
*prophandler
;
201 php_pqtypes_t
*intern
;
202 } php_pqtypes_object_t
;
204 typedef struct php_pqconn_event_data
{
205 php_pqconn_object_t
*obj
;
209 } php_pqconn_event_data_t
;
211 typedef enum php_pqres_fetch
{
212 PHP_PQRES_FETCH_ARRAY
,
213 PHP_PQRES_FETCH_ASSOC
,
214 PHP_PQRES_FETCH_OBJECT
217 typedef struct php_pqres_iterator
{
218 zend_object_iterator zi
;
221 php_pqres_fetch_t fetch_type
;
222 } php_pqres_iterator_t
;
224 typedef struct php_pqres
{
226 php_pqres_iterator_t
*iter
;
230 typedef struct php_pqres_object
{
232 zend_object_value zv
;
233 HashTable
*prophandler
;
235 } php_pqres_object_t
;
237 typedef struct php_pqstm
{
238 php_pqconn_object_t
*conn
;
243 typedef struct php_pqstm_object
{
245 zend_object_value zv
;
246 HashTable
*prophandler
;
248 } php_pqstm_object_t
;
250 typedef enum php_pqtxn_isolation
{
251 PHP_PQTXN_READ_COMMITTED
,
252 PHP_PQTXN_REPEATABLE_READ
,
253 PHP_PQTXN_SERIALIZABLE
,
254 } php_pqtxn_isolation_t
;
256 typedef struct php_pqtxn
{
257 php_pqconn_object_t
*conn
;
258 php_pqtxn_isolation_t isolation
;
262 unsigned deferrable
:1;
265 typedef struct php_pqtxn_object
{
267 zend_object_value zv
;
268 HashTable
*prophandler
;
270 } php_pqtxn_object_t
;
272 typedef struct php_pqcancel
{
274 php_pqconn_object_t
*conn
;
277 typedef struct php_pqcancel_object
{
279 zend_object_value zv
;
280 HashTable
*prophandler
;
281 php_pqcancel_t
*intern
;
282 } php_pqcancel_object_t
;
284 typedef struct php_pqevent
{
285 php_pq_callback_t cb
;
290 typedef struct php_pqevent_object
{
292 zend_object_value zv
;
293 HashTable
*prophandler
;
294 php_pqevent_t
*intern
;
295 } php_pqevent_object_t
;
297 typedef struct php_pqlob
{
300 php_pqtxn_object_t
*txn
;
303 typedef struct php_pqlob_object
{
305 zend_object_value zv
;
306 HashTable
*prophandler
;
308 } php_pqlob_object_t
;
310 typedef enum php_pqcopy_direction
{
311 PHP_PQCOPY_FROM_STDIN
,
313 } php_pqcopy_direction_t
;
315 typedef enum php_pqcopy_status
{
319 } php_pqcopy_status_t
;
321 typedef struct php_pqcopy
{
322 php_pqcopy_direction_t direction
;
325 php_pqconn_object_t
*conn
;
328 typedef struct php_pqcopy_object
{
330 zend_object_value zv
;
331 HashTable
*prophandler
;
332 php_pqcopy_t
*intern
;
333 } php_pqcopy_object_t
;
335 static HashTable php_pqconn_object_prophandlers
;
336 static HashTable php_pqtypes_object_prophandlers
;
337 static HashTable php_pqres_object_prophandlers
;
338 static HashTable php_pqstm_object_prophandlers
;
339 static HashTable php_pqtxn_object_prophandlers
;
340 static HashTable php_pqcancel_object_prophandlers
;
341 static HashTable php_pqevent_object_prophandlers
;
342 static HashTable php_pqlob_object_prophandlers
;
343 static HashTable php_pqcopy_object_prophandlers
;
345 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
347 typedef struct php_pq_object_prophandler
{
348 php_pq_object_prophandler_func_t read
;
349 php_pq_object_prophandler_func_t write
;
350 } php_pq_object_prophandler_t
;
352 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
354 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
356 php_pqres_iterator_t
*iter
;
357 zval
*prop
, *zfetch_type
;
359 iter
= ecalloc(1, sizeof(*iter
));
360 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
361 iter
->zi
.data
= object
;
364 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
365 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
366 convert_to_long_ex(&zfetch_type
);
368 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
369 if (zfetch_type
!= prop
) {
370 zval_ptr_dtor(&zfetch_type
);
372 if (Z_REFCOUNT_P(prop
)) {
373 zval_ptr_dtor(&prop
);
379 return (zend_object_iterator
*) iter
;
382 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
384 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
386 if (iter
->current_val
) {
387 zval_ptr_dtor(&iter
->current_val
);
388 iter
->current_val
= NULL
;
390 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
394 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
396 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
397 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
399 switch (PQresultStatus(obj
->intern
->res
)) {
400 case PGRES_TUPLES_OK
:
401 case PGRES_SINGLE_TUPLE
:
402 if (PQntuples(obj
->intern
->res
) <= iter
->index
) {
413 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type
, zval
**data_ptr TSRMLS_DC
)
423 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
433 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
434 if (PQgetisnull(res
, row
, c
)) {
435 switch (fetch_type
) {
436 case PHP_PQRES_FETCH_OBJECT
:
437 add_property_null(data
, PQfname(res
, c
));
440 case PHP_PQRES_FETCH_ASSOC
:
441 add_assoc_null(data
, PQfname(res
, c
));
444 case PHP_PQRES_FETCH_ARRAY
:
445 add_index_null(data
, c
);
449 char *val
= PQgetvalue(res
, row
, c
);
450 int len
= PQgetlength(res
, row
, c
);
452 switch (fetch_type
) {
453 case PHP_PQRES_FETCH_OBJECT
:
454 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
457 case PHP_PQRES_FETCH_ASSOC
:
458 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
461 case PHP_PQRES_FETCH_ARRAY
:
462 add_index_stringl(data
, c
, val
, len
,1);
471 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
473 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
474 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
476 if (iter
->current_val
) {
477 zval_ptr_dtor(&iter
->current_val
);
479 iter
->current_val
= php_pqres_row_to_zval(obj
->intern
->res
, iter
->index
, iter
->fetch_type
, NULL TSRMLS_CC
);
480 *data_ptr
= &iter
->current_val
;
483 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
485 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
487 *key_num
= (ulong
) iter
->index
;
489 return HASH_KEY_IS_LONG
;
492 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
494 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
499 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
501 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
506 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
507 php_pqres_iterator_dtor
,
508 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
509 php_pqres_iterator_valid
,
510 /* fetch the item data for the current element */
511 php_pqres_iterator_current
,
512 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
513 php_pqres_iterator_key
,
514 /* step forwards to next element */
515 php_pqres_iterator_next
,
516 /* rewind to start of data (optional, may be NULL) */
517 php_pqres_iterator_rewind
,
518 /* invalidate current value/key (optional, may be NULL) */
522 static int php_pqres_count_elements(zval
*object
, long *count TSRMLS_DC
)
524 php_pqres_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
529 *count
= (long) PQntuples(obj
->intern
->res
);
534 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
538 switch (PQresultStatus(res
)) {
539 case PGRES_BAD_RESPONSE
:
540 case PGRES_NONFATAL_ERROR
:
541 case PGRES_FATAL_ERROR
:
542 zexc
= throw_exce(EX_SQL TSRMLS_CC
, "%s", PHP_PQresultErrorMessage(res
));
543 zend_update_property_string(php_pqexc_domain_class_entry
, zexc
, ZEND_STRL("sqlstate"), PQresultErrorField(res
, PG_DIAG_SQLSTATE
) TSRMLS_CC
);
551 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC)
555 if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
556 zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
561 static ulong
php_pqconn_add_eventhandler(php_pqconn_object_t
*obj
, const char *type_str
, size_t type_len
, zval
*zevent TSRMLS_DC
)
566 if (SUCCESS
== zend_hash_find(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
568 h
= zend_hash_next_free_element(Z_ARRVAL_PP(evhs
));
569 add_next_index_zval(*evhs
, zevent
);
576 h
= zend_hash_next_free_element(Z_ARRVAL_P(evh
));
577 add_next_index_zval(evh
, zevent
);
578 zend_hash_add(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(zval
*), NULL
);
584 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
585 if (cb
->fci
.size
> 0) {
586 zend_fcall_info_args_clear(&cb
->fci
, 1);
587 zval_ptr_dtor(&cb
->fci
.function_name
);
588 if (cb
->fci
.object_ptr
) {
589 zval_ptr_dtor(&cb
->fci
.object_ptr
);
595 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
597 Z_ADDREF_P(cb
->fci
.function_name
);
598 if (cb
->fci
.object_ptr
) {
599 Z_ADDREF_P(cb
->fci
.object_ptr
);
603 static void php_pq_object_to_zval(void *o
, zval
**zv TSRMLS_DC
)
605 php_pq_object_t
*obj
= o
;
611 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
613 (*zv
)->type
= IS_OBJECT
;
614 (*zv
)->value
.obj
= obj
->zv
;
617 static void php_pq_object_to_zval_no_addref(void *o
, zval
**zv TSRMLS_DC
)
619 php_pq_object_t
*obj
= o
;
627 (*zv
)->type
= IS_OBJECT
;
628 (*zv
)->value
.obj
= obj
->zv
;
631 static void php_pq_object_addref(void *o TSRMLS_DC
)
633 php_pq_object_t
*obj
= o
;
634 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
637 static void php_pq_object_delref(void *o TSRMLS_DC
)
639 php_pq_object_t
*obj
= o
;
640 zend_objects_store_del_ref_by_handle_ex(obj
->zv
.handle
, obj
->zv
.handlers TSRMLS_CC
);
643 static void php_pqconn_object_free(void *o TSRMLS_DC
)
645 php_pqconn_object_t
*obj
= o
;
647 fprintf(stderr
, "FREE conn(#%d) %p\n", obj
->zv
.handle
, obj
);
650 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
651 php_resource_factory_dtor(&obj
->intern
->factory
);
652 php_pq_callback_dtor(&obj
->intern
->onevent
);
653 zend_hash_destroy(&obj
->intern
->listeners
);
654 zend_hash_destroy(&obj
->intern
->eventhandlers
);
658 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
662 static void php_pqtypes_object_free(void *o TSRMLS_DC
)
664 php_pqtypes_object_t
*obj
= o
;
666 fprintf(stderr
, "FREE types(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
669 zend_hash_destroy(&obj
->intern
->types
);
670 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
674 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
678 static void php_pqres_object_free(void *o TSRMLS_DC
)
680 php_pqres_object_t
*obj
= o
;
682 fprintf(stderr
, "FREE res(#%d) %p\n", obj
->zv
.handle
, obj
);
685 if (obj
->intern
->res
) {
686 PQresultSetInstanceData(obj
->intern
->res
, php_pqconn_event
, NULL
);
687 PQclear(obj
->intern
->res
);
688 obj
->intern
->res
= NULL
;
691 if (obj
->intern
->iter
) {
692 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
693 obj
->intern
->iter
= NULL
;
696 zend_hash_destroy(&obj
->intern
->bound
);
701 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
705 static void php_pqstm_object_free(void *o TSRMLS_DC
)
707 php_pqstm_object_t
*obj
= o
;
709 fprintf(stderr
, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
712 char *quoted_name
= PQescapeIdentifier(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, strlen(obj
->intern
->name
));
714 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
720 smart_str_appends(&cmd
, "DEALLOCATE ");
721 smart_str_appends(&cmd
, quoted_name
);
723 PQfreemem(quoted_name
);
725 if ((res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
))) {
728 smart_str_free(&cmd
);
731 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
732 efree(obj
->intern
->name
);
733 zend_hash_destroy(&obj
->intern
->bound
);
737 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
741 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
743 php_pqtxn_object_t
*obj
= o
;
745 fprintf(stderr
, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
748 if (obj
->intern
->open
) {
749 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
755 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
759 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
763 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
765 php_pqcancel_object_t
*obj
= o
;
767 fprintf(stderr
, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
770 PQfreeCancel(obj
->intern
->cancel
);
771 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
775 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
779 static void php_pqevent_object_free(void *o TSRMLS_DC
)
781 php_pqevent_object_t
*obj
= o
;
783 fprintf(stderr
, "FREE event(#%d) %p\n", obj
->zv
.handle
, obj
);
786 php_pq_callback_dtor(&obj
->intern
->cb
);
787 efree(obj
->intern
->type
);
791 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
795 static void php_pqlob_object_free(void *o TSRMLS_DC
)
797 php_pqlob_object_t
*obj
= o
;
799 fprintf(stderr
, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->txn
->zv
.handle
, obj
->intern
->txn
);
802 if (obj
->intern
->lofd
) {
803 lo_close(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
805 php_pq_object_delref(obj
->intern
->txn TSRMLS_CC
);
809 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
813 static void php_pqcopy_object_free(void *o TSRMLS_DC
)
815 php_pqcopy_object_t
*obj
= o
;
817 fprintf(stderr
, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
820 efree(obj
->intern
->expression
);
821 efree(obj
->intern
->options
);
822 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
826 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
830 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
832 php_pqconn_object_t
*o
;
834 o
= ecalloc(1, sizeof(*o
));
835 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
836 object_properties_init((zend_object
*) o
, ce
);
837 o
->prophandler
= &php_pqconn_object_prophandlers
;
847 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
848 o
->zv
.handlers
= &php_pqconn_object_handlers
;
853 static zend_object_value
php_pqtypes_create_object_ex(zend_class_entry
*ce
, php_pqtypes_t
*intern
, php_pqtypes_object_t
**ptr TSRMLS_DC
)
855 php_pqtypes_object_t
*o
;
857 o
= ecalloc(1, sizeof(*o
));
858 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
859 object_properties_init((zend_object
*) o
, ce
);
860 o
->prophandler
= &php_pqtypes_object_prophandlers
;
870 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtypes_object_free
, NULL TSRMLS_CC
);
871 o
->zv
.handlers
= &php_pqtypes_object_handlers
;
876 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, php_pqres_t
*intern
, php_pqres_object_t
**ptr TSRMLS_DC
)
878 php_pqres_object_t
*o
;
880 o
= ecalloc(1, sizeof(*o
));
881 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
882 object_properties_init((zend_object
*) o
, ce
);
883 o
->prophandler
= &php_pqres_object_prophandlers
;
893 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
894 o
->zv
.handlers
= &php_pqres_object_handlers
;
899 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*intern
, php_pqstm_object_t
**ptr TSRMLS_DC
)
901 php_pqstm_object_t
*o
;
903 o
= ecalloc(1, sizeof(*o
));
904 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
905 object_properties_init((zend_object
*) o
, ce
);
906 o
->prophandler
= &php_pqstm_object_prophandlers
;
916 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
917 o
->zv
.handlers
= &php_pqstm_object_handlers
;
922 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*intern
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
924 php_pqtxn_object_t
*o
;
926 o
= ecalloc(1, sizeof(*o
));
927 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
928 object_properties_init((zend_object
*) o
, ce
);
929 o
->prophandler
= &php_pqtxn_object_prophandlers
;
939 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
940 o
->zv
.handlers
= &php_pqtxn_object_handlers
;
945 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*intern
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
947 php_pqcancel_object_t
*o
;
949 o
= ecalloc(1, sizeof(*o
));
950 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
951 object_properties_init((zend_object
*) o
, ce
);
952 o
->prophandler
= &php_pqcancel_object_prophandlers
;
962 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
963 o
->zv
.handlers
= &php_pqcancel_object_handlers
;
968 static zend_object_value
php_pqevent_create_object_ex(zend_class_entry
*ce
, php_pqevent_t
*intern
, php_pqevent_object_t
**ptr TSRMLS_DC
)
970 php_pqevent_object_t
*o
;
972 o
= ecalloc(1, sizeof(*o
));
973 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
974 object_properties_init((zend_object
*) o
, ce
);
975 o
->prophandler
= &php_pqevent_object_prophandlers
;
985 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqevent_object_free
, NULL TSRMLS_CC
);
986 o
->zv
.handlers
= &php_pqevent_object_handlers
;
991 static zend_object_value
php_pqlob_create_object_ex(zend_class_entry
*ce
, php_pqlob_t
*intern
, php_pqlob_object_t
**ptr TSRMLS_DC
)
993 php_pqlob_object_t
*o
;
995 o
= ecalloc(1, sizeof(*o
));
996 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
997 object_properties_init((zend_object
*) o
, ce
);
998 o
->prophandler
= &php_pqlob_object_prophandlers
;
1008 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqlob_object_free
, NULL TSRMLS_CC
);
1009 o
->zv
.handlers
= &php_pqlob_object_handlers
;
1014 static zend_object_value
php_pqcopy_create_object_ex(zend_class_entry
*ce
, php_pqcopy_t
*intern
, php_pqcopy_object_t
**ptr TSRMLS_DC
)
1016 php_pqcopy_object_t
*o
;
1018 o
= ecalloc(1, sizeof(*o
));
1019 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
1020 object_properties_init((zend_object
*) o
, ce
);
1021 o
->prophandler
= &php_pqcopy_object_prophandlers
;
1031 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcopy_object_free
, NULL TSRMLS_CC
);
1032 o
->zv
.handlers
= &php_pqcopy_object_handlers
;
1037 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1039 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1042 static zend_object_value
php_pqtypes_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1044 return php_pqtypes_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1047 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1049 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1052 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1054 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1057 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1059 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1062 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1064 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1067 static zend_object_value
php_pqevent_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1069 return php_pqevent_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1072 static zend_object_value
php_pqlob_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1074 return php_pqlob_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1077 static zend_object_value
php_pqcopy_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1079 return php_pqcopy_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1082 static int apply_pi_to_ht(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1084 zend_property_info
*pi
= p
;
1085 HashTable
*ht
= va_arg(argv
, HashTable
*);
1086 zval
*object
= va_arg(argv
, zval
*);
1087 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
1088 int addref
= va_arg(argv
, int);
1089 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
1092 Z_ADDREF_P(property
);
1094 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
1096 return ZEND_HASH_APPLY_KEEP
;
1099 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
1102 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1105 ALLOC_HASHTABLE(ht
);
1106 ZEND_INIT_SYMTABLE(ht
);
1108 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_ht
, 4, ht
, object
, obj
, 1);
1113 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1115 php_pqconn_object_t
*obj
= o
;
1117 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
1120 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1122 php_pqconn_object_t
*obj
= o
;
1124 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
1127 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1129 php_pqconn_object_t
*obj
= o
;
1130 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
1133 RETVAL_STRING(error
, 1);
1139 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
1141 php_pq_callback_t
*listener
= p
;
1142 PGnotify
*nfy
= arg
;
1143 zval
*zpid
, *zchannel
, *zmessage
;
1145 MAKE_STD_ZVAL(zpid
);
1146 ZVAL_LONG(zpid
, nfy
->be_pid
);
1147 MAKE_STD_ZVAL(zchannel
);
1148 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
1149 MAKE_STD_ZVAL(zmessage
);
1150 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
1152 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
1153 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
1155 zval_ptr_dtor(&zchannel
);
1156 zval_ptr_dtor(&zmessage
);
1157 zval_ptr_dtor(&zpid
);
1159 return ZEND_HASH_APPLY_KEEP
;
1162 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1164 HashTable
*listeners
= p
;
1165 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
1167 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
1168 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
1171 return ZEND_HASH_APPLY_KEEP
;
1174 static void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
1178 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
1179 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
1184 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1186 php_pqconn_object_t
*obj
= o
;
1188 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
1191 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1193 php_pqconn_object_t
*obj
= o
;
1195 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
1198 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1200 php_pqconn_object_t
*obj
= o
;
1203 if (Z_TYPE_P(value
) != IS_STRING
) {
1204 if (Z_REFCOUNT_P(value
) > 1) {
1207 ZVAL_ZVAL(tmp
, zenc
, 1, 0);
1208 convert_to_string(tmp
);
1211 convert_to_string_ex(&zenc
);
1215 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
1216 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
1219 if (zenc
!= value
) {
1220 zval_ptr_dtor(&zenc
);
1224 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1226 php_pqconn_object_t
*obj
= o
;
1228 RETVAL_BOOL(obj
->intern
->unbuffered
);
1231 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1233 php_pqconn_object_t
*obj
= o
;
1235 obj
->intern
->unbuffered
= zend_is_true(value
);
1238 static void php_pqconn_object_read_db(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1240 php_pqconn_object_t
*obj
= o
;
1241 char *db
= PQdb(obj
->intern
->conn
);
1244 RETVAL_STRING(db
, 1);
1246 RETVAL_EMPTY_STRING();
1250 static void php_pqconn_object_read_user(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1252 php_pqconn_object_t
*obj
= o
;
1253 char *user
= PQuser(obj
->intern
->conn
);
1256 RETVAL_STRING(user
, 1);
1258 RETVAL_EMPTY_STRING();
1262 static void php_pqconn_object_read_pass(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1264 php_pqconn_object_t
*obj
= o
;
1265 char *pass
= PQpass(obj
->intern
->conn
);
1268 RETVAL_STRING(pass
, 1);
1270 RETVAL_EMPTY_STRING();
1274 static void php_pqconn_object_read_host(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1276 php_pqconn_object_t
*obj
= o
;
1277 char *host
= PQhost(obj
->intern
->conn
);
1280 RETVAL_STRING(host
, 1);
1282 RETVAL_EMPTY_STRING();
1286 static void php_pqconn_object_read_port(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1288 php_pqconn_object_t
*obj
= o
;
1289 char *port
= PQport(obj
->intern
->conn
);
1292 RETVAL_STRING(port
, 1);
1294 RETVAL_EMPTY_STRING();
1298 static void php_pqconn_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1300 php_pqconn_object_t
*obj
= o
;
1301 char *options
= PQoptions(obj
->intern
->conn
);
1304 RETVAL_STRING(options
, 1);
1306 RETVAL_EMPTY_STRING();
1310 static void php_pqconn_object_read_event_handlers(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1312 php_pqconn_object_t
*obj
= o
;
1314 array_init(return_value
);
1315 zend_hash_copy(Z_ARRVAL_P(return_value
), &obj
->intern
->eventhandlers
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
1318 static void php_pqtypes_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1320 php_pqtypes_object_t
*obj
= o
;
1322 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1325 static int has_dimension(HashTable
*ht
, zval
*member
, char **key_str
, int *key_len
, ulong
*index TSRMLS_DC
)
1330 switch (Z_TYPE_P(member
)) {
1332 convert_to_string_ex(&tmp
);
1335 if (!is_numeric_string(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
), &lval
, NULL
, 0)) {
1336 int exists
= zend_hash_exists(ht
, Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
) + 1);
1339 *key_str
= estrndup(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
));
1341 *key_len
= Z_STRLEN_P(tmp
) + 1;
1344 if (member
!= tmp
) {
1345 zval_ptr_dtor(&tmp
);
1352 lval
= Z_LVAL_P(member
);
1356 if (member
!= tmp
) {
1357 zval_ptr_dtor(&tmp
);
1362 return zend_hash_index_exists(ht
, lval
);
1365 static int php_pqtypes_object_has_dimension(zval
*object
, zval
*member
, int check_empty TSRMLS_DC
)
1367 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1368 char *key_str
= NULL
;
1373 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1376 if (key_str
&& key_len
) {
1377 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1379 return Z_TYPE_PP(data
) != IS_NULL
;
1383 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1384 return Z_TYPE_PP(data
) != IS_NULL
;
1392 return has_dimension(&obj
->intern
->types
, member
, NULL
, NULL
, NULL TSRMLS_CC
);
1398 static zval
*php_pqtypes_object_read_dimension(zval
*object
, zval
*member
, int type TSRMLS_DC
)
1401 char *key_str
= NULL
;
1403 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1405 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1408 if (key_str
&& key_len
) {
1409 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1414 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1426 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1428 php_pqres_object_t
*obj
= o
;
1430 RETVAL_LONG(PQresultStatus(obj
->intern
->res
));
1433 static void php_pqres_object_read_status_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1435 php_pqres_object_t
*obj
= o
;
1437 RETVAL_STRING(PQresStatus(PQresultStatus(obj
->intern
->res
))+sizeof("PGRES"), 1);
1440 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1442 php_pqres_object_t
*obj
= o
;
1443 char *error
= PHP_PQresultErrorMessage(obj
->intern
->res
);
1446 RETVAL_STRING(error
, 1);
1452 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1454 php_pqres_object_t
*obj
= o
;
1456 RETVAL_LONG(PQntuples(obj
->intern
->res
));
1459 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1461 php_pqres_object_t
*obj
= o
;
1463 RETVAL_LONG(PQnfields(obj
->intern
->res
));
1466 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1468 php_pqres_object_t
*obj
= o
;
1470 RETVAL_LONG(atoi(PQcmdTuples(obj
->intern
->res
)));
1473 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1475 php_pqres_object_t
*obj
= o
;
1477 if (obj
->intern
->iter
) {
1478 RETVAL_LONG(obj
->intern
->iter
->fetch_type
);
1480 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
1484 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1486 php_pqres_object_t
*obj
= o
;
1487 zval
*zfetch_type
= value
;
1489 if (Z_TYPE_P(value
) != IS_LONG
) {
1490 if (Z_REFCOUNT_P(value
) > 1) {
1493 ZVAL_ZVAL(tmp
, zfetch_type
, 1, 0);
1494 convert_to_long(tmp
);
1497 convert_to_long_ex(&zfetch_type
);
1501 if (!obj
->intern
->iter
) {
1502 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
1503 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
1505 obj
->intern
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
1507 if (zfetch_type
!= value
) {
1508 zval_ptr_dtor(&zfetch_type
);
1512 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1514 php_pqstm_object_t
*obj
= o
;
1516 RETVAL_STRING(obj
->intern
->name
, 1);
1519 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1521 php_pqstm_object_t
*obj
= o
;
1523 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1526 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1528 php_pqtxn_object_t
*obj
= o
;
1530 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1533 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1535 php_pqtxn_object_t
*obj
= o
;
1537 RETVAL_LONG(obj
->intern
->isolation
);
1540 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1542 php_pqtxn_object_t
*obj
= o
;
1544 RETVAL_BOOL(obj
->intern
->readonly
);
1547 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1549 php_pqtxn_object_t
*obj
= o
;
1551 RETVAL_BOOL(obj
->intern
->deferrable
);
1554 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1556 php_pqtxn_object_t
*obj
= o
;
1557 php_pqtxn_isolation_t orig
= obj
->intern
->isolation
;
1558 zval
*zisolation
= value
;
1561 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
1562 if (Z_REFCOUNT_P(value
) > 1) {
1565 ZVAL_ZVAL(tmp
, zisolation
, 1, 0);
1566 convert_to_long(tmp
);
1569 convert_to_long_ex(&zisolation
);
1573 switch ((obj
->intern
->isolation
= Z_LVAL_P(zisolation
))) {
1574 case PHP_PQTXN_READ_COMMITTED
:
1575 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL READ COMMITED");
1577 case PHP_PQTXN_REPEATABLE_READ
:
1578 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
1580 case PHP_PQTXN_SERIALIZABLE
:
1581 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
1584 obj
->intern
->isolation
= orig
;
1589 if (zisolation
!= value
) {
1590 zval_ptr_dtor(&zisolation
);
1594 php_pqres_success(res TSRMLS_CC
);
1599 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1601 php_pqtxn_object_t
*obj
= o
;
1604 if ((obj
->intern
->readonly
= zend_is_true(value
))) {
1605 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ ONLY");
1607 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ WRITE");
1611 php_pqres_success(res TSRMLS_CC
);
1616 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1618 php_pqtxn_object_t
*obj
= o
;
1621 if ((obj
->intern
->deferrable
= zend_is_true(value
))) {
1622 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION DEFERRABLE");
1624 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION NOT DEFERRABLE");
1628 php_pqres_success(res TSRMLS_CC
);
1633 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1635 php_pqcancel_object_t
*obj
= o
;
1637 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1640 static void php_pqevent_object_read_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1642 php_pqevent_object_t
*obj
= o
;
1644 RETVAL_STRING(obj
->intern
->type
, 1);
1647 static void php_pqlob_object_read_transaction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1649 php_pqlob_object_t
*obj
= o
;
1651 php_pq_object_to_zval(obj
->intern
->txn
, &return_value TSRMLS_CC
);
1654 static void php_pqlob_object_read_oid(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1656 php_pqlob_object_t
*obj
= o
;
1658 RETVAL_LONG(obj
->intern
->loid
);
1661 static void php_pqcopy_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1663 php_pqcopy_object_t
*obj
= o
;
1665 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1668 static void php_pqcopy_object_read_direction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1670 php_pqcopy_object_t
*obj
= o
;
1672 RETVAL_LONG(obj
->intern
->direction
);
1675 static void php_pqcopy_object_read_expression(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1677 php_pqcopy_object_t
*obj
= o
;
1679 RETURN_STRING(obj
->intern
->expression
, 1);
1682 static void php_pqcopy_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1684 php_pqcopy_object_t
*obj
= o
;
1686 RETURN_STRING(obj
->intern
->options
, 1);
1689 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
1690 while (ce
->parent
) {
1696 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
1698 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1699 php_pq_object_prophandler_t
*handler
;
1703 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1704 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1705 if (type
== BP_VAR_R
) {
1706 ALLOC_ZVAL(return_value
);
1707 Z_SET_REFCOUNT_P(return_value
, 0);
1708 Z_UNSET_ISREF_P(return_value
);
1710 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1712 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1713 return_value
= NULL
;
1716 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1719 return return_value
;
1722 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1724 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1725 php_pq_object_prophandler_t
*handler
;
1727 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1728 if (handler
->write
) {
1729 handler
->write(object
, obj
, value TSRMLS_CC
);
1732 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1736 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1738 zval
*zsocket
, zmember
;
1744 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1747 INIT_PZVAL(&zmember
);
1748 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1749 MAKE_STD_ZVAL(zsocket
);
1751 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
1752 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
1753 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1754 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1755 php_stream_to_zval(stream
, zsocket
);
1761 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1762 zval_ptr_dtor(&zsocket
);
1768 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1769 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1771 # define TSRMLS_DF(d)
1772 # define TSRMLS_CF(d)
1775 static int apply_event(void *p
, void *a TSRMLS_DC
)
1779 zval
*retval
= NULL
;
1781 zend_call_method_with_1_params(evh
, Z_OBJCE_PP(evh
), NULL
, "trigger", &retval
, args
);
1783 zval_ptr_dtor(&retval
);
1786 return ZEND_HASH_APPLY_KEEP
;
1789 static void php_pqconn_event_connreset(PGEventConnReset
*event
)
1791 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1797 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("reset"), (void *) &evhs
)) {
1798 zval
*args
, *connection
= NULL
;
1800 MAKE_STD_ZVAL(args
);
1802 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1803 add_next_index_zval(args
, connection
);
1804 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1805 zval_ptr_dtor(&args
);
1810 static void php_pqres_init_instance_data(PGresult
*res
, php_pqres_object_t
**ptr TSRMLS_DC
)
1812 php_pqres_object_t
*obj
;
1813 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
1816 ZEND_INIT_SYMTABLE(&r
->bound
);
1817 php_pqres_create_object_ex(php_pqres_class_entry
, r
, &obj TSRMLS_CC
);
1819 PQresultSetInstanceData(res
, php_pqconn_event
, obj
);
1826 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
)
1828 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1831 php_pqres_object_t
*obj
;
1835 php_pqres_init_instance_data(event
->result
, &obj TSRMLS_CC
);
1837 /* event listener */
1838 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("result"), (void *) &evhs
)) {
1839 zval
*args
, *connection
= NULL
, *res
= NULL
;
1841 MAKE_STD_ZVAL(args
);
1843 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1844 add_next_index_zval(args
, connection
);
1845 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1846 add_next_index_zval(args
, res
);
1847 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1848 zval_ptr_dtor(&args
);
1851 /* async callback */
1852 if (data
->obj
->intern
->onevent
.fci
.size
> 0) {
1855 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1856 zend_fcall_info_argn(&data
->obj
->intern
->onevent
.fci TSRMLS_CC
, 1, &res
);
1857 zend_fcall_info_call(&data
->obj
->intern
->onevent
.fci
, &data
->obj
->intern
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1858 zval_ptr_dtor(&res
);
1864 static void php_pqconn_event_resultdestroy(PGEventResultDestroy
*event
)
1866 php_pqres_object_t
*obj
= PQresultInstanceData(event
->result
, php_pqconn_event
);
1869 obj
->intern
->res
= NULL
;
1873 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1876 case PGEVT_CONNRESET
:
1877 php_pqconn_event_connreset(e
);
1879 case PGEVT_RESULTCREATE
:
1880 php_pqconn_event_resultcreate(e
);
1882 case PGEVT_RESULTDESTROY
:
1883 php_pqconn_event_resultdestroy(e
);
1892 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1894 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1902 static void php_pqconn_notice_recv(void *p
, const PGresult
*res
)
1904 php_pqconn_event_data_t
*data
= p
;
1910 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("notice"), (void *) &evhs
)) {
1911 zval
*args
, *connection
= NULL
;
1913 MAKE_STD_ZVAL(args
);
1915 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1916 add_next_index_zval(args
, connection
);
1917 add_next_index_string(args
, PHP_PQresultErrorMessage(res
), 1);
1918 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1919 zval_ptr_dtor(&args
);
1924 typedef struct php_pqconn_resource_factory_data
{
1927 } php_pqconn_resource_factory_data_t
;
1929 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
1931 php_pqconn_resource_factory_data_t
*o
= init_arg
;
1932 PGconn
*conn
= NULL
;;
1934 if (o
->flags
& PHP_PQCONN_ASYNC
) {
1935 conn
= PQconnectStart(o
->dsn
);
1937 conn
= PQconnectdb(o
->dsn
);
1941 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
1947 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
1949 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
1951 /* we don't care for anything, except free'ing evdata */
1953 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
1954 memset(evdata
, 0, sizeof(*evdata
));
1961 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
1962 php_pqconn_resource_factory_ctor
,
1964 php_pqconn_resource_factory_dtor
1967 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1969 // FIXME: ping server
1972 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1974 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
1975 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1);
1977 if (quoted_channel
) {
1981 spprintf(&cmd
, 0, "UNLISTEN %s", quoted_channel
);
1982 if ((res
= PQexec(obj
->intern
->conn
, cmd
))) {
1987 PQfreemem(quoted_channel
);
1990 return ZEND_HASH_APPLY_REMOVE
;
1993 static void php_pqconn_notice_ignore(void *p
, const PGresult
*res
)
1997 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1999 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
2004 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
2006 /* ignore notices */
2007 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
2009 /* cancel async queries */
2010 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
2011 char err
[256] = {0};
2013 PQcancel(cancel
, err
, sizeof(err
));
2014 PQfreeCancel(cancel
);
2016 /* clean up async results */
2017 while ((res
= PQgetResult(*handle
))) {
2021 /* clean up transaction & session */
2022 switch (PQtransactionStatus(*handle
)) {
2024 res
= PQexec(*handle
, "RESET ALL");
2027 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
2036 /* clean up notify listeners */
2037 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
2039 /* release instance data */
2040 memset(evdata
, 0, sizeof(*evdata
));
2045 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
2046 ZEND_ARG_INFO(0, dsn
)
2047 ZEND_ARG_INFO(0, async
)
2048 ZEND_END_ARG_INFO();
2049 static PHP_METHOD(pqconn
, __construct
) {
2050 zend_error_handling zeh
;
2056 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2057 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
);
2058 zend_restore_error_handling(&zeh TSRMLS_CC
);
2060 if (SUCCESS
== rv
) {
2061 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2064 throw_exce(EX_BAD_METHODCALL TSRMLS_CC
, "pq\\Connection already initialized");
2066 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
2067 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
2069 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
2071 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
2072 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
2074 if (flags
& PHP_PQCONN_PERSISTENT
) {
2075 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
);
2076 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
2078 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
2081 if (flags
& PHP_PQCONN_ASYNC
) {
2082 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
2085 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
2087 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
2088 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
2090 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
2091 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2097 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
2098 ZEND_END_ARG_INFO();
2099 static PHP_METHOD(pqconn
, reset
) {
2100 zend_error_handling zeh
;
2103 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2104 rv
= zend_parse_parameters_none();
2105 zend_restore_error_handling(&zeh TSRMLS_CC
);
2107 if (SUCCESS
== rv
) {
2108 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2111 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2113 PQreset(obj
->intern
->conn
);
2115 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
2116 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2119 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2124 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
2125 ZEND_END_ARG_INFO();
2126 static PHP_METHOD(pqconn
, resetAsync
) {
2127 zend_error_handling zeh
;
2130 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2131 rv
= zend_parse_parameters_none();
2132 zend_restore_error_handling(&zeh TSRMLS_CC
);
2134 if (SUCCESS
== rv
) {
2135 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2138 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2140 if (!PQresetStart(obj
->intern
->conn
)) {
2141 throw_exce(EX_IO TSRMLS_CC
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2143 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
2146 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2151 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
)
2153 HashTable ht
, *existing_listeners
;
2155 php_pq_callback_addref(listener
);
2157 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
2158 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
2160 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
2161 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
2162 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
2166 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
2167 ZEND_ARG_INFO(0, channel
)
2168 ZEND_ARG_INFO(0, callable
)
2169 ZEND_END_ARG_INFO();
2170 static PHP_METHOD(pqconn
, listen
) {
2171 zend_error_handling zeh
;
2172 char *channel_str
= NULL
;
2173 int channel_len
= 0;
2174 php_pq_callback_t listener
;
2177 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2178 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2179 zend_restore_error_handling(&zeh TSRMLS_CC
);
2181 if (SUCCESS
== rv
) {
2182 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2185 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2187 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2189 if (!quoted_channel
) {
2190 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2193 smart_str cmd
= {0};
2195 smart_str_appends(&cmd
, "LISTEN ");
2196 smart_str_appends(&cmd
, quoted_channel
);
2199 res
= PQexec(obj
->intern
->conn
, cmd
.c
);
2201 smart_str_free(&cmd
);
2202 PQfreemem(quoted_channel
);
2205 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2207 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2208 obj
->intern
->poller
= PQconsumeInput
;
2209 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2214 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2220 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
2221 ZEND_ARG_INFO(0, channel
)
2222 ZEND_ARG_INFO(0, callable
)
2223 ZEND_END_ARG_INFO();
2224 static PHP_METHOD(pqconn
, listenAsync
) {
2225 zend_error_handling zeh
;
2226 char *channel_str
= NULL
;
2227 int channel_len
= 0;
2228 php_pq_callback_t listener
;
2231 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2232 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2233 zend_restore_error_handling(&zeh TSRMLS_CC
);
2235 if (SUCCESS
== rv
) {
2236 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2239 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2241 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2243 if (!quoted_channel
) {
2244 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2246 smart_str cmd
= {0};
2248 smart_str_appends(&cmd
, "LISTEN ");
2249 smart_str_appends(&cmd
, quoted_channel
);
2252 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
2253 throw_exce(EX_IO TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2255 obj
->intern
->poller
= PQconsumeInput
;
2256 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2259 smart_str_free(&cmd
);
2260 PQfreemem(quoted_channel
);
2261 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2267 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
2268 ZEND_ARG_INFO(0, channel
)
2269 ZEND_ARG_INFO(0, message
)
2270 ZEND_END_ARG_INFO();
2271 static PHP_METHOD(pqconn
, notify
) {
2272 zend_error_handling zeh
;
2273 char *channel_str
, *message_str
;
2274 int channel_len
, message_len
;
2277 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2278 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2279 zend_restore_error_handling(&zeh TSRMLS_CC
);
2281 if (SUCCESS
== rv
) {
2282 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2285 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2288 char *params
[2] = {channel_str
, message_str
};
2290 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
2293 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2295 php_pqres_success(res TSRMLS_CC
);
2299 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2304 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
2305 ZEND_ARG_INFO(0, channel
)
2306 ZEND_ARG_INFO(0, message
)
2307 ZEND_END_ARG_INFO();
2308 static PHP_METHOD(pqconn
, notifyAsync
) {
2309 zend_error_handling zeh
;
2310 char *channel_str
, *message_str
;
2311 int channel_len
, message_len
;
2314 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2315 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2316 zend_restore_error_handling(&zeh TSRMLS_CC
);
2318 if (SUCCESS
== rv
) {
2319 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2322 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2324 char *params
[2] = {channel_str
, message_str
};
2326 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
2327 throw_exce(EX_IO TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2329 obj
->intern
->poller
= PQconsumeInput
;
2332 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2337 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
2338 ZEND_END_ARG_INFO();
2339 static PHP_METHOD(pqconn
, poll
) {
2340 zend_error_handling zeh
;
2343 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2344 rv
= zend_parse_parameters_none();
2345 zend_restore_error_handling(&zeh TSRMLS_CC
);
2347 if (SUCCESS
== rv
) {
2348 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2351 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2352 } else if (!obj
->intern
->poller
) {
2353 throw_exce(EX_RUNTIME TSRMLS_CC
, "No asynchronous operation active");
2355 if (obj
->intern
->poller
== PQconsumeInput
) {
2356 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
2358 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
2360 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2365 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
2366 ZEND_ARG_INFO(0, query
)
2367 ZEND_END_ARG_INFO();
2368 static PHP_METHOD(pqconn
, exec
) {
2369 zend_error_handling zeh
;
2374 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2375 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
);
2376 zend_restore_error_handling(&zeh TSRMLS_CC
);
2378 if (SUCCESS
== rv
) {
2379 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2382 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2384 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
2387 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2388 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2389 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2394 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2399 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
2400 ZEND_END_ARG_INFO();
2401 static PHP_METHOD(pqconn
, getResult
) {
2402 zend_error_handling zeh
;
2405 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2406 rv
= zend_parse_parameters_none();
2407 zend_restore_error_handling(&zeh TSRMLS_CC
);
2409 if (SUCCESS
== rv
) {
2410 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2413 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connectio not initialized");
2415 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
2420 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2423 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2428 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
2429 ZEND_ARG_INFO(0, query
)
2430 ZEND_ARG_INFO(0, callable
)
2431 ZEND_END_ARG_INFO();
2432 static PHP_METHOD(pqconn
, execAsync
) {
2433 zend_error_handling zeh
;
2434 php_pq_callback_t resolver
= {{0}};
2439 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2440 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
2441 zend_restore_error_handling(&zeh TSRMLS_CC
);
2443 if (SUCCESS
== rv
) {
2444 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2447 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2448 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
2449 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2450 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2451 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2453 obj
->intern
->poller
= PQconsumeInput
;
2454 php_pq_callback_dtor(&obj
->intern
->onevent
);
2455 if (resolver
.fci
.size
> 0) {
2456 obj
->intern
->onevent
= resolver
;
2457 php_pq_callback_addref(&obj
->intern
->onevent
);
2459 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2464 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
2469 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
2470 convert_to_long_ex(ztype
);
2473 **types
= Z_LVAL_PP(ztype
);
2476 if (*ztype
!= *(zval
**)p
) {
2477 zval_ptr_dtor(ztype
);
2479 return ZEND_HASH_APPLY_KEEP
;
2482 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
2488 params
= (char ***) va_arg(argv
, char ***);
2489 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
2491 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
2495 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
2496 convert_to_string_ex(zparam
);
2499 **params
= Z_STRVAL_PP(zparam
);
2502 if (*zparam
!= *(zval
**)p
) {
2503 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
2506 return ZEND_HASH_APPLY_KEEP
;
2509 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
2511 int count
= zend_hash_num_elements(ht
);
2518 /* +1 for when less types than params are specified */
2519 *types
= tmp
= ecalloc(count
+ 1, sizeof(**types
));
2520 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
2526 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
2528 int count
= zend_hash_num_elements(ht
);
2535 *params
= tmp
= ecalloc(count
, sizeof(char *));
2536 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
2542 static Oid *php_pq_ntypes_to_array(zend_bool fill, int argc, ...)
2545 Oid *oids = ecalloc(argc + 1, sizeof(*oids));
2548 va_start(argv, argc);
2549 for (i = 0; i < argc; ++i) {
2551 oids[i] = va_arg(argv, Oid);
2561 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
2562 ZEND_ARG_INFO(0, query
)
2563 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2564 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2565 ZEND_END_ARG_INFO();
2566 static PHP_METHOD(pqconn
, execParams
) {
2567 zend_error_handling zeh
;
2571 zval
*ztypes
= NULL
;
2574 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2575 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
2576 zend_restore_error_handling(&zeh TSRMLS_CC
);
2578 if (SUCCESS
== rv
) {
2579 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2582 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2587 char **params
= NULL
;
2590 ZEND_INIT_SYMTABLE(&zdtor
);
2591 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2594 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2597 res
= PQexecParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
2599 zend_hash_destroy(&zdtor
);
2608 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2610 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2611 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2616 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2622 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
2623 ZEND_ARG_INFO(0, query
)
2624 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2625 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2626 ZEND_ARG_INFO(0, callable
)
2627 ZEND_END_ARG_INFO();
2628 static PHP_METHOD(pqconn
, execParamsAsync
) {
2629 zend_error_handling zeh
;
2630 php_pq_callback_t resolver
= {{0}};
2634 zval
*ztypes
= NULL
;
2637 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2638 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
2639 zend_restore_error_handling(&zeh TSRMLS_CC
);
2641 if (SUCCESS
== rv
) {
2642 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2645 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2649 char **params
= NULL
;
2652 ZEND_INIT_SYMTABLE(&zdtor
);
2653 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2656 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2659 if (!PQsendQueryParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
2660 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2661 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2662 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2664 obj
->intern
->poller
= PQconsumeInput
;
2665 php_pq_callback_dtor(&obj
->intern
->onevent
);
2666 if (resolver
.fci
.size
> 0) {
2667 obj
->intern
->onevent
= resolver
;
2668 php_pq_callback_addref(&obj
->intern
->onevent
);
2670 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2673 zend_hash_destroy(&zdtor
);
2682 zend_restore_error_handling(&zeh TSRMLS_CC
);
2685 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2693 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2697 count
= zend_hash_num_elements(typest
);
2698 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2701 res
= PQprepare(obj
->intern
->conn
, name
, query
, count
, types
);
2709 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2711 rv
= php_pqres_success(res TSRMLS_CC
);
2713 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2719 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
2720 ZEND_ARG_INFO(0, type
)
2721 ZEND_ARG_INFO(0, query
)
2722 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2723 ZEND_END_ARG_INFO();
2724 static PHP_METHOD(pqconn
, prepare
) {
2725 zend_error_handling zeh
;
2726 zval
*ztypes
= NULL
;
2727 char *name_str
, *query_str
;
2728 int name_len
, *query_len
;
2731 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2732 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2733 zend_restore_error_handling(&zeh TSRMLS_CC
);
2735 if (SUCCESS
== rv
) {
2736 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2739 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2740 } else if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2741 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2743 php_pq_object_addref(obj TSRMLS_CC
);
2745 stm
->name
= estrdup(name_str
);
2746 ZEND_INIT_SYMTABLE(&stm
->bound
);
2748 return_value
->type
= IS_OBJECT
;
2749 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2754 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2761 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2765 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2768 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, count
, types
)) {
2770 throw_exce(EX_IO TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2771 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2773 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2776 obj
->intern
->poller
= PQconsumeInput
;
2777 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2787 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
2788 ZEND_ARG_INFO(0, type
)
2789 ZEND_ARG_INFO(0, query
)
2790 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2791 ZEND_END_ARG_INFO();
2792 static PHP_METHOD(pqconn
, prepareAsync
) {
2793 zend_error_handling zeh
;
2794 zval
*ztypes
= NULL
;
2795 char *name_str
, *query_str
;
2796 int name_len
, *query_len
;
2799 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2800 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2801 zend_restore_error_handling(&zeh TSRMLS_CC
);
2803 if (SUCCESS
== rv
) {
2804 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2807 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2808 } else if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2809 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2811 php_pq_object_addref(obj TSRMLS_CC
);
2813 stm
->name
= estrdup(name_str
);
2814 ZEND_INIT_SYMTABLE(&stm
->bound
);
2816 return_value
->type
= IS_OBJECT
;
2817 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2822 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
2823 ZEND_ARG_INFO(0, string
)
2824 ZEND_END_ARG_INFO();
2825 static PHP_METHOD(pqconn
, quote
) {
2829 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2830 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2833 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2835 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
2838 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2841 RETVAL_STRING(quoted
, 1);
2848 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
2849 ZEND_ARG_INFO(0, type
)
2850 ZEND_END_ARG_INFO();
2851 static PHP_METHOD(pqconn
, quoteName
) {
2855 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2856 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2859 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2861 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
2864 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2867 RETVAL_STRING(quoted
, 1);
2874 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
2875 ZEND_ARG_INFO(0, bytea
)
2876 ZEND_END_ARG_INFO();
2877 static PHP_METHOD(pqconn
, escapeBytea
) {
2881 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2882 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2885 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2888 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
2891 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2894 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
2895 PQfreemem(escaped_str
);
2901 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
2902 ZEND_ARG_INFO(0, bytea
)
2903 ZEND_END_ARG_INFO();
2904 static PHP_METHOD(pqconn
, unescapeBytea
) {
2908 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2909 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2912 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2914 size_t unescaped_len
;
2915 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
2917 if (!unescaped_str
) {
2918 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2921 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
2922 PQfreemem(unescaped_str
);
2928 static const char *isolation_level(long *isolation
) {
2929 switch (*isolation
) {
2930 case PHP_PQTXN_SERIALIZABLE
:
2931 return "SERIALIZABLE";
2932 case PHP_PQTXN_REPEATABLE_READ
:
2933 return "REPEATABLE READ";
2935 *isolation
= PHP_PQTXN_READ_COMMITTED
;
2937 case PHP_PQTXN_READ_COMMITTED
:
2938 return "READ COMMITTED";
2942 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2944 STATUS rv
= FAILURE
;
2947 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2950 if (!conn_obj
->intern
) {
2951 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2954 smart_str cmd
= {0};
2955 const char *il
= isolation_level(&isolation
);
2957 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2958 smart_str_appends(&cmd
, il
);
2959 smart_str_appends(&cmd
, ", READ ");
2960 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2961 smart_str_appends(&cmd
, ",");
2962 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
2963 smart_str_appends(&cmd
, " DEFERRABLE");
2966 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
2969 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2971 rv
= php_pqres_success(res TSRMLS_CC
);
2973 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2976 smart_str_free(&cmd
);
2982 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
)
2984 STATUS rv
= FAILURE
;
2987 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2990 if (!conn_obj
->intern
) {
2991 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2993 smart_str cmd
= {0};
2994 const char *il
= isolation_level(&isolation
);
2996 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2997 smart_str_appends(&cmd
, il
);
2998 smart_str_appends(&cmd
, ", READ ");
2999 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
3000 smart_str_appends(&cmd
, ",");
3001 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
3002 smart_str_appends(&cmd
, " DEFERRABLE");
3005 if (!PQsendQuery(conn_obj
->intern
->conn
, cmd
.c
)) {
3006 throw_exce(EX_IO TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
3009 conn_obj
->intern
->poller
= PQconsumeInput
;
3010 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
3013 smart_str_free(&cmd
);
3019 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
3020 ZEND_ARG_INFO(0, isolation
)
3021 ZEND_ARG_INFO(0, readonly
)
3022 ZEND_ARG_INFO(0, deferrable
)
3023 ZEND_END_ARG_INFO();
3024 static PHP_METHOD(pqconn
, startTransaction
) {
3025 zend_error_handling zeh
;
3026 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3027 zend_bool readonly
= 0, deferrable
= 0;
3030 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3031 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
3032 zend_restore_error_handling(&zeh TSRMLS_CC
);
3034 if (SUCCESS
== rv
) {
3035 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3037 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3039 if (SUCCESS
== rv
) {
3040 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
3042 php_pq_object_addref(obj TSRMLS_CC
);
3045 txn
->isolation
= isolation
;
3046 txn
->readonly
= readonly
;
3047 txn
->deferrable
= deferrable
;
3049 return_value
->type
= IS_OBJECT
;
3050 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3055 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
3056 ZEND_ARG_INFO(0, isolation
)
3057 ZEND_ARG_INFO(0, readonly
)
3058 ZEND_ARG_INFO(0, deferrable
)
3059 ZEND_END_ARG_INFO();
3060 static PHP_METHOD(pqconn
, startTransactionAsync
) {
3061 zend_error_handling zeh
;
3062 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3063 zend_bool readonly
= 0, deferrable
= 0;
3066 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3067 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
3068 zend_restore_error_handling(&zeh TSRMLS_CC
);
3069 if (SUCCESS
== rv
) {
3070 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3072 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3074 if (SUCCESS
== rv
) {
3075 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
3077 php_pq_object_addref(obj TSRMLS_CC
);
3079 txn
->isolation
= isolation
;
3080 txn
->readonly
= readonly
;
3081 txn
->deferrable
= deferrable
;
3083 return_value
->type
= IS_OBJECT
;
3084 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3089 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
3090 ZEND_ARG_INFO(0, stdio_stream
)
3091 ZEND_END_ARG_INFO();
3092 static PHP_METHOD(pqconn
, trace
) {
3093 zval
*zstream
= NULL
;
3095 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
3096 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3099 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3102 PQuntrace(obj
->intern
->conn
);
3106 php_stream
*stream
= NULL
;
3108 php_stream_from_zval(stream
, &zstream
);
3110 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
3113 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
3114 PQtrace(obj
->intern
->conn
, fp
);
3122 static zend_function_entry php_pqconn_methods
[] = {
3123 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3124 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
3125 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
3126 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
3127 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
3128 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
3129 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
3130 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
3131 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
3132 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
3133 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
3134 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
3135 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
3136 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
3137 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
3138 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
3139 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
3140 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
3141 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
3142 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
3143 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
3144 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
3148 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct
, 0, 0, 1)
3149 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3150 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3151 ZEND_END_ARG_INFO();
3152 static PHP_METHOD(pqtypes
, __construct
) {
3153 zend_error_handling zeh
;
3154 zval
*zconn
, *znsp
= NULL
;
3157 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3158 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|a!", &zconn
, php_pqconn_class_entry
, &znsp
);
3159 zend_restore_error_handling(&zeh TSRMLS_CC
);
3161 if (SUCCESS
== rv
) {
3162 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3164 if (!conn_obj
->intern
) {
3165 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3167 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3168 zval
*retval
= NULL
;
3170 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3171 obj
->intern
->conn
= conn_obj
;
3172 php_pq_object_addref(conn_obj TSRMLS_CC
);
3173 zend_hash_init(&obj
->intern
->types
, 300, NULL
, ZVAL_PTR_DTOR
, 0);
3176 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
, znsp
);
3178 zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
);
3182 zval_ptr_dtor(&retval
);
3188 #define PHP_PQ_TYPES_QUERY \
3189 "select t.oid, t.* " \
3190 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
3191 "where typisdefined " \
3193 #define PHP_PQ_OID_TEXT 25
3195 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh
, 0, 0, 0)
3196 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3197 ZEND_END_ARG_INFO();
3198 static PHP_METHOD(pqtypes
, refresh
) {
3199 HashTable
*nsp
= NULL
;
3200 zend_error_handling zeh
;
3203 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3204 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|H/!", &nsp
);
3205 zend_restore_error_handling(&zeh TSRMLS_CC
);
3207 if (SUCCESS
== rv
) {
3208 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3211 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Types not initialized");
3215 if (!nsp
|| !zend_hash_num_elements(nsp
)) {
3216 res
= PQexec(obj
->intern
->conn
->intern
->conn
, PHP_PQ_TYPES_QUERY
" and nspname in ('public', 'pg_catalog')");
3220 char **params
= NULL
;
3222 smart_str str
= {0};
3224 smart_str_appends(&str
, PHP_PQ_TYPES_QUERY
" and nspname in(");
3225 zend_hash_init(&zdtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
3226 count
= php_pq_params_to_array(nsp
, ¶ms
, &zdtor TSRMLS_CC
);
3227 oids
= ecalloc(count
+ 1, sizeof(*oids
));
3228 for (i
= 0; i
< count
; ++i
) {
3229 oids
[i
] = PHP_PQ_OID_TEXT
;
3231 smart_str_appendc(&str
, ',');
3233 smart_str_appendc(&str
, '$');
3234 smart_str_append_unsigned(&str
, i
+1);
3236 smart_str_appendc(&str
, ')');
3239 res
= PQexecParams(obj
->intern
->conn
->intern
->conn
, str
.c
, count
, oids
, (const char *const*) params
, NULL
, NULL
, 0);
3241 smart_str_free(&str
);
3244 zend_hash_destroy(&zdtor
);
3248 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3250 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3253 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
3254 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT
, NULL TSRMLS_CC
);
3255 long oid
= atol(PQgetvalue(res
, r
, 0 ));
3256 char *name
= PQgetvalue(res
, r
, 1);
3260 zend_hash_index_update(&obj
->intern
->types
, oid
, (void *) &row
, sizeof(zval
*), NULL
);
3261 zend_hash_add(&obj
->intern
->types
, name
, strlen(name
) + 1, (void *) &row
, sizeof(zval
*), NULL
);
3266 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3272 static zend_function_entry php_pqtypes_methods
[] = {
3273 PHP_ME(pqtypes
, __construct
, ai_pqtypes_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3274 PHP_ME(pqtypes
, refresh
, ai_pqtypes_refresh
, ZEND_ACC_PUBLIC
)
3278 static STATUS
php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type
, zval
***row TSRMLS_DC
)
3281 php_pqres_fetch_t orig_fetch
;
3284 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3287 if (!obj
->intern
->iter
) {
3288 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
3289 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3291 orig_fetch
= obj
->intern
->iter
->fetch_type
;
3292 obj
->intern
->iter
->fetch_type
= fetch_type
;
3293 if (SUCCESS
== (rv
= obj
->intern
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
))) {
3294 obj
->intern
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->intern
->iter
, row TSRMLS_CC
);
3295 obj
->intern
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3297 obj
->intern
->iter
->fetch_type
= orig_fetch
;
3302 typedef struct php_pqres_col
{
3307 static STATUS
column_nn(php_pqres_object_t
*obj
, zval
*zcol
, php_pqres_col_t
*col TSRMLS_DC
)
3312 switch (Z_TYPE_P(zcol
)) {
3314 convert_to_string(zcol
);
3318 if (!is_numeric_string(Z_STRVAL_P(zcol
), Z_STRLEN_P(zcol
), &index
, NULL
, 0)) {
3319 name
= Z_STRVAL_P(zcol
);
3324 index
= Z_LVAL_P(zcol
);
3330 col
->num
= PQfnumber(obj
->intern
->res
, name
);
3332 col
->name
= PQfname(obj
->intern
->res
, index
);
3337 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column at index %ld", index
);
3340 if (col
->num
== -1) {
3341 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column with name '%s'", name
);
3347 static int compare_index(const void *lptr
, const void *rptr TSRMLS_DC
)
3349 const Bucket
*l
= *(const Bucket
**) lptr
;
3350 const Bucket
*r
= *(const Bucket
**) rptr
;
3361 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind
, 0, 0, 2)
3362 ZEND_ARG_INFO(0, col
)
3363 ZEND_ARG_INFO(1, ref
)
3364 ZEND_END_ARG_INFO();
3365 static PHP_METHOD(pqres
, bind
) {
3368 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z/z", &zcol
, &zref
)) {
3369 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3372 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3374 php_pqres_col_t col
;
3376 if (SUCCESS
!= column_nn(obj
, zcol
, &col TSRMLS_CC
)) {
3381 if (SUCCESS
!= zend_hash_index_update(&obj
->intern
->bound
, col
.num
, (void *) &zref
, sizeof(zval
*), NULL
)) {
3382 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to bind column %s@%d", col
.name
, col
.num
);
3385 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3393 static int apply_bound(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3395 zval
**zvalue
, **zbound
= p
;
3396 zval
**zrow
= va_arg(argv
, zval
**);
3397 STATUS
*rv
= va_arg(argv
, STATUS
*);
3399 if (SUCCESS
!= zend_hash_index_find(Z_ARRVAL_PP(zrow
), key
->h
, (void *) &zvalue
)) {
3400 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column ad index %lu", key
->h
);
3402 return ZEND_HASH_APPLY_STOP
;
3405 ZVAL_COPY_VALUE(*zbound
, *zvalue
);
3407 zval_ptr_dtor(zvalue
);
3408 Z_ADDREF_P(*zbound
);
3411 return ZEND_HASH_APPLY_KEEP
;
3415 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound
, 0, 0, 0)
3416 ZEND_END_ARG_INFO();
3417 static PHP_METHOD(pqres
, fetchBound
) {
3418 zend_error_handling zeh
;
3421 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3422 rv
= zend_parse_parameters_none();
3423 zend_restore_error_handling(&zeh TSRMLS_CC
);
3425 if (SUCCESS
== rv
) {
3426 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3429 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3433 if (SUCCESS
== php_pqres_iteration(getThis(), obj
, PHP_PQRES_FETCH_ARRAY
, &row TSRMLS_CC
) && row
) {
3434 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3435 zend_hash_apply_with_arguments(&obj
->intern
->bound TSRMLS_CC
, apply_bound
, 2, row
, &rv
);
3436 zend_restore_error_handling(&zeh TSRMLS_CC
);
3438 if (SUCCESS
!= rv
) {
3441 RETVAL_ZVAL(*row
, 1, 0);
3448 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
3449 ZEND_ARG_INFO(0, fetch_type
)
3450 ZEND_END_ARG_INFO();
3451 static PHP_METHOD(pqres
, fetchRow
) {
3452 zend_error_handling zeh
;
3453 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3454 long fetch_type
= -1;
3457 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3458 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3459 zend_restore_error_handling(&zeh TSRMLS_CC
);
3461 if (SUCCESS
== rv
) {
3463 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3467 if (fetch_type
== -1) {
3468 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3471 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3472 php_pqres_iteration(getThis(), obj
, fetch_type
, &row TSRMLS_CC
);
3473 zend_restore_error_handling(&zeh TSRMLS_CC
);
3476 RETVAL_ZVAL(*row
, 1, 0);
3482 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
3485 HashTable
*ht
= HASH_OF(row
);
3486 int count
= zend_hash_num_elements(ht
);
3489 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
3491 zend_hash_internal_pointer_reset(ht
);
3493 zend_hash_move_forward(ht
);
3495 zend_hash_get_current_data(ht
, (void *) &data
);
3500 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
3501 ZEND_ARG_INFO(0, col_num
)
3502 ZEND_END_ARG_INFO();
3503 static PHP_METHOD(pqres
, fetchCol
) {
3504 zend_error_handling zeh
;
3508 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3509 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
);
3510 zend_restore_error_handling(&zeh TSRMLS_CC
);
3512 if (SUCCESS
== rv
) {
3513 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3516 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3520 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3521 php_pqres_iteration(getThis(), obj
, obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: 0, &row TSRMLS_CC
);
3523 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
3526 RETVAL_ZVAL(*col
, 1, 0);
3529 zend_restore_error_handling(&zeh TSRMLS_CC
);
3534 static int apply_to_col(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3537 php_pqres_object_t
*obj
= va_arg(argv
, php_pqres_object_t
*);
3538 php_pqres_col_t
*col
, **cols
= va_arg(argv
, php_pqres_col_t
**);
3539 STATUS
*rv
= va_arg(argv
, STATUS
*);
3543 if (SUCCESS
!= column_nn(obj
, *c
, col TSRMLS_CC
)) {
3545 return ZEND_HASH_APPLY_STOP
;
3549 return ZEND_HASH_APPLY_KEEP
;
3553 static php_pqres_col_t
*php_pqres_convert_to_cols(php_pqres_object_t
*obj
, HashTable
*ht TSRMLS_DC
)
3555 php_pqres_col_t
*tmp
, *cols
= ecalloc(zend_hash_num_elements(ht
), sizeof(*cols
));
3556 STATUS rv
= SUCCESS
;
3559 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_col
, 2, obj
, &tmp
, &rv
);
3561 if (SUCCESS
== rv
) {
3569 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map
, 0, 0, 0)
3570 ZEND_ARG_INFO(0, keys
)
3571 ZEND_ARG_INFO(0, vals
)
3572 ZEND_ARG_INFO(0, fetch_type
)
3573 ZEND_END_ARG_INFO();
3574 static PHP_METHOD(pqres
, map
) {
3575 zend_error_handling zeh
;
3576 zval
*zkeys
= 0, *zvals
= 0;
3577 long fetch_type
= -1;
3580 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3581 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z/!z/!l", &zkeys
, &zvals
, &fetch_type
);
3582 zend_restore_error_handling(&zeh TSRMLS_CC
);
3584 if (SUCCESS
== rv
) {
3585 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3588 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3591 php_pqres_col_t def
= {PQfname(obj
->intern
->res
, 0), 0}, *keys
= NULL
, *vals
= NULL
;
3594 convert_to_array(zkeys
);
3596 if ((ks
= zend_hash_num_elements(Z_ARRVAL_P(zkeys
)))) {
3597 keys
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zkeys
) TSRMLS_CC
);
3607 convert_to_array(zvals
);
3609 if ((vs
= zend_hash_num_elements(Z_ARRVAL_P(zvals
)))) {
3610 vals
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zvals
) TSRMLS_CC
);
3614 if (fetch_type
== -1) {
3615 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3622 switch (fetch_type
) {
3623 case PHP_PQRES_FETCH_ARRAY
:
3624 case PHP_PQRES_FETCH_ASSOC
:
3625 array_init(return_value
);
3627 case PHP_PQRES_FETCH_OBJECT
:
3628 object_init(return_value
);
3631 for (r
= 0, rows
= PQntuples(obj
->intern
->res
); r
< rows
; ++r
) {
3634 cur
= &return_value
;
3635 for (k
= 0; k
< ks
; ++k
) {
3636 char *key
= PQgetvalue(obj
->intern
->res
, r
, keys
[k
].num
);
3637 int len
= PQgetlength(obj
->intern
->res
, r
, keys
[k
].num
);
3639 if (SUCCESS
!= zend_symtable_find(HASH_OF(*cur
), key
, len
+ 1, (void *) &cur
)) {
3643 switch (fetch_type
) {
3644 case PHP_PQRES_FETCH_ARRAY
:
3645 case PHP_PQRES_FETCH_ASSOC
:
3648 case PHP_PQRES_FETCH_OBJECT
:
3652 if (SUCCESS
!= zend_symtable_update(HASH_OF(*cur
), key
, len
+ 1, (void *) &tmp
, sizeof(zval
*), (void *) &cur
)) {
3653 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create map");
3659 for (v
= 0; v
< vs
; ++v
) {
3660 char *val
= PQgetvalue(obj
->intern
->res
, r
, vals
[v
].num
);
3661 int len
= PQgetlength(obj
->intern
->res
, r
, vals
[v
].num
);
3663 switch (fetch_type
) {
3664 case PHP_PQRES_FETCH_ARRAY
:
3665 add_index_stringl(*cur
, vals
[v
].num
, val
, len
, 1);
3667 case PHP_PQRES_FETCH_ASSOC
:
3668 add_assoc_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3670 case PHP_PQRES_FETCH_OBJECT
:
3671 add_property_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3676 php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, cur TSRMLS_CC
);
3682 if (keys
&& keys
!= &def
) {
3692 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all
, 0, 0, 0)
3693 ZEND_ARG_INFO(0, fetch_type
)
3694 ZEND_END_ARG_INFO();
3695 static PHP_METHOD(pqres
, fetchAll
) {
3696 zend_error_handling zeh
;
3697 long fetch_type
= -1;
3700 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3701 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3702 zend_restore_error_handling(&zeh TSRMLS_CC
);
3704 if (SUCCESS
== rv
) {
3705 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3707 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3709 int r
, rows
= PQntuples(obj
->intern
->res
);
3711 if (fetch_type
== -1) {
3712 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3715 array_init(return_value
);
3716 for (r
= 0; r
< rows
; ++r
) {
3717 add_next_index_zval(return_value
, php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, NULL TSRMLS_CC
));
3723 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count
, 0, 0, 0)
3724 ZEND_END_ARG_INFO();
3725 static PHP_METHOD(pqres
, count
) {
3726 if (SUCCESS
== zend_parse_parameters_none()) {
3729 if (SUCCESS
!= php_pqres_count_elements(getThis(), &count TSRMLS_CC
)) {
3730 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3737 static zend_function_entry php_pqres_methods
[] = {
3738 PHP_ME(pqres
, bind
, ai_pqres_bind
, ZEND_ACC_PUBLIC
)
3739 PHP_ME(pqres
, fetchBound
, ai_pqres_fetch_bound
, ZEND_ACC_PUBLIC
)
3740 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
3741 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
3742 PHP_ME(pqres
, fetchAll
, ai_pqres_fetch_all
, ZEND_ACC_PUBLIC
)
3743 PHP_ME(pqres
, count
, ai_pqres_count
, ZEND_ACC_PUBLIC
)
3744 PHP_ME(pqres
, map
, ai_pqres_map
, ZEND_ACC_PUBLIC
)
3748 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
3749 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
3750 ZEND_ARG_INFO(0, type
)
3751 ZEND_ARG_INFO(0, query
)
3752 ZEND_ARG_ARRAY_INFO(0, types
, 1)
3753 ZEND_ARG_INFO(0, async
)
3754 ZEND_END_ARG_INFO();
3755 static PHP_METHOD(pqstm
, __construct
) {
3756 zend_error_handling zeh
;
3757 zval
*zconn
, *ztypes
= NULL
;
3758 char *name_str
, *query_str
;
3759 int name_len
, *query_len
;
3760 zend_bool async
= 0;
3763 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3764 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
);
3765 zend_restore_error_handling(&zeh TSRMLS_CC
);
3767 if (SUCCESS
== rv
) {
3768 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3769 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3771 if (!conn_obj
->intern
) {
3772 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3775 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3777 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3780 if (SUCCESS
== rv
) {
3781 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
3783 php_pq_object_addref(conn_obj TSRMLS_CC
);
3784 stm
->conn
= conn_obj
;
3785 stm
->name
= estrdup(name_str
);
3786 ZEND_INIT_SYMTABLE(&stm
->bound
);
3792 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind
, 0, 0, 2)
3793 ZEND_ARG_INFO(0, param_no
)
3794 ZEND_ARG_INFO(1, param_ref
)
3795 ZEND_END_ARG_INFO();
3796 static PHP_METHOD(pqstm
, bind
) {
3800 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "lz", ¶m_no
, ¶m_ref
)) {
3801 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3804 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3806 Z_ADDREF_P(param_ref
);
3807 zend_hash_index_update(&obj
->intern
->bound
, param_no
, (void *) ¶m_ref
, sizeof(zval
*), NULL
);
3808 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3813 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
3814 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3815 ZEND_END_ARG_INFO();
3816 static PHP_METHOD(pqstm
, exec
) {
3817 zend_error_handling zeh
;
3818 zval
*zparams
= NULL
;
3821 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3822 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
);
3823 zend_restore_error_handling(&zeh TSRMLS_CC
);
3825 if (SUCCESS
== rv
) {
3826 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3829 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3832 char **params
= NULL
;
3836 ZEND_INIT_SYMTABLE(&zdtor
);
3839 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3841 count
= php_pq_params_to_array(&obj
->intern
->bound
, ¶ms
, &zdtor TSRMLS_CC
);
3844 res
= PQexecPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
3849 zend_hash_destroy(&zdtor
);
3852 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3853 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3854 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
3855 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3861 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
3862 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3863 ZEND_ARG_INFO(0, callable
)
3864 ZEND_END_ARG_INFO();
3865 static PHP_METHOD(pqstm
, execAsync
) {
3866 zend_error_handling zeh
;
3867 zval
*zparams
= NULL
;
3868 php_pq_callback_t resolver
= {{0}};
3871 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3872 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
);
3873 zend_restore_error_handling(&zeh TSRMLS_CC
);
3875 if (SUCCESS
== rv
) {
3876 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3879 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3882 char **params
= NULL
;
3886 ZEND_INIT_SYMTABLE(&zdtor
);
3887 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3890 if (!PQsendQueryPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
3891 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3892 } else if (obj
->intern
->conn
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
->intern
->conn
)) {
3893 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3895 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
3896 if (resolver
.fci
.size
> 0) {
3897 obj
->intern
->conn
->intern
->onevent
= resolver
;
3898 php_pq_callback_addref(&obj
->intern
->conn
->intern
->onevent
);
3900 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3907 zend_hash_destroy(&zdtor
);
3910 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3915 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
3916 ZEND_END_ARG_INFO();
3917 static PHP_METHOD(pqstm
, desc
) {
3918 zend_error_handling zeh
;
3921 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3922 rv
= zend_parse_parameters_none();
3923 zend_restore_error_handling(&zeh TSRMLS_CC
);
3925 if (SUCCESS
== rv
) {
3926 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3929 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3931 PGresult
*res
= PQdescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
);
3934 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3936 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3939 array_init(return_value
);
3940 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
3941 add_next_index_long(return_value
, PQparamtype(res
, p
));
3945 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3951 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async
, 0, 0, 0)
3952 ZEND_END_ARG_INFO();
3953 static PHP_METHOD(pqstm
, descAsync
) {
3954 zend_error_handling zeh
;
3957 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3958 rv
= zend_parse_parameters_none();
3959 zend_restore_error_handling(&zeh TSRMLS_CC
);
3961 if (SUCCESS
== rv
) {
3962 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3965 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3966 } else if (!PQsendDescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
)) {
3967 throw_exce(EX_IO TSRMLS_CC
, "Failed to describe statement: %s", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3969 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3970 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3975 static zend_function_entry php_pqstm_methods
[] = {
3976 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3977 PHP_ME(pqstm
, bind
, ai_pqstm_bind
, ZEND_ACC_PUBLIC
)
3978 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
3979 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
3980 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
3981 PHP_ME(pqstm
, descAsync
, ai_pqstm_desc_async
, ZEND_ACC_PUBLIC
)
3985 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
3986 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3987 ZEND_ARG_INFO(0, async
)
3988 ZEND_ARG_INFO(0, isolation
)
3989 ZEND_ARG_INFO(0, readonly
)
3990 ZEND_ARG_INFO(0, deferrable
)
3991 ZEND_END_ARG_INFO();
3992 static PHP_METHOD(pqtxn
, __construct
) {
3993 zend_error_handling zeh
;
3995 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3996 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
3999 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4000 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
);
4001 zend_restore_error_handling(&zeh TSRMLS_CC
);
4003 if (SUCCESS
== rv
) {
4004 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4006 if (!conn_obj
->intern
) {
4007 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4010 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
4012 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
4015 if (SUCCESS
== rv
) {
4016 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4018 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4020 php_pq_object_addref(conn_obj TSRMLS_CC
);
4021 obj
->intern
->conn
= conn_obj
;
4022 obj
->intern
->open
= 1;
4023 obj
->intern
->isolation
= isolation
;
4024 obj
->intern
->readonly
= readonly
;
4025 obj
->intern
->deferrable
= deferrable
;
4031 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint
, 0, 0, 0)
4032 ZEND_END_ARG_INFO();
4033 static PHP_METHOD(pqtxn
, savepoint
) {
4034 zend_error_handling zeh
;
4037 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4038 rv
= zend_parse_parameters_none();
4039 zend_restore_error_handling(&zeh TSRMLS_CC
);
4041 if (SUCCESS
== rv
) {
4042 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4045 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4046 } else if (!obj
->intern
->open
) {
4047 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4050 smart_str cmd
= {0};
4052 smart_str_appends(&cmd
, "SAVEPOINT \"");
4053 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4054 smart_str_appends(&cmd
, "\"");
4057 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4060 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4062 php_pqres_success(res TSRMLS_CC
);
4066 smart_str_free(&cmd
);
4071 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async
, 0, 0, 0)
4072 ZEND_END_ARG_INFO();
4073 static PHP_METHOD(pqtxn
, savepointAsync
) {
4074 zend_error_handling zeh
;
4077 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4078 rv
= zend_parse_parameters_none();
4079 zend_restore_error_handling(&zeh TSRMLS_CC
);
4081 if (SUCCESS
== rv
) {
4082 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4085 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4086 } else if (!obj
->intern
->open
) {
4087 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4089 smart_str cmd
= {0};
4091 smart_str_appends(&cmd
, "SAVEPOINT \"");
4092 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4093 smart_str_appends(&cmd
, "\"");
4096 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4097 throw_exce(EX_IO TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4100 smart_str_free(&cmd
);
4105 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
4106 ZEND_END_ARG_INFO();
4107 static PHP_METHOD(pqtxn
, commit
) {
4108 zend_error_handling zeh
;
4111 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4112 rv
= zend_parse_parameters_none();
4113 zend_restore_error_handling(&zeh TSRMLS_CC
);
4115 if (SUCCESS
== rv
) {
4116 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4119 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transacation not initialized");
4120 } else if (!obj
->intern
->open
) {
4121 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transacation already closed");
4124 smart_str cmd
= {0};
4126 if (!obj
->intern
->savepoint
) {
4127 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4129 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4130 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4131 smart_str_appends(&cmd
, "\"");
4134 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4138 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4140 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4142 obj
->intern
->open
= 0;
4148 smart_str_free(&cmd
);
4149 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4154 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
4155 ZEND_END_ARG_INFO();
4156 static PHP_METHOD(pqtxn
, commitAsync
) {
4157 zend_error_handling zeh
;
4160 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4161 rv
= zend_parse_parameters_none();
4162 zend_restore_error_handling(&zeh TSRMLS_CC
);
4164 if (SUCCESS
== rv
) {
4165 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4168 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4169 } else if (!obj
->intern
->open
) {
4170 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4173 smart_str cmd
= {0};
4175 if (!obj
->intern
->savepoint
) {
4176 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4178 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4179 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4180 smart_str_appends(&cmd
, "\"");
4183 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4187 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commmit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4190 obj
->intern
->open
= 0;
4192 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4193 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4196 smart_str_free(&cmd
);
4201 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
4202 ZEND_END_ARG_INFO();
4203 static PHP_METHOD(pqtxn
, rollback
) {
4204 zend_error_handling zeh
;
4207 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4208 rv
= zend_parse_parameters_none();
4209 zend_restore_error_handling(&zeh TSRMLS_CC
);
4211 if (SUCCESS
== rv
) {
4212 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4215 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4216 } else if (!obj
->intern
->open
) {
4217 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4220 smart_str cmd
= {0};
4222 if (!obj
->intern
->savepoint
) {
4223 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4225 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4226 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4227 smart_str_appends(&cmd
, "\"");
4230 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4234 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4236 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4238 obj
->intern
->open
= 0;
4244 smart_str_free(&cmd
);
4245 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4250 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
4251 ZEND_END_ARG_INFO();
4252 static PHP_METHOD(pqtxn
, rollbackAsync
) {
4253 zend_error_handling zeh
;
4256 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4257 rv
= zend_parse_parameters_none();
4258 zend_restore_error_handling(&zeh TSRMLS_CC
);
4260 if (SUCCESS
== rv
) {
4261 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4264 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4265 } else if (!obj
->intern
->open
) {
4266 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4269 smart_str cmd
= {0};
4271 if (!obj
->intern
->savepoint
) {
4272 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4274 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4275 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4276 smart_str_appends(&cmd
, "\"");
4279 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4283 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4286 obj
->intern
->open
= 0;
4288 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4291 smart_str_free(&cmd
);
4292 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4297 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot
, 0, 0, 0)
4298 ZEND_END_ARG_INFO();
4299 static PHP_METHOD(pqtxn
, exportSnapshot
) {
4300 zend_error_handling zeh
;
4303 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4304 rv
= zend_parse_parameters_none();
4305 zend_restore_error_handling(&zeh TSRMLS_CC
);
4307 if (SUCCESS
== rv
) {
4308 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4311 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4313 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()");
4316 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4318 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4319 RETVAL_STRING(PQgetvalue(res
, 0, 0), 1);
4325 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4330 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async
, 0, 0, 0)
4331 ZEND_END_ARG_INFO();
4332 static PHP_METHOD(pqtxn
, exportSnapshotAsync
) {
4333 zend_error_handling zeh
;
4336 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4337 rv
= zend_parse_parameters_none();
4338 zend_restore_error_handling(&zeh TSRMLS_CC
);
4340 if (SUCCESS
== rv
) {
4341 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4344 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4345 } else if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()")) {
4346 throw_exce(EX_IO TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4348 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4349 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4354 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot
, 0, 0, 1)
4355 ZEND_ARG_INFO(0, snapshot_id
)
4356 ZEND_END_ARG_INFO();
4357 static PHP_METHOD(pqtxn
, importSnapshot
) {
4358 zend_error_handling zeh
;
4363 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4364 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4365 zend_restore_error_handling(&zeh TSRMLS_CC
);
4367 if (SUCCESS
== rv
) {
4368 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4371 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4372 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4373 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4375 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4378 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4381 smart_str cmd
= {0};
4383 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4384 smart_str_appends(&cmd
, sid
);
4387 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4390 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4392 php_pqres_success(res TSRMLS_CC
);
4396 smart_str_free(&cmd
);
4397 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4403 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async
, 0, 0, 1)
4404 ZEND_ARG_INFO(0, snapshot_id
)
4405 ZEND_END_ARG_INFO();
4406 static PHP_METHOD(pqtxn
, importSnapshotAsync
) {
4407 zend_error_handling zeh
;
4412 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4413 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4414 zend_restore_error_handling(&zeh TSRMLS_CC
);
4416 if (SUCCESS
== rv
) {
4417 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4420 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4421 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4422 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4424 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4427 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4429 smart_str cmd
= {0};
4431 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4432 smart_str_appends(&cmd
, sid
);
4435 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4436 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4438 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4441 smart_str_free(&cmd
);
4442 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4448 static const char *strmode(long mode
)
4450 switch (mode
& (INV_READ
|INV_WRITE
)) {
4451 case INV_READ
|INV_WRITE
:
4462 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob
, 0, 0, 1)
4463 ZEND_ARG_INFO(0, oid
)
4464 ZEND_ARG_INFO(0, mode
)
4465 ZEND_END_ARG_INFO();
4466 static PHP_METHOD(pqtxn
, openLOB
) {
4467 zend_error_handling zeh
;
4468 long mode
= INV_WRITE
|INV_READ
, loid
;
4471 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4472 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &loid
, &mode
);
4473 zend_restore_error_handling(&zeh TSRMLS_CC
);
4475 if (SUCCESS
== rv
) {
4476 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4479 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4481 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4484 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
));
4486 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4490 php_pq_object_addref(obj TSRMLS_CC
);
4493 return_value
->type
= IS_OBJECT
;
4494 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4497 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4502 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob
, 0, 0, 0)
4503 ZEND_ARG_INFO(0, mode
)
4504 ZEND_END_ARG_INFO();
4505 static PHP_METHOD(pqtxn
, createLOB
) {
4506 zend_error_handling zeh
;
4507 long mode
= INV_WRITE
|INV_READ
;
4510 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4511 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &mode
);
4512 zend_restore_error_handling(&zeh TSRMLS_CC
);
4514 if (SUCCESS
== rv
) {
4515 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4518 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4520 Oid loid
= lo_creat(obj
->intern
->conn
->intern
->conn
, mode
);
4522 if (loid
== InvalidOid
) {
4523 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create large object with mode '%s' (%s)", strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4525 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4528 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
));
4530 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4534 php_pq_object_addref(obj TSRMLS_CC
);
4537 return_value
->type
= IS_OBJECT
;
4538 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4542 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4547 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob
, 0, 0, 1)
4548 ZEND_ARG_INFO(0, oid
)
4549 ZEND_END_ARG_INFO();
4550 static PHP_METHOD(pqtxn
, unlinkLOB
) {
4551 zend_error_handling zeh
;
4555 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4556 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &loid
);
4557 zend_restore_error_handling(&zeh TSRMLS_CC
);
4559 if (SUCCESS
== rv
) {
4560 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4563 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4565 int rc
= lo_unlink(obj
->intern
->conn
->intern
->conn
, loid
);
4568 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to unlink LOB (oid=%ld): %s", loid
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4571 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4576 static zend_function_entry php_pqtxn_methods
[] = {
4577 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4578 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
4579 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
4580 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
4581 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
4582 PHP_ME(pqtxn
, savepoint
, ai_pqtxn_savepoint
, ZEND_ACC_PUBLIC
)
4583 PHP_ME(pqtxn
, savepointAsync
, ai_pqtxn_savepoint_async
, ZEND_ACC_PUBLIC
)
4584 PHP_ME(pqtxn
, exportSnapshot
, ai_pqtxn_export_snapshot
, ZEND_ACC_PUBLIC
)
4585 PHP_ME(pqtxn
, exportSnapshotAsync
, ai_pqtxn_export_snapshot_async
, ZEND_ACC_PUBLIC
)
4586 PHP_ME(pqtxn
, importSnapshot
, ai_pqtxn_import_snapshot
, ZEND_ACC_PUBLIC
)
4587 PHP_ME(pqtxn
, importSnapshotAsync
, ai_pqtxn_import_snapshot_async
, ZEND_ACC_PUBLIC
)
4588 PHP_ME(pqtxn
, openLOB
, ai_pqtxn_open_lob
, ZEND_ACC_PUBLIC
)
4589 PHP_ME(pqtxn
, createLOB
, ai_pqtxn_create_lob
, ZEND_ACC_PUBLIC
)
4590 PHP_ME(pqtxn
, unlinkLOB
, ai_pqtxn_unlink_lob
, ZEND_ACC_PUBLIC
)
4594 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
4595 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4596 ZEND_END_ARG_INFO();
4597 static PHP_METHOD(pqcancel
, __construct
) {
4598 zend_error_handling zeh
;
4602 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4603 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
);
4604 zend_restore_error_handling(&zeh TSRMLS_CC
);
4606 if (SUCCESS
== rv
) {
4607 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4609 if (!conn_obj
->intern
) {
4610 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4612 PGcancel
*cancel
= PQgetCancel(conn_obj
->intern
->conn
);
4615 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
4617 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4619 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4620 obj
->intern
->cancel
= cancel
;
4621 php_pq_object_addref(conn_obj TSRMLS_CC
);
4622 obj
->intern
->conn
= conn_obj
;
4628 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
4629 ZEND_END_ARG_INFO();
4630 static PHP_METHOD(pqcancel
, cancel
) {
4631 zend_error_handling zeh
;
4634 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4635 rv
= zend_parse_parameters_none();
4636 zend_restore_error_handling(&zeh TSRMLS_CC
);
4638 if (SUCCESS
== rv
) {
4639 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4642 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Cancel not initialized");
4644 char err
[256] = {0};
4646 if (!PQcancel(obj
->intern
->cancel
, err
, sizeof(err
))) {
4647 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to request cancellation (%s)", err
);
4653 static zend_function_entry php_pqcancel_methods
[] = {
4654 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4655 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
4659 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_construct
, 0, 0, 3)
4660 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4661 ZEND_ARG_INFO(0, type
)
4662 ZEND_ARG_INFO(0, callable
)
4663 ZEND_END_ARG_INFO();
4664 static PHP_METHOD(pqevent
, __construct
) {
4665 zend_error_handling zeh
;
4669 php_pq_callback_t cb
;
4672 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4673 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Osf", &zconn
, php_pqconn_class_entry
, &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
4674 zend_restore_error_handling(&zeh TSRMLS_CC
);
4676 if (SUCCESS
== rv
) {
4677 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4679 if (!conn_obj
->intern
) {
4680 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4682 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4684 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4685 php_pq_callback_addref(&cb
);
4686 obj
->intern
->cb
= cb
;
4687 obj
->intern
->type
= estrdup(type_str
);
4688 obj
->intern
->h
= php_pqconn_add_eventhandler(conn_obj
, type_str
, type_len
, getThis() TSRMLS_CC
);
4693 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_trigger
, 0, 0, 1)
4694 ZEND_ARG_ARRAY_INFO(0, args
, 1)
4695 ZEND_END_ARG_INFO();
4696 static PHP_METHOD(pqevent
, trigger
) {
4697 zend_error_handling zeh
;
4701 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4702 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a/", &args
);
4703 zend_restore_error_handling(&zeh TSRMLS_CC
);
4705 if (SUCCESS
== rv
) {
4706 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4709 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Event not initialized");
4713 if (SUCCESS
!= zend_fcall_info_call(&obj
->intern
->cb
.fci
, &obj
->intern
->cb
.fcc
, &rv
, args TSRMLS_CC
)) {
4714 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to trigger event");
4717 RETVAL_ZVAL(rv
, 0, 1);
4726 static zend_function_entry php_pqevent_methods
[] = {
4727 PHP_ME(pqevent
, __construct
, ai_pqevent_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4728 PHP_ME(pqevent
, trigger
, ai_pqevent_trigger
, ZEND_ACC_PUBLIC
)
4732 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct
, 0, 0, 1)
4733 ZEND_ARG_OBJ_INFO(0, transaction
, pq
\\Transaction
, 0)
4734 ZEND_ARG_INFO(0, oid
)
4735 ZEND_ARG_INFO(0, mode
)
4736 ZEND_END_ARG_INFO();
4737 static PHP_METHOD(pqlob
, __construct
) {
4738 zend_error_handling zeh
;
4740 long mode
= INV_WRITE
|INV_READ
, loid
= InvalidOid
;
4743 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4744 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|ll", &ztxn
, php_pqtxn_class_entry
, &loid
, &mode
);
4745 zend_restore_error_handling(&zeh TSRMLS_CC
);
4747 if (SUCCESS
== rv
) {
4748 php_pqtxn_object_t
*txn_obj
= zend_object_store_get_object(ztxn TSRMLS_CC
);
4750 if (!txn_obj
->intern
) {
4751 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4752 } else if (!txn_obj
->intern
->open
) {
4753 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transation already closed");
4755 if (loid
== InvalidOid
) {
4756 loid
= lo_creat(txn_obj
->intern
->conn
->intern
->conn
, mode
);
4759 if (loid
== InvalidOid
) {
4760 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
));
4762 int lofd
= lo_open(txn_obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4765 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
));
4767 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4769 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4770 obj
->intern
->lofd
= lofd
;
4771 obj
->intern
->loid
= loid
;
4772 php_pq_object_addref(txn_obj TSRMLS_CC
);
4773 obj
->intern
->txn
= txn_obj
;
4777 php_pqconn_notify_listeners(txn_obj
->intern
->conn TSRMLS_CC
);
4782 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write
, 0, 0, 1)
4783 ZEND_ARG_INFO(0, data
)
4784 ZEND_END_ARG_INFO();
4785 static PHP_METHOD(pqlob
, write
) {
4786 zend_error_handling zeh
;
4791 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4792 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4793 zend_restore_error_handling(&zeh TSRMLS_CC
);
4795 if (SUCCESS
== rv
) {
4796 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4799 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4801 int written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, data_str
, data_len
);
4804 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
));
4806 RETVAL_LONG(written
);
4809 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4814 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read
, 0, 0, 0)
4815 ZEND_ARG_INFO(0, length
)
4816 ZEND_ARG_INFO(1, read
)
4817 ZEND_END_ARG_INFO();
4818 static PHP_METHOD(pqlob
, read
) {
4819 zend_error_handling zeh
;
4820 long length
= 0x1000;
4824 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4825 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lz!", &length
, &zread
);
4826 zend_restore_error_handling(&zeh TSRMLS_CC
);
4828 if (SUCCESS
== rv
) {
4829 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4832 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4834 char *buffer
= emalloc(length
+ 1);
4835 int read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4839 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
));
4843 ZVAL_LONG(zread
, read
);
4845 buffer
[read
] = '\0';
4846 RETVAL_STRINGL(buffer
, read
, 0);
4849 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4854 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek
, 0, 0, 1)
4855 ZEND_ARG_INFO(0, offset
)
4856 ZEND_ARG_INFO(0, whence
)
4857 ZEND_END_ARG_INFO();
4858 static PHP_METHOD(pqlob
, seek
) {
4859 zend_error_handling zeh
;
4860 long offset
, whence
= SEEK_SET
;
4863 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4864 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &offset
, &whence
);
4865 zend_restore_error_handling(&zeh TSRMLS_CC
);
4867 if (SUCCESS
== rv
) {
4868 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4871 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4873 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4876 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
));
4878 RETVAL_LONG(position
);
4881 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4886 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell
, 0, 0, 0)
4887 ZEND_END_ARG_INFO();
4888 static PHP_METHOD(pqlob
, tell
) {
4889 zend_error_handling zeh
;
4892 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4893 rv
= zend_parse_parameters_none();
4894 zend_restore_error_handling(&zeh TSRMLS_CC
);
4896 if (SUCCESS
== rv
) {
4897 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4900 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4902 int position
= lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
4905 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
));
4907 RETVAL_LONG(position
);
4910 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4915 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate
, 0, 0, 0)
4916 ZEND_ARG_INFO(0, length
)
4917 ZEND_END_ARG_INFO();
4918 static PHP_METHOD(pqlob
, truncate
) {
4919 zend_error_handling zeh
;
4923 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4924 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &length
);
4925 zend_restore_error_handling(&zeh TSRMLS_CC
);
4927 if (SUCCESS
== rv
) {
4928 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4931 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4933 int rc
= lo_truncate(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, length
);
4936 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
));
4939 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4944 static zend_function_entry php_pqlob_methods
[] = {
4945 PHP_ME(pqlob
, __construct
, ai_pqlob_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4946 PHP_ME(pqlob
, write
, ai_pqlob_write
, ZEND_ACC_PUBLIC
)
4947 PHP_ME(pqlob
, read
, ai_pqlob_read
, ZEND_ACC_PUBLIC
)
4948 PHP_ME(pqlob
, seek
, ai_pqlob_seek
, ZEND_ACC_PUBLIC
)
4949 PHP_ME(pqlob
, tell
, ai_pqlob_tell
, ZEND_ACC_PUBLIC
)
4950 PHP_ME(pqlob
, truncate
, ai_pqlob_truncate
, ZEND_ACC_PUBLIC
)
4954 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct
, 0, 0, 3)
4955 ZEND_ARG_OBJ_INFO(0, "connection", pq
\\Connection
, 0)
4956 ZEND_ARG_INFO(0, expression
)
4957 ZEND_ARG_INFO(0, direction
)
4958 ZEND_ARG_INFO(0, options
)
4959 ZEND_END_ARG_INFO();
4960 static PHP_METHOD(pqcopy
, __construct
) {
4961 zend_error_handling zeh
;
4963 char *expr_str
, *opt_str
= "";
4964 int expr_len
, opt_len
= 0;
4968 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4969 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
);
4970 zend_restore_error_handling(&zeh TSRMLS_CC
);
4972 if (SUCCESS
== rv
) {
4973 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4975 if (!conn_obj
->intern
) {
4976 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4978 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4979 smart_str cmd
= {0};
4982 smart_str_appends(&cmd
, "COPY ");
4983 smart_str_appendl(&cmd
, expr_str
, expr_len
);
4985 switch (direction
) {
4986 case PHP_PQCOPY_FROM_STDIN
:
4987 smart_str_appends(&cmd
, " FROM STDIN ");
4989 case PHP_PQCOPY_TO_STDOUT
:
4990 smart_str_appends(&cmd
, " TO STDOUT ");
4993 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
);
4994 smart_str_free(&cmd
);
4997 smart_str_appendl(&cmd
, opt_str
, opt_len
);
5000 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
5003 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5005 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
5006 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
5007 obj
->intern
->direction
= direction
;
5008 obj
->intern
->expression
= estrdup(expr_str
);
5009 obj
->intern
->options
= estrdup(opt_str
);
5010 obj
->intern
->conn
= conn_obj
;
5011 php_pq_object_addref(conn_obj TSRMLS_CC
);
5017 smart_str_free(&cmd
);
5018 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5023 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put
, 0, 0, 1)
5024 ZEND_ARG_INFO(0, data
)
5025 ZEND_END_ARG_INFO();
5026 static PHP_METHOD(pqcopy
, put
) {
5027 zend_error_handling zeh
;
5032 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5033 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
5034 zend_restore_error_handling(&zeh TSRMLS_CC
);
5036 if (SUCCESS
== rv
) {
5037 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5040 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
5041 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
5042 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not initialized with FROM_STDIN");
5044 if (1 != PQputCopyData(obj
->intern
->conn
->intern
->conn
, data_str
, data_len
)) {
5045 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5047 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5052 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end
, 0, 0, 0)
5053 ZEND_ARG_INFO(0, error
)
5054 ZEND_END_ARG_INFO();
5055 static PHP_METHOD(pqcopy
, end
) {
5056 zend_error_handling zeh
;
5057 char *error_str
= NULL
;
5061 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5062 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &error_str
, &error_len
);
5063 zend_restore_error_handling(&zeh TSRMLS_CC
);
5065 if (SUCCESS
== rv
) {
5066 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5069 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY not intitialized");
5070 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
5071 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intitialized with FROM_STDIN");
5073 if (1 != PQputCopyEnd(obj
->intern
->conn
->intern
->conn
, error_str
)) {
5074 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5076 PGresult
*res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
5079 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5081 php_pqres_success(res TSRMLS_CC
);
5086 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5091 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get
, 0, 0, 1)
5092 ZEND_ARG_INFO(1, data
)
5093 ZEND_END_ARG_INFO();
5094 static PHP_METHOD(pqcopy
, get
) {
5095 zend_error_handling zeh
;
5099 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5100 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
);
5101 zend_restore_error_handling(&zeh TSRMLS_CC
);
5103 if (SUCCESS
== rv
) {
5104 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5107 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
5108 } else if (obj
->intern
->direction
!= PHP_PQCOPY_TO_STDOUT
) {
5109 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intialized with TO_STDOUT");
5112 char *buffer
= NULL
;
5113 int bytes
= PQgetCopyData(obj
->intern
->conn
->intern
->conn
, &buffer
, 0);
5117 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5121 res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
5124 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5126 php_pqres_success(res TSRMLS_CC
);
5135 ZVAL_STRINGL(zdata
, buffer
, bytes
, 1);
5137 ZVAL_EMPTY_STRING(zdata
);
5150 static zend_function_entry php_pqcopy_methods
[] = {
5151 PHP_ME(pqcopy
, __construct
, ai_pqcopy_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
5152 PHP_ME(pqcopy
, put
, ai_pqcopy_put
, ZEND_ACC_PUBLIC
)
5153 PHP_ME(pqcopy
, end
, ai_pqcopy_end
, ZEND_ACC_PUBLIC
)
5154 PHP_ME(pqcopy
, get
, ai_pqcopy_get
, ZEND_ACC_PUBLIC
)
5158 static zend_function_entry php_pqexc_methods
[] = {
5162 /* {{{ PHP_MINIT_FUNCTION
5164 static PHP_MINIT_FUNCTION(pq
)
5166 zend_class_entry ce
= {0};
5167 php_pq_object_prophandler_t ph
= {0};
5169 INIT_NS_CLASS_ENTRY(ce
, "pq", "Exception", php_pqexc_methods
);
5170 php_pqexc_interface_class_entry
= zend_register_internal_interface(&ce TSRMLS_CC
);
5172 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT TSRMLS_CC
);
5173 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("RUNTIME"), EX_RUNTIME TSRMLS_CC
);
5174 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("CONNECTION_FAILED"), EX_CONNECTION_FAILED TSRMLS_CC
);
5175 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("IO"), EX_IO TSRMLS_CC
);
5176 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("ESCAPE"), EX_ESCAPE TSRMLS_CC
);
5177 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("BAD_METHODCALL"), EX_BAD_METHODCALL TSRMLS_CC
);
5178 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("UNINITIALIZED"), EX_UNINITIALIZED TSRMLS_CC
);
5179 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("DOMAIN"), EX_DOMAIN TSRMLS_CC
);
5180 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("SQL"), EX_SQL TSRMLS_CC
);
5182 memset(&ce
, 0, sizeof(ce
));
5183 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "InvalidArgumentException", php_pqexc_methods
);
5184 php_pqexc_invalid_argument_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_InvalidArgumentException
, "InvalidArgumentException" TSRMLS_CC
);
5185 zend_class_implements(php_pqexc_invalid_argument_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5187 memset(&ce
, 0, sizeof(ce
));
5188 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "RuntimeException", php_pqexc_methods
);
5189 php_pqexc_runtime_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_RuntimeException
, "RuntimeException" TSRMLS_CC
);
5190 zend_class_implements(php_pqexc_runtime_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5192 memset(&ce
, 0, sizeof(ce
));
5193 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "BadMethodCallException", php_pqexc_methods
);
5194 php_pqexc_bad_methodcall_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_BadMethodCallException
, "BadMethodCallException" TSRMLS_CC
);
5195 zend_class_implements(php_pqexc_bad_methodcall_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5197 memset(&ce
, 0, sizeof(ce
));
5198 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "DomainException", php_pqexc_methods
);
5199 php_pqexc_domain_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_DomainException
, "DomainException" TSRMLS_CC
);
5200 zend_class_implements(php_pqexc_domain_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5201 zend_declare_property_null(php_pqexc_domain_class_entry
, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5203 memset(&ce
, 0, sizeof(ce
));
5204 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
5205 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5206 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
5208 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5209 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
5210 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
5211 php_pqconn_object_handlers
.clone_obj
= NULL
;
5212 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
5213 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5215 zend_hash_init(&php_pqconn_object_prophandlers
, 14, NULL
, NULL
, 1);
5217 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5218 ph
.read
= php_pqconn_object_read_status
;
5219 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5221 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5222 ph
.read
= php_pqconn_object_read_transaction_status
;
5223 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
5225 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5226 ph
.read
= NULL
; /* forward to std prophandler */
5227 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
5229 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5230 ph
.read
= php_pqconn_object_read_error_message
;
5231 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5233 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5234 ph
.read
= php_pqconn_object_read_busy
;
5235 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
5237 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5238 ph
.read
= php_pqconn_object_read_encoding
;
5239 ph
.write
= php_pqconn_object_write_encoding
;
5240 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
5243 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5244 ph
.read
= php_pqconn_object_read_unbuffered
;
5245 ph
.write
= php_pqconn_object_write_unbuffered
;
5246 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
5249 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5250 ph
.read
= php_pqconn_object_read_db
;
5251 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
5253 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5254 ph
.read
= php_pqconn_object_read_user
;
5255 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
5257 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5258 ph
.read
= php_pqconn_object_read_pass
;
5259 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
5261 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5262 ph
.read
= php_pqconn_object_read_host
;
5263 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
5265 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5266 ph
.read
= php_pqconn_object_read_port
;
5267 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
5269 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5270 ph
.read
= php_pqconn_object_read_options
;
5271 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5273 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5274 ph
.read
= php_pqconn_object_read_event_handlers
;
5275 zend_hash_add(&php_pqconn_object_prophandlers
, "eventHandlers", sizeof("eventHandlers"), (void *) &ph
, sizeof(ph
), NULL
);
5277 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
5278 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
5279 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
5280 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
5281 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
5282 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
5283 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
5284 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
5286 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
5287 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
5288 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
5289 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
5290 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
5292 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
5293 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
5294 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
5295 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
5297 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
5298 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
5299 memset(&ce
, 0, sizeof(ce
));
5300 INIT_NS_CLASS_ENTRY(ce
, "pq", "Types", php_pqtypes_methods
);
5301 php_pqtypes_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5302 php_pqtypes_class_entry
->create_object
= php_pqtypes_create_object
;
5304 memcpy(&php_pqtypes_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5305 php_pqtypes_object_handlers
.read_property
= php_pq_object_read_prop
;
5306 php_pqtypes_object_handlers
.write_property
= php_pq_object_write_prop
;
5307 php_pqtypes_object_handlers
.clone_obj
= NULL
;
5308 php_pqtypes_object_handlers
.get_property_ptr_ptr
= NULL
;
5309 php_pqtypes_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5310 php_pqtypes_object_handlers
.has_dimension
= php_pqtypes_object_has_dimension
;
5311 php_pqtypes_object_handlers
.read_dimension
= php_pqtypes_object_read_dimension
;
5312 php_pqtypes_object_handlers
.unset_dimension
= NULL
;
5313 php_pqtypes_object_handlers
.write_dimension
= NULL
;
5315 zend_hash_init(&php_pqtypes_object_prophandlers
, 1, NULL
, NULL
, 1);
5317 zend_declare_property_null(php_pqtypes_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5318 ph
.read
= php_pqtypes_object_read_connection
;
5319 zend_hash_add(&php_pqtypes_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5321 memset(&ce
, 0, sizeof(ce
));
5322 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
5323 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5324 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
5325 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
5326 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
5327 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 2, zend_ce_traversable
, spl_ce_Countable
);
5329 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5330 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
5331 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
5332 php_pqres_object_handlers
.clone_obj
= NULL
;
5333 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
5334 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5335 php_pqres_object_handlers
.count_elements
= php_pqres_count_elements
;
5337 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
5339 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5340 ph
.read
= php_pqres_object_read_status
;
5341 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5343 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5344 ph
.read
= php_pqres_object_read_status_message
;
5345 zend_hash_add(&php_pqres_object_prophandlers
, "statusMessage", sizeof("statusMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5347 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5348 ph
.read
= php_pqres_object_read_error_message
;
5349 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5351 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5352 ph
.read
= php_pqres_object_read_num_rows
;
5353 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
5355 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5356 ph
.read
= php_pqres_object_read_num_cols
;
5357 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
5359 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5360 ph
.read
= php_pqres_object_read_affected_rows
;
5361 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
5363 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5364 ph
.read
= php_pqres_object_read_fetch_type
;
5365 ph
.write
= php_pqres_object_write_fetch_type
;
5366 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
5369 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
5370 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
5371 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
5372 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
5373 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
5374 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
5375 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
5376 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
5377 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
5378 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
5380 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
5381 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
5382 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
5384 memset(&ce
, 0, sizeof(ce
));
5385 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
5386 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5387 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
5389 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5390 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
5391 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
5392 php_pqstm_object_handlers
.clone_obj
= NULL
;
5393 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
5394 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5396 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
5398 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5399 ph
.read
= php_pqstm_object_read_name
;
5400 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
5402 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5403 ph
.read
= php_pqstm_object_read_connection
;
5404 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5406 memset(&ce
, 0, sizeof(ce
));
5407 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
5408 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5409 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
5411 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5412 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
5413 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
5414 php_pqtxn_object_handlers
.clone_obj
= NULL
;
5415 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
5416 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5418 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
5420 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5421 ph
.read
= php_pqtxn_object_read_connection
;
5422 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5424 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5425 ph
.read
= php_pqtxn_object_read_isolation
;
5426 ph
.write
= php_pqtxn_object_write_isolation
;
5427 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
5429 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5430 ph
.read
= php_pqtxn_object_read_readonly
;
5431 ph
.write
= php_pqtxn_object_write_readonly
;
5432 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
5434 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5435 ph
.read
= php_pqtxn_object_read_deferrable
;
5436 ph
.write
= php_pqtxn_object_write_deferrable
;
5437 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
5440 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
5441 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
5442 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
5444 memset(&ce
, 0, sizeof(ce
));
5445 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
5446 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5447 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
5449 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5450 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
5451 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
5452 php_pqcancel_object_handlers
.clone_obj
= NULL
;
5453 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
5454 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5456 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
5458 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5459 ph
.read
= php_pqcancel_object_read_connection
;
5460 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5462 memset(&ce
, 0, sizeof(ce
));
5463 INIT_NS_CLASS_ENTRY(ce
, "pq", "Event", php_pqevent_methods
);
5464 php_pqevent_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5465 php_pqevent_class_entry
->create_object
= php_pqevent_create_object
;
5467 memcpy(&php_pqevent_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5468 php_pqevent_object_handlers
.read_property
= php_pq_object_read_prop
;
5469 php_pqevent_object_handlers
.write_property
= php_pq_object_write_prop
;
5470 php_pqevent_object_handlers
.clone_obj
= NULL
;
5471 php_pqevent_object_handlers
.get_property_ptr_ptr
= NULL
;
5472 php_pqevent_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5474 zend_hash_init(&php_pqevent_object_prophandlers
, 1, NULL
, NULL
, 1);
5476 zend_declare_property_null(php_pqevent_class_entry
, ZEND_STRL("type"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5477 ph
.read
= php_pqevent_object_read_type
;
5478 zend_hash_add(&php_pqevent_object_prophandlers
, "type", sizeof("type"), (void *) &ph
, sizeof(ph
), NULL
);
5480 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
5481 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESULT"), ZEND_STRL("result") TSRMLS_CC
);
5482 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESET"), ZEND_STRL("reset") TSRMLS_CC
);
5484 memset(&ce
, 0, sizeof(ce
));
5485 INIT_NS_CLASS_ENTRY(ce
, "pq", "LOB", php_pqlob_methods
);
5486 php_pqlob_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5487 php_pqlob_class_entry
->create_object
= php_pqlob_create_object
;
5489 memcpy(&php_pqlob_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5490 php_pqlob_object_handlers
.read_property
= php_pq_object_read_prop
;
5491 php_pqlob_object_handlers
.write_property
= php_pq_object_write_prop
;
5492 php_pqlob_object_handlers
.clone_obj
= NULL
;
5493 php_pqlob_object_handlers
.get_property_ptr_ptr
= NULL
;
5494 php_pqlob_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5496 zend_hash_init(&php_pqlob_object_prophandlers
, 2, NULL
, NULL
, 1);
5498 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5499 ph
.read
= php_pqlob_object_read_transaction
;
5500 zend_hash_add(&php_pqlob_object_prophandlers
, "transaction", sizeof("transaction"), (void *) &ph
, sizeof(ph
), NULL
);
5502 zend_declare_property_long(php_pqlob_class_entry
, ZEND_STRL("oid"), InvalidOid
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5503 ph
.read
= php_pqlob_object_read_oid
;
5504 zend_hash_add(&php_pqlob_object_prophandlers
, "oid", sizeof("oid"), (void *) &ph
, sizeof(ph
), NULL
);
5506 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC
);
5507 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("R"), INV_READ TSRMLS_CC
);
5508 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("W"), INV_WRITE TSRMLS_CC
);
5509 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("RW"), INV_READ
|INV_WRITE TSRMLS_CC
);
5511 memset(&ce
, 0, sizeof(ce
));
5512 INIT_NS_CLASS_ENTRY(ce
, "pq", "COPY", php_pqcopy_methods
);
5513 php_pqcopy_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5514 php_pqcopy_class_entry
->create_object
= php_pqcopy_create_object
;
5516 memcpy(&php_pqcopy_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5517 php_pqcopy_object_handlers
.read_property
= php_pq_object_read_prop
;
5518 php_pqcopy_object_handlers
.write_property
= php_pq_object_write_prop
;
5519 php_pqcopy_object_handlers
.clone_obj
= NULL
;
5520 php_pqcopy_object_handlers
.get_property_ptr_ptr
= NULL
;
5521 php_pqcopy_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5523 zend_hash_init(&php_pqcopy_object_prophandlers
, 4, NULL
, NULL
, 1);
5525 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5526 ph
.read
= php_pqcopy_object_read_connection
;
5527 zend_hash_add(&php_pqcopy_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5529 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5530 ph
.read
= php_pqcopy_object_read_expression
;
5531 zend_hash_add(&php_pqcopy_object_prophandlers
, "expression", sizeof("expression"), (void *) &ph
, sizeof(ph
), NULL
);
5533 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5534 ph
.read
= php_pqcopy_object_read_direction
;
5535 zend_hash_add(&php_pqcopy_object_prophandlers
, "direction", sizeof("direction"), (void *) &ph
, sizeof(ph
), NULL
);
5537 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5538 ph
.read
= php_pqcopy_object_read_options
;
5539 zend_hash_add(&php_pqcopy_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5541 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC
);
5542 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC
);
5544 php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops
, NULL
, NULL TSRMLS_CC
);
5547 REGISTER_INI_ENTRIES();
5553 /* {{{ PHP_MSHUTDOWN_FUNCTION
5555 static PHP_MSHUTDOWN_FUNCTION(pq
)
5557 /* uncomment this line if you have INI entries
5558 UNREGISTER_INI_ENTRIES();
5560 php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL
, 0 TSRMLS_CC
);
5565 /* {{{ PHP_MINFO_FUNCTION
5567 static PHP_MINFO_FUNCTION(pq
)
5569 #ifdef HAVE_PQLIBVERSION
5572 char libpq_version
[10] = "pre-9.1";
5574 php_info_print_table_start();
5575 php_info_print_table_header(2, "PQ Support", "enabled");
5576 php_info_print_table_row(2, "Extension Version", PHP_PQ_EXT_VERSION
);
5577 php_info_print_table_end();
5579 php_info_print_table_start();
5580 php_info_print_table_header(2, "Used Library", "Version");
5581 #ifdef HAVE_PQLIBVERSION
5582 libpq_v
= PQlibVersion();
5583 slprintf(libpq_version
, sizeof(libpq_version
), "%d.%d.%d", libpq_v
/10000%100, libpq_v
/100%100, libpq_v
%100);
5585 php_info_print_table_row(2, "libpq", libpq_version
);
5586 php_info_print_table_end();
5588 /* Remove comments if you have entries in php.ini
5589 DISPLAY_INI_ENTRIES();
5594 const zend_function_entry pq_functions
[] = {
5598 static zend_module_dep pq_module_deps
[] = {
5599 ZEND_MOD_REQUIRED("raphf")
5600 ZEND_MOD_REQUIRED("spl")
5604 /* {{{ pq_module_entry
5606 zend_module_entry pq_module_entry
= {
5607 STANDARD_MODULE_HEADER_EX
,
5614 NULL
,/*PHP_RINIT(pq),*/
5615 NULL
,/*PHP_RSHUTDOWN(pq),*/
5618 STANDARD_MODULE_PROPERTIES
5622 #ifdef COMPILE_DL_PQ
5632 * vim600: noet sw=4 ts=4 fdm=marker
5633 * vim<600: noet sw=4 ts=4