2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
17 #define SMART_STR_PREALLOC 256
20 #include <Zend/zend_interfaces.h>
21 #include <Zend/zend_exceptions.h>
22 #include <ext/standard/info.h>
23 #include <ext/standard/php_smart_str.h>
24 #include <ext/spl/spl_array.h>
25 #include <ext/spl/spl_exceptions.h>
26 #include <ext/raphf/php_raphf.h>
28 #include <libpq-events.h>
29 #include <libpq/libpq-fs.h>
34 typedef int STATUS
; /* SUCCESS/FAILURE */
36 static char *rtrim(char *e
) {
39 while (l
-- > 0 && e
[l
] == '\n') {
45 #define PHP_PQerrorMessage(c) rtrim(PQerrorMessage((c)))
46 #define PHP_PQresultErrorMessage(r) rtrim(PQresultErrorMessage((r)))
48 static int php_pqconn_event(PGEventId id
, void *e
, void *data
);
50 #define PHP_PQclear(_r) \
52 zval *_resinszv = PQresultInstanceData((_r), php_pqconn_event); \
53 if (!_resinszv) PQclear((_r)); \
57 ZEND_DECLARE_MODULE_GLOBALS(pq)
62 /* Remove comments and fill if you need to have entries in php.ini
64 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
65 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
70 /* {{{ php_pq_init_globals
72 /* Uncomment this function if you have INI entries
73 static void php_pq_init_globals(zend_pq_globals *pq_globals)
75 pq_globals->global_value = 0;
76 pq_globals->global_string = NULL;
81 static zend_class_entry
*php_pqconn_class_entry
;
82 static zend_class_entry
*php_pqtypes_class_entry
;
83 static zend_class_entry
*php_pqres_class_entry
;
84 static zend_class_entry
*php_pqstm_class_entry
;
85 static zend_class_entry
*php_pqtxn_class_entry
;
86 static zend_class_entry
*php_pqcancel_class_entry
;
87 static zend_class_entry
*php_pqevent_class_entry
;
88 static zend_class_entry
*php_pqlob_class_entry
;
89 static zend_class_entry
*php_pqcopy_class_entry
;
91 typedef enum php_pqexc_type
{
104 static zend_class_entry
*php_pqexc_interface_class_entry
;
105 static zend_class_entry
*php_pqexc_default_class_entry
;
106 static zend_class_entry
*php_pqexc_invalid_argument_class_entry
;
107 static zend_class_entry
*php_pqexc_runtime_class_entry
;
108 static zend_class_entry
*php_pqexc_bad_methodcall_class_entry
;
109 static zend_class_entry
*php_pqexc_domain_class_entry
;
111 static zend_class_entry
*exce(php_pqexc_type_t type
)
116 return php_pqexc_default_class_entry
;
117 case EX_INVALID_ARGUMENT
:
118 return php_pqexc_invalid_argument_class_entry
;
120 case EX_CONNECTION_FAILED
:
123 return php_pqexc_runtime_class_entry
;
124 case EX_UNINITIALIZED
:
125 case EX_BAD_METHODCALL
:
126 return php_pqexc_bad_methodcall_class_entry
;
129 return php_pqexc_domain_class_entry
;
133 static zval
*throw_exce(php_pqexc_type_t type TSRMLS_DC
, const char *fmt
, ...)
140 vspprintf(&msg
, 0, fmt
, argv
);
143 zexc
= zend_throw_exception(exce(type
), msg
, type TSRMLS_CC
);
149 static zend_object_handlers php_pqconn_object_handlers
;
150 static zend_object_handlers php_pqtypes_object_handlers
;
151 static zend_object_handlers php_pqres_object_handlers
;
152 static zend_object_handlers php_pqstm_object_handlers
;
153 static zend_object_handlers php_pqtxn_object_handlers
;
154 static zend_object_handlers php_pqcancel_object_handlers
;
155 static zend_object_handlers php_pqevent_object_handlers
;
156 static zend_object_handlers php_pqlob_object_handlers
;
157 static zend_object_handlers php_pqcopy_object_handlers
;
159 typedef struct php_pq_callback
{
161 zend_fcall_info_cache fcc
;
165 typedef struct php_pq_object
{
167 zend_object_value zv
;
168 HashTable
*prophandler
;
172 #define PHP_PQCONN_ASYNC 0x01
173 #define PHP_PQCONN_PERSISTENT 0x02
175 typedef struct php_pqconn
{
177 int (*poller
)(PGconn
*);
178 php_resource_factory_t factory
;
180 HashTable eventhandlers
;
181 php_pq_callback_t onevent
;
182 unsigned unbuffered
:1;
185 typedef struct php_pqconn_object
{
187 zend_object_value zv
;
188 HashTable
*prophandler
;
189 php_pqconn_t
*intern
;
190 } php_pqconn_object_t
;
192 typedef struct php_pqtypes
{
194 php_pqconn_object_t
*conn
;
197 typedef struct php_pqtypes_object
{
199 zend_object_value zv
;
200 HashTable
*prophandler
;
201 php_pqtypes_t
*intern
;
202 } php_pqtypes_object_t
;
204 typedef struct php_pqconn_event_data
{
205 php_pqconn_object_t
*obj
;
209 } php_pqconn_event_data_t
;
211 typedef enum php_pqres_fetch
{
212 PHP_PQRES_FETCH_ARRAY
,
213 PHP_PQRES_FETCH_ASSOC
,
214 PHP_PQRES_FETCH_OBJECT
217 typedef struct php_pqres_iterator
{
218 zend_object_iterator zi
;
221 php_pqres_fetch_t fetch_type
;
222 } php_pqres_iterator_t
;
224 typedef struct php_pqres
{
226 php_pqres_iterator_t
*iter
;
230 typedef struct php_pqres_object
{
232 zend_object_value zv
;
233 HashTable
*prophandler
;
235 } php_pqres_object_t
;
237 typedef struct php_pqstm
{
238 php_pqconn_object_t
*conn
;
243 typedef struct php_pqstm_object
{
245 zend_object_value zv
;
246 HashTable
*prophandler
;
248 } php_pqstm_object_t
;
250 typedef enum php_pqtxn_isolation
{
251 PHP_PQTXN_READ_COMMITTED
,
252 PHP_PQTXN_REPEATABLE_READ
,
253 PHP_PQTXN_SERIALIZABLE
,
254 } php_pqtxn_isolation_t
;
256 typedef struct php_pqtxn
{
257 php_pqconn_object_t
*conn
;
258 php_pqtxn_isolation_t isolation
;
262 unsigned deferrable
:1;
265 typedef struct php_pqtxn_object
{
267 zend_object_value zv
;
268 HashTable
*prophandler
;
270 } php_pqtxn_object_t
;
272 typedef struct php_pqcancel
{
274 php_pqconn_object_t
*conn
;
277 typedef struct php_pqcancel_object
{
279 zend_object_value zv
;
280 HashTable
*prophandler
;
281 php_pqcancel_t
*intern
;
282 } php_pqcancel_object_t
;
284 typedef struct php_pqevent
{
285 php_pq_callback_t cb
;
286 php_pqconn_object_t
*conn
;
290 typedef struct php_pqevent_object
{
292 zend_object_value zv
;
293 HashTable
*prophandler
;
294 php_pqevent_t
*intern
;
295 } php_pqevent_object_t
;
297 typedef struct php_pqlob
{
300 php_pqtxn_object_t
*txn
;
303 typedef struct php_pqlob_object
{
305 zend_object_value zv
;
306 HashTable
*prophandler
;
308 } php_pqlob_object_t
;
310 typedef enum php_pqcopy_direction
{
311 PHP_PQCOPY_FROM_STDIN
,
313 } php_pqcopy_direction_t
;
315 typedef enum php_pqcopy_status
{
319 } php_pqcopy_status_t
;
321 typedef struct php_pqcopy
{
322 php_pqcopy_direction_t direction
;
325 php_pqconn_object_t
*conn
;
328 typedef struct php_pqcopy_object
{
330 zend_object_value zv
;
331 HashTable
*prophandler
;
332 php_pqcopy_t
*intern
;
333 } php_pqcopy_object_t
;
335 static HashTable php_pqconn_object_prophandlers
;
336 static HashTable php_pqtypes_object_prophandlers
;
337 static HashTable php_pqres_object_prophandlers
;
338 static HashTable php_pqstm_object_prophandlers
;
339 static HashTable php_pqtxn_object_prophandlers
;
340 static HashTable php_pqcancel_object_prophandlers
;
341 static HashTable php_pqevent_object_prophandlers
;
342 static HashTable php_pqlob_object_prophandlers
;
343 static HashTable php_pqcopy_object_prophandlers
;
345 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
347 typedef struct php_pq_object_prophandler
{
348 php_pq_object_prophandler_func_t read
;
349 php_pq_object_prophandler_func_t write
;
350 } php_pq_object_prophandler_t
;
352 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
354 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
356 php_pqres_iterator_t
*iter
;
357 zval
*prop
, *zfetch_type
;
359 iter
= ecalloc(1, sizeof(*iter
));
360 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
361 iter
->zi
.data
= object
;
364 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
365 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
366 convert_to_long_ex(&zfetch_type
);
368 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
369 if (zfetch_type
!= prop
) {
370 zval_ptr_dtor(&zfetch_type
);
372 if (Z_REFCOUNT_P(prop
)) {
373 zval_ptr_dtor(&prop
);
379 return (zend_object_iterator
*) iter
;
382 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
384 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
386 if (iter
->current_val
) {
387 zval_ptr_dtor(&iter
->current_val
);
388 iter
->current_val
= NULL
;
390 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
394 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
396 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
397 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
399 if (PQresultStatus(obj
->intern
->res
) != PGRES_TUPLES_OK
) {
402 if (PQntuples(obj
->intern
->res
) <= iter
->index
) {
409 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type
, zval
**data_ptr TSRMLS_DC
)
419 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
429 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
430 if (PQgetisnull(res
, row
, c
)) {
431 switch (fetch_type
) {
432 case PHP_PQRES_FETCH_OBJECT
:
433 add_property_null(data
, PQfname(res
, c
));
436 case PHP_PQRES_FETCH_ASSOC
:
437 add_assoc_null(data
, PQfname(res
, c
));
440 case PHP_PQRES_FETCH_ARRAY
:
441 add_index_null(data
, c
);
445 char *val
= PQgetvalue(res
, row
, c
);
446 int len
= PQgetlength(res
, row
, c
);
448 switch (fetch_type
) {
449 case PHP_PQRES_FETCH_OBJECT
:
450 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
453 case PHP_PQRES_FETCH_ASSOC
:
454 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
457 case PHP_PQRES_FETCH_ARRAY
:
458 add_index_stringl(data
, c
, val
, len
,1);
467 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
469 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
470 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
472 if (iter
->current_val
) {
473 zval_ptr_dtor(&iter
->current_val
);
475 iter
->current_val
= php_pqres_row_to_zval(obj
->intern
->res
, iter
->index
, iter
->fetch_type
, NULL TSRMLS_CC
);
476 *data_ptr
= &iter
->current_val
;
479 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
481 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
483 *key_num
= (ulong
) iter
->index
;
485 return HASH_KEY_IS_LONG
;
488 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
490 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
495 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
497 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
502 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
503 php_pqres_iterator_dtor
,
504 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
505 php_pqres_iterator_valid
,
506 /* fetch the item data for the current element */
507 php_pqres_iterator_current
,
508 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
509 php_pqres_iterator_key
,
510 /* step forwards to next element */
511 php_pqres_iterator_next
,
512 /* rewind to start of data (optional, may be NULL) */
513 php_pqres_iterator_rewind
,
514 /* invalidate current value/key (optional, may be NULL) */
518 static int php_pqres_count_elements(zval
*object
, long *count TSRMLS_DC
)
520 php_pqres_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
525 *count
= (long) PQntuples(obj
->intern
->res
);
530 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
534 switch (PQresultStatus(res
)) {
535 case PGRES_BAD_RESPONSE
:
536 case PGRES_NONFATAL_ERROR
:
537 case PGRES_FATAL_ERROR
:
538 zexc
= throw_exce(EX_SQL TSRMLS_CC
, "%s", PHP_PQresultErrorMessage(res
));
539 zend_update_property_string(php_pqexc_domain_class_entry
, zexc
, ZEND_STRL("sqlstate"), PQresultErrorField(res
, PG_DIAG_SQLSTATE
) TSRMLS_CC
);
546 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
547 if (cb
->fci
.size
> 0) {
548 zend_fcall_info_args_clear(&cb
->fci
, 1);
549 zval_ptr_dtor(&cb
->fci
.function_name
);
550 if (cb
->fci
.object_ptr
) {
551 zval_ptr_dtor(&cb
->fci
.object_ptr
);
557 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
559 Z_ADDREF_P(cb
->fci
.function_name
);
560 if (cb
->fci
.object_ptr
) {
561 Z_ADDREF_P(cb
->fci
.object_ptr
);
565 static void php_pq_object_to_zval(void *o
, zval
**zv TSRMLS_DC
)
567 php_pq_object_t
*obj
= o
;
573 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
575 (*zv
)->type
= IS_OBJECT
;
576 (*zv
)->value
.obj
= obj
->zv
;
579 static void php_pq_object_addref(void *o TSRMLS_DC
)
581 php_pq_object_t
*obj
= o
;
582 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
585 static void php_pq_object_delref(void *o TSRMLS_DC
)
587 php_pq_object_t
*obj
= o
;
588 zend_objects_store_del_ref_by_handle_ex(obj
->zv
.handle
, obj
->zv
.handlers TSRMLS_CC
);
591 static void php_pqconn_object_free(void *o TSRMLS_DC
)
593 php_pqconn_object_t
*obj
= o
;
596 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
597 php_resource_factory_dtor(&obj
->intern
->factory
);
598 php_pq_callback_dtor(&obj
->intern
->onevent
);
599 zend_hash_destroy(&obj
->intern
->listeners
);
600 zend_hash_destroy(&obj
->intern
->eventhandlers
);
604 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
608 static void php_pqtypes_object_free(void *o TSRMLS_DC
)
610 php_pqtypes_object_t
*obj
= o
;
613 zend_hash_destroy(&obj
->intern
->types
);
614 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
618 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
622 static void php_pqres_object_free(void *o TSRMLS_DC
)
624 php_pqres_object_t
*obj
= o
;
627 if (obj
->intern
->res
) {
628 zval
*res
= PQresultInstanceData(obj
->intern
->res
, php_pqconn_event
);
630 if (1 == Z_REFCOUNT_P(res
)) {
631 PQresultSetInstanceData(obj
->intern
->res
, php_pqconn_event
, NULL
);
635 PQclear(obj
->intern
->res
);
636 obj
->intern
->res
= NULL
;
640 if (obj
->intern
->iter
) {
641 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
642 obj
->intern
->iter
= NULL
;
645 zend_hash_destroy(&obj
->intern
->bound
);
650 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
654 static void php_pqstm_object_free(void *o TSRMLS_DC
)
656 php_pqstm_object_t
*obj
= o
;
659 char *quoted_name
= PQescapeIdentifier(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, strlen(obj
->intern
->name
));
661 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
667 smart_str_appends(&cmd
, "DEALLOCATE ");
668 smart_str_appends(&cmd
, quoted_name
);
670 PQfreemem(quoted_name
);
672 if ((res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
))) {
675 smart_str_free(&cmd
);
678 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
679 efree(obj
->intern
->name
);
680 zend_hash_destroy(&obj
->intern
->bound
);
684 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
688 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
690 php_pqtxn_object_t
*obj
= o
;
693 if (obj
->intern
->open
) {
694 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
700 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
704 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
708 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
710 php_pqcancel_object_t
*obj
= o
;
713 PQfreeCancel(obj
->intern
->cancel
);
714 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
718 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
722 static void php_pqevent_object_free(void *o TSRMLS_DC
)
724 php_pqevent_object_t
*obj
= o
;
727 php_pq_callback_dtor(&obj
->intern
->cb
);
728 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
729 efree(obj
->intern
->type
);
733 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
737 static void php_pqlob_object_free(void *o TSRMLS_DC
)
739 php_pqlob_object_t
*obj
= o
;
742 if (obj
->intern
->lofd
) {
743 lo_close(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
745 php_pq_object_delref(obj
->intern
->txn TSRMLS_CC
);
749 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
753 static void php_pqcopy_object_free(void *o TSRMLS_DC
)
755 php_pqcopy_object_t
*obj
= o
;
758 efree(obj
->intern
->expression
);
759 efree(obj
->intern
->options
);
760 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
764 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
768 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
770 php_pqconn_object_t
*o
;
772 o
= ecalloc(1, sizeof(*o
));
773 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
774 object_properties_init((zend_object
*) o
, ce
);
775 o
->prophandler
= &php_pqconn_object_prophandlers
;
785 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
786 o
->zv
.handlers
= &php_pqconn_object_handlers
;
791 static zend_object_value
php_pqtypes_create_object_ex(zend_class_entry
*ce
, php_pqtypes_t
*intern
, php_pqtypes_object_t
**ptr TSRMLS_DC
)
793 php_pqtypes_object_t
*o
;
795 o
= ecalloc(1, sizeof(*o
));
796 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
797 object_properties_init((zend_object
*) o
, ce
);
798 o
->prophandler
= &php_pqtypes_object_prophandlers
;
808 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtypes_object_free
, NULL TSRMLS_CC
);
809 o
->zv
.handlers
= &php_pqtypes_object_handlers
;
814 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, php_pqres_t
*intern
, php_pqres_object_t
**ptr TSRMLS_DC
)
816 php_pqres_object_t
*o
;
818 o
= ecalloc(1, sizeof(*o
));
819 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
820 object_properties_init((zend_object
*) o
, ce
);
821 o
->prophandler
= &php_pqres_object_prophandlers
;
831 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
832 o
->zv
.handlers
= &php_pqres_object_handlers
;
837 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*intern
, php_pqstm_object_t
**ptr TSRMLS_DC
)
839 php_pqstm_object_t
*o
;
841 o
= ecalloc(1, sizeof(*o
));
842 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
843 object_properties_init((zend_object
*) o
, ce
);
844 o
->prophandler
= &php_pqstm_object_prophandlers
;
854 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
855 o
->zv
.handlers
= &php_pqstm_object_handlers
;
860 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*intern
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
862 php_pqtxn_object_t
*o
;
864 o
= ecalloc(1, sizeof(*o
));
865 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
866 object_properties_init((zend_object
*) o
, ce
);
867 o
->prophandler
= &php_pqtxn_object_prophandlers
;
877 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
878 o
->zv
.handlers
= &php_pqtxn_object_handlers
;
883 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*intern
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
885 php_pqcancel_object_t
*o
;
887 o
= ecalloc(1, sizeof(*o
));
888 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
889 object_properties_init((zend_object
*) o
, ce
);
890 o
->prophandler
= &php_pqcancel_object_prophandlers
;
900 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
901 o
->zv
.handlers
= &php_pqcancel_object_handlers
;
906 static zend_object_value
php_pqevent_create_object_ex(zend_class_entry
*ce
, php_pqevent_t
*intern
, php_pqevent_object_t
**ptr TSRMLS_DC
)
908 php_pqevent_object_t
*o
;
910 o
= ecalloc(1, sizeof(*o
));
911 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
912 object_properties_init((zend_object
*) o
, ce
);
913 o
->prophandler
= &php_pqevent_object_prophandlers
;
923 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqevent_object_free
, NULL TSRMLS_CC
);
924 o
->zv
.handlers
= &php_pqevent_object_handlers
;
929 static zend_object_value
php_pqlob_create_object_ex(zend_class_entry
*ce
, php_pqlob_t
*intern
, php_pqlob_object_t
**ptr TSRMLS_DC
)
931 php_pqlob_object_t
*o
;
933 o
= ecalloc(1, sizeof(*o
));
934 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
935 object_properties_init((zend_object
*) o
, ce
);
936 o
->prophandler
= &php_pqlob_object_prophandlers
;
946 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqlob_object_free
, NULL TSRMLS_CC
);
947 o
->zv
.handlers
= &php_pqlob_object_handlers
;
952 static zend_object_value
php_pqcopy_create_object_ex(zend_class_entry
*ce
, php_pqcopy_t
*intern
, php_pqcopy_object_t
**ptr TSRMLS_DC
)
954 php_pqcopy_object_t
*o
;
956 o
= ecalloc(1, sizeof(*o
));
957 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
958 object_properties_init((zend_object
*) o
, ce
);
959 o
->prophandler
= &php_pqcopy_object_prophandlers
;
969 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcopy_object_free
, NULL TSRMLS_CC
);
970 o
->zv
.handlers
= &php_pqcopy_object_handlers
;
975 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
977 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
980 static zend_object_value
php_pqtypes_create_object(zend_class_entry
*class_type TSRMLS_DC
)
982 return php_pqtypes_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
985 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
987 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
990 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
992 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
995 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
997 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1000 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1002 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1005 static zend_object_value
php_pqevent_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1007 return php_pqevent_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1010 static zend_object_value
php_pqlob_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1012 return php_pqlob_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1015 static zend_object_value
php_pqcopy_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1017 return php_pqcopy_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1020 static int apply_ph_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1022 php_pq_object_prophandler_t
*ph
= p
;
1023 HashTable
*ht
= va_arg(argv
, HashTable
*);
1024 zval
**return_value
, *object
= va_arg(argv
, zval
*);
1025 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
1027 if (SUCCESS
== zend_hash_find(ht
, key
->arKey
, key
->nKeyLength
, (void *) &return_value
)) {
1030 zval_ptr_dtor(return_value
);
1031 MAKE_STD_ZVAL(*return_value
);
1032 ZVAL_NULL(*return_value
);
1034 ph
->read(object
, obj
, *return_value TSRMLS_CC
);
1038 return ZEND_HASH_APPLY_KEEP
;
1041 static int apply_pi_to_debug(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1043 zend_property_info
*pi
= p
;
1044 HashTable
*ht
= va_arg(argv
, HashTable
*);
1045 zval
*object
= va_arg(argv
, zval
*);
1046 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
1047 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
1049 if (1||!Z_REFCOUNT_P(property
)) {
1050 Z_ADDREF_P(property
);
1052 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
1054 return ZEND_HASH_APPLY_KEEP
;
1057 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
1060 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1063 ALLOC_HASHTABLE(ht
);
1064 ZEND_INIT_SYMTABLE(ht
);
1066 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_debug
, 3, ht
, object
, obj
);
1067 zend_hash_apply_with_arguments(obj
->prophandler TSRMLS_CC
, apply_ph_to_debug
, 3, ht
, object
, obj
);
1072 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1074 php_pqconn_object_t
*obj
= o
;
1076 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
1079 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1081 php_pqconn_object_t
*obj
= o
;
1083 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
1086 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1088 php_pqconn_object_t
*obj
= o
;
1089 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
1092 RETVAL_STRING(error
, 1);
1098 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
1100 php_pq_callback_t
*listener
= p
;
1101 PGnotify
*nfy
= arg
;
1102 zval
*zpid
, *zchannel
, *zmessage
;
1104 MAKE_STD_ZVAL(zpid
);
1105 ZVAL_LONG(zpid
, nfy
->be_pid
);
1106 MAKE_STD_ZVAL(zchannel
);
1107 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
1108 MAKE_STD_ZVAL(zmessage
);
1109 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
1111 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
1112 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
1114 zval_ptr_dtor(&zchannel
);
1115 zval_ptr_dtor(&zmessage
);
1116 zval_ptr_dtor(&zpid
);
1118 return ZEND_HASH_APPLY_KEEP
;
1121 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1123 HashTable
*listeners
= p
;
1124 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
1126 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
1127 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
1130 return ZEND_HASH_APPLY_KEEP
;
1133 static void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
1137 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
1138 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
1143 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1145 php_pqconn_object_t
*obj
= o
;
1147 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
1150 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1152 php_pqconn_object_t
*obj
= o
;
1154 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
1157 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1159 php_pqconn_object_t
*obj
= o
;
1162 if (Z_TYPE_P(value
) != IS_STRING
) {
1163 convert_to_string_ex(&zenc
);
1166 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
1167 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
1170 if (zenc
!= value
) {
1171 zval_ptr_dtor(&zenc
);
1175 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1177 php_pqconn_object_t
*obj
= o
;
1179 RETVAL_BOOL(obj
->intern
->unbuffered
);
1182 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1184 php_pqconn_object_t
*obj
= o
;
1186 obj
->intern
->unbuffered
= zend_is_true(value
);
1189 static void php_pqconn_object_read_db(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1191 php_pqconn_object_t
*obj
= o
;
1192 char *db
= PQdb(obj
->intern
->conn
);
1195 RETVAL_STRING(db
, 1);
1197 RETVAL_EMPTY_STRING();
1201 static void php_pqconn_object_read_user(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1203 php_pqconn_object_t
*obj
= o
;
1204 char *user
= PQuser(obj
->intern
->conn
);
1207 RETVAL_STRING(user
, 1);
1209 RETVAL_EMPTY_STRING();
1213 static void php_pqconn_object_read_pass(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1215 php_pqconn_object_t
*obj
= o
;
1216 char *pass
= PQpass(obj
->intern
->conn
);
1219 RETVAL_STRING(pass
, 1);
1221 RETVAL_EMPTY_STRING();
1225 static void php_pqconn_object_read_host(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1227 php_pqconn_object_t
*obj
= o
;
1228 char *host
= PQhost(obj
->intern
->conn
);
1231 RETVAL_STRING(host
, 1);
1233 RETVAL_EMPTY_STRING();
1237 static void php_pqconn_object_read_port(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1239 php_pqconn_object_t
*obj
= o
;
1240 char *port
= PQport(obj
->intern
->conn
);
1243 RETVAL_STRING(port
, 1);
1245 RETVAL_EMPTY_STRING();
1249 static void php_pqconn_object_read_options(zval
*objec
, void *o
, zval
*return_value TSRMLS_DC
)
1251 php_pqconn_object_t
*obj
= o
;
1252 char *options
= PQoptions(obj
->intern
->conn
);
1255 RETVAL_STRING(options
, 1);
1257 RETVAL_EMPTY_STRING();
1261 static void php_pqtypes_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1263 php_pqtypes_object_t
*obj
= o
;
1265 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1268 static int has_dimension(HashTable
*ht
, zval
*member
, char **key_str
, int *key_len
, long *index TSRMLS_DC
)
1273 switch (Z_TYPE_P(member
)) {
1275 convert_to_string_ex(&tmp
);
1278 if (!is_numeric_string(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
), &lval
, NULL
, 0)) {
1279 if (member
!= tmp
) {
1280 zval_ptr_dtor(&tmp
);
1283 *key_str
= estrndup(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
));
1285 *key_len
= Z_STRLEN_P(tmp
) + 1;
1288 return zend_hash_exists(ht
, Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
) + 1);
1292 lval
= Z_LVAL_P(member
);
1296 if (member
!= tmp
) {
1297 zval_ptr_dtor(&tmp
);
1302 return zend_hash_index_exists(ht
, lval
);
1305 static int php_pqtypes_object_has_dimension(zval
*object
, zval
*member
, int check_empty TSRMLS_DC
)
1307 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1308 char *key_str
= NULL
;
1313 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1316 if (key_str
&& key_len
) {
1317 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1319 return Z_TYPE_PP(data
) != IS_NULL
;
1323 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) data
)) {
1324 return Z_TYPE_PP(data
) != IS_NULL
;
1329 return has_dimension(&obj
->intern
->types
, member
, NULL
, NULL
, NULL TSRMLS_CC
);
1335 static zval
*php_pqtypes_object_read_dimension(zval
*object
, zval
*member
, int type TSRMLS_DC
)
1338 char *key_str
= NULL
;
1340 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1342 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1345 if (key_str
&& key_len
) {
1346 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1351 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1360 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1362 php_pqres_object_t
*obj
= o
;
1364 RETVAL_LONG(PQresultStatus(obj
->intern
->res
));
1367 static void php_pqres_object_read_status_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1369 php_pqres_object_t
*obj
= o
;
1371 RETVAL_STRING(PQresStatus(PQresultStatus(obj
->intern
->res
))+sizeof("PGRES"), 1);
1374 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1376 php_pqres_object_t
*obj
= o
;
1377 char *error
= PHP_PQresultErrorMessage(obj
->intern
->res
);
1380 RETVAL_STRING(error
, 1);
1386 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1388 php_pqres_object_t
*obj
= o
;
1390 RETVAL_LONG(PQntuples(obj
->intern
->res
));
1393 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1395 php_pqres_object_t
*obj
= o
;
1397 RETVAL_LONG(PQnfields(obj
->intern
->res
));
1400 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1402 php_pqres_object_t
*obj
= o
;
1404 RETVAL_LONG(atoi(PQcmdTuples(obj
->intern
->res
)));
1407 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1409 php_pqres_object_t
*obj
= o
;
1411 if (obj
->intern
->iter
) {
1412 RETVAL_LONG(obj
->intern
->iter
->fetch_type
);
1414 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
1418 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1420 php_pqres_object_t
*obj
= o
;
1421 zval
*zfetch_type
= value
;
1423 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
1424 convert_to_long_ex(&zfetch_type
);
1427 if (!obj
->intern
->iter
) {
1428 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
1429 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
1431 obj
->intern
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
1433 if (zfetch_type
!= value
) {
1434 zval_ptr_dtor(&zfetch_type
);
1438 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1440 php_pqstm_object_t
*obj
= o
;
1442 RETVAL_STRING(obj
->intern
->name
, 1);
1445 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1447 php_pqstm_object_t
*obj
= o
;
1449 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1452 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1454 php_pqtxn_object_t
*obj
= o
;
1456 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1459 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1461 php_pqtxn_object_t
*obj
= o
;
1463 RETVAL_LONG(obj
->intern
->isolation
);
1466 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1468 php_pqtxn_object_t
*obj
= o
;
1470 RETVAL_LONG(obj
->intern
->readonly
);
1473 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1475 php_pqtxn_object_t
*obj
= o
;
1477 RETVAL_LONG(obj
->intern
->deferrable
);
1480 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1482 php_pqtxn_object_t
*obj
= o
;
1483 php_pqtxn_isolation_t orig
= obj
->intern
->isolation
;
1484 zval
*zisolation
= value
;
1487 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
1488 convert_to_long_ex(&zisolation
);
1491 switch ((obj
->intern
->isolation
= Z_LVAL_P(zisolation
))) {
1492 case PHP_PQTXN_READ_COMMITTED
:
1493 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ COMMITED");
1495 case PHP_PQTXN_REPEATABLE_READ
:
1496 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION REPEATABLE READ");
1498 case PHP_PQTXN_SERIALIZABLE
:
1499 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION SERIALIZABLE");
1502 obj
->intern
->isolation
= orig
;
1507 if (zisolation
!= value
) {
1508 zval_ptr_dtor(&zisolation
);
1512 php_pqres_success(res TSRMLS_CC
);
1517 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1519 php_pqtxn_object_t
*obj
= o
;
1522 if ((obj
->intern
->readonly
= zend_is_true(value
))) {
1523 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ ONLY");
1525 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ WRITE");
1529 php_pqres_success(res TSRMLS_CC
);
1534 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1536 php_pqtxn_object_t
*obj
= o
;
1539 if ((obj
->intern
->deferrable
= zend_is_true(value
))) {
1540 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION DEFERRABLE");
1542 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION NOT DEFERRABLE");
1546 php_pqres_success(res TSRMLS_CC
);
1551 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1553 php_pqcancel_object_t
*obj
= o
;
1555 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1558 static void php_pqevent_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1560 php_pqevent_object_t
*obj
= o
;
1562 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1565 static void php_pqevent_object_read_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1567 php_pqevent_object_t
*obj
= o
;
1569 RETVAL_STRING(obj
->intern
->type
, 1);
1572 static void php_pqlob_object_read_transaction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1574 php_pqlob_object_t
*obj
= o
;
1576 php_pq_object_to_zval(obj
->intern
->txn
, &return_value TSRMLS_CC
);
1579 static void php_pqlob_object_read_oid(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1581 php_pqlob_object_t
*obj
= o
;
1583 RETVAL_LONG(obj
->intern
->loid
);
1586 static void php_pqcopy_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1588 php_pqcopy_object_t
*obj
= o
;
1590 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1593 static void php_pqcopy_object_read_direction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1595 php_pqcopy_object_t
*obj
= o
;
1597 RETVAL_LONG(obj
->intern
->direction
);
1600 static void php_pqcopy_object_read_expression(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1602 php_pqcopy_object_t
*obj
= o
;
1604 RETURN_STRING(obj
->intern
->expression
, 1);
1607 static void php_pqcopy_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1609 php_pqcopy_object_t
*obj
= o
;
1611 RETURN_STRING(obj
->intern
->options
, 1);
1614 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
1615 while (ce
->parent
) {
1621 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
1623 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1624 php_pq_object_prophandler_t
*handler
;
1628 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1629 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1630 if (type
== BP_VAR_R
) {
1631 ALLOC_ZVAL(return_value
);
1632 Z_SET_REFCOUNT_P(return_value
, 0);
1633 Z_UNSET_ISREF_P(return_value
);
1635 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1637 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1638 return_value
= NULL
;
1641 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1644 return return_value
;
1647 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1649 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1650 php_pq_object_prophandler_t
*handler
;
1652 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1653 if (handler
->write
) {
1654 handler
->write(object
, obj
, value TSRMLS_CC
);
1657 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1661 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1663 zval
*zsocket
, zmember
;
1669 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1672 INIT_PZVAL(&zmember
);
1673 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1674 MAKE_STD_ZVAL(zsocket
);
1676 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
1677 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
1678 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1679 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1680 php_stream_to_zval(stream
, zsocket
);
1686 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1687 zval_ptr_dtor(&zsocket
);
1693 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1694 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1696 # define TSRMLS_DF(d)
1697 # define TSRMLS_CF(d)
1700 static int apply_event(void *p
, void *a TSRMLS_DC
)
1704 zval
*retval
= NULL
;
1706 zend_call_method_with_1_params(evh
, Z_OBJCE_PP(evh
), NULL
, "trigger", &retval
, args
);
1708 zval_ptr_dtor(&retval
);
1711 return ZEND_HASH_APPLY_KEEP
;
1714 static void php_pqconn_event_connreset(PGEventConnReset
*event
)
1716 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1722 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("reset"), (void *) &evhs
)) {
1723 zval
*args
, *connection
= NULL
;
1725 MAKE_STD_ZVAL(args
);
1727 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1728 add_next_index_zval(args
, connection
);
1729 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1730 zval_ptr_dtor(&args
);
1735 static zval
*result_instance_zval(PGresult
*res TSRMLS_DC
)
1737 zval
*rid
= PQresultInstanceData(res
, php_pqconn_event
);
1740 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
1744 ZEND_INIT_SYMTABLE(&r
->bound
);
1745 rid
->type
= IS_OBJECT
;
1746 rid
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
1748 PQresultSetInstanceData(res
, php_pqconn_event
, rid
);
1755 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
)
1757 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1763 /* event listener */
1764 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("result"), (void *) &evhs
)) {
1765 zval
*args
, *connection
= NULL
, *res
= result_instance_zval(event
->result TSRMLS_CC
);
1767 MAKE_STD_ZVAL(args
);
1769 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1770 add_next_index_zval(args
, connection
);
1771 add_next_index_zval(args
, res
);
1772 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1773 zval_ptr_dtor(&args
);
1776 /* async callback */
1777 if (data
->obj
->intern
->onevent
.fci
.size
> 0) {
1778 zval
*res
= result_instance_zval(event
->result TSRMLS_CC
);
1780 zend_fcall_info_argn(&data
->obj
->intern
->onevent
.fci TSRMLS_CC
, 1, &res
);
1781 zend_fcall_info_call(&data
->obj
->intern
->onevent
.fci
, &data
->obj
->intern
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1782 zval_ptr_dtor(&res
);
1787 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1790 case PGEVT_CONNRESET
:
1791 php_pqconn_event_connreset(e
);
1793 case PGEVT_RESULTCREATE
:
1794 php_pqconn_event_resultcreate(e
);
1803 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1805 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1813 static void php_pqconn_notice_recv(void *p
, const PGresult
*res
)
1815 php_pqconn_event_data_t
*data
= p
;
1821 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("notice"), (void *) &evhs
)) {
1822 zval
*args
, *connection
= NULL
;
1824 MAKE_STD_ZVAL(args
);
1826 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1827 add_next_index_zval(args
, connection
);
1828 add_next_index_string(args
, PHP_PQresultErrorMessage(res
), 1);
1829 zend_hash_apply_with_argument(Z_ARRVAL_PP(evhs
), apply_event
, args TSRMLS_CC
);
1830 zval_ptr_dtor(&args
);
1835 typedef struct php_pqconn_resource_factory_data
{
1838 } php_pqconn_resource_factory_data_t
;
1840 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
1842 php_pqconn_resource_factory_data_t
*o
= init_arg
;
1843 PGconn
*conn
= NULL
;;
1845 if (o
->flags
& PHP_PQCONN_ASYNC
) {
1846 conn
= PQconnectStart(o
->dsn
);
1848 conn
= PQconnectdb(o
->dsn
);
1852 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
1858 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
1860 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
1862 /* we don't care for anything, except free'ing evdata */
1864 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
1865 memset(evdata
, 0, sizeof(*evdata
));
1872 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
1873 php_pqconn_resource_factory_ctor
,
1875 php_pqconn_resource_factory_dtor
1878 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1880 // FIXME: ping server
1883 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1885 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
1886 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1);
1888 if (quoted_channel
) {
1892 spprintf(&cmd
, 0, "UNLISTEN %s", quoted_channel
);
1893 if ((res
= PQexec(obj
->intern
->conn
, cmd
))) {
1898 PQfreemem(quoted_channel
);
1901 return ZEND_HASH_APPLY_REMOVE
;
1904 static void php_pqconn_notice_ignore(void *p
, const PGresult
*res
)
1908 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1910 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
1915 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
1917 /* ignore notices */
1918 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
1920 /* cancel async queries */
1921 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
1922 char err
[256] = {0};
1924 PQcancel(cancel
, err
, sizeof(err
));
1925 PQfreeCancel(cancel
);
1927 /* clean up async results */
1928 while ((res
= PQgetResult(*handle
))) {
1932 /* clean up transaction & session */
1933 switch (PQtransactionStatus(*handle
)) {
1935 res
= PQexec(*handle
, "RESET ALL");
1938 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
1947 /* clean up notify listeners */
1948 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
1950 /* release instance data */
1951 memset(evdata
, 0, sizeof(*evdata
));
1956 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
1957 ZEND_ARG_INFO(0, dsn
)
1958 ZEND_ARG_INFO(0, async
)
1959 ZEND_END_ARG_INFO();
1960 static PHP_METHOD(pqconn
, __construct
) {
1961 zend_error_handling zeh
;
1967 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1968 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
);
1969 zend_restore_error_handling(&zeh TSRMLS_CC
);
1971 if (SUCCESS
== rv
) {
1972 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1975 throw_exce(EX_BAD_METHODCALL TSRMLS_CC
, "pq\\Connection already initialized");
1977 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
1978 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
1980 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
1982 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
1983 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
1985 if (flags
& PHP_PQCONN_PERSISTENT
) {
1986 php_persistent_handle_factory_t
*phf
= php_persistent_handle_concede(NULL
, ZEND_STRL("pq\\Connection"), dsn_str
, dsn_len
, php_pqconn_wakeup
, php_pqconn_retire TSRMLS_CC
);
1987 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
1989 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
1992 if (flags
& PHP_PQCONN_ASYNC
) {
1993 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
1996 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
1998 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
1999 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
2001 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
2002 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2008 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
2009 ZEND_END_ARG_INFO();
2010 static PHP_METHOD(pqconn
, reset
) {
2011 zend_error_handling zeh
;
2014 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2015 rv
= zend_parse_parameters_none();
2016 zend_restore_error_handling(&zeh TSRMLS_CC
);
2018 if (SUCCESS
== rv
) {
2019 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2022 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2024 PQreset(obj
->intern
->conn
);
2026 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
2027 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2030 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2035 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
2036 ZEND_END_ARG_INFO();
2037 static PHP_METHOD(pqconn
, resetAsync
) {
2038 zend_error_handling zeh
;
2041 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2042 rv
= zend_parse_parameters_none();
2043 zend_restore_error_handling(&zeh TSRMLS_CC
);
2045 if (SUCCESS
== rv
) {
2046 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2049 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2051 if (!PQresetStart(obj
->intern
->conn
)) {
2052 throw_exce(EX_IO TSRMLS_CC
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2054 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
2057 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2062 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
)
2064 HashTable ht
, *existing_listeners
;
2066 php_pq_callback_addref(listener
);
2068 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
2069 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
2071 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
2072 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
2073 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
2077 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
2078 ZEND_ARG_INFO(0, channel
)
2079 ZEND_ARG_INFO(0, callable
)
2080 ZEND_END_ARG_INFO();
2081 static PHP_METHOD(pqconn
, listen
) {
2082 zend_error_handling zeh
;
2083 char *channel_str
= NULL
;
2084 int channel_len
= 0;
2085 php_pq_callback_t listener
;
2088 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2089 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2090 zend_restore_error_handling(&zeh TSRMLS_CC
);
2092 if (SUCCESS
== rv
) {
2093 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2096 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2098 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2100 if (!quoted_channel
) {
2101 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2104 smart_str cmd
= {0};
2106 smart_str_appends(&cmd
, "LISTEN ");
2107 smart_str_appends(&cmd
, quoted_channel
);
2110 res
= PQexec(obj
->intern
->conn
, cmd
.c
);
2112 smart_str_free(&cmd
);
2113 PQfreemem(quoted_channel
);
2116 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2118 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2119 obj
->intern
->poller
= PQconsumeInput
;
2120 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2125 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2131 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
2132 ZEND_ARG_INFO(0, channel
)
2133 ZEND_ARG_INFO(0, callable
)
2134 ZEND_END_ARG_INFO();
2135 static PHP_METHOD(pqconn
, listenAsync
) {
2136 zend_error_handling zeh
;
2137 char *channel_str
= NULL
;
2138 int channel_len
= 0;
2139 php_pq_callback_t listener
;
2142 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2143 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2144 zend_restore_error_handling(&zeh TSRMLS_CC
);
2146 if (SUCCESS
== rv
) {
2147 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2150 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2152 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2154 if (!quoted_channel
) {
2155 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2157 smart_str cmd
= {0};
2159 smart_str_appends(&cmd
, "LISTEN ");
2160 smart_str_appends(&cmd
, quoted_channel
);
2163 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
2164 throw_exce(EX_IO TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2166 obj
->intern
->poller
= PQconsumeInput
;
2167 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2170 smart_str_free(&cmd
);
2171 PQfreemem(quoted_channel
);
2172 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2178 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
2179 ZEND_ARG_INFO(0, channel
)
2180 ZEND_ARG_INFO(0, message
)
2181 ZEND_END_ARG_INFO();
2182 static PHP_METHOD(pqconn
, notify
) {
2183 zend_error_handling zeh
;
2184 char *channel_str
, *message_str
;
2185 int channel_len
, message_len
;
2188 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2189 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2190 zend_restore_error_handling(&zeh TSRMLS_CC
);
2192 if (SUCCESS
== rv
) {
2193 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2196 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2199 char *params
[2] = {channel_str
, message_str
};
2201 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
2204 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2206 php_pqres_success(res TSRMLS_CC
);
2210 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2215 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
2216 ZEND_ARG_INFO(0, channel
)
2217 ZEND_ARG_INFO(0, message
)
2218 ZEND_END_ARG_INFO();
2219 static PHP_METHOD(pqconn
, notifyAsync
) {
2220 zend_error_handling zeh
;
2221 char *channel_str
, *message_str
;
2222 int channel_len
, message_len
;
2225 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2226 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2227 zend_restore_error_handling(&zeh TSRMLS_CC
);
2229 if (SUCCESS
== rv
) {
2230 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2233 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2235 char *params
[2] = {channel_str
, message_str
};
2237 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
2238 throw_exce(EX_IO TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2240 obj
->intern
->poller
= PQconsumeInput
;
2243 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2248 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
2249 ZEND_END_ARG_INFO();
2250 static PHP_METHOD(pqconn
, poll
) {
2251 zend_error_handling zeh
;
2254 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2255 rv
= zend_parse_parameters_none();
2256 zend_restore_error_handling(&zeh TSRMLS_CC
);
2258 if (SUCCESS
== rv
) {
2259 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2262 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2263 } else if (!obj
->intern
->poller
) {
2264 throw_exce(EX_RUNTIME TSRMLS_CC
, "No asynchronous operation active");
2266 if (obj
->intern
->poller
== PQconsumeInput
) {
2267 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
2269 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
2271 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2276 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
2277 ZEND_ARG_INFO(0, query
)
2278 ZEND_END_ARG_INFO();
2279 static PHP_METHOD(pqconn
, exec
) {
2280 zend_error_handling zeh
;
2285 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2286 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
);
2287 zend_restore_error_handling(&zeh TSRMLS_CC
);
2289 if (SUCCESS
== rv
) {
2290 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2293 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2295 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
2298 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2299 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2300 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2303 ZEND_INIT_SYMTABLE(&r
->bound
);
2304 return_value
->type
= IS_OBJECT
;
2305 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2308 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2313 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
2314 ZEND_END_ARG_INFO();
2315 static PHP_METHOD(pqconn
, getResult
) {
2316 zend_error_handling zeh
;
2319 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2320 rv
= zend_parse_parameters_none();
2321 zend_restore_error_handling(&zeh TSRMLS_CC
);
2323 if (SUCCESS
== rv
) {
2324 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2327 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connectio not initialized");
2329 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
2334 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2337 ZEND_INIT_SYMTABLE(&r
->bound
);
2338 return_value
->type
= IS_OBJECT
;
2339 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2342 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2347 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
2348 ZEND_ARG_INFO(0, query
)
2349 ZEND_ARG_INFO(0, callable
)
2350 ZEND_END_ARG_INFO();
2351 static PHP_METHOD(pqconn
, execAsync
) {
2352 zend_error_handling zeh
;
2353 php_pq_callback_t resolver
= {{0}};
2358 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2359 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
2360 zend_restore_error_handling(&zeh TSRMLS_CC
);
2362 if (SUCCESS
== rv
) {
2363 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2366 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2367 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
2368 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2369 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2370 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2372 obj
->intern
->poller
= PQconsumeInput
;
2373 php_pq_callback_dtor(&obj
->intern
->onevent
);
2374 if (resolver
.fci
.size
> 0) {
2375 obj
->intern
->onevent
= resolver
;
2376 php_pq_callback_addref(&obj
->intern
->onevent
);
2378 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2383 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
2388 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
2389 convert_to_long_ex(ztype
);
2392 **types
= Z_LVAL_PP(ztype
);
2395 if (*ztype
!= *(zval
**)p
) {
2396 zval_ptr_dtor(ztype
);
2398 return ZEND_HASH_APPLY_KEEP
;
2401 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
2407 params
= (char ***) va_arg(argv
, char ***);
2408 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
2410 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
2414 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
2415 convert_to_string_ex(zparam
);
2418 **params
= Z_STRVAL_PP(zparam
);
2421 if (*zparam
!= *(zval
**)p
) {
2422 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
2425 return ZEND_HASH_APPLY_KEEP
;
2428 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
2430 int count
= zend_hash_num_elements(ht
);
2437 /* +1 for when less types than params are specified */
2438 *types
= tmp
= ecalloc(count
+ 1, sizeof(**types
));
2439 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
2445 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
2447 int count
= zend_hash_num_elements(ht
);
2454 *params
= tmp
= ecalloc(count
, sizeof(char *));
2455 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
2461 static Oid *php_pq_ntypes_to_array(zend_bool fill, int argc, ...)
2464 Oid *oids = ecalloc(argc + 1, sizeof(*oids));
2467 va_start(argv, argc);
2468 for (i = 0; i < argc; ++i) {
2470 oids[i] = va_arg(argv, Oid);
2480 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
2481 ZEND_ARG_INFO(0, query
)
2482 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2483 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2484 ZEND_END_ARG_INFO();
2485 static PHP_METHOD(pqconn
, execParams
) {
2486 zend_error_handling zeh
;
2490 zval
*ztypes
= NULL
;
2493 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2494 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
2495 zend_restore_error_handling(&zeh TSRMLS_CC
);
2497 if (SUCCESS
== rv
) {
2498 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2501 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2506 char **params
= NULL
;
2509 ZEND_INIT_SYMTABLE(&zdtor
);
2510 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2513 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2516 res
= PQexecParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
2518 zend_hash_destroy(&zdtor
);
2527 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2529 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2530 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
2533 ZEND_INIT_SYMTABLE(&r
->bound
);
2534 return_value
->type
= IS_OBJECT
;
2535 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
2538 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2544 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
2545 ZEND_ARG_INFO(0, query
)
2546 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2547 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2548 ZEND_ARG_INFO(0, callable
)
2549 ZEND_END_ARG_INFO();
2550 static PHP_METHOD(pqconn
, execParamsAsync
) {
2551 zend_error_handling zeh
;
2552 php_pq_callback_t resolver
= {{0}};
2556 zval
*ztypes
= NULL
;
2559 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2560 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
2561 zend_restore_error_handling(&zeh TSRMLS_CC
);
2563 if (SUCCESS
== rv
) {
2564 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2567 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2571 char **params
= NULL
;
2574 ZEND_INIT_SYMTABLE(&zdtor
);
2575 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2578 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2581 if (!PQsendQueryParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
2582 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2583 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2584 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2586 obj
->intern
->poller
= PQconsumeInput
;
2587 php_pq_callback_dtor(&obj
->intern
->onevent
);
2588 if (resolver
.fci
.size
> 0) {
2589 obj
->intern
->onevent
= resolver
;
2590 php_pq_callback_addref(&obj
->intern
->onevent
);
2592 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2595 zend_hash_destroy(&zdtor
);
2604 zend_restore_error_handling(&zeh TSRMLS_CC
);
2607 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2615 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2619 count
= zend_hash_num_elements(typest
);
2620 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2623 res
= PQprepare(obj
->intern
->conn
, name
, query
, count
, types
);
2631 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2633 rv
= php_pqres_success(res TSRMLS_CC
);
2635 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2641 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
2642 ZEND_ARG_INFO(0, type
)
2643 ZEND_ARG_INFO(0, query
)
2644 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2645 ZEND_END_ARG_INFO();
2646 static PHP_METHOD(pqconn
, prepare
) {
2647 zend_error_handling zeh
;
2648 zval
*ztypes
= NULL
;
2649 char *name_str
, *query_str
;
2650 int name_len
, *query_len
;
2653 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2654 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2655 zend_restore_error_handling(&zeh TSRMLS_CC
);
2657 if (SUCCESS
== rv
) {
2658 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2661 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2662 } else if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2663 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2665 php_pq_object_addref(obj TSRMLS_CC
);
2667 stm
->name
= estrdup(name_str
);
2668 ZEND_INIT_SYMTABLE(&stm
->bound
);
2670 return_value
->type
= IS_OBJECT
;
2671 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2676 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2683 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2687 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2690 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, count
, types
)) {
2692 throw_exce(EX_IO TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2693 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2695 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2698 obj
->intern
->poller
= PQconsumeInput
;
2699 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2709 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
2710 ZEND_ARG_INFO(0, type
)
2711 ZEND_ARG_INFO(0, query
)
2712 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2713 ZEND_END_ARG_INFO();
2714 static PHP_METHOD(pqconn
, prepareAsync
) {
2715 zend_error_handling zeh
;
2716 zval
*ztypes
= NULL
;
2717 char *name_str
, *query_str
;
2718 int name_len
, *query_len
;
2721 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2722 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2723 zend_restore_error_handling(&zeh TSRMLS_CC
);
2725 if (SUCCESS
== rv
) {
2726 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2729 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2730 } else if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2731 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2733 php_pq_object_addref(obj TSRMLS_CC
);
2735 stm
->name
= estrdup(name_str
);
2736 ZEND_INIT_SYMTABLE(&stm
->bound
);
2738 return_value
->type
= IS_OBJECT
;
2739 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2744 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
2745 ZEND_ARG_INFO(0, string
)
2746 ZEND_END_ARG_INFO();
2747 static PHP_METHOD(pqconn
, quote
) {
2751 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2752 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2755 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2757 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
2760 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2763 RETVAL_STRING(quoted
, 1);
2770 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
2771 ZEND_ARG_INFO(0, type
)
2772 ZEND_END_ARG_INFO();
2773 static PHP_METHOD(pqconn
, quoteName
) {
2777 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2778 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2781 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2783 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
2786 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2789 RETVAL_STRING(quoted
, 1);
2796 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
2797 ZEND_ARG_INFO(0, bytea
)
2798 ZEND_END_ARG_INFO();
2799 static PHP_METHOD(pqconn
, escapeBytea
) {
2803 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2804 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2807 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2810 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
2813 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2816 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
2817 PQfreemem(escaped_str
);
2823 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
2824 ZEND_ARG_INFO(0, bytea
)
2825 ZEND_END_ARG_INFO();
2826 static PHP_METHOD(pqconn
, unescapeBytea
) {
2830 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2831 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2834 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2836 size_t unescaped_len
;
2837 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
2839 if (!unescaped_str
) {
2840 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2843 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
2844 PQfreemem(unescaped_str
);
2850 static const char *isolation_level(long *isolation
) {
2851 switch (*isolation
) {
2852 case PHP_PQTXN_SERIALIZABLE
:
2853 return "SERIALIZABLE";
2854 case PHP_PQTXN_REPEATABLE_READ
:
2855 return "REPEATABLE READ";
2857 *isolation
= PHP_PQTXN_READ_COMMITTED
;
2859 case PHP_PQTXN_READ_COMMITTED
:
2860 return "READ COMMITTED";
2864 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2866 STATUS rv
= FAILURE
;
2869 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2872 if (!conn_obj
->intern
) {
2873 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2876 smart_str cmd
= {0};
2877 const char *il
= isolation_level(&isolation
);
2879 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2880 smart_str_appends(&cmd
, il
);
2881 smart_str_appends(&cmd
, ", READ ");
2882 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2883 smart_str_appends(&cmd
, ",");
2884 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
2885 smart_str_appends(&cmd
, " DEFERRABLE");
2888 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
2891 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2893 rv
= php_pqres_success(res TSRMLS_CC
);
2895 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2898 smart_str_free(&cmd
);
2904 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
)
2906 STATUS rv
= FAILURE
;
2909 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2912 if (!conn_obj
->intern
) {
2913 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2915 smart_str cmd
= {0};
2916 const char *il
= isolation_level(&isolation
);
2918 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2919 smart_str_appends(&cmd
, il
);
2920 smart_str_appends(&cmd
, ", READ ");
2921 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2922 smart_str_appends(&cmd
, ",");
2923 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
2924 smart_str_appends(&cmd
, " DEFERRABLE");
2927 if (!PQsendQuery(conn_obj
->intern
->conn
, cmd
.c
)) {
2928 throw_exce(EX_IO TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2931 conn_obj
->intern
->poller
= PQconsumeInput
;
2932 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2935 smart_str_free(&cmd
);
2941 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
2942 ZEND_ARG_INFO(0, isolation
)
2943 ZEND_ARG_INFO(0, readonly
)
2944 ZEND_ARG_INFO(0, deferrable
)
2945 ZEND_END_ARG_INFO();
2946 static PHP_METHOD(pqconn
, startTransaction
) {
2947 zend_error_handling zeh
;
2948 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2949 zend_bool readonly
= 0, deferrable
= 0;
2952 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2953 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
2954 zend_restore_error_handling(&zeh TSRMLS_CC
);
2956 if (SUCCESS
== rv
) {
2957 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2959 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2961 if (SUCCESS
== rv
) {
2962 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2964 php_pq_object_addref(obj TSRMLS_CC
);
2967 txn
->isolation
= isolation
;
2968 txn
->readonly
= readonly
;
2969 txn
->deferrable
= deferrable
;
2971 return_value
->type
= IS_OBJECT
;
2972 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
2977 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
2978 ZEND_ARG_INFO(0, isolation
)
2979 ZEND_ARG_INFO(0, readonly
)
2980 ZEND_ARG_INFO(0, deferrable
)
2981 ZEND_END_ARG_INFO();
2982 static PHP_METHOD(pqconn
, startTransactionAsync
) {
2983 zend_error_handling zeh
;
2984 long isolation
= PHP_PQTXN_READ_COMMITTED
;
2985 zend_bool readonly
= 0, deferrable
= 0;
2988 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2989 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
2990 zend_restore_error_handling(&zeh TSRMLS_CC
);
2991 if (SUCCESS
== rv
) {
2992 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2994 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
2996 if (SUCCESS
== rv
) {
2997 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
2999 php_pq_object_addref(obj TSRMLS_CC
);
3001 txn
->isolation
= isolation
;
3002 txn
->readonly
= readonly
;
3003 txn
->deferrable
= deferrable
;
3005 return_value
->type
= IS_OBJECT
;
3006 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3011 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
3012 ZEND_ARG_INFO(0, stdio_stream
)
3013 ZEND_END_ARG_INFO();
3014 static PHP_METHOD(pqconn
, trace
) {
3015 zval
*zstream
= NULL
;
3017 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
3018 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3021 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3024 PQuntrace(obj
->intern
->conn
);
3028 php_stream
*stream
= NULL
;
3030 php_stream_from_zval(stream
, &zstream
);
3032 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
3035 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
3036 PQtrace(obj
->intern
->conn
, fp
);
3044 static zend_function_entry php_pqconn_methods
[] = {
3045 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3046 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
3047 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
3048 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
3049 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
3050 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
3051 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
3052 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
3053 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
3054 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
3055 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
3056 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
3057 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
3058 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
3059 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
3060 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
3061 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
3062 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
3063 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
3064 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
3065 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
3066 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
3070 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct
, 0, 0, 1)
3071 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3072 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3073 ZEND_END_ARG_INFO();
3074 static PHP_METHOD(pqtypes
, __construct
) {
3075 zend_error_handling zeh
;
3076 zval
*zconn
, *znsp
= NULL
;
3079 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3080 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|a!", &zconn
, php_pqconn_class_entry
, &znsp
);
3081 zend_restore_error_handling(&zeh TSRMLS_CC
);
3083 if (SUCCESS
== rv
) {
3084 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3086 if (!conn_obj
->intern
) {
3087 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3089 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3090 zval
*retval
= NULL
;
3092 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3093 obj
->intern
->conn
= conn_obj
;
3094 php_pq_object_addref(conn_obj TSRMLS_CC
);
3095 zend_hash_init(&obj
->intern
->types
, 300, NULL
, ZVAL_PTR_DTOR
, 0);
3098 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
, znsp
);
3100 zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
);
3104 zval_ptr_dtor(&retval
);
3110 #define PHP_PQ_TYPES_QUERY \
3111 "select t.oid, t.* " \
3112 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
3113 "where typisdefined " \
3115 #define PHP_PQ_OID_TEXT 25
3117 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh
, 0, 0, 0)
3118 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3119 ZEND_END_ARG_INFO();
3120 static PHP_METHOD(pqtypes
, refresh
) {
3121 HashTable
*nsp
= NULL
;
3122 zend_error_handling zeh
;
3125 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3126 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|H/!", &nsp
);
3127 zend_restore_error_handling(&zeh TSRMLS_CC
);
3129 if (SUCCESS
== rv
) {
3130 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3133 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Types not initialized");
3137 if (!nsp
|| !zend_hash_num_elements(nsp
)) {
3138 res
= PQexec(obj
->intern
->conn
->intern
->conn
, PHP_PQ_TYPES_QUERY
" and nspname in ('public', 'pg_catalog')");
3142 char **params
= NULL
;
3144 smart_str str
= {0};
3146 smart_str_appends(&str
, PHP_PQ_TYPES_QUERY
" and nspname in(");
3147 zend_hash_init(&zdtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
3148 count
= php_pq_params_to_array(nsp
, ¶ms
, &zdtor TSRMLS_CC
);
3149 oids
= ecalloc(count
+ 1, sizeof(*oids
));
3150 for (i
= 0; i
< count
; ++i
) {
3151 oids
[i
] = PHP_PQ_OID_TEXT
;
3153 smart_str_appendc(&str
, ',');
3155 smart_str_appendc(&str
, '$');
3156 smart_str_append_unsigned(&str
, i
+1);
3158 smart_str_appendc(&str
, ')');
3161 res
= PQexecParams(obj
->intern
->conn
->intern
->conn
, str
.c
, count
, oids
, (const char *const*) params
, NULL
, NULL
, 0);
3163 smart_str_free(&str
);
3166 zend_hash_destroy(&zdtor
);
3170 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3172 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3175 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
3176 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT
, NULL TSRMLS_CC
);
3177 long oid
= atol(PQgetvalue(res
, r
, 0 ));
3178 char *name
= PQgetvalue(res
, r
, 1);
3182 zend_hash_index_update(&obj
->intern
->types
, oid
, (void *) &row
, sizeof(zval
*), NULL
);
3183 zend_hash_add(&obj
->intern
->types
, name
, strlen(name
) + 1, (void *) &row
, sizeof(zval
*), NULL
);
3188 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3194 static zend_function_entry php_pqtypes_methods
[] = {
3195 PHP_ME(pqtypes
, __construct
, ai_pqtypes_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3196 PHP_ME(pqtypes
, refresh
, ai_pqtypes_refresh
, ZEND_ACC_PUBLIC
)
3200 static STATUS
php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type
, zval
***row TSRMLS_DC
)
3203 php_pqres_fetch_t orig_fetch
;
3206 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3209 if (!obj
->intern
->iter
) {
3210 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
3211 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3213 orig_fetch
= obj
->intern
->iter
->fetch_type
;
3214 obj
->intern
->iter
->fetch_type
= fetch_type
;
3215 if (SUCCESS
== (rv
= obj
->intern
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
))) {
3216 obj
->intern
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->intern
->iter
, row TSRMLS_CC
);
3217 obj
->intern
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3219 obj
->intern
->iter
->fetch_type
= orig_fetch
;
3224 typedef struct php_pqres_col
{
3229 static STATUS
column_nn(php_pqres_object_t
*obj
, zval
*zcol
, php_pqres_col_t
*col TSRMLS_DC
)
3234 switch (Z_TYPE_P(zcol
)) {
3236 convert_to_string(zcol
);
3240 if (!is_numeric_string(Z_STRVAL_P(zcol
), Z_STRLEN_P(zcol
), &index
, NULL
, 0)) {
3241 name
= Z_STRVAL_P(zcol
);
3246 index
= Z_LVAL_P(zcol
);
3252 col
->num
= PQfnumber(obj
->intern
->res
, name
);
3254 col
->name
= PQfname(obj
->intern
->res
, index
);
3259 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column at index %ld", index
);
3262 if (col
->num
== -1) {
3263 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column with name '%s'", name
);
3269 static int compare_index(const void *lptr
, const void *rptr TSRMLS_DC
)
3271 const Bucket
*l
= *(const Bucket
**) lptr
;
3272 const Bucket
*r
= *(const Bucket
**) rptr
;
3283 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind
, 0, 0, 2)
3284 ZEND_ARG_INFO(0, col
)
3285 ZEND_ARG_INFO(1, ref
)
3286 ZEND_END_ARG_INFO();
3287 static PHP_METHOD(pqres
, bind
) {
3290 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z/z", &zcol
, &zref
)) {
3291 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3294 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3296 php_pqres_col_t col
;
3298 if (SUCCESS
!= column_nn(obj
, zcol
, &col TSRMLS_CC
)) {
3303 if (SUCCESS
!= zend_hash_index_update(&obj
->intern
->bound
, col
.num
, (void *) &zref
, sizeof(zval
*), NULL
)) {
3304 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to bind column %s@%d", col
.name
, col
.num
);
3307 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3315 static int apply_bound(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3317 zval
**zvalue
, **zbound
= p
;
3318 zval
**zrow
= va_arg(argv
, zval
**);
3319 STATUS
*rv
= va_arg(argv
, STATUS
*);
3321 if (SUCCESS
!= zend_hash_index_find(Z_ARRVAL_PP(zrow
), key
->h
, (void *) &zvalue
)) {
3322 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column ad index %lu", key
->h
);
3324 return ZEND_HASH_APPLY_STOP
;
3327 ZVAL_COPY_VALUE(*zbound
, *zvalue
);
3329 zval_ptr_dtor(zvalue
);
3330 Z_ADDREF_P(*zbound
);
3333 return ZEND_HASH_APPLY_KEEP
;
3337 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound
, 0, 0, 0)
3338 ZEND_END_ARG_INFO();
3339 static PHP_METHOD(pqres
, fetchBound
) {
3340 zend_error_handling zeh
;
3343 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3344 rv
= zend_parse_parameters_none();
3345 zend_restore_error_handling(&zeh TSRMLS_CC
);
3347 if (SUCCESS
== rv
) {
3348 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3351 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3355 if (SUCCESS
== php_pqres_iteration(getThis(), obj
, PHP_PQRES_FETCH_ARRAY
, &row TSRMLS_CC
) && row
) {
3356 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3357 zend_hash_apply_with_arguments(&obj
->intern
->bound TSRMLS_CC
, apply_bound
, 2, row
, &rv
);
3358 zend_restore_error_handling(&zeh TSRMLS_CC
);
3360 if (SUCCESS
!= rv
) {
3363 RETVAL_ZVAL(*row
, 1, 0);
3370 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
3371 ZEND_ARG_INFO(0, fetch_type
)
3372 ZEND_END_ARG_INFO();
3373 static PHP_METHOD(pqres
, fetchRow
) {
3374 zend_error_handling zeh
;
3375 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3376 long fetch_type
= -1;
3379 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3380 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3381 zend_restore_error_handling(&zeh TSRMLS_CC
);
3383 if (SUCCESS
== rv
) {
3385 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3389 if (fetch_type
== -1) {
3390 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3393 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3394 php_pqres_iteration(getThis(), obj
, fetch_type
, &row TSRMLS_CC
);
3395 zend_restore_error_handling(&zeh TSRMLS_CC
);
3398 RETVAL_ZVAL(*row
, 1, 0);
3404 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
3407 HashTable
*ht
= HASH_OF(row
);
3408 int count
= zend_hash_num_elements(ht
);
3411 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
3413 zend_hash_internal_pointer_reset(ht
);
3415 zend_hash_move_forward(ht
);
3417 zend_hash_get_current_data(ht
, (void *) &data
);
3422 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
3423 ZEND_ARG_INFO(0, col_num
)
3424 ZEND_END_ARG_INFO();
3425 static PHP_METHOD(pqres
, fetchCol
) {
3426 zend_error_handling zeh
;
3430 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3431 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
);
3432 zend_restore_error_handling(&zeh TSRMLS_CC
);
3434 if (SUCCESS
== rv
) {
3435 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3438 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3442 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3443 php_pqres_iteration(getThis(), obj
, obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: 0, &row TSRMLS_CC
);
3445 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
3448 RETVAL_ZVAL(*col
, 1, 0);
3451 zend_restore_error_handling(&zeh TSRMLS_CC
);
3456 static int apply_to_col(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3459 php_pqres_object_t
*obj
= va_arg(argv
, php_pqres_object_t
*);
3460 php_pqres_col_t
*col
, **cols
= va_arg(argv
, php_pqres_col_t
**);
3461 STATUS
*rv
= va_arg(argv
, STATUS
*);
3465 if (SUCCESS
!= column_nn(obj
, *c
, col TSRMLS_CC
)) {
3467 return ZEND_HASH_APPLY_STOP
;
3471 return ZEND_HASH_APPLY_KEEP
;
3475 static php_pqres_col_t
*php_pqres_convert_to_cols(php_pqres_object_t
*obj
, HashTable
*ht TSRMLS_DC
)
3477 php_pqres_col_t
*tmp
, *cols
= ecalloc(zend_hash_num_elements(ht
), sizeof(*cols
));
3478 STATUS rv
= SUCCESS
;
3481 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_col
, 2, obj
, &tmp
, &rv
);
3483 if (SUCCESS
== rv
) {
3491 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map
, 0, 0, 0)
3492 ZEND_ARG_INFO(0, keys
)
3493 ZEND_ARG_INFO(0, vals
)
3494 ZEND_ARG_INFO(0, fetch_type
)
3495 ZEND_END_ARG_INFO();
3496 static PHP_METHOD(pqres
, map
) {
3497 zend_error_handling zeh
;
3498 zval
*zkeys
= 0, *zvals
= 0;
3499 long fetch_type
= -1;
3502 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3503 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z/!z/!l", &zkeys
, &zvals
, &fetch_type
);
3504 zend_restore_error_handling(&zeh TSRMLS_CC
);
3506 if (SUCCESS
== rv
) {
3507 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3510 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3513 php_pqres_col_t def
= {PQfname(obj
->intern
->res
, 0), 0}, *keys
= NULL
, *vals
= NULL
;
3516 convert_to_array(zkeys
);
3518 if ((ks
= zend_hash_num_elements(Z_ARRVAL_P(zkeys
)))) {
3519 keys
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zkeys
) TSRMLS_CC
);
3529 convert_to_array(zvals
);
3531 if ((vs
= zend_hash_num_elements(Z_ARRVAL_P(zvals
)))) {
3532 vals
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zvals
) TSRMLS_CC
);
3536 if (fetch_type
== -1) {
3537 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3544 switch (fetch_type
) {
3545 case PHP_PQRES_FETCH_ARRAY
:
3546 case PHP_PQRES_FETCH_ASSOC
:
3547 array_init(return_value
);
3549 case PHP_PQRES_FETCH_OBJECT
:
3550 object_init(return_value
);
3553 for (r
= 0, rows
= PQntuples(obj
->intern
->res
); r
< rows
; ++r
) {
3556 cur
= &return_value
;
3557 for (k
= 0; k
< ks
; ++k
) {
3558 char *key
= PQgetvalue(obj
->intern
->res
, r
, keys
[k
].num
);
3559 int len
= PQgetlength(obj
->intern
->res
, r
, keys
[k
].num
);
3561 if (SUCCESS
!= zend_symtable_find(HASH_OF(*cur
), key
, len
+ 1, (void *) &cur
)) {
3565 switch (fetch_type
) {
3566 case PHP_PQRES_FETCH_ARRAY
:
3567 case PHP_PQRES_FETCH_ASSOC
:
3570 case PHP_PQRES_FETCH_OBJECT
:
3574 if (SUCCESS
!= zend_symtable_update(HASH_OF(*cur
), key
, len
+ 1, (void *) &tmp
, sizeof(zval
*), (void *) &cur
)) {
3575 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create map");
3581 for (v
= 0; v
< vs
; ++v
) {
3582 char *val
= PQgetvalue(obj
->intern
->res
, r
, vals
[v
].num
);
3583 int len
= PQgetlength(obj
->intern
->res
, r
, vals
[v
].num
);
3585 switch (fetch_type
) {
3586 case PHP_PQRES_FETCH_ARRAY
:
3587 add_index_stringl(*cur
, vals
[v
].num
, val
, len
, 1);
3589 case PHP_PQRES_FETCH_ASSOC
:
3590 add_assoc_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3592 case PHP_PQRES_FETCH_OBJECT
:
3593 add_property_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3598 php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, cur TSRMLS_CC
);
3604 if (keys
&& keys
!= &def
) {
3614 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count
, 0, 0, 0)
3615 ZEND_END_ARG_INFO();
3616 static PHP_METHOD(pqres
, count
) {
3617 if (SUCCESS
== zend_parse_parameters_none()) {
3620 if (SUCCESS
!= php_pqres_count_elements(getThis(), &count TSRMLS_CC
)) {
3621 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3628 static zend_function_entry php_pqres_methods
[] = {
3629 PHP_ME(pqres
, bind
, ai_pqres_bind
, ZEND_ACC_PUBLIC
)
3630 PHP_ME(pqres
, fetchBound
, ai_pqres_fetch_bound
, ZEND_ACC_PUBLIC
)
3631 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
3632 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
3633 PHP_ME(pqres
, count
, ai_pqres_count
, ZEND_ACC_PUBLIC
)
3634 PHP_ME(pqres
, map
, ai_pqres_map
, ZEND_ACC_PUBLIC
)
3638 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
3639 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
3640 ZEND_ARG_INFO(0, type
)
3641 ZEND_ARG_INFO(0, query
)
3642 ZEND_ARG_ARRAY_INFO(0, types
, 1)
3643 ZEND_ARG_INFO(0, async
)
3644 ZEND_END_ARG_INFO();
3645 static PHP_METHOD(pqstm
, __construct
) {
3646 zend_error_handling zeh
;
3647 zval
*zconn
, *ztypes
= NULL
;
3648 char *name_str
, *query_str
;
3649 int name_len
, *query_len
;
3650 zend_bool async
= 0;
3653 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3654 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Oss|a/!b", &zconn
, php_pqconn_class_entry
, &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
, &async
);
3655 zend_restore_error_handling(&zeh TSRMLS_CC
);
3657 if (SUCCESS
== rv
) {
3658 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3659 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3661 if (!conn_obj
->intern
) {
3662 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3665 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3667 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3670 if (SUCCESS
== rv
) {
3671 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
3673 php_pq_object_addref(conn_obj TSRMLS_CC
);
3674 stm
->conn
= conn_obj
;
3675 stm
->name
= estrdup(name_str
);
3676 ZEND_INIT_SYMTABLE(&stm
->bound
);
3682 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind
, 0, 0, 2)
3683 ZEND_ARG_INFO(0, param_no
)
3684 ZEND_ARG_INFO(1, param_ref
)
3685 ZEND_END_ARG_INFO();
3686 static PHP_METHOD(pqstm
, bind
) {
3690 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "lz", ¶m_no
, ¶m_ref
)) {
3691 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3694 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3696 Z_ADDREF_P(param_ref
);
3697 zend_hash_index_update(&obj
->intern
->bound
, param_no
, (void *) ¶m_ref
, sizeof(zval
*), NULL
);
3698 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3703 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
3704 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3705 ZEND_END_ARG_INFO();
3706 static PHP_METHOD(pqstm
, exec
) {
3707 zend_error_handling zeh
;
3708 zval
*zparams
= NULL
;
3711 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3712 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
);
3713 zend_restore_error_handling(&zeh TSRMLS_CC
);
3715 if (SUCCESS
== rv
) {
3716 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3719 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3722 char **params
= NULL
;
3726 ZEND_INIT_SYMTABLE(&zdtor
);
3729 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3731 count
= php_pq_params_to_array(&obj
->intern
->bound
, ¶ms
, &zdtor TSRMLS_CC
);
3734 res
= PQexecPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
3739 zend_hash_destroy(&zdtor
);
3742 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3743 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3744 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
3747 ZEND_INIT_SYMTABLE(&r
->bound
);
3748 return_value
->type
= IS_OBJECT
;
3749 return_value
->value
.obj
= php_pqres_create_object_ex(php_pqres_class_entry
, r
, NULL TSRMLS_CC
);
3751 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3757 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
3758 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3759 ZEND_ARG_INFO(0, callable
)
3760 ZEND_END_ARG_INFO();
3761 static PHP_METHOD(pqstm
, execAsync
) {
3762 zend_error_handling zeh
;
3763 zval
*zparams
= NULL
;
3764 php_pq_callback_t resolver
= {{0}};
3767 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3768 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
);
3769 zend_restore_error_handling(&zeh TSRMLS_CC
);
3771 if (SUCCESS
== rv
) {
3772 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3775 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3778 char **params
= NULL
;
3782 ZEND_INIT_SYMTABLE(&zdtor
);
3783 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3786 if (!PQsendQueryPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
3787 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3788 } else if (obj
->intern
->conn
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
->intern
->conn
)) {
3789 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3791 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
3792 if (resolver
.fci
.size
> 0) {
3793 obj
->intern
->conn
->intern
->onevent
= resolver
;
3794 php_pq_callback_addref(&obj
->intern
->conn
->intern
->onevent
);
3796 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3803 zend_hash_destroy(&zdtor
);
3806 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3811 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
3812 ZEND_END_ARG_INFO();
3813 static PHP_METHOD(pqstm
, desc
) {
3814 zend_error_handling zeh
;
3817 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3818 rv
= zend_parse_parameters_none();
3819 zend_restore_error_handling(&zeh TSRMLS_CC
);
3821 if (SUCCESS
== rv
) {
3822 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3825 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3827 PGresult
*res
= PQdescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
);
3830 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3832 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3835 array_init(return_value
);
3836 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
3837 add_next_index_long(return_value
, PQparamtype(res
, p
));
3841 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3847 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async
, 0, 0, 0)
3848 ZEND_END_ARG_INFO();
3849 static PHP_METHOD(pqstm
, descAsync
) {
3850 zend_error_handling zeh
;
3853 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3854 rv
= zend_parse_parameters_none();
3855 zend_restore_error_handling(&zeh TSRMLS_CC
);
3857 if (SUCCESS
== rv
) {
3858 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3861 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3862 } else if (!PQsendDescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
)) {
3863 throw_exce(EX_IO TSRMLS_CC
, "Failed to describe statement: %s", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3865 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3866 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3871 static zend_function_entry php_pqstm_methods
[] = {
3872 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3873 PHP_ME(pqstm
, bind
, ai_pqstm_bind
, ZEND_ACC_PUBLIC
)
3874 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
3875 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
3876 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
3877 PHP_ME(pqstm
, descAsync
, ai_pqstm_desc_async
, ZEND_ACC_PUBLIC
)
3881 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
3882 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3883 ZEND_ARG_INFO(0, async
)
3884 ZEND_ARG_INFO(0, isolation
)
3885 ZEND_ARG_INFO(0, readonly
)
3886 ZEND_ARG_INFO(0, deferrable
)
3887 ZEND_END_ARG_INFO();
3888 static PHP_METHOD(pqtxn
, __construct
) {
3889 zend_error_handling zeh
;
3891 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3892 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
3895 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3896 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
);
3897 zend_restore_error_handling(&zeh TSRMLS_CC
);
3899 if (SUCCESS
== rv
) {
3900 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3902 if (!conn_obj
->intern
) {
3903 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3906 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3908 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3911 if (SUCCESS
== rv
) {
3912 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3914 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3916 php_pq_object_addref(conn_obj TSRMLS_CC
);
3917 obj
->intern
->conn
= conn_obj
;
3918 obj
->intern
->open
= 1;
3919 obj
->intern
->isolation
= isolation
;
3920 obj
->intern
->readonly
= readonly
;
3921 obj
->intern
->deferrable
= deferrable
;
3927 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint
, 0, 0, 0)
3928 ZEND_END_ARG_INFO();
3929 static PHP_METHOD(pqtxn
, savepoint
) {
3930 zend_error_handling zeh
;
3933 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3934 rv
= zend_parse_parameters_none();
3935 zend_restore_error_handling(&zeh TSRMLS_CC
);
3937 if (SUCCESS
== rv
) {
3938 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3941 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
3942 } else if (!obj
->intern
->open
) {
3943 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
3946 smart_str cmd
= {0};
3948 smart_str_appends(&cmd
, "SAVEPOINT \"");
3949 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
3950 smart_str_appends(&cmd
, "\"");
3953 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
3956 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3958 php_pqres_success(res TSRMLS_CC
);
3962 smart_str_free(&cmd
);
3967 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async
, 0, 0, 0)
3968 ZEND_END_ARG_INFO();
3969 static PHP_METHOD(pqtxn
, savepointAsync
) {
3970 zend_error_handling zeh
;
3973 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3974 rv
= zend_parse_parameters_none();
3975 zend_restore_error_handling(&zeh TSRMLS_CC
);
3977 if (SUCCESS
== rv
) {
3978 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3981 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
3982 } else if (!obj
->intern
->open
) {
3983 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
3985 smart_str cmd
= {0};
3987 smart_str_appends(&cmd
, "SAVEPOINT \"");
3988 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
3989 smart_str_appends(&cmd
, "\"");
3992 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
3993 throw_exce(EX_IO TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3996 smart_str_free(&cmd
);
4001 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
4002 ZEND_END_ARG_INFO();
4003 static PHP_METHOD(pqtxn
, commit
) {
4004 zend_error_handling zeh
;
4007 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4008 rv
= zend_parse_parameters_none();
4009 zend_restore_error_handling(&zeh TSRMLS_CC
);
4011 if (SUCCESS
== rv
) {
4012 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4015 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transacation not initialized");
4016 } else if (!obj
->intern
->open
) {
4017 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transacation already closed");
4020 smart_str cmd
= {0};
4022 if (!obj
->intern
->savepoint
) {
4023 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4025 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4026 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4027 smart_str_appends(&cmd
, "\"");
4030 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4034 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4036 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4038 obj
->intern
->open
= 0;
4044 smart_str_free(&cmd
);
4045 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4050 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
4051 ZEND_END_ARG_INFO();
4052 static PHP_METHOD(pqtxn
, commitAsync
) {
4053 zend_error_handling zeh
;
4056 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4057 rv
= zend_parse_parameters_none();
4058 zend_restore_error_handling(&zeh TSRMLS_CC
);
4060 if (SUCCESS
== rv
) {
4061 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4064 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4065 } else if (!obj
->intern
->open
) {
4066 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4069 smart_str cmd
= {0};
4071 if (!obj
->intern
->savepoint
) {
4072 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4074 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4075 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4076 smart_str_appends(&cmd
, "\"");
4079 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4083 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commmit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4086 obj
->intern
->open
= 0;
4088 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4089 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4092 smart_str_free(&cmd
);
4097 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
4098 ZEND_END_ARG_INFO();
4099 static PHP_METHOD(pqtxn
, rollback
) {
4100 zend_error_handling zeh
;
4103 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4104 rv
= zend_parse_parameters_none();
4105 zend_restore_error_handling(&zeh TSRMLS_CC
);
4107 if (SUCCESS
== rv
) {
4108 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4111 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4112 } else if (!obj
->intern
->open
) {
4113 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4116 smart_str cmd
= {0};
4118 if (!obj
->intern
->savepoint
) {
4119 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4121 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4122 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4123 smart_str_appends(&cmd
, "\"");
4126 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4130 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4132 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4134 obj
->intern
->open
= 0;
4140 smart_str_free(&cmd
);
4141 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4146 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
4147 ZEND_END_ARG_INFO();
4148 static PHP_METHOD(pqtxn
, rollbackAsync
) {
4149 zend_error_handling zeh
;
4152 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4153 rv
= zend_parse_parameters_none();
4154 zend_restore_error_handling(&zeh TSRMLS_CC
);
4156 if (SUCCESS
== rv
) {
4157 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4160 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4161 } else if (!obj
->intern
->open
) {
4162 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4165 smart_str cmd
= {0};
4167 if (!obj
->intern
->savepoint
) {
4168 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4170 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4171 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4172 smart_str_appends(&cmd
, "\"");
4175 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4179 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4182 obj
->intern
->open
= 0;
4184 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4187 smart_str_free(&cmd
);
4188 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4193 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot
, 0, 0, 0)
4194 ZEND_END_ARG_INFO();
4195 static PHP_METHOD(pqtxn
, exportSnapshot
) {
4196 zend_error_handling zeh
;
4199 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4200 rv
= zend_parse_parameters_none();
4201 zend_restore_error_handling(&zeh TSRMLS_CC
);
4203 if (SUCCESS
== rv
) {
4204 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4207 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4209 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()");
4212 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4214 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4215 RETVAL_STRING(PQgetvalue(res
, 0, 0), 1);
4221 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4226 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async
, 0, 0, 0)
4227 ZEND_END_ARG_INFO();
4228 static PHP_METHOD(pqtxn
, exportSnapshotAsync
) {
4229 zend_error_handling zeh
;
4232 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4233 rv
= zend_parse_parameters_none();
4234 zend_restore_error_handling(&zeh TSRMLS_CC
);
4236 if (SUCCESS
== rv
) {
4237 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4240 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4241 } else if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()")) {
4242 throw_exce(EX_IO TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4244 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4245 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4250 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot
, 0, 0, 1)
4251 ZEND_ARG_INFO(0, snapshot_id
)
4252 ZEND_END_ARG_INFO();
4253 static PHP_METHOD(pqtxn
, importSnapshot
) {
4254 zend_error_handling zeh
;
4259 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4260 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4261 zend_restore_error_handling(&zeh TSRMLS_CC
);
4263 if (SUCCESS
== rv
) {
4264 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4267 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4268 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4269 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4271 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4274 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4277 smart_str cmd
= {0};
4279 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4280 smart_str_appends(&cmd
, sid
);
4283 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4286 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4288 php_pqres_success(res TSRMLS_CC
);
4292 smart_str_free(&cmd
);
4293 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4299 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async
, 0, 0, 1)
4300 ZEND_ARG_INFO(0, snapshot_id
)
4301 ZEND_END_ARG_INFO();
4302 static PHP_METHOD(pqtxn
, importSnapshotAsync
) {
4303 zend_error_handling zeh
;
4308 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4309 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4310 zend_restore_error_handling(&zeh TSRMLS_CC
);
4312 if (SUCCESS
== rv
) {
4313 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4316 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4317 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4318 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4320 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4323 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4325 smart_str cmd
= {0};
4327 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4328 smart_str_appends(&cmd
, sid
);
4331 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4332 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4334 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4337 smart_str_free(&cmd
);
4338 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4344 static const char *strmode(long mode
)
4346 switch (mode
& (INV_READ
|INV_WRITE
)) {
4347 case INV_READ
|INV_WRITE
:
4358 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob
, 0, 0, 1)
4359 ZEND_ARG_INFO(0, oid
)
4360 ZEND_ARG_INFO(0, mode
)
4361 ZEND_END_ARG_INFO();
4362 static PHP_METHOD(pqtxn
, openLOB
) {
4363 zend_error_handling zeh
;
4364 long mode
= INV_WRITE
|INV_READ
, loid
;
4367 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4368 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &loid
, &mode
);
4369 zend_restore_error_handling(&zeh TSRMLS_CC
);
4371 if (SUCCESS
== rv
) {
4372 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4375 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4377 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4380 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%ld with mode '%s' (%s)", loid
, strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4382 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4386 php_pq_object_addref(obj TSRMLS_CC
);
4389 return_value
->type
= IS_OBJECT
;
4390 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4393 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4398 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob
, 0, 0, 0)
4399 ZEND_ARG_INFO(0, mode
)
4400 ZEND_END_ARG_INFO();
4401 static PHP_METHOD(pqtxn
, createLOB
) {
4402 zend_error_handling zeh
;
4403 long mode
= INV_WRITE
|INV_READ
;
4406 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4407 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &mode
);
4408 zend_restore_error_handling(&zeh TSRMLS_CC
);
4410 if (SUCCESS
== rv
) {
4411 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4414 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4416 Oid loid
= lo_creat(obj
->intern
->conn
->intern
->conn
, mode
);
4418 if (loid
== InvalidOid
) {
4419 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create large object with mode '%s' (%s)", strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4421 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4424 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%ld with mode '%s': %s", loid
, strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4426 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4430 php_pq_object_addref(obj TSRMLS_CC
);
4433 return_value
->type
= IS_OBJECT
;
4434 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4438 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4443 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob
, 0, 0, 1)
4444 ZEND_ARG_INFO(0, oid
)
4445 ZEND_END_ARG_INFO();
4446 static PHP_METHOD(pqtxn
, unlinkLOB
) {
4447 zend_error_handling zeh
;
4451 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4452 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &loid
);
4453 zend_restore_error_handling(&zeh TSRMLS_CC
);
4455 if (SUCCESS
== rv
) {
4456 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4459 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4461 int rc
= lo_unlink(obj
->intern
->conn
->intern
->conn
, loid
);
4464 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to unlink LOB (oid=%ld): %s", loid
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4467 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4472 static zend_function_entry php_pqtxn_methods
[] = {
4473 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4474 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
4475 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
4476 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
4477 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
4478 PHP_ME(pqtxn
, savepoint
, ai_pqtxn_savepoint
, ZEND_ACC_PUBLIC
)
4479 PHP_ME(pqtxn
, savepointAsync
, ai_pqtxn_savepoint_async
, ZEND_ACC_PUBLIC
)
4480 PHP_ME(pqtxn
, exportSnapshot
, ai_pqtxn_export_snapshot
, ZEND_ACC_PUBLIC
)
4481 PHP_ME(pqtxn
, exportSnapshotAsync
, ai_pqtxn_export_snapshot_async
, ZEND_ACC_PUBLIC
)
4482 PHP_ME(pqtxn
, importSnapshot
, ai_pqtxn_import_snapshot
, ZEND_ACC_PUBLIC
)
4483 PHP_ME(pqtxn
, importSnapshotAsync
, ai_pqtxn_import_snapshot_async
, ZEND_ACC_PUBLIC
)
4484 PHP_ME(pqtxn
, openLOB
, ai_pqtxn_open_lob
, ZEND_ACC_PUBLIC
)
4485 PHP_ME(pqtxn
, createLOB
, ai_pqtxn_create_lob
, ZEND_ACC_PUBLIC
)
4486 PHP_ME(pqtxn
, unlinkLOB
, ai_pqtxn_unlink_lob
, ZEND_ACC_PUBLIC
)
4490 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
4491 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4492 ZEND_END_ARG_INFO();
4493 static PHP_METHOD(pqcancel
, __construct
) {
4494 zend_error_handling zeh
;
4498 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4499 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
);
4500 zend_restore_error_handling(&zeh TSRMLS_CC
);
4502 if (SUCCESS
== rv
) {
4503 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4505 if (!conn_obj
->intern
) {
4506 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4508 PGcancel
*cancel
= PQgetCancel(conn_obj
->intern
->conn
);
4511 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
4513 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4515 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4516 obj
->intern
->cancel
= cancel
;
4517 php_pq_object_addref(conn_obj TSRMLS_CC
);
4518 obj
->intern
->conn
= conn_obj
;
4524 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
4525 ZEND_END_ARG_INFO();
4526 static PHP_METHOD(pqcancel
, cancel
) {
4527 zend_error_handling zeh
;
4530 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4531 rv
= zend_parse_parameters_none();
4532 zend_restore_error_handling(&zeh TSRMLS_CC
);
4534 if (SUCCESS
== rv
) {
4535 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4538 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Cancel not initialized");
4540 char err
[256] = {0};
4542 if (!PQcancel(obj
->intern
->cancel
, err
, sizeof(err
))) {
4543 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to request cancellation (%s)", err
);
4549 static zend_function_entry php_pqcancel_methods
[] = {
4550 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4551 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
4555 static void php_pqconn_add_eventhandler(zval
*zconn
, php_pqconn_object_t
*conn_obj
, const char *type_str
, size_t type_len
, zval
*zevent TSRMLS_DC
)
4559 if (SUCCESS
== zend_hash_find(&conn_obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
4561 add_next_index_zval(*evhs
, zevent
);
4568 add_next_index_zval(evh
, zevent
);
4569 zend_hash_add(&conn_obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(zval
*), NULL
);
4573 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_construct
, 0, 0, 3)
4574 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4575 ZEND_ARG_INFO(0, type
)
4576 ZEND_ARG_INFO(0, callable
)
4577 ZEND_END_ARG_INFO();
4578 static PHP_METHOD(pqevent
, __construct
) {
4579 zend_error_handling zeh
;
4583 php_pq_callback_t cb
;
4586 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4587 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Osf", &zconn
, php_pqconn_class_entry
, &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
4588 zend_restore_error_handling(&zeh TSRMLS_CC
);
4590 if (SUCCESS
== rv
) {
4591 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4593 if (!conn_obj
->intern
) {
4594 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4596 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4598 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4599 php_pq_callback_addref(&cb
);
4600 obj
->intern
->cb
= cb
;
4601 php_pq_object_addref(conn_obj TSRMLS_CC
);
4602 obj
->intern
->conn
= conn_obj
;
4603 obj
->intern
->type
= estrdup(type_str
);
4605 php_pqconn_add_eventhandler(zconn
, conn_obj
, type_str
, type_len
, getThis() TSRMLS_CC
);
4610 ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_trigger
, 0, 0, 1)
4611 ZEND_ARG_ARRAY_INFO(0, args
, 1)
4612 ZEND_END_ARG_INFO();
4613 static PHP_METHOD(pqevent
, trigger
) {
4614 zend_error_handling zeh
;
4618 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4619 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a/", &args
);
4620 zend_restore_error_handling(&zeh TSRMLS_CC
);
4622 if (SUCCESS
== rv
) {
4623 php_pqevent_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4626 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Event not initialized");
4630 if (SUCCESS
!= zend_fcall_info_call(&obj
->intern
->cb
.fci
, &obj
->intern
->cb
.fcc
, &rv
, args TSRMLS_CC
)) {
4631 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to trigger event");
4634 RETVAL_ZVAL(rv
, 0, 1);
4643 static zend_function_entry php_pqevent_methods
[] = {
4644 PHP_ME(pqevent
, __construct
, ai_pqevent_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4645 PHP_ME(pqevent
, trigger
, ai_pqevent_trigger
, ZEND_ACC_PUBLIC
)
4649 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct
, 0, 0, 1)
4650 ZEND_ARG_OBJ_INFO(0, transaction
, pq
\\Transaction
, 0)
4651 ZEND_ARG_INFO(0, oid
)
4652 ZEND_ARG_INFO(0, mode
)
4653 ZEND_END_ARG_INFO();
4654 static PHP_METHOD(pqlob
, __construct
) {
4655 zend_error_handling zeh
;
4657 long mode
= INV_WRITE
|INV_READ
, loid
= InvalidOid
;
4660 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4661 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|ll", &ztxn
, php_pqtxn_class_entry
, &loid
, &mode
);
4662 zend_restore_error_handling(&zeh TSRMLS_CC
);
4664 if (SUCCESS
== rv
) {
4665 php_pqtxn_object_t
*txn_obj
= zend_object_store_get_object(ztxn TSRMLS_CC
);
4667 if (!txn_obj
->intern
) {
4668 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4669 } else if (!txn_obj
->intern
->open
) {
4670 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transation already closed");
4672 if (loid
== InvalidOid
) {
4673 loid
= lo_creat(txn_obj
->intern
->conn
->intern
->conn
, mode
);
4676 if (loid
== InvalidOid
) {
4677 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create large object with mode '%s' (%s)", strmode(mode
), PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
));
4679 int lofd
= lo_open(txn_obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4682 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%ld with mode '%s' (%s)", loid
, strmode(mode
), PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
));
4684 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4686 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4687 obj
->intern
->lofd
= lofd
;
4688 obj
->intern
->loid
= loid
;
4689 php_pq_object_addref(txn_obj TSRMLS_CC
);
4690 obj
->intern
->txn
= txn_obj
;
4694 php_pqconn_notify_listeners(txn_obj
->intern
->conn TSRMLS_CC
);
4699 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write
, 0, 0, 1)
4700 ZEND_ARG_INFO(0, data
)
4701 ZEND_END_ARG_INFO();
4702 static PHP_METHOD(pqlob
, write
) {
4703 zend_error_handling zeh
;
4708 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4709 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4710 zend_restore_error_handling(&zeh TSRMLS_CC
);
4712 if (SUCCESS
== rv
) {
4713 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4716 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4718 int written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, data_str
, data_len
);
4721 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to write to LOB with oid=%ld (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4723 RETVAL_LONG(written
);
4726 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4731 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read
, 0, 0, 0)
4732 ZEND_ARG_INFO(0, length
)
4733 ZEND_ARG_INFO(1, read
)
4734 ZEND_END_ARG_INFO();
4735 static PHP_METHOD(pqlob
, read
) {
4736 zend_error_handling zeh
;
4737 long length
= 0x1000;
4741 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4742 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lz!", &length
, &zread
);
4743 zend_restore_error_handling(&zeh TSRMLS_CC
);
4745 if (SUCCESS
== rv
) {
4746 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4749 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4751 char *buffer
= emalloc(length
+ 1);
4752 int read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4756 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to read from LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4760 ZVAL_LONG(zread
, read
);
4762 buffer
[read
] = '\0';
4763 RETVAL_STRINGL(buffer
, read
, 0);
4766 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4771 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek
, 0, 0, 1)
4772 ZEND_ARG_INFO(0, offset
)
4773 ZEND_ARG_INFO(0, whence
)
4774 ZEND_END_ARG_INFO();
4775 static PHP_METHOD(pqlob
, seek
) {
4776 zend_error_handling zeh
;
4777 long offset
, whence
= SEEK_SET
;
4780 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4781 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &offset
, &whence
);
4782 zend_restore_error_handling(&zeh TSRMLS_CC
);
4784 if (SUCCESS
== rv
) {
4785 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4788 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4790 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4793 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to seek offset in LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4795 RETVAL_LONG(position
);
4798 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4803 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell
, 0, 0, 0)
4804 ZEND_END_ARG_INFO();
4805 static PHP_METHOD(pqlob
, tell
) {
4806 zend_error_handling zeh
;
4809 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4810 rv
= zend_parse_parameters_none();
4811 zend_restore_error_handling(&zeh TSRMLS_CC
);
4813 if (SUCCESS
== rv
) {
4814 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4817 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4819 int position
= lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
4822 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to tell offset in LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4824 RETVAL_LONG(position
);
4827 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4832 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate
, 0, 0, 0)
4833 ZEND_ARG_INFO(0, length
)
4834 ZEND_END_ARG_INFO();
4835 static PHP_METHOD(pqlob
, truncate
) {
4836 zend_error_handling zeh
;
4840 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4841 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &length
);
4842 zend_restore_error_handling(&zeh TSRMLS_CC
);
4844 if (SUCCESS
== rv
) {
4845 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4848 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4850 int rc
= lo_truncate(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, length
);
4853 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to truncate LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4856 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4861 static zend_function_entry php_pqlob_methods
[] = {
4862 PHP_ME(pqlob
, __construct
, ai_pqlob_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4863 PHP_ME(pqlob
, write
, ai_pqlob_write
, ZEND_ACC_PUBLIC
)
4864 PHP_ME(pqlob
, read
, ai_pqlob_read
, ZEND_ACC_PUBLIC
)
4865 PHP_ME(pqlob
, seek
, ai_pqlob_seek
, ZEND_ACC_PUBLIC
)
4866 PHP_ME(pqlob
, tell
, ai_pqlob_tell
, ZEND_ACC_PUBLIC
)
4867 PHP_ME(pqlob
, truncate
, ai_pqlob_truncate
, ZEND_ACC_PUBLIC
)
4871 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct
, 0, 0, 3)
4872 ZEND_ARG_OBJ_INFO(0, "connection", pq
\\Connection
, 0)
4873 ZEND_ARG_INFO(0, expression
)
4874 ZEND_ARG_INFO(0, direction
)
4875 ZEND_ARG_INFO(0, options
)
4876 ZEND_END_ARG_INFO();
4877 static PHP_METHOD(pqcopy
, __construct
) {
4878 zend_error_handling zeh
;
4880 char *expr_str
, *opt_str
= "";
4881 int expr_len
, opt_len
= 0;
4885 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4886 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "Osl|s", &zconn
, php_pqconn_class_entry
, &expr_str
, &expr_len
, &direction
, &opt_str
, &opt_len
);
4887 zend_restore_error_handling(&zeh TSRMLS_CC
);
4889 if (SUCCESS
== rv
) {
4890 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4892 if (!conn_obj
->intern
) {
4893 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4895 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4896 smart_str cmd
= {0};
4899 smart_str_appends(&cmd
, "COPY ");
4900 smart_str_appendl(&cmd
, expr_str
, expr_len
);
4902 switch (direction
) {
4903 case PHP_PQCOPY_FROM_STDIN
:
4904 smart_str_appends(&cmd
, " FROM STDIN ");
4906 case PHP_PQCOPY_TO_STDOUT
:
4907 smart_str_appends(&cmd
, " TO STDOUT ");
4910 throw_exce(EX_RUNTIME TSRMLS_CC
, "Invalid COPY direction, expected one of FROM_STDIN (%d) TO_STDOUT (%d), got %ld", PHP_PQCOPY_FROM_STDIN
, PHP_PQCOPY_TO_STDOUT
, direction
);
4911 smart_str_free(&cmd
);
4914 smart_str_appendl(&cmd
, opt_str
, opt_len
);
4917 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
4920 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4922 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4923 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4924 obj
->intern
->direction
= direction
;
4925 obj
->intern
->expression
= estrdup(expr_str
);
4926 obj
->intern
->options
= estrdup(opt_str
);
4927 obj
->intern
->conn
= conn_obj
;
4928 php_pq_object_addref(conn_obj TSRMLS_CC
);
4934 smart_str_free(&cmd
);
4935 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4940 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put
, 0, 0, 1)
4941 ZEND_ARG_INFO(0, data
)
4942 ZEND_END_ARG_INFO();
4943 static PHP_METHOD(pqcopy
, put
) {
4944 zend_error_handling zeh
;
4949 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4950 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4951 zend_restore_error_handling(&zeh TSRMLS_CC
);
4953 if (SUCCESS
== rv
) {
4954 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4957 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
4958 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
4959 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not initialized with FROM_STDIN");
4961 if (1 != PQputCopyData(obj
->intern
->conn
->intern
->conn
, data_str
, data_len
)) {
4962 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4964 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4969 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end
, 0, 0, 0)
4970 ZEND_ARG_INFO(0, error
)
4971 ZEND_END_ARG_INFO();
4972 static PHP_METHOD(pqcopy
, end
) {
4973 zend_error_handling zeh
;
4974 char *error_str
= NULL
;
4978 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4979 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &error_str
, &error_len
);
4980 zend_restore_error_handling(&zeh TSRMLS_CC
);
4982 if (SUCCESS
== rv
) {
4983 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4986 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY not intitialized");
4987 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
4988 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intitialized with FROM_STDIN");
4990 if (1 != PQputCopyEnd(obj
->intern
->conn
->intern
->conn
, error_str
)) {
4991 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4993 PGresult
*res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
4996 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4998 php_pqres_success(res TSRMLS_CC
);
5003 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5008 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get
, 0, 0, 1)
5009 ZEND_ARG_INFO(1, data
)
5010 ZEND_END_ARG_INFO();
5011 static PHP_METHOD(pqcopy
, get
) {
5012 zend_error_handling zeh
;
5016 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5017 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
);
5018 zend_restore_error_handling(&zeh TSRMLS_CC
);
5020 if (SUCCESS
== rv
) {
5021 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5024 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
5025 } else if (obj
->intern
->direction
!= PHP_PQCOPY_TO_STDOUT
) {
5026 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intialized with TO_STDOUT");
5029 char *buffer
= NULL
;
5030 int bytes
= PQgetCopyData(obj
->intern
->conn
->intern
->conn
, &buffer
, 0);
5034 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5038 res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
5041 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5043 php_pqres_success(res TSRMLS_CC
);
5052 ZVAL_STRINGL(zdata
, buffer
, bytes
, 1);
5054 ZVAL_EMPTY_STRING(zdata
);
5067 static zend_function_entry php_pqcopy_methods
[] = {
5068 PHP_ME(pqcopy
, __construct
, ai_pqcopy_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
5069 PHP_ME(pqcopy
, put
, ai_pqcopy_put
, ZEND_ACC_PUBLIC
)
5070 PHP_ME(pqcopy
, end
, ai_pqcopy_end
, ZEND_ACC_PUBLIC
)
5071 PHP_ME(pqcopy
, get
, ai_pqcopy_get
, ZEND_ACC_PUBLIC
)
5075 static zend_function_entry php_pqexc_methods
[] = {
5079 /* {{{ PHP_MINIT_FUNCTION
5081 static PHP_MINIT_FUNCTION(pq
)
5083 zend_class_entry ce
= {0};
5084 php_pq_object_prophandler_t ph
= {0};
5086 INIT_NS_CLASS_ENTRY(ce
, "pq", "Exception", php_pqexc_methods
);
5087 php_pqexc_interface_class_entry
= zend_register_internal_interface(&ce TSRMLS_CC
);
5089 memset(&ce
, 0, sizeof(ce
));
5090 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "Exception", php_pqexc_methods
);
5091 php_pqexc_default_class_entry
= zend_register_internal_class_ex(&ce
, zend_exception_get_default(TSRMLS_C
), "Exception" TSRMLS_CC
);
5092 zend_class_implements(php_pqexc_default_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5094 memset(&ce
, 0, sizeof(ce
));
5095 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "InvalidArgumentException", php_pqexc_methods
);
5096 php_pqexc_invalid_argument_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_InvalidArgumentException
, "InvalidArgumentException" TSRMLS_CC
);
5097 zend_class_implements(php_pqexc_invalid_argument_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5099 memset(&ce
, 0, sizeof(ce
));
5100 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "RuntimeException", php_pqexc_methods
);
5101 php_pqexc_runtime_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_RuntimeException
, "RuntimeException" TSRMLS_CC
);
5102 zend_class_implements(php_pqexc_runtime_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5104 memset(&ce
, 0, sizeof(ce
));
5105 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "BadMethodCallException", php_pqexc_methods
);
5106 php_pqexc_bad_methodcall_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_BadMethodCallException
, "BadMethodCallException" TSRMLS_CC
);
5107 zend_class_implements(php_pqexc_bad_methodcall_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5109 memset(&ce
, 0, sizeof(ce
));
5110 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "DomainException", php_pqexc_methods
);
5111 php_pqexc_domain_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_DomainException
, "DomainException" TSRMLS_CC
);
5112 zend_class_implements(php_pqexc_domain_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5113 zend_declare_property_null(php_pqexc_domain_class_entry
, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5115 memset(&ce
, 0, sizeof(ce
));
5116 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
5117 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5118 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
5120 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5121 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
5122 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
5123 php_pqconn_object_handlers
.clone_obj
= NULL
;
5124 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
5125 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5127 zend_hash_init(&php_pqconn_object_prophandlers
, 13, NULL
, NULL
, 1);
5129 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5130 ph
.read
= php_pqconn_object_read_status
;
5131 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5133 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5134 ph
.read
= php_pqconn_object_read_transaction_status
;
5135 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
5137 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5138 ph
.read
= NULL
; /* forward to std prophandler */
5139 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
5141 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5142 ph
.read
= php_pqconn_object_read_error_message
;
5143 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5145 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5146 ph
.read
= php_pqconn_object_read_busy
;
5147 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
5149 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5150 ph
.read
= php_pqconn_object_read_encoding
;
5151 ph
.write
= php_pqconn_object_write_encoding
;
5152 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
5155 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5156 ph
.read
= php_pqconn_object_read_unbuffered
;
5157 ph
.write
= php_pqconn_object_write_unbuffered
;
5158 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
5161 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5162 ph
.read
= php_pqconn_object_read_db
;
5163 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
5165 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5166 ph
.read
= php_pqconn_object_read_user
;
5167 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
5169 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5170 ph
.read
= php_pqconn_object_read_pass
;
5171 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
5173 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5174 ph
.read
= php_pqconn_object_read_host
;
5175 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
5177 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5178 ph
.read
= php_pqconn_object_read_port
;
5179 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
5181 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5182 ph
.read
= php_pqconn_object_read_options
;
5183 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5185 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
5186 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
5187 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
5188 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
5189 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
5190 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
5191 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
5192 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
5194 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
5195 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
5196 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
5197 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
5198 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
5200 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
5201 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
5202 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
5203 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
5205 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
5206 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
5207 memset(&ce
, 0, sizeof(ce
));
5208 INIT_NS_CLASS_ENTRY(ce
, "pq", "Types", php_pqtypes_methods
);
5209 php_pqtypes_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5210 php_pqtypes_class_entry
->create_object
= php_pqtypes_create_object
;
5212 memcpy(&php_pqtypes_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5213 php_pqtypes_object_handlers
.read_property
= php_pq_object_read_prop
;
5214 php_pqtypes_object_handlers
.write_property
= php_pq_object_write_prop
;
5215 php_pqtypes_object_handlers
.clone_obj
= NULL
;
5216 php_pqtypes_object_handlers
.get_property_ptr_ptr
= NULL
;
5217 php_pqtypes_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5218 php_pqtypes_object_handlers
.has_dimension
= php_pqtypes_object_has_dimension
;
5219 php_pqtypes_object_handlers
.read_dimension
= php_pqtypes_object_read_dimension
;
5220 php_pqtypes_object_handlers
.unset_dimension
= NULL
;
5221 php_pqtypes_object_handlers
.write_dimension
= NULL
;
5223 zend_hash_init(&php_pqtypes_object_prophandlers
, 1, NULL
, NULL
, 1);
5225 zend_declare_property_null(php_pqtypes_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5226 ph
.read
= php_pqtypes_object_read_connection
;
5227 zend_hash_add(&php_pqtypes_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5229 memset(&ce
, 0, sizeof(ce
));
5230 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
5231 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5232 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
5233 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
5234 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
5235 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 2, zend_ce_traversable
, spl_ce_Countable
);
5237 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5238 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
5239 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
5240 php_pqres_object_handlers
.clone_obj
= NULL
;
5241 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
5242 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5243 php_pqres_object_handlers
.count_elements
= php_pqres_count_elements
;
5245 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
5247 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5248 ph
.read
= php_pqres_object_read_status
;
5249 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5251 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5252 ph
.read
= php_pqres_object_read_status_message
;
5253 zend_hash_add(&php_pqres_object_prophandlers
, "statusMessage", sizeof("statusMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5255 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5256 ph
.read
= php_pqres_object_read_error_message
;
5257 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5259 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5260 ph
.read
= php_pqres_object_read_num_rows
;
5261 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
5263 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5264 ph
.read
= php_pqres_object_read_num_cols
;
5265 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
5267 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5268 ph
.read
= php_pqres_object_read_affected_rows
;
5269 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
5271 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5272 ph
.read
= php_pqres_object_read_fetch_type
;
5273 ph
.write
= php_pqres_object_write_fetch_type
;
5274 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
5277 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
5278 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
5279 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
5280 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
5281 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
5282 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
5283 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
5284 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
5285 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
5286 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
5288 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
5289 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
5290 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
5292 memset(&ce
, 0, sizeof(ce
));
5293 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
5294 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5295 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
5297 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5298 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
5299 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
5300 php_pqstm_object_handlers
.clone_obj
= NULL
;
5301 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
5302 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5304 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
5306 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5307 ph
.read
= php_pqstm_object_read_name
;
5308 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
5310 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5311 ph
.read
= php_pqstm_object_read_connection
;
5312 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5314 memset(&ce
, 0, sizeof(ce
));
5315 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
5316 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5317 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
5319 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5320 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
5321 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
5322 php_pqtxn_object_handlers
.clone_obj
= NULL
;
5323 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
5324 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5326 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
5328 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5329 ph
.read
= php_pqtxn_object_read_connection
;
5330 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5332 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5333 ph
.read
= php_pqtxn_object_read_isolation
;
5334 ph
.write
= php_pqtxn_object_write_isolation
;
5335 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
5337 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("readonly"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5338 ph
.read
= php_pqtxn_object_read_readonly
;
5339 ph
.write
= php_pqtxn_object_write_readonly
;
5340 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
5342 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5343 ph
.read
= php_pqtxn_object_read_deferrable
;
5344 ph
.write
= php_pqtxn_object_write_deferrable
;
5345 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
5348 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
5349 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
5350 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
5352 memset(&ce
, 0, sizeof(ce
));
5353 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
5354 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5355 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
5357 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5358 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
5359 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
5360 php_pqcancel_object_handlers
.clone_obj
= NULL
;
5361 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
5362 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5364 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
5366 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5367 ph
.read
= php_pqcancel_object_read_connection
;
5368 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5370 memset(&ce
, 0, sizeof(ce
));
5371 INIT_NS_CLASS_ENTRY(ce
, "pq", "Event", php_pqevent_methods
);
5372 php_pqevent_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5373 php_pqevent_class_entry
->create_object
= php_pqevent_create_object
;
5375 memcpy(&php_pqevent_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5376 php_pqevent_object_handlers
.read_property
= php_pq_object_read_prop
;
5377 php_pqevent_object_handlers
.write_property
= php_pq_object_write_prop
;
5378 php_pqevent_object_handlers
.clone_obj
= NULL
;
5379 php_pqevent_object_handlers
.get_property_ptr_ptr
= NULL
;
5380 php_pqevent_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5382 zend_hash_init(&php_pqevent_object_prophandlers
, 2, NULL
, NULL
, 1);
5384 zend_declare_property_null(php_pqevent_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5385 ph
.read
= php_pqevent_object_read_connection
;
5386 zend_hash_add(&php_pqevent_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5388 zend_declare_property_null(php_pqevent_class_entry
, ZEND_STRL("type"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5389 ph
.read
= php_pqevent_object_read_type
;
5390 zend_hash_add(&php_pqevent_object_prophandlers
, "type", sizeof("type"), (void *) &ph
, sizeof(ph
), NULL
);
5392 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
5393 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESULT"), ZEND_STRL("result") TSRMLS_CC
);
5394 zend_declare_class_constant_stringl(php_pqevent_class_entry
, ZEND_STRL("RESET"), ZEND_STRL("reset") TSRMLS_CC
);
5396 memset(&ce
, 0, sizeof(ce
));
5397 INIT_NS_CLASS_ENTRY(ce
, "pq", "LOB", php_pqlob_methods
);
5398 php_pqlob_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5399 php_pqlob_class_entry
->create_object
= php_pqlob_create_object
;
5401 memcpy(&php_pqlob_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5402 php_pqlob_object_handlers
.read_property
= php_pq_object_read_prop
;
5403 php_pqlob_object_handlers
.write_property
= php_pq_object_write_prop
;
5404 php_pqlob_object_handlers
.clone_obj
= NULL
;
5405 php_pqlob_object_handlers
.get_property_ptr_ptr
= NULL
;
5406 php_pqlob_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5408 zend_hash_init(&php_pqlob_object_prophandlers
, 2, NULL
, NULL
, 1);
5410 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5411 ph
.read
= php_pqlob_object_read_transaction
;
5412 zend_hash_add(&php_pqlob_object_prophandlers
, "transaction", sizeof("transaction"), (void *) &ph
, sizeof(ph
), NULL
);
5414 zend_declare_property_long(php_pqlob_class_entry
, ZEND_STRL("oid"), InvalidOid
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5415 ph
.read
= php_pqlob_object_read_oid
;
5416 zend_hash_add(&php_pqlob_object_prophandlers
, "oid", sizeof("oid"), (void *) &ph
, sizeof(ph
), NULL
);
5418 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC
);
5419 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("R"), INV_READ TSRMLS_CC
);
5420 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("W"), INV_WRITE TSRMLS_CC
);
5421 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("RW"), INV_READ
|INV_WRITE TSRMLS_CC
);
5423 memset(&ce
, 0, sizeof(ce
));
5424 INIT_NS_CLASS_ENTRY(ce
, "pq", "COPY", php_pqcopy_methods
);
5425 php_pqcopy_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5426 php_pqcopy_class_entry
->create_object
= php_pqcopy_create_object
;
5428 memcpy(&php_pqcopy_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5429 php_pqcopy_object_handlers
.read_property
= php_pq_object_read_prop
;
5430 php_pqcopy_object_handlers
.write_property
= php_pq_object_write_prop
;
5431 php_pqcopy_object_handlers
.clone_obj
= NULL
;
5432 php_pqcopy_object_handlers
.get_property_ptr_ptr
= NULL
;
5433 php_pqcopy_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5435 zend_hash_init(&php_pqcopy_object_prophandlers
, 4, NULL
, NULL
, 1);
5437 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5438 ph
.read
= php_pqcopy_object_read_connection
;
5439 zend_hash_add(&php_pqcopy_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5441 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5442 ph
.read
= php_pqcopy_object_read_expression
;
5443 zend_hash_add(&php_pqcopy_object_prophandlers
, "expression", sizeof("expression"), (void *) &ph
, sizeof(ph
), NULL
);
5445 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5446 ph
.read
= php_pqcopy_object_read_direction
;
5447 zend_hash_add(&php_pqcopy_object_prophandlers
, "direction", sizeof("direction"), (void *) &ph
, sizeof(ph
), NULL
);
5449 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5450 ph
.read
= php_pqcopy_object_read_options
;
5451 zend_hash_add(&php_pqcopy_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5453 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC
);
5454 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC
);
5456 php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops
, NULL
, NULL TSRMLS_CC
);
5459 REGISTER_INI_ENTRIES();
5465 /* {{{ PHP_MSHUTDOWN_FUNCTION
5467 static PHP_MSHUTDOWN_FUNCTION(pq
)
5469 /* uncomment this line if you have INI entries
5470 UNREGISTER_INI_ENTRIES();
5472 php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL
, 0 TSRMLS_CC
);
5477 /* {{{ PHP_MINFO_FUNCTION
5479 static PHP_MINFO_FUNCTION(pq
)
5481 #ifdef HAVE_PQLIBVERSION
5484 char libpq_version
[10] = "pre-9.1";
5486 php_info_print_table_start();
5487 php_info_print_table_header(2, "PQ Support", "enabled");
5488 php_info_print_table_row(2, "Extension Version", PHP_PQ_EXT_VERSION
);
5489 php_info_print_table_end();
5491 php_info_print_table_start();
5492 php_info_print_table_header(2, "Used Library", "Version");
5493 #ifdef HAVE_PQLIBVERSION
5494 libpq_v
= PQlibVersion();
5495 slprintf(libpq_version
, sizeof(libpq_version
), "%d.%d.%d", libpq_v
/10000%100, libpq_v
/100%100, libpq_v
%100);
5497 php_info_print_table_row(2, "libpq", libpq_version
);
5498 php_info_print_table_end();
5500 /* Remove comments if you have entries in php.ini
5501 DISPLAY_INI_ENTRIES();
5506 const zend_function_entry pq_functions
[] = {
5510 static zend_module_dep pq_module_deps
[] = {
5511 ZEND_MOD_REQUIRED("raphf")
5512 ZEND_MOD_REQUIRED("spl")
5516 /* {{{ pq_module_entry
5518 zend_module_entry pq_module_entry
= {
5519 STANDARD_MODULE_HEADER_EX
,
5526 NULL
,/*PHP_RINIT(pq),*/
5527 NULL
,/*PHP_RSHUTDOWN(pq),*/
5530 STANDARD_MODULE_PROPERTIES
5534 #ifdef COMPILE_DL_PQ
5544 * vim600: noet sw=4 ts=4 fdm=marker
5545 * vim<600: noet sw=4 ts=4