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
;
60 static zend_object_handlers php_pqconn_object_handlers
;
61 static zend_object_handlers php_pqres_object_handlers
;
62 static zend_object_handlers php_pqstm_object_handlers
;
63 static zend_object_handlers php_pqtxn_object_handlers
;
65 typedef struct php_pq_callback
{
67 zend_fcall_info_cache fcc
;
71 typedef struct php_pq_object
{
74 HashTable
*prophandler
;
77 typedef struct php_pqconn_object
{
80 HashTable
*prophandler
;
82 int (*poller
)(PGconn
*);
84 php_pq_callback_t onevent
;
85 } php_pqconn_object_t
;
87 typedef struct php_pqconn_event_data
{
88 php_pqconn_object_t
*obj
;
92 } php_pqconn_event_data_t
;
94 typedef enum php_pqres_fetch
{
95 PHP_PQRES_FETCH_ARRAY
,
96 PHP_PQRES_FETCH_ASSOC
,
97 PHP_PQRES_FETCH_OBJECT
100 typedef struct php_pqres_iterator
{
101 zend_object_iterator zi
;
104 php_pqres_fetch_t fetch_type
;
105 } php_pqres_iterator_t
;
107 typedef struct php_pqres_object
{
110 HashTable
*prophandler
;
112 php_pqres_iterator_t
*iter
;
113 } php_pqres_object_t
;
115 typedef struct php_pqstm
{
120 typedef struct php_pqstm_object
{
123 HashTable
*prophandler
;
124 } php_pqstm_object_t
;
126 typedef enum php_pqtxn_isolation
{
127 PHP_PQTXN_READ_COMMITTED
,
128 PHP_PQTXN_REPEATABLE_READ
,
129 PHP_PQTXN_SERIALIZABLE
,
130 } php_pqtxn_isolation_t
;
132 typedef struct php_pqtxn
{
134 php_pqtxn_isolation_t isolation
;
136 unsigned deferrable
:1;
139 typedef struct php_pqtxn_object
{
142 HashTable
*prophandler
;
143 } php_pqtxn_object_t
;
145 static HashTable php_pqconn_object_prophandlers
;
146 static HashTable php_pqres_object_prophandlers
;
147 static HashTable php_pqstm_object_prophandlers
;
148 static HashTable php_pqtxn_object_prophandlers
;
150 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
152 typedef struct php_pq_object_prophandler
{
153 php_pq_object_prophandler_func_t read
;
154 php_pq_object_prophandler_func_t write
;
155 } php_pq_object_prophandler_t
;
157 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
159 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
161 php_pqres_iterator_t
*iter
;
162 zval
*prop
, *zfetch_type
;
164 iter
= ecalloc(1, sizeof(*iter
));
165 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
166 iter
->zi
.data
= object
;
169 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
170 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
171 convert_to_long_ex(&zfetch_type
);
173 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
174 if (zfetch_type
!= prop
) {
175 zval_ptr_dtor(&zfetch_type
);
177 if (Z_REFCOUNT_P(prop
)) {
178 zval_ptr_dtor(&prop
);
184 return (zend_object_iterator
*) iter
;
187 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
189 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
191 if (iter
->current_val
) {
192 zval_ptr_dtor(&iter
->current_val
);
193 iter
->current_val
= NULL
;
195 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
199 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
201 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
202 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
204 if (PQresultStatus(obj
->res
) != PGRES_TUPLES_OK
) {
207 if (PQntuples(obj
->res
) <= iter
->index
) {
214 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type TSRMLS_DC
)
220 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
226 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
227 if (PQgetisnull(res
, row
, c
)) {
228 switch (fetch_type
) {
229 case PHP_PQRES_FETCH_OBJECT
:
230 add_property_null(data
, PQfname(res
, c
));
233 case PHP_PQRES_FETCH_ASSOC
:
234 add_assoc_null(data
, PQfname(res
, c
));
237 case PHP_PQRES_FETCH_ARRAY
:
238 add_index_null(data
, c
);
242 char *val
= PQgetvalue(res
, row
, c
);
243 int len
= PQgetlength(res
, row
, c
);
245 switch (fetch_type
) {
246 case PHP_PQRES_FETCH_OBJECT
:
247 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
250 case PHP_PQRES_FETCH_ASSOC
:
251 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
254 case PHP_PQRES_FETCH_ARRAY
:
255 add_index_stringl(data
, c
, val
, len
,1);
264 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
266 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
267 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
269 if (iter
->current_val
) {
270 zval_ptr_dtor(&iter
->current_val
);
272 iter
->current_val
= php_pqres_row_to_zval(obj
->res
, iter
->index
, iter
->fetch_type TSRMLS_CC
);
273 *data_ptr
= &iter
->current_val
;
276 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
278 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
280 *key_num
= (ulong
) iter
->index
;
282 return HASH_KEY_IS_LONG
;
285 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
287 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
292 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
294 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
299 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
300 php_pqres_iterator_dtor
,
301 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
302 php_pqres_iterator_valid
,
303 /* fetch the item data for the current element */
304 php_pqres_iterator_current
,
305 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
306 php_pqres_iterator_key
,
307 /* step forwards to next element */
308 php_pqres_iterator_next
,
309 /* rewind to start of data (optional, may be NULL) */
310 php_pqres_iterator_rewind
,
311 /* invalidate current value/key (optional, may be NULL) */
315 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
317 switch (PQresultStatus(res
)) {
318 case PGRES_BAD_RESPONSE
:
319 case PGRES_NONFATAL_ERROR
:
320 case PGRES_FATAL_ERROR
:
321 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "%s", PQresultErrorMessage(res
));
328 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
329 if (cb
->fci
.size
> 0) {
330 zend_fcall_info_args_clear(&cb
->fci
, 1);
331 zval_ptr_dtor(&cb
->fci
.function_name
);
332 if (cb
->fci
.object_ptr
) {
333 zval_ptr_dtor(&cb
->fci
.object_ptr
);
339 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
341 Z_ADDREF_P(cb
->fci
.function_name
);
342 if (cb
->fci
.object_ptr
) {
343 Z_ADDREF_P(cb
->fci
.object_ptr
);
347 static void php_pqconn_object_free(void *o TSRMLS_DC
)
349 php_pqconn_object_t
*obj
= o
;
355 if (obj
->onevent
.fci
.size
> 0) {
356 php_pq_callback_dtor(&obj
->onevent
);
358 zend_hash_destroy(&obj
->listeners
);
359 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
363 static int php_pqconn_event(PGEventId id
, void *e
, void *data
);
365 static void php_pqres_object_free(void *o TSRMLS_DC
)
367 php_pqres_object_t
*obj
= o
;
370 zval
*res
= PQresultInstanceData(obj
->res
, php_pqconn_event
);
372 PQresultSetInstanceData(obj
->res
, php_pqconn_event
, NULL
);
380 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
383 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
387 static void php_pqstm_object_free(void *o TSRMLS_DC
)
389 php_pqstm_object_t
*obj
= o
;
392 zval_ptr_dtor(&obj
->stm
->conn
);
393 efree(obj
->stm
->name
);
397 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
401 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
403 php_pqtxn_object_t
*obj
= o
;
406 zval_ptr_dtor(&obj
->txn
->conn
);
407 obj
->txn
->conn
= NULL
;
411 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
415 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, PGconn
*conn
, php_pqconn_object_t
**ptr TSRMLS_DC
)
417 zend_object_value ov
;
418 php_pqconn_object_t
*o
;
420 o
= ecalloc(1, sizeof(*o
));
421 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
422 object_properties_init((zend_object
*) o
, ce
);
423 o
->prophandler
= &php_pqconn_object_prophandlers
;
433 zend_hash_init(&o
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
435 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
436 ov
.handlers
= &php_pqconn_object_handlers
;
441 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, PGresult
*res
, php_pqres_object_t
**ptr TSRMLS_DC
)
443 zend_object_value ov
;
444 php_pqres_object_t
*o
;
446 o
= ecalloc(1, sizeof(*o
));
447 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
448 object_properties_init((zend_object
*) o
, ce
);
449 o
->prophandler
= &php_pqres_object_prophandlers
;
459 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
460 ov
.handlers
= &php_pqres_object_handlers
;
465 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*stm
, php_pqstm_object_t
**ptr TSRMLS_DC
)
467 zend_object_value ov
;
468 php_pqstm_object_t
*o
;
470 o
= ecalloc(1, sizeof(*o
));
471 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
472 object_properties_init((zend_object
*) o
, ce
);
473 o
->prophandler
= &php_pqstm_object_prophandlers
;
483 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
484 ov
.handlers
= &php_pqstm_object_handlers
;
489 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*txn
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
491 zend_object_value ov
;
492 php_pqtxn_object_t
*o
;
494 o
= ecalloc(1, sizeof(*o
));
495 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
496 object_properties_init((zend_object
*) o
, ce
);
497 o
->prophandler
= &php_pqtxn_object_prophandlers
;
507 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
508 ov
.handlers
= &php_pqtxn_object_handlers
;
513 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
515 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
518 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
520 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
523 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
525 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
528 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
530 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
533 static int apply_ph_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
535 php_pq_object_prophandler_t
*ph
= p
;
536 HashTable
*ht
= va_arg(argv
, HashTable
*);
537 zval
**return_value
, *object
= va_arg(argv
, zval
*);
538 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
540 if (SUCCESS
== zend_hash_find(ht
, key
->arKey
, key
->nKeyLength
, (void *) &return_value
)) {
543 zval_ptr_dtor(return_value
);
544 MAKE_STD_ZVAL(*return_value
);
545 ZVAL_NULL(*return_value
);
547 ph
->read(object
, obj
, *return_value TSRMLS_CC
);
551 return ZEND_HASH_APPLY_KEEP
;
554 static int apply_pi_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
556 zend_property_info
*pi
= p
;
557 HashTable
*ht
= va_arg(argv
, HashTable
*);
558 zval
*object
= va_arg(argv
, zval
*);
559 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
560 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
562 if (!Z_REFCOUNT_P(property
)) {
563 Z_ADDREF_P(property
);
565 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
567 return ZEND_HASH_APPLY_KEEP
;
570 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
573 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
577 ZEND_INIT_SYMTABLE(ht
);
579 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_debug
, 3, ht
, object
, obj
);
580 zend_hash_apply_with_arguments(obj
->prophandler TSRMLS_CC
, apply_ph_to_debug
, 3, ht
, object
, obj
);
584 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
586 php_pqconn_object_t
*obj
= o
;
588 RETVAL_LONG(PQstatus(obj
->conn
));
591 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
593 php_pqconn_object_t
*obj
= o
;
595 RETVAL_LONG(PQtransactionStatus(obj
->conn
));
598 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
600 php_pqconn_object_t
*obj
= o
;
601 char *error
= PQerrorMessage(obj
->conn
);
604 RETVAL_STRING(error
, 1);
610 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
612 php_pq_callback_t
*listener
= p
;
614 zval
*zpid
, *zchannel
, *zmessage
;
617 ZVAL_LONG(zpid
, nfy
->be_pid
);
618 MAKE_STD_ZVAL(zchannel
);
619 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
620 MAKE_STD_ZVAL(zmessage
);
621 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
623 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
624 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
626 zval_ptr_dtor(&zchannel
);
627 zval_ptr_dtor(&zmessage
);
628 zval_ptr_dtor(&zpid
);
630 return ZEND_HASH_APPLY_KEEP
;
633 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
635 HashTable
*listeners
= p
;
636 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
638 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
639 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
642 return ZEND_HASH_APPLY_KEEP
;
645 static void php_pqconn_notify_listeners(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
650 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
653 while ((nfy
= PQnotifies(obj
->conn
))) {
654 zend_hash_apply_with_arguments(&obj
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
659 /* FIXME: extend to types->nspname->typname */
660 #define PHP_PQ_TYPES_QUERY \
661 "select t.oid, t.* " \
662 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
663 "where typisdefined " \
665 "and nspname in ('public', 'pg_catalog')"
666 static void php_pqconn_object_read_types(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
668 php_pqconn_object_t
*obj
= o
;
669 PGresult
*res
= PQexec(obj
->conn
, PHP_PQ_TYPES_QUERY
);
671 php_pqconn_notify_listeners(object
, obj TSRMLS_CC
);
673 /* FIXME: cache that */
675 if (PGRES_TUPLES_OK
== PQresultStatus(res
)) {
677 zval
*byoid
, *byname
;
679 MAKE_STD_ZVAL(byoid
);
680 MAKE_STD_ZVAL(byname
);
683 object_init(return_value
);
684 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
685 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
687 add_property_zval(byoid
, PQgetvalue(res
, r
, 0), row
);
688 add_property_zval(byname
, PQgetvalue(res
, r
, 1), row
);
692 add_property_zval(return_value
, "byOid", byoid
);
693 add_property_zval(return_value
, "byName", byname
);
694 zval_ptr_dtor(&byoid
);
695 zval_ptr_dtor(&byname
);
697 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types: %s", PQresultErrorMessage(res
));
701 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types: %s", PQerrorMessage(obj
->conn
));
705 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
707 php_pqconn_object_t
*obj
= o
;
709 RETVAL_BOOL(PQisBusy(obj
->conn
));
712 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
714 php_pqconn_object_t
*obj
= o
;
716 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->conn
)), 1);
719 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
721 php_pqconn_object_t
*obj
= o
;
724 if (Z_TYPE_P(value
) != IS_STRING
) {
725 convert_to_string_ex(&zenc
);
728 if (0 > PQsetClientEncoding(obj
->conn
, Z_STRVAL_P(zenc
))) {
729 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
733 zval_ptr_dtor(&zenc
);
737 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
739 php_pqres_object_t
*obj
= o
;
741 RETVAL_LONG(PQresultStatus(obj
->res
));
744 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
746 php_pqres_object_t
*obj
= o
;
747 char *error
= PQresultErrorMessage(obj
->res
);
750 RETVAL_STRING(error
, 1);
756 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
758 php_pqres_object_t
*obj
= o
;
760 RETVAL_LONG(PQntuples(obj
->res
));
763 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
765 php_pqres_object_t
*obj
= o
;
767 RETVAL_LONG(PQnfields(obj
->res
));
770 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
772 php_pqres_object_t
*obj
= o
;
774 RETVAL_LONG(atoi(PQcmdTuples(obj
->res
)));
777 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
779 php_pqres_object_t
*obj
= o
;
782 RETVAL_LONG(obj
->iter
->fetch_type
);
784 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
788 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
790 php_pqres_object_t
*obj
= o
;
791 zval
*zfetch_type
= value
;
793 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
794 convert_to_long_ex(&zfetch_type
);
798 obj
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
799 obj
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
801 obj
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
803 if (zfetch_type
!= value
) {
804 zval_ptr_dtor(&zfetch_type
);
808 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
810 php_pqstm_object_t
*obj
= o
;
812 RETVAL_STRING(obj
->stm
->name
, 1);
815 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
817 php_pqstm_object_t
*obj
= o
;
819 RETVAL_ZVAL(obj
->stm
->conn
, 1, 0);
822 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
824 php_pqtxn_object_t
*obj
= o
;
826 RETVAL_ZVAL(obj
->txn
->conn
, 1, 0);
829 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
831 php_pqtxn_object_t
*obj
= o
;
833 RETVAL_LONG(obj
->txn
->isolation
);
836 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
838 php_pqtxn_object_t
*obj
= o
;
840 RETVAL_LONG(obj
->txn
->readonly
);
843 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
845 php_pqtxn_object_t
*obj
= o
;
847 RETVAL_LONG(obj
->txn
->deferrable
);
850 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
852 php_pqtxn_object_t
*obj
= o
;
853 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
854 php_pqtxn_isolation_t orig
= obj
->txn
->isolation
;
855 zval
*zisolation
= value
;
858 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
859 convert_to_long_ex(&zisolation
);
862 switch ((obj
->txn
->isolation
= Z_LVAL_P(zisolation
))) {
863 case PHP_PQTXN_READ_COMMITTED
:
864 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION READ COMMITED");
866 case PHP_PQTXN_REPEATABLE_READ
:
867 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION REPEATABLE READ");
869 case PHP_PQTXN_SERIALIZABLE
:
870 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION SERIALIZABLE");
873 obj
->txn
->isolation
= orig
;
878 if (zisolation
!= value
) {
879 zval_ptr_dtor(&zisolation
);
883 php_pqres_success(res TSRMLS_CC
);
888 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
890 php_pqtxn_object_t
*obj
= o
;
891 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
894 if ((obj
->txn
->readonly
= zend_is_true(value
))) {
895 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION READ ONLY");
897 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION READ WRITE");
901 php_pqres_success(res TSRMLS_CC
);
906 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
908 php_pqtxn_object_t
*obj
= o
;
909 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
912 if ((obj
->txn
->deferrable
= zend_is_true(value
))) {
913 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION DEFERRABLE");
915 res
= PQexec(conn_obj
->conn
, "SET TRANSACTION NOT DEFERRABLE");
919 php_pqres_success(res TSRMLS_CC
);
924 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
931 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
933 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
934 php_pq_object_prophandler_t
*handler
;
938 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
939 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
940 if (type
== BP_VAR_R
) {
941 ALLOC_ZVAL(return_value
);
942 Z_SET_REFCOUNT_P(return_value
, 0);
943 Z_UNSET_ISREF_P(return_value
);
945 handler
->read(object
, obj
, return_value TSRMLS_CC
);
947 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
951 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
957 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
959 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
960 php_pq_object_prophandler_t
*handler
;
962 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
963 if (handler
->write
) {
964 handler
->write(object
, obj
, value TSRMLS_CC
);
967 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
971 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
973 zval
*zsocket
, zmember
;
979 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
982 INIT_PZVAL(&zmember
);
983 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
984 MAKE_STD_ZVAL(zsocket
);
986 if ((CONNECTION_BAD
!= PQstatus(obj
->conn
))
987 && (-1 < (socket
= PQsocket(obj
->conn
)))
988 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
989 php_stream_to_zval(stream
, zsocket
);
995 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
996 zval_ptr_dtor(&zsocket
);
1002 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1003 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1005 # define TSRMLS_DF(d)
1006 # define TSRMLS_CF(d)
1009 static void php_pqconn_event_register(PGEventRegister
*event
, php_pqconn_event_data_t
*data
)
1011 PQsetInstanceData(event
->conn
, php_pqconn_event
, data
);
1013 static void php_pqconn_event_conndestroy(PGEventConnDestroy
*event
, php_pqconn_event_data_t
*data
)
1015 PQsetInstanceData(event
->conn
, php_pqconn_event
, NULL
);
1018 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
, php_pqconn_event_data_t
*data
)
1022 if (data
->obj
->onevent
.fci
.size
> 0) {
1026 res
->type
= IS_OBJECT
;
1027 res
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, event
->result
, NULL TSRMLS_CC
);
1030 PQresultSetInstanceData(event
->result
, php_pqconn_event
, res
);
1032 zend_fcall_info_argn(&data
->obj
->onevent
.fci TSRMLS_CC
, 1, &res
);
1033 zend_fcall_info_call(&data
->obj
->onevent
.fci
, &data
->obj
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1034 zval_ptr_dtor(&res
);
1038 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1041 case PGEVT_REGISTER
:
1042 php_pqconn_event_register(e
, data
);
1044 case PGEVT_CONNDESTROY
:
1045 php_pqconn_event_conndestroy(e
, data
);
1047 case PGEVT_RESULTCREATE
:
1048 php_pqconn_event_resultcreate(e
, data
);
1057 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1059 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1067 static void php_pqconn_notice_recv(void *o
, const PGresult
*res
)
1069 php_pqconn_object_t
*obj
= o
;
1074 MAKE_STD_ZVAL(notice
);
1075 ZVAL_STRING(notice
, PQerrorMessage(res
), 1);
1078 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
1079 ZEND_ARG_INFO(0, dsn
)
1080 ZEND_ARG_INFO(0, async
)
1081 ZEND_END_ARG_INFO();
1082 static PHP_METHOD(pqconn
, __construct
) {
1083 zend_error_handling zeh
;
1086 zend_bool async
= 0;
1088 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1089 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|b", &dsn_str
, &dsn_len
, &async
)) {
1090 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1091 php_pqconn_event_data_t
*data
= php_pqconn_event_data_init(obj TSRMLS_CC
);
1094 PQfinish(obj
->conn
);
1097 obj
->conn
= PQconnectStart(dsn_str
);
1098 obj
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
1100 obj
->conn
= PQconnectdb(dsn_str
);
1102 PQsetNoticeReceiver(obj
->conn
, php_pqconn_notice_recv
, obj
);
1103 PQregisterEventProc(obj
->conn
, php_pqconn_event
, "ext-pq", data
);
1104 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
1105 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection failed: %s", PQerrorMessage(obj
->conn
));
1108 zend_restore_error_handling(&zeh TSRMLS_CC
);
1111 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
1112 ZEND_END_ARG_INFO();
1113 static PHP_METHOD(pqconn
, reset
) {
1114 if (SUCCESS
== zend_parse_parameters_none()) {
1115 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1120 if (CONNECTION_OK
== PQstatus(obj
->conn
)) {
1123 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection reset failed: %s", PQerrorMessage(obj
->conn
));
1126 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1132 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
1133 ZEND_END_ARG_INFO();
1134 static PHP_METHOD(pqconn
, resetAsync
) {
1135 if (SUCCESS
== zend_parse_parameters_none()) {
1136 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1139 if (PQresetStart(obj
->conn
)) {
1140 obj
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
1144 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1150 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
)
1152 HashTable ht
, *existing_listeners
;
1154 php_pq_callback_addref(listener
);
1156 if (SUCCESS
== zend_hash_find(&obj
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
1157 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
1159 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
1160 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
1161 zend_hash_add(&obj
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
1165 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
1166 ZEND_ARG_INFO(0, channel
)
1167 ZEND_ARG_INFO(0, callable
)
1168 ZEND_END_ARG_INFO();
1169 static PHP_METHOD(pqconn
, listen
) {
1170 char *channel_str
= NULL
;
1171 int channel_len
= 0;
1172 php_pq_callback_t listener
;
1174 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
)) {
1175 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1177 obj
->poller
= PQconsumeInput
;
1180 char *quoted_channel
= PQescapeIdentifier(obj
->conn
, channel_str
, channel_len
);
1182 if (quoted_channel
) {
1186 spprintf(&cmd
, 0, "LISTEN %s", channel_str
);
1187 res
= PQexec(obj
->conn
, cmd
);
1190 PQfreemem(quoted_channel
);
1194 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1195 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
1202 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not install listener: %s", PQerrorMessage(obj
->conn
));
1206 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1208 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape channel identifier: %s", PQerrorMessage(obj
->conn
));
1211 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1217 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
1218 ZEND_ARG_INFO(0, channel
)
1219 ZEND_ARG_INFO(0, message
)
1220 ZEND_END_ARG_INFO();
1221 static PHP_METHOD(pqconn
, notify
) {
1222 char *channel_str
, *message_str
;
1223 int channel_len
, message_len
;
1225 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
)) {
1226 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1230 char *params
[2] = {channel_str
, message_str
};
1232 res
= PQexecParams(obj
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
1235 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1242 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not notify listeners: %s", PQerrorMessage(obj
->conn
));
1246 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1249 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1255 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
1256 ZEND_END_ARG_INFO();
1257 static PHP_METHOD(pqconn
, poll
) {
1258 if (SUCCESS
== zend_parse_parameters_none()) {
1259 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1263 if (obj
->poller
== PQconsumeInput
) {
1264 RETVAL_LONG(obj
->poller(obj
->conn
) * PGRES_POLLING_OK
);
1265 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1268 RETURN_LONG(obj
->poller(obj
->conn
));
1271 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "No asynchronous operation active");
1274 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1280 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
1281 ZEND_ARG_INFO(0, query
)
1282 ZEND_END_ARG_INFO();
1283 static PHP_METHOD(pqconn
, exec
) {
1284 zend_error_handling zeh
;
1288 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1289 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
)) {
1290 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1293 PGresult
*res
= PQexec(obj
->conn
, query_str
);
1295 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1298 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1299 return_value
->type
= IS_OBJECT
;
1300 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1303 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1306 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1309 zend_restore_error_handling(&zeh TSRMLS_CC
);
1312 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
1313 ZEND_END_ARG_INFO();
1314 static PHP_METHOD(pqconn
, getResult
) {
1315 if (SUCCESS
== zend_parse_parameters_none()) {
1316 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1319 PGresult
*res
= PQgetResult(obj
->conn
);
1322 return_value
->type
= IS_OBJECT
;
1323 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1328 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1334 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
1335 ZEND_ARG_INFO(0, query
)
1336 ZEND_ARG_INFO(0, callable
)
1337 ZEND_END_ARG_INFO();
1338 static PHP_METHOD(pqconn
, execAsync
) {
1339 zend_error_handling zeh
;
1340 php_pq_callback_t resolver
;
1344 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1345 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
)) {
1346 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1349 php_pq_callback_dtor(&obj
->onevent
);
1350 if (resolver
.fci
.size
> 0) {
1351 obj
->onevent
= resolver
;
1352 php_pq_callback_addref(&obj
->onevent
);
1355 obj
->poller
= PQconsumeInput
;
1357 if (PQsendQuery(obj
->conn
, query_str
)) {
1358 if (zend_is_true(zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1359 if (!PQsetSingleRowMode(obj
->conn
)) {
1360 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1365 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1369 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1373 zend_restore_error_handling(&zeh TSRMLS_CC
);
1376 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
1381 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
1382 convert_to_long_ex(ztype
);
1385 **types
= Z_LVAL_PP(ztype
);
1388 if (*ztype
!= *(zval
**)p
) {
1389 zval_ptr_dtor(ztype
);
1391 return ZEND_HASH_APPLY_KEEP
;
1394 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1400 params
= (char ***) va_arg(argv
, char ***);
1401 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
1403 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
1407 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
1408 convert_to_string_ex(zparam
);
1411 **params
= Z_STRVAL_PP(zparam
);
1414 if (*zparam
!= *(zval
**)p
) {
1415 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
1418 return ZEND_HASH_APPLY_KEEP
;
1421 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
1423 int count
= zend_hash_num_elements(ht
);
1430 /* +1 for when less types than params are specified */
1431 *types
= tmp
= ecalloc(count
+ 1, sizeof(Oid
));
1432 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
1438 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
1440 int count
= zend_hash_num_elements(ht
);
1447 *params
= tmp
= ecalloc(count
, sizeof(char *));
1448 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
1454 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
1455 ZEND_ARG_INFO(0, query
)
1456 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1457 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1458 ZEND_END_ARG_INFO();
1459 static PHP_METHOD(pqconn
, execParams
) {
1460 zend_error_handling zeh
;
1464 zval
*ztypes
= NULL
;
1466 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1467 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
)) {
1468 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1474 char **params
= NULL
;
1477 ZEND_INIT_SYMTABLE(&zdtor
);
1478 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1481 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
1484 res
= PQexecParams(obj
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
1486 zend_hash_destroy(&zdtor
);
1494 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1497 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1498 return_value
->type
= IS_OBJECT
;
1499 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1502 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1506 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1510 zend_restore_error_handling(&zeh TSRMLS_CC
);
1513 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
1514 ZEND_ARG_INFO(0, query
)
1515 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1516 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1517 ZEND_ARG_INFO(0, callable
)
1518 ZEND_END_ARG_INFO();
1519 static PHP_METHOD(pqconn
, execParamsAsync
) {
1520 zend_error_handling zeh
;
1521 php_pq_callback_t resolver
;
1525 zval
*ztypes
= NULL
;
1527 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1528 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
)) {
1529 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1534 char **params
= NULL
;
1537 ZEND_INIT_SYMTABLE(&zdtor
);
1538 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1541 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
1544 php_pq_callback_dtor(&obj
->onevent
);
1545 if (resolver
.fci
.size
> 0) {
1546 obj
->onevent
= resolver
;
1547 php_pq_callback_addref(&obj
->onevent
);
1550 obj
->poller
= PQconsumeInput
;
1552 if (PQsendQueryParams(obj
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
1553 if (zend_is_true(zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1554 if (!PQsetSingleRowMode(obj
->conn
)) {
1555 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1560 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1564 zend_hash_destroy(&zdtor
);
1572 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1575 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1579 zend_restore_error_handling(&zeh TSRMLS_CC
);
1582 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
1590 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1594 count
= zend_hash_num_elements(typest
);
1595 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
1598 res
= PQprepare(obj
->conn
, name
, query
, count
, types
);
1605 rv
= php_pqres_success(res TSRMLS_CC
);
1609 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement: %s", PQerrorMessage(obj
->conn
));
1615 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
1616 ZEND_ARG_INFO(0, name
)
1617 ZEND_ARG_INFO(0, query
)
1618 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1619 ZEND_END_ARG_INFO();
1620 static PHP_METHOD(pqconn
, prepare
) {
1621 zend_error_handling zeh
;
1622 zval
*ztypes
= NULL
;
1623 char *name_str
, *query_str
;
1624 int name_len
, *query_len
;
1626 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1627 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
1628 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1631 if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1632 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
1634 stm
->conn
= getThis();
1635 Z_ADDREF_P(stm
->conn
);
1636 stm
->name
= estrdup(name_str
);
1638 return_value
->type
= IS_OBJECT
;
1639 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
1641 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1643 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1646 zend_restore_error_handling(&zeh TSRMLS_CC
);
1649 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
1656 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1660 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
1663 if (PQsendPrepare(obj
->conn
, name
, query
, count
, types
)) {
1664 if (zend_is_true(zend_read_property(Z_OBJCE_P(object
), object
, ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1665 if (!PQsetSingleRowMode(obj
->conn
)) {
1666 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1671 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement: %s", PQerrorMessage(obj
->conn
));
1682 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
1683 ZEND_ARG_INFO(0, name
)
1684 ZEND_ARG_INFO(0, query
)
1685 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1686 ZEND_END_ARG_INFO();
1687 static PHP_METHOD(pqconn
, prepareAsync
) {
1688 zend_error_handling zeh
;
1689 zval
*ztypes
= NULL
;
1690 char *name_str
, *query_str
;
1691 int name_len
, *query_len
;
1693 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1694 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
1695 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1698 obj
->poller
= PQconsumeInput
;
1699 if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1700 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
1702 stm
->conn
= getThis();
1703 Z_ADDREF_P(stm
->conn
);
1704 stm
->name
= estrdup(name_str
);
1706 return_value
->type
= IS_OBJECT
;
1707 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
1709 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1711 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1714 zend_restore_error_handling(&zeh TSRMLS_CC
);
1717 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
1718 ZEND_ARG_INFO(0, string
)
1719 ZEND_END_ARG_INFO();
1720 static PHP_METHOD(pqconn
, quote
) {
1724 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1725 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1728 char *quoted
= PQescapeLiteral(obj
->conn
, str
, len
);
1731 RETVAL_STRING(quoted
, 1);
1734 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote string: %s", PQerrorMessage(obj
->conn
));
1738 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1744 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
1745 ZEND_ARG_INFO(0, name
)
1746 ZEND_END_ARG_INFO();
1747 static PHP_METHOD(pqconn
, quoteName
) {
1751 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1752 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1755 char *quoted
= PQescapeIdentifier(obj
->conn
, str
, len
);
1758 RETVAL_STRING(quoted
, 1);
1761 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote name: %s", PQerrorMessage(obj
->conn
));
1765 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1771 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
1772 ZEND_ARG_INFO(0, bytea
)
1773 ZEND_END_ARG_INFO();
1774 static PHP_METHOD(pqconn
, escapeBytea
) {
1778 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1779 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1783 char *escaped_str
= (char *) PQescapeByteaConn(obj
->conn
, (unsigned char *) str
, len
, &escaped_len
);
1786 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
1787 PQfreemem(escaped_str
);
1789 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape bytea: %s", PQerrorMessage(obj
->conn
));
1793 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1799 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
1800 ZEND_ARG_INFO(0, bytea
)
1801 ZEND_END_ARG_INFO();
1802 static PHP_METHOD(pqconn
, unescapeBytea
) {
1806 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1807 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1810 size_t unescaped_len
;
1811 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
1813 if (unescaped_str
) {
1814 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
1815 PQfreemem(unescaped_str
);
1817 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape bytea: %s", PQerrorMessage(obj
->conn
));
1821 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1827 static const char *isolation_level(long *isolation
) {
1828 switch (*isolation
) {
1829 case PHP_PQTXN_SERIALIZABLE
:
1830 return "SERIALIZABLE";
1831 case PHP_PQTXN_REPEATABLE_READ
:
1832 return "REPEATABLE READ";
1834 *isolation
= PHP_PQTXN_READ_COMMITTED
;
1836 case PHP_PQTXN_READ_COMMITTED
:
1837 return "READ COMMITTED";
1841 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
1844 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
1847 if (conn_obj
->conn
) {
1851 spprintf(&cmd
, 0, "START TRANSACTION ISOLATION LEVEL %s, READ %s, %s DEFERRABLE",
1852 isolation_level(&isolation
), readonly
? "ONLY" : "WRITE", deferrable
? "": "NOT");
1854 res
= PQexec(conn_obj
->conn
, cmd
);
1859 STATUS rv
= php_pqres_success(res TSRMLS_CC
);
1864 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not start transaction: %s", PQerrorMessage(conn_obj
->conn
));
1868 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1873 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
)
1876 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
1879 if (conn_obj
->conn
) {
1882 spprintf(&cmd
, 0, "START TRANSACTION ISOLATION LEVEL %s, READ %s, %s DEFERRABLE",
1883 isolation_level(&isolation
), readonly
? "ONLY" : "WRITE", deferrable
? "": "NOT");
1885 if (PQsendQuery(conn_obj
->conn
, cmd
)) {
1886 conn_obj
->poller
= PQconsumeInput
;
1891 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not start transaction: %s", PQerrorMessage(conn_obj
->conn
));
1895 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1900 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
1901 ZEND_ARG_INFO(0, isolation
)
1902 ZEND_ARG_INFO(0, readonly
)
1903 ZEND_ARG_INFO(0, deferrable
)
1904 ZEND_END_ARG_INFO();
1905 static PHP_METHOD(pqconn
, startTransaction
) {
1906 zend_error_handling zeh
;
1907 long isolation
= PHP_PQTXN_READ_COMMITTED
;
1908 zend_bool readonly
= 0, deferrable
= 0;
1910 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1911 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
)) {
1913 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1915 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
1917 if (SUCCESS
== rv
) {
1918 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1920 txn
->conn
= getThis();
1921 Z_ADDREF_P(txn
->conn
);
1922 txn
->isolation
= isolation
;
1923 txn
->readonly
= readonly
;
1924 txn
->deferrable
= deferrable
;
1926 return_value
->type
= IS_OBJECT
;
1927 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
1930 zend_restore_error_handling(&zeh TSRMLS_CC
);
1934 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
1935 ZEND_ARG_INFO(0, isolation
)
1936 ZEND_ARG_INFO(0, readonly
)
1937 ZEND_ARG_INFO(0, deferrable
)
1938 ZEND_END_ARG_INFO();
1939 static PHP_METHOD(pqconn
, startTransactionAsync
) {
1940 zend_error_handling zeh
;
1941 long isolation
= PHP_PQTXN_READ_COMMITTED
;
1942 zend_bool readonly
= 0, deferrable
= 0;
1944 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1945 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
)) {
1947 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1949 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
1951 if (SUCCESS
== rv
) {
1952 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1954 txn
->conn
= getThis();
1955 Z_ADDREF_P(txn
->conn
);
1956 txn
->isolation
= isolation
;
1957 txn
->readonly
= readonly
;
1958 txn
->deferrable
= deferrable
;
1960 return_value
->type
= IS_OBJECT
;
1961 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
1964 zend_restore_error_handling(&zeh TSRMLS_CC
);
1967 static zend_function_entry php_pqconn_methods
[] = {
1968 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
1969 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
1970 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
1971 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
1972 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
1973 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
1974 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
1975 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
1976 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
1977 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
1978 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
1979 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
1980 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
1981 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
1982 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
1983 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
1984 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
1985 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
1986 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
1990 static zval
**php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type TSRMLS_DC
)
1993 php_pqres_fetch_t orig_fetch
;
1996 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2000 obj
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
2001 obj
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
2003 orig_fetch
= obj
->iter
->fetch_type
;
2004 obj
->iter
->fetch_type
= fetch_type
;
2005 if (SUCCESS
== obj
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->iter TSRMLS_CC
)) {
2006 obj
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->iter
, &row TSRMLS_CC
);
2007 obj
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
2009 obj
->iter
->fetch_type
= orig_fetch
;
2011 return row
? row
: NULL
;
2014 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
2015 ZEND_ARG_INFO(0, fetch_type
)
2016 ZEND_END_ARG_INFO();
2017 static PHP_METHOD(pqres
, fetchRow
) {
2018 zend_error_handling zeh
;
2019 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2020 long fetch_type
= obj
->iter
? obj
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
2022 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2023 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
)) {
2024 zval
**row
= php_pqres_iteration(getThis(), obj
, fetch_type TSRMLS_CC
);
2027 RETVAL_ZVAL(*row
, 1, 0);
2032 zend_restore_error_handling(&zeh TSRMLS_CC
);
2035 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
2038 HashTable
*ht
= HASH_OF(row
);
2039 int count
= zend_hash_num_elements(ht
);
2042 zend_hash_internal_pointer_reset(ht
);
2044 zend_hash_move_forward(ht
);
2046 zend_hash_get_current_data(ht
, (void *) &data
);
2048 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
2053 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
2054 ZEND_ARG_INFO(0, col_num
)
2055 ZEND_END_ARG_INFO();
2056 static PHP_METHOD(pqres
, fetchCol
) {
2057 zend_error_handling zeh
;
2060 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2061 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
)) {
2062 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2063 zval
**row
= php_pqres_iteration(getThis(), obj
, obj
->iter
? obj
->iter
->fetch_type
: 0 TSRMLS_CC
);
2066 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
2069 RETVAL_ZVAL(*col
, 1, 0);
2077 zend_restore_error_handling(&zeh TSRMLS_CC
);
2081 static zend_function_entry php_pqres_methods
[] = {
2082 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
2083 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
2087 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
2088 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
2089 ZEND_ARG_INFO(0, name
)
2090 ZEND_ARG_INFO(0, query
)
2091 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2092 ZEND_ARG_INFO(0, async
)
2093 ZEND_END_ARG_INFO();
2094 static PHP_METHOD(pqstm
, __construct
) {
2095 zend_error_handling zeh
;
2096 zval
*zconn
, *ztypes
= NULL
;
2097 char *name_str
, *query_str
;
2098 int name_len
, *query_len
;
2099 zend_bool async
= 0;
2101 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2102 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
)) {
2103 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2104 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2106 if (conn_obj
->conn
) {
2109 conn_obj
->poller
= PQconsumeInput
;
2110 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
2112 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
2113 php_pqconn_notify_listeners(zconn
, conn_obj TSRMLS_CC
);
2116 if (SUCCESS
== rv
) {
2117 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2120 Z_ADDREF_P(stm
->conn
);
2121 stm
->name
= estrdup(name_str
);
2125 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2128 zend_restore_error_handling(&zeh TSRMLS_CC
);
2131 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
2132 ZEND_ARG_ARRAY_INFO(0, params
, 1)
2133 ZEND_END_ARG_INFO();
2134 static PHP_METHOD(pqstm
, exec
) {
2135 zend_error_handling zeh
;
2136 zval
*zparams
= NULL
;
2138 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2139 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
)) {
2140 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2143 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->stm
->conn TSRMLS_CC
);
2145 if (conn_obj
->conn
) {
2147 char **params
= NULL
;
2152 ZEND_INIT_SYMTABLE(&zdtor
);
2153 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2156 res
= PQexecPrepared(conn_obj
->conn
, obj
->stm
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
2162 zend_hash_destroy(&zdtor
);
2165 php_pqconn_notify_listeners(obj
->stm
->conn
, conn_obj TSRMLS_CC
);
2168 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2169 return_value
->type
= IS_OBJECT
;
2170 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
2173 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement: %s", PQerrorMessage(conn_obj
->conn
));
2176 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2179 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
2182 zend_restore_error_handling(&zeh TSRMLS_CC
);
2185 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
2186 ZEND_ARG_ARRAY_INFO(0, params
, 1)
2187 ZEND_ARG_INFO(0, callable
)
2188 ZEND_END_ARG_INFO();
2189 static PHP_METHOD(pqstm
, execAsync
) {
2190 zend_error_handling zeh
;
2191 zval
*zparams
= NULL
;
2192 php_pq_callback_t resolver
;
2194 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2195 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
)) {
2196 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2199 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->stm
->conn TSRMLS_CC
);
2201 if (conn_obj
->conn
) {
2203 char **params
= NULL
;
2207 ZEND_INIT_SYMTABLE(&zdtor
);
2208 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2211 php_pq_callback_dtor(&conn_obj
->onevent
);
2212 if (resolver
.fci
.size
> 0) {
2213 conn_obj
->onevent
= resolver
;
2214 php_pq_callback_addref(&conn_obj
->onevent
);
2217 conn_obj
->poller
= PQconsumeInput
;
2219 if (PQsendQueryPrepared(conn_obj
->conn
, obj
->stm
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
2220 if (zend_is_true(zend_read_property(Z_OBJCE_P(obj
->stm
->conn
), obj
->stm
->conn
, ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
2221 if (!PQsetSingleRowMode(conn_obj
->conn
)) {
2222 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(conn_obj
->conn
));
2227 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement: %s", PQerrorMessage(conn_obj
->conn
));
2235 zend_hash_destroy(&zdtor
);
2238 php_pqconn_notify_listeners(obj
->stm
->conn
, conn_obj TSRMLS_CC
);
2241 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2245 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
2249 zend_restore_error_handling(&zeh TSRMLS_CC
);
2252 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
2253 ZEND_END_ARG_INFO();
2254 static PHP_METHOD(pqstm
, desc
) {
2255 zend_error_handling zeh
;
2257 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2258 if (SUCCESS
== zend_parse_parameters_none()) {
2259 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2262 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->stm
->conn TSRMLS_CC
);
2264 if (conn_obj
->conn
) {
2265 PGresult
*res
= PQdescribePrepared(conn_obj
->conn
, obj
->stm
->name
);
2267 php_pqconn_notify_listeners(obj
->stm
->conn
, conn_obj TSRMLS_CC
);
2270 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2273 array_init(return_value
);
2274 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
2275 add_next_index_long(return_value
, PQparamtype(res
, p
));
2279 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not describe statement: %s", PQerrorMessage(conn_obj
->conn
));
2282 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2285 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
2288 zend_restore_error_handling(&zeh TSRMLS_CC
);
2291 static zend_function_entry php_pqstm_methods
[] = {
2292 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2293 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
2294 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
2295 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
2299 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
2300 ZEND_ARG_INFO(0, connection
)
2301 ZEND_ARG_INFO(0, async
)
2302 ZEND_ARG_INFO(0, isolation
)
2303 ZEND_ARG_INFO(0, readonly
)
2304 ZEND_ARG_INFO(0, deferrable
)
2305 ZEND_END_ARG_INFO();
2306 static PHP_METHOD(pqtxn
, __construct
) {
2307 zend_error_handling zeh
;
2309 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2310 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
2312 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2313 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
)) {
2315 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2316 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2318 if (conn_obj
->conn
) {
2320 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2322 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2325 if (SUCCESS
== rv
) {
2327 zval_ptr_dtor(&obj
->txn
->conn
);
2331 obj
->txn
= ecalloc(1, sizeof(*obj
->txn
));
2332 obj
->txn
->conn
= zconn
;
2333 obj
->txn
->isolation
= isolation
;
2334 obj
->txn
->readonly
= readonly
;
2335 obj
->txn
->deferrable
= deferrable
;
2338 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
2341 zend_restore_error_handling(&zeh TSRMLS_CC
);
2344 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
2345 ZEND_END_ARG_INFO();
2346 static PHP_METHOD(pqtxn
, commit
) {
2347 zend_error_handling zeh
;
2349 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2350 if (SUCCESS
== zend_parse_parameters_none()) {
2351 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2354 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2356 if (conn_obj
->conn
) {
2357 PGresult
*res
= PQexec(conn_obj
->conn
, "COMMIT");
2360 php_pqres_success(res TSRMLS_CC
);
2363 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not commit transaction: %s", PQerrorMessage(conn_obj
->conn
));
2366 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2369 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2372 zend_restore_error_handling(&zeh TSRMLS_CC
);
2375 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
2376 ZEND_END_ARG_INFO();
2377 static PHP_METHOD(pqtxn
, commitAsync
) {
2378 zend_error_handling zeh
;
2380 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2381 if (SUCCESS
== zend_parse_parameters_none()) {
2382 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2385 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2387 if (conn_obj
->conn
) {
2388 conn_obj
->poller
= PQconsumeInput
;
2390 if (!PQsendQuery(conn_obj
->conn
, "COMMIT")) {
2391 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not commit transaction: %s", PQerrorMessage(conn_obj
->conn
));
2394 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2397 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2400 zend_restore_error_handling(&zeh TSRMLS_CC
);
2403 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
2404 ZEND_END_ARG_INFO();
2405 static PHP_METHOD(pqtxn
, rollback
) {
2406 zend_error_handling zeh
;
2408 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2409 if (SUCCESS
== zend_parse_parameters_none()) {
2410 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2413 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2415 if (conn_obj
->conn
) {
2416 PGresult
*res
= PQexec(conn_obj
->conn
, "ROLLBACK");
2419 php_pqres_success(res TSRMLS_CC
);
2422 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not rollback transaction: %s", PQerrorMessage(conn_obj
->conn
));
2425 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2428 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2431 zend_restore_error_handling(&zeh TSRMLS_CC
);
2434 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
2435 ZEND_END_ARG_INFO();
2436 static PHP_METHOD(pqtxn
, rollbackAsync
) {
2437 zend_error_handling zeh
;
2439 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
2440 if (SUCCESS
== zend_parse_parameters_none()) {
2441 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2444 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->txn
->conn TSRMLS_CC
);
2446 if (conn_obj
->conn
) {
2447 conn_obj
->poller
= PQconsumeInput
;
2448 if (!PQsendQuery(conn_obj
->conn
, "REOLLBACK")) {
2449 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not rollback transaction: %s", PQerrorMessage(conn_obj
->conn
));
2452 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not intialized");
2455 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Transaction not initialized");
2458 zend_restore_error_handling(&zeh TSRMLS_CC
);
2461 static zend_function_entry php_pqtxn_methods
[] = {
2462 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
2463 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
2464 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
2465 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
2466 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
2470 /* {{{ PHP_MINIT_FUNCTION
2472 static PHP_MINIT_FUNCTION(pq
)
2474 zend_class_entry ce
= {0};
2475 php_pq_object_prophandler_t ph
= {0};
2477 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
2478 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2479 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
2481 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2482 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
2483 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
2484 php_pqconn_object_handlers
.clone_obj
= NULL
;
2485 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
2486 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2488 zend_hash_init(&php_pqconn_object_prophandlers
, 8, NULL
, NULL
, 1);
2490 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2491 ph
.read
= php_pqconn_object_read_status
;
2492 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
2494 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2495 ph
.read
= php_pqconn_object_read_transaction_status
;
2496 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
2498 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2499 ph
.read
= NULL
; /* forward to std prophandler */
2500 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
2502 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2503 ph
.read
= php_pqconn_object_read_error_message
;
2504 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
2506 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("types"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2507 ph
.read
= php_pqconn_object_read_types
;
2508 zend_hash_add(&php_pqconn_object_prophandlers
, "types", sizeof("types"), (void *) &ph
, sizeof(ph
), NULL
);
2510 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2511 ph
.read
= php_pqconn_object_read_busy
;
2512 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
2514 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2515 ph
.read
= php_pqconn_object_read_encoding
;
2516 ph
.write
= php_pqconn_object_write_encoding
;
2517 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
2520 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2522 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
2523 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
2524 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
2525 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
2526 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
2527 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
2528 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
2529 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
2531 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
2532 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
2533 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
2534 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
2535 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
2537 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
2538 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
2539 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
2540 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
2542 memset(&ce
, 0, sizeof(ce
));
2543 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
2544 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2545 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
2546 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
2547 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
2548 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 1, zend_ce_traversable
);
2550 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2551 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
2552 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
2553 php_pqres_object_handlers
.clone_obj
= NULL
;
2554 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
2555 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2557 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
2559 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2560 ph
.read
= php_pqres_object_read_status
;
2561 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
2563 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2564 ph
.read
= php_pqres_object_read_error_message
;
2565 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
2567 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2568 ph
.read
= php_pqres_object_read_num_rows
;
2569 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
2571 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2572 ph
.read
= php_pqres_object_read_num_cols
;
2573 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
2575 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2576 ph
.read
= php_pqres_object_read_affected_rows
;
2577 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
2579 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2580 ph
.read
= php_pqres_object_read_fetch_type
;
2581 ph
.write
= php_pqres_object_write_fetch_type
;
2582 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
2585 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
2586 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
2587 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
2588 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
2589 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
2590 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
2591 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
2592 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
2593 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
2594 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
2596 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
2597 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
2598 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
2600 memset(&ce
, 0, sizeof(ce
));
2601 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
2602 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2603 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
2605 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2606 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
2607 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
2608 php_pqstm_object_handlers
.clone_obj
= NULL
;
2609 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
2610 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2612 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
2614 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2615 ph
.read
= php_pqstm_object_read_name
;
2616 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
2618 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2619 ph
.read
= php_pqstm_object_read_connection
;
2620 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
2622 memset(&ce
, 0, sizeof(ce
));
2623 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
2624 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2625 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
2627 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2628 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
2629 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
2630 php_pqtxn_object_handlers
.clone_obj
= NULL
;
2631 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
2632 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2634 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
2636 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2637 ph
.read
= php_pqtxn_object_read_connection
;
2638 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
2640 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2641 ph
.read
= php_pqtxn_object_read_isolation
;
2642 ph
.write
= php_pqtxn_object_write_isolation
;
2643 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
2645 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("readonly"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2646 ph
.read
= php_pqtxn_object_read_readonly
;
2647 ph
.write
= php_pqtxn_object_write_readonly
;
2648 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
2650 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2651 ph
.read
= php_pqtxn_object_read_deferrable
;
2652 ph
.write
= php_pqtxn_object_write_deferrable
;
2653 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
2656 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
2657 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
2658 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
2661 REGISTER_INI_ENTRIES();
2667 /* {{{ PHP_MSHUTDOWN_FUNCTION
2669 static PHP_MSHUTDOWN_FUNCTION(pq
)
2671 /* uncomment this line if you have INI entries
2672 UNREGISTER_INI_ENTRIES();
2678 /* {{{ PHP_MINFO_FUNCTION
2680 static PHP_MINFO_FUNCTION(pq
)
2682 php_info_print_table_start();
2683 php_info_print_table_header(2, "pq support", "enabled");
2684 php_info_print_table_end();
2686 /* Remove comments if you have entries in php.ini
2687 DISPLAY_INI_ENTRIES();
2692 const zend_function_entry pq_functions
[] = {
2696 /* {{{ pq_module_entry
2698 zend_module_entry pq_module_entry
= {
2699 STANDARD_MODULE_HEADER
,
2704 NULL
,/*PHP_RINIT(pq),*/
2705 NULL
,/*PHP_RSHUTDOWN(pq),*/
2708 STANDARD_MODULE_PROPERTIES
2712 #ifdef COMPILE_DL_PQ
2722 * vim600: noet sw=4 ts=4 fdm=marker
2723 * vim<600: noet sw=4 ts=4