2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
18 #include <Zend/zend_smart_str.h>
20 #include <libpq-events.h>
24 #include "php_pq_misc.h"
25 #include "php_pq_object.h"
26 #include "php_pqexc.h"
27 #include "php_pqconn.h"
28 #include "php_pqconn_event.h"
29 #include "php_pqres.h"
30 #include "php_pqstm.h"
31 #include "php_pqtxn.h"
32 #include "php_pqcur.h"
34 zend_class_entry
*php_pqconn_class_entry
;
35 static zend_object_handlers php_pqconn_object_handlers
;
36 static HashTable php_pqconn_object_prophandlers
;
38 static void php_pq_callback_hash_dtor(zval
*p
)
40 php_pq_callback_dtor(Z_PTR_P(p
));
45 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, unsigned long id)
49 if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
50 zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
55 static zend_long
php_pqconn_add_eventhandler(php_pqconn_object_t
*obj
, const char *type_str
, size_t type_len
, php_pq_callback_t
*cb
)
60 if (!(zevhs
= zend_hash_str_find(&obj
->intern
->eventhandlers
, type_str
, type_len
))) {
64 ALLOC_HASHTABLE(evhs
);
65 zend_hash_init(evhs
, 1, NULL
, php_pq_callback_hash_dtor
, 0);
68 zevhs
= zend_hash_str_add(&obj
->intern
->eventhandlers
, type_str
, type_len
, &tmp
);
71 php_pq_callback_addref(cb
);
72 h
= zend_hash_next_free_element(Z_ARRVAL_P(zevhs
));
73 zend_hash_index_update_mem(Z_ARRVAL_P(zevhs
), h
, (void *) cb
, sizeof(*cb
));
78 static void php_pqconn_object_free(zend_object
*o
)
80 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(NULL
, o
);
82 fprintf(stderr
, "FREE conn(#%d) %p\n", obj
->zo
.handle
, obj
);
85 php_pq_callback_dtor(&obj
->intern
->onevent
);
86 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn
);
87 php_resource_factory_dtor(&obj
->intern
->factory
);
88 zend_hash_destroy(&obj
->intern
->listeners
);
89 zend_hash_destroy(&obj
->intern
->statements
);
90 zend_hash_destroy(&obj
->intern
->converters
);
91 zend_hash_destroy(&obj
->intern
->eventhandlers
);
95 php_pq_object_dtor(o
);
99 php_pqconn_object_t
*php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
)
101 return php_pq_object_create(ce
, intern
, sizeof(php_pqconn_object_t
),
102 &php_pqconn_object_handlers
, &php_pqconn_object_prophandlers
);
105 static zend_object
*php_pqconn_create_object(zend_class_entry
*class_type
)
107 return &php_pqconn_create_object_ex(class_type
, NULL
)->zo
;
110 static void php_pqconn_object_read_status(void *o
, zval
*return_value
)
112 php_pqconn_object_t
*obj
= o
;
114 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
117 static void php_pqconn_object_read_transaction_status(void *o
, zval
*return_value
)
119 php_pqconn_object_t
*obj
= o
;
121 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
124 static void php_pqconn_object_read_error_message(void *o
, zval
*return_value
)
126 php_pqconn_object_t
*obj
= o
;
127 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
130 RETVAL_STRING(error
);
136 static int apply_notify_listener(zval
*p
, void *arg
)
138 php_pq_callback_t
*listener
= Z_PTR_P(p
);
140 zval zpid
, zchannel
, zmessage
;
142 ZVAL_LONG(&zpid
, nfy
->be_pid
);
143 ZVAL_STRING(&zchannel
, nfy
->relname
);
144 ZVAL_STRING(&zmessage
, nfy
->extra
);
146 zend_fcall_info_argn(&listener
->fci
, 3, &zchannel
, &zmessage
, &zpid
);
147 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL
);
148 zend_fcall_info_args_clear(&listener
->fci
, 0);
150 zval_ptr_dtor(&zchannel
);
151 zval_ptr_dtor(&zmessage
);
152 zval_ptr_dtor(&zpid
);
154 return ZEND_HASH_APPLY_KEEP
;
157 static int apply_notify_listeners(zval
*p
, int argc
, va_list argv
, zend_hash_key
*key
)
159 HashTable
*listeners
= Z_ARRVAL_P(p
);
160 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
162 if (0 == fnmatch(key
->key
->val
, nfy
->relname
, 0)) {
163 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy
);
166 return ZEND_HASH_APPLY_KEEP
;
169 void php_pqconn_notify_listeners(php_pqconn_object_t
*obj
)
173 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
174 zend_hash_apply_with_arguments(&obj
->intern
->listeners
, apply_notify_listeners
, 1, nfy
);
179 static void php_pqconn_object_read_busy(void *o
, zval
*return_value
)
181 php_pqconn_object_t
*obj
= o
;
183 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
186 static void php_pqconn_object_read_encoding(void *o
, zval
*return_value
)
188 php_pqconn_object_t
*obj
= o
;
190 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)));
193 static void php_pqconn_object_write_encoding(void *o
, zval
*value
)
195 php_pqconn_object_t
*obj
= o
;
196 zend_string
*zenc
= zval_get_string(value
);
198 if (0 > PQsetClientEncoding(obj
->intern
->conn
, zenc
->val
)) {
199 php_error(E_NOTICE
, "Unrecognized encoding '%s'", zenc
->val
);
202 zend_string_release(zenc
);
205 static void php_pqconn_object_read_unbuffered(void *o
, zval
*return_value
)
207 php_pqconn_object_t
*obj
= o
;
209 RETVAL_BOOL(obj
->intern
->unbuffered
);
212 static void php_pqconn_object_write_unbuffered(void *o
, zval
*value
)
214 php_pqconn_object_t
*obj
= o
;
216 obj
->intern
->unbuffered
= z_is_true(value
);
219 static void php_pqconn_object_read_nonblocking(void *o
, zval
*return_value
)
221 php_pqconn_object_t
*obj
= o
;
223 RETVAL_BOOL(PQisnonblocking(obj
->intern
->conn
));
226 static void php_pqconn_object_write_nonblocking(void *o
, zval
*value
)
228 php_pqconn_object_t
*obj
= o
;
230 PQsetnonblocking(obj
->intern
->conn
, z_is_true(value
));
233 static void php_pqconn_object_read_db(void *o
, zval
*return_value
)
235 php_pqconn_object_t
*obj
= o
;
236 char *db
= PQdb(obj
->intern
->conn
);
241 RETVAL_EMPTY_STRING();
245 static void php_pqconn_object_read_user(void *o
, zval
*return_value
)
247 php_pqconn_object_t
*obj
= o
;
248 char *user
= PQuser(obj
->intern
->conn
);
253 RETVAL_EMPTY_STRING();
257 static void php_pqconn_object_read_pass(void *o
, zval
*return_value
)
259 php_pqconn_object_t
*obj
= o
;
260 char *pass
= PQpass(obj
->intern
->conn
);
265 RETVAL_EMPTY_STRING();
269 static void php_pqconn_object_read_host(void *o
, zval
*return_value
)
271 php_pqconn_object_t
*obj
= o
;
272 char *host
= PQhost(obj
->intern
->conn
);
277 RETVAL_EMPTY_STRING();
281 static void php_pqconn_object_read_port(void *o
, zval
*return_value
)
283 php_pqconn_object_t
*obj
= o
;
284 char *port
= PQport(obj
->intern
->conn
);
289 RETVAL_EMPTY_STRING();
294 static void php_pqconn_object_read_params(void *o
, zval
*return_value
)
296 php_pqconn_object_t
*obj
= o
;
297 PQconninfoOption
*ptr
, *params
= PQconninfo(obj
->intern
->conn
);
299 array_init(return_value
);
302 for (ptr
= params
; ptr
->keyword
; ++ptr
) {
304 add_assoc_string(return_value
, ptr
->keyword
, ptr
->val
);
306 add_assoc_null(return_value
, ptr
->keyword
);
309 PQconninfoFree(params
);
314 static void php_pqconn_object_read_options(void *o
, zval
*return_value
)
316 php_pqconn_object_t
*obj
= o
;
317 char *options
= PQoptions(obj
->intern
->conn
);
320 RETVAL_STRING(options
);
322 RETVAL_EMPTY_STRING();
326 static int apply_read_callback_ex(zval
*p
, void *arg
)
331 zend_hash_next_index_insert(rv
, php_pq_callback_to_zval(Z_PTR_P(p
), &zcb
));
333 return ZEND_HASH_APPLY_KEEP
;
336 static int apply_read_callbacks(zval
*p
, int argc
, va_list argv
, zend_hash_key
*key
)
338 HashTable
*evhs
= Z_ARRVAL_P(p
), *rv
= va_arg(argv
, HashTable
*);
339 zval entry
, *entry_ptr
;
341 array_init_size(&entry
, zend_hash_num_elements(evhs
));
344 entry_ptr
= zend_hash_add(rv
, key
->key
, &entry
);
346 entry_ptr
= zend_hash_index_update(rv
, key
->h
, &entry
);
349 zend_hash_apply_with_argument(evhs
, apply_read_callback_ex
, Z_ARRVAL_P(entry_ptr
));
351 return ZEND_HASH_APPLY_KEEP
;
353 static void php_pqconn_object_read_event_handlers(void *o
, zval
*return_value
)
355 php_pqconn_object_t
*obj
= o
;
357 array_init(return_value
);
358 zend_hash_apply_with_arguments(&obj
->intern
->eventhandlers
, apply_read_callbacks
, 1, Z_ARRVAL_P(return_value
));
361 static void php_pqconn_object_gc_event_handlers(void *o
, zval
*return_value
)
363 php_pqconn_object_t
*obj
= o
;
366 ZEND_HASH_FOREACH_VAL(&obj
->intern
->eventhandlers
, evhs
)
370 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(evhs
), evh
)
374 add_next_index_zval(return_value
, php_pq_callback_to_zval_no_addref(Z_PTR_P(evh
), &zcb
));
376 ZEND_HASH_FOREACH_END();
378 ZEND_HASH_FOREACH_END();
381 static void php_pqconn_object_read_listeners(void *o
, zval
*return_value
)
383 php_pqconn_object_t
*obj
= o
;
385 array_init(return_value
);
386 zend_hash_apply_with_arguments(&obj
->intern
->listeners
, apply_read_callbacks
, 1, Z_ARRVAL_P(return_value
));
389 static void php_pqconn_object_gc_listeners(void *o
, zval
*return_value
)
391 php_pqconn_object_t
*obj
= o
;
394 ZEND_HASH_FOREACH_VAL(&obj
->intern
->listeners
, listeners
)
398 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(listeners
), listener
)
402 add_next_index_zval(return_value
, php_pq_callback_to_zval_no_addref(Z_PTR_P(listener
), &zcb
));
404 ZEND_HASH_FOREACH_END();
406 ZEND_HASH_FOREACH_END();
409 static void php_pqconn_object_read_converters(void *o
, zval
*return_value
)
411 php_pqconn_object_t
*obj
= o
;
413 array_init(return_value
);
414 zend_hash_copy(Z_ARRVAL_P(return_value
), &obj
->intern
->converters
, zval_add_ref
);
417 static void php_pqconn_object_gc_converters(void *o
, zval
*return_value
)
419 php_pqconn_object_t
*obj
= o
;
422 ZEND_HASH_FOREACH_VAL(&obj
->intern
->converters
, converter
)
424 add_next_index_zval(return_value
, converter
);
426 ZEND_HASH_FOREACH_END();
429 static void php_pqconn_object_read_def_fetch_type(void *o
, zval
*return_value
)
431 php_pqconn_object_t
*obj
= o
;
433 RETVAL_LONG(obj
->intern
->default_fetch_type
);
435 static void php_pqconn_object_write_def_fetch_type(void *o
, zval
*value
)
437 php_pqconn_object_t
*obj
= o
;
439 obj
->intern
->default_fetch_type
= zval_get_long(value
) & 0x3; /* two bits only */
442 static void php_pqconn_object_read_def_txn_isolation(void *o
, zval
*return_value
)
444 php_pqconn_object_t
*obj
= o
;
446 RETVAL_LONG(obj
->intern
->default_txn_isolation
);
448 static void php_pqconn_object_write_def_txn_isolation(void *o
, zval
*value
)
450 php_pqconn_object_t
*obj
= o
;
452 obj
->intern
->default_txn_isolation
= zval_get_long(value
) & 0x3; /* two bits only */
455 static void php_pqconn_object_read_def_txn_readonly(void *o
, zval
*return_value
)
457 php_pqconn_object_t
*obj
= o
;
459 RETVAL_BOOL(obj
->intern
->default_txn_readonly
);
461 static void php_pqconn_object_write_def_txn_readonly(void *o
, zval
*value
)
463 php_pqconn_object_t
*obj
= o
;
465 obj
->intern
->default_txn_readonly
= z_is_true(value
);
468 static void php_pqconn_object_read_def_txn_deferrable(void *o
, zval
*return_value
)
470 php_pqconn_object_t
*obj
= o
;
472 RETVAL_BOOL(obj
->intern
->default_txn_deferrable
);
474 static void php_pqconn_object_write_def_txn_deferrable(void *o
, zval
*value
)
476 php_pqconn_object_t
*obj
= o
;
478 obj
->intern
->default_txn_deferrable
= zend_is_true(value
);
481 static void php_pqconn_object_read_def_auto_conv(void *o
, zval
*return_value
)
483 php_pqconn_object_t
*obj
= o
;
485 RETVAL_LONG(obj
->intern
->default_auto_convert
);
487 static void php_pqconn_object_write_def_auto_conv(void *o
, zval
*value
)
489 php_pqconn_object_t
*obj
= o
;
491 obj
->intern
->default_auto_convert
= zval_get_long(value
) & PHP_PQRES_CONV_ALL
;
494 #ifdef HAVE_PQLIBVERSION
495 static void php_pqconn_object_read_lib_version(void *o
, zval
*return_value
)
498 int v
= PQlibVersion();
501 slprintf(ver
, sizeof(ver
), "%d.%d.%d", v
/10000, v
/100%100, v
%100);
503 slprintf(ver
, sizeof(ver
), "%d.%d", v
/10000, v
%100);
508 #ifdef HAVE_PQPROTOCOLVERSION
509 static void php_pqconn_object_read_protocol_version(void *o
, zval
*return_value
)
511 php_pqconn_object_t
*obj
= o
;
513 RETVAL_LONG(PQprotocolVersion(obj
->intern
->conn
));
516 #ifdef HAVE_PQSERVERVERSION
517 static void php_pqconn_object_read_server_version(void *o
, zval
*return_value
)
519 php_pqconn_object_t
*obj
= o
;
521 int v
= PQserverVersion(obj
->intern
->conn
);
524 slprintf(ver
, sizeof(ver
), "%d.%d.%d", v
/10000, v
/100%100, v
%100);
526 slprintf(ver
, sizeof(ver
), "%d.%d", v
/10000, v
%100);
532 static ZEND_RESULT_CODE
php_pqconn_update_socket(zval
*zobj
, php_pqconn_object_t
*obj
)
534 zval zsocket
, zmember
;
536 ZEND_RESULT_CODE retval
;
540 obj
= PHP_PQ_OBJ(zobj
, NULL
);
543 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1);
545 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
546 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
547 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
548 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
549 php_stream_to_zval(stream
, &zsocket
);
555 #if PHP_VERSION_ID >= 80000
556 zend_std_write_property(Z_OBJ_P(zobj
), Z_STR(zmember
), &zsocket
, NULL
);
558 zend_std_write_property(zobj
, &zmember
, &zsocket
, NULL
);
560 zval_ptr_dtor(&zsocket
);
561 zval_ptr_dtor(&zmember
);
566 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg
)
568 php_pqconn_resource_factory_data_t
*o
= init_arg
;
569 PGconn
*conn
= NULL
;;
571 if (o
->flags
& PHP_PQCONN_ASYNC
) {
572 conn
= PQconnectStart(o
->dsn
);
574 conn
= PQconnectdb(o
->dsn
);
578 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
584 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle
)
586 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
588 /* we don't care for anything, except free'ing evdata */
590 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
591 memset(evdata
, 0, sizeof(*evdata
));
598 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
599 php_pqconn_resource_factory_ctor
,
601 php_pqconn_resource_factory_dtor
604 php_resource_factory_ops_t
*php_pqconn_get_resource_factory_ops(void)
606 return &php_pqconn_resource_factory_ops
;
609 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle
)
611 PGresult
*res
= PQexec(*handle
, "");
612 php_pqres_clear(res
);
614 if (CONNECTION_OK
!= PQstatus(*handle
)) {
619 static inline PGresult
*unlisten(PGconn
*conn
, const char *channel_str
, size_t channel_len
)
621 char *quoted_channel
= PQescapeIdentifier(conn
, channel_str
, channel_len
);
622 PGresult
*res
= NULL
;
624 if (quoted_channel
) {
627 smart_str_appends(&cmd
, "UNLISTEN ");
628 smart_str_appends(&cmd
, quoted_channel
);
631 res
= php_pq_exec(conn
, smart_str_v(&cmd
));
633 smart_str_free(&cmd
);
634 PQfreemem(quoted_channel
);
640 static int apply_unlisten(zval
*p
, int argc
, va_list argv
, zend_hash_key
*key
)
642 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
643 PGresult
*res
= unlisten(obj
->intern
->conn
, key
->key
->val
, key
->key
->len
);
646 php_pqres_clear(res
);
649 return ZEND_HASH_APPLY_REMOVE
;
652 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle
)
654 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
659 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
662 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
664 /* cancel async queries */
665 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
668 PQcancel(cancel
, err
, sizeof(err
));
669 PQfreeCancel(cancel
);
671 /* clean up async results */
672 while ((res
= PQgetResult(*handle
))) {
673 php_pqres_clear(res
);
676 /* clean up transaction & session */
677 switch (PQtransactionStatus(*handle
)) {
679 res
= PQexec(*handle
, "RESET ALL");
682 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
687 php_pqres_clear(res
);
691 /* clean up notify listeners */
692 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners
, apply_unlisten
, 1, evdata
->obj
);
694 /* release instance data */
699 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
700 ZEND_ARG_INFO(0, dsn
)
701 ZEND_ARG_INFO(0, flags
)
703 static PHP_METHOD(pqconn
, __construct
) {
704 zend_error_handling zeh
;
710 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
711 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "|sl", &dsn_str
, &dsn_len
, &flags
);
712 zend_restore_error_handling(&zeh
);
715 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
718 throw_exce(EX_BAD_METHODCALL
, "pq\\Connection already initialized");
720 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj
);
721 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
723 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
725 obj
->intern
->default_auto_convert
= PHP_PQRES_CONV_ALL
;
727 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
728 zend_hash_init(&obj
->intern
->statements
, 0, NULL
, NULL
, 0);
729 zend_hash_init(&obj
->intern
->converters
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
730 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
732 if (flags
& PHP_PQCONN_PERSISTENT
) {
733 zend_string
*dsn
= zend_string_init(dsn_str
, dsn_len
, 0);
734 php_persistent_handle_factory_t
*phf
= php_persistent_handle_concede(NULL
, PHP_PQ_G
->connection
.name
, dsn
, php_pqconn_wakeup
, php_pqconn_retire
);
735 php_persistent_handle_resource_factory_init(&obj
->intern
->factory
, phf
);
736 zend_string_release(dsn
);
738 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
741 if (flags
& PHP_PQCONN_ASYNC
) {
742 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
745 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata
);
747 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
748 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
750 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj
)) {
751 throw_exce(EX_CONNECTION_FAILED
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
757 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
759 static PHP_METHOD(pqconn
, reset
) {
760 zend_error_handling zeh
;
763 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
764 rv
= zend_parse_parameters_none();
765 zend_restore_error_handling(&zeh
);
768 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
771 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
773 PQreset(obj
->intern
->conn
);
775 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
776 throw_exce(EX_CONNECTION_FAILED
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
779 php_pqconn_notify_listeners(obj
);
784 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
786 static PHP_METHOD(pqconn
, resetAsync
) {
787 zend_error_handling zeh
;
790 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
791 rv
= zend_parse_parameters_none();
792 zend_restore_error_handling(&zeh
);
795 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
798 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
800 if (!PQresetStart(obj
->intern
->conn
)) {
801 throw_exce(EX_IO
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
803 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
806 php_pqconn_notify_listeners(obj
);
811 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten
, 0, 0, 1)
812 ZEND_ARG_INFO(0, channel
)
814 static PHP_METHOD(pqconn
, unlisten
)
816 zend_error_handling zeh
;
821 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
822 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str
, &channel_len
);
823 zend_restore_error_handling(&zeh
);
826 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
829 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
830 } else if (SUCCESS
== zend_hash_str_del(&obj
->intern
->listeners
, channel_str
, channel_len
)) {
831 PGresult
*res
= unlisten(obj
->intern
->conn
, channel_str
, channel_len
);
834 php_pqres_success(res
);
835 php_pqres_clear(res
);
841 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten_async
, 0, 0, 1)
842 ZEND_ARG_INFO(0, channel
)
844 static PHP_METHOD(pqconn
, unlistenAsync
) {
845 zend_error_handling zeh
;
850 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
851 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str
, &channel_len
);
852 zend_restore_error_handling(&zeh
);
855 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
858 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
860 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
862 if (!quoted_channel
) {
863 throw_exce(EX_ESCAPE
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
867 smart_str_appends(&cmd
, "UNLISTEN ");
868 smart_str_appends(&cmd
, quoted_channel
);
871 if (!PQsendQuery(obj
->intern
->conn
, smart_str_v(&cmd
))) {
872 throw_exce(EX_IO
, "Failed to uninstall listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
874 obj
->intern
->poller
= PQconsumeInput
;
875 zend_hash_str_del(&obj
->intern
->listeners
, channel_str
, channel_len
);
878 smart_str_free(&cmd
);
879 PQfreemem(quoted_channel
);
880 php_pqconn_notify_listeners(obj
);
886 static void php_pqconn_add_listener(php_pqconn_object_t
*obj
, const char *channel_str
, size_t channel_len
, php_pq_callback_t
*listener
)
890 php_pq_callback_addref(listener
);
892 if ((existing
= zend_hash_str_find(&obj
->intern
->listeners
, channel_str
, channel_len
))) {
893 zend_hash_next_index_insert_mem(Z_ARRVAL_P(existing
), (void *) listener
, sizeof(*listener
));
899 zend_hash_init(ht
, 0, NULL
, php_pq_callback_hash_dtor
, 0);
900 zend_hash_next_index_insert_mem(ht
, (void *) listener
, sizeof(*listener
));
903 zend_hash_str_add(&obj
->intern
->listeners
, channel_str
, channel_len
, &tmp
);
907 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 2)
908 ZEND_ARG_INFO(0, channel
)
909 ZEND_ARG_INFO(0, callable
)
911 static PHP_METHOD(pqconn
, listen
) {
912 zend_error_handling zeh
;
913 char *channel_str
= NULL
;
914 size_t channel_len
= 0;
915 php_pq_callback_t listener
= PHP_PQ_CALLBACK_INIT
;
918 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
919 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
920 zend_restore_error_handling(&zeh
);
923 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
926 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
928 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
930 if (!quoted_channel
) {
931 throw_exce(EX_ESCAPE
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
936 smart_str_appends(&cmd
, "LISTEN ");
937 smart_str_appends(&cmd
, quoted_channel
);
940 res
= php_pq_exec(obj
->intern
->conn
, smart_str_v(&cmd
));
942 smart_str_free(&cmd
);
943 PQfreemem(quoted_channel
);
946 throw_exce(EX_RUNTIME
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
948 if (SUCCESS
== php_pqres_success(res
)) {
949 obj
->intern
->poller
= PQconsumeInput
;
950 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener
);
952 php_pqres_clear(res
);
955 php_pqconn_notify_listeners(obj
);
961 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
962 ZEND_ARG_INFO(0, channel
)
963 ZEND_ARG_INFO(0, callable
)
965 static PHP_METHOD(pqconn
, listenAsync
) {
966 zend_error_handling zeh
;
967 char *channel_str
= NULL
;
968 size_t channel_len
= 0;
969 php_pq_callback_t listener
= PHP_PQ_CALLBACK_INIT
;
972 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
973 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
974 zend_restore_error_handling(&zeh
);
977 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
980 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
982 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
984 if (!quoted_channel
) {
985 throw_exce(EX_ESCAPE
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
989 smart_str_appends(&cmd
, "LISTEN ");
990 smart_str_appends(&cmd
, quoted_channel
);
993 if (!PQsendQuery(obj
->intern
->conn
, smart_str_v(&cmd
))) {
994 throw_exce(EX_IO
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
996 obj
->intern
->poller
= PQconsumeInput
;
997 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener
);
1000 smart_str_free(&cmd
);
1001 PQfreemem(quoted_channel
);
1002 php_pqconn_notify_listeners(obj
);
1008 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
1009 ZEND_ARG_INFO(0, channel
)
1010 ZEND_ARG_INFO(0, message
)
1011 ZEND_END_ARG_INFO();
1012 static PHP_METHOD(pqconn
, notify
) {
1013 zend_error_handling zeh
;
1014 char *channel_str
, *message_str
;
1015 size_t channel_len
, message_len
;
1016 ZEND_RESULT_CODE rv
;
1018 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1019 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
1020 zend_restore_error_handling(&zeh
);
1022 if (SUCCESS
== rv
) {
1023 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1026 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1029 char *params
[2] = {channel_str
, message_str
};
1031 res
= php_pq_exec_params(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
1034 throw_exce(EX_RUNTIME
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1036 php_pqres_success(res
);
1037 php_pqres_clear(res
);
1040 php_pqconn_notify_listeners(obj
);
1045 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
1046 ZEND_ARG_INFO(0, channel
)
1047 ZEND_ARG_INFO(0, message
)
1048 ZEND_END_ARG_INFO();
1049 static PHP_METHOD(pqconn
, notifyAsync
) {
1050 zend_error_handling zeh
;
1051 char *channel_str
, *message_str
;
1052 size_t channel_len
, message_len
;
1053 ZEND_RESULT_CODE rv
;
1055 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1056 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
1057 zend_restore_error_handling(&zeh
);
1059 if (SUCCESS
== rv
) {
1060 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1063 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1065 char *params
[2] = {channel_str
, message_str
};
1067 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
1068 throw_exce(EX_IO
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1070 obj
->intern
->poller
= PQconsumeInput
;
1073 php_pqconn_notify_listeners(obj
);
1078 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
1079 ZEND_END_ARG_INFO();
1080 static PHP_METHOD(pqconn
, poll
) {
1081 zend_error_handling zeh
;
1082 ZEND_RESULT_CODE rv
;
1084 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1085 rv
= zend_parse_parameters_none();
1086 zend_restore_error_handling(&zeh
);
1088 if (SUCCESS
== rv
) {
1089 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1092 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1093 } else if (!obj
->intern
->poller
) {
1094 throw_exce(EX_RUNTIME
, "No asynchronous operation active");
1096 if (obj
->intern
->poller
== PQconsumeInput
) {
1097 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
1099 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
1101 php_pqconn_notify_listeners(obj
);
1106 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_flush
, 0, 0, 0)
1107 ZEND_END_ARG_INFO();
1108 static PHP_METHOD(pqconn
, flush
) {
1109 zend_error_handling zeh
;
1110 ZEND_RESULT_CODE rv
;
1112 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1113 rv
= zend_parse_parameters_none();
1114 zend_restore_error_handling(&zeh
);
1116 if (SUCCESS
== rv
) {
1117 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1120 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1121 } else if (!obj
->intern
->poller
) {
1122 throw_exce(EX_RUNTIME
, "No asynchronous operation active");
1124 switch (PQflush(obj
->intern
->conn
)) {
1127 throw_exce(EX_RUNTIME
, "Failed to flush connection: %s", PHP_PQerrorMessage(obj
->intern
->conn
));
1140 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
1141 ZEND_ARG_INFO(0, query
)
1142 ZEND_END_ARG_INFO();
1143 static PHP_METHOD(pqconn
, exec
) {
1144 zend_error_handling zeh
;
1147 ZEND_RESULT_CODE rv
;
1149 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1150 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query_str
, &query_len
);
1151 zend_restore_error_handling(&zeh
);
1153 if (SUCCESS
== rv
) {
1154 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1157 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1159 PGresult
*res
= php_pq_exec(obj
->intern
->conn
, query_str
);
1162 throw_exce(EX_RUNTIME
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1163 } else if (SUCCESS
== php_pqres_success(res
)) {
1164 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), return_value
);
1166 php_pqres_clear(res
);
1169 php_pqconn_notify_listeners(obj
);
1174 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
1175 ZEND_END_ARG_INFO();
1176 static PHP_METHOD(pqconn
, getResult
) {
1177 zend_error_handling zeh
;
1178 ZEND_RESULT_CODE rv
;
1180 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1181 rv
= zend_parse_parameters_none();
1182 zend_restore_error_handling(&zeh
);
1184 if (SUCCESS
== rv
) {
1185 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1188 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1190 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
1191 php_pq_object_t
*res_obj
;
1193 if (res
&& (res_obj
= PQresultInstanceData(res
, php_pqconn_event
))) {
1194 php_pq_object_to_zval_no_addref(res_obj
, return_value
);
1199 php_pqconn_notify_listeners(obj
);
1204 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
1205 ZEND_ARG_INFO(0, query
)
1206 ZEND_ARG_INFO(0, callable
)
1207 ZEND_END_ARG_INFO();
1208 static PHP_METHOD(pqconn
, execAsync
) {
1209 zend_error_handling zeh
;
1210 php_pq_callback_t resolver
= PHP_PQ_CALLBACK_INIT
;
1213 ZEND_RESULT_CODE rv
;
1215 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1216 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
1217 zend_restore_error_handling(&zeh
);
1219 if (SUCCESS
== rv
) {
1220 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1223 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1224 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
1225 throw_exce(EX_IO
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1226 #if HAVE_PQSETSINGLEROWMODE
1227 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
1228 throw_exce(EX_RUNTIME
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1231 php_pq_callback_recurse(&obj
->intern
->onevent
, &resolver
);
1232 obj
->intern
->poller
= PQconsumeInput
;
1233 php_pqconn_notify_listeners(obj
);
1238 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
1239 ZEND_ARG_INFO(0, query
)
1240 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1241 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1242 ZEND_END_ARG_INFO();
1243 static PHP_METHOD(pqconn
, execParams
) {
1244 zend_error_handling zeh
;
1248 zval
*ztypes
= NULL
;
1249 ZEND_RESULT_CODE rv
;
1251 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1252 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
1253 zend_restore_error_handling(&zeh
);
1255 if (SUCCESS
== rv
) {
1256 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1259 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1262 php_pq_params_t
*params
;
1264 params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, Z_ARRVAL_P(zparams
));
1265 res
= php_pq_exec_params(obj
->intern
->conn
, query_str
, params
->param
.count
, params
->type
.oids
, (const char *const*) params
->param
.strings
, NULL
, NULL
, 0);
1266 php_pq_params_free(¶ms
);
1269 throw_exce(EX_RUNTIME
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1271 if (SUCCESS
== php_pqres_success(res
)) {
1272 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), return_value
);
1274 php_pqres_clear(res
);
1277 php_pqconn_notify_listeners(obj
);
1283 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
1284 ZEND_ARG_INFO(0, query
)
1285 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1286 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1287 ZEND_ARG_INFO(0, callable
)
1288 ZEND_END_ARG_INFO();
1289 static PHP_METHOD(pqconn
, execParamsAsync
) {
1290 zend_error_handling zeh
;
1291 php_pq_callback_t resolver
= PHP_PQ_CALLBACK_INIT
;
1295 zval
*ztypes
= NULL
;
1296 ZEND_RESULT_CODE rv
;
1298 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1299 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
1300 zend_restore_error_handling(&zeh
);
1302 if (SUCCESS
== rv
) {
1303 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1306 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1309 php_pq_params_t
*params
;
1311 params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, Z_ARRVAL_P(zparams
));
1312 rc
= PQsendQueryParams(obj
->intern
->conn
, query_str
, params
->param
.count
, params
->type
.oids
, (const char *const*) params
->param
.strings
, NULL
, NULL
, 0);
1313 php_pq_params_free(¶ms
);
1316 throw_exce(EX_IO
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1317 #if HAVE_PQSETSINGLEROWMODE
1318 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
1319 throw_exce(EX_RUNTIME
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1322 php_pq_callback_recurse(&obj
->intern
->onevent
, &resolver
);
1323 obj
->intern
->poller
= PQconsumeInput
;
1324 php_pqconn_notify_listeners(obj
);
1328 zend_restore_error_handling(&zeh
);
1331 ZEND_RESULT_CODE
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, php_pq_params_t
*params
)
1334 ZEND_RESULT_CODE rv
;
1337 obj
= PHP_PQ_OBJ(object
, NULL
);
1340 res
= php_pq_prepare(obj
->intern
->conn
, name
, query
, params
->type
.count
, params
->type
.oids
);
1344 throw_exce(EX_RUNTIME
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1346 rv
= php_pqres_success(res
);
1347 php_pqres_clear(res
);
1348 php_pqconn_notify_listeners(obj
);
1354 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
1355 ZEND_ARG_INFO(0, name
)
1356 ZEND_ARG_INFO(0, query
)
1357 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1358 ZEND_END_ARG_INFO();
1359 static PHP_METHOD(pqconn
, prepare
) {
1360 zend_error_handling zeh
;
1361 zval
*ztypes
= NULL
;
1362 char *name_str
, *query_str
;
1363 size_t name_len
, *query_len
;
1364 ZEND_RESULT_CODE rv
;
1366 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1367 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
1368 zend_restore_error_handling(&zeh
);
1370 if (SUCCESS
== rv
) {
1371 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1374 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1376 php_pq_params_t
*params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, NULL
);
1378 if (SUCCESS
!= php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, params
)) {
1379 php_pq_params_free(¶ms
);
1381 php_pqstm_t
*stm
= php_pqstm_init(obj
, name_str
, query_str
, params
);
1383 RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
)->zo
);
1389 ZEND_RESULT_CODE
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, php_pq_params_t
*params
)
1391 ZEND_RESULT_CODE rv
;
1394 obj
= PHP_PQ_OBJ(object
, NULL
);
1397 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, params
->type
.count
, params
->type
.oids
)) {
1399 throw_exce(EX_IO
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1402 obj
->intern
->poller
= PQconsumeInput
;
1403 php_pqconn_notify_listeners(obj
);
1409 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
1410 ZEND_ARG_INFO(0, name
)
1411 ZEND_ARG_INFO(0, query
)
1412 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1413 ZEND_END_ARG_INFO();
1414 static PHP_METHOD(pqconn
, prepareAsync
) {
1415 zend_error_handling zeh
;
1416 zval
*ztypes
= NULL
;
1417 char *name_str
, *query_str
;
1418 size_t name_len
, *query_len
;
1419 ZEND_RESULT_CODE rv
;
1421 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1422 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
1423 zend_restore_error_handling(&zeh
);
1425 if (SUCCESS
== rv
) {
1426 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1429 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1431 php_pq_params_t
*params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, NULL
);
1433 if (SUCCESS
!= php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, params
)) {
1434 php_pq_params_free(¶ms
);
1436 php_pqstm_t
*stm
= php_pqstm_init(obj
, name_str
, query_str
, params
);
1438 RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
)->zo
);
1444 ZEND_RESULT_CODE
php_pqconn_declare(zval
*object
, php_pqconn_object_t
*obj
, const char *decl
)
1447 ZEND_RESULT_CODE rv
;
1450 obj
= PHP_PQ_OBJ(object
, NULL
);
1453 res
= php_pq_exec(obj
->intern
->conn
, decl
);
1457 throw_exce(EX_RUNTIME
, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1459 rv
= php_pqres_success(res
);
1460 php_pqres_clear(res
);
1461 php_pqconn_notify_listeners(obj
);
1467 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare
, 0, 0, 3)
1468 ZEND_ARG_INFO(0, name
)
1469 ZEND_ARG_INFO(0, flags
)
1470 ZEND_ARG_INFO(0, query
)
1471 ZEND_END_ARG_INFO();
1472 static PHP_METHOD(pqconn
, declare
) {
1473 zend_error_handling zeh
;
1474 char *name_str
, *query_str
;
1475 size_t name_len
, query_len
;
1477 ZEND_RESULT_CODE rv
;
1479 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1480 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str
, &name_len
, &flags
, &query_str
, &query_len
);
1481 zend_restore_error_handling(&zeh
);
1483 if (SUCCESS
== rv
) {
1484 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1487 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1490 char *decl
= php_pqcur_declare_str(name_str
, name_len
, flags
, query_str
, query_len
, &query_offset
);
1492 if (SUCCESS
!= php_pqconn_declare(getThis(), obj
, decl
)) {
1495 php_pqcur_t
*cur
= php_pqcur_init(obj
, name_str
, decl
, query_offset
, flags
);
1497 RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry
, cur
)->zo
);
1503 ZEND_RESULT_CODE
php_pqconn_declare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *decl
)
1505 ZEND_RESULT_CODE rv
;
1508 obj
= PHP_PQ_OBJ(object
, NULL
);
1511 if (!PQsendQuery(obj
->intern
->conn
, decl
)) {
1513 throw_exce(EX_IO
, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1516 obj
->intern
->poller
= PQconsumeInput
;
1517 php_pqconn_notify_listeners(obj
);
1523 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare_async
, 0, 0, 2)
1524 ZEND_ARG_INFO(0, name
)
1525 ZEND_ARG_INFO(0, flags
)
1526 ZEND_ARG_INFO(0, query
)
1527 ZEND_END_ARG_INFO();
1528 static PHP_METHOD(pqconn
, declareAsync
) {
1529 zend_error_handling zeh
;
1530 char *name_str
, *query_str
;
1531 size_t name_len
, query_len
;
1533 ZEND_RESULT_CODE rv
;
1535 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1536 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str
, &name_len
, &flags
, &query_str
, &query_len
);
1537 zend_restore_error_handling(&zeh
);
1539 if (SUCCESS
== rv
) {
1540 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1543 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1546 char *decl
= php_pqcur_declare_str(name_str
, name_len
, flags
, query_str
, query_len
, &query_offset
);
1548 if (SUCCESS
!= php_pqconn_declare_async(getThis(), obj
, decl
)) {
1551 php_pqcur_t
*cur
= php_pqcur_init(obj
, name_str
, decl
, query_offset
, flags
);
1553 RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry
, cur
)->zo
);
1559 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
1560 ZEND_ARG_INFO(0, string
)
1561 ZEND_END_ARG_INFO();
1562 static PHP_METHOD(pqconn
, quote
) {
1566 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1567 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1570 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1572 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
1575 php_error_docref(NULL
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1578 RETVAL_STRING(quoted
);
1585 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
1586 ZEND_ARG_INFO(0, type
)
1587 ZEND_END_ARG_INFO();
1588 static PHP_METHOD(pqconn
, quoteName
) {
1592 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1593 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1596 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1598 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
1601 php_error_docref(NULL
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1604 RETVAL_STRING(quoted
);
1611 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
1612 ZEND_ARG_INFO(0, bytea
)
1613 ZEND_END_ARG_INFO();
1614 static PHP_METHOD(pqconn
, escapeBytea
) {
1618 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1619 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1622 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1625 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
1628 php_error_docref(NULL
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1631 RETVAL_STRINGL(escaped_str
, escaped_len
- 1);
1632 PQfreemem(escaped_str
);
1638 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
1639 ZEND_ARG_INFO(0, bytea
)
1640 ZEND_END_ARG_INFO();
1641 static PHP_METHOD(pqconn
, unescapeBytea
) {
1645 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1646 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1649 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1651 size_t unescaped_len
;
1652 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
1654 if (!unescaped_str
) {
1655 php_error_docref(NULL
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1658 RETVAL_STRINGL(unescaped_str
, unescaped_len
);
1659 PQfreemem(unescaped_str
);
1665 ZEND_RESULT_CODE
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable
)
1667 ZEND_RESULT_CODE rv
= FAILURE
;
1670 conn_obj
= PHP_PQ_OBJ(zconn
, NULL
);
1673 if (!conn_obj
->intern
) {
1674 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1677 smart_str cmd
= {0};
1678 const char *il
= php_pq_isolation_level(&isolation
);
1680 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
1681 smart_str_appends(&cmd
, il
);
1682 smart_str_appends(&cmd
, ", READ ");
1683 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
1684 smart_str_appends(&cmd
, ",");
1685 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
1686 smart_str_appends(&cmd
, " DEFERRABLE");
1689 res
= php_pq_exec(conn_obj
->intern
->conn
, smart_str_v(&cmd
));
1692 throw_exce(EX_RUNTIME
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
1694 rv
= php_pqres_success(res
);
1695 php_pqres_clear(res
);
1696 php_pqconn_notify_listeners(conn_obj
);
1699 smart_str_free(&cmd
);
1705 ZEND_RESULT_CODE
php_pqconn_start_transaction_async(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable
)
1707 ZEND_RESULT_CODE rv
= FAILURE
;
1710 conn_obj
= PHP_PQ_OBJ(zconn
, NULL
);
1713 if (!conn_obj
->intern
) {
1714 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1716 smart_str cmd
= {0};
1717 const char *il
= php_pq_isolation_level(&isolation
);
1719 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
1720 smart_str_appends(&cmd
, il
);
1721 smart_str_appends(&cmd
, ", READ ");
1722 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
1723 smart_str_appends(&cmd
, ",");
1724 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
1725 smart_str_appends(&cmd
, " DEFERRABLE");
1728 if (!PQsendQuery(conn_obj
->intern
->conn
, smart_str_v(&cmd
))) {
1729 throw_exce(EX_IO
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
1732 conn_obj
->intern
->poller
= PQconsumeInput
;
1733 php_pqconn_notify_listeners(conn_obj
);
1736 smart_str_free(&cmd
);
1742 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
1743 ZEND_ARG_INFO(0, isolation
)
1744 ZEND_ARG_INFO(0, readonly
)
1745 ZEND_ARG_INFO(0, deferrable
)
1746 ZEND_END_ARG_INFO();
1747 static PHP_METHOD(pqconn
, startTransaction
) {
1748 zend_error_handling zeh
;
1749 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1750 zend_long isolation
= obj
->intern
? obj
->intern
->default_txn_isolation
: PHP_PQTXN_READ_COMMITTED
;
1751 zend_bool readonly
= obj
->intern
? obj
->intern
->default_txn_readonly
: 0;
1752 zend_bool deferrable
= obj
->intern
? obj
->intern
->default_txn_deferrable
: 0;
1753 ZEND_RESULT_CODE rv
;
1755 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1756 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation
, &readonly
, &deferrable
);
1757 zend_restore_error_handling(&zeh
);
1759 if (SUCCESS
== rv
) {
1760 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable
);
1762 if (SUCCESS
== rv
) {
1763 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1765 php_pq_object_addref(obj
);
1768 txn
->isolation
= isolation
;
1769 txn
->readonly
= readonly
;
1770 txn
->deferrable
= deferrable
;
1772 RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
)->zo
);
1777 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
1778 ZEND_ARG_INFO(0, isolation
)
1779 ZEND_ARG_INFO(0, readonly
)
1780 ZEND_ARG_INFO(0, deferrable
)
1781 ZEND_END_ARG_INFO();
1782 static PHP_METHOD(pqconn
, startTransactionAsync
) {
1783 zend_error_handling zeh
;
1784 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1785 zend_long isolation
= obj
->intern
? obj
->intern
->default_txn_isolation
: PHP_PQTXN_READ_COMMITTED
;
1786 zend_bool readonly
= obj
->intern
? obj
->intern
->default_txn_readonly
: 0;
1787 zend_bool deferrable
= obj
->intern
? obj
->intern
->default_txn_deferrable
: 0;
1788 ZEND_RESULT_CODE rv
;
1790 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1791 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation
, &readonly
, &deferrable
);
1792 zend_restore_error_handling(&zeh
);
1794 if (SUCCESS
== rv
) {
1795 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable
);
1797 if (SUCCESS
== rv
) {
1798 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1800 php_pq_object_addref(obj
);
1803 txn
->isolation
= isolation
;
1804 txn
->readonly
= readonly
;
1805 txn
->deferrable
= deferrable
;
1807 RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
)->zo
);
1812 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
1813 ZEND_ARG_INFO(0, stdio_stream
)
1814 ZEND_END_ARG_INFO();
1815 static PHP_METHOD(pqconn
, trace
) {
1816 zval
*zstream
= NULL
;
1818 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &zstream
)) {
1819 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1822 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1825 PQuntrace(obj
->intern
->conn
);
1829 php_stream
*stream
= NULL
;
1831 php_stream_from_zval(stream
, zstream
);
1833 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
1836 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1837 PQtrace(obj
->intern
->conn
, fp
);
1845 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_off
, 0, 0, 1)
1846 ZEND_ARG_INFO(0, type
)
1847 ZEND_END_ARG_INFO();
1848 static PHP_METHOD(pqconn
, off
) {
1849 zend_error_handling zeh
;
1851 ZEND_RESULT_CODE rv
;
1853 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1854 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "S", &type
);
1855 zend_restore_error_handling(&zeh
);
1857 if (SUCCESS
== rv
) {
1858 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1861 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1863 RETURN_BOOL(SUCCESS
== zend_hash_del(&obj
->intern
->eventhandlers
, type
));
1868 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on
, 0, 0, 2)
1869 ZEND_ARG_INFO(0, type
)
1870 ZEND_ARG_INFO(0, callable
)
1871 ZEND_END_ARG_INFO();
1872 static PHP_METHOD(pqconn
, on
) {
1873 zend_error_handling zeh
;
1876 php_pq_callback_t cb
= PHP_PQ_CALLBACK_INIT
;
1877 ZEND_RESULT_CODE rv
;
1879 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1880 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
1881 zend_restore_error_handling(&zeh
);
1883 if (SUCCESS
== rv
) {
1884 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1887 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1889 RETVAL_LONG(php_pqconn_add_eventhandler(obj
, type_str
, type_len
, &cb
));
1894 struct apply_set_converter_arg
{
1900 static int apply_set_converter(zval
*zoid
, void *a
)
1902 zend_long oid
= zval_get_long(zoid
);
1903 struct apply_set_converter_arg
*arg
= a
;
1906 Z_ADDREF_P(arg
->zconv
);
1907 zend_hash_index_update(arg
->ht
, oid
, arg
->zconv
);
1909 zend_hash_index_del(arg
->ht
, oid
);
1912 return ZEND_HASH_APPLY_KEEP
;
1915 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_set_converter
, 0, 0, 1)
1916 ZEND_ARG_OBJ_INFO(0, converter
, pq
\\Converter
, 0)
1917 ZEND_END_ARG_INFO();
1918 static PHP_METHOD(pqconn
, setConverter
) {
1919 ZEND_RESULT_CODE rv
;
1920 zend_error_handling zeh
;
1923 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1924 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv
, php_pqconv_class_entry
);
1925 zend_restore_error_handling(&zeh
);
1927 if (SUCCESS
== rv
) {
1928 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1931 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1934 struct apply_set_converter_arg arg
= {NULL
};
1937 php_pq_call_method(zcnv
, "converttypes", 0, &zoids
);
1938 ZVAL_DUP(&tmp
, &zoids
);
1939 convert_to_array(&tmp
);
1941 arg
.ht
= &obj
->intern
->converters
;
1945 zend_hash_apply_with_argument(Z_ARRVAL(tmp
), apply_set_converter
, &arg
);
1947 zval_ptr_dtor(&tmp
);
1948 zval_ptr_dtor(&zoids
);
1953 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unset_converter
, 0, 0, 1)
1954 ZEND_ARG_OBJ_INFO(0, converter
, pq
\\Converter
, 0)
1955 ZEND_END_ARG_INFO();
1956 static PHP_METHOD(pqconn
, unsetConverter
) {
1957 ZEND_RESULT_CODE rv
;
1958 zend_error_handling zeh
;
1961 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1962 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv
, php_pqconv_class_entry
);
1963 zend_restore_error_handling(&zeh
);
1965 if (SUCCESS
== rv
) {
1966 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1969 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1972 struct apply_set_converter_arg arg
= {NULL
};
1975 php_pq_call_method(zcnv
, "converttypes", 0, &zoids
);
1976 ZVAL_DUP(&tmp
, &zoids
);
1977 convert_to_array(&tmp
);
1979 arg
.ht
= &obj
->intern
->converters
;
1983 zend_hash_apply_with_argument(Z_ARRVAL(tmp
), apply_set_converter
, &arg
);
1985 zval_ptr_dtor(&tmp
);
1986 zval_ptr_dtor(&zoids
);
1991 static zend_function_entry php_pqconn_methods
[] = {
1992 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
)
1993 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
1994 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
1995 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
1996 PHP_ME(pqconn
, flush
, ai_pqconn_flush
, ZEND_ACC_PUBLIC
)
1997 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
1998 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
1999 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
2000 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
2001 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
2002 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
2003 PHP_ME(pqconn
, declare
, ai_pqconn_declare
, ZEND_ACC_PUBLIC
)
2004 PHP_ME(pqconn
, declareAsync
, ai_pqconn_declare_async
, ZEND_ACC_PUBLIC
)
2005 PHP_ME(pqconn
, unlisten
, ai_pqconn_unlisten
, ZEND_ACC_PUBLIC
)
2006 PHP_ME(pqconn
, unlistenAsync
, ai_pqconn_unlisten_async
, ZEND_ACC_PUBLIC
)
2007 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
2008 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
2009 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
2010 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
2011 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
2012 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
2013 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
2014 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
2015 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
2016 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
2017 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
2018 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
2019 PHP_ME(pqconn
, off
, ai_pqconn_off
, ZEND_ACC_PUBLIC
)
2020 PHP_ME(pqconn
, on
, ai_pqconn_on
, ZEND_ACC_PUBLIC
)
2021 PHP_ME(pqconn
, setConverter
, ai_pqconn_set_converter
, ZEND_ACC_PUBLIC
)
2022 PHP_ME(pqconn
, unsetConverter
, ai_pqconn_unset_converter
, ZEND_ACC_PUBLIC
)
2026 PHP_MSHUTDOWN_FUNCTION(pqconn
)
2028 php_persistent_handle_cleanup(PHP_PQ_G
->connection
.name
, NULL
);
2029 zend_string_release(PHP_PQ_G
->connection
.name
);
2030 zend_hash_destroy(&php_pqconn_object_prophandlers
);
2034 PHP_MINIT_FUNCTION(pqconn
)
2036 zend_class_entry ce
= {0};
2037 php_pq_object_prophandler_t ph
= {0};
2039 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
2040 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
);
2041 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
2043 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
2044 php_pqconn_object_handlers
.offset
= XtOffsetOf(php_pqconn_object_t
, zo
);
2045 php_pqconn_object_handlers
.free_obj
= php_pqconn_object_free
;
2046 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
2047 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
2048 php_pqconn_object_handlers
.clone_obj
= NULL
;
2049 php_pqconn_object_handlers
.get_property_ptr_ptr
= php_pq_object_get_prop_ptr_null
;
2050 php_pqconn_object_handlers
.get_gc
= php_pq_object_get_gc
;
2051 php_pqconn_object_handlers
.get_properties
= php_pq_object_properties
;
2052 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
2054 zend_hash_init(&php_pqconn_object_prophandlers
, 23, NULL
, php_pq_object_prophandler_dtor
, 1);
2056 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC
);
2057 ph
.read
= php_pqconn_object_read_status
;
2058 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "status", sizeof("status")-1, (void *) &ph
, sizeof(ph
));
2060 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC
);
2061 ph
.read
= php_pqconn_object_read_transaction_status
;
2062 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus")-1, (void *) &ph
, sizeof(ph
));
2064 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC
);
2065 ph
.read
= NULL
; /* forward to std prophandler */
2066 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "socket", sizeof("socket")-1, (void *) &ph
, sizeof(ph
));
2068 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC
);
2069 ph
.read
= php_pqconn_object_read_error_message
;
2070 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage")-1, (void *) &ph
, sizeof(ph
));
2072 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC
);
2073 ph
.read
= php_pqconn_object_read_busy
;
2074 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "busy", sizeof("busy")-1, (void *) &ph
, sizeof(ph
));
2076 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC
);
2077 ph
.read
= php_pqconn_object_read_encoding
;
2078 ph
.write
= php_pqconn_object_write_encoding
;
2079 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding")-1, (void *) &ph
, sizeof(ph
));
2082 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC
);
2083 ph
.read
= php_pqconn_object_read_unbuffered
;
2084 ph
.write
= php_pqconn_object_write_unbuffered
;
2085 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered")-1, (void *) &ph
, sizeof(ph
));
2088 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("nonblocking"), 0, ZEND_ACC_PUBLIC
);
2089 ph
.read
= php_pqconn_object_read_nonblocking
;
2090 ph
.write
= php_pqconn_object_write_nonblocking
;
2091 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "nonblocking", sizeof("nonblocking")-1, (void *) &ph
, sizeof(ph
));
2094 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC
);
2095 ph
.read
= php_pqconn_object_read_db
;
2096 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "db", sizeof("db")-1, (void *) &ph
, sizeof(ph
));
2098 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC
);
2099 ph
.read
= php_pqconn_object_read_user
;
2100 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "user", sizeof("user")-1, (void *) &ph
, sizeof(ph
));
2102 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC
);
2103 ph
.read
= php_pqconn_object_read_pass
;
2104 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "pass", sizeof("pass")-1, (void *) &ph
, sizeof(ph
));
2106 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC
);
2107 ph
.read
= php_pqconn_object_read_host
;
2108 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "host", sizeof("host")-1, (void *) &ph
, sizeof(ph
));
2110 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC
);
2111 ph
.read
= php_pqconn_object_read_port
;
2112 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "port", sizeof("port")-1, (void *) &ph
, sizeof(ph
));
2115 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("params"), ZEND_ACC_PUBLIC
);
2116 ph
.read
= php_pqconn_object_read_params
;
2117 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "params", sizeof("params")-1, (void *) &ph
, sizeof(ph
));
2120 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC
);
2121 ph
.read
= php_pqconn_object_read_options
;
2122 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "options", sizeof("options")-1, (void *) &ph
, sizeof(ph
));
2124 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC
);
2125 ph
.read
= php_pqconn_object_read_event_handlers
;
2126 ph
.gc
= php_pqconn_object_gc_event_handlers
;
2127 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "eventHandlers", sizeof("eventHandlers")-1, (void *) &ph
, sizeof(ph
));
2130 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("listeners"), ZEND_ACC_PUBLIC
);
2131 ph
.read
= php_pqconn_object_read_listeners
;
2132 ph
.gc
= php_pqconn_object_gc_listeners
;
2133 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "listeners", sizeof("listeners")-1, (void *) &ph
, sizeof(ph
));
2136 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("converters"), ZEND_ACC_PUBLIC
);
2137 ph
.read
= php_pqconn_object_read_converters
;
2138 ph
.gc
= php_pqconn_object_gc_converters
;
2139 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "converters", sizeof("converters")-1, (void *) &ph
, sizeof(ph
));
2142 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC
);
2143 ph
.read
= php_pqconn_object_read_def_fetch_type
;
2144 ph
.write
= php_pqconn_object_write_def_fetch_type
;
2145 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultFetchType", sizeof("defaultFetchType")-1, (void *) &ph
, sizeof(ph
));
2148 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC
);
2149 ph
.read
= php_pqconn_object_read_def_txn_isolation
;
2150 ph
.write
= php_pqconn_object_write_def_txn_isolation
;
2151 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation")-1, (void *) &ph
, sizeof(ph
));
2154 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC
);
2155 ph
.read
= php_pqconn_object_read_def_txn_readonly
;
2156 ph
.write
= php_pqconn_object_write_def_txn_readonly
;
2157 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly")-1, (void *) &ph
, sizeof(ph
));
2160 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC
);
2161 ph
.read
= php_pqconn_object_read_def_txn_deferrable
;
2162 ph
.write
= php_pqconn_object_write_def_txn_deferrable
;
2163 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable")-1, (void *) &ph
, sizeof(ph
));
2166 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL
, ZEND_ACC_PUBLIC
);
2167 ph
.read
= php_pqconn_object_read_def_auto_conv
;
2168 ph
.write
= php_pqconn_object_write_def_auto_conv
;
2169 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultAutoConvert", sizeof("defaultAutoConvert")-1, (void *) &ph
, sizeof(ph
));
2172 #ifdef HAVE_PQLIBVERSION
2173 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("libraryVersion"), ZEND_ACC_PUBLIC
);
2174 ph
.read
= php_pqconn_object_read_lib_version
;
2175 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, ZEND_STRL("libraryVersion"), (void *) &ph
, sizeof(ph
));
2178 #ifdef HAVE_PQPROTOCOLVERSION
2179 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("protocolVersion"), ZEND_ACC_PUBLIC
);
2180 ph
.read
= php_pqconn_object_read_protocol_version
;
2181 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, ZEND_STRL("protocolVersion"), (void *) &ph
, sizeof(ph
));
2184 #ifdef HAVE_PQSERVERVERSION
2185 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("serverVersion"), ZEND_ACC_PUBLIC
);
2186 ph
.read
= php_pqconn_object_read_server_version
;
2187 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, ZEND_STRL("serverVersion"), (void *) &ph
, sizeof(ph
));
2190 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK
);
2191 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD
);
2192 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED
);
2193 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE
);
2194 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE
);
2195 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK
);
2196 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP
);
2197 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV
);
2198 #ifdef HAVE_CONNECTION_CHECK_WRITABLE
2199 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("CHECK_WRITABLE"), CONNECTION_CHECK_WRITABLE
);
2201 #ifdef HAVE_CONNECTION_CONSUME
2202 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("CONSUME"), CONNECTION_CONSUME
);
2204 #ifdef HAVE_CONNECTION_GSS_STARTUP
2205 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("GSS_STARTUP"), CONNECTION_GSS_STARTUP
);
2208 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE
);
2209 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE
);
2210 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS
);
2211 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR
);
2212 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN
);
2214 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED
);
2215 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING
);
2216 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING
);
2217 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK
);
2219 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice"));
2220 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result"));
2221 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset"));
2223 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1);
2224 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2);
2226 PHP_PQ_G
->connection
.name
= zend_string_init(ZEND_STRL("pq\\Connection"), 1);
2228 return php_persistent_handle_provide(PHP_PQ_G
->connection
.name
, php_pqconn_get_resource_factory_ops(), NULL
, NULL
);
2236 * vim600: noet sw=4 ts=4 fdm=marker
2237 * vim<600: noet sw=4 ts=4