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
;
39 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC)
43 if (SUCCESS == zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
44 zend_hash_index_del(Z_ARRVAL_PP(evhs), id);
49 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
)
54 if (!(evhs
= zend_hash_str_find_ptr(&obj
->intern
->eventhandlers
, type_str
, type_len
))) {
57 zend_hash_init(&evh
, 1, NULL
, (dtor_func_t
) php_pq_callback_dtor
, 0);
58 evhs
= zend_hash_str_add_mem(&obj
->intern
->eventhandlers
, type_str
, type_len
, (void *) &evh
, sizeof(evh
));
61 php_pq_callback_addref(cb
);
62 h
= zend_hash_next_free_element(evhs
);
63 zend_hash_index_update_ptr(evhs
, h
, (void *) cb
);
68 static void php_pqconn_object_free(zend_object
*o
)
70 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(NULL
, o
);
72 fprintf(stderr
, "FREE conn(#%d) %p\n", obj
->zv
.handle
, obj
);
75 php_pq_callback_dtor(&obj
->intern
->onevent
);
76 php_resource_factory_handle_dtor(&obj
->intern
->factory
, obj
->intern
->conn
);
77 php_resource_factory_dtor(&obj
->intern
->factory
);
78 zend_hash_destroy(&obj
->intern
->listeners
);
79 zend_hash_destroy(&obj
->intern
->converters
);
80 zend_hash_destroy(&obj
->intern
->eventhandlers
);
84 zend_object_std_dtor(o
);
89 php_pqconn_object_t
*php_pqconn_create_object_ex(zend_class_entry
*ce
, php_pqconn_t
*intern
)
91 php_pqconn_object_t
*o
;
93 o
= ecalloc(1, sizeof(*o
) + zend_object_properties_size(ce
));
94 zend_object_std_init(&o
->zo
, ce
);
95 object_properties_init(&o
->zo
, ce
);
96 o
->prophandler
= &php_pqconn_object_prophandlers
;
102 o
->zo
.handlers
= &php_pqconn_object_handlers
;
107 static zend_object
*php_pqconn_create_object(zend_class_entry
*class_type
)
109 return &php_pqconn_create_object_ex(class_type
, NULL
)->zo
;
112 static void php_pqconn_object_read_status(zval
*object
, void *o
, zval
*return_value
)
114 php_pqconn_object_t
*obj
= o
;
116 RETVAL_LONG(PQstatus(obj
->intern
->conn
));
119 static void php_pqconn_object_read_transaction_status(zval
*object
, void *o
, zval
*return_value
)
121 php_pqconn_object_t
*obj
= o
;
123 RETVAL_LONG(PQtransactionStatus(obj
->intern
->conn
));
126 static void php_pqconn_object_read_error_message(zval
*object
, void *o
, zval
*return_value
)
128 php_pqconn_object_t
*obj
= o
;
129 char *error
= PHP_PQerrorMessage(obj
->intern
->conn
);
132 RETVAL_STRING(error
);
138 static int apply_notify_listener(zval
*p
, void *arg
)
140 php_pq_callback_t
*listener
= Z_PTR_P(p
);
142 zval zpid
, zchannel
, zmessage
;
144 ZVAL_LONG(&zpid
, nfy
->be_pid
);
145 ZVAL_STRING(&zchannel
, nfy
->relname
);
146 ZVAL_STRING(&zmessage
, nfy
->extra
);
148 zend_fcall_info_argn(&listener
->fci
, 3, &zchannel
, &zmessage
, &zpid
);
149 zend_fcall_info_call(&listener
->fci
, &listener
->fcc
, NULL
, NULL
);
151 zval_ptr_dtor(&zchannel
);
152 zval_ptr_dtor(&zmessage
);
153 zval_ptr_dtor(&zpid
);
155 return ZEND_HASH_APPLY_KEEP
;
158 static int apply_notify_listeners(zval
*p
, int argc
, va_list argv
, zend_hash_key
*key
)
160 HashTable
*listeners
= Z_ARRVAL_P(p
);
161 PGnotify
*nfy
= va_arg(argv
, PGnotify
*);
163 if (0 == fnmatch(key
->key
->val
, nfy
->relname
, 0)) {
164 zend_hash_apply_with_argument(listeners
, apply_notify_listener
, nfy
);
167 return ZEND_HASH_APPLY_KEEP
;
170 void php_pqconn_notify_listeners(php_pqconn_object_t
*obj
)
174 while ((nfy
= PQnotifies(obj
->intern
->conn
))) {
175 zend_hash_apply_with_arguments(&obj
->intern
->listeners
, apply_notify_listeners
, 1, nfy
);
180 static void php_pqconn_object_read_busy(zval
*object
, void *o
, zval
*return_value
)
182 php_pqconn_object_t
*obj
= o
;
184 RETVAL_BOOL(PQisBusy(obj
->intern
->conn
));
187 static void php_pqconn_object_read_encoding(zval
*object
, void *o
, zval
*return_value
)
189 php_pqconn_object_t
*obj
= o
;
191 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj
->intern
->conn
)));
194 static void php_pqconn_object_write_encoding(zval
*object
, void *o
, zval
*value
)
196 php_pqconn_object_t
*obj
= o
;
197 zend_string
*zenc
= zval_get_string(value
);
199 if (0 > PQsetClientEncoding(obj
->intern
->conn
, zenc
->val
)) {
200 php_error(E_NOTICE
, "Unrecognized encoding '%s'", zenc
->val
);
203 zend_string_release(zenc
);
206 static void php_pqconn_object_read_unbuffered(zval
*object
, void *o
, zval
*return_value
)
208 php_pqconn_object_t
*obj
= o
;
210 RETVAL_BOOL(obj
->intern
->unbuffered
);
213 static void php_pqconn_object_write_unbuffered(zval
*object
, void *o
, zval
*value
)
215 php_pqconn_object_t
*obj
= o
;
217 obj
->intern
->unbuffered
= z_is_true(value
);
220 static void php_pqconn_object_read_db(zval
*object
, void *o
, zval
*return_value
)
222 php_pqconn_object_t
*obj
= o
;
223 char *db
= PQdb(obj
->intern
->conn
);
228 RETVAL_EMPTY_STRING();
232 static void php_pqconn_object_read_user(zval
*object
, void *o
, zval
*return_value
)
234 php_pqconn_object_t
*obj
= o
;
235 char *user
= PQuser(obj
->intern
->conn
);
240 RETVAL_EMPTY_STRING();
244 static void php_pqconn_object_read_pass(zval
*object
, void *o
, zval
*return_value
)
246 php_pqconn_object_t
*obj
= o
;
247 char *pass
= PQpass(obj
->intern
->conn
);
252 RETVAL_EMPTY_STRING();
256 static void php_pqconn_object_read_host(zval
*object
, void *o
, zval
*return_value
)
258 php_pqconn_object_t
*obj
= o
;
259 char *host
= PQhost(obj
->intern
->conn
);
264 RETVAL_EMPTY_STRING();
268 static void php_pqconn_object_read_port(zval
*object
, void *o
, zval
*return_value
)
270 php_pqconn_object_t
*obj
= o
;
271 char *port
= PQport(obj
->intern
->conn
);
276 RETVAL_EMPTY_STRING();
281 static void php_pqconn_object_read_params(zval
*object
, void *o
, zval
*return_value
)
283 php_pqconn_object_t
*obj
= o
;
284 PQconninfoOption
*ptr
, *params
= PQconninfo(obj
->intern
->conn
);
286 array_init(return_value
);
289 for (ptr
= params
; ptr
->keyword
; ++ptr
) {
291 add_assoc_string(return_value
, ptr
->keyword
, ptr
->val
);
293 add_assoc_null(return_value
, ptr
->keyword
);
296 PQconninfoFree(params
);
301 static void php_pqconn_object_read_options(zval
*object
, void *o
, zval
*return_value
)
303 php_pqconn_object_t
*obj
= o
;
304 char *options
= PQoptions(obj
->intern
->conn
);
307 RETVAL_STRING(options
);
309 RETVAL_EMPTY_STRING();
313 static int apply_read_event_handler_ex(zval
*p
, void *arg
)
318 zend_hash_next_index_insert(rv
, php_pq_callback_to_zval(Z_PTR_P(p
), &zcb
));
320 return ZEND_HASH_APPLY_KEEP
;
323 static int apply_read_event_handlers(zval
*p
, int argc
, va_list argv
, zend_hash_key
*key
)
325 HashTable
*evhs
= Z_PTR_P(p
), *rv
= va_arg(argv
, HashTable
*);
326 zval entry
, *entry_ptr
;
328 array_init_size(&entry
, zend_hash_num_elements(evhs
));
331 entry_ptr
= zend_hash_add(rv
, key
->key
, &entry
);
333 entry_ptr
= zend_hash_index_update(rv
, key
->h
, &entry
);
336 zend_hash_apply_with_argument(evhs
, apply_read_event_handler_ex
, Z_ARRVAL_P(entry_ptr
));
338 return ZEND_HASH_APPLY_KEEP
;
340 static void php_pqconn_object_read_event_handlers(zval
*object
, void *o
, zval
*return_value
)
342 php_pqconn_object_t
*obj
= o
;
344 array_init(return_value
);
345 zend_hash_apply_with_arguments(&obj
->intern
->eventhandlers
, apply_read_event_handlers
, 1, Z_ARRVAL_P(return_value
) TSRMLS_CC
);
348 static void php_pqconn_object_read_def_fetch_type(zval
*object
, void *o
, zval
*return_value
)
350 php_pqconn_object_t
*obj
= o
;
352 RETVAL_LONG(obj
->intern
->default_fetch_type
);
354 static void php_pqconn_object_write_def_fetch_type(zval
*object
, void *o
, zval
*value
)
356 php_pqconn_object_t
*obj
= o
;
358 obj
->intern
->default_fetch_type
= zval_get_long(value
) & 0x3; /* two bits only */
361 static void php_pqconn_object_read_def_txn_isolation(zval
*object
, void *o
, zval
*return_value
)
363 php_pqconn_object_t
*obj
= o
;
365 RETVAL_LONG(obj
->intern
->default_txn_isolation
);
367 static void php_pqconn_object_write_def_txn_isolation(zval
*object
, void *o
, zval
*value
)
369 php_pqconn_object_t
*obj
= o
;
371 obj
->intern
->default_txn_isolation
= zval_get_long(value
) & 0x3; /* two bits only */
374 static void php_pqconn_object_read_def_txn_readonly(zval
*object
, void *o
, zval
*return_value
)
376 php_pqconn_object_t
*obj
= o
;
378 RETVAL_BOOL(obj
->intern
->default_txn_readonly
);
380 static void php_pqconn_object_write_def_txn_readonly(zval
*object
, void *o
, zval
*value
)
382 php_pqconn_object_t
*obj
= o
;
384 obj
->intern
->default_txn_readonly
= z_is_true(value
);
387 static void php_pqconn_object_read_def_txn_deferrable(zval
*object
, void *o
, zval
*return_value
)
389 php_pqconn_object_t
*obj
= o
;
391 RETVAL_BOOL(obj
->intern
->default_txn_deferrable
);
393 static void php_pqconn_object_write_def_txn_deferrable(zval
*object
, void *o
, zval
*value
)
395 php_pqconn_object_t
*obj
= o
;
397 obj
->intern
->default_txn_deferrable
= zend_is_true(value
);
400 static void php_pqconn_object_read_def_auto_conv(zval
*object
, void *o
, zval
*return_value
)
402 php_pqconn_object_t
*obj
= o
;
404 RETVAL_LONG(obj
->intern
->default_auto_convert
);
406 static void php_pqconn_object_write_def_auto_conv(zval
*object
, void *o
, zval
*value
)
408 php_pqconn_object_t
*obj
= o
;
410 obj
->intern
->default_auto_convert
= zval_get_long(value
) & PHP_PQRES_CONV_ALL
;
413 static ZEND_RESULT_CODE
php_pqconn_update_socket(zval
*zobj
, php_pqconn_object_t
*obj
)
415 zval zsocket
, zmember
;
417 ZEND_RESULT_CODE retval
;
421 obj
= PHP_PQ_OBJ(zobj
, NULL
);
424 ZVAL_STRINGL(&zmember
, "socket", sizeof("socket")-1);
426 if ((CONNECTION_BAD
!= PQstatus(obj
->intern
->conn
))
427 && (-1 < (socket
= PQsocket(obj
->intern
->conn
)))
428 && (stream
= php_stream_fopen_from_fd(socket
, "r+b", NULL
))) {
429 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
430 php_stream_to_zval(stream
, &zsocket
);
436 zend_get_std_object_handlers()->write_property(zobj
, &zmember
, &zsocket
, NULL
);
437 zval_ptr_dtor(&zsocket
);
442 static void *php_pqconn_resource_factory_ctor(void *data
, void *init_arg
)
444 php_pqconn_resource_factory_data_t
*o
= init_arg
;
445 PGconn
*conn
= NULL
;;
447 if (o
->flags
& PHP_PQCONN_ASYNC
) {
448 conn
= PQconnectStart(o
->dsn
);
450 conn
= PQconnectdb(o
->dsn
);
454 PQregisterEventProc(conn
, php_pqconn_event
, "ext-pq", NULL
);
460 static void php_pqconn_resource_factory_dtor(void *opaque
, void *handle
)
462 php_pqconn_event_data_t
*evdata
= PQinstanceData(handle
, php_pqconn_event
);
464 /* we don't care for anything, except free'ing evdata */
466 PQsetInstanceData(handle
, php_pqconn_event
, NULL
);
467 memset(evdata
, 0, sizeof(*evdata
));
474 static php_resource_factory_ops_t php_pqconn_resource_factory_ops
= {
475 php_pqconn_resource_factory_ctor
,
477 php_pqconn_resource_factory_dtor
480 php_resource_factory_ops_t
*php_pqconn_get_resource_factory_ops(void)
482 return &php_pqconn_resource_factory_ops
;
485 static void php_pqconn_wakeup(php_persistent_handle_factory_t
*f
, void **handle
)
487 PGresult
*res
= PQexec(*handle
, "");
490 if (CONNECTION_OK
!= PQstatus(*handle
)) {
495 static inline PGresult
*unlisten(PGconn
*conn
, const char *channel_str
, size_t channel_len
)
497 char *quoted_channel
= PQescapeIdentifier(conn
, channel_str
, channel_len
);
498 PGresult
*res
= NULL
;
500 if (quoted_channel
) {
503 smart_str_appends(&cmd
, "UNLISTEN ");
504 smart_str_appends(&cmd
, quoted_channel
);
507 res
= PQexec(conn
, smart_str_v(&cmd
));
509 smart_str_free(&cmd
);
510 PQfreemem(quoted_channel
);
516 static int apply_unlisten(zval
*p
, int argc
, va_list argv
, zend_hash_key
*key
)
518 php_pqconn_object_t
*obj
= va_arg(argv
, php_pqconn_object_t
*);
519 PGresult
*res
= unlisten(obj
->intern
->conn
, key
->key
->val
, key
->key
->len
);
525 return ZEND_HASH_APPLY_REMOVE
;
528 static void php_pqconn_retire(php_persistent_handle_factory_t
*f
, void **handle
)
530 php_pqconn_event_data_t
*evdata
= PQinstanceData(*handle
, php_pqconn_event
);
535 PQsetInstanceData(*handle
, php_pqconn_event
, NULL
);
538 PQsetNoticeReceiver(*handle
, php_pqconn_notice_ignore
, NULL
);
540 /* cancel async queries */
541 if (PQisBusy(*handle
) && (cancel
= PQgetCancel(*handle
))) {
544 PQcancel(cancel
, err
, sizeof(err
));
545 PQfreeCancel(cancel
);
547 /* clean up async results */
548 while ((res
= PQgetResult(*handle
))) {
552 /* clean up transaction & session */
553 switch (PQtransactionStatus(*handle
)) {
555 res
= PQexec(*handle
, "RESET ALL");
558 res
= PQexec(*handle
, "ROLLBACK; RESET ALL");
567 /* clean up notify listeners */
568 zend_hash_apply_with_arguments(&evdata
->obj
->intern
->listeners
, apply_unlisten
, 1, evdata
->obj
);
570 /* release instance data */
575 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct
, 0, 0, 1)
576 ZEND_ARG_INFO(0, dsn
)
577 ZEND_ARG_INFO(0, flags
)
579 static PHP_METHOD(pqconn
, __construct
) {
580 zend_error_handling zeh
;
586 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
587 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "|sl", &dsn_str
, &dsn_len
, &flags
);
588 zend_restore_error_handling(&zeh TSRMLS_CC
);
591 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
594 throw_exce(EX_BAD_METHODCALL
, "pq\\Connection already initialized");
596 php_pqconn_event_data_t
*evdata
= php_pqconn_event_data_init(obj
);
597 php_pqconn_resource_factory_data_t rfdata
= {dsn_str
, flags
};
599 obj
->intern
= ecalloc(1, sizeof(*obj
->intern
));
601 obj
->intern
->default_auto_convert
= PHP_PQRES_CONV_ALL
;
603 zend_hash_init(&obj
->intern
->listeners
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
604 zend_hash_init(&obj
->intern
->converters
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
605 zend_hash_init(&obj
->intern
->eventhandlers
, 0, NULL
, (dtor_func_t
) zend_hash_destroy
, 0);
607 if (flags
& PHP_PQCONN_PERSISTENT
) {
608 zend_string
*dsn
= zend_string_init(dsn_str
, dsn_len
, 0);
609 php_persistent_handle_factory_t
*phf
= php_persistent_handle_concede(NULL
, PHP_PQ_G
->connection
.name
, dsn
, php_pqconn_wakeup
, php_pqconn_retire
);
610 php_persistent_handle_resource_factory_init(&obj
->intern
->factory
, phf
);
611 zend_string_release(dsn
);
613 php_resource_factory_init(&obj
->intern
->factory
, &php_pqconn_resource_factory_ops
, NULL
, NULL
);
616 if (flags
& PHP_PQCONN_ASYNC
) {
617 obj
->intern
->poller
= (int (*)(PGconn
*)) PQconnectPoll
;
620 obj
->intern
->conn
= php_resource_factory_handle_ctor(&obj
->intern
->factory
, &rfdata
);
622 PQsetInstanceData(obj
->intern
->conn
, php_pqconn_event
, evdata
);
623 PQsetNoticeReceiver(obj
->intern
->conn
, php_pqconn_notice_recv
, evdata
);
625 if (SUCCESS
!= php_pqconn_update_socket(getThis(), obj
)) {
626 throw_exce(EX_CONNECTION_FAILED
, "Connection failed (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
632 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset
, 0, 0, 0)
634 static PHP_METHOD(pqconn
, reset
) {
635 zend_error_handling zeh
;
638 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
639 rv
= zend_parse_parameters_none();
640 zend_restore_error_handling(&zeh
);
643 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
646 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
648 PQreset(obj
->intern
->conn
);
650 if (CONNECTION_OK
!= PQstatus(obj
->intern
->conn
)) {
651 throw_exce(EX_CONNECTION_FAILED
, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
654 php_pqconn_notify_listeners(obj
);
659 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async
, 0, 0, 0)
661 static PHP_METHOD(pqconn
, resetAsync
) {
662 zend_error_handling zeh
;
665 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
666 rv
= zend_parse_parameters_none();
667 zend_restore_error_handling(&zeh
);
670 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
673 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
675 if (!PQresetStart(obj
->intern
->conn
)) {
676 throw_exce(EX_IO TSRMLS_CC
, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
678 obj
->intern
->poller
= (int (*)(PGconn
*)) PQresetPoll
;
681 php_pqconn_notify_listeners(obj
);
686 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten
, 0, 0, 1)
687 ZEND_ARG_INFO(0, channel
)
689 static PHP_METHOD(pqconn
, unlisten
)
691 zend_error_handling zeh
;
696 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
697 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str
, &channel_len
);
698 zend_restore_error_handling(&zeh
);
701 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
704 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
705 } else if (SUCCESS
== zend_hash_str_del(&obj
->intern
->listeners
, channel_str
, channel_len
)) {
706 PGresult
*res
= unlisten(obj
->intern
->conn
, channel_str
, channel_len
);
709 php_pqres_success(res
);
716 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten_async
, 0, 0, 1)
717 ZEND_ARG_INFO(0, channel
)
719 static PHP_METHOD(pqconn
, unlistenAsync
) {
720 zend_error_handling zeh
;
725 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
726 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s", &channel_str
, &channel_len
);
727 zend_restore_error_handling(&zeh
);
730 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
733 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
735 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
737 if (!quoted_channel
) {
738 throw_exce(EX_ESCAPE
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
742 smart_str_appends(&cmd
, "UNLISTEN ");
743 smart_str_appends(&cmd
, quoted_channel
);
746 if (!PQsendQuery(obj
->intern
->conn
, smart_str_v(&cmd
))) {
747 throw_exce(EX_IO
, "Failed to uninstall listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
749 obj
->intern
->poller
= PQconsumeInput
;
750 zend_hash_str_del(&obj
->intern
->listeners
, channel_str
, channel_len
);
753 smart_str_free(&cmd
);
754 PQfreemem(quoted_channel
);
755 php_pqconn_notify_listeners(obj
);
761 static void php_pqconn_add_listener(php_pqconn_object_t
*obj
, const char *channel_str
, size_t channel_len
, php_pq_callback_t
*listener
)
765 php_pq_callback_addref(listener
);
767 if ((existing
= zend_hash_str_find(&obj
->intern
->listeners
, channel_str
, channel_len
))) {
768 zend_hash_next_index_insert_mem(Z_ARRVAL_P(existing
), (void *) listener
, sizeof(*listener
));
771 zend_hash_next_index_insert_mem(Z_ARRVAL(tmp
), (void *) listener
, sizeof(*listener
));
772 zend_hash_str_add(&obj
->intern
->listeners
, channel_str
, channel_len
, &tmp
);
776 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen
, 0, 0, 2)
777 ZEND_ARG_INFO(0, channel
)
778 ZEND_ARG_INFO(0, callable
)
780 static PHP_METHOD(pqconn
, listen
) {
781 zend_error_handling zeh
;
782 char *channel_str
= NULL
;
783 size_t channel_len
= 0;
784 php_pq_callback_t listener
= {{0}};
787 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
788 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
789 zend_restore_error_handling(&zeh
);
792 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
795 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
797 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
799 if (!quoted_channel
) {
800 throw_exce(EX_ESCAPE
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
805 smart_str_appends(&cmd
, "LISTEN ");
806 smart_str_appends(&cmd
, quoted_channel
);
809 res
= PQexec(obj
->intern
->conn
, smart_str_v(&cmd
));
811 smart_str_free(&cmd
);
812 PQfreemem(quoted_channel
);
815 throw_exce(EX_RUNTIME
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
817 if (SUCCESS
== php_pqres_success(res
)) {
818 obj
->intern
->poller
= PQconsumeInput
;
819 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener
);
824 php_pqconn_notify_listeners(obj
);
830 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async
, 0, 0, 0)
831 ZEND_ARG_INFO(0, channel
)
832 ZEND_ARG_INFO(0, callable
)
834 static PHP_METHOD(pqconn
, listenAsync
) {
835 zend_error_handling zeh
;
836 char *channel_str
= NULL
;
837 size_t channel_len
= 0;
838 php_pq_callback_t listener
= {{0}};
841 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
842 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &channel_str
, &channel_len
, &listener
.fci
, &listener
.fcc
);
843 zend_restore_error_handling(&zeh
);
846 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
849 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
851 char *quoted_channel
= PQescapeIdentifier(obj
->intern
->conn
, channel_str
, channel_len
);
853 if (!quoted_channel
) {
854 throw_exce(EX_ESCAPE TSRMLS_CC
, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
858 smart_str_appends(&cmd
, "LISTEN ");
859 smart_str_appends(&cmd
, quoted_channel
);
862 if (!PQsendQuery(obj
->intern
->conn
, smart_str_v(&cmd
))) {
863 throw_exce(EX_IO
, "Failed to install listener (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
865 obj
->intern
->poller
= PQconsumeInput
;
866 php_pqconn_add_listener(obj
, channel_str
, channel_len
, &listener
);
869 smart_str_free(&cmd
);
870 PQfreemem(quoted_channel
);
871 php_pqconn_notify_listeners(obj
);
877 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify
, 0, 0, 2)
878 ZEND_ARG_INFO(0, channel
)
879 ZEND_ARG_INFO(0, message
)
881 static PHP_METHOD(pqconn
, notify
) {
882 zend_error_handling zeh
;
883 char *channel_str
, *message_str
;
884 size_t channel_len
, message_len
;
887 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
888 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
889 zend_restore_error_handling(&zeh
);
892 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
895 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
898 char *params
[2] = {channel_str
, message_str
};
900 res
= PQexecParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0);
903 throw_exce(EX_RUNTIME
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
905 php_pqres_success(res
);
909 php_pqconn_notify_listeners(obj
);
914 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async
, 0, 0, 2)
915 ZEND_ARG_INFO(0, channel
)
916 ZEND_ARG_INFO(0, message
)
918 static PHP_METHOD(pqconn
, notifyAsync
) {
919 zend_error_handling zeh
;
920 char *channel_str
, *message_str
;
921 size_t channel_len
, message_len
;
924 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
925 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &channel_str
, &channel_len
, &message_str
, &message_len
);
926 zend_restore_error_handling(&zeh
);
929 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
932 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
934 char *params
[2] = {channel_str
, message_str
};
936 if (!PQsendQueryParams(obj
->intern
->conn
, "select pg_notify($1, $2)", 2, NULL
, (const char *const*) params
, NULL
, NULL
, 0)) {
937 throw_exce(EX_IO
, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
939 obj
->intern
->poller
= PQconsumeInput
;
942 php_pqconn_notify_listeners(obj
);
947 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll
, 0, 0, 0)
949 static PHP_METHOD(pqconn
, poll
) {
950 zend_error_handling zeh
;
953 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
954 rv
= zend_parse_parameters_none();
955 zend_restore_error_handling(&zeh
);
958 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
961 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
962 } else if (!obj
->intern
->poller
) {
963 throw_exce(EX_RUNTIME
, "No asynchronous operation active");
965 if (obj
->intern
->poller
== PQconsumeInput
) {
966 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
) * PGRES_POLLING_OK
);
968 RETVAL_LONG(obj
->intern
->poller(obj
->intern
->conn
));
970 php_pqconn_notify_listeners(obj
);
975 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec
, 0, 0, 1)
976 ZEND_ARG_INFO(0, query
)
978 static PHP_METHOD(pqconn
, exec
) {
979 zend_error_handling zeh
;
984 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
985 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query_str
, &query_len
);
986 zend_restore_error_handling(&zeh
);
989 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
992 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
994 PGresult
*res
= PQexec(obj
->intern
->conn
, query_str
);
997 throw_exce(EX_RUNTIME
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
998 } else if (SUCCESS
== php_pqres_success(res
)) {
999 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), return_value
);
1004 php_pqconn_notify_listeners(obj
);
1009 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result
, 0, 0, 0)
1010 ZEND_END_ARG_INFO();
1011 static PHP_METHOD(pqconn
, getResult
) {
1012 zend_error_handling zeh
;
1013 ZEND_RESULT_CODE rv
;
1015 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1016 rv
= zend_parse_parameters_none();
1017 zend_restore_error_handling(&zeh
);
1019 if (SUCCESS
== rv
) {
1020 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1023 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1025 PGresult
*res
= PQgetResult(obj
->intern
->conn
);
1030 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), return_value
);
1033 php_pqconn_notify_listeners(obj
);
1038 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async
, 0, 0, 1)
1039 ZEND_ARG_INFO(0, query
)
1040 ZEND_ARG_INFO(0, callable
)
1041 ZEND_END_ARG_INFO();
1042 static PHP_METHOD(pqconn
, execAsync
) {
1043 zend_error_handling zeh
;
1044 php_pq_callback_t resolver
= {{0}};
1047 ZEND_RESULT_CODE rv
;
1049 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1050 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "s|f", &query_str
, &query_len
, &resolver
.fci
, &resolver
.fcc
);
1051 zend_restore_error_handling(&zeh
);
1053 if (SUCCESS
== rv
) {
1054 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1057 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1058 } else if (!PQsendQuery(obj
->intern
->conn
, query_str
)) {
1059 throw_exce(EX_IO
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1060 #if HAVE_PQSETSINGLEROWMODE
1061 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
1062 throw_exce(EX_RUNTIME
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1065 php_pq_callback_recurse(&obj
->intern
->onevent
, &resolver
);
1066 obj
->intern
->poller
= PQconsumeInput
;
1067 php_pqconn_notify_listeners(obj
);
1072 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params
, 0, 0, 2)
1073 ZEND_ARG_INFO(0, query
)
1074 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1075 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1076 ZEND_END_ARG_INFO();
1077 static PHP_METHOD(pqconn
, execParams
) {
1078 zend_error_handling zeh
;
1082 zval
*ztypes
= NULL
;
1083 ZEND_RESULT_CODE rv
;
1085 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1086 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!", &query_str
, &query_len
, &zparams
, &ztypes
);
1087 zend_restore_error_handling(&zeh
);
1089 if (SUCCESS
== rv
) {
1090 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1093 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1096 php_pq_params_t
*params
;
1098 params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, Z_ARRVAL_P(zparams
));
1099 res
= PQexecParams(obj
->intern
->conn
, query_str
, params
->param
.count
, params
->type
.oids
, (const char *const*) params
->param
.strings
, NULL
, NULL
, 0);
1100 php_pq_params_free(¶ms
);
1103 throw_exce(EX_RUNTIME
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1105 if (SUCCESS
== php_pqres_success(res
)) {
1106 php_pq_object_to_zval_no_addref(PQresultInstanceData(res
, php_pqconn_event
), return_value
);
1111 php_pqconn_notify_listeners(obj
);
1117 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async
, 0, 0, 2)
1118 ZEND_ARG_INFO(0, query
)
1119 ZEND_ARG_ARRAY_INFO(0, params
, 0)
1120 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1121 ZEND_ARG_INFO(0, callable
)
1122 ZEND_END_ARG_INFO();
1123 static PHP_METHOD(pqconn
, execParamsAsync
) {
1124 zend_error_handling zeh
;
1125 php_pq_callback_t resolver
= {{0}};
1129 zval
*ztypes
= NULL
;
1130 ZEND_RESULT_CODE rv
;
1132 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1133 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sa/|a/!f", &query_str
, &query_len
, &zparams
, &ztypes
, &resolver
.fci
, &resolver
.fcc
);
1134 zend_restore_error_handling(&zeh
);
1136 if (SUCCESS
== rv
) {
1137 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1140 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1143 php_pq_params_t
*params
;
1145 params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, Z_ARRVAL_P(zparams
));
1146 rc
= PQsendQueryParams(obj
->intern
->conn
, query_str
, params
->param
.count
, params
->type
.oids
, (const char *const*) params
->param
.strings
, NULL
, NULL
, 0);
1147 php_pq_params_free(¶ms
);
1150 throw_exce(EX_IO
, "Failed to execute query (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1151 #if HAVE_PQSETSINGLEROWMODE
1152 } else if (obj
->intern
->unbuffered
&& !PQsetSingleRowMode(obj
->intern
->conn
)) {
1153 throw_exce(EX_RUNTIME
, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1156 php_pq_callback_recurse(&obj
->intern
->onevent
, &resolver
);
1157 obj
->intern
->poller
= PQconsumeInput
;
1158 php_pqconn_notify_listeners(obj
);
1162 zend_restore_error_handling(&zeh
);
1165 ZEND_RESULT_CODE
php_pqconn_prepare(zval
*object
, php_pqconn_object_t
*obj
, const char *name
, const char *query
, php_pq_params_t
*params
)
1168 ZEND_RESULT_CODE rv
;
1171 obj
= PHP_PQ_OBJ(object
, NULL
);
1174 res
= PQprepare(obj
->intern
->conn
, name
, query
, params
->type
.count
, params
->type
.oids
);
1178 throw_exce(EX_RUNTIME
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1180 rv
= php_pqres_success(res
);
1182 php_pqconn_notify_listeners(obj
);
1188 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare
, 0, 0, 2)
1189 ZEND_ARG_INFO(0, name
)
1190 ZEND_ARG_INFO(0, query
)
1191 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1192 ZEND_END_ARG_INFO();
1193 static PHP_METHOD(pqconn
, prepare
) {
1194 zend_error_handling zeh
;
1195 zval
*ztypes
= NULL
;
1196 char *name_str
, *query_str
;
1197 size_t name_len
, *query_len
;
1198 ZEND_RESULT_CODE rv
;
1200 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1201 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
1202 zend_restore_error_handling(&zeh
);
1204 if (SUCCESS
== rv
) {
1205 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1208 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1210 php_pq_params_t
*params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, NULL
);
1212 if (SUCCESS
!= php_pqconn_prepare(getThis(), obj
, name_str
, query_str
, params
)) {
1213 php_pq_params_free(¶ms
);
1215 php_pqstm_t
*stm
= php_pqstm_init(obj
, name_str
, query_str
, params
);
1217 RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
)->zo
);
1223 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 TSRMLS_DC
)
1225 ZEND_RESULT_CODE rv
;
1228 obj
= PHP_PQ_OBJ(object
, NULL
);
1231 if (!PQsendPrepare(obj
->intern
->conn
, name
, query
, params
->type
.count
, params
->type
.oids
)) {
1233 throw_exce(EX_IO
, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1236 obj
->intern
->poller
= PQconsumeInput
;
1237 php_pqconn_notify_listeners(obj
);
1243 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async
, 0, 0, 2)
1244 ZEND_ARG_INFO(0, name
)
1245 ZEND_ARG_INFO(0, query
)
1246 ZEND_ARG_ARRAY_INFO(0, types
, 1)
1247 ZEND_END_ARG_INFO();
1248 static PHP_METHOD(pqconn
, prepareAsync
) {
1249 zend_error_handling zeh
;
1250 zval
*ztypes
= NULL
;
1251 char *name_str
, *query_str
;
1252 size_t name_len
, *query_len
;
1253 ZEND_RESULT_CODE rv
;
1255 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1256 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a/!", &name_str
, &name_len
, &query_str
, &query_len
, &ztypes
);
1257 zend_restore_error_handling(&zeh
);
1259 if (SUCCESS
== rv
) {
1260 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1263 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1265 php_pq_params_t
*params
= php_pq_params_init(&obj
->intern
->converters
, ztypes
? Z_ARRVAL_P(ztypes
) : NULL
, NULL
);
1267 if (SUCCESS
!= php_pqconn_prepare_async(getThis(), obj
, name_str
, query_str
, params
)) {
1268 php_pq_params_free(¶ms
);
1270 php_pqstm_t
*stm
= php_pqstm_init(obj
, name_str
, query_str
, params
);
1272 RETVAL_OBJ(&php_pqstm_create_object_ex(php_pqstm_class_entry
, stm
)->zo
);
1278 ZEND_RESULT_CODE
php_pqconn_declare(zval
*object
, php_pqconn_object_t
*obj
, const char *decl
)
1281 ZEND_RESULT_CODE rv
;
1284 obj
= PHP_PQ_OBJ(object
, NULL
);
1287 res
= PQexec(obj
->intern
->conn
, decl
);
1291 throw_exce(EX_RUNTIME
, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1293 rv
= php_pqres_success(res
);
1295 php_pqconn_notify_listeners(obj
);
1301 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare
, 0, 0, 3)
1302 ZEND_ARG_INFO(0, name
)
1303 ZEND_ARG_INFO(0, flags
)
1304 ZEND_ARG_INFO(0, query
)
1305 ZEND_END_ARG_INFO();
1306 static PHP_METHOD(pqconn
, declare
) {
1307 zend_error_handling zeh
;
1308 char *name_str
, *query_str
;
1309 size_t name_len
, query_len
;
1311 ZEND_RESULT_CODE rv
;
1313 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1314 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str
, &name_len
, &flags
, &query_str
, &query_len
);
1315 zend_restore_error_handling(&zeh
);
1317 if (SUCCESS
== rv
) {
1318 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1321 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1324 char *decl
= php_pqcur_declare_str(name_str
, name_len
, flags
, query_str
, query_len
, &query_offset
);
1326 if (SUCCESS
!= php_pqconn_declare(getThis(), obj
, decl
)) {
1329 php_pqcur_t
*cur
= php_pqcur_init(obj
, name_str
, decl
, query_offset
, flags
);
1331 RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry
, cur
)->zo
);
1337 ZEND_RESULT_CODE
php_pqconn_declare_async(zval
*object
, php_pqconn_object_t
*obj
, const char *decl
)
1339 ZEND_RESULT_CODE rv
;
1342 obj
= PHP_PQ_OBJ(object
, NULL
);
1345 if (!PQsendQuery(obj
->intern
->conn
, decl
)) {
1347 throw_exce(EX_IO
, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1350 obj
->intern
->poller
= PQconsumeInput
;
1351 php_pqconn_notify_listeners(obj
);
1357 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare_async
, 0, 0, 2)
1358 ZEND_ARG_INFO(0, name
)
1359 ZEND_ARG_INFO(0, flags
)
1360 ZEND_ARG_INFO(0, query
)
1361 ZEND_END_ARG_INFO();
1362 static PHP_METHOD(pqconn
, declareAsync
) {
1363 zend_error_handling zeh
;
1364 char *name_str
, *query_str
;
1365 size_t name_len
, query_len
;
1367 ZEND_RESULT_CODE rv
;
1369 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1370 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &name_str
, &name_len
, &flags
, &query_str
, &query_len
);
1371 zend_restore_error_handling(&zeh
);
1373 if (SUCCESS
== rv
) {
1374 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1377 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1380 char *decl
= php_pqcur_declare_str(name_str
, name_len
, flags
, query_str
, query_len
, &query_offset
);
1382 if (SUCCESS
!= php_pqconn_declare_async(getThis(), obj
, decl
)) {
1385 php_pqcur_t
*cur
= php_pqcur_init(obj
, name_str
, decl
, query_offset
, flags
);
1387 RETVAL_OBJ(&php_pqcur_create_object_ex(php_pqcur_class_entry
, cur
)->zo
);
1393 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote
, 0, 0, 1)
1394 ZEND_ARG_INFO(0, string
)
1395 ZEND_END_ARG_INFO();
1396 static PHP_METHOD(pqconn
, quote
) {
1400 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1401 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1404 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1406 char *quoted
= PQescapeLiteral(obj
->intern
->conn
, str
, len
);
1409 php_error_docref(NULL
, E_WARNING
, "Failed to quote string (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1412 RETVAL_STRING(quoted
);
1419 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name
, 0, 0, 1)
1420 ZEND_ARG_INFO(0, type
)
1421 ZEND_END_ARG_INFO();
1422 static PHP_METHOD(pqconn
, quoteName
) {
1426 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1427 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1430 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1432 char *quoted
= PQescapeIdentifier(obj
->intern
->conn
, str
, len
);
1435 php_error_docref(NULL
, E_WARNING
, "Failed to quote name (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1438 RETVAL_STRING(quoted
);
1445 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea
, 0, 0, 1)
1446 ZEND_ARG_INFO(0, bytea
)
1447 ZEND_END_ARG_INFO();
1448 static PHP_METHOD(pqconn
, escapeBytea
) {
1452 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1453 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1456 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1459 char *escaped_str
= (char *) PQescapeByteaConn(obj
->intern
->conn
, (unsigned char *) str
, len
, &escaped_len
);
1462 php_error_docref(NULL
, E_WARNING
, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1465 RETVAL_STRINGL(escaped_str
, escaped_len
- 1);
1466 PQfreemem(escaped_str
);
1472 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea
, 0, 0, 1)
1473 ZEND_ARG_INFO(0, bytea
)
1474 ZEND_END_ARG_INFO();
1475 static PHP_METHOD(pqconn
, unescapeBytea
) {
1479 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str
, &len
)) {
1480 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1483 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1485 size_t unescaped_len
;
1486 char *unescaped_str
= (char *) PQunescapeBytea((unsigned char *)str
, &unescaped_len
);
1488 if (!unescaped_str
) {
1489 php_error_docref(NULL
, E_WARNING
, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj
->intern
->conn
));
1492 RETVAL_STRINGL(unescaped_str
, unescaped_len
);
1493 PQfreemem(unescaped_str
);
1499 ZEND_RESULT_CODE
php_pqconn_start_transaction(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable
)
1501 ZEND_RESULT_CODE rv
= FAILURE
;
1504 conn_obj
= PHP_PQ_OBJ(zconn
, NULL
);
1507 if (!conn_obj
->intern
) {
1508 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1511 smart_str cmd
= {0};
1512 const char *il
= php_pq_isolation_level(&isolation
);
1514 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
1515 smart_str_appends(&cmd
, il
);
1516 smart_str_appends(&cmd
, ", READ ");
1517 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
1518 smart_str_appends(&cmd
, ",");
1519 smart_str_appends(&cmd
, deferrable
? "" : " NOT");
1520 smart_str_appends(&cmd
, " DEFERRABLE");
1523 res
= PQexec(conn_obj
->intern
->conn
, smart_str_v(&cmd
));
1526 throw_exce(EX_RUNTIME
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
1528 rv
= php_pqres_success(res
);
1530 php_pqconn_notify_listeners(conn_obj
);
1533 smart_str_free(&cmd
);
1539 ZEND_RESULT_CODE
php_pqconn_start_transaction_async(zval
*zconn
, php_pqconn_object_t
*conn_obj
, long isolation
, zend_bool readonly
, zend_bool deferrable
)
1541 ZEND_RESULT_CODE rv
= FAILURE
;
1544 conn_obj
= PHP_PQ_OBJ(zconn
, NULL
);
1547 if (!conn_obj
->intern
) {
1548 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1550 smart_str cmd
= {0};
1551 const char *il
= php_pq_isolation_level(&isolation
);
1553 smart_str_appends(&cmd
, "START TRANSACTION ISOLATION LEVEL ");
1554 smart_str_appends(&cmd
, il
);
1555 smart_str_appends(&cmd
, ", READ ");
1556 smart_str_appends(&cmd
, readonly
? "ONLY" : "WRITE");
1557 smart_str_appends(&cmd
, ",");
1558 smart_str_appends(&cmd
, deferrable
? "" : "NOT ");
1559 smart_str_appends(&cmd
, " DEFERRABLE");
1562 if (!PQsendQuery(conn_obj
->intern
->conn
, smart_str_v(&cmd
))) {
1563 throw_exce(EX_IO
, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj
->intern
->conn
));
1566 conn_obj
->intern
->poller
= PQconsumeInput
;
1567 php_pqconn_notify_listeners(conn_obj
);
1570 smart_str_free(&cmd
);
1576 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction
, 0, 0, 0)
1577 ZEND_ARG_INFO(0, isolation
)
1578 ZEND_ARG_INFO(0, readonly
)
1579 ZEND_ARG_INFO(0, deferrable
)
1580 ZEND_END_ARG_INFO();
1581 static PHP_METHOD(pqconn
, startTransaction
) {
1582 zend_error_handling zeh
;
1583 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1584 zend_long isolation
= obj
->intern
? obj
->intern
->default_txn_isolation
: PHP_PQTXN_READ_COMMITTED
;
1585 zend_bool readonly
= obj
->intern
? obj
->intern
->default_txn_readonly
: 0;
1586 zend_bool deferrable
= obj
->intern
? obj
->intern
->default_txn_deferrable
: 0;
1587 ZEND_RESULT_CODE rv
;
1589 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1590 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation
, &readonly
, &deferrable
);
1591 zend_restore_error_handling(&zeh
);
1593 if (SUCCESS
== rv
) {
1594 rv
= php_pqconn_start_transaction(getThis(), obj
, isolation
, readonly
, deferrable
);
1596 if (SUCCESS
== rv
) {
1597 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1599 php_pq_object_addref(obj
);
1602 txn
->isolation
= isolation
;
1603 txn
->readonly
= readonly
;
1604 txn
->deferrable
= deferrable
;
1606 RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
)->zo
);
1611 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async
, 0, 0, 0)
1612 ZEND_ARG_INFO(0, isolation
)
1613 ZEND_ARG_INFO(0, readonly
)
1614 ZEND_ARG_INFO(0, deferrable
)
1615 ZEND_END_ARG_INFO();
1616 static PHP_METHOD(pqconn
, startTransactionAsync
) {
1617 zend_error_handling zeh
;
1618 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1619 zend_long isolation
= obj
->intern
? obj
->intern
->default_txn_isolation
: PHP_PQTXN_READ_COMMITTED
;
1620 zend_bool readonly
= obj
->intern
? obj
->intern
->default_txn_readonly
: 0;
1621 zend_bool deferrable
= obj
->intern
? obj
->intern
->default_txn_deferrable
: 0;
1622 ZEND_RESULT_CODE rv
;
1624 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1625 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "|lbb", &isolation
, &readonly
, &deferrable
);
1626 zend_restore_error_handling(&zeh
);
1628 if (SUCCESS
== rv
) {
1629 rv
= php_pqconn_start_transaction_async(getThis(), obj
, isolation
, readonly
, deferrable
);
1631 if (SUCCESS
== rv
) {
1632 php_pqtxn_t
*txn
= ecalloc(1, sizeof(*txn
));
1634 php_pq_object_addref(obj
);
1637 txn
->isolation
= isolation
;
1638 txn
->readonly
= readonly
;
1639 txn
->deferrable
= deferrable
;
1641 RETVAL_OBJ(&php_pqtxn_create_object_ex(php_pqtxn_class_entry
, txn
)->zo
);
1646 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace
, 0, 0, 0)
1647 ZEND_ARG_INFO(0, stdio_stream
)
1648 ZEND_END_ARG_INFO();
1649 static PHP_METHOD(pqconn
, trace
) {
1650 zval
*zstream
= NULL
;
1652 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &zstream
)) {
1653 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1656 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1659 PQuntrace(obj
->intern
->conn
);
1663 php_stream
*stream
= NULL
;
1665 php_stream_from_zval(stream
, zstream
);
1667 if (SUCCESS
!= php_stream_cast(stream
, PHP_STREAM_AS_STDIO
, (void *) &fp
, REPORT_ERRORS
)) {
1670 stream
->flags
|= PHP_STREAM_FLAG_NO_CLOSE
;
1671 PQtrace(obj
->intern
->conn
, fp
);
1679 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_off
, 0, 0, 1)
1680 ZEND_ARG_INFO(0, type
)
1681 ZEND_END_ARG_INFO();
1682 static PHP_METHOD(pqconn
, off
) {
1683 zend_error_handling zeh
;
1685 ZEND_RESULT_CODE rv
;
1687 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1688 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "S", &type
);
1689 zend_restore_error_handling(&zeh
);
1691 if (SUCCESS
== rv
) {
1692 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1695 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1697 RETURN_BOOL(SUCCESS
== zend_hash_del(&obj
->intern
->eventhandlers
, type
));
1702 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on
, 0, 0, 2)
1703 ZEND_ARG_INFO(0, type
)
1704 ZEND_ARG_INFO(0, callable
)
1705 ZEND_END_ARG_INFO();
1706 static PHP_METHOD(pqconn
, on
) {
1707 zend_error_handling zeh
;
1710 php_pq_callback_t cb
= {{0}};
1711 ZEND_RESULT_CODE rv
;
1713 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1714 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &type_str
, &type_len
, &cb
.fci
, &cb
.fcc
);
1715 zend_restore_error_handling(&zeh
);
1717 if (SUCCESS
== rv
) {
1718 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1721 throw_exce(EX_UNINITIALIZED TSRMLS_CC
, "pq\\Connection not initialized");
1723 RETVAL_LONG(php_pqconn_add_eventhandler(obj
, type_str
, type_len
, &cb
));
1728 struct apply_set_converter_arg
{
1734 static int apply_set_converter(zval
*zoid
, void *a
)
1736 zend_long oid
= zval_get_long(zoid
);
1737 struct apply_set_converter_arg
*arg
= a
;
1740 Z_ADDREF_P(arg
->zconv
);
1741 zend_hash_index_update(arg
->ht
, oid
, arg
->zconv
);
1743 zend_hash_index_del(arg
->ht
, oid
);
1746 return ZEND_HASH_APPLY_KEEP
;
1749 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_set_converter
, 0, 0, 1)
1750 ZEND_ARG_OBJ_INFO(0, converter
, pq
\\Converter
, 0)
1751 ZEND_END_ARG_INFO();
1752 static PHP_METHOD(pqconn
, setConverter
) {
1753 ZEND_RESULT_CODE rv
;
1754 zend_error_handling zeh
;
1757 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1758 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv
, php_pqconv_class_entry
);
1759 zend_restore_error_handling(&zeh
);
1761 if (SUCCESS
== rv
) {
1762 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1765 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1768 struct apply_set_converter_arg arg
= {NULL
};
1771 zend_call_method_with_0_params(zcnv
, NULL
, NULL
, "converttypes", &zoids
);
1772 ZVAL_DUP(&tmp
, &zoids
);
1773 convert_to_array(&tmp
);
1775 arg
.ht
= &obj
->intern
->converters
;
1779 zend_hash_apply_with_argument(Z_ARRVAL(tmp
), apply_set_converter
, &arg
);
1781 zval_ptr_dtor(&tmp
);
1782 zval_ptr_dtor(&zoids
);
1787 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unset_converter
, 0, 0, 1)
1788 ZEND_ARG_OBJ_INFO(0, converter
, pq
\\Converter
, 0)
1789 ZEND_END_ARG_INFO();
1790 static PHP_METHOD(pqconn
, unsetConverter
) {
1791 ZEND_RESULT_CODE rv
;
1792 zend_error_handling zeh
;
1795 zend_replace_error_handling(EH_THROW
, exce(EX_INVALID_ARGUMENT
), &zeh
);
1796 rv
= zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcnv
, php_pqconv_class_entry
);
1797 zend_restore_error_handling(&zeh
);
1799 if (SUCCESS
== rv
) {
1800 php_pqconn_object_t
*obj
= PHP_PQ_OBJ(getThis(), NULL
);
1803 throw_exce(EX_UNINITIALIZED
, "pq\\Connection not initialized");
1806 struct apply_set_converter_arg arg
= {NULL
};
1809 zend_call_method_with_0_params(zcnv
, NULL
, NULL
, "converttypes", &zoids
);
1810 ZVAL_DUP(&tmp
, &zoids
);
1811 convert_to_array(&tmp
);
1813 arg
.ht
= &obj
->intern
->converters
;
1817 zend_hash_apply_with_argument(Z_ARRVAL(tmp
), apply_set_converter
, &arg
);
1819 zval_ptr_dtor(&tmp
);
1820 zval_ptr_dtor(&zoids
);
1825 static zend_function_entry php_pqconn_methods
[] = {
1826 PHP_ME(pqconn
, __construct
, ai_pqconn_construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
1827 PHP_ME(pqconn
, reset
, ai_pqconn_reset
, ZEND_ACC_PUBLIC
)
1828 PHP_ME(pqconn
, resetAsync
, ai_pqconn_reset_async
, ZEND_ACC_PUBLIC
)
1829 PHP_ME(pqconn
, poll
, ai_pqconn_poll
, ZEND_ACC_PUBLIC
)
1830 PHP_ME(pqconn
, exec
, ai_pqconn_exec
, ZEND_ACC_PUBLIC
)
1831 PHP_ME(pqconn
, execAsync
, ai_pqconn_exec_async
, ZEND_ACC_PUBLIC
)
1832 PHP_ME(pqconn
, execParams
, ai_pqconn_exec_params
, ZEND_ACC_PUBLIC
)
1833 PHP_ME(pqconn
, execParamsAsync
, ai_pqconn_exec_params_async
, ZEND_ACC_PUBLIC
)
1834 PHP_ME(pqconn
, prepare
, ai_pqconn_prepare
, ZEND_ACC_PUBLIC
)
1835 PHP_ME(pqconn
, prepareAsync
, ai_pqconn_prepare_async
, ZEND_ACC_PUBLIC
)
1836 PHP_ME(pqconn
, declare
, ai_pqconn_declare
, ZEND_ACC_PUBLIC
)
1837 PHP_ME(pqconn
, declareAsync
, ai_pqconn_declare_async
, ZEND_ACC_PUBLIC
)
1838 PHP_ME(pqconn
, unlisten
, ai_pqconn_unlisten
, ZEND_ACC_PUBLIC
)
1839 PHP_ME(pqconn
, unlistenAsync
, ai_pqconn_unlisten_async
, ZEND_ACC_PUBLIC
)
1840 PHP_ME(pqconn
, listen
, ai_pqconn_listen
, ZEND_ACC_PUBLIC
)
1841 PHP_ME(pqconn
, listenAsync
, ai_pqconn_listen_async
, ZEND_ACC_PUBLIC
)
1842 PHP_ME(pqconn
, notify
, ai_pqconn_notify
, ZEND_ACC_PUBLIC
)
1843 PHP_ME(pqconn
, notifyAsync
, ai_pqconn_notify_async
, ZEND_ACC_PUBLIC
)
1844 PHP_ME(pqconn
, getResult
, ai_pqconn_get_result
, ZEND_ACC_PUBLIC
)
1845 PHP_ME(pqconn
, quote
, ai_pqconn_quote
, ZEND_ACC_PUBLIC
)
1846 PHP_ME(pqconn
, quoteName
, ai_pqconn_quote_name
, ZEND_ACC_PUBLIC
)
1847 PHP_ME(pqconn
, escapeBytea
, ai_pqconn_escape_bytea
, ZEND_ACC_PUBLIC
)
1848 PHP_ME(pqconn
, unescapeBytea
, ai_pqconn_unescape_bytea
, ZEND_ACC_PUBLIC
)
1849 PHP_ME(pqconn
, startTransaction
, ai_pqconn_start_transaction
, ZEND_ACC_PUBLIC
)
1850 PHP_ME(pqconn
, startTransactionAsync
, ai_pqconn_start_transaction_async
, ZEND_ACC_PUBLIC
)
1851 PHP_ME(pqconn
, trace
, ai_pqconn_trace
, ZEND_ACC_PUBLIC
)
1852 PHP_ME(pqconn
, off
, ai_pqconn_off
, ZEND_ACC_PUBLIC
)
1853 PHP_ME(pqconn
, on
, ai_pqconn_on
, ZEND_ACC_PUBLIC
)
1854 PHP_ME(pqconn
, setConverter
, ai_pqconn_set_converter
, ZEND_ACC_PUBLIC
)
1855 PHP_ME(pqconn
, unsetConverter
, ai_pqconn_unset_converter
, ZEND_ACC_PUBLIC
)
1859 PHP_MSHUTDOWN_FUNCTION(pqconn
)
1861 php_persistent_handle_cleanup(PHP_PQ_G
->connection
.name
, NULL
);
1862 zend_string_release(PHP_PQ_G
->connection
.name
);
1863 zend_hash_destroy(&php_pqconn_object_prophandlers
);
1867 PHP_MINIT_FUNCTION(pqconn
)
1869 zend_class_entry ce
= {0};
1870 php_pq_object_prophandler_t ph
= {0};
1872 INIT_NS_CLASS_ENTRY(ce
, "pq", "Connection", php_pqconn_methods
);
1873 php_pqconn_class_entry
= zend_register_internal_class_ex(&ce
, NULL
);
1874 php_pqconn_class_entry
->create_object
= php_pqconn_create_object
;
1876 memcpy(&php_pqconn_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
1877 php_pqconn_object_handlers
.offset
= XtOffsetOf(php_pqconn_object_t
, zo
);
1878 php_pqconn_object_handlers
.free_obj
= php_pqconn_object_free
;
1879 php_pqconn_object_handlers
.read_property
= php_pq_object_read_prop
;
1880 php_pqconn_object_handlers
.write_property
= php_pq_object_write_prop
;
1881 php_pqconn_object_handlers
.clone_obj
= NULL
;
1882 php_pqconn_object_handlers
.get_property_ptr_ptr
= NULL
;
1883 php_pqconn_object_handlers
.get_gc
= NULL
;
1884 php_pqconn_object_handlers
.get_properties
= php_pq_object_properties
;
1885 php_pqconn_object_handlers
.get_debug_info
= php_pq_object_debug_info
;
1887 zend_hash_init(&php_pqconn_object_prophandlers
, 20, NULL
, NULL
, 1);
1889 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("status"), CONNECTION_BAD
, ZEND_ACC_PUBLIC
);
1890 ph
.read
= php_pqconn_object_read_status
;
1891 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "status", sizeof("status")-1, (void *) &ph
, sizeof(ph
));
1893 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN
, ZEND_ACC_PUBLIC
);
1894 ph
.read
= php_pqconn_object_read_transaction_status
;
1895 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "transactionStatus", sizeof("transactionStatus")-1, (void *) &ph
, sizeof(ph
));
1897 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("socket"), ZEND_ACC_PUBLIC
);
1898 ph
.read
= NULL
; /* forward to std prophandler */
1899 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "socket", sizeof("socket")-1, (void *) &ph
, sizeof(ph
));
1901 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC
);
1902 ph
.read
= php_pqconn_object_read_error_message
;
1903 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "errorMessage", sizeof("errorMessage")-1, (void *) &ph
, sizeof(ph
));
1905 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC
);
1906 ph
.read
= php_pqconn_object_read_busy
;
1907 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "busy", sizeof("busy")-1, (void *) &ph
, sizeof(ph
));
1909 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC
);
1910 ph
.read
= php_pqconn_object_read_encoding
;
1911 ph
.write
= php_pqconn_object_write_encoding
;
1912 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "encoding", sizeof("encoding")-1, (void *) &ph
, sizeof(ph
));
1915 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC
);
1916 ph
.read
= php_pqconn_object_read_unbuffered
;
1917 ph
.write
= php_pqconn_object_write_unbuffered
;
1918 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "unbuffered", sizeof("unbuffered")-1, (void *) &ph
, sizeof(ph
));
1921 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("db"), ZEND_ACC_PUBLIC
);
1922 ph
.read
= php_pqconn_object_read_db
;
1923 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "db", sizeof("db")-1, (void *) &ph
, sizeof(ph
));
1925 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("user"), ZEND_ACC_PUBLIC
);
1926 ph
.read
= php_pqconn_object_read_user
;
1927 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "user", sizeof("user")-1, (void *) &ph
, sizeof(ph
));
1929 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("pass"), ZEND_ACC_PUBLIC
);
1930 ph
.read
= php_pqconn_object_read_pass
;
1931 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "pass", sizeof("pass")-1, (void *) &ph
, sizeof(ph
));
1933 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("host"), ZEND_ACC_PUBLIC
);
1934 ph
.read
= php_pqconn_object_read_host
;
1935 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "host", sizeof("host")-1, (void *) &ph
, sizeof(ph
));
1937 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("port"), ZEND_ACC_PUBLIC
);
1938 ph
.read
= php_pqconn_object_read_port
;
1939 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "port", sizeof("port")-1, (void *) &ph
, sizeof(ph
));
1942 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("params"), ZEND_ACC_PUBLIC
);
1943 ph
.read
= php_pqconn_object_read_params
;
1944 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "params", sizeof("params")-1, (void *) &ph
, sizeof(ph
));
1947 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("options"), ZEND_ACC_PUBLIC
);
1948 ph
.read
= php_pqconn_object_read_options
;
1949 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "options", sizeof("options")-1, (void *) &ph
, sizeof(ph
));
1951 zend_declare_property_null(php_pqconn_class_entry
, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC
);
1952 ph
.read
= php_pqconn_object_read_event_handlers
;
1953 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "eventHandlers", sizeof("eventHandlers")-1, (void *) &ph
, sizeof(ph
));
1955 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC
);
1956 ph
.read
= php_pqconn_object_read_def_fetch_type
;
1957 ph
.write
= php_pqconn_object_write_def_fetch_type
;
1958 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultFetchType", sizeof("defaultFetchType")-1, (void *) &ph
, sizeof(ph
));
1961 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC
);
1962 ph
.read
= php_pqconn_object_read_def_txn_isolation
;
1963 ph
.write
= php_pqconn_object_write_def_txn_isolation
;
1964 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation")-1, (void *) &ph
, sizeof(ph
));
1967 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC
);
1968 ph
.read
= php_pqconn_object_read_def_txn_readonly
;
1969 ph
.write
= php_pqconn_object_write_def_txn_readonly
;
1970 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly")-1, (void *) &ph
, sizeof(ph
));
1973 zend_declare_property_bool(php_pqconn_class_entry
, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC
);
1974 ph
.read
= php_pqconn_object_read_def_txn_deferrable
;
1975 ph
.write
= php_pqconn_object_write_def_txn_deferrable
;
1976 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable")-1, (void *) &ph
, sizeof(ph
));
1979 zend_declare_property_long(php_pqconn_class_entry
, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL
, ZEND_ACC_PUBLIC
);
1980 ph
.read
= php_pqconn_object_read_def_auto_conv
;
1981 ph
.write
= php_pqconn_object_write_def_auto_conv
;
1982 zend_hash_str_add_mem(&php_pqconn_object_prophandlers
, "defaultAutoConvert", sizeof("defaultAutoConvert")-1, (void *) &ph
, sizeof(ph
));
1985 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("OK"), CONNECTION_OK
);
1986 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("BAD"), CONNECTION_BAD
);
1987 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("STARTED"), CONNECTION_STARTED
);
1988 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("MADE"), CONNECTION_MADE
);
1989 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE
);
1990 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK
);
1991 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP
);
1992 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("SETENV"), CONNECTION_SETENV
);
1994 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE
);
1995 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE
);
1996 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS
);
1997 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR
);
1998 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN
);
2000 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED
);
2001 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING
);
2002 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING
);
2003 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK
);
2005 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice"));
2006 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result"));
2007 zend_declare_class_constant_stringl(php_pqconn_class_entry
, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset"));
2009 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("ASYNC"), 0x1);
2010 zend_declare_class_constant_long(php_pqconn_class_entry
, ZEND_STRL("PERSISTENT"), 0x2);
2012 PHP_PQ_G
->connection
.name
= zend_string_init(ZEND_STRL("pq\\Connection"), 1);
2014 return php_persistent_handle_provide(PHP_PQ_G
->connection
.name
, php_pqconn_get_resource_factory_ops(), NULL
, NULL
);
2022 * vim600: noet sw=4 ts=4 fdm=marker
2023 * vim<600: noet sw=4 ts=4