2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
17 #define SMART_STR_PREALLOC 256
20 #include <Zend/zend_interfaces.h>
21 #include <Zend/zend_exceptions.h>
22 #include <ext/standard/info.h>
23 #include <ext/standard/php_smart_str.h>
24 #include <ext/spl/spl_array.h>
25 #include <ext/spl/spl_exceptions.h>
26 #include <ext/raphf/php_raphf.h>
28 #include <libpq-events.h>
29 #include <libpq/libpq-fs.h>
34 typedef int STATUS
; /* SUCCESS/FAILURE */
36 static char *rtrim(char *e
) {
39 while (l
-- > 0 && e
[l
] == '\n') {
45 #define PHP_PQerrorMessage(c) rtrim(PQerrorMessage((c)))
46 #define PHP_PQresultErrorMessage(r) rtrim(PQresultErrorMessage((r)))
48 static int php_pqconn_event(PGEventId id
, void *e
, void *data
);
50 #define PHP_PQclear(_r) \
52 php_pqres_object_t *_o = PQresultInstanceData((_r), php_pqconn_event); \
54 php_pq_object_delref(_o TSRMLS_CC); \
61 ZEND_DECLARE_MODULE_GLOBALS(pq)
66 /* Remove comments and fill if you need to have entries in php.ini
68 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
69 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
74 /* {{{ php_pq_init_globals
76 /* Uncomment this function if you have INI entries
77 static void php_pq_init_globals(zend_pq_globals *pq_globals)
79 pq_globals->global_value = 0;
80 pq_globals->global_string = NULL;
85 static zend_class_entry
*php_pqconn_class_entry
;
86 static zend_class_entry
*php_pqtypes_class_entry
;
87 static zend_class_entry
*php_pqres_class_entry
;
88 static zend_class_entry
*php_pqstm_class_entry
;
89 static zend_class_entry
*php_pqtxn_class_entry
;
90 static zend_class_entry
*php_pqcancel_class_entry
;
91 static zend_class_entry
*php_pqlob_class_entry
;
92 static zend_class_entry
*php_pqcopy_class_entry
;
94 typedef enum php_pqexc_type
{
106 static zend_class_entry
*php_pqexc_interface_class_entry
;
107 static zend_class_entry
*php_pqexc_invalid_argument_class_entry
;
108 static zend_class_entry
*php_pqexc_runtime_class_entry
;
109 static zend_class_entry
*php_pqexc_bad_methodcall_class_entry
;
110 static zend_class_entry
*php_pqexc_domain_class_entry
;
112 static zend_class_entry
*exce(php_pqexc_type_t type
)
116 case EX_INVALID_ARGUMENT
:
117 return php_pqexc_invalid_argument_class_entry
;
119 case EX_CONNECTION_FAILED
:
122 return php_pqexc_runtime_class_entry
;
123 case EX_UNINITIALIZED
:
124 case EX_BAD_METHODCALL
:
125 return php_pqexc_bad_methodcall_class_entry
;
128 return php_pqexc_domain_class_entry
;
132 static zval
*throw_exce(php_pqexc_type_t type TSRMLS_DC
, const char *fmt
, ...)
139 vspprintf(&msg
, 0, fmt
, argv
);
142 zexc
= zend_throw_exception(exce(type
), msg
, type TSRMLS_CC
);
148 static zend_object_handlers php_pqconn_object_handlers
;
149 static zend_object_handlers php_pqtypes_object_handlers
;
150 static zend_object_handlers php_pqres_object_handlers
;
151 static zend_object_handlers php_pqstm_object_handlers
;
152 static zend_object_handlers php_pqtxn_object_handlers
;
153 static zend_object_handlers php_pqcancel_object_handlers
;
154 static zend_object_handlers php_pqlob_object_handlers
;
155 static zend_object_handlers php_pqcopy_object_handlers
;
157 typedef struct php_pq_callback
{
159 zend_fcall_info_cache fcc
;
163 typedef struct php_pq_object
{
165 zend_object_value zv
;
166 HashTable
*prophandler
;
170 #define PHP_PQCONN_ASYNC 0x01
171 #define PHP_PQCONN_PERSISTENT 0x02
173 typedef struct php_pqconn
{
175 int (*poller
)(PGconn
*);
176 php_resource_factory_t factory
;
178 HashTable eventhandlers
;
179 php_pq_callback_t onevent
;
180 unsigned unbuffered
:1;
183 typedef struct php_pqconn_object
{
185 zend_object_value zv
;
186 HashTable
*prophandler
;
187 php_pqconn_t
*intern
;
188 } php_pqconn_object_t
;
190 typedef struct php_pqtypes
{
192 php_pqconn_object_t
*conn
;
195 typedef struct php_pqtypes_object
{
197 zend_object_value zv
;
198 HashTable
*prophandler
;
199 php_pqtypes_t
*intern
;
200 } php_pqtypes_object_t
;
202 typedef struct php_pqconn_event_data
{
203 php_pqconn_object_t
*obj
;
207 } php_pqconn_event_data_t
;
209 typedef enum php_pqres_fetch
{
210 PHP_PQRES_FETCH_ARRAY
,
211 PHP_PQRES_FETCH_ASSOC
,
212 PHP_PQRES_FETCH_OBJECT
215 typedef struct php_pqres_iterator
{
216 zend_object_iterator zi
;
219 php_pqres_fetch_t fetch_type
;
220 } php_pqres_iterator_t
;
222 typedef struct php_pqres
{
224 php_pqres_iterator_t
*iter
;
228 typedef struct php_pqres_object
{
230 zend_object_value zv
;
231 HashTable
*prophandler
;
233 } php_pqres_object_t
;
235 typedef struct php_pqstm
{
236 php_pqconn_object_t
*conn
;
241 typedef struct php_pqstm_object
{
243 zend_object_value zv
;
244 HashTable
*prophandler
;
246 } php_pqstm_object_t
;
248 typedef enum php_pqtxn_isolation
{
249 PHP_PQTXN_READ_COMMITTED
,
250 PHP_PQTXN_REPEATABLE_READ
,
251 PHP_PQTXN_SERIALIZABLE
,
252 } php_pqtxn_isolation_t
;
254 typedef struct php_pqtxn
{
255 php_pqconn_object_t
*conn
;
256 php_pqtxn_isolation_t isolation
;
260 unsigned deferrable
:1;
263 typedef struct php_pqtxn_object
{
265 zend_object_value zv
;
266 HashTable
*prophandler
;
268 } php_pqtxn_object_t
;
270 typedef struct php_pqcancel
{
272 php_pqconn_object_t
*conn
;
275 typedef struct php_pqcancel_object
{
277 zend_object_value zv
;
278 HashTable
*prophandler
;
279 php_pqcancel_t
*intern
;
280 } php_pqcancel_object_t
;
282 typedef struct php_pqevent
{
283 php_pq_callback_t cb
;
288 typedef struct php_pqevent_object
{
290 zend_object_value zv
;
291 HashTable
*prophandler
;
292 php_pqevent_t
*intern
;
293 } php_pqevent_object_t
;
295 typedef struct php_pqlob
{
299 php_pqtxn_object_t
*txn
;
302 typedef struct php_pqlob_object
{
304 zend_object_value zv
;
305 HashTable
*prophandler
;
307 } php_pqlob_object_t
;
309 typedef enum php_pqcopy_direction
{
310 PHP_PQCOPY_FROM_STDIN
,
312 } php_pqcopy_direction_t
;
314 typedef enum php_pqcopy_status
{
318 } php_pqcopy_status_t
;
320 typedef struct php_pqcopy
{
321 php_pqcopy_direction_t direction
;
324 php_pqconn_object_t
*conn
;
327 typedef struct php_pqcopy_object
{
329 zend_object_value zv
;
330 HashTable
*prophandler
;
331 php_pqcopy_t
*intern
;
332 } php_pqcopy_object_t
;
334 static HashTable php_pqconn_object_prophandlers
;
335 static HashTable php_pqtypes_object_prophandlers
;
336 static HashTable php_pqres_object_prophandlers
;
337 static HashTable php_pqstm_object_prophandlers
;
338 static HashTable php_pqtxn_object_prophandlers
;
339 static HashTable php_pqcancel_object_prophandlers
;
340 static HashTable php_pqlob_object_prophandlers
;
341 static HashTable php_pqcopy_object_prophandlers
;
343 typedef void (*php_pq_object_prophandler_func_t
)(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
);
345 typedef struct php_pq_object_prophandler
{
346 php_pq_object_prophandler_func_t read
;
347 php_pq_object_prophandler_func_t write
;
348 } php_pq_object_prophandler_t
;
350 static zend_object_iterator_funcs php_pqres_iterator_funcs
;
352 static zend_object_iterator
*php_pqres_iterator_init(zend_class_entry
*ce
, zval
*object
, int by_ref TSRMLS_DC
)
354 php_pqres_iterator_t
*iter
;
355 zval
*prop
, *zfetch_type
;
357 iter
= ecalloc(1, sizeof(*iter
));
358 iter
->zi
.funcs
= &php_pqres_iterator_funcs
;
359 iter
->zi
.data
= object
;
362 zfetch_type
= prop
= zend_read_property(ce
, object
, ZEND_STRL("fetchType"), 0 TSRMLS_CC
);
363 if (Z_TYPE_P(zfetch_type
) != IS_LONG
) {
364 convert_to_long_ex(&zfetch_type
);
366 iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
367 if (zfetch_type
!= prop
) {
368 zval_ptr_dtor(&zfetch_type
);
370 if (Z_REFCOUNT_P(prop
)) {
371 zval_ptr_dtor(&prop
);
377 return (zend_object_iterator
*) iter
;
380 static void php_pqres_iterator_dtor(zend_object_iterator
*i TSRMLS_DC
)
382 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
384 if (iter
->current_val
) {
385 zval_ptr_dtor(&iter
->current_val
);
386 iter
->current_val
= NULL
;
388 zval_ptr_dtor((zval
**) &iter
->zi
.data
);
392 static STATUS
php_pqres_iterator_valid(zend_object_iterator
*i TSRMLS_DC
)
394 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
395 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
397 switch (PQresultStatus(obj
->intern
->res
)) {
398 case PGRES_TUPLES_OK
:
399 case PGRES_SINGLE_TUPLE
:
400 if (PQntuples(obj
->intern
->res
) <= iter
->index
) {
411 static zval
*php_pqres_row_to_zval(PGresult
*res
, unsigned row
, php_pqres_fetch_t fetch_type
, zval
**data_ptr TSRMLS_DC
)
421 if (PHP_PQRES_FETCH_OBJECT
== fetch_type
) {
431 if (PQntuples(res
) > row
) {
432 for (c
= 0, cols
= PQnfields(res
); c
< cols
; ++c
) {
433 if (PQgetisnull(res
, row
, c
)) {
434 switch (fetch_type
) {
435 case PHP_PQRES_FETCH_OBJECT
:
436 add_property_null(data
, PQfname(res
, c
));
439 case PHP_PQRES_FETCH_ASSOC
:
440 add_assoc_null(data
, PQfname(res
, c
));
443 case PHP_PQRES_FETCH_ARRAY
:
444 add_index_null(data
, c
);
448 char *val
= PQgetvalue(res
, row
, c
);
449 int len
= PQgetlength(res
, row
, c
);
451 switch (fetch_type
) {
452 case PHP_PQRES_FETCH_OBJECT
:
453 add_property_stringl(data
, PQfname(res
, c
), val
, len
, 1);
456 case PHP_PQRES_FETCH_ASSOC
:
457 add_assoc_stringl(data
, PQfname(res
, c
), val
, len
, 1);
460 case PHP_PQRES_FETCH_ARRAY
:
461 add_index_stringl(data
, c
, val
, len
,1);
471 static void php_pqres_iterator_current(zend_object_iterator
*i
, zval
***data_ptr TSRMLS_DC
)
473 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
474 php_pqres_object_t
*obj
= zend_object_store_get_object(iter
->zi
.data TSRMLS_CC
);
476 if (!iter
->current_val
) {
477 iter
->current_val
= php_pqres_row_to_zval(obj
->intern
->res
, iter
->index
, iter
->fetch_type
, NULL TSRMLS_CC
);
479 *data_ptr
= &iter
->current_val
;
482 static int php_pqres_iterator_key(zend_object_iterator
*i
, char **key_str
, uint
*key_len
, ulong
*key_num TSRMLS_DC
)
484 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
486 *key_num
= (ulong
) iter
->index
;
488 return HASH_KEY_IS_LONG
;
491 static void php_pqres_iterator_invalidate(zend_object_iterator
*i TSRMLS_DC
)
493 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
495 if (iter
->current_val
) {
496 zval_ptr_dtor(&iter
->current_val
);
497 iter
->current_val
= NULL
;
501 static void php_pqres_iterator_next(zend_object_iterator
*i TSRMLS_DC
)
503 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
505 php_pqres_iterator_invalidate(i TSRMLS_CC
);
509 static void php_pqres_iterator_rewind(zend_object_iterator
*i TSRMLS_DC
)
511 php_pqres_iterator_t
*iter
= (php_pqres_iterator_t
*) i
;
513 php_pqres_iterator_invalidate(i TSRMLS_CC
);
517 static zend_object_iterator_funcs php_pqres_iterator_funcs
= {
518 php_pqres_iterator_dtor
,
519 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
520 php_pqres_iterator_valid
,
521 /* fetch the item data for the current element */
522 php_pqres_iterator_current
,
523 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
524 php_pqres_iterator_key
,
525 /* step forwards to next element */
526 php_pqres_iterator_next
,
527 /* rewind to start of data (optional, may be NULL) */
528 php_pqres_iterator_rewind
,
529 /* invalidate current value/key (optional, may be NULL) */
530 php_pqres_iterator_invalidate
533 static int php_pqres_count_elements(zval
*object
, long *count TSRMLS_DC
)
535 php_pqres_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
540 *count
= (long) PQntuples(obj
->intern
->res
);
545 static STATUS
php_pqres_success(PGresult
*res TSRMLS_DC
)
549 switch (PQresultStatus(res
)) {
550 case PGRES_BAD_RESPONSE
:
551 case PGRES_NONFATAL_ERROR
:
552 case PGRES_FATAL_ERROR
:
553 zexc
= throw_exce(EX_SQL TSRMLS_CC
, "%s", PHP_PQresultErrorMessage(res
));
554 zend_update_property_string(php_pqexc_domain_class_entry
, zexc
, ZEND_STRL("sqlstate"), PQresultErrorField(res
, PG_DIAG_SQLSTATE
) TSRMLS_CC
);
561 static void php_pq_callback_dtor(php_pq_callback_t
*cb
) {
562 if (cb
->fci
.size
> 0) {
563 zend_fcall_info_args_clear(&cb
->fci
, 1);
564 zval_ptr_dtor(&cb
->fci
.function_name
);
565 if (cb
->fci
.object_ptr
) {
566 zval_ptr_dtor(&cb
->fci
.object_ptr
);
572 static void php_pq_callback_addref(php_pq_callback_t
*cb
)
574 Z_ADDREF_P(cb
->fci
.function_name
);
575 if (cb
->fci
.object_ptr
) {
576 Z_ADDREF_P(cb
->fci
.object_ptr
);
581 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC)
585 if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
586 zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
591 static ulong
php_pqconn_add_eventhandler(php_pqconn_object_t
*obj
, const char *type_str
, size_t type_len
, php_pq_callback_t
*cb TSRMLS_DC
)
596 if (SUCCESS
!= zend_hash_find(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
599 zend_hash_init(&evh
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
600 zend_hash_add(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(evh
), (void *) &evhs
);
603 php_pq_callback_addref(cb
);
604 h
= zend_hash_next_free_element(evhs
);
605 zend_hash_index_update(evhs
, h
, (void *) cb
, sizeof(*cb
), NULL
);
610 static void php_pq_object_to_zval(void *o
, zval
**zv TSRMLS_DC
)
612 php_pq_object_t
*obj
= o
;
618 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
620 (*zv
)->type
= IS_OBJECT
;
621 (*zv
)->value
.obj
= obj
->zv
;
624 static void php_pq_object_to_zval_no_addref(void *o
, zval
**zv TSRMLS_DC
)
626 php_pq_object_t
*obj
= o
;
634 (*zv
)->type
= IS_OBJECT
;
635 (*zv
)->value
.obj
= obj
->zv
;
638 static void php_pq_object_addref(void *o TSRMLS_DC
)
640 php_pq_object_t
*obj
= o
;
641 zend_objects_store_add_ref_by_handle(obj
->zv
.handle TSRMLS_CC
);
644 static void php_pq_object_delref(void *o TSRMLS_DC
)
646 php_pq_object_t
*obj
= o
;
647 zend_objects_store_del_ref_by_handle_ex(obj
->zv
.handle
, obj
->zv
.handlers TSRMLS_CC
);
650 static void php_pqconn_object_free(void *o TSRMLS_DC
)
652 php_pqconn_object_t
*obj
= o
;
654 fprintf(stderr
, "FREE conn(#%d) %p\n", obj
->zv
.handle
, obj
);
657 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
658 php_resource_factory_dtor(&obj
->intern
->factory
);
659 php_pq_callback_dtor(&obj
->intern
->onevent
);
660 zend_hash_destroy(&obj
->intern
->listeners
);
661 zend_hash_destroy(&obj
->intern
->eventhandlers
);
665 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
669 static void php_pqtypes_object_free(void *o TSRMLS_DC
)
671 php_pqtypes_object_t
*obj
= o
;
673 fprintf(stderr
, "FREE types(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
676 zend_hash_destroy(&obj
->intern
->types
);
677 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
681 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
685 static void php_pqres_object_free(void *o TSRMLS_DC
)
687 php_pqres_object_t
*obj
= o
;
689 fprintf(stderr
, "FREE res(#%d) %p\n", obj
->zv
.handle
, obj
);
692 if (obj
->intern
->res
) {
693 PQresultSetInstanceData(obj
->intern
->res
, php_pqconn_event
, NULL
);
694 PQclear(obj
->intern
->res
);
695 obj
->intern
->res
= NULL
;
698 if (obj
->intern
->iter
) {
699 php_pqres_iterator_dtor((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
700 obj
->intern
->iter
= NULL
;
703 zend_hash_destroy(&obj
->intern
->bound
);
708 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
712 static void php_pqstm_object_free(void *o TSRMLS_DC
)
714 php_pqstm_object_t
*obj
= o
;
716 fprintf(stderr
, "FREE stm(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
719 char *quoted_name
= PQescapeIdentifier(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, strlen(obj
->intern
->name
));
721 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
727 smart_str_appends(&cmd
, "DEALLOCATE ");
728 smart_str_appends(&cmd
, quoted_name
);
730 PQfreemem(quoted_name
);
732 if ((res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
))) {
735 smart_str_free(&cmd
);
738 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
739 efree(obj
->intern
->name
);
740 zend_hash_destroy(&obj
->intern
->bound
);
744 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
748 static void php_pqtxn_object_free(void *o TSRMLS_DC
)
750 php_pqtxn_object_t
*obj
= o
;
752 fprintf(stderr
, "FREE txn(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
755 if (obj
->intern
->open
) {
756 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
762 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
766 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
770 static void php_pqcancel_object_free(void *o TSRMLS_DC
)
772 php_pqcancel_object_t
*obj
= o
;
774 fprintf(stderr
, "FREE cancel(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
777 PQfreeCancel(obj
->intern
->cancel
);
778 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
782 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
786 static void php_pqlob_object_free(void *o TSRMLS_DC
)
788 php_pqlob_object_t
*obj
= o
;
790 fprintf(stderr
, "FREE lob(#%d) %p (txn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->txn
->zv
.handle
, obj
->intern
->txn
);
793 if (obj
->intern
->lofd
) {
794 lo_close(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
796 /* invalidate the stream */
797 if (obj
->intern
->stream
) {
798 zend_list_delete(obj
->intern
->stream
);
799 obj
->intern
->stream
= 0;
801 php_pq_object_delref(obj
->intern
->txn TSRMLS_CC
);
805 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
809 static void php_pqcopy_object_free(void *o TSRMLS_DC
)
811 php_pqcopy_object_t
*obj
= o
;
813 fprintf(stderr
, "FREE copy(#%d) %p (conn(#%d): %p)\n", obj
->zv
.handle
, obj
, obj
->intern
->conn
->zv
.handle
, obj
->intern
->conn
);
816 efree(obj
->intern
->expression
);
817 efree(obj
->intern
->options
);
818 php_pq_object_delref(obj
->intern
->conn TSRMLS_CC
);
822 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
826 static zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
828 php_pqconn_object_t
*o
;
830 o
= ecalloc(1, sizeof(*o
));
831 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
832 object_properties_init((zend_object
*) o
, ce
);
833 o
->prophandler
= &php_pqconn_object_prophandlers
;
843 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
844 o
->zv
.handlers
= &php_pqconn_object_handlers
;
849 static zend_object_value
php_pqtypes_create_object_ex(zend_class_entry
*ce
, php_pqtypes_t
*intern
, php_pqtypes_object_t
**ptr TSRMLS_DC
)
851 php_pqtypes_object_t
*o
;
853 o
= ecalloc(1, sizeof(*o
));
854 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
855 object_properties_init((zend_object
*) o
, ce
);
856 o
->prophandler
= &php_pqtypes_object_prophandlers
;
866 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtypes_object_free
, NULL TSRMLS_CC
);
867 o
->zv
.handlers
= &php_pqtypes_object_handlers
;
872 static zend_object_value
php_pqres_create_object_ex(zend_class_entry
*ce
, php_pqres_t
*intern
, php_pqres_object_t
**ptr TSRMLS_DC
)
874 php_pqres_object_t
*o
;
876 o
= ecalloc(1, sizeof(*o
));
877 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
878 object_properties_init((zend_object
*) o
, ce
);
879 o
->prophandler
= &php_pqres_object_prophandlers
;
889 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqres_object_free
, NULL TSRMLS_CC
);
890 o
->zv
.handlers
= &php_pqres_object_handlers
;
895 static zend_object_value
php_pqstm_create_object_ex(zend_class_entry
*ce
, php_pqstm_t
*intern
, php_pqstm_object_t
**ptr TSRMLS_DC
)
897 php_pqstm_object_t
*o
;
899 o
= ecalloc(1, sizeof(*o
));
900 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
901 object_properties_init((zend_object
*) o
, ce
);
902 o
->prophandler
= &php_pqstm_object_prophandlers
;
912 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqstm_object_free
, NULL TSRMLS_CC
);
913 o
->zv
.handlers
= &php_pqstm_object_handlers
;
918 static zend_object_value
php_pqtxn_create_object_ex(zend_class_entry
*ce
, php_pqtxn_t
*intern
, php_pqtxn_object_t
**ptr TSRMLS_DC
)
920 php_pqtxn_object_t
*o
;
922 o
= ecalloc(1, sizeof(*o
));
923 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
924 object_properties_init((zend_object
*) o
, ce
);
925 o
->prophandler
= &php_pqtxn_object_prophandlers
;
935 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqtxn_object_free
, NULL TSRMLS_CC
);
936 o
->zv
.handlers
= &php_pqtxn_object_handlers
;
941 static zend_object_value
php_pqcancel_create_object_ex(zend_class_entry
*ce
, php_pqcancel_t
*intern
, php_pqcancel_object_t
**ptr TSRMLS_DC
)
943 php_pqcancel_object_t
*o
;
945 o
= ecalloc(1, sizeof(*o
));
946 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
947 object_properties_init((zend_object
*) o
, ce
);
948 o
->prophandler
= &php_pqcancel_object_prophandlers
;
958 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcancel_object_free
, NULL TSRMLS_CC
);
959 o
->zv
.handlers
= &php_pqcancel_object_handlers
;
964 static zend_object_value
php_pqlob_create_object_ex(zend_class_entry
*ce
, php_pqlob_t
*intern
, php_pqlob_object_t
**ptr TSRMLS_DC
)
966 php_pqlob_object_t
*o
;
968 o
= ecalloc(1, sizeof(*o
));
969 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
970 object_properties_init((zend_object
*) o
, ce
);
971 o
->prophandler
= &php_pqlob_object_prophandlers
;
981 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqlob_object_free
, NULL TSRMLS_CC
);
982 o
->zv
.handlers
= &php_pqlob_object_handlers
;
987 static zend_object_value
php_pqcopy_create_object_ex(zend_class_entry
*ce
, php_pqcopy_t
*intern
, php_pqcopy_object_t
**ptr TSRMLS_DC
)
989 php_pqcopy_object_t
*o
;
991 o
= ecalloc(1, sizeof(*o
));
992 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
993 object_properties_init((zend_object
*) o
, ce
);
994 o
->prophandler
= &php_pqcopy_object_prophandlers
;
1004 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqcopy_object_free
, NULL TSRMLS_CC
);
1005 o
->zv
.handlers
= &php_pqcopy_object_handlers
;
1010 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1012 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1015 static zend_object_value
php_pqtypes_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1017 return php_pqtypes_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1020 static zend_object_value
php_pqres_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1022 return php_pqres_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1025 static zend_object_value
php_pqstm_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1027 return php_pqstm_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1030 static zend_object_value
php_pqtxn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1032 return php_pqtxn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1035 static zend_object_value
php_pqcancel_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1037 return php_pqcancel_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1040 static zend_object_value
php_pqlob_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1042 return php_pqlob_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1045 static zend_object_value
php_pqcopy_create_object(zend_class_entry
*class_type TSRMLS_DC
)
1047 return php_pqcopy_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
1050 static int apply_pi_to_ht(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1052 zend_property_info
*pi
= p
;
1053 HashTable
*ht
= va_arg(argv
, HashTable
*);
1054 zval
*object
= va_arg(argv
, zval
*);
1055 php_pq_object_t
*obj
= va_arg(argv
, php_pq_object_t
*);
1056 int addref
= va_arg(argv
, int);
1057 zval
*property
= zend_read_property(obj
->zo
.ce
, object
, pi
->name
, pi
->name_length
, 0 TSRMLS_CC
);
1060 Z_ADDREF_P(property
);
1062 zend_hash_add(ht
, pi
->name
, pi
->name_length
+ 1, (void *) &property
, sizeof(zval
*), NULL
);
1064 return ZEND_HASH_APPLY_KEEP
;
1067 static HashTable
*php_pq_object_debug_info(zval
*object
, int *temp TSRMLS_DC
)
1070 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1073 ALLOC_HASHTABLE(ht
);
1074 ZEND_INIT_SYMTABLE(ht
);
1076 zend_hash_apply_with_arguments(&obj
->zo
.ce
->properties_info TSRMLS_CC
, apply_pi_to_ht
, 4, ht
, object
, obj
, 1);
1081 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1083 php_pqconn_object_t
*obj
= o
;
1085 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
1088 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1090 php_pqconn_object_t
*obj
= o
;
1092 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
1095 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1097 php_pqconn_object_t
*obj
= o
;
1098 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
1101 RETVAL_STRING(error
, 1);
1107 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
1109 php_pq_callback_t
*listener
= p
;
1110 PGnotify
*nfy
= arg
;
1111 zval
*zpid
, *zchannel
, *zmessage
;
1113 MAKE_STD_ZVAL(zpid
);
1114 ZVAL_LONG(zpid
, nfy
->be_pid
);
1115 MAKE_STD_ZVAL(zchannel
);
1116 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
1117 MAKE_STD_ZVAL(zmessage
);
1118 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
1120 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
1121 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
1123 zval_ptr_dtor(&zchannel
);
1124 zval_ptr_dtor(&zmessage
);
1125 zval_ptr_dtor(&zpid
);
1127 return ZEND_HASH_APPLY_KEEP
;
1130 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1132 HashTable
*listeners
= p
;
1133 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
1135 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
1136 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
1139 return ZEND_HASH_APPLY_KEEP
;
1142 static void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
1146 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
1147 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
1152 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1154 php_pqconn_object_t
*obj
= o
;
1156 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
1159 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1161 php_pqconn_object_t
*obj
= o
;
1163 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
1166 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1168 php_pqconn_object_t
*obj
= o
;
1171 if (Z_TYPE_P(value
) != IS_STRING
) {
1172 if (Z_REFCOUNT_P(value
) > 1) {
1175 ZVAL_ZVAL(tmp
, zenc
, 1, 0);
1176 convert_to_string(tmp
);
1179 convert_to_string_ex(&zenc
);
1183 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
1184 zend_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
1187 if (zenc
!= value
) {
1188 zval_ptr_dtor(&zenc
);
1192 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1194 php_pqconn_object_t
*obj
= o
;
1196 RETVAL_BOOL(obj
->intern
->unbuffered
);
1199 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1201 php_pqconn_object_t
*obj
= o
;
1203 obj
->intern
->unbuffered
= zend_is_true(value
);
1206 static void php_pqconn_object_read_db(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1208 php_pqconn_object_t
*obj
= o
;
1209 char *db
= PQdb(obj
->intern
->conn
);
1212 RETVAL_STRING(db
, 1);
1214 RETVAL_EMPTY_STRING();
1218 static void php_pqconn_object_read_user(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1220 php_pqconn_object_t
*obj
= o
;
1221 char *user
= PQuser(obj
->intern
->conn
);
1224 RETVAL_STRING(user
, 1);
1226 RETVAL_EMPTY_STRING();
1230 static void php_pqconn_object_read_pass(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1232 php_pqconn_object_t
*obj
= o
;
1233 char *pass
= PQpass(obj
->intern
->conn
);
1236 RETVAL_STRING(pass
, 1);
1238 RETVAL_EMPTY_STRING();
1242 static void php_pqconn_object_read_host(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1244 php_pqconn_object_t
*obj
= o
;
1245 char *host
= PQhost(obj
->intern
->conn
);
1248 RETVAL_STRING(host
, 1);
1250 RETVAL_EMPTY_STRING();
1254 static void php_pqconn_object_read_port(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1256 php_pqconn_object_t
*obj
= o
;
1257 char *port
= PQport(obj
->intern
->conn
);
1260 RETVAL_STRING(port
, 1);
1262 RETVAL_EMPTY_STRING();
1266 static void php_pqconn_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1268 php_pqconn_object_t
*obj
= o
;
1269 char *options
= PQoptions(obj
->intern
->conn
);
1272 RETVAL_STRING(options
, 1);
1274 RETVAL_EMPTY_STRING();
1278 static void php_pqconn_object_read_event_handlers(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1280 php_pqconn_object_t
*obj
= o
;
1282 array_init(return_value
);
1283 zend_hash_copy(Z_ARRVAL_P(return_value
), &obj
->intern
->eventhandlers
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
1286 static void php_pqtypes_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1288 php_pqtypes_object_t
*obj
= o
;
1290 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1293 static int has_dimension(HashTable
*ht
, zval
*member
, char **key_str
, int *key_len
, ulong
*index TSRMLS_DC
)
1298 switch (Z_TYPE_P(member
)) {
1300 convert_to_string_ex(&tmp
);
1303 if (!is_numeric_string(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
), &lval
, NULL
, 0)) {
1304 int exists
= zend_hash_exists(ht
, Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
) + 1);
1307 *key_str
= estrndup(Z_STRVAL_P(tmp
), Z_STRLEN_P(tmp
));
1309 *key_len
= Z_STRLEN_P(tmp
) + 1;
1312 if (member
!= tmp
) {
1313 zval_ptr_dtor(&tmp
);
1320 lval
= Z_LVAL_P(member
);
1324 if (member
!= tmp
) {
1325 zval_ptr_dtor(&tmp
);
1330 return zend_hash_index_exists(ht
, lval
);
1333 static int php_pqtypes_object_has_dimension(zval
*object
, zval
*member
, int check_empty TSRMLS_DC
)
1335 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1336 char *key_str
= NULL
;
1341 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1344 if (key_str
&& key_len
) {
1345 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1347 return Z_TYPE_PP(data
) != IS_NULL
;
1351 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1352 return Z_TYPE_PP(data
) != IS_NULL
;
1360 return has_dimension(&obj
->intern
->types
, member
, NULL
, NULL
, NULL TSRMLS_CC
);
1366 static zval
*php_pqtypes_object_read_dimension(zval
*object
, zval
*member
, int type TSRMLS_DC
)
1369 char *key_str
= NULL
;
1371 php_pqtypes_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1373 if (has_dimension(&obj
->intern
->types
, member
, &key_str
, &key_len
, &index TSRMLS_CC
)) {
1376 if (key_str
&& key_len
) {
1377 if (SUCCESS
== zend_hash_find(&obj
->intern
->types
, key_str
, key_len
, (void *) &data
)) {
1382 if (SUCCESS
== zend_hash_index_find(&obj
->intern
->types
, index
, (void *) &data
)) {
1394 static void php_pqres_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1396 php_pqres_object_t
*obj
= o
;
1398 RETVAL_LONG(PQresultStatus(obj
->intern
->res
));
1401 static void php_pqres_object_read_status_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1403 php_pqres_object_t
*obj
= o
;
1405 RETVAL_STRING(PQresStatus(PQresultStatus(obj
->intern
->res
))+sizeof("PGRES"), 1);
1408 static void php_pqres_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1410 php_pqres_object_t
*obj
= o
;
1411 char *error
= PHP_PQresultErrorMessage(obj
->intern
->res
);
1414 RETVAL_STRING(error
, 1);
1420 static void php_pqres_object_read_num_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1422 php_pqres_object_t
*obj
= o
;
1424 RETVAL_LONG(PQntuples(obj
->intern
->res
));
1427 static void php_pqres_object_read_num_cols(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1429 php_pqres_object_t
*obj
= o
;
1431 RETVAL_LONG(PQnfields(obj
->intern
->res
));
1434 static void php_pqres_object_read_affected_rows(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1436 php_pqres_object_t
*obj
= o
;
1438 RETVAL_LONG(atoi(PQcmdTuples(obj
->intern
->res
)));
1441 static void php_pqres_object_read_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1443 php_pqres_object_t
*obj
= o
;
1445 if (obj
->intern
->iter
) {
1446 RETVAL_LONG(obj
->intern
->iter
->fetch_type
);
1448 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY
);
1452 static void php_pqres_object_write_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1454 php_pqres_object_t
*obj
= o
;
1455 zval
*zfetch_type
= value
;
1457 if (Z_TYPE_P(value
) != IS_LONG
) {
1458 if (Z_REFCOUNT_P(value
) > 1) {
1461 ZVAL_ZVAL(tmp
, zfetch_type
, 1, 0);
1462 convert_to_long(tmp
);
1465 convert_to_long_ex(&zfetch_type
);
1469 if (!obj
->intern
->iter
) {
1470 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(object
), object
, 0 TSRMLS_CC
);
1471 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
1473 obj
->intern
->iter
->fetch_type
= Z_LVAL_P(zfetch_type
);
1475 if (zfetch_type
!= value
) {
1476 zval_ptr_dtor(&zfetch_type
);
1480 static void php_pqstm_object_read_name(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1482 php_pqstm_object_t
*obj
= o
;
1484 RETVAL_STRING(obj
->intern
->name
, 1);
1487 static void php_pqstm_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1489 php_pqstm_object_t
*obj
= o
;
1491 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1494 static void php_pqtxn_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1496 php_pqtxn_object_t
*obj
= o
;
1498 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1501 static void php_pqtxn_object_read_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1503 php_pqtxn_object_t
*obj
= o
;
1505 RETVAL_LONG(obj
->intern
->isolation
);
1508 static void php_pqtxn_object_read_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1510 php_pqtxn_object_t
*obj
= o
;
1512 RETVAL_BOOL(obj
->intern
->readonly
);
1515 static void php_pqtxn_object_read_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1517 php_pqtxn_object_t
*obj
= o
;
1519 RETVAL_BOOL(obj
->intern
->deferrable
);
1522 static void php_pqtxn_object_write_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1524 php_pqtxn_object_t
*obj
= o
;
1525 php_pqtxn_isolation_t orig
= obj
->intern
->isolation
;
1526 zval
*zisolation
= value
;
1529 if (Z_TYPE_P(zisolation
) != IS_LONG
) {
1530 if (Z_REFCOUNT_P(value
) > 1) {
1533 ZVAL_ZVAL(tmp
, zisolation
, 1, 0);
1534 convert_to_long(tmp
);
1537 convert_to_long_ex(&zisolation
);
1541 switch ((obj
->intern
->isolation
= Z_LVAL_P(zisolation
))) {
1542 case PHP_PQTXN_READ_COMMITTED
:
1543 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL READ COMMITED");
1545 case PHP_PQTXN_REPEATABLE_READ
:
1546 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
1548 case PHP_PQTXN_SERIALIZABLE
:
1549 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
1552 obj
->intern
->isolation
= orig
;
1557 if (zisolation
!= value
) {
1558 zval_ptr_dtor(&zisolation
);
1562 php_pqres_success(res TSRMLS_CC
);
1567 static void php_pqtxn_object_write_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1569 php_pqtxn_object_t
*obj
= o
;
1572 if ((obj
->intern
->readonly
= zend_is_true(value
))) {
1573 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ ONLY");
1575 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION READ WRITE");
1579 php_pqres_success(res TSRMLS_CC
);
1584 static void php_pqtxn_object_write_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
1586 php_pqtxn_object_t
*obj
= o
;
1589 if ((obj
->intern
->deferrable
= zend_is_true(value
))) {
1590 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION DEFERRABLE");
1592 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SET TRANSACTION NOT DEFERRABLE");
1596 php_pqres_success(res TSRMLS_CC
);
1601 static void php_pqcancel_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1603 php_pqcancel_object_t
*obj
= o
;
1605 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1608 static void php_pqlob_object_read_transaction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1610 php_pqlob_object_t
*obj
= o
;
1612 php_pq_object_to_zval(obj
->intern
->txn
, &return_value TSRMLS_CC
);
1615 static void php_pqlob_object_read_oid(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1617 php_pqlob_object_t
*obj
= o
;
1619 RETVAL_LONG(obj
->intern
->loid
);
1622 static void php_pqlob_object_update_stream(zval
*this_ptr
, php_pqlob_object_t
*obj
, zval
**zstream TSRMLS_DC
);
1624 static void php_pqlob_object_read_stream(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1626 php_pqlob_object_t
*obj
= o
;
1628 if (!obj
->intern
->stream
) {
1631 php_pqlob_object_update_stream(object
, obj
, &zstream TSRMLS_CC
);
1632 RETVAL_ZVAL(zstream
, 1, 1);
1634 RETVAL_RESOURCE(obj
->intern
->stream
);
1635 zend_list_addref(obj
->intern
->stream
);
1639 static void php_pqcopy_object_read_connection(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1641 php_pqcopy_object_t
*obj
= o
;
1643 php_pq_object_to_zval(obj
->intern
->conn
, &return_value TSRMLS_CC
);
1646 static void php_pqcopy_object_read_direction(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1648 php_pqcopy_object_t
*obj
= o
;
1650 RETVAL_LONG(obj
->intern
->direction
);
1653 static void php_pqcopy_object_read_expression(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1655 php_pqcopy_object_t
*obj
= o
;
1657 RETURN_STRING(obj
->intern
->expression
, 1);
1660 static void php_pqcopy_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
1662 php_pqcopy_object_t
*obj
= o
;
1664 RETURN_STRING(obj
->intern
->options
, 1);
1667 static zend_class_entry
*ancestor(zend_class_entry
*ce
) {
1668 while (ce
->parent
) {
1674 static zval
*php_pq_object_read_prop(zval
*object
, zval
*member
, int type
, const zend_literal
*key TSRMLS_DC
)
1676 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1677 php_pq_object_prophandler_t
*handler
;
1681 zend_error(E_WARNING
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
);
1682 } else if ((SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) && handler
->read
) {
1683 if (type
== BP_VAR_R
) {
1684 ALLOC_ZVAL(return_value
);
1685 Z_SET_REFCOUNT_P(return_value
, 0);
1686 Z_UNSET_ISREF_P(return_value
);
1688 handler
->read(object
, obj
, return_value TSRMLS_CC
);
1690 zend_error(E_ERROR
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
);
1691 return_value
= NULL
;
1694 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, key TSRMLS_CC
);
1697 return return_value
;
1700 static void php_pq_object_write_prop(zval
*object
, zval
*member
, zval
*value
, const zend_literal
*key TSRMLS_DC
)
1702 php_pq_object_t
*obj
= zend_object_store_get_object(object TSRMLS_CC
);
1703 php_pq_object_prophandler_t
*handler
;
1705 if (SUCCESS
== zend_hash_find(obj
->prophandler
, Z_STRVAL_P(member
), Z_STRLEN_P(member
)+1, (void *) &handler
)) {
1706 if (handler
->write
) {
1707 handler
->write(object
, obj
, value TSRMLS_CC
);
1710 zend_get_std_object_handlers()->write_property(object
, member
, value
, key TSRMLS_CC
);
1714 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
1716 zval
*zsocket
, zmember
;
1722 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1725 INIT_PZVAL(&zmember
);
1726 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
1727 MAKE_STD_ZVAL(zsocket
);
1729 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
1730 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
1731 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
1732 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1733 php_stream_to_zval(stream
, zsocket
);
1739 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
1740 zval_ptr_dtor(&zsocket
);
1746 # define TSRMLS_DF(d) TSRMLS_D = (d)->ts
1747 # define TSRMLS_CF(d) (d)->ts = TSRMLS_C
1749 # define TSRMLS_DF(d)
1750 # define TSRMLS_CF(d)
1753 static int apply_event(void *p
, void *a TSRMLS_DC
)
1755 php_pq_callback_t
*cb
= p
;
1757 zval
*retval
= NULL
;
1759 zend_fcall_info_args(&cb
->fci
, args TSRMLS_CC
);
1760 zend_fcall_info_call(&cb
->fci
, &cb
->fcc
, &retval
, NULL TSRMLS_CC
);
1762 zval_ptr_dtor(&retval
);
1765 return ZEND_HASH_APPLY_KEEP
;
1768 static void php_pqconn_event_connreset(PGEventConnReset
*event
)
1770 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1776 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("reset"), (void *) &evhs
)) {
1777 zval
*args
, *connection
= NULL
;
1779 MAKE_STD_ZVAL(args
);
1781 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1782 add_next_index_zval(args
, connection
);
1783 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1784 zval_ptr_dtor(&args
);
1789 static void php_pqres_init_instance_data(PGresult
*res
, php_pqres_object_t
**ptr TSRMLS_DC
)
1791 php_pqres_object_t
*obj
;
1792 php_pqres_t
*r
= ecalloc(1, sizeof(*r
));
1795 ZEND_INIT_SYMTABLE(&r
->bound
);
1796 php_pqres_create_object_ex(php_pqres_class_entry
, r
, &obj TSRMLS_CC
);
1798 PQresultSetInstanceData(res
, php_pqconn_event
, obj
);
1805 static void php_pqconn_event_resultcreate(PGEventResultCreate
*event
)
1807 php_pqconn_event_data_t
*data
= PQinstanceData(event
->conn
, php_pqconn_event
);
1810 php_pqres_object_t
*obj
;
1814 php_pqres_init_instance_data(event
->result
, &obj TSRMLS_CC
);
1816 /* event listener */
1817 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("result"), (void *) &evhs
)) {
1818 zval
*args
, *connection
= NULL
, *res
= NULL
;
1820 MAKE_STD_ZVAL(args
);
1822 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1823 add_next_index_zval(args
, connection
);
1824 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1825 add_next_index_zval(args
, res
);
1826 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1827 zval_ptr_dtor(&args
);
1830 /* async callback */
1831 if (data
->obj
->intern
->onevent
.fci
.size
> 0) {
1834 php_pq_object_to_zval(obj
, &res TSRMLS_CC
);
1835 zend_fcall_info_argn(&data
->obj
->intern
->onevent
.fci TSRMLS_CC
, 1, &res
);
1836 zend_fcall_info_call(&data
->obj
->intern
->onevent
.fci
, &data
->obj
->intern
->onevent
.fcc
, NULL
, NULL TSRMLS_CC
);
1837 zval_ptr_dtor(&res
);
1843 static void php_pqconn_event_resultdestroy(PGEventResultDestroy
*event
)
1845 php_pqres_object_t
*obj
= PQresultInstanceData(event
->result
, php_pqconn_event
);
1848 obj
->intern
->res
= NULL
;
1852 static int php_pqconn_event(PGEventId id
, void *e
, void *data
)
1855 case PGEVT_CONNRESET
:
1856 php_pqconn_event_connreset(e
);
1858 case PGEVT_RESULTCREATE
:
1859 php_pqconn_event_resultcreate(e
);
1861 case PGEVT_RESULTDESTROY
:
1862 php_pqconn_event_resultdestroy(e
);
1871 static php_pqconn_event_data_t
*php_pqconn_event_data_init(php_pqconn_object_t
*obj TSRMLS_DC
)
1873 php_pqconn_event_data_t
*data
= emalloc(sizeof(*data
));
1881 static void php_pqconn_notice_recv(void *p
, const PGresult
*res
)
1883 php_pqconn_event_data_t
*data
= p
;
1889 if (SUCCESS
== zend_hash_find(&data
->obj
->intern
->eventhandlers
, ZEND_STRS("notice"), (void *) &evhs
)) {
1890 zval
*args
, *connection
= NULL
;
1892 MAKE_STD_ZVAL(args
);
1894 php_pq_object_to_zval(data
->obj
, &connection TSRMLS_CC
);
1895 add_next_index_zval(args
, connection
);
1896 add_next_index_string(args
, PHP_PQresultErrorMessage(res
), 1);
1897 zend_hash_apply_with_argument(evhs
, apply_event
, args TSRMLS_CC
);
1898 zval_ptr_dtor(&args
);
1903 typedef struct php_pqconn_resource_factory_data
{
1906 } php_pqconn_resource_factory_data_t
;
1908 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
1910 php_pqconn_resource_factory_data_t
*o
= init_arg
;
1911 PGconn
*conn
= NULL
;;
1913 if (o
->flags
& PHP_PQCONN_ASYNC
) {
1914 conn
= PQconnectStart(o
->dsn
);
1916 conn
= PQconnectdb(o
->dsn
);
1920 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
1926 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
1928 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
1930 /* we don't care for anything, except free'ing evdata */
1932 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
1933 memset(evdata
, 0, sizeof(*evdata
));
1940 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
1941 php_pqconn_resource_factory_ctor
,
1943 php_pqconn_resource_factory_dtor
1946 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1948 // FIXME: ping server
1951 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
1953 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
1954 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1);
1956 if (quoted_channel
) {
1960 spprintf(&cmd
, 0, "UNLISTEN %s", quoted_channel
);
1961 if ((res
= PQexec(obj
->intern
->conn
, cmd
))) {
1966 PQfreemem(quoted_channel
);
1969 return ZEND_HASH_APPLY_REMOVE
;
1972 static void php_pqconn_notice_ignore(void *p
, const PGresult
*res
)
1976 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
1978 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
1983 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
1985 /* ignore notices */
1986 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
1988 /* cancel async queries */
1989 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
1990 char err
[256] = {0};
1992 PQcancel(cancel
, err
, sizeof(err
));
1993 PQfreeCancel(cancel
);
1995 /* clean up async results */
1996 while ((res
= PQgetResult(*handle
))) {
2000 /* clean up transaction & session */
2001 switch (PQtransactionStatus(*handle
)) {
2003 res
= PQexec(*handle
, "RESET ALL");
2006 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
2015 /* clean up notify listeners */
2016 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
2018 /* release instance data */
2019 memset(evdata
, 0, sizeof(*evdata
));
2024 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
2025 ZEND_ARG_INFO(0, dsn
)
2026 ZEND_ARG_INFO(0, async
)
2027 ZEND_END_ARG_INFO();
2028 static PHP_METHOD(pqconn
, __construct
) {
2029 zend_error_handling zeh
;
2035 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2036 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
);
2037 zend_restore_error_handling(&zeh TSRMLS_CC
);
2039 if (SUCCESS
== rv
) {
2040 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2043 throw_exce(EX_BAD_METHODCALL TSRMLS_CC
, "pq\\Connection already initialized");
2045 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
2046 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
2048 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
2050 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
2051 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
2053 if (flags
& PHP_PQCONN_PERSISTENT
) {
2054 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
);
2055 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
2057 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
2060 if (flags
& PHP_PQCONN_ASYNC
) {
2061 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
2064 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
2066 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
2067 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
2069 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
2070 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2076 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
2077 ZEND_END_ARG_INFO();
2078 static PHP_METHOD(pqconn
, reset
) {
2079 zend_error_handling zeh
;
2082 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2083 rv
= zend_parse_parameters_none();
2084 zend_restore_error_handling(&zeh TSRMLS_CC
);
2086 if (SUCCESS
== rv
) {
2087 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2090 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2092 PQreset(obj
->intern
->conn
);
2094 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
2095 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2098 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2103 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
2104 ZEND_END_ARG_INFO();
2105 static PHP_METHOD(pqconn
, resetAsync
) {
2106 zend_error_handling zeh
;
2109 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2110 rv
= zend_parse_parameters_none();
2111 zend_restore_error_handling(&zeh TSRMLS_CC
);
2113 if (SUCCESS
== rv
) {
2114 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2117 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2119 if (!PQresetStart(obj
->intern
->conn
)) {
2120 throw_exce(EX_IO TSRMLS_CC
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2122 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
2125 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2130 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
)
2132 HashTable ht
, *existing_listeners
;
2134 php_pq_callback_addref(listener
);
2136 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
2137 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
2139 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
2140 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
2141 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
2145 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 0)
2146 ZEND_ARG_INFO(0, channel
)
2147 ZEND_ARG_INFO(0, callable
)
2148 ZEND_END_ARG_INFO();
2149 static PHP_METHOD(pqconn
, listen
) {
2150 zend_error_handling zeh
;
2151 char *channel_str
= NULL
;
2152 int channel_len
= 0;
2153 php_pq_callback_t listener
;
2156 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2157 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2158 zend_restore_error_handling(&zeh TSRMLS_CC
);
2160 if (SUCCESS
== rv
) {
2161 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2164 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2166 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2168 if (!quoted_channel
) {
2169 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2172 smart_str cmd
= {0};
2174 smart_str_appends(&cmd
, "LISTEN ");
2175 smart_str_appends(&cmd
, quoted_channel
);
2178 res
= PQexec(obj
->intern
->conn
, cmd
.c
);
2180 smart_str_free(&cmd
);
2181 PQfreemem(quoted_channel
);
2184 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2186 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2187 obj
->intern
->poller
= PQconsumeInput
;
2188 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2193 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2199 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
2200 ZEND_ARG_INFO(0, channel
)
2201 ZEND_ARG_INFO(0, callable
)
2202 ZEND_END_ARG_INFO();
2203 static PHP_METHOD(pqconn
, listenAsync
) {
2204 zend_error_handling zeh
;
2205 char *channel_str
= NULL
;
2206 int channel_len
= 0;
2207 php_pq_callback_t listener
;
2210 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2211 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
2212 zend_restore_error_handling(&zeh TSRMLS_CC
);
2214 if (SUCCESS
== rv
) {
2215 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2218 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2220 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
2222 if (!quoted_channel
) {
2223 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2225 smart_str cmd
= {0};
2227 smart_str_appends(&cmd
, "LISTEN ");
2228 smart_str_appends(&cmd
, quoted_channel
);
2231 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
2232 throw_exce(EX_IO TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2234 obj
->intern
->poller
= PQconsumeInput
;
2235 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
2238 smart_str_free(&cmd
);
2239 PQfreemem(quoted_channel
);
2240 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2246 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
2247 ZEND_ARG_INFO(0, channel
)
2248 ZEND_ARG_INFO(0, message
)
2249 ZEND_END_ARG_INFO();
2250 static PHP_METHOD(pqconn
, notify
) {
2251 zend_error_handling zeh
;
2252 char *channel_str
, *message_str
;
2253 int channel_len
, message_len
;
2256 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2257 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2258 zend_restore_error_handling(&zeh TSRMLS_CC
);
2260 if (SUCCESS
== rv
) {
2261 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2264 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2267 char *params
[2] = {channel_str
, message_str
};
2269 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
2272 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2274 php_pqres_success(res TSRMLS_CC
);
2278 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2283 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
2284 ZEND_ARG_INFO(0, channel
)
2285 ZEND_ARG_INFO(0, message
)
2286 ZEND_END_ARG_INFO();
2287 static PHP_METHOD(pqconn
, notifyAsync
) {
2288 zend_error_handling zeh
;
2289 char *channel_str
, *message_str
;
2290 int channel_len
, message_len
;
2293 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2294 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
2295 zend_restore_error_handling(&zeh TSRMLS_CC
);
2297 if (SUCCESS
== rv
) {
2298 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2301 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2303 char *params
[2] = {channel_str
, message_str
};
2305 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
2306 throw_exce(EX_IO TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2308 obj
->intern
->poller
= PQconsumeInput
;
2311 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2316 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
2317 ZEND_END_ARG_INFO();
2318 static PHP_METHOD(pqconn
, poll
) {
2319 zend_error_handling zeh
;
2322 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2323 rv
= zend_parse_parameters_none();
2324 zend_restore_error_handling(&zeh TSRMLS_CC
);
2326 if (SUCCESS
== rv
) {
2327 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2330 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2331 } else if (!obj
->intern
->poller
) {
2332 throw_exce(EX_RUNTIME TSRMLS_CC
, "No asynchronous operation active");
2334 if (obj
->intern
->poller
== PQconsumeInput
) {
2335 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
2337 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
2339 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2344 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
2345 ZEND_ARG_INFO(0, query
)
2346 ZEND_END_ARG_INFO();
2347 static PHP_METHOD(pqconn
, exec
) {
2348 zend_error_handling zeh
;
2353 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2354 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
);
2355 zend_restore_error_handling(&zeh TSRMLS_CC
);
2357 if (SUCCESS
== rv
) {
2358 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2361 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2363 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
2366 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2367 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2368 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2373 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2378 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
2379 ZEND_END_ARG_INFO();
2380 static PHP_METHOD(pqconn
, getResult
) {
2381 zend_error_handling zeh
;
2384 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2385 rv
= zend_parse_parameters_none();
2386 zend_restore_error_handling(&zeh TSRMLS_CC
);
2388 if (SUCCESS
== rv
) {
2389 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2392 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2394 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
2399 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2402 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2407 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
2408 ZEND_ARG_INFO(0, query
)
2409 ZEND_ARG_INFO(0, callable
)
2410 ZEND_END_ARG_INFO();
2411 static PHP_METHOD(pqconn
, execAsync
) {
2412 zend_error_handling zeh
;
2413 php_pq_callback_t resolver
= {{0}};
2418 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2419 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
2420 zend_restore_error_handling(&zeh TSRMLS_CC
);
2422 if (SUCCESS
== rv
) {
2423 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2426 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2427 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
2428 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2429 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2430 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2432 obj
->intern
->poller
= PQconsumeInput
;
2433 php_pq_callback_dtor(&obj
->intern
->onevent
);
2434 if (resolver
.fci
.size
> 0) {
2435 obj
->intern
->onevent
= resolver
;
2436 php_pq_callback_addref(&obj
->intern
->onevent
);
2438 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2443 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
2448 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
2449 convert_to_long_ex(ztype
);
2452 **types
= Z_LVAL_PP(ztype
);
2455 if (*ztype
!= *(zval
**)p
) {
2456 zval_ptr_dtor(ztype
);
2458 return ZEND_HASH_APPLY_KEEP
;
2461 static int apply_to_param(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
2467 params
= (char ***) va_arg(argv
, char ***);
2468 zdtor
= (HashTable
*) va_arg(argv
, HashTable
*);
2470 if (Z_TYPE_PP(zparam
) == IS_NULL
) {
2474 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
2475 convert_to_string_ex(zparam
);
2478 **params
= Z_STRVAL_PP(zparam
);
2481 if (*zparam
!= *(zval
**)p
) {
2482 zend_hash_next_index_insert(zdtor
, zparam
, sizeof(zval
*), NULL
);
2485 return ZEND_HASH_APPLY_KEEP
;
2488 static int php_pq_types_to_array(HashTable
*ht
, Oid
**types TSRMLS_DC
)
2490 int count
= zend_hash_num_elements(ht
);
2497 /* +1 for when less types than params are specified */
2498 *types
= tmp
= ecalloc(count
+ 1, sizeof(**types
));
2499 zend_hash_apply_with_argument(ht
, apply_to_oid
, &tmp TSRMLS_CC
);
2505 static int php_pq_params_to_array(HashTable
*ht
, char ***params
, HashTable
*zdtor TSRMLS_DC
)
2507 int count
= zend_hash_num_elements(ht
);
2514 *params
= tmp
= ecalloc(count
, sizeof(char *));
2515 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param
, 2, &tmp
, zdtor
);
2521 static Oid *php_pq_ntypes_to_array(zend_bool fill, int argc, ...)
2524 Oid *oids = ecalloc(argc + 1, sizeof(*oids));
2527 va_start(argv, argc);
2528 for (i = 0; i < argc; ++i) {
2530 oids[i] = va_arg(argv, Oid);
2540 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
2541 ZEND_ARG_INFO(0, query
)
2542 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2543 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2544 ZEND_END_ARG_INFO();
2545 static PHP_METHOD(pqconn
, execParams
) {
2546 zend_error_handling zeh
;
2550 zval
*ztypes
= NULL
;
2553 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2554 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
2555 zend_restore_error_handling(&zeh TSRMLS_CC
);
2557 if (SUCCESS
== rv
) {
2558 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2561 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2566 char **params
= NULL
;
2569 ZEND_INIT_SYMTABLE(&zdtor
);
2570 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2573 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2576 res
= PQexecParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0);
2578 zend_hash_destroy(&zdtor
);
2587 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2589 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
2590 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
2595 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2601 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
2602 ZEND_ARG_INFO(0, query
)
2603 ZEND_ARG_ARRAY_INFO(0, params
, 0)
2604 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2605 ZEND_ARG_INFO(0, callable
)
2606 ZEND_END_ARG_INFO();
2607 static PHP_METHOD(pqconn
, execParamsAsync
) {
2608 zend_error_handling zeh
;
2609 php_pq_callback_t resolver
= {{0}};
2613 zval
*ztypes
= NULL
;
2616 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2617 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
2618 zend_restore_error_handling(&zeh TSRMLS_CC
);
2620 if (SUCCESS
== rv
) {
2621 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2624 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2628 char **params
= NULL
;
2631 ZEND_INIT_SYMTABLE(&zdtor
);
2632 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
2635 php_pq_types_to_array(Z_ARRVAL_P(ztypes
), &types TSRMLS_CC
);
2638 if (!PQsendQueryParams(obj
->intern
->conn
, query_str
, count
, types
, (const char *const*) params
, NULL
, NULL
, 0)) {
2639 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2640 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2641 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2643 obj
->intern
->poller
= PQconsumeInput
;
2644 php_pq_callback_dtor(&obj
->intern
->onevent
);
2645 if (resolver
.fci
.size
> 0) {
2646 obj
->intern
->onevent
= resolver
;
2647 php_pq_callback_addref(&obj
->intern
->onevent
);
2649 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2652 zend_hash_destroy(&zdtor
);
2661 zend_restore_error_handling(&zeh TSRMLS_CC
);
2664 static STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2672 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2676 count
= zend_hash_num_elements(typest
);
2677 php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2680 res
= PQprepare(obj
->intern
->conn
, name
, query
, count
, types
);
2688 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2690 rv
= php_pqres_success(res TSRMLS_CC
);
2692 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2698 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
2699 ZEND_ARG_INFO(0, type
)
2700 ZEND_ARG_INFO(0, query
)
2701 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2702 ZEND_END_ARG_INFO();
2703 static PHP_METHOD(pqconn
, prepare
) {
2704 zend_error_handling zeh
;
2705 zval
*ztypes
= NULL
;
2706 char *name_str
, *query_str
;
2707 int name_len
, *query_len
;
2710 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2711 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2712 zend_restore_error_handling(&zeh TSRMLS_CC
);
2714 if (SUCCESS
== rv
) {
2715 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2718 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2719 } else if (SUCCESS
== php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2720 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2722 php_pq_object_addref(obj TSRMLS_CC
);
2724 stm
->name
= estrdup(name_str
);
2725 ZEND_INIT_SYMTABLE(&stm
->bound
);
2727 return_value
->type
= IS_OBJECT
;
2728 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2733 static STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, HashTable
*typest TSRMLS_DC
)
2740 obj
= zend_object_store_get_object(object TSRMLS_CC
);
2744 count
= php_pq_types_to_array(typest
, &types TSRMLS_CC
);
2747 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, count
, types
)) {
2749 throw_exce(EX_IO TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2750 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
2752 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2755 obj
->intern
->poller
= PQconsumeInput
;
2756 php_pqconn_notify_listeners(obj TSRMLS_CC
);
2766 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
2767 ZEND_ARG_INFO(0, type
)
2768 ZEND_ARG_INFO(0, query
)
2769 ZEND_ARG_ARRAY_INFO(0, types
, 1)
2770 ZEND_END_ARG_INFO();
2771 static PHP_METHOD(pqconn
, prepareAsync
) {
2772 zend_error_handling zeh
;
2773 zval
*ztypes
= NULL
;
2774 char *name_str
, *query_str
;
2775 int name_len
, *query_len
;
2778 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
2779 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
2780 zend_restore_error_handling(&zeh TSRMLS_CC
);
2782 if (SUCCESS
== rv
) {
2783 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2786 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2787 } else if (SUCCESS
== php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
)) {
2788 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
2790 php_pq_object_addref(obj TSRMLS_CC
);
2792 stm
->name
= estrdup(name_str
);
2793 ZEND_INIT_SYMTABLE(&stm
->bound
);
2795 return_value
->type
= IS_OBJECT
;
2796 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
2801 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
2802 ZEND_ARG_INFO(0, string
)
2803 ZEND_END_ARG_INFO();
2804 static PHP_METHOD(pqconn
, quote
) {
2808 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2809 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2812 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2814 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
2817 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2820 RETVAL_STRING(quoted
, 1);
2827 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
2828 ZEND_ARG_INFO(0, type
)
2829 ZEND_END_ARG_INFO();
2830 static PHP_METHOD(pqconn
, quoteName
) {
2834 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2835 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2838 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2840 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
2843 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2846 RETVAL_STRING(quoted
, 1);
2853 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
2854 ZEND_ARG_INFO(0, bytea
)
2855 ZEND_END_ARG_INFO();
2856 static PHP_METHOD(pqconn
, escapeBytea
) {
2860 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2861 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2864 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2867 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
2870 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2873 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
2874 PQfreemem(escaped_str
);
2880 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
2881 ZEND_ARG_INFO(0, bytea
)
2882 ZEND_END_ARG_INFO();
2883 static PHP_METHOD(pqconn
, unescapeBytea
) {
2887 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
2888 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
2891 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2893 size_t unescaped_len
;
2894 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
2896 if (!unescaped_str
) {
2897 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
2900 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
2901 PQfreemem(unescaped_str
);
2907 static const char *isolation_level(long *isolation
) {
2908 switch (*isolation
) {
2909 case PHP_PQTXN_SERIALIZABLE
:
2910 return "SERIALIZABLE";
2911 case PHP_PQTXN_REPEATABLE_READ
:
2912 return "REPEATABLE READ";
2914 *isolation
= PHP_PQTXN_READ_COMMITTED
;
2916 case PHP_PQTXN_READ_COMMITTED
:
2917 return "READ COMMITTED";
2921 static STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
2923 STATUS rv
= FAILURE
;
2926 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2929 if (!conn_obj
->intern
) {
2930 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2933 smart_str cmd
= {0};
2934 const char *il
= isolation_level(&isolation
);
2936 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2937 smart_str_appends(&cmd
, il
);
2938 smart_str_appends(&cmd
, ", READ ");
2939 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2940 smart_str_appends(&cmd
, ",");
2941 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
2942 smart_str_appends(&cmd
, " DEFERRABLE");
2945 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
2948 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2950 rv
= php_pqres_success(res TSRMLS_CC
);
2952 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2955 smart_str_free(&cmd
);
2961 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
)
2963 STATUS rv
= FAILURE
;
2966 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
2969 if (!conn_obj
->intern
) {
2970 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
2972 smart_str cmd
= {0};
2973 const char *il
= isolation_level(&isolation
);
2975 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
2976 smart_str_appends(&cmd
, il
);
2977 smart_str_appends(&cmd
, ", READ ");
2978 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
2979 smart_str_appends(&cmd
, ",");
2980 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
2981 smart_str_appends(&cmd
, " DEFERRABLE");
2984 if (!PQsendQuery(conn_obj
->intern
->conn
, cmd
.c
)) {
2985 throw_exce(EX_IO TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
2988 conn_obj
->intern
->poller
= PQconsumeInput
;
2989 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
2992 smart_str_free(&cmd
);
2998 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
2999 ZEND_ARG_INFO(0, isolation
)
3000 ZEND_ARG_INFO(0, readonly
)
3001 ZEND_ARG_INFO(0, deferrable
)
3002 ZEND_END_ARG_INFO();
3003 static PHP_METHOD(pqconn
, startTransaction
) {
3004 zend_error_handling zeh
;
3005 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3006 zend_bool readonly
= 0, deferrable
= 0;
3009 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3010 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
3011 zend_restore_error_handling(&zeh TSRMLS_CC
);
3013 if (SUCCESS
== rv
) {
3014 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3016 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3018 if (SUCCESS
== rv
) {
3019 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
3021 php_pq_object_addref(obj TSRMLS_CC
);
3024 txn
->isolation
= isolation
;
3025 txn
->readonly
= readonly
;
3026 txn
->deferrable
= deferrable
;
3028 return_value
->type
= IS_OBJECT
;
3029 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3034 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
3035 ZEND_ARG_INFO(0, isolation
)
3036 ZEND_ARG_INFO(0, readonly
)
3037 ZEND_ARG_INFO(0, deferrable
)
3038 ZEND_END_ARG_INFO();
3039 static PHP_METHOD(pqconn
, startTransactionAsync
) {
3040 zend_error_handling zeh
;
3041 long isolation
= PHP_PQTXN_READ_COMMITTED
;
3042 zend_bool readonly
= 0, deferrable
= 0;
3045 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3046 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
3047 zend_restore_error_handling(&zeh TSRMLS_CC
);
3048 if (SUCCESS
== rv
) {
3049 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3051 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
3053 if (SUCCESS
== rv
) {
3054 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
3056 php_pq_object_addref(obj TSRMLS_CC
);
3058 txn
->isolation
= isolation
;
3059 txn
->readonly
= readonly
;
3060 txn
->deferrable
= deferrable
;
3062 return_value
->type
= IS_OBJECT
;
3063 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
3068 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
3069 ZEND_ARG_INFO(0, stdio_stream
)
3070 ZEND_END_ARG_INFO();
3071 static PHP_METHOD(pqconn
, trace
) {
3072 zval
*zstream
= NULL
;
3074 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
3075 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3078 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3081 PQuntrace(obj
->intern
->conn
);
3085 php_stream
*stream
= NULL
;
3087 php_stream_from_zval(stream
, &zstream
);
3089 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
3092 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
3093 PQtrace(obj
->intern
->conn
, fp
);
3101 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on
, 0, 0, 2)
3102 ZEND_ARG_INFO(0, type
)
3103 ZEND_ARG_INFO(0, callable
)
3104 ZEND_END_ARG_INFO();
3105 static PHP_METHOD(pqconn
, on
) {
3106 zend_error_handling zeh
;
3109 php_pq_callback_t cb
;
3112 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3113 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
3114 zend_restore_error_handling(&zeh TSRMLS_CC
);
3116 if (SUCCESS
== rv
) {
3117 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3120 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3122 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3124 RETVAL_LONG(php_pqconn_add_eventhandler(obj
, type_str
, type_len
, &cb TSRMLS_CC
));
3129 static zend_function_entry php_pqconn_methods
[] = {
3130 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3131 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
3132 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
3133 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
3134 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
3135 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
3136 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
3137 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
3138 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
3139 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
3140 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
3141 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
3142 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
3143 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
3144 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
3145 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
3146 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
3147 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
3148 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
3149 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
3150 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
3151 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
3152 PHP_ME(pqconn
, on
, ai_pqconn_on
, ZEND_ACC_PUBLIC
)
3156 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_construct
, 0, 0, 1)
3157 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3158 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3159 ZEND_END_ARG_INFO();
3160 static PHP_METHOD(pqtypes
, __construct
) {
3161 zend_error_handling zeh
;
3162 zval
*zconn
, *znsp
= NULL
;
3165 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3166 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|a!", &zconn
, php_pqconn_class_entry
, &znsp
);
3167 zend_restore_error_handling(&zeh TSRMLS_CC
);
3169 if (SUCCESS
== rv
) {
3170 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3172 if (!conn_obj
->intern
) {
3173 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3175 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3176 zval
*retval
= NULL
;
3178 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
3179 obj
->intern
->conn
= conn_obj
;
3180 php_pq_object_addref(conn_obj TSRMLS_CC
);
3181 zend_hash_init(&obj
->intern
->types
, 300, NULL
, ZVAL_PTR_DTOR
, 0);
3184 zend_call_method_with_1_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
, znsp
);
3186 zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL
, "refresh", &retval
);
3190 zval_ptr_dtor(&retval
);
3196 #define PHP_PQ_TYPES_QUERY \
3197 "select t.oid, t.* " \
3198 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
3199 "where typisdefined " \
3201 #define PHP_PQ_OID_TEXT 25
3203 ZEND_BEGIN_ARG_INFO_EX(ai_pqtypes_refresh
, 0, 0, 0)
3204 ZEND_ARG_ARRAY_INFO(0, namespaces
, 1)
3205 ZEND_END_ARG_INFO();
3206 static PHP_METHOD(pqtypes
, refresh
) {
3207 HashTable
*nsp
= NULL
;
3208 zend_error_handling zeh
;
3211 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3212 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|H/!", &nsp
);
3213 zend_restore_error_handling(&zeh TSRMLS_CC
);
3215 if (SUCCESS
== rv
) {
3216 php_pqtypes_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3219 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Types not initialized");
3223 if (!nsp
|| !zend_hash_num_elements(nsp
)) {
3224 res
= PQexec(obj
->intern
->conn
->intern
->conn
, PHP_PQ_TYPES_QUERY
" and nspname in ('public', 'pg_catalog')");
3228 char **params
= NULL
;
3230 smart_str str
= {0};
3232 smart_str_appends(&str
, PHP_PQ_TYPES_QUERY
" and nspname in(");
3233 zend_hash_init(&zdtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
3234 count
= php_pq_params_to_array(nsp
, ¶ms
, &zdtor TSRMLS_CC
);
3235 oids
= ecalloc(count
+ 1, sizeof(*oids
));
3236 for (i
= 0; i
< count
; ++i
) {
3237 oids
[i
] = PHP_PQ_OID_TEXT
;
3239 smart_str_appendc(&str
, ',');
3241 smart_str_appendc(&str
, '$');
3242 smart_str_append_unsigned(&str
, i
+1);
3244 smart_str_appendc(&str
, ')');
3247 res
= PQexecParams(obj
->intern
->conn
->intern
->conn
, str
.c
, count
, oids
, (const char *const*) params
, NULL
, NULL
, 0);
3249 smart_str_free(&str
);
3252 zend_hash_destroy(&zdtor
);
3256 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch types (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3258 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3261 for (r
= 0, rows
= PQntuples(res
); r
< rows
; ++r
) {
3262 zval
*row
= php_pqres_row_to_zval(res
, r
, PHP_PQRES_FETCH_OBJECT
, NULL TSRMLS_CC
);
3263 long oid
= atol(PQgetvalue(res
, r
, 0 ));
3264 char *name
= PQgetvalue(res
, r
, 1);
3268 zend_hash_index_update(&obj
->intern
->types
, oid
, (void *) &row
, sizeof(zval
*), NULL
);
3269 zend_hash_add(&obj
->intern
->types
, name
, strlen(name
) + 1, (void *) &row
, sizeof(zval
*), NULL
);
3274 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3280 static zend_function_entry php_pqtypes_methods
[] = {
3281 PHP_ME(pqtypes
, __construct
, ai_pqtypes_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3282 PHP_ME(pqtypes
, refresh
, ai_pqtypes_refresh
, ZEND_ACC_PUBLIC
)
3286 static STATUS
php_pqres_iteration(zval
*this_ptr
, php_pqres_object_t
*obj
, php_pqres_fetch_t fetch_type
, zval
***row TSRMLS_DC
)
3289 php_pqres_fetch_t orig_fetch
;
3292 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3295 if (obj
->intern
->iter
) {
3296 obj
->intern
->iter
->zi
.funcs
->move_forward((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3298 obj
->intern
->iter
= (php_pqres_iterator_t
*) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC
);
3299 obj
->intern
->iter
->zi
.funcs
->rewind((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
);
3301 orig_fetch
= obj
->intern
->iter
->fetch_type
;
3302 obj
->intern
->iter
->fetch_type
= fetch_type
;
3303 if (SUCCESS
== (rv
= obj
->intern
->iter
->zi
.funcs
->valid((zend_object_iterator
*) obj
->intern
->iter TSRMLS_CC
))) {
3304 obj
->intern
->iter
->zi
.funcs
->get_current_data((zend_object_iterator
*) obj
->intern
->iter
, row TSRMLS_CC
);
3306 obj
->intern
->iter
->fetch_type
= orig_fetch
;
3311 typedef struct php_pqres_col
{
3316 static STATUS
column_nn(php_pqres_object_t
*obj
, zval
*zcol
, php_pqres_col_t
*col TSRMLS_DC
)
3321 switch (Z_TYPE_P(zcol
)) {
3323 convert_to_string(zcol
);
3327 if (!is_numeric_string(Z_STRVAL_P(zcol
), Z_STRLEN_P(zcol
), &index
, NULL
, 0)) {
3328 name
= Z_STRVAL_P(zcol
);
3333 index
= Z_LVAL_P(zcol
);
3339 col
->num
= PQfnumber(obj
->intern
->res
, name
);
3341 col
->name
= PQfname(obj
->intern
->res
, index
);
3346 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column at index %ld", index
);
3349 if (col
->num
== -1) {
3350 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column with name '%s'", name
);
3356 static int compare_index(const void *lptr
, const void *rptr TSRMLS_DC
)
3358 const Bucket
*l
= *(const Bucket
**) lptr
;
3359 const Bucket
*r
= *(const Bucket
**) rptr
;
3370 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind
, 0, 0, 2)
3371 ZEND_ARG_INFO(0, col
)
3372 ZEND_ARG_INFO(1, ref
)
3373 ZEND_END_ARG_INFO();
3374 static PHP_METHOD(pqres
, bind
) {
3377 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z/z", &zcol
, &zref
)) {
3378 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3381 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3383 php_pqres_col_t col
;
3385 if (SUCCESS
!= column_nn(obj
, zcol
, &col TSRMLS_CC
)) {
3390 if (SUCCESS
!= zend_hash_index_update(&obj
->intern
->bound
, col
.num
, (void *) &zref
, sizeof(zval
*), NULL
)) {
3391 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to bind column %s@%d", col
.name
, col
.num
);
3394 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3402 static int apply_bound(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3404 zval
**zvalue
, **zbound
= p
;
3405 zval
**zrow
= va_arg(argv
, zval
**);
3406 STATUS
*rv
= va_arg(argv
, STATUS
*);
3408 if (SUCCESS
!= zend_hash_index_find(Z_ARRVAL_PP(zrow
), key
->h
, (void *) &zvalue
)) {
3409 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to find column ad index %lu", key
->h
);
3411 return ZEND_HASH_APPLY_STOP
;
3414 ZVAL_COPY_VALUE(*zbound
, *zvalue
);
3416 zval_ptr_dtor(zvalue
);
3417 Z_ADDREF_P(*zbound
);
3420 return ZEND_HASH_APPLY_KEEP
;
3424 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound
, 0, 0, 0)
3425 ZEND_END_ARG_INFO();
3426 static PHP_METHOD(pqres
, fetchBound
) {
3427 zend_error_handling zeh
;
3430 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3431 rv
= zend_parse_parameters_none();
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 if (SUCCESS
== php_pqres_iteration(getThis(), obj
, PHP_PQRES_FETCH_ARRAY
, &row TSRMLS_CC
) && row
) {
3443 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3444 zend_hash_apply_with_arguments(&obj
->intern
->bound TSRMLS_CC
, apply_bound
, 2, row
, &rv
);
3445 zend_restore_error_handling(&zeh TSRMLS_CC
);
3447 if (SUCCESS
!= rv
) {
3450 RETVAL_ZVAL(*row
, 1, 0);
3457 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row
, 0, 0, 0)
3458 ZEND_ARG_INFO(0, fetch_type
)
3459 ZEND_END_ARG_INFO();
3460 static PHP_METHOD(pqres
, fetchRow
) {
3461 zend_error_handling zeh
;
3462 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3463 long fetch_type
= -1;
3466 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3467 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3468 zend_restore_error_handling(&zeh TSRMLS_CC
);
3470 if (SUCCESS
== rv
) {
3472 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3476 if (fetch_type
== -1) {
3477 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3480 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3481 php_pqres_iteration(getThis(), obj
, fetch_type
, &row TSRMLS_CC
);
3482 zend_restore_error_handling(&zeh TSRMLS_CC
);
3485 RETVAL_ZVAL(*row
, 1, 0);
3491 static zval
**column_at(zval
*row
, int col TSRMLS_DC
)
3494 HashTable
*ht
= HASH_OF(row
);
3495 int count
= zend_hash_num_elements(ht
);
3498 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Column index %d exceeds column count %d", col
, count
);
3500 zend_hash_internal_pointer_reset(ht
);
3502 zend_hash_move_forward(ht
);
3504 zend_hash_get_current_data(ht
, (void *) &data
);
3509 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col
, 0, 0, 0)
3510 ZEND_ARG_INFO(0, col_num
)
3511 ZEND_END_ARG_INFO();
3512 static PHP_METHOD(pqres
, fetchCol
) {
3513 zend_error_handling zeh
;
3517 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3518 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_col
);
3519 zend_restore_error_handling(&zeh TSRMLS_CC
);
3521 if (SUCCESS
== rv
) {
3522 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3525 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3529 zend_replace_error_handling(EH_THROW
, exce(EX_RUNTIME
), &zeh TSRMLS_CC
);
3530 php_pqres_iteration(getThis(), obj
, obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: 0, &row TSRMLS_CC
);
3532 zval
**col
= column_at(*row
, fetch_col TSRMLS_CC
);
3535 RETVAL_ZVAL(*col
, 1, 0);
3538 zend_restore_error_handling(&zeh TSRMLS_CC
);
3543 static int apply_to_col(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
3546 php_pqres_object_t
*obj
= va_arg(argv
, php_pqres_object_t
*);
3547 php_pqres_col_t
*col
, **cols
= va_arg(argv
, php_pqres_col_t
**);
3548 STATUS
*rv
= va_arg(argv
, STATUS
*);
3552 if (SUCCESS
!= column_nn(obj
, *c
, col TSRMLS_CC
)) {
3554 return ZEND_HASH_APPLY_STOP
;
3558 return ZEND_HASH_APPLY_KEEP
;
3562 static php_pqres_col_t
*php_pqres_convert_to_cols(php_pqres_object_t
*obj
, HashTable
*ht TSRMLS_DC
)
3564 php_pqres_col_t
*tmp
, *cols
= ecalloc(zend_hash_num_elements(ht
), sizeof(*cols
));
3565 STATUS rv
= SUCCESS
;
3568 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_col
, 2, obj
, &tmp
, &rv
);
3570 if (SUCCESS
== rv
) {
3578 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map
, 0, 0, 0)
3579 ZEND_ARG_INFO(0, keys
)
3580 ZEND_ARG_INFO(0, vals
)
3581 ZEND_ARG_INFO(0, fetch_type
)
3582 ZEND_END_ARG_INFO();
3583 static PHP_METHOD(pqres
, map
) {
3584 zend_error_handling zeh
;
3585 zval
*zkeys
= 0, *zvals
= 0;
3586 long fetch_type
= -1;
3589 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3590 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z/!z/!l", &zkeys
, &zvals
, &fetch_type
);
3591 zend_restore_error_handling(&zeh TSRMLS_CC
);
3593 if (SUCCESS
== rv
) {
3594 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3597 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3600 php_pqres_col_t def
= {PQfname(obj
->intern
->res
, 0), 0}, *keys
= NULL
, *vals
= NULL
;
3603 convert_to_array(zkeys
);
3605 if ((ks
= zend_hash_num_elements(Z_ARRVAL_P(zkeys
)))) {
3606 keys
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zkeys
) TSRMLS_CC
);
3616 convert_to_array(zvals
);
3618 if ((vs
= zend_hash_num_elements(Z_ARRVAL_P(zvals
)))) {
3619 vals
= php_pqres_convert_to_cols(obj
, Z_ARRVAL_P(zvals
) TSRMLS_CC
);
3623 if (fetch_type
== -1) {
3624 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3631 switch (fetch_type
) {
3632 case PHP_PQRES_FETCH_ARRAY
:
3633 case PHP_PQRES_FETCH_ASSOC
:
3634 array_init(return_value
);
3636 case PHP_PQRES_FETCH_OBJECT
:
3637 object_init(return_value
);
3640 for (r
= 0, rows
= PQntuples(obj
->intern
->res
); r
< rows
; ++r
) {
3643 cur
= &return_value
;
3644 for (k
= 0; k
< ks
; ++k
) {
3645 char *key
= PQgetvalue(obj
->intern
->res
, r
, keys
[k
].num
);
3646 int len
= PQgetlength(obj
->intern
->res
, r
, keys
[k
].num
);
3648 if (SUCCESS
!= zend_symtable_find(HASH_OF(*cur
), key
, len
+ 1, (void *) &cur
)) {
3652 switch (fetch_type
) {
3653 case PHP_PQRES_FETCH_ARRAY
:
3654 case PHP_PQRES_FETCH_ASSOC
:
3657 case PHP_PQRES_FETCH_OBJECT
:
3661 if (SUCCESS
!= zend_symtable_update(HASH_OF(*cur
), key
, len
+ 1, (void *) &tmp
, sizeof(zval
*), (void *) &cur
)) {
3662 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create map");
3668 for (v
= 0; v
< vs
; ++v
) {
3669 char *val
= PQgetvalue(obj
->intern
->res
, r
, vals
[v
].num
);
3670 int len
= PQgetlength(obj
->intern
->res
, r
, vals
[v
].num
);
3672 switch (fetch_type
) {
3673 case PHP_PQRES_FETCH_ARRAY
:
3674 add_index_stringl(*cur
, vals
[v
].num
, val
, len
, 1);
3676 case PHP_PQRES_FETCH_ASSOC
:
3677 add_assoc_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3679 case PHP_PQRES_FETCH_OBJECT
:
3680 add_property_stringl(*cur
, vals
[v
].name
, val
, len
, 1);
3685 php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, cur TSRMLS_CC
);
3691 if (keys
&& keys
!= &def
) {
3701 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all
, 0, 0, 0)
3702 ZEND_ARG_INFO(0, fetch_type
)
3703 ZEND_END_ARG_INFO();
3704 static PHP_METHOD(pqres
, fetchAll
) {
3705 zend_error_handling zeh
;
3706 long fetch_type
= -1;
3709 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3710 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &fetch_type
);
3711 zend_restore_error_handling(&zeh TSRMLS_CC
);
3713 if (SUCCESS
== rv
) {
3714 php_pqres_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3716 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3718 int r
, rows
= PQntuples(obj
->intern
->res
);
3720 if (fetch_type
== -1) {
3721 fetch_type
= obj
->intern
->iter
? obj
->intern
->iter
->fetch_type
: PHP_PQRES_FETCH_ARRAY
;
3724 array_init(return_value
);
3725 for (r
= 0; r
< rows
; ++r
) {
3726 add_next_index_zval(return_value
, php_pqres_row_to_zval(obj
->intern
->res
, r
, fetch_type
, NULL TSRMLS_CC
));
3732 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count
, 0, 0, 0)
3733 ZEND_END_ARG_INFO();
3734 static PHP_METHOD(pqres
, count
) {
3735 if (SUCCESS
== zend_parse_parameters_none()) {
3738 if (SUCCESS
!= php_pqres_count_elements(getThis(), &count TSRMLS_CC
)) {
3739 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Result not initialized");
3746 static zend_function_entry php_pqres_methods
[] = {
3747 PHP_ME(pqres
, bind
, ai_pqres_bind
, ZEND_ACC_PUBLIC
)
3748 PHP_ME(pqres
, fetchBound
, ai_pqres_fetch_bound
, ZEND_ACC_PUBLIC
)
3749 PHP_ME(pqres
, fetchRow
, ai_pqres_fetch_row
, ZEND_ACC_PUBLIC
)
3750 PHP_ME(pqres
, fetchCol
, ai_pqres_fetch_col
, ZEND_ACC_PUBLIC
)
3751 PHP_ME(pqres
, fetchAll
, ai_pqres_fetch_all
, ZEND_ACC_PUBLIC
)
3752 PHP_ME(pqres
, count
, ai_pqres_count
, ZEND_ACC_PUBLIC
)
3753 PHP_ME(pqres
, map
, ai_pqres_map
, ZEND_ACC_PUBLIC
)
3757 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct
, 0, 0, 3)
3758 ZEND_ARG_OBJ_INFO(0, Connection
, pq
\\Connection
, 0)
3759 ZEND_ARG_INFO(0, type
)
3760 ZEND_ARG_INFO(0, query
)
3761 ZEND_ARG_ARRAY_INFO(0, types
, 1)
3762 ZEND_ARG_INFO(0, async
)
3763 ZEND_END_ARG_INFO();
3764 static PHP_METHOD(pqstm
, __construct
) {
3765 zend_error_handling zeh
;
3766 zval
*zconn
, *ztypes
= NULL
;
3767 char *name_str
, *query_str
;
3768 int name_len
, *query_len
;
3769 zend_bool async
= 0;
3772 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3773 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
);
3774 zend_restore_error_handling(&zeh TSRMLS_CC
);
3776 if (SUCCESS
== rv
) {
3777 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3778 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
3780 if (!conn_obj
->intern
) {
3781 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
3784 rv
= php_pqconn_prepare_async(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3786 rv
= php_pqconn_prepare(zconn
, conn_obj
, name_str
, query_str
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL TSRMLS_CC
);
3789 if (SUCCESS
== rv
) {
3790 php_pqstm_t
*stm
= ecalloc(1, sizeof(*stm
));
3792 php_pq_object_addref(conn_obj TSRMLS_CC
);
3793 stm
->conn
= conn_obj
;
3794 stm
->name
= estrdup(name_str
);
3795 ZEND_INIT_SYMTABLE(&stm
->bound
);
3801 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_bind
, 0, 0, 2)
3802 ZEND_ARG_INFO(0, param_no
)
3803 ZEND_ARG_INFO(1, param_ref
)
3804 ZEND_END_ARG_INFO();
3805 static PHP_METHOD(pqstm
, bind
) {
3809 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "lz", ¶m_no
, ¶m_ref
)) {
3810 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3813 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3815 Z_ADDREF_P(param_ref
);
3816 zend_hash_index_update(&obj
->intern
->bound
, param_no
, (void *) ¶m_ref
, sizeof(zval
*), NULL
);
3817 zend_hash_sort(&obj
->intern
->bound
, zend_qsort
, compare_index
, 0 TSRMLS_CC
);
3822 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec
, 0, 0, 0)
3823 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3824 ZEND_END_ARG_INFO();
3825 static PHP_METHOD(pqstm
, exec
) {
3826 zend_error_handling zeh
;
3827 zval
*zparams
= NULL
;
3830 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3831 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!", &zparams
);
3832 zend_restore_error_handling(&zeh TSRMLS_CC
);
3834 if (SUCCESS
== rv
) {
3835 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3838 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3841 char **params
= NULL
;
3845 ZEND_INIT_SYMTABLE(&zdtor
);
3848 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3850 count
= php_pq_params_to_array(&obj
->intern
->bound
, ¶ms
, &zdtor TSRMLS_CC
);
3853 res
= PQexecPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0);
3858 zend_hash_destroy(&zdtor
);
3861 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3862 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3863 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
3864 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3870 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec_async
, 0, 0, 0)
3871 ZEND_ARG_ARRAY_INFO(0, params
, 1)
3872 ZEND_ARG_INFO(0, callable
)
3873 ZEND_END_ARG_INFO();
3874 static PHP_METHOD(pqstm
, execAsync
) {
3875 zend_error_handling zeh
;
3876 zval
*zparams
= NULL
;
3877 php_pq_callback_t resolver
= {{0}};
3880 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3881 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|a/!f", &zparams
, &resolver
.fci
, &resolver
.fcc
);
3882 zend_restore_error_handling(&zeh TSRMLS_CC
);
3884 if (SUCCESS
== rv
) {
3885 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3888 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3891 char **params
= NULL
;
3895 ZEND_INIT_SYMTABLE(&zdtor
);
3896 count
= php_pq_params_to_array(Z_ARRVAL_P(zparams
), ¶ms
, &zdtor TSRMLS_CC
);
3899 if (!PQsendQueryPrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
, count
, (const char *const*) params
, NULL
, NULL
, 0)) {
3900 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3901 } else if (obj
->intern
->conn
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
->intern
->conn
)) {
3902 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3904 php_pq_callback_dtor(&obj
->intern
->conn
->intern
->onevent
);
3905 if (resolver
.fci
.size
> 0) {
3906 obj
->intern
->conn
->intern
->onevent
= resolver
;
3907 php_pq_callback_addref(&obj
->intern
->conn
->intern
->onevent
);
3909 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3916 zend_hash_destroy(&zdtor
);
3919 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3924 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc
, 0, 0, 0)
3925 ZEND_END_ARG_INFO();
3926 static PHP_METHOD(pqstm
, desc
) {
3927 zend_error_handling zeh
;
3930 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3931 rv
= zend_parse_parameters_none();
3932 zend_restore_error_handling(&zeh TSRMLS_CC
);
3934 if (SUCCESS
== rv
) {
3935 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3938 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3940 PGresult
*res
= PQdescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
);
3943 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to describe statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3945 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
3948 array_init(return_value
);
3949 for (p
= 0, params
= PQnparams(res
); p
< params
; ++p
) {
3950 add_next_index_long(return_value
, PQparamtype(res
, p
));
3954 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3960 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_desc_async
, 0, 0, 0)
3961 ZEND_END_ARG_INFO();
3962 static PHP_METHOD(pqstm
, descAsync
) {
3963 zend_error_handling zeh
;
3966 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
3967 rv
= zend_parse_parameters_none();
3968 zend_restore_error_handling(&zeh TSRMLS_CC
);
3970 if (SUCCESS
== rv
) {
3971 php_pqstm_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
3974 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Statement not initialized");
3975 } else if (!PQsendDescribePrepared(obj
->intern
->conn
->intern
->conn
, obj
->intern
->name
)) {
3976 throw_exce(EX_IO TSRMLS_CC
, "Failed to describe statement: %s", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
3978 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
3979 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
3984 static zend_function_entry php_pqstm_methods
[] = {
3985 PHP_ME(pqstm
, __construct
, ai_pqstm_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
3986 PHP_ME(pqstm
, bind
, ai_pqstm_bind
, ZEND_ACC_PUBLIC
)
3987 PHP_ME(pqstm
, exec
, ai_pqstm_exec
, ZEND_ACC_PUBLIC
)
3988 PHP_ME(pqstm
, desc
, ai_pqstm_desc
, ZEND_ACC_PUBLIC
)
3989 PHP_ME(pqstm
, execAsync
, ai_pqstm_exec_async
, ZEND_ACC_PUBLIC
)
3990 PHP_ME(pqstm
, descAsync
, ai_pqstm_desc_async
, ZEND_ACC_PUBLIC
)
3994 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct
, 0, 0, 1)
3995 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
3996 ZEND_ARG_INFO(0, async
)
3997 ZEND_ARG_INFO(0, isolation
)
3998 ZEND_ARG_INFO(0, readonly
)
3999 ZEND_ARG_INFO(0, deferrable
)
4000 ZEND_END_ARG_INFO();
4001 static PHP_METHOD(pqtxn
, __construct
) {
4002 zend_error_handling zeh
;
4004 long isolation
= PHP_PQTXN_READ_COMMITTED
;
4005 zend_bool async
= 0, readonly
= 0, deferrable
= 0;
4008 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4009 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|blbb", &zconn
, php_pqconn_class_entry
, &async
, &isolation
, &readonly
, &deferrable
);
4010 zend_restore_error_handling(&zeh TSRMLS_CC
);
4012 if (SUCCESS
== rv
) {
4013 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4015 if (!conn_obj
->intern
) {
4016 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4019 rv
= php_pqconn_start_transaction_async(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
4021 rv
= php_pqconn_start_transaction(zconn
, conn_obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
4024 if (SUCCESS
== rv
) {
4025 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4027 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4029 php_pq_object_addref(conn_obj TSRMLS_CC
);
4030 obj
->intern
->conn
= conn_obj
;
4031 obj
->intern
->open
= 1;
4032 obj
->intern
->isolation
= isolation
;
4033 obj
->intern
->readonly
= readonly
;
4034 obj
->intern
->deferrable
= deferrable
;
4040 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint
, 0, 0, 0)
4041 ZEND_END_ARG_INFO();
4042 static PHP_METHOD(pqtxn
, savepoint
) {
4043 zend_error_handling zeh
;
4046 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4047 rv
= zend_parse_parameters_none();
4048 zend_restore_error_handling(&zeh TSRMLS_CC
);
4050 if (SUCCESS
== rv
) {
4051 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4054 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4055 } else if (!obj
->intern
->open
) {
4056 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4059 smart_str cmd
= {0};
4061 smart_str_appends(&cmd
, "SAVEPOINT \"");
4062 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4063 smart_str_appends(&cmd
, "\"");
4066 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4069 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4071 php_pqres_success(res TSRMLS_CC
);
4075 smart_str_free(&cmd
);
4080 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_savepoint_async
, 0, 0, 0)
4081 ZEND_END_ARG_INFO();
4082 static PHP_METHOD(pqtxn
, savepointAsync
) {
4083 zend_error_handling zeh
;
4086 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4087 rv
= zend_parse_parameters_none();
4088 zend_restore_error_handling(&zeh TSRMLS_CC
);
4090 if (SUCCESS
== rv
) {
4091 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4094 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4095 } else if (!obj
->intern
->open
) {
4096 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4098 smart_str cmd
= {0};
4100 smart_str_appends(&cmd
, "SAVEPOINT \"");
4101 smart_str_append_unsigned(&cmd
, ++obj
->intern
->savepoint
);
4102 smart_str_appends(&cmd
, "\"");
4105 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4106 throw_exce(EX_IO TSRMLS_CC
, "Failed to create %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4109 smart_str_free(&cmd
);
4114 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit
, 0, 0, 0)
4115 ZEND_END_ARG_INFO();
4116 static PHP_METHOD(pqtxn
, commit
) {
4117 zend_error_handling zeh
;
4120 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4121 rv
= zend_parse_parameters_none();
4122 zend_restore_error_handling(&zeh TSRMLS_CC
);
4124 if (SUCCESS
== rv
) {
4125 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4128 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transacation not initialized");
4129 } else if (!obj
->intern
->open
) {
4130 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transacation already closed");
4133 smart_str cmd
= {0};
4135 if (!obj
->intern
->savepoint
) {
4136 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4138 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4139 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4140 smart_str_appends(&cmd
, "\"");
4143 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4147 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4149 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4151 obj
->intern
->open
= 0;
4157 smart_str_free(&cmd
);
4158 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4163 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async
, 0, 0, 0)
4164 ZEND_END_ARG_INFO();
4165 static PHP_METHOD(pqtxn
, commitAsync
) {
4166 zend_error_handling zeh
;
4169 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4170 rv
= zend_parse_parameters_none();
4171 zend_restore_error_handling(&zeh TSRMLS_CC
);
4173 if (SUCCESS
== rv
) {
4174 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4177 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4178 } else if (!obj
->intern
->open
) {
4179 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4182 smart_str cmd
= {0};
4184 if (!obj
->intern
->savepoint
) {
4185 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "COMMIT");
4187 smart_str_appends(&cmd
, "RELEASE SAVEPOINT \"");
4188 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4189 smart_str_appends(&cmd
, "\"");
4192 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4196 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "commmit transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4199 obj
->intern
->open
= 0;
4201 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4202 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4205 smart_str_free(&cmd
);
4210 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback
, 0, 0, 0)
4211 ZEND_END_ARG_INFO();
4212 static PHP_METHOD(pqtxn
, rollback
) {
4213 zend_error_handling zeh
;
4216 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4217 rv
= zend_parse_parameters_none();
4218 zend_restore_error_handling(&zeh TSRMLS_CC
);
4220 if (SUCCESS
== rv
) {
4221 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4224 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4225 } else if (!obj
->intern
->open
) {
4226 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4229 smart_str cmd
= {0};
4231 if (!obj
->intern
->savepoint
) {
4232 res
= PQexec(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4234 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4235 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4236 smart_str_appends(&cmd
, "\"");
4239 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4243 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4245 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4247 obj
->intern
->open
= 0;
4253 smart_str_free(&cmd
);
4254 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4259 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async
, 0, 0, 0)
4260 ZEND_END_ARG_INFO();
4261 static PHP_METHOD(pqtxn
, rollbackAsync
) {
4262 zend_error_handling zeh
;
4265 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4266 rv
= zend_parse_parameters_none();
4267 zend_restore_error_handling(&zeh TSRMLS_CC
);
4269 if (SUCCESS
== rv
) {
4270 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4273 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4274 } else if (!obj
->intern
->open
) {
4275 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction already closed");
4278 smart_str cmd
= {0};
4280 if (!obj
->intern
->savepoint
) {
4281 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, "ROLLBACK");
4283 smart_str_appends(&cmd
, "ROLLBACK TO SAVEPOINT \"");
4284 smart_str_append_unsigned(&cmd
, obj
->intern
->savepoint
--);
4285 smart_str_appends(&cmd
, "\"");
4288 rc
= PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4292 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
? cmd
.c
: "rollback transaction", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4295 obj
->intern
->open
= 0;
4297 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4300 smart_str_free(&cmd
);
4301 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4306 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot
, 0, 0, 0)
4307 ZEND_END_ARG_INFO();
4308 static PHP_METHOD(pqtxn
, exportSnapshot
) {
4309 zend_error_handling zeh
;
4312 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4313 rv
= zend_parse_parameters_none();
4314 zend_restore_error_handling(&zeh TSRMLS_CC
);
4316 if (SUCCESS
== rv
) {
4317 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4320 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4322 PGresult
*res
= PQexec(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()");
4325 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4327 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
4328 RETVAL_STRING(PQgetvalue(res
, 0, 0), 1);
4334 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4339 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_export_snapshot_async
, 0, 0, 0)
4340 ZEND_END_ARG_INFO();
4341 static PHP_METHOD(pqtxn
, exportSnapshotAsync
) {
4342 zend_error_handling zeh
;
4345 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4346 rv
= zend_parse_parameters_none();
4347 zend_restore_error_handling(&zeh TSRMLS_CC
);
4349 if (SUCCESS
== rv
) {
4350 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4353 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4354 } else if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, "SELECT pg_export_snapshot()")) {
4355 throw_exce(EX_IO TSRMLS_CC
, "Failed to export transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4357 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4358 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4363 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot
, 0, 0, 1)
4364 ZEND_ARG_INFO(0, snapshot_id
)
4365 ZEND_END_ARG_INFO();
4366 static PHP_METHOD(pqtxn
, importSnapshot
) {
4367 zend_error_handling zeh
;
4372 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4373 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4374 zend_restore_error_handling(&zeh TSRMLS_CC
);
4376 if (SUCCESS
== rv
) {
4377 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4380 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4381 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4382 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4384 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4387 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4390 smart_str cmd
= {0};
4392 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4393 smart_str_appends(&cmd
, sid
);
4396 res
= PQexec(obj
->intern
->conn
->intern
->conn
, cmd
.c
);
4399 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to import transaction snapshot (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4401 php_pqres_success(res TSRMLS_CC
);
4405 smart_str_free(&cmd
);
4406 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4412 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_import_snapshot_async
, 0, 0, 1)
4413 ZEND_ARG_INFO(0, snapshot_id
)
4414 ZEND_END_ARG_INFO();
4415 static PHP_METHOD(pqtxn
, importSnapshotAsync
) {
4416 zend_error_handling zeh
;
4421 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4422 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &snapshot_str
, &snapshot_len
);
4423 zend_restore_error_handling(&zeh TSRMLS_CC
);
4425 if (SUCCESS
== rv
) {
4426 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4429 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4430 } else if (obj
->intern
->isolation
< PHP_PQTXN_REPEATABLE_READ
) {
4431 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transaction must have at least isolation level REPEATABLE READ to be able to import a snapshot");
4433 char *sid
= PQescapeLiteral(obj
->intern
->conn
->intern
->conn
, snapshot_str
, snapshot_len
);
4436 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to quote snapshot identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4438 smart_str cmd
= {0};
4440 smart_str_appends(&cmd
, "SET TRANSACTION SNAPSHOT ");
4441 smart_str_appends(&cmd
, sid
);
4444 if (!PQsendQuery(obj
->intern
->conn
->intern
->conn
, cmd
.c
)) {
4445 throw_exce(EX_IO TSRMLS_CC
, "Failed to %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4447 obj
->intern
->conn
->intern
->poller
= PQconsumeInput
;
4450 smart_str_free(&cmd
);
4451 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4457 static const char *strmode(long mode
)
4459 switch (mode
& (INV_READ
|INV_WRITE
)) {
4460 case INV_READ
|INV_WRITE
:
4471 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_open_lob
, 0, 0, 1)
4472 ZEND_ARG_INFO(0, oid
)
4473 ZEND_ARG_INFO(0, mode
)
4474 ZEND_END_ARG_INFO();
4475 static PHP_METHOD(pqtxn
, openLOB
) {
4476 zend_error_handling zeh
;
4477 long mode
= INV_WRITE
|INV_READ
, loid
;
4480 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4481 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &loid
, &mode
);
4482 zend_restore_error_handling(&zeh TSRMLS_CC
);
4484 if (SUCCESS
== rv
) {
4485 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4488 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4490 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4493 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%u with mode '%s' (%s)", loid
, strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4495 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4499 php_pq_object_addref(obj TSRMLS_CC
);
4502 return_value
->type
= IS_OBJECT
;
4503 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4506 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4511 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_create_lob
, 0, 0, 0)
4512 ZEND_ARG_INFO(0, mode
)
4513 ZEND_END_ARG_INFO();
4514 static PHP_METHOD(pqtxn
, createLOB
) {
4515 zend_error_handling zeh
;
4516 long mode
= INV_WRITE
|INV_READ
;
4519 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4520 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &mode
);
4521 zend_restore_error_handling(&zeh TSRMLS_CC
);
4523 if (SUCCESS
== rv
) {
4524 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4527 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4529 Oid loid
= lo_creat(obj
->intern
->conn
->intern
->conn
, mode
);
4531 if (loid
== InvalidOid
) {
4532 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to create large object with mode '%s' (%s)", strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4534 int lofd
= lo_open(obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4537 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%u with mode '%s': %s", loid
, strmode(mode
), PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4539 php_pqlob_t
*lob
= ecalloc(1, sizeof(*lob
));
4543 php_pq_object_addref(obj TSRMLS_CC
);
4546 return_value
->type
= IS_OBJECT
;
4547 return_value
->value
.obj
= php_pqlob_create_object_ex(php_pqlob_class_entry
, lob
, NULL TSRMLS_CC
);
4551 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4556 ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_unlink_lob
, 0, 0, 1)
4557 ZEND_ARG_INFO(0, oid
)
4558 ZEND_END_ARG_INFO();
4559 static PHP_METHOD(pqtxn
, unlinkLOB
) {
4560 zend_error_handling zeh
;
4564 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4565 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &loid
);
4566 zend_restore_error_handling(&zeh TSRMLS_CC
);
4568 if (SUCCESS
== rv
) {
4569 php_pqtxn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4572 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4574 int rc
= lo_unlink(obj
->intern
->conn
->intern
->conn
, loid
);
4577 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to unlink LOB (oid=%u): %s", loid
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
4580 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
4585 static zend_function_entry php_pqtxn_methods
[] = {
4586 PHP_ME(pqtxn
, __construct
, ai_pqtxn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4587 PHP_ME(pqtxn
, commit
, ai_pqtxn_commit
, ZEND_ACC_PUBLIC
)
4588 PHP_ME(pqtxn
, rollback
, ai_pqtxn_rollback
, ZEND_ACC_PUBLIC
)
4589 PHP_ME(pqtxn
, commitAsync
, ai_pqtxn_commit_async
, ZEND_ACC_PUBLIC
)
4590 PHP_ME(pqtxn
, rollbackAsync
, ai_pqtxn_rollback_async
, ZEND_ACC_PUBLIC
)
4591 PHP_ME(pqtxn
, savepoint
, ai_pqtxn_savepoint
, ZEND_ACC_PUBLIC
)
4592 PHP_ME(pqtxn
, savepointAsync
, ai_pqtxn_savepoint_async
, ZEND_ACC_PUBLIC
)
4593 PHP_ME(pqtxn
, exportSnapshot
, ai_pqtxn_export_snapshot
, ZEND_ACC_PUBLIC
)
4594 PHP_ME(pqtxn
, exportSnapshotAsync
, ai_pqtxn_export_snapshot_async
, ZEND_ACC_PUBLIC
)
4595 PHP_ME(pqtxn
, importSnapshot
, ai_pqtxn_import_snapshot
, ZEND_ACC_PUBLIC
)
4596 PHP_ME(pqtxn
, importSnapshotAsync
, ai_pqtxn_import_snapshot_async
, ZEND_ACC_PUBLIC
)
4597 PHP_ME(pqtxn
, openLOB
, ai_pqtxn_open_lob
, ZEND_ACC_PUBLIC
)
4598 PHP_ME(pqtxn
, createLOB
, ai_pqtxn_create_lob
, ZEND_ACC_PUBLIC
)
4599 PHP_ME(pqtxn
, unlinkLOB
, ai_pqtxn_unlink_lob
, ZEND_ACC_PUBLIC
)
4603 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct
, 0, 0, 1)
4604 ZEND_ARG_OBJ_INFO(0, connection
, pq
\\Connection
, 0)
4605 ZEND_END_ARG_INFO();
4606 static PHP_METHOD(pqcancel
, __construct
) {
4607 zend_error_handling zeh
;
4611 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4612 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zconn
, php_pqconn_class_entry
);
4613 zend_restore_error_handling(&zeh TSRMLS_CC
);
4615 if (SUCCESS
== rv
) {
4616 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
4618 if (!conn_obj
->intern
) {
4619 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
4621 PGcancel
*cancel
= PQgetCancel(conn_obj
->intern
->conn
);
4624 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to acquire cancel (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
4626 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4628 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4629 obj
->intern
->cancel
= cancel
;
4630 php_pq_object_addref(conn_obj TSRMLS_CC
);
4631 obj
->intern
->conn
= conn_obj
;
4637 ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel
, 0, 0, 0)
4638 ZEND_END_ARG_INFO();
4639 static PHP_METHOD(pqcancel
, cancel
) {
4640 zend_error_handling zeh
;
4643 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4644 rv
= zend_parse_parameters_none();
4645 zend_restore_error_handling(&zeh TSRMLS_CC
);
4647 if (SUCCESS
== rv
) {
4648 php_pqcancel_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4651 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Cancel not initialized");
4653 char err
[256] = {0};
4655 if (!PQcancel(obj
->intern
->cancel
, err
, sizeof(err
))) {
4656 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to request cancellation (%s)", err
);
4662 static zend_function_entry php_pqcancel_methods
[] = {
4663 PHP_ME(pqcancel
, __construct
, ai_pqcancel_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4664 PHP_ME(pqcancel
, cancel
, ai_pqcancel_cancel
, ZEND_ACC_PUBLIC
)
4668 static size_t php_pqlob_stream_write(php_stream
*stream
, const char *buffer
, size_t length TSRMLS_DC
)
4670 php_pqlob_object_t
*obj
= stream
->abstract
;
4674 written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4677 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to write to LOB with oid=%u (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4680 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4686 static size_t php_pqlob_stream_read(php_stream
*stream
, char *buffer
, size_t length TSRMLS_DC
)
4688 php_pqlob_object_t
*obj
= stream
->abstract
;
4693 if (!buffer
&& !length
) {
4694 if (lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
) == lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, 0, SEEK_CUR
)) {
4698 read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4701 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to read from LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4705 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4711 static STATUS
php_pqlob_stream_close(php_stream
*stream
, int close_handle TSRMLS_DC
)
4716 static int php_pqlob_stream_flush(php_stream
*stream TSRMLS_DC
)
4721 static STATUS
php_pqlob_stream_seek(php_stream
*stream
, off_t offset
, int whence
, off_t
*newoffset TSRMLS_DC
)
4723 STATUS rv
= FAILURE
;
4724 php_pqlob_object_t
*obj
= stream
->abstract
;
4727 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4730 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to seek offset in LOB with oid=%d (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4733 *newoffset
= position
;
4737 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4743 static php_stream_ops php_pqlob_stream_ops
= {
4744 /* stdio like functions - these are mandatory! */
4745 php_pqlob_stream_write
,
4746 php_pqlob_stream_read
,
4747 php_pqlob_stream_close
,
4748 php_pqlob_stream_flush
,
4752 /* these are optional */
4753 php_pqlob_stream_seek
,
4756 NULL
, /* set_option */
4759 static void php_pqlob_object_update_stream(zval
*this_ptr
, php_pqlob_object_t
*obj
, zval
**zstream_ptr TSRMLS_DC
)
4761 zval
*zstream
, zmember
;
4764 INIT_PZVAL(&zmember
);
4765 ZVAL_STRINGL(&zmember
, "stream", sizeof("stream")-1, 0);
4767 MAKE_STD_ZVAL(zstream
);
4769 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4771 stream
= php_stream_alloc(&php_pqlob_stream_ops
, obj
, NULL
, "r+b");
4772 stream
->flags
|= PHP_STREAM_FLAG_NO_FCLOSE
;
4773 zend_list_addref(obj
->intern
->stream
= stream
->rsrc_id
);
4774 php_stream_to_zval(stream
, zstream
);
4776 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zstream
, NULL TSRMLS_CC
);
4779 *zstream_ptr
= zstream
;
4781 zval_ptr_dtor(&zstream
);
4785 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_construct
, 0, 0, 1)
4786 ZEND_ARG_OBJ_INFO(0, transaction
, pq
\\Transaction
, 0)
4787 ZEND_ARG_INFO(0, oid
)
4788 ZEND_ARG_INFO(0, mode
)
4789 ZEND_END_ARG_INFO();
4790 static PHP_METHOD(pqlob
, __construct
) {
4791 zend_error_handling zeh
;
4793 long mode
= INV_WRITE
|INV_READ
, loid
= InvalidOid
;
4796 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4797 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O|ll", &ztxn
, php_pqtxn_class_entry
, &loid
, &mode
);
4798 zend_restore_error_handling(&zeh TSRMLS_CC
);
4800 if (SUCCESS
== rv
) {
4801 php_pqtxn_object_t
*txn_obj
= zend_object_store_get_object(ztxn TSRMLS_CC
);
4803 if (!txn_obj
->intern
) {
4804 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Transaction not initialized");
4805 } else if (!txn_obj
->intern
->open
) {
4806 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\Transation already closed");
4808 if (loid
== InvalidOid
) {
4809 loid
= lo_creat(txn_obj
->intern
->conn
->intern
->conn
, mode
);
4812 if (loid
== InvalidOid
) {
4813 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
));
4815 int lofd
= lo_open(txn_obj
->intern
->conn
->intern
->conn
, loid
, mode
);
4818 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to open large object with oid=%u with mode '%s' (%s)", loid
, strmode(mode
), PHP_PQerrorMessage(txn_obj
->intern
->conn
->intern
->conn
));
4820 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4822 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
4823 obj
->intern
->lofd
= lofd
;
4824 obj
->intern
->loid
= loid
;
4825 php_pq_object_addref(txn_obj TSRMLS_CC
);
4826 obj
->intern
->txn
= txn_obj
;
4830 php_pqconn_notify_listeners(txn_obj
->intern
->conn TSRMLS_CC
);
4835 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_write
, 0, 0, 1)
4836 ZEND_ARG_INFO(0, data
)
4837 ZEND_END_ARG_INFO();
4838 static PHP_METHOD(pqlob
, write
) {
4839 zend_error_handling zeh
;
4844 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4845 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
4846 zend_restore_error_handling(&zeh TSRMLS_CC
);
4848 if (SUCCESS
== rv
) {
4849 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4852 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4854 int written
= lo_write(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, data_str
, data_len
);
4857 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to write to LOB with oid=%u (%s)", obj
->intern
->loid
, PHP_PQerrorMessage(obj
->intern
->txn
->intern
->conn
->intern
->conn
));
4859 RETVAL_LONG(written
);
4862 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4867 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_read
, 0, 0, 0)
4868 ZEND_ARG_INFO(0, length
)
4869 ZEND_ARG_INFO(1, read
)
4870 ZEND_END_ARG_INFO();
4871 static PHP_METHOD(pqlob
, read
) {
4872 zend_error_handling zeh
;
4873 long length
= 0x1000;
4877 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4878 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lz!", &length
, &zread
);
4879 zend_restore_error_handling(&zeh TSRMLS_CC
);
4881 if (SUCCESS
== rv
) {
4882 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4885 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4887 char *buffer
= emalloc(length
+ 1);
4888 int read
= lo_read(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, buffer
, length
);
4892 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
));
4896 ZVAL_LONG(zread
, read
);
4898 buffer
[read
] = '\0';
4899 RETVAL_STRINGL(buffer
, read
, 0);
4902 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4907 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_seek
, 0, 0, 1)
4908 ZEND_ARG_INFO(0, offset
)
4909 ZEND_ARG_INFO(0, whence
)
4910 ZEND_END_ARG_INFO();
4911 static PHP_METHOD(pqlob
, seek
) {
4912 zend_error_handling zeh
;
4913 long offset
, whence
= SEEK_SET
;
4916 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4917 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|l", &offset
, &whence
);
4918 zend_restore_error_handling(&zeh TSRMLS_CC
);
4920 if (SUCCESS
== rv
) {
4921 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4924 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4926 int position
= lo_lseek(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, offset
, whence
);
4929 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
));
4931 RETVAL_LONG(position
);
4934 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4939 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_tell
, 0, 0, 0)
4940 ZEND_END_ARG_INFO();
4941 static PHP_METHOD(pqlob
, tell
) {
4942 zend_error_handling zeh
;
4945 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4946 rv
= zend_parse_parameters_none();
4947 zend_restore_error_handling(&zeh TSRMLS_CC
);
4949 if (SUCCESS
== rv
) {
4950 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4953 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4955 int position
= lo_tell(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
);
4958 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
));
4960 RETVAL_LONG(position
);
4963 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4968 ZEND_BEGIN_ARG_INFO_EX(ai_pqlob_truncate
, 0, 0, 0)
4969 ZEND_ARG_INFO(0, length
)
4970 ZEND_END_ARG_INFO();
4971 static PHP_METHOD(pqlob
, truncate
) {
4972 zend_error_handling zeh
;
4976 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
4977 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &length
);
4978 zend_restore_error_handling(&zeh TSRMLS_CC
);
4980 if (SUCCESS
== rv
) {
4981 php_pqlob_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
4984 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\LOB not initialized");
4986 int rc
= lo_truncate(obj
->intern
->txn
->intern
->conn
->intern
->conn
, obj
->intern
->lofd
, length
);
4989 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
));
4992 php_pqconn_notify_listeners(obj
->intern
->txn
->intern
->conn TSRMLS_CC
);
4997 static zend_function_entry php_pqlob_methods
[] = {
4998 PHP_ME(pqlob
, __construct
, ai_pqlob_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
4999 PHP_ME(pqlob
, write
, ai_pqlob_write
, ZEND_ACC_PUBLIC
)
5000 PHP_ME(pqlob
, read
, ai_pqlob_read
, ZEND_ACC_PUBLIC
)
5001 PHP_ME(pqlob
, seek
, ai_pqlob_seek
, ZEND_ACC_PUBLIC
)
5002 PHP_ME(pqlob
, tell
, ai_pqlob_tell
, ZEND_ACC_PUBLIC
)
5003 PHP_ME(pqlob
, truncate
, ai_pqlob_truncate
, ZEND_ACC_PUBLIC
)
5007 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_construct
, 0, 0, 3)
5008 ZEND_ARG_OBJ_INFO(0, "connection", pq
\\Connection
, 0)
5009 ZEND_ARG_INFO(0, expression
)
5010 ZEND_ARG_INFO(0, direction
)
5011 ZEND_ARG_INFO(0, options
)
5012 ZEND_END_ARG_INFO();
5013 static PHP_METHOD(pqcopy
, __construct
) {
5014 zend_error_handling zeh
;
5016 char *expr_str
, *opt_str
= "";
5017 int expr_len
, opt_len
= 0;
5021 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5022 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
);
5023 zend_restore_error_handling(&zeh TSRMLS_CC
);
5025 if (SUCCESS
== rv
) {
5026 php_pqconn_object_t
*conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
5028 if (!conn_obj
->intern
) {
5029 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
5031 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5032 smart_str cmd
= {0};
5035 smart_str_appends(&cmd
, "COPY ");
5036 smart_str_appendl(&cmd
, expr_str
, expr_len
);
5038 switch (direction
) {
5039 case PHP_PQCOPY_FROM_STDIN
:
5040 smart_str_appends(&cmd
, " FROM STDIN ");
5042 case PHP_PQCOPY_TO_STDOUT
:
5043 smart_str_appends(&cmd
, " TO STDOUT ");
5046 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
);
5047 smart_str_free(&cmd
);
5050 smart_str_appendl(&cmd
, opt_str
, opt_len
);
5053 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
5056 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start %s (%s)", cmd
.c
, PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5058 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
5059 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
5060 obj
->intern
->direction
= direction
;
5061 obj
->intern
->expression
= estrdup(expr_str
);
5062 obj
->intern
->options
= estrdup(opt_str
);
5063 obj
->intern
->conn
= conn_obj
;
5064 php_pq_object_addref(conn_obj TSRMLS_CC
);
5070 smart_str_free(&cmd
);
5071 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5076 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_put
, 0, 0, 1)
5077 ZEND_ARG_INFO(0, data
)
5078 ZEND_END_ARG_INFO();
5079 static PHP_METHOD(pqcopy
, put
) {
5080 zend_error_handling zeh
;
5085 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5086 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &data_str
, &data_len
);
5087 zend_restore_error_handling(&zeh TSRMLS_CC
);
5089 if (SUCCESS
== rv
) {
5090 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5093 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
5094 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
5095 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not initialized with FROM_STDIN");
5097 if (1 != PQputCopyData(obj
->intern
->conn
->intern
->conn
, data_str
, data_len
)) {
5098 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to put COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5100 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5105 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_end
, 0, 0, 0)
5106 ZEND_ARG_INFO(0, error
)
5107 ZEND_END_ARG_INFO();
5108 static PHP_METHOD(pqcopy
, end
) {
5109 zend_error_handling zeh
;
5110 char *error_str
= NULL
;
5114 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5115 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &error_str
, &error_len
);
5116 zend_restore_error_handling(&zeh TSRMLS_CC
);
5118 if (SUCCESS
== rv
) {
5119 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5122 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY not intitialized");
5123 } else if (obj
->intern
->direction
!= PHP_PQCOPY_FROM_STDIN
) {
5124 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intitialized with FROM_STDIN");
5126 if (1 != PQputCopyEnd(obj
->intern
->conn
->intern
->conn
, error_str
)) {
5127 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to end COPY (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5129 PGresult
*res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
5132 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5134 php_pqres_success(res TSRMLS_CC
);
5139 php_pqconn_notify_listeners(obj
->intern
->conn TSRMLS_CC
);
5144 ZEND_BEGIN_ARG_INFO_EX(ai_pqcopy_get
, 0, 0, 1)
5145 ZEND_ARG_INFO(1, data
)
5146 ZEND_END_ARG_INFO();
5147 static PHP_METHOD(pqcopy
, get
) {
5148 zend_error_handling zeh
;
5152 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
5153 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
);
5154 zend_restore_error_handling(&zeh TSRMLS_CC
);
5156 if (SUCCESS
== rv
) {
5157 php_pqcopy_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
5160 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\COPY not initialized");
5161 } else if (obj
->intern
->direction
!= PHP_PQCOPY_TO_STDOUT
) {
5162 throw_exce(EX_RUNTIME TSRMLS_CC
, "pq\\COPY was not intialized with TO_STDOUT");
5165 char *buffer
= NULL
;
5166 int bytes
= PQgetCopyData(obj
->intern
->conn
->intern
->conn
, &buffer
, 0);
5170 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY data (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5174 res
= PQgetResult(obj
->intern
->conn
->intern
->conn
);
5177 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to fetch COPY result (%s)", PHP_PQerrorMessage(obj
->intern
->conn
->intern
->conn
));
5179 php_pqres_success(res TSRMLS_CC
);
5188 ZVAL_STRINGL(zdata
, buffer
, bytes
, 1);
5190 ZVAL_EMPTY_STRING(zdata
);
5203 static zend_function_entry php_pqcopy_methods
[] = {
5204 PHP_ME(pqcopy
, __construct
, ai_pqcopy_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
5205 PHP_ME(pqcopy
, put
, ai_pqcopy_put
, ZEND_ACC_PUBLIC
)
5206 PHP_ME(pqcopy
, end
, ai_pqcopy_end
, ZEND_ACC_PUBLIC
)
5207 PHP_ME(pqcopy
, get
, ai_pqcopy_get
, ZEND_ACC_PUBLIC
)
5211 static zend_function_entry php_pqexc_methods
[] = {
5215 /* {{{ PHP_MINIT_FUNCTION
5217 static PHP_MINIT_FUNCTION(pq
)
5219 zend_class_entry ce
= {0};
5220 php_pq_object_prophandler_t ph
= {0};
5222 INIT_NS_CLASS_ENTRY(ce
, "pq", "Exception", php_pqexc_methods
);
5223 php_pqexc_interface_class_entry
= zend_register_internal_interface(&ce TSRMLS_CC
);
5225 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("INVALID_ARGUMENT"), EX_INVALID_ARGUMENT TSRMLS_CC
);
5226 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("RUNTIME"), EX_RUNTIME TSRMLS_CC
);
5227 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("CONNECTION_FAILED"), EX_CONNECTION_FAILED TSRMLS_CC
);
5228 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("IO"), EX_IO TSRMLS_CC
);
5229 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("ESCAPE"), EX_ESCAPE TSRMLS_CC
);
5230 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("BAD_METHODCALL"), EX_BAD_METHODCALL TSRMLS_CC
);
5231 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("UNINITIALIZED"), EX_UNINITIALIZED TSRMLS_CC
);
5232 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("DOMAIN"), EX_DOMAIN TSRMLS_CC
);
5233 zend_declare_class_constant_long(php_pqexc_interface_class_entry
, ZEND_STRL("SQL"), EX_SQL TSRMLS_CC
);
5235 memset(&ce
, 0, sizeof(ce
));
5236 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "InvalidArgumentException", php_pqexc_methods
);
5237 php_pqexc_invalid_argument_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_InvalidArgumentException
, "InvalidArgumentException" TSRMLS_CC
);
5238 zend_class_implements(php_pqexc_invalid_argument_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5240 memset(&ce
, 0, sizeof(ce
));
5241 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "RuntimeException", php_pqexc_methods
);
5242 php_pqexc_runtime_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_RuntimeException
, "RuntimeException" TSRMLS_CC
);
5243 zend_class_implements(php_pqexc_runtime_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5245 memset(&ce
, 0, sizeof(ce
));
5246 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "BadMethodCallException", php_pqexc_methods
);
5247 php_pqexc_bad_methodcall_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_BadMethodCallException
, "BadMethodCallException" TSRMLS_CC
);
5248 zend_class_implements(php_pqexc_bad_methodcall_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5250 memset(&ce
, 0, sizeof(ce
));
5251 INIT_NS_CLASS_ENTRY(ce
, "pq\\Exception", "DomainException", php_pqexc_methods
);
5252 php_pqexc_domain_class_entry
= zend_register_internal_class_ex(&ce
, spl_ce_DomainException
, "DomainException" TSRMLS_CC
);
5253 zend_class_implements(php_pqexc_domain_class_entry TSRMLS_CC
, 1, php_pqexc_interface_class_entry
);
5254 zend_declare_property_null(php_pqexc_domain_class_entry
, ZEND_STRL("sqlstate"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5256 memset(&ce
, 0, sizeof(ce
));
5257 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
5258 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5259 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
5261 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5262 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
5263 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
5264 php_pqconn_object_handlers
.clone_obj
= NULL
;
5265 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
5266 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5268 zend_hash_init(&php_pqconn_object_prophandlers
, 14, NULL
, NULL
, 1);
5270 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5271 ph
.read
= php_pqconn_object_read_status
;
5272 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5274 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5275 ph
.read
= php_pqconn_object_read_transaction_status
;
5276 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
5278 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5279 ph
.read
= NULL
; /* forward to std prophandler */
5280 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
5282 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5283 ph
.read
= php_pqconn_object_read_error_message
;
5284 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5286 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5287 ph
.read
= php_pqconn_object_read_busy
;
5288 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
5290 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5291 ph
.read
= php_pqconn_object_read_encoding
;
5292 ph
.write
= php_pqconn_object_write_encoding
;
5293 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
5296 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5297 ph
.read
= php_pqconn_object_read_unbuffered
;
5298 ph
.write
= php_pqconn_object_write_unbuffered
;
5299 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
5302 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5303 ph
.read
= php_pqconn_object_read_db
;
5304 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
5306 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5307 ph
.read
= php_pqconn_object_read_user
;
5308 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
5310 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5311 ph
.read
= php_pqconn_object_read_pass
;
5312 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
5314 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5315 ph
.read
= php_pqconn_object_read_host
;
5316 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
5318 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5319 ph
.read
= php_pqconn_object_read_port
;
5320 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
5322 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5323 ph
.read
= php_pqconn_object_read_options
;
5324 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5326 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5327 ph
.read
= php_pqconn_object_read_event_handlers
;
5328 zend_hash_add(&php_pqconn_object_prophandlers
, "eventHandlers", sizeof("eventHandlers"), (void *) &ph
, sizeof(ph
), NULL
);
5330 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
5331 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
5332 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
5333 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
5334 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
5335 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
5336 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
5337 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
5339 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
5340 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
5341 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
5342 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
5343 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
5345 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
5346 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
5347 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
5348 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
5350 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
5351 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result") TSRMLS_CC
);
5352 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset") TSRMLS_CC
);
5354 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
5355 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
5357 memset(&ce
, 0, sizeof(ce
));
5358 INIT_NS_CLASS_ENTRY(ce
, "pq", "Types", php_pqtypes_methods
);
5359 php_pqtypes_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5360 php_pqtypes_class_entry
->create_object
= php_pqtypes_create_object
;
5362 memcpy(&php_pqtypes_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5363 php_pqtypes_object_handlers
.read_property
= php_pq_object_read_prop
;
5364 php_pqtypes_object_handlers
.write_property
= php_pq_object_write_prop
;
5365 php_pqtypes_object_handlers
.clone_obj
= NULL
;
5366 php_pqtypes_object_handlers
.get_property_ptr_ptr
= NULL
;
5367 php_pqtypes_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5368 php_pqtypes_object_handlers
.has_dimension
= php_pqtypes_object_has_dimension
;
5369 php_pqtypes_object_handlers
.read_dimension
= php_pqtypes_object_read_dimension
;
5370 php_pqtypes_object_handlers
.unset_dimension
= NULL
;
5371 php_pqtypes_object_handlers
.write_dimension
= NULL
;
5373 zend_hash_init(&php_pqtypes_object_prophandlers
, 1, NULL
, NULL
, 1);
5375 zend_declare_property_null(php_pqtypes_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5376 ph
.read
= php_pqtypes_object_read_connection
;
5377 zend_hash_add(&php_pqtypes_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5379 memset(&ce
, 0, sizeof(ce
));
5380 INIT_NS_CLASS_ENTRY(ce
, "pq", "Result", php_pqres_methods
);
5381 php_pqres_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5382 php_pqres_class_entry
->create_object
= php_pqres_create_object
;
5383 php_pqres_class_entry
->iterator_funcs
.funcs
= &php_pqres_iterator_funcs
;
5384 php_pqres_class_entry
->get_iterator
= php_pqres_iterator_init
;
5385 zend_class_implements(php_pqres_class_entry TSRMLS_CC
, 2, zend_ce_traversable
, spl_ce_Countable
);
5387 memcpy(&php_pqres_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5388 php_pqres_object_handlers
.read_property
= php_pq_object_read_prop
;
5389 php_pqres_object_handlers
.write_property
= php_pq_object_write_prop
;
5390 php_pqres_object_handlers
.clone_obj
= NULL
;
5391 php_pqres_object_handlers
.get_property_ptr_ptr
= NULL
;
5392 php_pqres_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5393 php_pqres_object_handlers
.count_elements
= php_pqres_count_elements
;
5395 zend_hash_init(&php_pqres_object_prophandlers
, 6, NULL
, NULL
, 1);
5397 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5398 ph
.read
= php_pqres_object_read_status
;
5399 zend_hash_add(&php_pqres_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
5401 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5402 ph
.read
= php_pqres_object_read_status_message
;
5403 zend_hash_add(&php_pqres_object_prophandlers
, "statusMessage", sizeof("statusMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5405 zend_declare_property_null(php_pqres_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5406 ph
.read
= php_pqres_object_read_error_message
;
5407 zend_hash_add(&php_pqres_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
5409 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5410 ph
.read
= php_pqres_object_read_num_rows
;
5411 zend_hash_add(&php_pqres_object_prophandlers
, "numRows", sizeof("numRows"), (void *) &ph
, sizeof(ph
), NULL
);
5413 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5414 ph
.read
= php_pqres_object_read_num_cols
;
5415 zend_hash_add(&php_pqres_object_prophandlers
, "numCols", sizeof("numCols"), (void *) &ph
, sizeof(ph
), NULL
);
5417 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5418 ph
.read
= php_pqres_object_read_affected_rows
;
5419 zend_hash_add(&php_pqres_object_prophandlers
, "affectedRows", sizeof("affectedRows"), (void *) &ph
, sizeof(ph
), NULL
);
5421 zend_declare_property_long(php_pqres_class_entry
, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5422 ph
.read
= php_pqres_object_read_fetch_type
;
5423 ph
.write
= php_pqres_object_write_fetch_type
;
5424 zend_hash_add(&php_pqres_object_prophandlers
, "fetchType", sizeof("fetchType"), (void *) &ph
, sizeof(ph
), NULL
);
5427 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC
);
5428 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC
);
5429 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC
);
5430 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC
);
5431 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC
);
5432 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC
);
5433 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC
);
5434 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC
);
5435 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC
);
5436 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC
);
5438 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC
);
5439 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC
);
5440 zend_declare_class_constant_long(php_pqres_class_entry
, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC
);
5442 memset(&ce
, 0, sizeof(ce
));
5443 INIT_NS_CLASS_ENTRY(ce
, "pq", "Statement", php_pqstm_methods
);
5444 php_pqstm_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5445 php_pqstm_class_entry
->create_object
= php_pqstm_create_object
;
5447 memcpy(&php_pqstm_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5448 php_pqstm_object_handlers
.read_property
= php_pq_object_read_prop
;
5449 php_pqstm_object_handlers
.write_property
= php_pq_object_write_prop
;
5450 php_pqstm_object_handlers
.clone_obj
= NULL
;
5451 php_pqstm_object_handlers
.get_property_ptr_ptr
= NULL
;
5452 php_pqstm_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5454 zend_hash_init(&php_pqstm_object_prophandlers
, 2, NULL
, NULL
, 1);
5456 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5457 ph
.read
= php_pqstm_object_read_name
;
5458 zend_hash_add(&php_pqstm_object_prophandlers
, "name", sizeof("name"), (void *) &ph
, sizeof(ph
), NULL
);
5460 zend_declare_property_null(php_pqstm_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5461 ph
.read
= php_pqstm_object_read_connection
;
5462 zend_hash_add(&php_pqstm_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5464 memset(&ce
, 0, sizeof(ce
));
5465 INIT_NS_CLASS_ENTRY(ce
, "pq", "Transaction", php_pqtxn_methods
);
5466 php_pqtxn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5467 php_pqtxn_class_entry
->create_object
= php_pqtxn_create_object
;
5469 memcpy(&php_pqtxn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5470 php_pqtxn_object_handlers
.read_property
= php_pq_object_read_prop
;
5471 php_pqtxn_object_handlers
.write_property
= php_pq_object_write_prop
;
5472 php_pqtxn_object_handlers
.clone_obj
= NULL
;
5473 php_pqtxn_object_handlers
.get_property_ptr_ptr
= NULL
;
5474 php_pqtxn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5476 zend_hash_init(&php_pqtxn_object_prophandlers
, 4, NULL
, NULL
, 1);
5478 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5479 ph
.read
= php_pqtxn_object_read_connection
;
5480 zend_hash_add(&php_pqtxn_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5482 zend_declare_property_null(php_pqtxn_class_entry
, ZEND_STRL("isolation"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5483 ph
.read
= php_pqtxn_object_read_isolation
;
5484 ph
.write
= php_pqtxn_object_write_isolation
;
5485 zend_hash_add(&php_pqtxn_object_prophandlers
, "isolation", sizeof("isolation"), (void *) &ph
, sizeof(ph
), NULL
);
5487 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("readonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5488 ph
.read
= php_pqtxn_object_read_readonly
;
5489 ph
.write
= php_pqtxn_object_write_readonly
;
5490 zend_hash_add(&php_pqtxn_object_prophandlers
, "readonly", sizeof("readonly"), (void *) &ph
, sizeof(ph
), NULL
);
5492 zend_declare_property_bool(php_pqtxn_class_entry
, ZEND_STRL("deferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
5493 ph
.read
= php_pqtxn_object_read_deferrable
;
5494 ph
.write
= php_pqtxn_object_write_deferrable
;
5495 zend_hash_add(&php_pqtxn_object_prophandlers
, "deferrable", sizeof("deferrable"), (void *) &ph
, sizeof(ph
), NULL
);
5498 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("READ_COMMITTED"), PHP_PQTXN_READ_COMMITTED TSRMLS_CC
);
5499 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("REPEATABLE_READ"), PHP_PQTXN_REPEATABLE_READ TSRMLS_CC
);
5500 zend_declare_class_constant_long(php_pqtxn_class_entry
, ZEND_STRL("SERIALIZABLE"), PHP_PQTXN_SERIALIZABLE TSRMLS_CC
);
5502 memset(&ce
, 0, sizeof(ce
));
5503 INIT_NS_CLASS_ENTRY(ce
, "pq", "Cancel", php_pqcancel_methods
);
5504 php_pqcancel_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5505 php_pqcancel_class_entry
->create_object
= php_pqcancel_create_object
;
5507 memcpy(&php_pqcancel_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5508 php_pqcancel_object_handlers
.read_property
= php_pq_object_read_prop
;
5509 php_pqcancel_object_handlers
.write_property
= php_pq_object_write_prop
;
5510 php_pqcancel_object_handlers
.clone_obj
= NULL
;
5511 php_pqcancel_object_handlers
.get_property_ptr_ptr
= NULL
;
5512 php_pqcancel_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5514 zend_hash_init(&php_pqcancel_object_prophandlers
, 1, NULL
, NULL
, 1);
5516 zend_declare_property_null(php_pqcancel_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5517 ph
.read
= php_pqcancel_object_read_connection
;
5518 zend_hash_add(&php_pqcancel_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5520 memset(&ce
, 0, sizeof(ce
));
5521 INIT_NS_CLASS_ENTRY(ce
, "pq", "LOB", php_pqlob_methods
);
5522 php_pqlob_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5523 php_pqlob_class_entry
->create_object
= php_pqlob_create_object
;
5525 memcpy(&php_pqlob_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5526 php_pqlob_object_handlers
.read_property
= php_pq_object_read_prop
;
5527 php_pqlob_object_handlers
.write_property
= php_pq_object_write_prop
;
5528 php_pqlob_object_handlers
.clone_obj
= NULL
;
5529 php_pqlob_object_handlers
.get_property_ptr_ptr
= NULL
;
5530 php_pqlob_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5532 zend_hash_init(&php_pqlob_object_prophandlers
, 3, NULL
, NULL
, 1);
5534 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("transaction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5535 ph
.read
= php_pqlob_object_read_transaction
;
5536 zend_hash_add(&php_pqlob_object_prophandlers
, "transaction", sizeof("transaction"), (void *) &ph
, sizeof(ph
), NULL
);
5538 zend_declare_property_long(php_pqlob_class_entry
, ZEND_STRL("oid"), InvalidOid
, ZEND_ACC_PUBLIC TSRMLS_CC
);
5539 ph
.read
= php_pqlob_object_read_oid
;
5540 zend_hash_add(&php_pqlob_object_prophandlers
, "oid", sizeof("oid"), (void *) &ph
, sizeof(ph
), NULL
);
5542 zend_declare_property_null(php_pqlob_class_entry
, ZEND_STRL("stream"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5543 ph
.read
= php_pqlob_object_read_stream
;
5544 zend_hash_add(&php_pqlob_object_prophandlers
, "stream", sizeof("stream"), (void *) &ph
, sizeof(ph
), NULL
);
5546 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("INVALID_OID"), InvalidOid TSRMLS_CC
);
5547 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("R"), INV_READ TSRMLS_CC
);
5548 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("W"), INV_WRITE TSRMLS_CC
);
5549 zend_declare_class_constant_long(php_pqlob_class_entry
, ZEND_STRL("RW"), INV_READ
|INV_WRITE TSRMLS_CC
);
5551 memset(&ce
, 0, sizeof(ce
));
5552 INIT_NS_CLASS_ENTRY(ce
, "pq", "COPY", php_pqcopy_methods
);
5553 php_pqcopy_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
5554 php_pqcopy_class_entry
->create_object
= php_pqcopy_create_object
;
5556 memcpy(&php_pqcopy_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
5557 php_pqcopy_object_handlers
.read_property
= php_pq_object_read_prop
;
5558 php_pqcopy_object_handlers
.write_property
= php_pq_object_write_prop
;
5559 php_pqcopy_object_handlers
.clone_obj
= NULL
;
5560 php_pqcopy_object_handlers
.get_property_ptr_ptr
= NULL
;
5561 php_pqcopy_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
5563 zend_hash_init(&php_pqcopy_object_prophandlers
, 4, NULL
, NULL
, 1);
5565 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5566 ph
.read
= php_pqcopy_object_read_connection
;
5567 zend_hash_add(&php_pqcopy_object_prophandlers
, "connection", sizeof("connection"), (void *) &ph
, sizeof(ph
), NULL
);
5569 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("expression"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5570 ph
.read
= php_pqcopy_object_read_expression
;
5571 zend_hash_add(&php_pqcopy_object_prophandlers
, "expression", sizeof("expression"), (void *) &ph
, sizeof(ph
), NULL
);
5573 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("direction"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5574 ph
.read
= php_pqcopy_object_read_direction
;
5575 zend_hash_add(&php_pqcopy_object_prophandlers
, "direction", sizeof("direction"), (void *) &ph
, sizeof(ph
), NULL
);
5577 zend_declare_property_null(php_pqcopy_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
5578 ph
.read
= php_pqcopy_object_read_options
;
5579 zend_hash_add(&php_pqcopy_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
5581 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("FROM_STDIN"), PHP_PQCOPY_FROM_STDIN TSRMLS_CC
);
5582 zend_declare_class_constant_long(php_pqcopy_class_entry
, ZEND_STRL("TO_STDOUT"), PHP_PQCOPY_TO_STDOUT TSRMLS_CC
);
5584 php_persistent_handle_provide(ZEND_STRL("pq\\Connection"), &php_pqconn_resource_factory_ops
, NULL
, NULL TSRMLS_CC
);
5587 REGISTER_INI_ENTRIES();
5593 /* {{{ PHP_MSHUTDOWN_FUNCTION
5595 static PHP_MSHUTDOWN_FUNCTION(pq
)
5597 /* uncomment this line if you have INI entries
5598 UNREGISTER_INI_ENTRIES();
5600 php_persistent_handle_cleanup(ZEND_STRL("pq\\Connection"), NULL
, 0 TSRMLS_CC
);
5605 /* {{{ PHP_MINFO_FUNCTION
5607 static PHP_MINFO_FUNCTION(pq
)
5609 #ifdef HAVE_PQLIBVERSION
5612 char libpq_version
[10] = "pre-9.1";
5614 php_info_print_table_start();
5615 php_info_print_table_header(2, "PQ Support", "enabled");
5616 php_info_print_table_row(2, "Extension Version", PHP_PQ_EXT_VERSION
);
5617 php_info_print_table_end();
5619 php_info_print_table_start();
5620 php_info_print_table_header(2, "Used Library", "Version");
5621 #ifdef HAVE_PQLIBVERSION
5622 libpq_v
= PQlibVersion();
5623 slprintf(libpq_version
, sizeof(libpq_version
), "%d.%d.%d", libpq_v
/10000%100, libpq_v
/100%100, libpq_v
%100);
5625 php_info_print_table_row(2, "libpq", libpq_version
);
5626 php_info_print_table_end();
5628 /* Remove comments if you have entries in php.ini
5629 DISPLAY_INI_ENTRIES();
5634 const zend_function_entry pq_functions
[] = {
5638 static zend_module_dep pq_module_deps
[] = {
5639 ZEND_MOD_REQUIRED("raphf")
5640 ZEND_MOD_REQUIRED("spl")
5644 /* {{{ pq_module_entry
5646 zend_module_entry pq_module_entry
= {
5647 STANDARD_MODULE_HEADER_EX
,
5654 NULL
,/*PHP_RINIT(pq),*/
5655 NULL
,/*PHP_RSHUTDOWN(pq),*/
5658 STANDARD_MODULE_PROPERTIES
5662 #ifdef COMPILE_DL_PQ
5672 * vim600: noet sw=4 ts=4 fdm=marker
5673 * vim<600: noet sw=4 ts=4