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 +--------------------------------------------------------------------+
19 #define SMART_STR_PREALLOC 256
20 #include <ext/standard/php_smart_str.h>
22 #include <libpq-events.h>
26 #include "php_pq_misc.h"
27 #include "php_pq_object.h"
28 #include "php_pqexc.h"
29 #include "php_pqconn.h"
30 #include "php_pqconn_event.h"
31 #include "php_pqres.h"
32 #include "php_pqstm.h"
33 #include "php_pqtxn.h"
34 #include "php_pqcur.h"
36 zend_class_entry
*php_pqconn_class_entry
;
37 static zend_object_handlers php_pqconn_object_handlers
;
38 static HashTable php_pqconn_object_prophandlers
;
41 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC)
45 if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
46 zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
51 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
)
56 if (SUCCESS
!= zend_hash_find(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evhs
)) {
59 zend_hash_init(&evh
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
60 zend_hash_add(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1, (void *) &evh
, sizeof(evh
), (void *) &evhs
);
63 php_pq_callback_addref(cb
);
64 h
= zend_hash_next_free_element(evhs
);
65 zend_hash_index_update(evhs
, h
, (void *) cb
, sizeof(*cb
), NULL
);
70 static void php_pqconn_object_free(void *o TSRMLS_DC
)
72 php_pqconn_object_t
*obj
= o
;
74 fprintf(stderr
, "FREE conn(#%d) %p\n", obj
->zv
.handle
, obj
);
77 php_pq_callback_dtor(&obj
->intern
->onevent
);
78 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn TSRMLS_CC
);
79 php_resource_factory_dtor(&obj
->intern
->factory
);
80 zend_hash_destroy(&obj
->intern
->listeners
);
81 zend_hash_destroy(&obj
->intern
->converters
);
82 zend_hash_destroy(&obj
->intern
->eventhandlers
);
86 zend_object_std_dtor((zend_object
*) o TSRMLS_CC
);
91 zend_object_value
php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
, php_pqconn_object_t
**ptr TSRMLS_DC
)
93 php_pqconn_object_t
*o
;
95 o
= ecalloc(1, sizeof(*o
));
96 zend_object_std_init((zend_object
*) o
, ce TSRMLS_CC
);
97 object_properties_init((zend_object
*) o
, ce
);
98 o
->prophandler
= &php_pqconn_object_prophandlers
;
108 o
->zv
.handle
= zend_objects_store_put((zend_object
*) o
, NULL
, php_pqconn_object_free
, NULL TSRMLS_CC
);
109 o
->zv
.handlers
= &php_pqconn_object_handlers
;
114 static zend_object_value
php_pqconn_create_object(zend_class_entry
*class_type TSRMLS_DC
)
116 return php_pqconn_create_object_ex(class_type
, NULL
, NULL TSRMLS_CC
);
119 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
121 php_pqconn_object_t
*obj
= o
;
123 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
126 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
128 php_pqconn_object_t
*obj
= o
;
130 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
133 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
135 php_pqconn_object_t
*obj
= o
;
136 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
139 RETVAL_STRING(error
, 1);
145 static int apply_notify_listener(void *p
, void *arg TSRMLS_DC
)
147 php_pq_callback_t
*listener
= p
;
149 zval
*zpid
, *zchannel
, *zmessage
;
152 ZVAL_LONG(zpid
, nfy
->be_pid
);
153 MAKE_STD_ZVAL(zchannel
);
154 ZVAL_STRING(zchannel
, nfy
->relname
, 1);
155 MAKE_STD_ZVAL(zmessage
);
156 ZVAL_STRING(zmessage
, nfy
->extra
, 1);
158 zend_fcall_info_argn(&listener
->fci TSRMLS_CC
, 3, &zchannel
, &zmessage
, &zpid
);
159 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL TSRMLS_CC
);
161 zval_ptr_dtor(&zchannel
);
162 zval_ptr_dtor(&zmessage
);
163 zval_ptr_dtor(&zpid
);
165 return ZEND_HASH_APPLY_KEEP
;
168 static int apply_notify_listeners(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
170 HashTable
*listeners
= p
;
171 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
173 if (0 == fnmatch(key
->arKey
, nfy
->relname
, 0)) {
174 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy TSRMLS_CC
);
177 return ZEND_HASH_APPLY_KEEP
;
180 void php_pqconn_notify_listeners(php_pqconn_object_t
*obj TSRMLS_DC
)
184 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
185 zend_hash_apply_with_arguments(&obj
->intern
->listeners TSRMLS_CC
, apply_notify_listeners
, 1, nfy
);
190 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
192 php_pqconn_object_t
*obj
= o
;
194 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
197 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
199 php_pqconn_object_t
*obj
= o
;
201 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)), 1);
204 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
206 php_pqconn_object_t
*obj
= o
;
209 if (Z_TYPE_P(value
) != IS_STRING
) {
210 if (Z_REFCOUNT_P(value
) > 1) {
213 ZVAL_ZVAL(tmp
, zenc
, 1, 0);
214 convert_to_string(tmp
);
217 convert_to_string_ex(&zenc
);
221 if (0 > PQsetClientEncoding(obj
->intern
->conn
, Z_STRVAL_P(zenc
))) {
222 php_error(E_NOTICE
, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc
));
226 zval_ptr_dtor(&zenc
);
230 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
232 php_pqconn_object_t
*obj
= o
;
234 RETVAL_BOOL(obj
->intern
->unbuffered
);
237 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
239 php_pqconn_object_t
*obj
= o
;
241 obj
->intern
->unbuffered
= z_is_true(value
);
244 static void php_pqconn_object_read_db(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
246 php_pqconn_object_t
*obj
= o
;
247 char *db
= PQdb(obj
->intern
->conn
);
250 RETVAL_STRING(db
, 1);
252 RETVAL_EMPTY_STRING();
256 static void php_pqconn_object_read_user(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
258 php_pqconn_object_t
*obj
= o
;
259 char *user
= PQuser(obj
->intern
->conn
);
262 RETVAL_STRING(user
, 1);
264 RETVAL_EMPTY_STRING();
268 static void php_pqconn_object_read_pass(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
270 php_pqconn_object_t
*obj
= o
;
271 char *pass
= PQpass(obj
->intern
->conn
);
274 RETVAL_STRING(pass
, 1);
276 RETVAL_EMPTY_STRING();
280 static void php_pqconn_object_read_host(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
282 php_pqconn_object_t
*obj
= o
;
283 char *host
= PQhost(obj
->intern
->conn
);
286 RETVAL_STRING(host
, 1);
288 RETVAL_EMPTY_STRING();
292 static void php_pqconn_object_read_port(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
294 php_pqconn_object_t
*obj
= o
;
295 char *port
= PQport(obj
->intern
->conn
);
298 RETVAL_STRING(port
, 1);
300 RETVAL_EMPTY_STRING();
305 static void php_pqconn_object_read_params(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
307 php_pqconn_object_t
*obj
= o
;
308 PQconninfoOption
*ptr
, *params
= PQconninfo(obj
->intern
->conn
);
310 array_init(return_value
);
313 for (ptr
= params
; ptr
->keyword
; ++ptr
) {
315 add_assoc_string(return_value
, ptr
->keyword
, ptr
->val
, 1);
317 add_assoc_null(return_value
, ptr
->keyword
);
320 PQconninfoFree(params
);
325 static void php_pqconn_object_read_options(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
327 php_pqconn_object_t
*obj
= o
;
328 char *options
= PQoptions(obj
->intern
->conn
);
331 RETVAL_STRING(options
, 1);
333 RETVAL_EMPTY_STRING();
337 static int apply_read_event_handler_ex(void *p
, void *arg TSRMLS_DC
)
340 zval
*zcb
= php_pq_callback_to_zval(p
);
342 zend_hash_next_index_insert(rv
, &zcb
, sizeof(zval
*), NULL
);
344 return ZEND_HASH_APPLY_KEEP
;
347 static int apply_read_event_handlers(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
349 HashTable
*evhs
= p
, *rv
= va_arg(argv
, HashTable
*);
350 zval
*entry
, **entry_ptr
;
352 MAKE_STD_ZVAL(entry
);
353 array_init_size(entry
, zend_hash_num_elements(evhs
));
355 if (key
->nKeyLength
) {
356 zend_hash_add(rv
, key
->arKey
, key
->nKeyLength
, &entry
, sizeof(zval
*), (void *) &entry_ptr
);
358 zend_hash_index_update(rv
, key
->h
, &entry
, sizeof(zval
*), (void *) &entry_ptr
);
361 zend_hash_apply_with_argument(evhs
, apply_read_event_handler_ex
, Z_ARRVAL_PP(entry_ptr
) TSRMLS_CC
);
363 return ZEND_HASH_APPLY_KEEP
;
365 static void php_pqconn_object_read_event_handlers(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
367 php_pqconn_object_t
*obj
= o
;
369 array_init(return_value
);
370 zend_hash_apply_with_arguments(&obj
->intern
->eventhandlers TSRMLS_CC
, apply_read_event_handlers
, 1, Z_ARRVAL_P(return_value
) TSRMLS_CC
);
373 static void php_pqconn_object_read_def_fetch_type(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
375 php_pqconn_object_t
*obj
= o
;
377 RETVAL_LONG(obj
->intern
->default_fetch_type
);
379 static void php_pqconn_object_write_def_fetch_type(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
381 php_pqconn_object_t
*obj
= o
;
384 if (Z_TYPE_P(zft
) != IS_LONG
) {
385 if (Z_REFCOUNT_P(zft
) > 1) {
388 ZVAL_ZVAL(tmp
, zft
, 1, 0);
389 convert_to_long(tmp
);
392 convert_to_long_ex(&zft
);
396 obj
->intern
->default_fetch_type
= Z_LVAL_P(zft
) & 0x3; /* two bits only */
403 static void php_pqconn_object_read_def_txn_isolation(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
405 php_pqconn_object_t
*obj
= o
;
407 RETVAL_LONG(obj
->intern
->default_txn_isolation
);
409 static void php_pqconn_object_write_def_txn_isolation(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
411 php_pqconn_object_t
*obj
= o
;
414 if (Z_TYPE_P(zti
) != IS_LONG
) {
415 if (Z_REFCOUNT_P(zti
) > 1) {
418 ZVAL_ZVAL(tmp
, zti
, 1, 0);
419 convert_to_long(tmp
);
422 convert_to_long_ex(&zti
);
426 obj
->intern
->default_txn_isolation
= Z_LVAL_P(zti
) & 0x3; /* two bits only */
433 static void php_pqconn_object_read_def_txn_readonly(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
435 php_pqconn_object_t
*obj
= o
;
437 RETVAL_BOOL(obj
->intern
->default_txn_readonly
);
439 static void php_pqconn_object_write_def_txn_readonly(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
441 php_pqconn_object_t
*obj
= o
;
443 obj
->intern
->default_txn_readonly
= zend_is_true(value
);
446 static void php_pqconn_object_read_def_txn_deferrable(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
448 php_pqconn_object_t
*obj
= o
;
450 RETVAL_BOOL(obj
->intern
->default_txn_deferrable
);
452 static void php_pqconn_object_write_def_txn_deferrable(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
454 php_pqconn_object_t
*obj
= o
;
456 obj
->intern
->default_txn_deferrable
= zend_is_true(value
);
459 static void php_pqconn_object_read_def_auto_conv(zval
*object
, void *o
, zval
*return_value TSRMLS_DC
)
461 php_pqconn_object_t
*obj
= o
;
463 RETVAL_LONG(obj
->intern
->default_auto_convert
);
465 static void php_pqconn_object_write_def_auto_conv(zval
*object
, void *o
, zval
*value TSRMLS_DC
)
467 php_pqconn_object_t
*obj
= o
;
470 if (Z_TYPE_P(zac
) != IS_LONG
) {
471 if (Z_REFCOUNT_P(zac
) > 1) {
474 ZVAL_ZVAL(tmp
, zac
, 1, 0);
475 convert_to_long(tmp
);
478 convert_to_long_ex(&zac
);
482 obj
->intern
->default_auto_convert
= Z_LVAL_P(zac
) & PHP_PQRES_CONV_ALL
;
489 static STATUS
php_pqconn_update_socket(zval
*this_ptr
, php_pqconn_object_t
*obj TSRMLS_DC
)
491 zval
*zsocket
, zmember
;
497 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
500 INIT_PZVAL(&zmember
);
501 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1, 0);
502 MAKE_STD_ZVAL(zsocket
);
504 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
505 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
506 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
507 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
508 php_stream_to_zval(stream
, zsocket
);
514 zend_get_std_object_handlers()->write_property(getThis(), &zmember
, zsocket
, NULL TSRMLS_CC
);
515 zval_ptr_dtor(&zsocket
);
520 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg TSRMLS_DC
)
522 php_pqconn_resource_factory_data_t
*o
= init_arg
;
523 PGconn
*conn
= NULL
;;
525 if (o
->flags
& PHP_PQCONN_ASYNC
) {
526 conn
= PQconnectStart(o
->dsn
);
528 conn
= PQconnectdb(o
->dsn
);
532 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
538 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle TSRMLS_DC
)
540 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
542 /* we don't care for anything, except free'ing evdata */
544 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
545 memset(evdata
, 0, sizeof(*evdata
));
552 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
553 php_pqconn_resource_factory_ctor
,
555 php_pqconn_resource_factory_dtor
558 php_resource_factory_ops_t
*php_pqconn_get_resource_factory_ops(void)
560 return &php_pqconn_resource_factory_ops
;
563 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
565 PGresult
*res
= PQexec(*handle
, "");
568 if (CONNECTION_OK
!= PQstatus(*handle
)) {
573 static inline PGresult
*unlisten(PGconn
*conn
, const char *channel_str
, size_t channel_len TSRMLS_DC
)
575 char *quoted_channel
= PQescapeIdentifier(conn
, channel_str
, channel_len
);
576 PGresult
*res
= NULL
;
578 if (quoted_channel
) {
581 smart_str_appends(&cmd
, "UNLISTEN ");
582 smart_str_appends(&cmd
, quoted_channel
);
585 res
= PQexec(conn
, cmd
.c
);
587 smart_str_free(&cmd
);
588 PQfreemem(quoted_channel
);
594 static int apply_unlisten(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
596 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
597 PGresult
*res
= unlisten(obj
->intern
->conn
, key
->arKey
, key
->nKeyLength
- 1 TSRMLS_CC
);
603 return ZEND_HASH_APPLY_REMOVE
;
606 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle TSRMLS_DC
)
608 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
613 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
616 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
618 /* cancel async queries */
619 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
622 PQcancel(cancel
, err
, sizeof(err
));
623 PQfreeCancel(cancel
);
625 /* clean up async results */
626 while ((res
= PQgetResult(*handle
))) {
630 /* clean up transaction & session */
631 switch (PQtransactionStatus(*handle
)) {
633 res
= PQexec(*handle
, "RESET ALL");
636 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
645 /* clean up notify listeners */
646 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners TSRMLS_CC
, apply_unlisten
, 1, evdata
->obj
);
648 /* release instance data */
653 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
654 ZEND_ARG_INFO(0, dsn
)
655 ZEND_ARG_INFO(0, flags
)
657 static PHP_METHOD(pqconn
, __construct
) {
658 zend_error_handling zeh
;
664 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
665 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sl", &dsn_str
, &dsn_len
, &flags
);
666 zend_restore_error_handling(&zeh TSRMLS_CC
);
669 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
672 throw_exce(EX_BAD_METHODCALL TSRMLS_CC
, "pq\\Connection already initialized");
674 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj TSRMLS_CC
);
675 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
677 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
679 obj
->intern
->default_auto_convert
= PHP_PQRES_CONV_ALL
;
681 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
682 zend_hash_init(&obj
->intern
->converters
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
683 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
685 if (flags
& PHP_PQCONN_PERSISTENT
) {
686 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
);
687 php_resource_factory_init(&obj
->intern
->factory
, php_persistent_handle_get_resource_factory_ops(), phf
, (void (*)(void*)) php_persistent_handle_abandon
);
689 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
692 if (flags
& PHP_PQCONN_ASYNC
) {
693 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
696 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata TSRMLS_CC
);
698 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
699 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
701 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj TSRMLS_CC
)) {
702 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
708 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
710 static PHP_METHOD(pqconn
, reset
) {
711 zend_error_handling zeh
;
714 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
715 rv
= zend_parse_parameters_none();
716 zend_restore_error_handling(&zeh TSRMLS_CC
);
719 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
722 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
724 PQreset(obj
->intern
->conn
);
726 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
727 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
730 php_pqconn_notify_listeners(obj TSRMLS_CC
);
735 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
737 static PHP_METHOD(pqconn
, resetAsync
) {
738 zend_error_handling zeh
;
741 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
742 rv
= zend_parse_parameters_none();
743 zend_restore_error_handling(&zeh TSRMLS_CC
);
746 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
749 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
751 if (!PQresetStart(obj
->intern
->conn
)) {
752 throw_exce(EX_IO TSRMLS_CC
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
754 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
757 php_pqconn_notify_listeners(obj TSRMLS_CC
);
762 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten
, 0, 0, 1)
763 ZEND_ARG_INFO(0, channel
)
765 static PHP_METHOD(pqconn
, unlisten
)
767 zend_error_handling zeh
;
772 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
773 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &channel_str
, &channel_len
);
774 zend_restore_error_handling(&zeh TSRMLS_CC
);
777 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
780 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
781 } else if (SUCCESS
== zend_hash_del(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1)) {
782 PGresult
*res
= unlisten(obj
->intern
->conn
, channel_str
, channel_len TSRMLS_CC
);
785 php_pqres_success(res TSRMLS_CC
);
792 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten_async
, 0, 0, 1)
793 ZEND_ARG_INFO(0, channel
)
795 static PHP_METHOD(pqconn
, unlistenAsync
) {
796 zend_error_handling zeh
;
801 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
802 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &channel_str
, &channel_len
);
803 zend_restore_error_handling(&zeh TSRMLS_CC
);
806 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
809 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
811 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
813 if (!quoted_channel
) {
814 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
818 smart_str_appends(&cmd
, "UNLISTEN ");
819 smart_str_appends(&cmd
, quoted_channel
);
822 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
823 throw_exce(EX_IO TSRMLS_CC
, "Failed to uninstall listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
825 obj
->intern
->poller
= PQconsumeInput
;
826 zend_hash_del(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1);
829 smart_str_free(&cmd
);
830 PQfreemem(quoted_channel
);
831 php_pqconn_notify_listeners(obj TSRMLS_CC
);
837 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
)
839 HashTable ht
, *existing_listeners
;
841 php_pq_callback_addref(listener
);
843 if (SUCCESS
== zend_hash_find(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &existing_listeners
)) {
844 zend_hash_next_index_insert(existing_listeners
, (void *) listener
, sizeof(*listener
), NULL
);
846 zend_hash_init(&ht
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
847 zend_hash_next_index_insert(&ht
, (void *) listener
, sizeof(*listener
), NULL
);
848 zend_hash_add(&obj
->intern
->listeners
, channel_str
, channel_len
+ 1, (void *) &ht
, sizeof(HashTable
), NULL
);
852 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 2)
853 ZEND_ARG_INFO(0, channel
)
854 ZEND_ARG_INFO(0, callable
)
856 static PHP_METHOD(pqconn
, listen
) {
857 zend_error_handling zeh
;
858 char *channel_str
= NULL
;
860 php_pq_callback_t listener
= {{0}};
863 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
864 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
865 zend_restore_error_handling(&zeh TSRMLS_CC
);
868 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
871 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
873 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
875 if (!quoted_channel
) {
876 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
881 smart_str_appends(&cmd
, "LISTEN ");
882 smart_str_appends(&cmd
, quoted_channel
);
885 res
= PQexec(obj
->intern
->conn
, cmd
.c
);
887 smart_str_free(&cmd
);
888 PQfreemem(quoted_channel
);
891 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
893 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
894 obj
->intern
->poller
= PQconsumeInput
;
895 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
900 php_pqconn_notify_listeners(obj TSRMLS_CC
);
906 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
907 ZEND_ARG_INFO(0, channel
)
908 ZEND_ARG_INFO(0, callable
)
910 static PHP_METHOD(pqconn
, listenAsync
) {
911 zend_error_handling zeh
;
912 char *channel_str
= NULL
;
914 php_pq_callback_t listener
= {{0}};
917 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
918 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
919 zend_restore_error_handling(&zeh TSRMLS_CC
);
922 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
925 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
927 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
929 if (!quoted_channel
) {
930 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
934 smart_str_appends(&cmd
, "LISTEN ");
935 smart_str_appends(&cmd
, quoted_channel
);
938 if (!PQsendQuery(obj
->intern
->conn
, cmd
.c
)) {
939 throw_exce(EX_IO TSRMLS_CC
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
941 obj
->intern
->poller
= PQconsumeInput
;
942 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener TSRMLS_CC
);
945 smart_str_free(&cmd
);
946 PQfreemem(quoted_channel
);
947 php_pqconn_notify_listeners(obj TSRMLS_CC
);
953 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
954 ZEND_ARG_INFO(0, channel
)
955 ZEND_ARG_INFO(0, message
)
957 static PHP_METHOD(pqconn
, notify
) {
958 zend_error_handling zeh
;
959 char *channel_str
, *message_str
;
960 int channel_len
, message_len
;
963 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
964 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
965 zend_restore_error_handling(&zeh TSRMLS_CC
);
968 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
971 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
974 char *params
[2] = {channel_str
, message_str
};
976 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
979 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
981 php_pqres_success(res TSRMLS_CC
);
985 php_pqconn_notify_listeners(obj TSRMLS_CC
);
990 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
991 ZEND_ARG_INFO(0, channel
)
992 ZEND_ARG_INFO(0, message
)
994 static PHP_METHOD(pqconn
, notifyAsync
) {
995 zend_error_handling zeh
;
996 char *channel_str
, *message_str
;
997 int channel_len
, message_len
;
1000 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1001 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
1002 zend_restore_error_handling(&zeh TSRMLS_CC
);
1004 if (SUCCESS
== rv
) {
1005 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1008 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1010 char *params
[2] = {channel_str
, message_str
};
1012 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
1013 throw_exce(EX_IO TSRMLS_CC
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1015 obj
->intern
->poller
= PQconsumeInput
;
1018 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1023 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
1024 ZEND_END_ARG_INFO();
1025 static PHP_METHOD(pqconn
, poll
) {
1026 zend_error_handling zeh
;
1029 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1030 rv
= zend_parse_parameters_none();
1031 zend_restore_error_handling(&zeh TSRMLS_CC
);
1033 if (SUCCESS
== rv
) {
1034 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1037 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1038 } else if (!obj
->intern
->poller
) {
1039 throw_exce(EX_RUNTIME TSRMLS_CC
, "No asynchronous operation active");
1041 if (obj
->intern
->poller
== PQconsumeInput
) {
1042 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
1044 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
1046 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1051 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
1052 ZEND_ARG_INFO(0, query
)
1053 ZEND_END_ARG_INFO();
1054 static PHP_METHOD(pqconn
, exec
) {
1055 zend_error_handling zeh
;
1060 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1061 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &query_str
, &query_len
);
1062 zend_restore_error_handling(&zeh TSRMLS_CC
);
1064 if (SUCCESS
== rv
) {
1065 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1068 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1070 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
1073 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1074 } else if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1075 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
1080 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1085 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
1086 ZEND_END_ARG_INFO();
1087 static PHP_METHOD(pqconn
, getResult
) {
1088 zend_error_handling zeh
;
1091 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1092 rv
= zend_parse_parameters_none();
1093 zend_restore_error_handling(&zeh TSRMLS_CC
);
1095 if (SUCCESS
== rv
) {
1096 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1099 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1101 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
1106 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
1109 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1114 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
1115 ZEND_ARG_INFO(0, query
)
1116 ZEND_ARG_INFO(0, callable
)
1117 ZEND_END_ARG_INFO();
1118 static PHP_METHOD(pqconn
, execAsync
) {
1119 zend_error_handling zeh
;
1120 php_pq_callback_t resolver
= {{0}};
1125 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1126 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
1127 zend_restore_error_handling(&zeh TSRMLS_CC
);
1129 if (SUCCESS
== rv
) {
1130 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1133 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1134 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
1135 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1136 #if HAVE_PQSETSINGLEROWMODE
1137 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
1138 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1141 php_pq_callback_recurse(&obj
->intern
->onevent
, &resolver TSRMLS_CC
);
1142 obj
->intern
->poller
= PQconsumeInput
;
1143 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1148 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
1149 ZEND_ARG_INFO(0, query
)
1150 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1151 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1152 ZEND_END_ARG_INFO();
1153 static PHP_METHOD(pqconn
, execParams
) {
1154 zend_error_handling zeh
;
1158 zval
*ztypes
= NULL
;
1161 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1162 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
1163 zend_restore_error_handling(&zeh TSRMLS_CC
);
1165 if (SUCCESS
== rv
) {
1166 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1169 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1172 php_pq_params_t
*params
;
1174 params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, Z_ARRVAL_P(zparams
) TSRMLS_CC
);
1175 res
= PQexecParams(obj
->intern
->conn
, query_str
, params
->param
.count
, params
->type
.oids
, (const char *const*) params
->param
.strings
, NULL
, NULL
, 0);
1176 php_pq_params_free(¶ms
);
1179 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1181 if (SUCCESS
== php_pqres_success(res TSRMLS_CC
)) {
1182 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), &return_value TSRMLS_CC
);
1187 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1193 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
1194 ZEND_ARG_INFO(0, query
)
1195 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1196 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1197 ZEND_ARG_INFO(0, callable
)
1198 ZEND_END_ARG_INFO();
1199 static PHP_METHOD(pqconn
, execParamsAsync
) {
1200 zend_error_handling zeh
;
1201 php_pq_callback_t resolver
= {{0}};
1205 zval
*ztypes
= NULL
;
1208 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1209 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
1210 zend_restore_error_handling(&zeh TSRMLS_CC
);
1212 if (SUCCESS
== rv
) {
1213 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1216 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1219 php_pq_params_t
*params
;
1221 params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, Z_ARRVAL_P(zparams
) TSRMLS_CC
);
1222 rc
= PQsendQueryParams(obj
->intern
->conn
, query_str
, params
->param
.count
, params
->type
.oids
, (const char *const*) params
->param
.strings
, NULL
, NULL
, 0);
1223 php_pq_params_free(¶ms
);
1226 throw_exce(EX_IO TSRMLS_CC
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1227 #if HAVE_PQSETSINGLEROWMODE
1228 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
1229 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1232 php_pq_callback_recurse(&obj
->intern
->onevent
, &resolver TSRMLS_CC
);
1233 obj
->intern
->poller
= PQconsumeInput
;
1234 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1238 zend_restore_error_handling(&zeh TSRMLS_CC
);
1241 STATUS
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, php_pq_params_t
*params TSRMLS_DC
)
1247 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1250 res
= PQprepare(obj
->intern
->conn
, name
, query
, params
->type
.count
, params
->type
.oids
);
1254 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1256 rv
= php_pqres_success(res TSRMLS_CC
);
1258 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1264 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
1265 ZEND_ARG_INFO(0, name
)
1266 ZEND_ARG_INFO(0, query
)
1267 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1268 ZEND_END_ARG_INFO();
1269 static PHP_METHOD(pqconn
, prepare
) {
1270 zend_error_handling zeh
;
1271 zval
*ztypes
= NULL
;
1272 char *name_str
, *query_str
;
1273 int name_len
, *query_len
;
1276 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1277 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
1278 zend_restore_error_handling(&zeh TSRMLS_CC
);
1280 if (SUCCESS
== rv
) {
1281 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1284 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1286 php_pq_params_t
*params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, NULL TSRMLS_CC
);
1288 if (SUCCESS
!= php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, params TSRMLS_CC
)) {
1289 php_pq_params_free(¶ms
);
1291 php_pqstm_t
*stm
= php_pqstm_init(obj
, name_str
, query_str
, params TSRMLS_CC
);
1293 return_value
->type
= IS_OBJECT
;
1294 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
1300 STATUS
php_pqconn_prepare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, php_pq_params_t
*params TSRMLS_DC
)
1305 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1308 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, params
->type
.count
, params
->type
.oids
)) {
1310 throw_exce(EX_IO TSRMLS_CC
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1313 obj
->intern
->poller
= PQconsumeInput
;
1314 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1320 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
1321 ZEND_ARG_INFO(0, name
)
1322 ZEND_ARG_INFO(0, query
)
1323 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1324 ZEND_END_ARG_INFO();
1325 static PHP_METHOD(pqconn
, prepareAsync
) {
1326 zend_error_handling zeh
;
1327 zval
*ztypes
= NULL
;
1328 char *name_str
, *query_str
;
1329 int name_len
, *query_len
;
1332 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1333 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
1334 zend_restore_error_handling(&zeh TSRMLS_CC
);
1336 if (SUCCESS
== rv
) {
1337 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1340 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1342 php_pq_params_t
*params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, NULL TSRMLS_CC
);
1344 if (SUCCESS
!= php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, params TSRMLS_CC
)) {
1345 php_pq_params_free(¶ms
);
1347 php_pqstm_t
*stm
= php_pqstm_init(obj
, name_str
, query_str
, params TSRMLS_CC
);
1349 return_value
->type
= IS_OBJECT
;
1350 return_value
->value
.obj
= php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
, NULL TSRMLS_CC
);
1356 STATUS
php_pqconn_declare(zval
*object
, php_pqconn_object_t
*obj
, const char *decl TSRMLS_DC
)
1362 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1365 res
= PQexec(obj
->intern
->conn
, decl
);
1369 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1371 rv
= php_pqres_success(res TSRMLS_CC
);
1373 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1379 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare
, 0, 0, 3)
1380 ZEND_ARG_INFO(0, name
)
1381 ZEND_ARG_INFO(0, flags
)
1382 ZEND_ARG_INFO(0, query
)
1383 ZEND_END_ARG_INFO();
1384 static PHP_METHOD(pqconn
, declare
) {
1385 zend_error_handling zeh
;
1386 char *name_str
, *query_str
;
1387 int name_len
, query_len
;
1391 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1392 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sls", &name_str
, &name_len
, &flags
, &query_str
, &query_len
);
1393 zend_restore_error_handling(&zeh TSRMLS_CC
);
1395 if (SUCCESS
== rv
) {
1396 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1399 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1401 char *decl
= php_pqcur_declare_str(name_str
, name_len
, flags
, query_str
, query_len
);
1403 if (SUCCESS
!= php_pqconn_declare(getThis(), obj
, decl TSRMLS_CC
)) {
1406 php_pqcur_t
*cur
= ecalloc(1, sizeof(*cur
));
1408 php_pq_object_addref(obj TSRMLS_CC
);
1411 cur
->name
= estrdup(name_str
);
1414 return_value
->type
= IS_OBJECT
;
1415 return_value
->value
.obj
= php_pqcur_create_object_ex(php_pqcur_class_entry
, cur
, NULL TSRMLS_CC
);
1421 STATUS
php_pqconn_declare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *decl TSRMLS_DC
)
1426 obj
= zend_object_store_get_object(object TSRMLS_CC
);
1429 if (!PQsendQuery(obj
->intern
->conn
, decl
)) {
1431 throw_exce(EX_IO TSRMLS_CC
, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1434 obj
->intern
->poller
= PQconsumeInput
;
1435 php_pqconn_notify_listeners(obj TSRMLS_CC
);
1441 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare_async
, 0, 0, 2)
1442 ZEND_ARG_INFO(0, name
)
1443 ZEND_ARG_INFO(0, flags
)
1444 ZEND_ARG_INFO(0, query
)
1445 ZEND_END_ARG_INFO();
1446 static PHP_METHOD(pqconn
, declareAsync
) {
1447 zend_error_handling zeh
;
1448 char *name_str
, *query_str
;
1449 int name_len
, query_len
;
1453 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1454 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sls", &name_str
, &name_len
, &flags
, &query_str
, &query_len
);
1455 zend_restore_error_handling(&zeh TSRMLS_CC
);
1457 if (SUCCESS
== rv
) {
1458 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1461 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1463 char *decl
= php_pqcur_declare_str(name_str
, name_len
, flags
, query_str
, query_len
);
1465 if (SUCCESS
!= php_pqconn_declare_async(getThis(), obj
, decl TSRMLS_CC
)) {
1468 php_pqcur_t
*cur
= ecalloc(1, sizeof(*cur
));
1470 php_pq_object_addref(obj TSRMLS_CC
);
1473 cur
->name
= estrdup(name_str
);
1476 return_value
->type
= IS_OBJECT
;
1477 return_value
->value
.obj
= php_pqcur_create_object_ex(php_pqcur_class_entry
, cur
, NULL TSRMLS_CC
);
1483 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
1484 ZEND_ARG_INFO(0, string
)
1485 ZEND_END_ARG_INFO();
1486 static PHP_METHOD(pqconn
, quote
) {
1490 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1491 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1494 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1496 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
1499 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1502 RETVAL_STRING(quoted
, 1);
1509 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
1510 ZEND_ARG_INFO(0, type
)
1511 ZEND_END_ARG_INFO();
1512 static PHP_METHOD(pqconn
, quoteName
) {
1516 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1517 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1520 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1522 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
1525 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1528 RETVAL_STRING(quoted
, 1);
1535 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
1536 ZEND_ARG_INFO(0, bytea
)
1537 ZEND_END_ARG_INFO();
1538 static PHP_METHOD(pqconn
, escapeBytea
) {
1542 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1543 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1546 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1549 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
1552 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1555 RETVAL_STRINGL(escaped_str
, escaped_len
- 1, 1);
1556 PQfreemem(escaped_str
);
1562 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
1563 ZEND_ARG_INFO(0, bytea
)
1564 ZEND_END_ARG_INFO();
1565 static PHP_METHOD(pqconn
, unescapeBytea
) {
1569 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &str
, &len
)) {
1570 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1573 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1575 size_t unescaped_len
;
1576 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
1578 if (!unescaped_str
) {
1579 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1582 RETVAL_STRINGL(unescaped_str
, unescaped_len
, 1);
1583 PQfreemem(unescaped_str
);
1589 STATUS
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
1591 STATUS rv
= FAILURE
;
1594 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
1597 if (!conn_obj
->intern
) {
1598 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1601 smart_str cmd
= {0};
1602 const char *il
= php_pq_isolation_level(&isolation
);
1604 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
1605 smart_str_appends(&cmd
, il
);
1606 smart_str_appends(&cmd
, ", READ ");
1607 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
1608 smart_str_appends(&cmd
, ",");
1609 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
1610 smart_str_appends(&cmd
, " DEFERRABLE");
1613 res
= PQexec(conn_obj
->intern
->conn
, cmd
.c
);
1616 throw_exce(EX_RUNTIME TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
1618 rv
= php_pqres_success(res TSRMLS_CC
);
1620 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
1623 smart_str_free(&cmd
);
1629 STATUS
php_pqconn_start_transaction_async(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable TSRMLS_DC
)
1631 STATUS rv
= FAILURE
;
1634 conn_obj
= zend_object_store_get_object(zconn TSRMLS_CC
);
1637 if (!conn_obj
->intern
) {
1638 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1640 smart_str cmd
= {0};
1641 const char *il
= php_pq_isolation_level(&isolation
);
1643 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
1644 smart_str_appends(&cmd
, il
);
1645 smart_str_appends(&cmd
, ", READ ");
1646 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
1647 smart_str_appends(&cmd
, ",");
1648 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
1649 smart_str_appends(&cmd
, " DEFERRABLE");
1652 if (!PQsendQuery(conn_obj
->intern
->conn
, cmd
.c
)) {
1653 throw_exce(EX_IO TSRMLS_CC
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
1656 conn_obj
->intern
->poller
= PQconsumeInput
;
1657 php_pqconn_notify_listeners(conn_obj TSRMLS_CC
);
1660 smart_str_free(&cmd
);
1666 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
1667 ZEND_ARG_INFO(0, isolation
)
1668 ZEND_ARG_INFO(0, readonly
)
1669 ZEND_ARG_INFO(0, deferrable
)
1670 ZEND_END_ARG_INFO();
1671 static PHP_METHOD(pqconn
, startTransaction
) {
1672 zend_error_handling zeh
;
1673 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1674 long isolation
= obj
->intern
? obj
->intern
->default_txn_isolation
: PHP_PQTXN_READ_COMMITTED
;
1675 zend_bool readonly
= obj
->intern
? obj
->intern
->default_txn_readonly
: 0;
1676 zend_bool deferrable
= obj
->intern
? obj
->intern
->default_txn_deferrable
: 0;
1679 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1680 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
1681 zend_restore_error_handling(&zeh TSRMLS_CC
);
1683 if (SUCCESS
== rv
) {
1684 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
1686 if (SUCCESS
== rv
) {
1687 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1689 php_pq_object_addref(obj TSRMLS_CC
);
1692 txn
->isolation
= isolation
;
1693 txn
->readonly
= readonly
;
1694 txn
->deferrable
= deferrable
;
1696 return_value
->type
= IS_OBJECT
;
1697 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
1702 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
1703 ZEND_ARG_INFO(0, isolation
)
1704 ZEND_ARG_INFO(0, readonly
)
1705 ZEND_ARG_INFO(0, deferrable
)
1706 ZEND_END_ARG_INFO();
1707 static PHP_METHOD(pqconn
, startTransactionAsync
) {
1708 zend_error_handling zeh
;
1709 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1710 long isolation
= obj
->intern
? obj
->intern
->default_txn_isolation
: PHP_PQTXN_READ_COMMITTED
;
1711 zend_bool readonly
= obj
->intern
? obj
->intern
->default_txn_readonly
: 0;
1712 zend_bool deferrable
= obj
->intern
? obj
->intern
->default_txn_deferrable
: 0;
1715 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1716 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lbb", &isolation
, &readonly
, &deferrable
);
1717 zend_restore_error_handling(&zeh TSRMLS_CC
);
1719 if (SUCCESS
== rv
) {
1720 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable TSRMLS_CC
);
1722 if (SUCCESS
== rv
) {
1723 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1725 php_pq_object_addref(obj TSRMLS_CC
);
1728 txn
->isolation
= isolation
;
1729 txn
->readonly
= readonly
;
1730 txn
->deferrable
= deferrable
;
1732 return_value
->type
= IS_OBJECT
;
1733 return_value
->value
.obj
= php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
, NULL TSRMLS_CC
);
1738 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
1739 ZEND_ARG_INFO(0, stdio_stream
)
1740 ZEND_END_ARG_INFO();
1741 static PHP_METHOD(pqconn
, trace
) {
1742 zval
*zstream
= NULL
;
1744 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r!", &zstream
)) {
1745 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1748 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1751 PQuntrace(obj
->intern
->conn
);
1755 php_stream
*stream
= NULL
;
1757 php_stream_from_zval(stream
, &zstream
);
1759 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
1762 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1763 PQtrace(obj
->intern
->conn
, fp
);
1771 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_off
, 0, 0, 1)
1772 ZEND_ARG_INFO(0, type
)
1773 ZEND_END_ARG_INFO();
1774 static PHP_METHOD(pqconn
, off
) {
1775 zend_error_handling zeh
;
1780 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1781 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &type_str
, &type_len
);
1782 zend_restore_error_handling(&zeh TSRMLS_CC
);
1784 if (SUCCESS
== rv
) {
1785 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1788 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1790 RETURN_BOOL(SUCCESS
== zend_hash_del(&obj
->intern
->eventhandlers
, type_str
, type_len
+ 1));
1795 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on
, 0, 0, 2)
1796 ZEND_ARG_INFO(0, type
)
1797 ZEND_ARG_INFO(0, callable
)
1798 ZEND_END_ARG_INFO();
1799 static PHP_METHOD(pqconn
, on
) {
1800 zend_error_handling zeh
;
1803 php_pq_callback_t cb
= {{0}};
1806 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1807 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sf", &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
1808 zend_restore_error_handling(&zeh TSRMLS_CC
);
1810 if (SUCCESS
== rv
) {
1811 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1814 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1816 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1818 RETVAL_LONG(php_pqconn_add_eventhandler(obj
, type_str
, type_len
, &cb TSRMLS_CC
));
1823 struct apply_set_converter_arg
{
1829 static int apply_set_converter(void *p
, void *a TSRMLS_DC
)
1831 zval
*tmp
, **zoid
= p
;
1832 struct apply_set_converter_arg
*arg
= a
;
1836 convert_to_long_ex(&tmp
);
1838 Z_ADDREF_PP(arg
->zconv
);
1839 zend_hash_index_update(arg
->ht
, Z_LVAL_P(tmp
), arg
->zconv
, sizeof(zval
*), NULL
);
1841 zend_hash_index_del(arg
->ht
, Z_LVAL_P(tmp
));
1843 zval_ptr_dtor(&tmp
);
1845 return ZEND_HASH_APPLY_KEEP
;
1848 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_set_converter
, 0, 0, 1)
1849 ZEND_ARG_OBJ_INFO(0, converter
, pq
\\Converter
, 0)
1850 ZEND_END_ARG_INFO();
1851 static PHP_METHOD(pqconn
, setConverter
) {
1853 zend_error_handling zeh
;
1856 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1857 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zcnv
, php_pqconv_class_entry
);
1858 zend_restore_error_handling(&zeh TSRMLS_CC
);
1860 if (SUCCESS
== rv
) {
1861 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1864 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1866 zval
*tmp
, *zoids
= NULL
;
1867 struct apply_set_converter_arg arg
= {NULL
};
1869 zend_call_method_with_0_params(&zcnv
, NULL
, NULL
, "converttypes", &zoids
);
1872 convert_to_array_ex(&tmp
);
1874 arg
.ht
= &obj
->intern
->converters
;
1878 zend_hash_apply_with_argument(Z_ARRVAL_P(tmp
), apply_set_converter
, &arg TSRMLS_CC
);
1880 zval_ptr_dtor(&tmp
);
1881 zval_ptr_dtor(&zoids
);
1886 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unset_converter
, 0, 0, 1)
1887 ZEND_ARG_OBJ_INFO(0, converter
, pq
\\Converter
, 0)
1888 ZEND_END_ARG_INFO();
1889 static PHP_METHOD(pqconn
, unsetConverter
) {
1891 zend_error_handling zeh
;
1894 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh TSRMLS_CC
);
1895 rv
= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &zcnv
, php_pqconv_class_entry
);
1896 zend_restore_error_handling(&zeh TSRMLS_CC
);
1898 if (SUCCESS
== rv
) {
1899 php_pqconn_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1902 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1904 zval
*tmp
, *zoids
= NULL
;
1905 struct apply_set_converter_arg arg
= {NULL
};
1907 zend_call_method_with_0_params(&zcnv
, NULL
, NULL
, "converttypes", &zoids
);
1910 convert_to_array_ex(&tmp
);
1912 arg
.ht
= &obj
->intern
->converters
;
1916 zend_hash_apply_with_argument(Z_ARRVAL_P(tmp
), apply_set_converter
, &arg TSRMLS_CC
);
1918 zval_ptr_dtor(&tmp
);
1919 zval_ptr_dtor(&zoids
);
1924 static zend_function_entry php_pqconn_methods
[] = {
1925 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
1926 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
1927 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
1928 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
1929 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
1930 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
1931 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
1932 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
1933 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
1934 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
1935 PHP_ME(pqconn
, declare
, ai_pqconn_declare
, ZEND_ACC_PUBLIC
)
1936 PHP_ME(pqconn
, declareAsync
, ai_pqconn_declare_async
, ZEND_ACC_PUBLIC
)
1937 PHP_ME(pqconn
, unlisten
, ai_pqconn_unlisten
, ZEND_ACC_PUBLIC
)
1938 PHP_ME(pqconn
, unlistenAsync
, ai_pqconn_unlisten_async
, ZEND_ACC_PUBLIC
)
1939 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
1940 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
1941 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
1942 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
1943 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
1944 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
1945 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
1946 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
1947 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
1948 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
1949 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
1950 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
1951 PHP_ME(pqconn
, off
, ai_pqconn_off
, ZEND_ACC_PUBLIC
)
1952 PHP_ME(pqconn
, on
, ai_pqconn_on
, ZEND_ACC_PUBLIC
)
1953 PHP_ME(pqconn
, setConverter
, ai_pqconn_set_converter
, ZEND_ACC_PUBLIC
)
1954 PHP_ME(pqconn
, unsetConverter
, ai_pqconn_unset_converter
, ZEND_ACC_PUBLIC
)
1958 PHP_MSHUTDOWN_FUNCTION(pqconn
)
1960 zend_hash_destroy(&php_pqconn_object_prophandlers
);
1964 PHP_MINIT_FUNCTION(pqconn
)
1966 zend_class_entry ce
= {0};
1967 php_pq_object_prophandler_t ph
= {0};
1969 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
1970 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
, NULL TSRMLS_CC
);
1971 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
1973 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
1974 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
1975 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
1976 php_pqconn_object_handlers
.clone_obj
= NULL
;
1977 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
1978 php_pqconn_object_handlers
.get_gc
= NULL
;
1979 php_pqconn_object_handlers
.get_properties
= php_pq_object_properties
;
1980 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
1982 zend_hash_init(&php_pqconn_object_prophandlers
, 20, NULL
, NULL
, 1);
1984 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC TSRMLS_CC
);
1985 ph
.read
= php_pqconn_object_read_status
;
1986 zend_hash_add(&php_pqconn_object_prophandlers
, "status", sizeof("status"), (void *) &ph
, sizeof(ph
), NULL
);
1988 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC TSRMLS_CC
);
1989 ph
.read
= php_pqconn_object_read_transaction_status
;
1990 zend_hash_add(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus"), (void *) &ph
, sizeof(ph
), NULL
);
1992 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC
);
1993 ph
.read
= NULL
; /* forward to std prophandler */
1994 zend_hash_add(&php_pqconn_object_prophandlers
, "socket", sizeof("socket"), (void *) &ph
, sizeof(ph
), NULL
);
1996 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC
);
1997 ph
.read
= php_pqconn_object_read_error_message
;
1998 zend_hash_add(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage"), (void *) &ph
, sizeof(ph
), NULL
);
2000 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2001 ph
.read
= php_pqconn_object_read_busy
;
2002 zend_hash_add(&php_pqconn_object_prophandlers
, "busy", sizeof("busy"), (void *) &ph
, sizeof(ph
), NULL
);
2004 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2005 ph
.read
= php_pqconn_object_read_encoding
;
2006 ph
.write
= php_pqconn_object_write_encoding
;
2007 zend_hash_add(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding"), (void *) &ph
, sizeof(ph
), NULL
);
2010 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2011 ph
.read
= php_pqconn_object_read_unbuffered
;
2012 ph
.write
= php_pqconn_object_write_unbuffered
;
2013 zend_hash_add(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered"), (void *) &ph
, sizeof(ph
), NULL
);
2016 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2017 ph
.read
= php_pqconn_object_read_db
;
2018 zend_hash_add(&php_pqconn_object_prophandlers
, "db", sizeof("db"), (void *) &ph
, sizeof(ph
), NULL
);
2020 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2021 ph
.read
= php_pqconn_object_read_user
;
2022 zend_hash_add(&php_pqconn_object_prophandlers
, "user", sizeof("user"), (void *) &ph
, sizeof(ph
), NULL
);
2024 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2025 ph
.read
= php_pqconn_object_read_pass
;
2026 zend_hash_add(&php_pqconn_object_prophandlers
, "pass", sizeof("pass"), (void *) &ph
, sizeof(ph
), NULL
);
2028 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2029 ph
.read
= php_pqconn_object_read_host
;
2030 zend_hash_add(&php_pqconn_object_prophandlers
, "host", sizeof("host"), (void *) &ph
, sizeof(ph
), NULL
);
2032 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2033 ph
.read
= php_pqconn_object_read_port
;
2034 zend_hash_add(&php_pqconn_object_prophandlers
, "port", sizeof("port"), (void *) &ph
, sizeof(ph
), NULL
);
2037 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("params"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2038 ph
.read
= php_pqconn_object_read_params
;
2039 zend_hash_add(&php_pqconn_object_prophandlers
, "params", sizeof("params"), (void *) &ph
, sizeof(ph
), NULL
);
2042 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2043 ph
.read
= php_pqconn_object_read_options
;
2044 zend_hash_add(&php_pqconn_object_prophandlers
, "options", sizeof("options"), (void *) &ph
, sizeof(ph
), NULL
);
2046 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC
);
2047 ph
.read
= php_pqconn_object_read_event_handlers
;
2048 zend_hash_add(&php_pqconn_object_prophandlers
, "eventHandlers", sizeof("eventHandlers"), (void *) &ph
, sizeof(ph
), NULL
);
2050 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2051 ph
.read
= php_pqconn_object_read_def_fetch_type
;
2052 ph
.write
= php_pqconn_object_write_def_fetch_type
;
2053 zend_hash_add(&php_pqconn_object_prophandlers
, "defaultFetchType", sizeof("defaultFetchType"), (void *) &ph
, sizeof(ph
), NULL
);
2056 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2057 ph
.read
= php_pqconn_object_read_def_txn_isolation
;
2058 ph
.write
= php_pqconn_object_write_def_txn_isolation
;
2059 zend_hash_add(&php_pqconn_object_prophandlers
, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation"), (void *) &ph
, sizeof(ph
), NULL
);
2062 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2063 ph
.read
= php_pqconn_object_read_def_txn_readonly
;
2064 ph
.write
= php_pqconn_object_write_def_txn_readonly
;
2065 zend_hash_add(&php_pqconn_object_prophandlers
, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly"), (void *) &ph
, sizeof(ph
), NULL
);
2068 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
2069 ph
.read
= php_pqconn_object_read_def_txn_deferrable
;
2070 ph
.write
= php_pqconn_object_write_def_txn_deferrable
;
2071 zend_hash_add(&php_pqconn_object_prophandlers
, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable"), (void *) &ph
, sizeof(ph
), NULL
);
2074 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL
, ZEND_ACC_PUBLIC TSRMLS_CC
);
2075 ph
.read
= php_pqconn_object_read_def_auto_conv
;
2076 ph
.write
= php_pqconn_object_write_def_auto_conv
;
2077 zend_hash_add(&php_pqconn_object_prophandlers
, "defaultAutoConvert", sizeof("defaultAutoConvert"), (void *) &ph
, sizeof(ph
), NULL
);
2080 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC
);
2081 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC
);
2082 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC
);
2083 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC
);
2084 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC
);
2085 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC
);
2086 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC
);
2087 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC
);
2089 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC
);
2090 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC
);
2091 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC
);
2092 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC
);
2093 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC
);
2095 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC
);
2096 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC
);
2097 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC
);
2098 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC
);
2100 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice") TSRMLS_CC
);
2101 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result") TSRMLS_CC
);
2102 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset") TSRMLS_CC
);
2104 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC
);
2105 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC
);
2115 * vim600: noet sw=4 ts=4 fdm=marker
2116 * vim<600: noet sw=4 ts=4