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)
33 const zend_function_entry pq_functions
[] = {
37 /* {{{ pq_module_entry
39 zend_module_entry pq_module_entry
= {
40 STANDARD_MODULE_HEADER
,
45 NULL
,/*PHP_RINIT(pq),*/
46 NULL
,/*PHP_RSHUTDOWN(pq),*/
49 STANDARD_MODULE_PROPERTIES
59 /* Remove comments and fill if you need to have entries in php.ini
61 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
62 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
67 /* {{{ php_pq_init_globals
69 /* Uncomment this function if you have INI entries
70 static void php_pq_init_globals(zend_pq_globals *pq_globals)
72 pq_globals->global_value = 0;
73 pq_globals->global_string = NULL;
78 static zend_class_entry
*php_pqconn_class_entry
;
79 static zend_class_entry
*php_pqres_class_entry
;
80 static zend_class_entry
*php_pqstm_class_entry
;
82 static zend_object_handlers php_pqconn_object_handlers
;
83 static zend_object_handlers php_pqres_object_handlers
;
84 static zend_object_handlers php_pqstm_object_handlers
;
86 typedef struct php_pq_callback
{
88 zend_fcall_info_cache fcc
;
92 typedef struct php_pq_object
{
95 HashTable
*prophandler
;
98 typedef struct php_pqconn_object
{
101 HashTable
*prophandler
;
103 int (*poller
)(PGconn
*);
105 php_pq_callback_t onevent
;
106 } php_pqconn_object_t
;
108 typedef struct php_pqconn_event_data
{
109 php_pqconn_object_t
*obj
;
113 } php_pqconn_event_data_t
;
115 typedef enum php_pqres_fetch
{
116 PHP_PQRES_FETCH_ARRAY
,
117 PHP_PQRES_FETCH_ASSOC
,
118 PHP_PQRES_FETCH_OBJECT
121 typedef struct php_pqres_iterator
{
122 zend_object_iterator zi
;
125 php_pqres_fetch_t fetch_type
;
126 } php_pqres_iterator_t
;
128 typedef struct php_pqres_object
{
131 HashTable
*prophandler
;
133 php_pqres_iterator_t
*iter
;
134 } php_pqres_object_t
;
136 typedef struct php_pqstm_object
{
139 HashTable
*prophandler
;
142 } php_pqstm_object_t
;
144 static HashTable php_pqconn_object_prophandlers
;
145 static HashTable php_pqres_object_prophandlers
;
146 static HashTable php_pqstm_object_prophandlers
;
148 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
150 typedef struct php_pq_object_prophandler
{
151 php_pq_object_prophandler_func_t read
;
152 php_pq_object_prophandler_func_t write
;
153 } php_pq_object_prophandler_t
;
155 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
157 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
159 php_pqres_iterator_t
*iter
;
160 zval
*prop
, *zfetch_type
;
162 iter
= ecalloc(1, sizeof(*iter
));
163 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
164 iter
->zi
.data
= object
;
167 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
168 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
169 convert_to_long_ex(&zfetch_type
);
171 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
172 if (zfetch_type
!= prop
) {
173 zval_ptr_dtor(&zfetch_type
);
175 if (Z_REFCOUNT_P(prop
)) {
176 zval_ptr_dtor(&prop
);
182 return (zend_object_iterator
*) iter
;
185 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
187 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
189 if (iter
->current_val
) {
190 zval_ptr_dtor(&iter
->current_val
);
191 iter
->current_val
= NULL
;
193 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
197 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
199 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
200 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
202 if (PQresultStatus(obj
->res
) != PGRES_TUPLES_OK
) {
205 if (PQntuples(obj
->res
) <= iter
->index
) {
212 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type TSRMLS_DC
)
218 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
224 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
225 if (PQgetisnull(res
, row
, c
)) {
226 switch (fetch_type
) {
227 case PHP_PQRES_FETCH_OBJECT
:
228 add_property_null(data
, PQfname(res
, c
));
231 case PHP_PQRES_FETCH_ASSOC
:
232 add_assoc_null(data
, PQfname(res
, c
));
235 case PHP_PQRES_FETCH_ARRAY
:
236 add_index_null(data
, c
);
240 char *val
= PQgetvalue(res
, row
, c
);
241 int len
= PQgetlength(res
, row
, c
);
243 switch (fetch_type
) {
244 case PHP_PQRES_FETCH_OBJECT
:
245 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
248 case PHP_PQRES_FETCH_ASSOC
:
249 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
252 case PHP_PQRES_FETCH_ARRAY
:
253 add_index_stringl(data
, c
, val
, len
,1);
262 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
264 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
265 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
267 if (iter
->current_val
) {
268 zval_ptr_dtor(&iter
->current_val
);
270 iter
->current_val
= php_pqres_row_to_zval(obj
->res
, iter
->index
, iter
->fetch_type TSRMLS_CC
);
271 *data_ptr
= &iter
->current_val
;
274 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
276 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
278 *key_num
= (ulong
) iter
->index
;
280 return HASH_KEY_IS_LONG
;
283 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
285 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
290 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
292 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
297 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
298 php_pqres_iterator_dtor
,
299 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
300 php_pqres_iterator_valid
,
301 /* fetch the item data for the current element */
302 php_pqres_iterator_current
,
303 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
304 php_pqres_iterator_key
,
305 /* step forwards to next element */
306 php_pqres_iterator_next
,
307 /* rewind to start of data (optional, may be NULL) */
308 php_pqres_iterator_rewind
,
309 /* invalidate current value/key (optional, may be NULL) */
313 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
314 if (cb
->fci
.size
> 0) {
315 zend_fcall_info_args_clear(&cb
->fci
, 1);
316 zval_ptr_dtor(&cb
->fci
.function_name
);
317 if (cb
->fci
.object_ptr
) {
318 zval_ptr_dtor(&cb
->fci
.object_ptr
);
324 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
326 Z_ADDREF_P(cb
->fci
.function_name
);
327 if (cb
->fci
.object_ptr
) {
328 Z_ADDREF_P(cb
->fci
.object_ptr
);
332 static void php_pqconn_object_free(void *o TSRMLS_DC
)
334 php_pqconn_object_t
*obj
= o
;
340 if (obj
->onevent
.fci
.size
> 0) {
341 php_pq_callback_dtor(&obj
->onevent
);
343 zend_hash_destroy(&obj
->listeners
);
344 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
348 static int php_pqconn_event(PGEventId id
, void *e
, void *data
);
350 static void php_pqres_object_free(void *o TSRMLS_DC
)
352 php_pqres_object_t
*obj
= o
;
355 zval
*res
= PQresultInstanceData(obj
->res
, php_pqconn_event
);
357 PQresultSetInstanceData(obj
->res
, php_pqconn_event
, NULL
);
365 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
368 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
372 static void php_pqstm_object_free(void *o TSRMLS_DC
)
374 php_pqstm_object_t
*obj
= o
;
381 zval_ptr_dtor(&obj
->conn
);
384 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
388 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, PGconn
*conn
, php_pqconn_object_t
**ptr TSRMLS_DC
)
390 zend_object_value ov
;
391 php_pqconn_object_t
*o
;
393 o
= ecalloc(1, sizeof(*o
));
394 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
395 object_properties_init((zend_object
*) o
, ce
);
396 o
->prophandler
= &php_pqconn_object_prophandlers
;
406 zend_hash_init(&o
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
408 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
409 ov
.handlers
= &php_pqconn_object_handlers
;
414 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, PGresult
*res
, php_pqres_object_t
**ptr TSRMLS_DC
)
416 zend_object_value ov
;
417 php_pqres_object_t
*o
;
419 o
= ecalloc(1, sizeof(*o
));
420 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
421 object_properties_init((zend_object
*) o
, ce
);
422 o
->prophandler
= &php_pqres_object_prophandlers
;
432 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
433 ov
.handlers
= &php_pqres_object_handlers
;
438 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, zval
*conn
, const char *name
, php_pqstm_object_t
**ptr TSRMLS_DC
)
440 zend_object_value ov
;
441 php_pqstm_object_t
*o
;
443 o
= ecalloc(1, sizeof(*o
));
444 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
445 object_properties_init((zend_object
*) o
, ce
);
446 o
->prophandler
= &php_pqstm_object_prophandlers
;
458 o
->name
= estrdup(name
);
461 ov
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
462 ov
.handlers
= &php_pqstm_object_handlers
;
467 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
469 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
472 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
474 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
477 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
479 return php_pqstm_create_object_ex(class_type
, NULL
, NULL
, NULL TSRMLS_CC
);
482 static int apply_ph_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
484 php_pq_object_prophandler_t
*ph
= p
;
485 HashTable
*ht
= va_arg(argv
, HashTable
*);
486 zval
**return_value
, *object
= va_arg(argv
, zval
*);
487 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
489 if (SUCCESS
== zend_hash_find(ht
, key
->arKey
, key
->nKeyLength
, (void *) &return_value
)) {
491 MAKE_STD_ZVAL(*return_value
);
492 ZVAL_NULL(*return_value
);
494 ph
->read(object
, obj
, *return_value TSRMLS_CC
);
499 ZVAL_STRINGL(&member
, key
->arKey
, key
->nKeyLength
-1, 0);
500 *return_value
= zend_get_std_object_handlers()->read_property(object
, &member
, BP_VAR_R
, NULL TSRMLS_CC
);
501 Z_ADDREF_PP(return_value
);
505 return ZEND_HASH_APPLY_KEEP
;
508 static int apply_pi_to_debug(void *p
, void *arg TSRMLS_DC
)
510 zend_property_info
*pi
= p
;
513 zend_hash_add_empty_element(ht
, pi
->name
, pi
->name_length
+ 1);
515 return ZEND_HASH_APPLY_KEEP
;
518 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
521 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
525 ZEND_INIT_SYMTABLE(ht
);
527 zend_hash_apply_with_argument(&obj
->zo
.ce
->properties_info
, apply_pi_to_debug
, ht TSRMLS_CC
);
528 zend_hash_apply_with_arguments(obj
->prophandler TSRMLS_CC
, apply_ph_to_debug
, 3, ht
, object
, obj
);
532 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
534 php_pqconn_object_t
*obj
= o
;
536 RETVAL_LONG(PQstatus(obj
->conn
));
539 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
541 php_pqconn_object_t
*obj
= o
;
543 RETVAL_LONG(PQtransactionStatus(obj
->conn
));
546 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
548 php_pqconn_object_t
*obj
= o
;
549 char *error
= PQerrorMessage(obj
->conn
);
552 RETVAL_STRING(error
, 1);
558 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
560 php_pq_callback_t
*listener
= p
;
562 zval
*zpid
, *zchannel
, *zmessage
;
565 ZVAL_LONG(zpid
, nfy
->be_pid
);
566 MAKE_STD_ZVAL(zchannel
);
567 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
568 MAKE_STD_ZVAL(zmessage
);
569 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
571 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
572 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
574 zval_ptr_dtor(&zchannel
);
575 zval_ptr_dtor(&zmessage
);
576 zval_ptr_dtor(&zpid
);
578 return ZEND_HASH_APPLY_KEEP
;
581 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
583 HashTable
*listeners
= p
;
584 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
586 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
587 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
590 return ZEND_HASH_APPLY_KEEP
;
593 static void php_pqconn_notify_listeners(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
598 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
601 while ((nfy
= PQnotifies(obj
->conn
))) {
602 zend_hash_apply_with_arguments(&obj
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
607 /* FIXME: extend to types->nspname->typname */
608 #define PHP_PQ_TYPES_QUERY \
609 "select t.oid, t.* " \
610 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
611 "where typisdefined " \
613 "and nspname in ('public', 'pg_catalog')"
614 static void php_pqconn_object_read_types(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
616 php_pqconn_object_t
*obj
= o
;
617 PGresult
*res
= PQexec(obj
->conn
, PHP_PQ_TYPES_QUERY
);
619 php_pqconn_notify_listeners(object
, obj TSRMLS_CC
);
621 /* FIXME: cache that */
623 if (PGRES_TUPLES_OK
== PQresultStatus(res
)) {
625 zval
*byoid
, *byname
;
627 MAKE_STD_ZVAL(byoid
);
628 MAKE_STD_ZVAL(byname
);
631 object_init(return_value
);
632 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
633 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
635 add_property_zval(byoid
, PQgetvalue(res
, r
, 0), row
);
636 add_property_zval(byname
, PQgetvalue(res
, r
, 1), row
);
640 add_property_zval(return_value
, "byOid", byoid
);
641 add_property_zval(return_value
, "byName", byname
);
642 zval_ptr_dtor(&byoid
);
643 zval_ptr_dtor(&byname
);
645 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types: %s", PQresultErrorMessage(res
));
649 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not fetch types: %s", PQerrorMessage(obj
->conn
));
653 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
655 php_pqconn_object_t
*obj
= o
;
657 RETVAL_BOOL(PQisBusy(obj
->conn
));
660 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
662 php_pqconn_object_t
*obj
= o
;
664 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->conn
)), 1);
667 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
669 php_pqconn_object_t
*obj
= o
;
672 if (Z_TYPE_P(value
) != IS_STRING
) {
673 convert_to_string_ex(&zenc
);
676 if (0 > PQsetClientEncoding(obj
->conn
, Z_STRVAL_P(zenc
))) {
677 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
681 zval_ptr_dtor(&zenc
);
685 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
687 php_pqres_object_t
*obj
= o
;
689 RETVAL_LONG(PQresultStatus(obj
->res
));
692 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
694 php_pqres_object_t
*obj
= o
;
695 char *error
= PQresultErrorMessage(obj
->res
);
698 RETVAL_STRING(error
, 1);
704 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
706 php_pqres_object_t
*obj
= o
;
708 RETVAL_LONG(PQntuples(obj
->res
));
711 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
713 php_pqres_object_t
*obj
= o
;
715 RETVAL_LONG(PQnfields(obj
->res
));
718 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
720 php_pqres_object_t
*obj
= o
;
722 RETVAL_LONG(atoi(PQcmdTuples(obj
->res
)));
725 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
727 php_pqres_object_t
*obj
= o
;
730 RETVAL_LONG(obj
->iter
->fetch_type
);
732 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
736 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
738 php_pqres_object_t
*obj
= o
;
739 zval
*zfetch_type
= value
;
741 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
742 convert_to_long_ex(&zfetch_type
);
746 obj
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
747 obj
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
749 obj
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
751 if (zfetch_type
!= value
) {
752 zval_ptr_dtor(&zfetch_type
);
756 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
758 php_pqstm_object_t
*obj
= o
;
760 RETVAL_STRING(obj
->name
, 1);
763 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
765 php_pqstm_object_t
*obj
= o
;
767 RETVAL_ZVAL(obj
->conn
, 1, 0);
770 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
777 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
779 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
780 php_pq_object_prophandler_t
*handler
;
784 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
785 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
786 if (type
== BP_VAR_R
) {
787 ALLOC_ZVAL(return_value
);
788 Z_SET_REFCOUNT_P(return_value
, 0);
789 Z_UNSET_ISREF_P(return_value
);
791 handler
->read(object
, obj
, return_value TSRMLS_CC
);
793 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
797 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
803 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
805 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
806 php_pq_object_prophandler_t
*handler
;
808 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
809 if (handler
->write
) {
810 handler
->write(object
, obj
, value TSRMLS_CC
);
813 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
817 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
819 zval
*zsocket
, zmember
;
825 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
828 INIT_PZVAL(&zmember
);
829 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
830 MAKE_STD_ZVAL(zsocket
);
832 if ((CONNECTION_BAD
!= PQstatus(obj
->conn
))
833 && (-1 < (socket
= PQsocket(obj
->conn
)))
834 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
835 php_stream_to_zval(stream
, zsocket
);
841 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
842 zval_ptr_dtor(&zsocket
);
848 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
849 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
851 # define TSRMLS_DF(d)
852 # define TSRMLS_CF(d)
855 static void php_pqconn_event_register(PGEventRegister
*event
, php_pqconn_event_data_t
*data
)
857 PQsetInstanceData(event
->conn
, php_pqconn_event
, data
);
859 static void php_pqconn_event_conndestroy(PGEventConnDestroy
*event
, php_pqconn_event_data_t
*data
)
861 PQsetInstanceData(event
->conn
, php_pqconn_event
, NULL
);
864 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
, php_pqconn_event_data_t
*data
)
868 if (data
->obj
->onevent
.fci
.size
> 0) {
872 res
->type
= IS_OBJECT
;
873 res
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, event
->result
, NULL TSRMLS_CC
);
876 PQresultSetInstanceData(event
->result
, php_pqconn_event
, res
);
878 zend_fcall_info_argn(&data
->obj
->onevent
.fci TSRMLS_CC
, 1, &res
);
879 zend_fcall_info_call(&data
->obj
->onevent
.fci
, &data
->obj
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
884 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
888 php_pqconn_event_register(e
, data
);
890 case PGEVT_CONNDESTROY
:
891 php_pqconn_event_conndestroy(e
, data
);
893 case PGEVT_RESULTCREATE
:
894 php_pqconn_event_resultcreate(e
, data
);
903 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
905 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
913 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
914 ZEND_ARG_INFO(0, dsn
)
915 ZEND_ARG_INFO(0, async
)
917 static PHP_METHOD(pqconn
, __construct
) {
918 zend_error_handling zeh
;
923 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
924 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|b", &dsn_str
, &dsn_len
, &async
)) {
925 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
926 php_pqconn_event_data_t
*data
= php_pqconn_event_data_init(obj TSRMLS_CC
);
932 obj
->conn
= PQconnectStart(dsn_str
);
933 obj
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
935 obj
->conn
= PQconnectdb(dsn_str
);
938 PQregisterEventProc(obj
->conn
, php_pqconn_event
, "ext-pq", data
);
939 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
940 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection failed: %s", PQerrorMessage(obj
->conn
));
943 zend_restore_error_handling(&zeh TSRMLS_CC
);
946 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
948 static PHP_METHOD(pqconn
, reset
) {
949 if (SUCCESS
== zend_parse_parameters_none()) {
950 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
955 if (CONNECTION_OK
== PQstatus(obj
->conn
)) {
958 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Connection reset failed: %s", PQerrorMessage(obj
->conn
));
961 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
967 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
969 static PHP_METHOD(pqconn
, resetAsync
) {
970 if (SUCCESS
== zend_parse_parameters_none()) {
971 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
974 if (PQresetStart(obj
->conn
)) {
975 obj
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
979 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
985 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
)
987 HashTable ht
, *existing_listeners
;
989 php_pq_callback_addref(listener
);
991 if (SUCCESS
== zend_hash_find(&obj
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
992 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
994 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
995 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
996 zend_hash_add(&obj
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
1000 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
1002 switch (PQresultStatus(res
)) {
1003 case PGRES_BAD_RESPONSE
:
1004 case PGRES_NONFATAL_ERROR
:
1005 case PGRES_FATAL_ERROR
:
1006 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "%s", PQresultErrorMessage(res
));
1013 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
1014 ZEND_ARG_INFO(0, channel
)
1015 ZEND_ARG_INFO(0, callable
)
1016 ZEND_END_ARG_INFO();
1017 static PHP_METHOD(pqconn
, listen
) {
1018 char *channel_str
= NULL
;
1019 int channel_len
= 0;
1020 php_pq_callback_t listener
;
1022 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
)) {
1023 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1025 obj
->poller
= PQconsumeInput
;
1028 char *quoted_channel
= PQescapeIdentifier(obj
->conn
, channel_str
, channel_len
);
1030 if (quoted_channel
) {
1034 spprintf(&cmd
, 0, "LISTEN %s", channel_str
);
1035 res
= PQexec(obj
->conn
, cmd
);
1038 PQfreemem(quoted_channel
);
1042 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1043 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
1050 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not install listener: %s", PQerrorMessage(obj
->conn
));
1054 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1056 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape channel identifier: %s", PQerrorMessage(obj
->conn
));
1059 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1065 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
1066 ZEND_ARG_INFO(0, channel
)
1067 ZEND_ARG_INFO(0, message
)
1068 ZEND_END_ARG_INFO();
1069 static PHP_METHOD(pqconn
, notify
) {
1070 char *channel_str
, *message_str
;
1071 int channel_len
, message_len
;
1073 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
)) {
1074 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1078 char *params
[2] = {channel_str
, message_str
};
1080 res
= PQexecParams(obj
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
1083 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1090 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not notify listeners: %s", PQerrorMessage(obj
->conn
));
1094 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1097 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1103 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
1104 ZEND_END_ARG_INFO();
1105 static PHP_METHOD(pqconn
, poll
) {
1106 if (SUCCESS
== zend_parse_parameters_none()) {
1107 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1111 if (obj
->poller
== PQconsumeInput
) {
1112 RETVAL_LONG(obj
->poller(obj
->conn
) * PGRES_POLLING_OK
);
1113 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1116 RETURN_LONG(obj
->poller(obj
->conn
));
1119 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "No asynchronous operation active");
1122 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1128 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
1129 ZEND_ARG_INFO(0, query
)
1130 ZEND_END_ARG_INFO();
1131 static PHP_METHOD(pqconn
, exec
) {
1132 zend_error_handling zeh
;
1136 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1137 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
)) {
1138 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1141 PGresult
*res
= PQexec(obj
->conn
, query_str
);
1143 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1146 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1147 return_value
->type
= IS_OBJECT
;
1148 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1151 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1154 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1157 zend_restore_error_handling(&zeh TSRMLS_CC
);
1160 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
1161 ZEND_END_ARG_INFO();
1162 static PHP_METHOD(pqconn
, getResult
) {
1163 if (SUCCESS
== zend_parse_parameters_none()) {
1164 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1167 PGresult
*res
= PQgetResult(obj
->conn
);
1170 return_value
->type
= IS_OBJECT
;
1171 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1176 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1182 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
1183 ZEND_ARG_INFO(0, query
)
1184 ZEND_ARG_INFO(0, callable
)
1185 ZEND_END_ARG_INFO();
1186 static PHP_METHOD(pqconn
, execAsync
) {
1187 zend_error_handling zeh
;
1188 php_pq_callback_t resolver
;
1192 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1193 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
)) {
1194 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1197 php_pq_callback_dtor(&obj
->onevent
);
1198 if (resolver
.fci
.size
> 0) {
1199 obj
->onevent
= resolver
;
1200 php_pq_callback_addref(&obj
->onevent
);
1203 obj
->poller
= PQconsumeInput
;
1205 if (PQsendQuery(obj
->conn
, query_str
)) {
1206 if (zend_is_true(zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1207 if (!PQsetSingleRowMode(obj
->conn
)) {
1208 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1213 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1217 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1221 zend_restore_error_handling(&zeh TSRMLS_CC
);
1224 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
1229 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
1230 convert_to_long_ex(ztype
);
1233 **types
= Z_LVAL_PP(ztype
);
1236 if (*ztype
!= *(zval
**)p
) {
1237 zval_ptr_dtor(ztype
);
1239 return ZEND_HASH_APPLY_KEEP
;
1242 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1248 params
= (char ***) va_arg(argv
, char ***);
1249 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
1251 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
1255 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
1256 convert_to_string_ex(zparam
);
1259 **params
= Z_STRVAL_PP(zparam
);
1262 if (*zparam
!= *(zval
**)p
) {
1263 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
1266 return ZEND_HASH_APPLY_KEEP
;
1269 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
1271 int count
= zend_hash_num_elements(ht
);
1278 /* +1 for when less types than params are specified */
1279 *types
= tmp
= ecalloc(count
+ 1, sizeof(Oid
));
1280 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
1286 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
1288 int count
= zend_hash_num_elements(ht
);
1295 *params
= tmp
= ecalloc(count
, sizeof(char *));
1296 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
1302 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
1303 ZEND_ARG_INFO(0, query
)
1304 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1305 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1306 ZEND_END_ARG_INFO();
1307 static PHP_METHOD(pqconn
, execParams
) {
1308 zend_error_handling zeh
;
1312 zval
*ztypes
= NULL
;
1314 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1315 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
)) {
1316 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1322 char **params
= NULL
;
1325 ZEND_INIT_SYMTABLE(&zdtor
);
1326 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1329 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
1332 res
= PQexecParams(obj
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
1334 zend_hash_destroy(&zdtor
);
1342 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1345 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1346 return_value
->type
= IS_OBJECT
;
1347 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1350 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1354 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1358 zend_restore_error_handling(&zeh TSRMLS_CC
);
1361 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
1362 ZEND_ARG_INFO(0, query
)
1363 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1364 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1365 ZEND_ARG_INFO(0, callable
)
1366 ZEND_END_ARG_INFO();
1367 static PHP_METHOD(pqconn
, execParamsAsync
) {
1368 zend_error_handling zeh
;
1369 php_pq_callback_t resolver
;
1373 zval
*ztypes
= NULL
;
1375 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1376 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
)) {
1377 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1382 char **params
= NULL
;
1385 ZEND_INIT_SYMTABLE(&zdtor
);
1386 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1389 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
1392 php_pq_callback_dtor(&obj
->onevent
);
1393 if (resolver
.fci
.size
> 0) {
1394 obj
->onevent
= resolver
;
1395 php_pq_callback_addref(&obj
->onevent
);
1398 obj
->poller
= PQconsumeInput
;
1400 if (PQsendQueryParams(obj
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
1401 if (zend_is_true(zend_read_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1402 if (!PQsetSingleRowMode(obj
->conn
)) {
1403 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1408 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute query: %s", PQerrorMessage(obj
->conn
));
1412 zend_hash_destroy(&zdtor
);
1420 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1423 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1427 zend_restore_error_handling(&zeh TSRMLS_CC
);
1430 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
1438 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1442 count
= zend_hash_num_elements(typest
);
1443 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
1446 res
= PQprepare(obj
->conn
, name
, query
, count
, types
);
1453 rv
= php_pqres_success(res TSRMLS_CC
);
1457 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement: %s", PQerrorMessage(obj
->conn
));
1463 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
1464 ZEND_ARG_INFO(0, name
)
1465 ZEND_ARG_INFO(0, query
)
1466 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1467 ZEND_END_ARG_INFO();
1468 static PHP_METHOD(pqconn
, prepare
) {
1469 zend_error_handling zeh
;
1470 zval
*ztypes
= NULL
;
1471 char *name_str
, *query_str
;
1472 int name_len
, *query_len
;
1474 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1475 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
1476 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1479 if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1480 return_value
->type
= IS_OBJECT
;
1481 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, getThis(), name_str
, NULL TSRMLS_CC
);
1483 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1485 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1488 zend_restore_error_handling(&zeh TSRMLS_CC
);
1491 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
1498 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1502 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
1505 if (PQsendPrepare(obj
->conn
, name
, query
, count
, types
)) {
1506 if (zend_is_true(zend_read_property(Z_OBJCE_P(object
), object
, ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1507 if (!PQsetSingleRowMode(obj
->conn
)) {
1508 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(obj
->conn
));
1513 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not prepare statement: %s", PQerrorMessage(obj
->conn
));
1524 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
1525 ZEND_ARG_INFO(0, name
)
1526 ZEND_ARG_INFO(0, query
)
1527 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1528 ZEND_END_ARG_INFO();
1529 static PHP_METHOD(pqconn
, prepareAsync
) {
1530 zend_error_handling zeh
;
1531 zval
*ztypes
= NULL
;
1532 char *name_str
, *query_str
;
1533 int name_len
, *query_len
;
1535 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1536 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
)) {
1537 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1540 obj
->poller
= PQconsumeInput
;
1541 if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1542 return_value
->type
= IS_OBJECT
;
1543 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, getThis(), name_str
, NULL TSRMLS_CC
);
1545 php_pqconn_notify_listeners(getThis(), obj TSRMLS_CC
);
1547 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1550 zend_restore_error_handling(&zeh TSRMLS_CC
);
1553 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
1554 ZEND_ARG_INFO(0, string
)
1555 ZEND_END_ARG_INFO();
1556 static PHP_METHOD(pqconn
, quote
) {
1560 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1561 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1564 char *quoted
= PQescapeLiteral(obj
->conn
, str
, len
);
1567 RETVAL_STRING(quoted
, 1);
1570 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote string: %s", PQerrorMessage(obj
->conn
));
1574 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1580 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
1581 ZEND_ARG_INFO(0, name
)
1582 ZEND_END_ARG_INFO();
1583 static PHP_METHOD(pqconn
, quoteName
) {
1587 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1588 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1591 char *quoted
= PQescapeIdentifier(obj
->conn
, str
, len
);
1594 RETVAL_STRING(quoted
, 1);
1597 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not quote name: %s", PQerrorMessage(obj
->conn
));
1601 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1607 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
1608 ZEND_ARG_INFO(0, bytea
)
1609 ZEND_END_ARG_INFO();
1610 static PHP_METHOD(pqconn
, escapeBytea
) {
1614 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1615 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1619 char *escaped_str
= (char *) PQescapeByteaConn(obj
->conn
, (unsigned char *) str
, len
, &escaped_len
);
1622 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
1623 PQfreemem(escaped_str
);
1625 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape bytea: %s", PQerrorMessage(obj
->conn
));
1629 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1635 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
1636 ZEND_ARG_INFO(0, bytea
)
1637 ZEND_END_ARG_INFO();
1638 static PHP_METHOD(pqconn
, unescapeBytea
) {
1642 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1643 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1646 size_t unescaped_len
;
1647 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
1649 if (unescaped_str
) {
1650 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
1651 PQfreemem(unescaped_str
);
1653 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not escape bytea: %s", PQerrorMessage(obj
->conn
));
1657 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1663 static zend_function_entry php_pqconn_methods
[] = {
1664 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
1665 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
1666 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
1667 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
1668 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
1669 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
1670 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
1671 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
1672 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
1673 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
1674 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
1675 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
1676 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
1677 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
1678 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
1679 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
1680 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
1684 static zval
**php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type TSRMLS_DC
)
1687 php_pqres_fetch_t orig_fetch
;
1690 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1694 obj
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
1695 obj
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
1697 orig_fetch
= obj
->iter
->fetch_type
;
1698 obj
->iter
->fetch_type
= fetch_type
;
1699 if (SUCCESS
== obj
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->iter TSRMLS_CC
)) {
1700 obj
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->iter
, &row TSRMLS_CC
);
1701 obj
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->iter TSRMLS_CC
);
1703 obj
->iter
->fetch_type
= orig_fetch
;
1705 return row
? row
: NULL
;
1708 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
1709 ZEND_ARG_INFO(0, fetch_type
)
1710 ZEND_END_ARG_INFO();
1711 static PHP_METHOD(pqres
, fetchRow
) {
1712 zend_error_handling zeh
;
1713 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1714 long fetch_type
= obj
->iter
? obj
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
1716 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1717 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
)) {
1718 zval
**row
= php_pqres_iteration(getThis(), obj
, fetch_type TSRMLS_CC
);
1721 RETVAL_ZVAL(*row
, 1, 0);
1726 zend_restore_error_handling(&zeh TSRMLS_CC
);
1729 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
1732 HashTable
*ht
= HASH_OF(row
);
1733 int count
= zend_hash_num_elements(ht
);
1736 zend_hash_internal_pointer_reset(ht
);
1738 zend_hash_move_forward(ht
);
1740 zend_hash_get_current_data(ht
, (void *) &data
);
1742 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
1747 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
1748 ZEND_ARG_INFO(0, col_num
)
1749 ZEND_END_ARG_INFO();
1750 static PHP_METHOD(pqres
, fetchCol
) {
1751 zend_error_handling zeh
;
1754 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1755 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
)) {
1756 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1757 zval
**row
= php_pqres_iteration(getThis(), obj
, obj
->iter
? obj
->iter
->fetch_type
: 0 TSRMLS_CC
);
1760 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
1763 RETVAL_ZVAL(*col
, 1, 0);
1771 zend_restore_error_handling(&zeh TSRMLS_CC
);
1775 static zend_function_entry php_pqres_methods
[] = {
1776 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
1777 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
1781 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
1782 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
1783 ZEND_ARG_INFO(0, name
)
1784 ZEND_ARG_INFO(0, query
)
1785 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1786 ZEND_ARG_INFO(0, async
)
1787 ZEND_END_ARG_INFO();
1788 static PHP_METHOD(pqstm
, __construct
) {
1789 zend_error_handling zeh
;
1790 zval
*zconn
, *ztypes
= NULL
;
1791 char *name_str
, *query_str
;
1792 int name_len
, *query_len
;
1793 zend_bool async
= 0;
1795 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1796 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
)) {
1797 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1798 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
1800 if (conn_obj
->conn
) {
1802 conn_obj
->poller
= PQconsumeInput
;
1803 if (SUCCESS
== php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1806 obj
->name
= estrdup(name_str
);
1809 if (SUCCESS
== php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
1812 obj
->name
= estrdup(name_str
);
1814 php_pqconn_notify_listeners(obj
->conn
, conn_obj TSRMLS_CC
);
1817 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1820 zend_restore_error_handling(&zeh TSRMLS_CC
);
1823 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
1824 ZEND_ARG_ARRAY_INFO(0, params
, 1)
1825 ZEND_END_ARG_INFO();
1826 static PHP_METHOD(pqstm
, exec
) {
1827 zend_error_handling zeh
;
1828 zval
*zparams
= NULL
;
1830 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1831 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
)) {
1832 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1834 if (obj
->conn
&& obj
->name
) {
1835 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->conn TSRMLS_CC
);
1837 if (conn_obj
->conn
) {
1839 char **params
= NULL
;
1844 ZEND_INIT_SYMTABLE(&zdtor
);
1845 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1848 res
= PQexecPrepared(conn_obj
->conn
, obj
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
1854 zend_hash_destroy(&zdtor
);
1857 php_pqconn_notify_listeners(obj
->conn
, conn_obj TSRMLS_CC
);
1860 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1861 return_value
->type
= IS_OBJECT
;
1862 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, res
, NULL TSRMLS_CC
);
1865 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement: %s", PQerrorMessage(conn_obj
->conn
));
1868 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1871 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
1874 zend_restore_error_handling(&zeh TSRMLS_CC
);
1877 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
1878 ZEND_ARG_ARRAY_INFO(0, params
, 1)
1879 ZEND_ARG_INFO(0, callable
)
1880 ZEND_END_ARG_INFO();
1881 static PHP_METHOD(pqstm
, execAsync
) {
1882 zend_error_handling zeh
;
1883 zval
*zparams
= NULL
;
1884 php_pq_callback_t resolver
;
1886 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1887 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
)) {
1888 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1890 if (obj
->conn
&& obj
->name
) {
1891 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->conn TSRMLS_CC
);
1893 if (conn_obj
->conn
) {
1895 char **params
= NULL
;
1899 ZEND_INIT_SYMTABLE(&zdtor
);
1900 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
1903 php_pq_callback_dtor(&conn_obj
->onevent
);
1904 if (resolver
.fci
.size
> 0) {
1905 conn_obj
->onevent
= resolver
;
1906 php_pq_callback_addref(&conn_obj
->onevent
);
1909 conn_obj
->poller
= PQconsumeInput
;
1911 if (PQsendQueryPrepared(conn_obj
->conn
, obj
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
1912 if (zend_is_true(zend_read_property(Z_OBJCE_P(obj
->conn
), obj
->conn
, ZEND_STRL("unbuffered"), 0 TSRMLS_CC
))) {
1913 if (!PQsetSingleRowMode(conn_obj
->conn
)) {
1914 php_error_docref(NULL TSRMLS_CC
, E_NOTICE
, "Could not enable unbuffered mode: %s", PQerrorMessage(conn_obj
->conn
));
1919 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not execute statement: %s", PQerrorMessage(conn_obj
->conn
));
1927 zend_hash_destroy(&zdtor
);
1930 php_pqconn_notify_listeners(obj
->conn
, conn_obj TSRMLS_CC
);
1933 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1937 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
1941 zend_restore_error_handling(&zeh TSRMLS_CC
);
1944 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
1945 ZEND_END_ARG_INFO();
1946 static PHP_METHOD(pqstm
, desc
) {
1947 zend_error_handling zeh
;
1949 zend_replace_error_handling(EH_THROW
, NULL
, &zeh TSRMLS_CC
);
1950 if (SUCCESS
== zend_parse_parameters_none()) {
1951 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1953 if (obj
->conn
&& obj
->name
) {
1954 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(obj
->conn TSRMLS_CC
);
1956 if (conn_obj
->conn
) {
1957 PGresult
*res
= PQdescribePrepared(conn_obj
->conn
, obj
->name
);
1959 php_pqconn_notify_listeners(obj
->conn
, conn_obj TSRMLS_CC
);
1962 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1965 array_init(return_value
);
1966 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
1967 add_next_index_long(return_value
, PQparamtype(res
, p
));
1971 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Could not describe statement: %s", PQerrorMessage(conn_obj
->conn
));
1974 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Connection not initialized");
1977 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "pq\\Statement not initialized");
1980 zend_restore_error_handling(&zeh TSRMLS_CC
);
1983 static zend_function_entry php_pqstm_methods
[] = {
1984 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
1985 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
1986 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
1987 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
1991 /* {{{ PHP_MINIT_FUNCTION
1993 PHP_MINIT_FUNCTION(pq
)
1995 zend_class_entry ce
= {0};
1996 php_pq_object_prophandler_t ph
= {0};
1998 zend_hash_init(&php_pqconn_object_prophandlers
, 1, NULL
, NULL
, 1);
1999 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
2000 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2001 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
2002 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2003 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
2004 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
2005 php_pqconn_object_handlers
.clone_obj
= NULL
;
2006 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
2007 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2009 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2010 ph
.read
= php_pqconn_object_read_status
;
2011 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
2013 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2014 ph
.read
= php_pqconn_object_read_transaction_status
;
2015 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
2017 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2018 ph
.read
= NULL
; /* forward to std prophandler */
2019 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
2021 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2022 ph
.read
= php_pqconn_object_read_error_message
;
2023 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
2025 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("types"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2026 ph
.read
= php_pqconn_object_read_types
;
2027 zend_hash_add(&php_pqconn_object_prophandlers
, "types", sizeof("types"), (void *) &ph
, sizeof(ph
), NULL
);
2029 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2030 ph
.read
= php_pqconn_object_read_busy
;
2031 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
2033 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2034 ph
.read
= php_pqconn_object_read_encoding
;
2035 ph
.write
= php_pqconn_object_write_encoding
;
2036 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
2039 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2041 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
2042 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
2043 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
2044 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
2045 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
2046 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
2047 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
2048 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
2050 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
2051 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
2052 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
2053 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
2054 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
2056 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
2057 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
2058 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
2059 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
2061 zend_hash_init(&php_pqres_object_prophandlers
, 1, NULL
, NULL
, 1);
2062 memset(&ce
, 0, sizeof(ce
));
2063 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
2064 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2065 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
2066 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
2067 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
2069 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2070 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
2071 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
2072 php_pqres_object_handlers
.clone_obj
= NULL
;
2073 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
2074 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2076 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2077 ph
.read
= php_pqres_object_read_status
;
2078 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
2080 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2081 ph
.read
= php_pqres_object_read_error_message
;
2082 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
2084 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2085 ph
.read
= php_pqres_object_read_num_rows
;
2086 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
2088 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2089 ph
.read
= php_pqres_object_read_num_cols
;
2090 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
2092 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2093 ph
.read
= php_pqres_object_read_affected_rows
;
2094 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
2096 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2097 ph
.read
= php_pqres_object_read_fetch_type
;
2098 ph
.write
= php_pqres_object_write_fetch_type
;
2099 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
2102 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
2103 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
2104 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
2105 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
2106 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
2107 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
2108 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
2109 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
2110 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
2111 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
2113 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
2114 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
2115 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
2117 zend_hash_init(&php_pqstm_object_prophandlers
, 1, NULL
, NULL
, 1);
2118 memset(&ce
, 0, sizeof(ce
));
2119 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
2120 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
2121 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
2123 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2124 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
2125 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
2126 php_pqstm_object_handlers
.clone_obj
= NULL
;
2127 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
2128 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2130 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2131 ph
.read
= php_pqstm_object_read_name
;
2132 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
2134 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2135 ph
.read
= php_pqstm_object_read_connection
;
2136 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
2139 REGISTER_INI_ENTRIES();
2145 /* {{{ PHP_MSHUTDOWN_FUNCTION
2147 PHP_MSHUTDOWN_FUNCTION(pq
)
2149 /* uncomment this line if you have INI entries
2150 UNREGISTER_INI_ENTRIES();
2156 /* {{{ PHP_MINFO_FUNCTION
2158 PHP_MINFO_FUNCTION(pq
)
2160 php_info_print_table_start();
2161 php_info_print_table_header(2, "pq support", "enabled");
2162 php_info_print_table_end();
2164 /* Remove comments if you have entries in php.ini
2165 DISPLAY_INI_ENTRIES();
2177 * vim600: noet sw=4 ts=4 fdm=marker
2178 * vim<600: noet sw=4 ts=4