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 +--------------------------------------------------------------------+
18 #include <Zend/zend_interfaces.h>
19 #include <ext/standard/info.h>
20 #include <ext/spl/spl_array.h>
22 #include <libpq-events.h>
27 typedef int STATUS
; /* SUCCESS/FAILURE */
30 ZEND_DECLARE_MODULE_GLOBALS(pq)
36 /* Remove comments and fill if you need to have entries in php.ini
38 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
39 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
44 /* {{{ php_pq_init_globals
46 /* Uncomment this function if you have INI entries
47 static void php_pq_init_globals(zend_pq_globals *pq_globals)
49 pq_globals->global_value = 0;
50 pq_globals->global_string = NULL;
55 static zend_class_entry
*php_pqconn_class_entry
;
56 static zend_class_entry
*php_pqres_class_entry
;
57 static zend_class_entry
*php_pqstm_class_entry
;
58 static zend_class_entry
*php_pqtxn_class_entry
;
59 static zend_class_entry
*php_pqcancel_class_entry
;
61 static zend_object_handlers php_pqconn_object_handlers
;
62 static zend_object_handlers php_pqres_object_handlers
;
63 static zend_object_handlers php_pqstm_object_handlers
;
64 static zend_object_handlers php_pqtxn_object_handlers
;
65 static zend_object_handlers php_pqcancel_object_handlers
;
67 typedef struct php_pq_callback
{
69 zend_fcall_info_cache fcc
;
73 typedef struct php_pq_object
{
76 HashTable
*prophandler
;
79 typedef struct php_pqconn_object
{
82 HashTable
*prophandler
;
84 int (*poller
)(PGconn
*);
86 php_pq_callback_t onevent
;
87 } php_pqconn_object_t
;
89 typedef struct php_pqconn_event_data
{
90 php_pqconn_object_t
*obj
;
94 } php_pqconn_event_data_t
;
96 typedef enum php_pqres_fetch
{
97 PHP_PQRES_FETCH_ARRAY
,
98 PHP_PQRES_FETCH_ASSOC
,
99 PHP_PQRES_FETCH_OBJECT
102 typedef struct php_pqres_iterator
{
103 zend_object_iterator zi
;
106 php_pqres_fetch_t fetch_type
;
107 } php_pqres_iterator_t
;
109 typedef struct php_pqres_object
{
112 HashTable
*prophandler
;
114 php_pqres_iterator_t
*iter
;
115 } php_pqres_object_t
;
117 typedef struct php_pqstm
{
122 typedef struct php_pqstm_object
{
125 HashTable
*prophandler
;
126 } php_pqstm_object_t
;
128 typedef enum php_pqtxn_isolation
{
129 PHP_PQTXN_READ_COMMITTED
,
130 PHP_PQTXN_REPEATABLE_READ
,
131 PHP_PQTXN_SERIALIZABLE
,
132 } php_pqtxn_isolation_t
;
134 typedef struct php_pqtxn
{
136 php_pqtxn_isolation_t isolation
;
138 unsigned deferrable
:1;
141 typedef struct php_pqtxn_object
{
144 HashTable
*prophandler
;
145 } php_pqtxn_object_t
;
147 typedef struct php_pqcancel
{
152 typedef struct php_pqcancel_object
{
154 php_pqcancel_t
*cancel
;
155 HashTable
*prophandler
;
156 } php_pqcancel_object_t
;
159 static HashTable php_pqconn_object_prophandlers
;
160 static HashTable php_pqres_object_prophandlers
;
161 static HashTable php_pqstm_object_prophandlers
;
162 static HashTable php_pqtxn_object_prophandlers
;
163 static HashTable php_pqcancel_object_prophandlers
;
165 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
167 typedef struct php_pq_object_prophandler
{
168 php_pq_object_prophandler_func_t read
;
169 php_pq_object_prophandler_func_t write
;
170 } php_pq_object_prophandler_t
;
172 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
174 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
176 php_pqres_iterator_t
*iter
;
177 zval
*prop
, *zfetch_type
;
179 iter
= ecalloc(1, sizeof(*iter
));
180 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
181 iter
->zi
.data
= object
;
184 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
185 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
186 convert_to_long_ex(&zfetch_type
);
188 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
189 if (zfetch_type
!= prop
) {
190 zval_ptr_dtor(&zfetch_type
);
192 if (Z_REFCOUNT_P(prop
)) {
193 zval_ptr_dtor(&prop
);
199 return (zend_object_iterator
*) iter
;
202 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
204 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
206 if (iter
->current_val
) {
207 zval_ptr_dtor(&iter
->current_val
);
208 iter
->current_val
= NULL
;
210 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
214 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
216 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
217 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
219 if (PQresultStatus(obj
->res
) != PGRES_TUPLES_OK
) {
222 if (PQntuples(obj
->res
) <= iter
->index
) {
229 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type TSRMLS_DC
)
235 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
241 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
242 if (PQgetisnull(res
, row
, c
)) {
243 switch (fetch_type
) {
244 case PHP_PQRES_FETCH_OBJECT
:
245 add_property_null(data
, PQfname(res
, c
));
248 case PHP_PQRES_FETCH_ASSOC
:
249 add_assoc_null(data
, PQfname(res
, c
));
252 case PHP_PQRES_FETCH_ARRAY
:
253 add_index_null(data
, c
);
257 char *val
= PQgetvalue(res
, row
, c
);
258 int len
= PQgetlength(res
, row
, c
);
260 switch (fetch_type
) {
261 case PHP_PQRES_FETCH_OBJECT
:
262 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
265 case PHP_PQRES_FETCH_ASSOC
:
266 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
269 case PHP_PQRES_FETCH_ARRAY
:
270 add_index_stringl(data
, c
, val
, len
,1);
279 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
281 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
282 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
284 if (iter
->current_val
) {
285 zval_ptr_dtor(&iter
->current_val
);
287 iter
->current_val
= php_pqres_row_to_zval(obj
->res
, iter
->index
, iter
->fetch_type TSRMLS_CC
);
288 *data_ptr
= &iter
->current_val
;
291 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
293 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
295 *key_num
= (ulong
) iter
->index
;
297 return HASH_KEY_IS_LONG
;
300 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
302 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
307 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
309 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
314 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
315 php_pqres_iterator_dtor
,
316 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
317 php_pqres_iterator_valid
,
318 /* fetch the item data for the current element */
319 php_pqres_iterator_current
,
320 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
321 php_pqres_iterator_key
,
322 /* step forwards to next element */
323 php_pqres_iterator_next
,
324 /* rewind to start of data (optional, may be NULL) */
325 php_pqres_iterator_rewind
,
326 /* invalidate current value/key (optional, may be NULL) */
330 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
332 switch (PQresultStatus(res
)) {
333 case PGRES_BAD_RESPONSE
:
334 case PGRES_NONFATAL_ERROR
:
335 case PGRES_FATAL_ERROR
:
336 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "%s", PQresultErrorMessage(res
));
343 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
344 if (cb
->fci
.size
> 0) {
345 zend_fcall_info_args_clear(&cb
->fci
, 1);
346 zval_ptr_dtor(&cb
->fci
.function_name
);
347 if (cb
->fci
.object_ptr
) {
348 zval_ptr_dtor(&cb
->fci
.object_ptr
);
354 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
356 Z_ADDREF_P(cb
->fci
.function_name
);
357 if (cb
->fci
.object_ptr
) {
358 Z_ADDREF_P(cb
->fci
.object_ptr
);
362 static void php_pqconn_object_free(void *o TSRMLS_DC
)
364 php_pqconn_object_t
*obj
= o
;
370 if (obj
->onevent
.fci
.size
> 0) {
371 php_pq_callback_dtor(&obj
->onevent
);
373 zend_hash_destroy(&obj
->listeners
);
374 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
378 static int php_pqconn_event(PGEventId id
, void *e
, void *data
);
380 static void php_pqres_object_free(void *o TSRMLS_DC
)
382 php_pqres_object_t
*obj
= o
;
385 zval
*res
= PQresultInstanceData(obj
->res
, php_pqconn_event
);
387 PQresultSetInstanceData(obj
->res
, php_pqconn_event
, NULL
);
395 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
398 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
402 static void php_pqstm_object_free(void *o TSRMLS_DC
)
404 php_pqstm_object_t
*obj
= o
;
407 zval_ptr_dtor(&obj
->stm
->conn
);
408 efree(obj
->stm
->name
);
412 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
416 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
418 php_pqtxn_object_t
*obj
= o
;
421 zval_ptr_dtor(&obj
->txn
->conn
);
425 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
429 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
431 php_pqcancel_object_t
*obj
= o
;
434 PQfreeCancel(obj
->cancel
->cancel
);
435 zval_ptr_dtor(&obj
->cancel
->conn
);
439 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
443 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, PGconn
*conn
, php_pqconn_object_t
**ptr TSRMLS_DC
)
445 zend_object_value ov
;
446 php_pqconn_object_t
*o
;
448 o
= ecalloc(1, sizeof(*o
));
449 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
450 object_properties_init((zend_object
*) o
, ce
);
451 o
->prophandler
= &php_pqconn_object_prophandlers
;
461 zend_hash_init(&o
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
463 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
464 ov
.handlers
= &php_pqconn_object_handlers
;
469 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, PGresult
*res
, php_pqres_object_t
**ptr TSRMLS_DC
)
471 zend_object_value ov
;
472 php_pqres_object_t
*o
;
474 o
= ecalloc(1, sizeof(*o
));
475 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
476 object_properties_init((zend_object
*) o
, ce
);
477 o
->prophandler
= &php_pqres_object_prophandlers
;
487 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
488 ov
.handlers
= &php_pqres_object_handlers
;
493 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*stm
, php_pqstm_object_t
**ptr TSRMLS_DC
)
495 zend_object_value ov
;
496 php_pqstm_object_t
*o
;
498 o
= ecalloc(1, sizeof(*o
));
499 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
500 object_properties_init((zend_object
*) o
, ce
);
501 o
->prophandler
= &php_pqstm_object_prophandlers
;
511 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
512 ov
.handlers
= &php_pqstm_object_handlers
;
517 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*txn
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
519 zend_object_value ov
;
520 php_pqtxn_object_t
*o
;
522 o
= ecalloc(1, sizeof(*o
));
523 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
524 object_properties_init((zend_object
*) o
, ce
);
525 o
->prophandler
= &php_pqtxn_object_prophandlers
;
535 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
536 ov
.handlers
= &php_pqtxn_object_handlers
;
541 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*cancel
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
543 zend_object_value ov
;
544 php_pqcancel_object_t
*o
;
546 o
= ecalloc(1, sizeof(*o
));
547 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
548 object_properties_init((zend_object
*) o
, ce
);
549 o
->prophandler
= &php_pqcancel_object_prophandlers
;
559 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
560 ov
.handlers
= &php_pqcancel_object_handlers
;
565 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
567 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
570 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
572 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
575 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
577 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
580 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
582 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
585 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
587 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
590 static int apply_ph_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
592 php_pq_object_prophandler_t
*ph
= p
;
593 HashTable
*ht
= va_arg(argv
, HashTable
*);
594 zval
**return_value
, *object
= va_arg(argv
, zval
*);
595 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
597 if (SUCCESS
== zend_hash_find(ht
, key
->arKey
, key
->nKeyLength
, (void *) &return_value
)) {
600 zval_ptr_dtor(return_value
);
601 MAKE_STD_ZVAL(*return_value
);
602 ZVAL_NULL(*return_value
);
604 ph
->read(object
, obj
, *return_value TSRMLS_CC
);
608 return ZEND_HASH_APPLY_KEEP
;
611 static int apply_pi_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
613 zend_property_info
*pi
= p
;
614 HashTable
*ht
= va_arg(argv
, HashTable
*);
615 zval
*object
= va_arg(argv
, zval
*);
616 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
617 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
619 if (!Z_REFCOUNT_P(property
)) {
620 Z_ADDREF_P(property
);
622 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
624 return ZEND_HASH_APPLY_KEEP
;
627 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
630 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
634 ZEND_INIT_SYMTABLE(ht
);
636 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_debug
, 3, ht
, object
, obj
);
637 zend_hash_apply_with_arguments(obj
->prophandler TSRMLS_CC
, apply_ph_to_debug
, 3, ht
, object
, obj
);
641 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
643 php_pqconn_object_t
*obj
= o
;
645 RETVAL_LONG(PQstatus(obj
->conn
));
648 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
650 php_pqconn_object_t
*obj
= o
;
652 RETVAL_LONG(PQtransactionStatus(obj
->conn
));
655 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
657 php_pqconn_object_t
*obj
= o
;
658 char *error
= PQerrorMessage(obj
->conn
);
661 RETVAL_STRING(error
, 1);
667 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
669 php_pq_callback_t
*listener
= p
;
671 zval
*zpid
, *zchannel
, *zmessage
;
674 ZVAL_LONG(zpid
, nfy
->be_pid
);
675 MAKE_STD_ZVAL(zchannel
);
676 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
677 MAKE_STD_ZVAL(zmessage
);
678 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
680 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
681 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
683 zval_ptr_dtor(&zchannel
);
684 zval_ptr_dtor(&zmessage
);
685 zval_ptr_dtor(&zpid
);
687 return ZEND_HASH_APPLY_KEEP
;
690 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
692 HashTable
*listeners
= p
;
693 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
695 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
696 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
699 return ZEND_HASH_APPLY_KEEP
;
702 static void php_pqconn_notify_listeners(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
707 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
710 while ((nfy
= PQnotifies(obj
->conn
))) {
711 zend_hash_apply_with_arguments(&obj
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
716 /* FIXME: extend to types->nspname->typname */
717 #define PHP_PQ_TYPES_QUERY \
718 "select t.oid, t.* " \
719 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
720 "where typisdefined " \
722 "and nspname in ('public', 'pg_catalog')"
723 static void php_pqconn_object_read_types(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
725 php_pqconn_object_t
*obj
= o
;
726 PGresult
*res
= PQexec(obj
->conn
, PHP_PQ_TYPES_QUERY
);
728 php_pqconn_notify_listeners(object
, obj TSRMLS_CC
);
730 /* FIXME: cache that */
732 if (PGRES_TUPLES_OK
== PQresultStatus(res
)) {
734 zval
*byoid
, *byname
;
736 MAKE_STD_ZVAL(byoid
);
737 MAKE_STD_ZVAL(byname
);
740 object_init(return_value
);
741 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
742 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
744 add_property_zval(byoid
, PQgetvalue(res
, r
, 0), row
);
745 add_property_zval(byname
, PQgetvalue(res
, r
, 1), row
);
749 add_property_zval(return_value
, "byOid", byoid
);
750 add_property_zval(return_value
, "byName", byname
);
751 zval_ptr_dtor(&byoid
);
752 zval_ptr_dtor(&byname
);
754 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types: %s", PQresultErrorMessage(res
));
758 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types: %s", PQerrorMessage(obj
->conn
));
762 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
764 php_pqconn_object_t
*obj
= o
;
766 RETVAL_BOOL(PQisBusy(obj
->conn
));
769 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
771 php_pqconn_object_t
*obj
= o
;
773 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->conn
)), 1);
776 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
778 php_pqconn_object_t
*obj
= o
;
781 if (Z_TYPE_P(value
) != IS_STRING
) {
782 convert_to_string_ex(&zenc
);
785 if (0 > PQsetClientEncoding(obj
->conn
, Z_STRVAL_P(zenc
))) {
786 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
790 zval_ptr_dtor(&zenc
);
794 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
796 php_pqres_object_t
*obj
= o
;
798 RETVAL_LONG(PQresultStatus(obj
->res
));
801 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
803 php_pqres_object_t
*obj
= o
;
804 char *error
= PQresultErrorMessage(obj
->res
);
807 RETVAL_STRING(error
, 1);
813 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
815 php_pqres_object_t
*obj
= o
;
817 RETVAL_LONG(PQntuples(obj
->res
));
820 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
822 php_pqres_object_t
*obj
= o
;
824 RETVAL_LONG(PQnfields(obj
->res
));
827 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
829 php_pqres_object_t
*obj
= o
;
831 RETVAL_LONG(atoi(PQcmdTuples(obj
->res
)));
834 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
836 php_pqres_object_t
*obj
= o
;
839 RETVAL_LONG(obj
->iter
->fetch_type
);
841 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
845 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
847 php_pqres_object_t
*obj
= o
;
848 zval
*zfetch_type
= value
;
850 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
851 convert_to_long_ex(&zfetch_type
);
855 obj
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
856 obj
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
858 obj
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
860 if (zfetch_type
!= value
) {
861 zval_ptr_dtor(&zfetch_type
);
865 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
867 php_pqstm_object_t
*obj
= o
;
869 RETVAL_STRING(obj
->stm
->name
, 1);
872 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
874 php_pqstm_object_t
*obj
= o
;
876 RETVAL_ZVAL(obj
->stm
->conn
, 1, 0);
879 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
881 php_pqtxn_object_t
*obj
= o
;
883 RETVAL_ZVAL(obj
->txn
->conn
, 1, 0);
886 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
888 php_pqtxn_object_t
*obj
= o
;
890 RETVAL_LONG(obj
->txn
->isolation
);
893 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
895 php_pqtxn_object_t
*obj
= o
;
897 RETVAL_LONG(obj
->txn
->readonly
);
900 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
902 php_pqtxn_object_t
*obj
= o
;
904 RETVAL_LONG(obj
->txn
->deferrable
);
907 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
909 php_pqtxn_object_t
*obj
= o
;
910 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
911 php_pqtxn_isolation_t orig
= obj
->txn
->isolation
;
912 zval
*zisolation
= value
;
915 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
916 convert_to_long_ex(&zisolation
);
919 switch ((obj
->txn
->isolation
= Z_LVAL_P(zisolation
))) {
920 case PHP_PQTXN_READ_COMMITTED
:
921 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION READ COMMITED");
923 case PHP_PQTXN_REPEATABLE_READ
:
924 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION REPEATABLE READ");
926 case PHP_PQTXN_SERIALIZABLE
:
927 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION SERIALIZABLE");
930 obj
->txn
->isolation
= orig
;
935 if (zisolation
!= value
) {
936 zval_ptr_dtor(&zisolation
);
940 php_pqres_success(res TSRMLS_CC
);
945 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
947 php_pqtxn_object_t
*obj
= o
;
948 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
951 if ((obj
->txn
->readonly
= zend_is_true(value
))) {
952 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION READ ONLY");
954 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION READ WRITE");
958 php_pqres_success(res TSRMLS_CC
);
963 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
965 php_pqtxn_object_t
*obj
= o
;
966 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
969 if ((obj
->txn
->deferrable
= zend_is_true(value
))) {
970 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION DEFERRABLE");
972 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION NOT DEFERRABLE");
976 php_pqres_success(res TSRMLS_CC
);
981 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
983 php_pqcancel_object_t
*obj
= o
;
985 RETVAL_ZVAL(obj
->cancel
->conn
, 1, 0);
988 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
995 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
997 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
998 php_pq_object_prophandler_t
*handler
;
1002 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1003 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1004 if (type
== BP_VAR_R
) {
1005 ALLOC_ZVAL(return_value
);
1006 Z_SET_REFCOUNT_P(return_value
, 0);
1007 Z_UNSET_ISREF_P(return_value
);
1009 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1011 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1012 return_value
= NULL
;
1015 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1018 return return_value
;
1021 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1023 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1024 php_pq_object_prophandler_t
*handler
;
1026 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1027 if (handler
->write
) {
1028 handler
->write(object
, obj
, value TSRMLS_CC
);
1031 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1035 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1037 zval
*zsocket
, zmember
;
1043 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1046 INIT_PZVAL(&zmember
);
1047 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1048 MAKE_STD_ZVAL(zsocket
);
1050 if ((CONNECTION_BAD
!= PQstatus(obj
->conn
))
1051 && (-1 < (socket
= PQsocket(obj
->conn
)))
1052 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1053 php_stream_to_zval(stream
, zsocket
);
1059 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1060 zval_ptr_dtor(&zsocket
);
1066 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1067 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1069 # define TSRMLS_DF(d)
1070 # define TSRMLS_CF(d)
1073 static void php_pqconn_event_register(PGEventRegister
*event
, php_pqconn_event_data_t
*data
)
1075 PQsetInstanceData(event
->conn
, php_pqconn_event
, data
);
1077 static void php_pqconn_event_conndestroy(PGEventConnDestroy
*event
, php_pqconn_event_data_t
*data
)
1079 PQsetInstanceData(event
->conn
, php_pqconn_event
, NULL
);
1082 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
, php_pqconn_event_data_t
*data
)
1086 if (data
->obj
->onevent
.fci
.size
> 0) {
1090 res
->type
= IS_OBJECT
;
1091 res
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, event
->result
, NULL TSRMLS_CC
);
1094 PQresultSetInstanceData(event
->result
, php_pqconn_event
, res
);
1096 zend_fcall_info_argn(&data
->obj
->onevent
.fci TSRMLS_CC
, 1, &res
);
1097 zend_fcall_info_call(&data
->obj
->onevent
.fci
, &data
->obj
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1098 zval_ptr_dtor(&res
);
1102 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1105 case PGEVT_REGISTER
:
1106 php_pqconn_event_register(e
, data
);
1108 case PGEVT_CONNDESTROY
:
1109 php_pqconn_event_conndestroy(e
, data
);
1111 case PGEVT_RESULTCREATE
:
1112 php_pqconn_event_resultcreate(e
, data
);
1121 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1123 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1131 static void php_pqconn_notice_recv(void *o
, const PGresult
*res
)
1133 php_pqconn_object_t
*obj
= o
;
1138 MAKE_STD_ZVAL(notice
);
1139 ZVAL_STRING(notice
, PQresultErrorMessage(res
), 1);
1142 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
1143 ZEND_ARG_INFO(0, dsn
)
1144 ZEND_ARG_INFO(0, async
)
1145 ZEND_END_ARG_INFO();
1146 static PHP_METHOD(pqconn
, __construct
) {
1147 zend_error_handling zeh
;
1150 zend_bool async
= 0;
1152 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1153 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|b", &dsn_str
, &dsn_len
, &async
)) {
1154 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1155 php_pqconn_event_data_t
*data
= php_pqconn_event_data_init(obj TSRMLS_CC
);
1158 PQfinish(obj
->conn
);
1161 obj
->conn
= PQconnectStart(dsn_str
);
1162 obj
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
1164 obj
->conn
= PQconnectdb(dsn_str
);
1166 PQsetNoticeReceiver(obj
->conn
, php_pqconn_notice_recv
, obj
);
1167 PQregisterEventProc(obj
->conn
, php_pqconn_event
, "ext-pq", data
);
1168 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
1169 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection failed: %s", PQerrorMessage(obj
->conn
));
1172 zend_restore_error_handling(&zeh TSRMLS_CC
);
1175 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
1176 ZEND_END_ARG_INFO();
1177 static PHP_METHOD(pqconn
, reset
) {
1178 if (SUCCESS
== zend_parse_parameters_none()) {
1179 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1184 if (CONNECTION_OK
== PQstatus(obj
->conn
)) {
1187 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection reset failed: %s", PQerrorMessage(obj
->conn
));
1190 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1196 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
1197 ZEND_END_ARG_INFO();
1198 static PHP_METHOD(pqconn
, resetAsync
) {
1199 if (SUCCESS
== zend_parse_parameters_none()) {
1200 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1203 if (PQresetStart(obj
->conn
)) {
1204 obj
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
1208 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1214 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
)
1216 HashTable ht
, *existing_listeners
;
1218 php_pq_callback_addref(listener
);
1220 if (SUCCESS
== zend_hash_find(&obj
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
1221 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
1223 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
1224 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
1225 zend_hash_add(&obj
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
1229 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
1230 ZEND_ARG_INFO(0, channel
)
1231 ZEND_ARG_INFO(0, callable
)
1232 ZEND_END_ARG_INFO();
1233 static PHP_METHOD(pqconn
, listen
) {
1234 char *channel_str
= NULL
;
1235 int channel_len
= 0;
1236 php_pq_callback_t listener
;
1238 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
)) {
1239 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1241 obj
->poller
= PQconsumeInput
;
1244 char *quoted_channel
= PQescapeIdentifier(obj
->conn
, channel_str
, channel_len
);
1246 if (quoted_channel
) {
1250 spprintf(&cmd
, 0, "LISTEN %s", channel_str
);
1251 res
= PQexec(obj
->conn
, cmd
);
1254 PQfreemem(quoted_channel
);
1258 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1259 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
1266 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not install listener: %s", PQerrorMessage(obj
->conn
));
1270 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1272 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape channel identifier: %s", PQerrorMessage(obj
->conn
));
1275 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1281 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
1282 ZEND_ARG_INFO(0, channel
)
1283 ZEND_ARG_INFO(0, message
)
1284 ZEND_END_ARG_INFO();
1285 static PHP_METHOD(pqconn
, notify
) {
1286 char *channel_str
, *message_str
;
1287 int channel_len
, message_len
;
1289 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
)) {
1290 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1294 char *params
[2] = {channel_str
, message_str
};
1296 res
= PQexecParams(obj
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
1299 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1306 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not notify listeners: %s", PQerrorMessage(obj
->conn
));
1310 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1313 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1319 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
1320 ZEND_END_ARG_INFO();
1321 static PHP_METHOD(pqconn
, poll
) {
1322 if (SUCCESS
== zend_parse_parameters_none()) {
1323 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1327 if (obj
->poller
== PQconsumeInput
) {
1328 RETVAL_LONG(obj
->poller(obj
->conn
) * PGRES_POLLING_OK
);
1329 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1332 RETURN_LONG(obj
->poller(obj
->conn
));
1335 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "No asynchronous operation active");
1338 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1344 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
1345 ZEND_ARG_INFO(0, query
)
1346 ZEND_END_ARG_INFO();
1347 static PHP_METHOD(pqconn
, exec
) {
1348 zend_error_handling zeh
;
1352 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1353 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
)) {
1354 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1357 PGresult
*res
= PQexec(obj
->conn
, query_str
);
1359 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1362 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1363 return_value
->type
= IS_OBJECT
;
1364 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1367 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1370 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1373 zend_restore_error_handling(&zeh TSRMLS_CC
);
1376 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
1377 ZEND_END_ARG_INFO();
1378 static PHP_METHOD(pqconn
, getResult
) {
1379 if (SUCCESS
== zend_parse_parameters_none()) {
1380 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1383 PGresult
*res
= PQgetResult(obj
->conn
);
1386 return_value
->type
= IS_OBJECT
;
1387 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1392 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1398 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
1399 ZEND_ARG_INFO(0, query
)
1400 ZEND_ARG_INFO(0, callable
)
1401 ZEND_END_ARG_INFO();
1402 static PHP_METHOD(pqconn
, execAsync
) {
1403 zend_error_handling zeh
;
1404 php_pq_callback_t resolver
= {{0}};
1408 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1409 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
)) {
1410 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1413 php_pq_callback_dtor(&obj
->onevent
);
1414 if (resolver
.fci
.size
> 0) {
1415 obj
->onevent
= resolver
;
1416 php_pq_callback_addref(&obj
->onevent
);
1419 obj
->poller
= PQconsumeInput
;
1421 if (PQsendQuery(obj
->conn
, query_str
)) {
1422 if (zend_is_true(zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1423 if (!PQsetSingleRowMode(obj
->conn
)) {
1424 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1429 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1433 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1437 zend_restore_error_handling(&zeh TSRMLS_CC
);
1440 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
1445 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
1446 convert_to_long_ex(ztype
);
1449 **types
= Z_LVAL_PP(ztype
);
1452 if (*ztype
!= *(zval
**)p
) {
1453 zval_ptr_dtor(ztype
);
1455 return ZEND_HASH_APPLY_KEEP
;
1458 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1464 params
= (char ***) va_arg(argv
, char ***);
1465 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
1467 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
1471 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
1472 convert_to_string_ex(zparam
);
1475 **params
= Z_STRVAL_PP(zparam
);
1478 if (*zparam
!= *(zval
**)p
) {
1479 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
1482 return ZEND_HASH_APPLY_KEEP
;
1485 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
1487 int count
= zend_hash_num_elements(ht
);
1494 /* +1 for when less types than params are specified */
1495 *types
= tmp
= ecalloc(count
+ 1, sizeof(Oid
));
1496 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
1502 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
1504 int count
= zend_hash_num_elements(ht
);
1511 *params
= tmp
= ecalloc(count
, sizeof(char *));
1512 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
1518 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
1519 ZEND_ARG_INFO(0, query
)
1520 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1521 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1522 ZEND_END_ARG_INFO();
1523 static PHP_METHOD(pqconn
, execParams
) {
1524 zend_error_handling zeh
;
1528 zval
*ztypes
= NULL
;
1530 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1531 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
)) {
1532 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1538 char **params
= NULL
;
1541 ZEND_INIT_SYMTABLE(&zdtor
);
1542 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1545 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
1548 res
= PQexecParams(obj
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
1550 zend_hash_destroy(&zdtor
);
1558 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1561 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1562 return_value
->type
= IS_OBJECT
;
1563 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1566 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1570 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1574 zend_restore_error_handling(&zeh TSRMLS_CC
);
1577 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
1578 ZEND_ARG_INFO(0, query
)
1579 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1580 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1581 ZEND_ARG_INFO(0, callable
)
1582 ZEND_END_ARG_INFO();
1583 static PHP_METHOD(pqconn
, execParamsAsync
) {
1584 zend_error_handling zeh
;
1585 php_pq_callback_t resolver
= {{0}};
1589 zval
*ztypes
= NULL
;
1591 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1592 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
)) {
1593 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1598 char **params
= NULL
;
1601 ZEND_INIT_SYMTABLE(&zdtor
);
1602 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1605 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
1608 php_pq_callback_dtor(&obj
->onevent
);
1609 if (resolver
.fci
.size
> 0) {
1610 obj
->onevent
= resolver
;
1611 php_pq_callback_addref(&obj
->onevent
);
1614 obj
->poller
= PQconsumeInput
;
1616 if (PQsendQueryParams(obj
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
1617 if (zend_is_true(zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1618 if (!PQsetSingleRowMode(obj
->conn
)) {
1619 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1624 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1628 zend_hash_destroy(&zdtor
);
1636 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1639 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1643 zend_restore_error_handling(&zeh TSRMLS_CC
);
1646 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
1654 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1658 count
= zend_hash_num_elements(typest
);
1659 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
1662 res
= PQprepare(obj
->conn
, name
, query
, count
, types
);
1669 rv
= php_pqres_success(res TSRMLS_CC
);
1673 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement: %s", PQerrorMessage(obj
->conn
));
1679 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
1680 ZEND_ARG_INFO(0, name
)
1681 ZEND_ARG_INFO(0, query
)
1682 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1683 ZEND_END_ARG_INFO();
1684 static PHP_METHOD(pqconn
, prepare
) {
1685 zend_error_handling zeh
;
1686 zval
*ztypes
= NULL
;
1687 char *name_str
, *query_str
;
1688 int name_len
, *query_len
;
1690 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1691 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
1692 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1695 if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1696 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
1698 stm
->conn
= getThis();
1699 Z_ADDREF_P(stm
->conn
);
1700 stm
->name
= estrdup(name_str
);
1702 return_value
->type
= IS_OBJECT
;
1703 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
1705 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1707 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1710 zend_restore_error_handling(&zeh TSRMLS_CC
);
1713 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
1720 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1724 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
1727 if (PQsendPrepare(obj
->conn
, name
, query
, count
, types
)) {
1728 if (zend_is_true(zend_read_property(Z_OBJCE_P(object
), object
, ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1729 if (!PQsetSingleRowMode(obj
->conn
)) {
1730 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1735 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement: %s", PQerrorMessage(obj
->conn
));
1746 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
1747 ZEND_ARG_INFO(0, name
)
1748 ZEND_ARG_INFO(0, query
)
1749 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1750 ZEND_END_ARG_INFO();
1751 static PHP_METHOD(pqconn
, prepareAsync
) {
1752 zend_error_handling zeh
;
1753 zval
*ztypes
= NULL
;
1754 char *name_str
, *query_str
;
1755 int name_len
, *query_len
;
1757 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1758 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
1759 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1762 obj
->poller
= PQconsumeInput
;
1763 if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1764 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
1766 stm
->conn
= getThis();
1767 Z_ADDREF_P(stm
->conn
);
1768 stm
->name
= estrdup(name_str
);
1770 return_value
->type
= IS_OBJECT
;
1771 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
1773 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1775 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1778 zend_restore_error_handling(&zeh TSRMLS_CC
);
1781 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
1782 ZEND_ARG_INFO(0, string
)
1783 ZEND_END_ARG_INFO();
1784 static PHP_METHOD(pqconn
, quote
) {
1788 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1789 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1792 char *quoted
= PQescapeLiteral(obj
->conn
, str
, len
);
1795 RETVAL_STRING(quoted
, 1);
1798 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote string: %s", PQerrorMessage(obj
->conn
));
1802 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1808 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
1809 ZEND_ARG_INFO(0, name
)
1810 ZEND_END_ARG_INFO();
1811 static PHP_METHOD(pqconn
, quoteName
) {
1815 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1816 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1819 char *quoted
= PQescapeIdentifier(obj
->conn
, str
, len
);
1822 RETVAL_STRING(quoted
, 1);
1825 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote name: %s", PQerrorMessage(obj
->conn
));
1829 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1835 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
1836 ZEND_ARG_INFO(0, bytea
)
1837 ZEND_END_ARG_INFO();
1838 static PHP_METHOD(pqconn
, escapeBytea
) {
1842 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1843 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1847 char *escaped_str
= (char *) PQescapeByteaConn(obj
->conn
, (unsigned char *) str
, len
, &escaped_len
);
1850 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
1851 PQfreemem(escaped_str
);
1853 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape bytea: %s", PQerrorMessage(obj
->conn
));
1857 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1863 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
1864 ZEND_ARG_INFO(0, bytea
)
1865 ZEND_END_ARG_INFO();
1866 static PHP_METHOD(pqconn
, unescapeBytea
) {
1870 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1871 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1874 size_t unescaped_len
;
1875 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
1877 if (unescaped_str
) {
1878 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
1879 PQfreemem(unescaped_str
);
1881 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape bytea: %s", PQerrorMessage(obj
->conn
));
1885 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1891 static const char *isolation_level(long *isolation
) {
1892 switch (*isolation
) {
1893 case PHP_PQTXN_SERIALIZABLE
:
1894 return "SERIALIZABLE";
1895 case PHP_PQTXN_REPEATABLE_READ
:
1896 return "REPEATABLE READ";
1898 *isolation
= PHP_PQTXN_READ_COMMITTED
;
1900 case PHP_PQTXN_READ_COMMITTED
:
1901 return "READ COMMITTED";
1905 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
1908 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
1911 if (conn_obj
->conn
) {
1915 spprintf(&cmd
, 0, "START TRANSACTION ISOLATION LEVEL %s, READ %s, %s DEFERRABLE",
1916 isolation_level(&isolation
), readonly
? "ONLY" : "WRITE", deferrable
? "": "NOT");
1918 res
= PQexec(conn_obj
->conn
, cmd
);
1923 STATUS rv
= php_pqres_success(res TSRMLS_CC
);
1928 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not start transaction: %s", PQerrorMessage(conn_obj
->conn
));
1932 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1937 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
)
1940 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
1943 if (conn_obj
->conn
) {
1946 spprintf(&cmd
, 0, "START TRANSACTION ISOLATION LEVEL %s, READ %s, %s DEFERRABLE",
1947 isolation_level(&isolation
), readonly
? "ONLY" : "WRITE", deferrable
? "": "NOT");
1949 if (PQsendQuery(conn_obj
->conn
, cmd
)) {
1950 conn_obj
->poller
= PQconsumeInput
;
1955 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not start transaction: %s", PQerrorMessage(conn_obj
->conn
));
1959 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1964 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
1965 ZEND_ARG_INFO(0, isolation
)
1966 ZEND_ARG_INFO(0, readonly
)
1967 ZEND_ARG_INFO(0, deferrable
)
1968 ZEND_END_ARG_INFO();
1969 static PHP_METHOD(pqconn
, startTransaction
) {
1970 zend_error_handling zeh
;
1971 long isolation
= PHP_PQTXN_READ_COMMITTED
;
1972 zend_bool readonly
= 0, deferrable
= 0;
1974 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1975 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
)) {
1977 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1979 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
1981 if (SUCCESS
== rv
) {
1982 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1984 txn
->conn
= getThis();
1985 Z_ADDREF_P(txn
->conn
);
1986 txn
->isolation
= isolation
;
1987 txn
->readonly
= readonly
;
1988 txn
->deferrable
= deferrable
;
1990 return_value
->type
= IS_OBJECT
;
1991 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
1994 zend_restore_error_handling(&zeh TSRMLS_CC
);
1998 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
1999 ZEND_ARG_INFO(0, isolation
)
2000 ZEND_ARG_INFO(0, readonly
)
2001 ZEND_ARG_INFO(0, deferrable
)
2002 ZEND_END_ARG_INFO();
2003 static PHP_METHOD(pqconn
, startTransactionAsync
) {
2004 zend_error_handling zeh
;
2005 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2006 zend_bool readonly
= 0, deferrable
= 0;
2008 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2009 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
)) {
2011 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2013 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2015 if (SUCCESS
== rv
) {
2016 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2018 txn
->conn
= getThis();
2019 Z_ADDREF_P(txn
->conn
);
2020 txn
->isolation
= isolation
;
2021 txn
->readonly
= readonly
;
2022 txn
->deferrable
= deferrable
;
2024 return_value
->type
= IS_OBJECT
;
2025 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
2028 zend_restore_error_handling(&zeh TSRMLS_CC
);
2031 static zend_function_entry php_pqconn_methods
[] = {
2032 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2033 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
2034 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
2035 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
2036 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
2037 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
2038 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
2039 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
2040 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
2041 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
2042 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
2043 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
2044 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
2045 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
2046 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
2047 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
2048 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
2049 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
2050 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
2054 static zval
**php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type TSRMLS_DC
)
2057 php_pqres_fetch_t orig_fetch
;
2060 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2064 obj
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
2065 obj
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
2067 orig_fetch
= obj
->iter
->fetch_type
;
2068 obj
->iter
->fetch_type
= fetch_type
;
2069 if (SUCCESS
== obj
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->iter TSRMLS_CC
)) {
2070 obj
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->iter
, &row TSRMLS_CC
);
2071 obj
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
2073 obj
->iter
->fetch_type
= orig_fetch
;
2075 return row
? row
: NULL
;
2078 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
2079 ZEND_ARG_INFO(0, fetch_type
)
2080 ZEND_END_ARG_INFO();
2081 static PHP_METHOD(pqres
, fetchRow
) {
2082 zend_error_handling zeh
;
2083 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2084 long fetch_type
= obj
->iter
? obj
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
2086 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2087 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
)) {
2088 zval
**row
= php_pqres_iteration(getThis(), obj
, fetch_type TSRMLS_CC
);
2091 RETVAL_ZVAL(*row
, 1, 0);
2096 zend_restore_error_handling(&zeh TSRMLS_CC
);
2099 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
2102 HashTable
*ht
= HASH_OF(row
);
2103 int count
= zend_hash_num_elements(ht
);
2106 zend_hash_internal_pointer_reset(ht
);
2108 zend_hash_move_forward(ht
);
2110 zend_hash_get_current_data(ht
, (void *) &data
);
2112 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
2117 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
2118 ZEND_ARG_INFO(0, col_num
)
2119 ZEND_END_ARG_INFO();
2120 static PHP_METHOD(pqres
, fetchCol
) {
2121 zend_error_handling zeh
;
2124 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2125 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
)) {
2126 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2127 zval
**row
= php_pqres_iteration(getThis(), obj
, obj
->iter
? obj
->iter
->fetch_type
: 0 TSRMLS_CC
);
2130 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
2133 RETVAL_ZVAL(*col
, 1, 0);
2141 zend_restore_error_handling(&zeh TSRMLS_CC
);
2145 static zend_function_entry php_pqres_methods
[] = {
2146 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
2147 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
2151 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
2152 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
2153 ZEND_ARG_INFO(0, name
)
2154 ZEND_ARG_INFO(0, query
)
2155 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2156 ZEND_ARG_INFO(0, async
)
2157 ZEND_END_ARG_INFO();
2158 static PHP_METHOD(pqstm
, __construct
) {
2159 zend_error_handling zeh
;
2160 zval
*zconn
, *ztypes
= NULL
;
2161 char *name_str
, *query_str
;
2162 int name_len
, *query_len
;
2163 zend_bool async
= 0;
2165 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2166 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Oss|a/!b", &zconn
, php_pqconn_class_entry
, &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
, &async
)) {
2167 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2168 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2170 if (conn_obj
->conn
) {
2173 conn_obj
->poller
= PQconsumeInput
;
2174 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
2176 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
2177 php_pqconn_notify_listeners(zconn
, conn_obj TSRMLS_CC
);
2180 if (SUCCESS
== rv
) {
2181 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2184 Z_ADDREF_P(stm
->conn
);
2185 stm
->name
= estrdup(name_str
);
2189 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2192 zend_restore_error_handling(&zeh TSRMLS_CC
);
2195 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
2196 ZEND_ARG_ARRAY_INFO(0, params
, 1)
2197 ZEND_END_ARG_INFO();
2198 static PHP_METHOD(pqstm
, exec
) {
2199 zend_error_handling zeh
;
2200 zval
*zparams
= NULL
;
2202 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2203 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
)) {
2204 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2207 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->stm
->conn TSRMLS_CC
);
2209 if (conn_obj
->conn
) {
2211 char **params
= NULL
;
2216 ZEND_INIT_SYMTABLE(&zdtor
);
2217 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2220 res
= PQexecPrepared(conn_obj
->conn
, obj
->stm
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
2226 zend_hash_destroy(&zdtor
);
2229 php_pqconn_notify_listeners(obj
->stm
->conn
, conn_obj TSRMLS_CC
);
2232 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2233 return_value
->type
= IS_OBJECT
;
2234 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
2237 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement: %s", PQerrorMessage(conn_obj
->conn
));
2240 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2243 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
2246 zend_restore_error_handling(&zeh TSRMLS_CC
);
2249 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
2250 ZEND_ARG_ARRAY_INFO(0, params
, 1)
2251 ZEND_ARG_INFO(0, callable
)
2252 ZEND_END_ARG_INFO();
2253 static PHP_METHOD(pqstm
, execAsync
) {
2254 zend_error_handling zeh
;
2255 zval
*zparams
= NULL
;
2256 php_pq_callback_t resolver
= {{0}};
2258 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2259 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
)) {
2260 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2263 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->stm
->conn TSRMLS_CC
);
2265 if (conn_obj
->conn
) {
2267 char **params
= NULL
;
2271 ZEND_INIT_SYMTABLE(&zdtor
);
2272 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2275 php_pq_callback_dtor(&conn_obj
->onevent
);
2276 if (resolver
.fci
.size
> 0) {
2277 conn_obj
->onevent
= resolver
;
2278 php_pq_callback_addref(&conn_obj
->onevent
);
2281 conn_obj
->poller
= PQconsumeInput
;
2283 if (PQsendQueryPrepared(conn_obj
->conn
, obj
->stm
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
2284 if (zend_is_true(zend_read_property(Z_OBJCE_P(obj
->stm
->conn
), obj
->stm
->conn
, ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
2285 if (!PQsetSingleRowMode(conn_obj
->conn
)) {
2286 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(conn_obj
->conn
));
2291 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement: %s", PQerrorMessage(conn_obj
->conn
));
2299 zend_hash_destroy(&zdtor
);
2302 php_pqconn_notify_listeners(obj
->stm
->conn
, conn_obj TSRMLS_CC
);
2305 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2309 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
2313 zend_restore_error_handling(&zeh TSRMLS_CC
);
2316 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
2317 ZEND_END_ARG_INFO();
2318 static PHP_METHOD(pqstm
, desc
) {
2319 zend_error_handling zeh
;
2321 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2322 if (SUCCESS
== zend_parse_parameters_none()) {
2323 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2326 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->stm
->conn TSRMLS_CC
);
2328 if (conn_obj
->conn
) {
2329 PGresult
*res
= PQdescribePrepared(conn_obj
->conn
, obj
->stm
->name
);
2331 php_pqconn_notify_listeners(obj
->stm
->conn
, conn_obj TSRMLS_CC
);
2334 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2337 array_init(return_value
);
2338 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
2339 add_next_index_long(return_value
, PQparamtype(res
, p
));
2343 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not describe statement: %s", PQerrorMessage(conn_obj
->conn
));
2346 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2349 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
2352 zend_restore_error_handling(&zeh TSRMLS_CC
);
2355 static zend_function_entry php_pqstm_methods
[] = {
2356 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2357 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
2358 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
2359 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
2363 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
2364 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
2365 ZEND_ARG_INFO(0, async
)
2366 ZEND_ARG_INFO(0, isolation
)
2367 ZEND_ARG_INFO(0, readonly
)
2368 ZEND_ARG_INFO(0, deferrable
)
2369 ZEND_END_ARG_INFO();
2370 static PHP_METHOD(pqtxn
, __construct
) {
2371 zend_error_handling zeh
;
2373 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2374 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
2376 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2377 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
)) {
2379 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2380 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2382 if (conn_obj
->conn
) {
2384 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2386 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2389 if (SUCCESS
== rv
) {
2391 zval_ptr_dtor(&obj
->txn
->conn
);
2395 obj
->txn
= ecalloc(1, sizeof(*obj
->txn
));
2396 obj
->txn
->conn
= zconn
;
2397 obj
->txn
->isolation
= isolation
;
2398 obj
->txn
->readonly
= readonly
;
2399 obj
->txn
->deferrable
= deferrable
;
2402 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2405 zend_restore_error_handling(&zeh TSRMLS_CC
);
2408 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
2409 ZEND_END_ARG_INFO();
2410 static PHP_METHOD(pqtxn
, commit
) {
2411 zend_error_handling zeh
;
2413 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2414 if (SUCCESS
== zend_parse_parameters_none()) {
2415 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2418 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2420 if (conn_obj
->conn
) {
2421 PGresult
*res
= PQexec(conn_obj
->conn
, "COMMIT");
2424 php_pqres_success(res TSRMLS_CC
);
2427 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not commit transaction: %s", PQerrorMessage(conn_obj
->conn
));
2430 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2433 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2436 zend_restore_error_handling(&zeh TSRMLS_CC
);
2439 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
2440 ZEND_END_ARG_INFO();
2441 static PHP_METHOD(pqtxn
, commitAsync
) {
2442 zend_error_handling zeh
;
2444 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2445 if (SUCCESS
== zend_parse_parameters_none()) {
2446 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2449 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2451 if (conn_obj
->conn
) {
2452 conn_obj
->poller
= PQconsumeInput
;
2454 if (!PQsendQuery(conn_obj
->conn
, "COMMIT")) {
2455 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not commit transaction: %s", PQerrorMessage(conn_obj
->conn
));
2458 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2461 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2464 zend_restore_error_handling(&zeh TSRMLS_CC
);
2467 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
2468 ZEND_END_ARG_INFO();
2469 static PHP_METHOD(pqtxn
, rollback
) {
2470 zend_error_handling zeh
;
2472 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2473 if (SUCCESS
== zend_parse_parameters_none()) {
2474 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2477 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2479 if (conn_obj
->conn
) {
2480 PGresult
*res
= PQexec(conn_obj
->conn
, "ROLLBACK");
2483 php_pqres_success(res TSRMLS_CC
);
2486 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not rollback transaction: %s", PQerrorMessage(conn_obj
->conn
));
2489 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2492 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2495 zend_restore_error_handling(&zeh TSRMLS_CC
);
2498 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
2499 ZEND_END_ARG_INFO();
2500 static PHP_METHOD(pqtxn
, rollbackAsync
) {
2501 zend_error_handling zeh
;
2503 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2504 if (SUCCESS
== zend_parse_parameters_none()) {
2505 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2508 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2510 if (conn_obj
->conn
) {
2511 conn_obj
->poller
= PQconsumeInput
;
2512 if (!PQsendQuery(conn_obj
->conn
, "REOLLBACK")) {
2513 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not rollback transaction: %s", PQerrorMessage(conn_obj
->conn
));
2516 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2519 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2522 zend_restore_error_handling(&zeh TSRMLS_CC
);
2525 static zend_function_entry php_pqtxn_methods
[] = {
2526 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2527 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
2528 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
2529 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
2530 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
2534 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
2535 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
2536 ZEND_END_ARG_INFO();
2537 static PHP_METHOD(pqcancel
, __construct
) {
2538 zend_error_handling zeh
;
2541 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2542 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
)) {
2543 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2545 if (conn_obj
->conn
) {
2546 PGcancel
*cancel
= PQgetCancel(conn_obj
->conn
);
2549 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2551 obj
->cancel
= ecalloc(1, sizeof(*obj
->cancel
));
2552 obj
->cancel
->cancel
= cancel
;
2553 obj
->cancel
->conn
= zconn
;
2554 Z_ADDREF_P(obj
->cancel
->conn
);
2556 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not acquire cancel: %s", PQerrorMessage(conn_obj
->conn
));
2559 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2562 zend_restore_error_handling(&zeh TSRMLS_CC
);
2565 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
2566 ZEND_END_ARG_INFO();
2567 static PHP_METHOD(pqcancel
, cancel
) {
2568 zend_error_handling zeh
;
2570 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2571 if (SUCCESS
== zend_parse_parameters_none()) {
2572 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2577 if (!PQcancel(obj
->cancel
->cancel
, err
, sizeof(err
))) {
2578 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not request cancellation: %s", err
);
2581 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Cancel not initialized");
2584 zend_restore_error_handling(&zeh TSRMLS_CC
);
2587 static zend_function_entry php_pqcancel_methods
[] = {
2588 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2589 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
2593 /* {{{ PHP_MINIT_FUNCTION
2595 static PHP_MINIT_FUNCTION(pq
)
2597 zend_class_entry ce
= {0};
2598 php_pq_object_prophandler_t ph
= {0};
2600 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
2601 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2602 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
2604 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2605 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
2606 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
2607 php_pqconn_object_handlers
.clone_obj
= NULL
;
2608 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
2609 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2611 zend_hash_init(&php_pqconn_object_prophandlers
, 8, NULL
, NULL
, 1);
2613 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2614 ph
.read
= php_pqconn_object_read_status
;
2615 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
2617 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2618 ph
.read
= php_pqconn_object_read_transaction_status
;
2619 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
2621 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2622 ph
.read
= NULL
; /* forward to std prophandler */
2623 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
2625 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2626 ph
.read
= php_pqconn_object_read_error_message
;
2627 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
2629 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("types"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2630 ph
.read
= php_pqconn_object_read_types
;
2631 zend_hash_add(&php_pqconn_object_prophandlers
, "types", sizeof("types"), (void *) &ph
, sizeof(ph
), NULL
);
2633 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2634 ph
.read
= php_pqconn_object_read_busy
;
2635 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
2637 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2638 ph
.read
= php_pqconn_object_read_encoding
;
2639 ph
.write
= php_pqconn_object_write_encoding
;
2640 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
2643 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2645 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
2646 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
2647 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
2648 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
2649 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
2650 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
2651 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
2652 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
2654 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
2655 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
2656 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
2657 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
2658 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
2660 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
2661 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
2662 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
2663 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
2665 memset(&ce
, 0, sizeof(ce
));
2666 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
2667 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2668 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
2669 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
2670 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
2671 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 1, zend_ce_traversable
);
2673 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2674 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
2675 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
2676 php_pqres_object_handlers
.clone_obj
= NULL
;
2677 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
2678 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2680 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
2682 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2683 ph
.read
= php_pqres_object_read_status
;
2684 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
2686 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2687 ph
.read
= php_pqres_object_read_error_message
;
2688 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
2690 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2691 ph
.read
= php_pqres_object_read_num_rows
;
2692 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
2694 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2695 ph
.read
= php_pqres_object_read_num_cols
;
2696 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
2698 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2699 ph
.read
= php_pqres_object_read_affected_rows
;
2700 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
2702 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2703 ph
.read
= php_pqres_object_read_fetch_type
;
2704 ph
.write
= php_pqres_object_write_fetch_type
;
2705 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
2708 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
2709 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
2710 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
2711 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
2712 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
2713 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
2714 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
2715 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
2716 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
2717 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
2719 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
2720 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
2721 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
2723 memset(&ce
, 0, sizeof(ce
));
2724 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
2725 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2726 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
2728 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2729 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
2730 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
2731 php_pqstm_object_handlers
.clone_obj
= NULL
;
2732 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
2733 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2735 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
2737 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2738 ph
.read
= php_pqstm_object_read_name
;
2739 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
2741 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2742 ph
.read
= php_pqstm_object_read_connection
;
2743 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
2745 memset(&ce
, 0, sizeof(ce
));
2746 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
2747 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2748 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
2750 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2751 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
2752 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
2753 php_pqtxn_object_handlers
.clone_obj
= NULL
;
2754 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
2755 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2757 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
2759 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2760 ph
.read
= php_pqtxn_object_read_connection
;
2761 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
2763 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2764 ph
.read
= php_pqtxn_object_read_isolation
;
2765 ph
.write
= php_pqtxn_object_write_isolation
;
2766 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
2768 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("readonly"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2769 ph
.read
= php_pqtxn_object_read_readonly
;
2770 ph
.write
= php_pqtxn_object_write_readonly
;
2771 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
2773 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2774 ph
.read
= php_pqtxn_object_read_deferrable
;
2775 ph
.write
= php_pqtxn_object_write_deferrable
;
2776 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
2779 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
2780 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
2781 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
2783 memset(&ce
, 0, sizeof(ce
));
2784 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
2785 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2786 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
2788 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2789 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
2790 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
2791 php_pqcancel_object_handlers
.clone_obj
= NULL
;
2792 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
2793 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2795 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
2797 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2798 ph
.read
= php_pqcancel_object_read_connection
;
2799 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
2802 REGISTER_INI_ENTRIES();
2808 /* {{{ PHP_MSHUTDOWN_FUNCTION
2810 static PHP_MSHUTDOWN_FUNCTION(pq
)
2812 /* uncomment this line if you have INI entries
2813 UNREGISTER_INI_ENTRIES();
2819 /* {{{ PHP_MINFO_FUNCTION
2821 static PHP_MINFO_FUNCTION(pq
)
2823 php_info_print_table_start();
2824 php_info_print_table_header(2, "pq support", "enabled");
2825 php_info_print_table_end();
2827 /* Remove comments if you have entries in php.ini
2828 DISPLAY_INI_ENTRIES();
2833 const zend_function_entry pq_functions
[] = {
2837 /* {{{ pq_module_entry
2839 zend_module_entry pq_module_entry
= {
2840 STANDARD_MODULE_HEADER
,
2845 NULL
,/*PHP_RINIT(pq),*/
2846 NULL
,/*PHP_RSHUTDOWN(pq),*/
2849 STANDARD_MODULE_PROPERTIES
2853 #ifdef COMPILE_DL_PQ
2863 * vim600: noet sw=4 ts=4 fdm=marker
2864 * vim<600: noet sw=4 ts=4