4378404eb98ba3a9fcd6d8788f672473ff5bc7ba
[m6w6/ext-pq] / src / php_pqconn.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: pq |
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 +--------------------------------------------------------------------+
11 */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include <php.h>
18
19 #define SMART_STR_PREALLOC 256
20 #include <ext/standard/php_smart_str.h>
21
22 #include <libpq-events.h>
23 #include <fnmatch.h>
24
25 #include "php_pq.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"
35
36 zend_class_entry *php_pqconn_class_entry;
37 static zend_object_handlers php_pqconn_object_handlers;
38 static HashTable php_pqconn_object_prophandlers;
39
40 /*
41 static void php_pqconn_del_eventhandler(php_pqconn_object_t *obj, const char *type_str, size_t type_len, ulong id TSRMLS_DC)
42 {
43 zval **evhs;
44
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);
47 }
48 }
49 */
50
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)
52 {
53 ulong h;
54 HashTable *evhs;
55
56 if (SUCCESS != zend_hash_find(&obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
57 HashTable evh;
58
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);
61 }
62
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);
66
67 return h;
68 }
69
70 static void php_pqconn_object_free(void *o TSRMLS_DC)
71 {
72 php_pqconn_object_t *obj = o;
73 #if DBG_GC
74 fprintf(stderr, "FREE conn(#%d) %p\n", obj->zv.handle, obj);
75 #endif
76 if (obj->intern) {
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);
83 efree(obj->intern);
84 obj->intern = NULL;
85 }
86 zend_object_std_dtor((zend_object *) o TSRMLS_CC);
87 efree(obj);
88 }
89
90
91 zend_object_value php_pqconn_create_object_ex(zend_class_entry *ce, php_pqconn_t *intern, php_pqconn_object_t **ptr TSRMLS_DC)
92 {
93 php_pqconn_object_t *o;
94
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;
99
100 if (ptr) {
101 *ptr = o;
102 }
103
104 if (intern) {
105 o->intern = intern;
106 }
107
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;
110
111 return o->zv;
112 }
113
114 static zend_object_value php_pqconn_create_object(zend_class_entry *class_type TSRMLS_DC)
115 {
116 return php_pqconn_create_object_ex(class_type, NULL, NULL TSRMLS_CC);
117 }
118
119 static void php_pqconn_object_read_status(zval *object, void *o, zval *return_value TSRMLS_DC)
120 {
121 php_pqconn_object_t *obj = o;
122
123 RETVAL_LONG(PQstatus(obj->intern->conn));
124 }
125
126 static void php_pqconn_object_read_transaction_status(zval *object, void *o, zval *return_value TSRMLS_DC)
127 {
128 php_pqconn_object_t *obj = o;
129
130 RETVAL_LONG(PQtransactionStatus(obj->intern->conn));
131 }
132
133 static void php_pqconn_object_read_error_message(zval *object, void *o, zval *return_value TSRMLS_DC)
134 {
135 php_pqconn_object_t *obj = o;
136 char *error = PHP_PQerrorMessage(obj->intern->conn);
137
138 if (error) {
139 RETVAL_STRING(error, 1);
140 } else {
141 RETVAL_NULL();
142 }
143 }
144
145 static int apply_notify_listener(void *p, void *arg TSRMLS_DC)
146 {
147 php_pq_callback_t *listener = p;
148 PGnotify *nfy = arg;
149 zval *zpid, *zchannel, *zmessage;
150
151 MAKE_STD_ZVAL(zpid);
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);
157
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);
160
161 zval_ptr_dtor(&zchannel);
162 zval_ptr_dtor(&zmessage);
163 zval_ptr_dtor(&zpid);
164
165 return ZEND_HASH_APPLY_KEEP;
166 }
167
168 static int apply_notify_listeners(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
169 {
170 HashTable *listeners = p;
171 PGnotify *nfy = va_arg(argv, PGnotify *);
172
173 if (0 == fnmatch(key->arKey, nfy->relname, 0)) {
174 zend_hash_apply_with_argument(listeners, apply_notify_listener, nfy TSRMLS_CC);
175 }
176
177 return ZEND_HASH_APPLY_KEEP;
178 }
179
180 void php_pqconn_notify_listeners(php_pqconn_object_t *obj TSRMLS_DC)
181 {
182 PGnotify *nfy;
183
184 while ((nfy = PQnotifies(obj->intern->conn))) {
185 zend_hash_apply_with_arguments(&obj->intern->listeners TSRMLS_CC, apply_notify_listeners, 1, nfy);
186 PQfreemem(nfy);
187 }
188 }
189
190 static void php_pqconn_object_read_busy(zval *object, void *o, zval *return_value TSRMLS_DC)
191 {
192 php_pqconn_object_t *obj = o;
193
194 RETVAL_BOOL(PQisBusy(obj->intern->conn));
195 }
196
197 static void php_pqconn_object_read_encoding(zval *object, void *o, zval *return_value TSRMLS_DC)
198 {
199 php_pqconn_object_t *obj = o;
200
201 RETVAL_STRING(pg_encoding_to_char(PQclientEncoding(obj->intern->conn)), 1);
202 }
203
204 static void php_pqconn_object_write_encoding(zval *object, void *o, zval *value TSRMLS_DC)
205 {
206 php_pqconn_object_t *obj = o;
207 zval *zenc = value;
208
209 if (Z_TYPE_P(value) != IS_STRING) {
210 if (Z_REFCOUNT_P(value) > 1) {
211 zval *tmp;
212 MAKE_STD_ZVAL(tmp);
213 ZVAL_ZVAL(tmp, zenc, 1, 0);
214 convert_to_string(tmp);
215 zenc = tmp;
216 } else {
217 convert_to_string_ex(&zenc);
218 }
219 }
220
221 if (0 > PQsetClientEncoding(obj->intern->conn, Z_STRVAL_P(zenc))) {
222 zend_error(E_NOTICE, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc));
223 }
224
225 if (zenc != value) {
226 zval_ptr_dtor(&zenc);
227 }
228 }
229
230 static void php_pqconn_object_read_unbuffered(zval *object, void *o, zval *return_value TSRMLS_DC)
231 {
232 php_pqconn_object_t *obj = o;
233
234 RETVAL_BOOL(obj->intern->unbuffered);
235 }
236
237 static void php_pqconn_object_write_unbuffered(zval *object, void *o, zval *value TSRMLS_DC)
238 {
239 php_pqconn_object_t *obj = o;
240
241 obj->intern->unbuffered = z_is_true(value);
242 }
243
244 static void php_pqconn_object_read_db(zval *object, void *o, zval *return_value TSRMLS_DC)
245 {
246 php_pqconn_object_t *obj = o;
247 char *db = PQdb(obj->intern->conn);
248
249 if (db) {
250 RETVAL_STRING(db, 1);
251 } else {
252 RETVAL_EMPTY_STRING();
253 }
254 }
255
256 static void php_pqconn_object_read_user(zval *object, void *o, zval *return_value TSRMLS_DC)
257 {
258 php_pqconn_object_t *obj = o;
259 char *user = PQuser(obj->intern->conn);
260
261 if (user) {
262 RETVAL_STRING(user, 1);
263 } else {
264 RETVAL_EMPTY_STRING();
265 }
266 }
267
268 static void php_pqconn_object_read_pass(zval *object, void *o, zval *return_value TSRMLS_DC)
269 {
270 php_pqconn_object_t *obj = o;
271 char *pass = PQpass(obj->intern->conn);
272
273 if (pass) {
274 RETVAL_STRING(pass, 1);
275 } else {
276 RETVAL_EMPTY_STRING();
277 }
278 }
279
280 static void php_pqconn_object_read_host(zval *object, void *o, zval *return_value TSRMLS_DC)
281 {
282 php_pqconn_object_t *obj = o;
283 char *host = PQhost(obj->intern->conn);
284
285 if (host) {
286 RETVAL_STRING(host, 1);
287 } else {
288 RETVAL_EMPTY_STRING();
289 }
290 }
291
292 static void php_pqconn_object_read_port(zval *object, void *o, zval *return_value TSRMLS_DC)
293 {
294 php_pqconn_object_t *obj = o;
295 char *port = PQport(obj->intern->conn);
296
297 if (port) {
298 RETVAL_STRING(port, 1);
299 } else {
300 RETVAL_EMPTY_STRING();
301 }
302 }
303
304 static void php_pqconn_object_read_options(zval *object, void *o, zval *return_value TSRMLS_DC)
305 {
306 php_pqconn_object_t *obj = o;
307 char *options = PQoptions(obj->intern->conn);
308
309 if (options) {
310 RETVAL_STRING(options, 1);
311 } else {
312 RETVAL_EMPTY_STRING();
313 }
314 }
315
316 static int apply_read_event_handler_ex(void *p, void *arg TSRMLS_DC)
317 {
318 HashTable *rv = arg;
319 zval *zcb = php_pq_callback_to_zval(p);
320
321 zend_hash_next_index_insert(rv, &zcb, sizeof(zval *), NULL);
322
323 return ZEND_HASH_APPLY_KEEP;
324 }
325
326 static int apply_read_event_handlers(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
327 {
328 HashTable *evhs = p, *rv = va_arg(argv, HashTable *);
329 zval *entry, **entry_ptr;
330
331 MAKE_STD_ZVAL(entry);
332 array_init_size(entry, zend_hash_num_elements(evhs));
333
334 if (key->nKeyLength) {
335 zend_hash_add(rv, key->arKey, key->nKeyLength, &entry, sizeof(zval *), (void *) &entry_ptr);
336 } else {
337 zend_hash_index_update(rv, key->h, &entry, sizeof(zval *), (void *) &entry_ptr);
338 }
339
340 zend_hash_apply_with_argument(evhs, apply_read_event_handler_ex, Z_ARRVAL_PP(entry_ptr) TSRMLS_CC);
341
342 return ZEND_HASH_APPLY_KEEP;
343 }
344 static void php_pqconn_object_read_event_handlers(zval *object, void *o, zval *return_value TSRMLS_DC)
345 {
346 php_pqconn_object_t *obj = o;
347
348 array_init(return_value);
349 zend_hash_apply_with_arguments(&obj->intern->eventhandlers TSRMLS_CC, apply_read_event_handlers, 1, Z_ARRVAL_P(return_value) TSRMLS_CC);
350 }
351
352 static void php_pqconn_object_read_def_fetch_type(zval *object, void *o, zval *return_value TSRMLS_DC)
353 {
354 php_pqconn_object_t *obj = o;
355
356 RETVAL_LONG(obj->intern->default_fetch_type);
357 }
358 static void php_pqconn_object_write_def_fetch_type(zval *object, void *o, zval *value TSRMLS_DC)
359 {
360 php_pqconn_object_t *obj = o;
361 zval *zft = value;
362
363 if (Z_TYPE_P(zft) != IS_LONG) {
364 if (Z_REFCOUNT_P(zft) > 1) {
365 zval *tmp;
366 MAKE_STD_ZVAL(tmp);
367 ZVAL_ZVAL(tmp, zft, 1, 0);
368 convert_to_long(tmp);
369 zft = tmp;
370 } else {
371 convert_to_long_ex(&zft);
372 }
373 }
374
375 obj->intern->default_fetch_type = Z_LVAL_P(zft) & 0x2; /* two bits only */
376
377 if (zft != value) {
378 zval_ptr_dtor(&zft);
379 }
380 }
381
382 static void php_pqconn_object_read_def_txn_isolation(zval *object, void *o, zval *return_value TSRMLS_DC)
383 {
384 php_pqconn_object_t *obj = o;
385
386 RETVAL_LONG(obj->intern->default_txn_isolation);
387 }
388 static void php_pqconn_object_write_def_txn_isolation(zval *object, void *o, zval *value TSRMLS_DC)
389 {
390 php_pqconn_object_t *obj = o;
391 zval *zti = value;
392
393 if (Z_TYPE_P(zti) != IS_LONG) {
394 if (Z_REFCOUNT_P(zti) > 1) {
395 zval *tmp;
396 MAKE_STD_ZVAL(tmp);
397 ZVAL_ZVAL(tmp, zti, 1, 0);
398 convert_to_long(tmp);
399 zti = tmp;
400 } else {
401 convert_to_long_ex(&zti);
402 }
403 }
404
405 obj->intern->default_txn_isolation = Z_LVAL_P(zti) & 0x2; /* two bits only */
406
407 if (zti != value) {
408 zval_ptr_dtor(&zti);
409 }
410 }
411
412 static void php_pqconn_object_read_def_txn_readonly(zval *object, void *o, zval *return_value TSRMLS_DC)
413 {
414 php_pqconn_object_t *obj = o;
415
416 RETVAL_BOOL(obj->intern->default_txn_readonly);
417 }
418 static void php_pqconn_object_write_def_txn_readonly(zval *object, void *o, zval *value TSRMLS_DC)
419 {
420 php_pqconn_object_t *obj = o;
421
422 obj->intern->default_txn_readonly = zend_is_true(value);
423 }
424
425 static void php_pqconn_object_read_def_txn_deferrable(zval *object, void *o, zval *return_value TSRMLS_DC)
426 {
427 php_pqconn_object_t *obj = o;
428
429 RETVAL_BOOL(obj->intern->default_txn_deferrable);
430 }
431 static void php_pqconn_object_write_def_txn_deferrable(zval *object, void *o, zval *value TSRMLS_DC)
432 {
433 php_pqconn_object_t *obj = o;
434
435 obj->intern->default_txn_deferrable = zend_is_true(value);
436 }
437
438 static STATUS php_pqconn_update_socket(zval *this_ptr, php_pqconn_object_t *obj TSRMLS_DC)
439 {
440 zval *zsocket, zmember;
441 php_stream *stream;
442 STATUS retval;
443 int socket;
444
445 if (!obj) {
446 obj = zend_object_store_get_object(getThis() TSRMLS_CC);
447 }
448
449 INIT_PZVAL(&zmember);
450 ZVAL_STRINGL(&zmember, "socket", sizeof("socket")-1, 0);
451 MAKE_STD_ZVAL(zsocket);
452
453 if ((CONNECTION_BAD != PQstatus(obj->intern->conn))
454 && (-1 < (socket = PQsocket(obj->intern->conn)))
455 && (stream = php_stream_fopen_from_fd(socket, "r+b", NULL))) {
456 stream->flags |= PHP_STREAM_FLAG_NO_CLOSE;
457 php_stream_to_zval(stream, zsocket);
458 retval = SUCCESS;
459 } else {
460 ZVAL_NULL(zsocket);
461 retval = FAILURE;
462 }
463 zend_get_std_object_handlers()->write_property(getThis(), &zmember, zsocket, NULL TSRMLS_CC);
464 zval_ptr_dtor(&zsocket);
465
466 return retval;
467 }
468
469 static void *php_pqconn_resource_factory_ctor(void *data, void *init_arg TSRMLS_DC)
470 {
471 php_pqconn_resource_factory_data_t *o = init_arg;
472 PGconn *conn = NULL;;
473
474 if (o->flags & PHP_PQCONN_ASYNC) {
475 conn = PQconnectStart(o->dsn);
476 } else {
477 conn = PQconnectdb(o->dsn);
478 }
479
480 if (conn) {
481 PQregisterEventProc(conn, php_pqconn_event, "ext-pq", NULL);
482 }
483
484 return conn;
485 }
486
487 static void php_pqconn_resource_factory_dtor(void *opaque, void *handle TSRMLS_DC)
488 {
489 php_pqconn_event_data_t *evdata = PQinstanceData(handle, php_pqconn_event);
490
491 /* we don't care for anything, except free'ing evdata */
492 if (evdata) {
493 PQsetInstanceData(handle, php_pqconn_event, NULL);
494 memset(evdata, 0, sizeof(*evdata));
495 efree(evdata);
496 }
497
498 PQfinish(handle);
499 }
500
501 static php_resource_factory_ops_t php_pqconn_resource_factory_ops = {
502 php_pqconn_resource_factory_ctor,
503 NULL,
504 php_pqconn_resource_factory_dtor
505 };
506
507 php_resource_factory_ops_t *php_pqconn_get_resource_factory_ops(void)
508 {
509 return &php_pqconn_resource_factory_ops;
510 }
511
512 static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle TSRMLS_DC)
513 {
514 // FIXME: ping server
515 }
516
517 static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t channel_len TSRMLS_DC)
518 {
519 char *quoted_channel = PQescapeIdentifier(conn, channel_str, channel_len);
520 PGresult *res = NULL;
521
522 if (quoted_channel) {
523 smart_str cmd = {0};
524
525 smart_str_appends(&cmd, "UNLISTEN ");
526 smart_str_appends(&cmd, quoted_channel);
527 smart_str_0(&cmd);
528
529 res = PQexec(conn, cmd.c);
530
531 smart_str_free(&cmd);
532 PQfreemem(quoted_channel);
533 }
534
535 return res;
536 }
537
538 static int apply_unlisten(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
539 {
540 php_pqconn_object_t *obj = va_arg(argv, php_pqconn_object_t *);
541 PGresult *res = unlisten(obj->intern->conn, key->arKey, key->nKeyLength - 1);
542
543 if (res) {
544 PHP_PQclear(res);
545 }
546
547 return ZEND_HASH_APPLY_REMOVE;
548 }
549
550 static void php_pqconn_retire(php_persistent_handle_factory_t *f, void **handle TSRMLS_DC)
551 {
552 php_pqconn_event_data_t *evdata = PQinstanceData(*handle, php_pqconn_event);
553 PGcancel *cancel;
554 PGresult *res;
555
556 /* go away */
557 PQsetInstanceData(*handle, php_pqconn_event, NULL);
558
559 /* ignore notices */
560 PQsetNoticeReceiver(*handle, php_pqconn_notice_ignore, NULL);
561
562 /* cancel async queries */
563 if (PQisBusy(*handle) && (cancel = PQgetCancel(*handle))) {
564 char err[256] = {0};
565
566 PQcancel(cancel, err, sizeof(err));
567 PQfreeCancel(cancel);
568 }
569 /* clean up async results */
570 while ((res = PQgetResult(*handle))) {
571 PHP_PQclear(res);
572 }
573
574 /* clean up transaction & session */
575 switch (PQtransactionStatus(*handle)) {
576 case PQTRANS_IDLE:
577 res = PQexec(*handle, "RESET ALL");
578 break;
579 default:
580 res = PQexec(*handle, "ROLLBACK; RESET ALL");
581 break;
582 }
583
584 if (res) {
585 PHP_PQclear(res);
586 }
587
588 if (evdata) {
589 /* clean up notify listeners */
590 zend_hash_apply_with_arguments(&evdata->obj->intern->listeners TSRMLS_CC, apply_unlisten, 1, evdata->obj);
591
592 /* release instance data */
593 //memset(evdata, 0, sizeof(*evdata));
594 efree(evdata);
595 }
596 }
597
598 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct, 0, 0, 1)
599 ZEND_ARG_INFO(0, dsn)
600 ZEND_ARG_INFO(0, async)
601 ZEND_END_ARG_INFO();
602 static PHP_METHOD(pqconn, __construct) {
603 zend_error_handling zeh;
604 char *dsn_str = "";
605 int dsn_len = 0;
606 long flags = 0;
607 STATUS rv;
608
609 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
610 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &dsn_str, &dsn_len, &flags);
611 zend_restore_error_handling(&zeh TSRMLS_CC);
612
613 if (SUCCESS == rv) {
614 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
615
616 if (obj->intern) {
617 throw_exce(EX_BAD_METHODCALL TSRMLS_CC, "pq\\Connection already initialized");
618 } else {
619 php_pqconn_event_data_t *evdata = php_pqconn_event_data_init(obj TSRMLS_CC);
620 php_pqconn_resource_factory_data_t rfdata = {dsn_str, flags};
621
622 obj->intern = ecalloc(1, sizeof(*obj->intern));
623
624 zend_hash_init(&obj->intern->listeners, 0, NULL, (dtor_func_t) zend_hash_destroy, 0);
625 zend_hash_init(&obj->intern->converters, 0, NULL, ZVAL_PTR_DTOR, 0);
626 zend_hash_init(&obj->intern->eventhandlers, 0, NULL, (dtor_func_t) zend_hash_destroy, 0);
627
628 if (flags & PHP_PQCONN_PERSISTENT) {
629 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);
630 php_resource_factory_init(&obj->intern->factory, php_persistent_handle_get_resource_factory_ops(), phf, (void (*)(void*)) php_persistent_handle_abandon);
631 } else {
632 php_resource_factory_init(&obj->intern->factory, &php_pqconn_resource_factory_ops, NULL, NULL);
633 }
634
635 if (flags & PHP_PQCONN_ASYNC) {
636 obj->intern->poller = (int (*)(PGconn*)) PQconnectPoll;
637 }
638
639 obj->intern->conn = php_resource_factory_handle_ctor(&obj->intern->factory, &rfdata TSRMLS_CC);
640
641 PQsetInstanceData(obj->intern->conn, php_pqconn_event, evdata);
642 PQsetNoticeReceiver(obj->intern->conn, php_pqconn_notice_recv, evdata);
643
644 if (SUCCESS != php_pqconn_update_socket(getThis(), obj TSRMLS_CC)) {
645 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC, "Connection failed (%s)", PHP_PQerrorMessage(obj->intern->conn));
646 }
647 }
648 }
649 }
650
651 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset, 0, 0, 0)
652 ZEND_END_ARG_INFO();
653 static PHP_METHOD(pqconn, reset) {
654 zend_error_handling zeh;
655 STATUS rv;
656
657 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
658 rv = zend_parse_parameters_none();
659 zend_restore_error_handling(&zeh TSRMLS_CC);
660
661 if (SUCCESS == rv) {
662 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
663
664 if (!obj->intern) {
665 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
666 } else {
667 PQreset(obj->intern->conn);
668
669 if (CONNECTION_OK != PQstatus(obj->intern->conn)) {
670 throw_exce(EX_CONNECTION_FAILED TSRMLS_CC, "Connection reset failed: (%s)", PHP_PQerrorMessage(obj->intern->conn));
671 }
672
673 php_pqconn_notify_listeners(obj TSRMLS_CC);
674 }
675 }
676 }
677
678 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset_async, 0, 0, 0)
679 ZEND_END_ARG_INFO();
680 static PHP_METHOD(pqconn, resetAsync) {
681 zend_error_handling zeh;
682 STATUS rv;
683
684 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
685 rv = zend_parse_parameters_none();
686 zend_restore_error_handling(&zeh TSRMLS_CC);
687
688 if (SUCCESS == rv) {
689 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
690
691 if (!obj->intern) {
692 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
693 } else {
694 if (!PQresetStart(obj->intern->conn)) {
695 throw_exce(EX_IO TSRMLS_CC, "Failed to start connection reset (%s)", PHP_PQerrorMessage(obj->intern->conn));
696 } else {
697 obj->intern->poller = (int (*)(PGconn*)) PQresetPoll;
698 }
699
700 php_pqconn_notify_listeners(obj TSRMLS_CC);
701 }
702 }
703 }
704
705 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten, 0, 0, 1)
706 ZEND_ARG_INFO(0, channel)
707 ZEND_END_ARG_INFO();
708 static PHP_METHOD(pqconn, unlisten)
709 {
710 zend_error_handling zeh;
711 char *channel_str;
712 int channel_len;
713 STATUS rv;
714
715 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
716 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &channel_str, &channel_len);
717 zend_restore_error_handling(&zeh TSRMLS_CC);
718
719 if (SUCCESS == rv) {
720 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
721
722 if (!obj->intern) {
723 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
724 } else if (SUCCESS == zend_hash_del(&obj->intern->listeners, channel_str, channel_len + 1)) {
725 PGresult *res = unlisten(obj->intern->conn, channel_str, channel_len);
726
727 if (res) {
728 php_pqres_success(res TSRMLS_CC);
729 PHP_PQclear(res);
730 }
731 }
732 }
733 }
734
735 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unlisten_async, 0, 0, 1)
736 ZEND_ARG_INFO(0, channel)
737 ZEND_END_ARG_INFO();
738 static PHP_METHOD(pqconn, unlistenAsync) {
739 zend_error_handling zeh;
740 char *channel_str;
741 int channel_len;
742 STATUS rv;
743
744 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
745 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &channel_str, &channel_len);
746 zend_restore_error_handling(&zeh TSRMLS_CC);
747
748 if (SUCCESS == rv) {
749 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
750
751 if (!obj->intern) {
752 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
753 } else {
754 char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len);
755
756 if (!quoted_channel) {
757 throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
758 } else {
759 smart_str cmd = {0};
760
761 smart_str_appends(&cmd, "UNLISTEN ");
762 smart_str_appends(&cmd, quoted_channel);
763 smart_str_0(&cmd);
764
765 if (!PQsendQuery(obj->intern->conn, cmd.c)) {
766 throw_exce(EX_IO TSRMLS_CC, "Failed to uninstall listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
767 } else {
768 obj->intern->poller = PQconsumeInput;
769 zend_hash_del(&obj->intern->listeners, channel_str, channel_len + 1);
770 }
771
772 smart_str_free(&cmd);
773 PQfreemem(quoted_channel);
774 php_pqconn_notify_listeners(obj TSRMLS_CC);
775 }
776 }
777 }
778 }
779
780 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)
781 {
782 HashTable ht, *existing_listeners;
783
784 php_pq_callback_addref(listener);
785
786 if (SUCCESS == zend_hash_find(&obj->intern->listeners, channel_str, channel_len + 1, (void *) &existing_listeners)) {
787 zend_hash_next_index_insert(existing_listeners, (void *) listener, sizeof(*listener), NULL);
788 } else {
789 zend_hash_init(&ht, 1, NULL, (dtor_func_t) php_pq_callback_dtor, 0);
790 zend_hash_next_index_insert(&ht, (void *) listener, sizeof(*listener), NULL);
791 zend_hash_add(&obj->intern->listeners, channel_str, channel_len + 1, (void *) &ht, sizeof(HashTable), NULL);
792 }
793 }
794
795 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen, 0, 0, 2)
796 ZEND_ARG_INFO(0, channel)
797 ZEND_ARG_INFO(0, callable)
798 ZEND_END_ARG_INFO();
799 static PHP_METHOD(pqconn, listen) {
800 zend_error_handling zeh;
801 char *channel_str = NULL;
802 int channel_len = 0;
803 php_pq_callback_t listener = {{0}};
804 STATUS rv;
805
806 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
807 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc);
808 zend_restore_error_handling(&zeh TSRMLS_CC);
809
810 if (SUCCESS == rv) {
811 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
812
813 if (!obj->intern) {
814 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
815 } else {
816 char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len);
817
818 if (!quoted_channel) {
819 throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
820 } else {
821 PGresult *res;
822 smart_str cmd = {0};
823
824 smart_str_appends(&cmd, "LISTEN ");
825 smart_str_appends(&cmd, quoted_channel);
826 smart_str_0(&cmd);
827
828 res = PQexec(obj->intern->conn, cmd.c);
829
830 smart_str_free(&cmd);
831 PQfreemem(quoted_channel);
832
833 if (!res) {
834 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
835 } else {
836 if (SUCCESS == php_pqres_success(res TSRMLS_CC)) {
837 obj->intern->poller = PQconsumeInput;
838 php_pqconn_add_listener(obj, channel_str, channel_len, &listener TSRMLS_CC);
839 }
840 PHP_PQclear(res);
841 }
842
843 php_pqconn_notify_listeners(obj TSRMLS_CC);
844 }
845 }
846 }
847 }
848
849 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_listen_async, 0, 0, 0)
850 ZEND_ARG_INFO(0, channel)
851 ZEND_ARG_INFO(0, callable)
852 ZEND_END_ARG_INFO();
853 static PHP_METHOD(pqconn, listenAsync) {
854 zend_error_handling zeh;
855 char *channel_str = NULL;
856 int channel_len = 0;
857 php_pq_callback_t listener = {{0}};
858 STATUS rv;
859
860 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
861 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sf", &channel_str, &channel_len, &listener.fci, &listener.fcc);
862 zend_restore_error_handling(&zeh TSRMLS_CC);
863
864 if (SUCCESS == rv) {
865 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
866
867 if (!obj->intern) {
868 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
869 } else {
870 char *quoted_channel = PQescapeIdentifier(obj->intern->conn, channel_str, channel_len);
871
872 if (!quoted_channel) {
873 throw_exce(EX_ESCAPE TSRMLS_CC, "Failed to escape channel identifier (%s)", PHP_PQerrorMessage(obj->intern->conn));
874 } else {
875 smart_str cmd = {0};
876
877 smart_str_appends(&cmd, "LISTEN ");
878 smart_str_appends(&cmd, quoted_channel);
879 smart_str_0(&cmd);
880
881 if (!PQsendQuery(obj->intern->conn, cmd.c)) {
882 throw_exce(EX_IO TSRMLS_CC, "Failed to install listener (%s)", PHP_PQerrorMessage(obj->intern->conn));
883 } else {
884 obj->intern->poller = PQconsumeInput;
885 php_pqconn_add_listener(obj, channel_str, channel_len, &listener TSRMLS_CC);
886 }
887
888 smart_str_free(&cmd);
889 PQfreemem(quoted_channel);
890 php_pqconn_notify_listeners(obj TSRMLS_CC);
891 }
892 }
893 }
894 }
895
896 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify, 0, 0, 2)
897 ZEND_ARG_INFO(0, channel)
898 ZEND_ARG_INFO(0, message)
899 ZEND_END_ARG_INFO();
900 static PHP_METHOD(pqconn, notify) {
901 zend_error_handling zeh;
902 char *channel_str, *message_str;
903 int channel_len, message_len;
904 STATUS rv;
905
906 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
907 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &channel_str, &channel_len, &message_str, &message_len);
908 zend_restore_error_handling(&zeh TSRMLS_CC);
909
910 if (SUCCESS == rv) {
911 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
912
913 if (!obj->intern) {
914 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
915 } else {
916 PGresult *res;
917 char *params[2] = {channel_str, message_str};
918
919 res = PQexecParams(obj->intern->conn, "select pg_notify($1, $2)", 2, NULL, (const char *const*) params, NULL, NULL, 0);
920
921 if (!res) {
922 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn));
923 } else {
924 php_pqres_success(res TSRMLS_CC);
925 PHP_PQclear(res);
926 }
927
928 php_pqconn_notify_listeners(obj TSRMLS_CC);
929 }
930 }
931 }
932
933 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_notify_async, 0, 0, 2)
934 ZEND_ARG_INFO(0, channel)
935 ZEND_ARG_INFO(0, message)
936 ZEND_END_ARG_INFO();
937 static PHP_METHOD(pqconn, notifyAsync) {
938 zend_error_handling zeh;
939 char *channel_str, *message_str;
940 int channel_len, message_len;
941 STATUS rv;
942
943 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
944 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &channel_str, &channel_len, &message_str, &message_len);
945 zend_restore_error_handling(&zeh TSRMLS_CC);
946
947 if (SUCCESS == rv) {
948 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
949
950 if (!obj->intern) {
951 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
952 } else {
953 char *params[2] = {channel_str, message_str};
954
955 if (!PQsendQueryParams(obj->intern->conn, "select pg_notify($1, $2)", 2, NULL, (const char *const*) params, NULL, NULL, 0)) {
956 throw_exce(EX_IO TSRMLS_CC, "Failed to notify listeners (%s)", PHP_PQerrorMessage(obj->intern->conn));
957 } else {
958 obj->intern->poller = PQconsumeInput;
959 }
960
961 php_pqconn_notify_listeners(obj TSRMLS_CC);
962 }
963 }
964 }
965
966 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll, 0, 0, 0)
967 ZEND_END_ARG_INFO();
968 static PHP_METHOD(pqconn, poll) {
969 zend_error_handling zeh;
970 STATUS rv;
971
972 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
973 rv = zend_parse_parameters_none();
974 zend_restore_error_handling(&zeh TSRMLS_CC);
975
976 if (SUCCESS == rv) {
977 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
978
979 if (!obj->intern) {
980 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
981 } else if (!obj->intern->poller) {
982 throw_exce(EX_RUNTIME TSRMLS_CC, "No asynchronous operation active");
983 } else {
984 if (obj->intern->poller == PQconsumeInput) {
985 RETVAL_LONG(obj->intern->poller(obj->intern->conn) * PGRES_POLLING_OK);
986 } else {
987 RETVAL_LONG(obj->intern->poller(obj->intern->conn));
988 }
989 php_pqconn_notify_listeners(obj TSRMLS_CC);
990 }
991 }
992 }
993
994 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec, 0, 0, 1)
995 ZEND_ARG_INFO(0, query)
996 ZEND_END_ARG_INFO();
997 static PHP_METHOD(pqconn, exec) {
998 zend_error_handling zeh;
999 char *query_str;
1000 int query_len;
1001 STATUS rv;
1002
1003 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1004 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query_str, &query_len);
1005 zend_restore_error_handling(&zeh TSRMLS_CC);
1006
1007 if (SUCCESS == rv) {
1008 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1009
1010 if (!obj->intern) {
1011 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1012 } else {
1013 PGresult *res = PQexec(obj->intern->conn, query_str);
1014
1015 if (!res) {
1016 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
1017 } else if (SUCCESS == php_pqres_success(res TSRMLS_CC)) {
1018 php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC);
1019 } else {
1020 PHP_PQclear(res);
1021 }
1022
1023 php_pqconn_notify_listeners(obj TSRMLS_CC);
1024 }
1025 }
1026 }
1027
1028 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_get_result, 0, 0, 0)
1029 ZEND_END_ARG_INFO();
1030 static PHP_METHOD(pqconn, getResult) {
1031 zend_error_handling zeh;
1032 STATUS rv;
1033
1034 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1035 rv = zend_parse_parameters_none();
1036 zend_restore_error_handling(&zeh TSRMLS_CC);
1037
1038 if (SUCCESS == rv) {
1039 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1040
1041 if (!obj->intern) {
1042 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1043 } else {
1044 PGresult *res = PQgetResult(obj->intern->conn);
1045
1046 if (!res) {
1047 RETVAL_NULL();
1048 } else {
1049 php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC);
1050 }
1051
1052 php_pqconn_notify_listeners(obj TSRMLS_CC);
1053 }
1054 }
1055 }
1056
1057 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_async, 0, 0, 1)
1058 ZEND_ARG_INFO(0, query)
1059 ZEND_ARG_INFO(0, callable)
1060 ZEND_END_ARG_INFO();
1061 static PHP_METHOD(pqconn, execAsync) {
1062 zend_error_handling zeh;
1063 php_pq_callback_t resolver = {{0}};
1064 char *query_str;
1065 int query_len;
1066 STATUS rv;
1067
1068 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1069 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|f", &query_str, &query_len, &resolver.fci, &resolver.fcc);
1070 zend_restore_error_handling(&zeh TSRMLS_CC);
1071
1072 if (SUCCESS == rv) {
1073 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1074
1075 if (!obj->intern) {
1076 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1077 } else if (!PQsendQuery(obj->intern->conn, query_str)) {
1078 throw_exce(EX_IO TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
1079 } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) {
1080 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn));
1081 } else {
1082 php_pq_callback_recurse(&obj->intern->onevent, &resolver TSRMLS_CC);
1083 obj->intern->poller = PQconsumeInput;
1084 php_pqconn_notify_listeners(obj TSRMLS_CC);
1085 }
1086 }
1087 }
1088
1089 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params, 0, 0, 2)
1090 ZEND_ARG_INFO(0, query)
1091 ZEND_ARG_ARRAY_INFO(0, params, 0)
1092 ZEND_ARG_ARRAY_INFO(0, types, 1)
1093 ZEND_END_ARG_INFO();
1094 static PHP_METHOD(pqconn, execParams) {
1095 zend_error_handling zeh;
1096 char *query_str;
1097 int query_len;
1098 zval *zparams;
1099 zval *ztypes = NULL;
1100 STATUS rv;
1101
1102 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1103 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/|a/!", &query_str, &query_len, &zparams, &ztypes);
1104 zend_restore_error_handling(&zeh TSRMLS_CC);
1105
1106 if (SUCCESS == rv) {
1107 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1108
1109 if (!obj->intern) {
1110 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1111 } else {
1112 PGresult *res;
1113 php_pq_params_t *params;
1114
1115 params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams) TSRMLS_CC);
1116 res = PQexecParams(obj->intern->conn, query_str, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0);
1117 php_pq_params_free(&params);
1118
1119 if (!res) {
1120 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
1121 } else {
1122 if (SUCCESS == php_pqres_success(res TSRMLS_CC)) {
1123 php_pq_object_to_zval_no_addref(PQresultInstanceData(res, php_pqconn_event), &return_value TSRMLS_CC);
1124 } else {
1125 PHP_PQclear(res);
1126 }
1127
1128 php_pqconn_notify_listeners(obj TSRMLS_CC);
1129 }
1130 }
1131 }
1132 }
1133
1134 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params_async, 0, 0, 2)
1135 ZEND_ARG_INFO(0, query)
1136 ZEND_ARG_ARRAY_INFO(0, params, 0)
1137 ZEND_ARG_ARRAY_INFO(0, types, 1)
1138 ZEND_ARG_INFO(0, callable)
1139 ZEND_END_ARG_INFO();
1140 static PHP_METHOD(pqconn, execParamsAsync) {
1141 zend_error_handling zeh;
1142 php_pq_callback_t resolver = {{0}};
1143 char *query_str;
1144 int query_len;
1145 zval *zparams;
1146 zval *ztypes = NULL;
1147 STATUS rv;
1148
1149 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1150 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/|a/!f", &query_str, &query_len, &zparams, &ztypes, &resolver.fci, &resolver.fcc);
1151 zend_restore_error_handling(&zeh TSRMLS_CC);
1152
1153 if (SUCCESS == rv) {
1154 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1155
1156 if (!obj->intern) {
1157 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1158 } else {
1159 int rc;
1160 php_pq_params_t *params;
1161
1162 params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, Z_ARRVAL_P(zparams) TSRMLS_CC);
1163 rc = PQsendQueryParams(obj->intern->conn, query_str, params->param.count, params->type.oids, (const char *const*) params->param.strings, NULL, NULL, 0);
1164 php_pq_params_free(&params);
1165
1166 if (!rc) {
1167 throw_exce(EX_IO TSRMLS_CC, "Failed to execute query (%s)", PHP_PQerrorMessage(obj->intern->conn));
1168 } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) {
1169 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn));
1170 } else {
1171 php_pq_callback_recurse(&obj->intern->onevent, &resolver TSRMLS_CC);
1172 obj->intern->poller = PQconsumeInput;
1173 php_pqconn_notify_listeners(obj TSRMLS_CC);
1174 }
1175 }
1176 }
1177 zend_restore_error_handling(&zeh TSRMLS_CC);
1178 }
1179
1180 STATUS php_pqconn_prepare(zval *object, php_pqconn_object_t *obj, const char *name, const char *query, php_pq_params_t *params TSRMLS_DC)
1181 {
1182 PGresult *res;
1183 STATUS rv;
1184
1185 if (!obj) {
1186 obj = zend_object_store_get_object(object TSRMLS_CC);
1187 }
1188
1189 res = PQprepare(obj->intern->conn, name, query, params->type.count, params->type.oids);
1190
1191 if (!res) {
1192 rv = FAILURE;
1193 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn));
1194 } else {
1195 rv = php_pqres_success(res TSRMLS_CC);
1196 PHP_PQclear(res);
1197 php_pqconn_notify_listeners(obj TSRMLS_CC);
1198 }
1199
1200 return rv;
1201 }
1202
1203 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare, 0, 0, 2)
1204 ZEND_ARG_INFO(0, name)
1205 ZEND_ARG_INFO(0, query)
1206 ZEND_ARG_ARRAY_INFO(0, types, 1)
1207 ZEND_END_ARG_INFO();
1208 static PHP_METHOD(pqconn, prepare) {
1209 zend_error_handling zeh;
1210 zval *ztypes = NULL;
1211 char *name_str, *query_str;
1212 int name_len, *query_len;
1213 STATUS rv;
1214
1215 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1216 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes);
1217 zend_restore_error_handling(&zeh TSRMLS_CC);
1218
1219 if (SUCCESS == rv) {
1220 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1221
1222 if (!obj->intern) {
1223 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1224 } else {
1225 php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL TSRMLS_CC);
1226
1227 if (SUCCESS != php_pqconn_prepare(getThis(), obj, name_str, query_str, params TSRMLS_CC)) {
1228 php_pq_params_free(&params);
1229 } else {
1230 php_pqstm_t *stm = ecalloc(1, sizeof(*stm));
1231
1232 php_pq_object_addref(obj TSRMLS_CC);
1233 stm->conn = obj;
1234 stm->name = estrdup(name_str);
1235 stm->params = params;
1236 ZEND_INIT_SYMTABLE(&stm->bound);
1237
1238 return_value->type = IS_OBJECT;
1239 return_value->value.obj = php_pqstm_create_object_ex(php_pqstm_class_entry, stm, NULL TSRMLS_CC);
1240 }
1241 }
1242 }
1243 }
1244
1245 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)
1246 {
1247 STATUS rv;
1248
1249 if (!obj) {
1250 obj = zend_object_store_get_object(object TSRMLS_CC);
1251 }
1252
1253 if (!PQsendPrepare(obj->intern->conn, name, query, params->type.count, params->type.oids)) {
1254 rv = FAILURE;
1255 throw_exce(EX_IO TSRMLS_CC, "Failed to prepare statement (%s)", PHP_PQerrorMessage(obj->intern->conn));
1256 } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) {
1257 rv = FAILURE;
1258 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn));
1259 } else {
1260 rv = SUCCESS;
1261 obj->intern->poller = PQconsumeInput;
1262 php_pqconn_notify_listeners(obj TSRMLS_CC);
1263 }
1264
1265 return rv;
1266 }
1267
1268 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare_async, 0, 0, 2)
1269 ZEND_ARG_INFO(0, name)
1270 ZEND_ARG_INFO(0, query)
1271 ZEND_ARG_ARRAY_INFO(0, types, 1)
1272 ZEND_END_ARG_INFO();
1273 static PHP_METHOD(pqconn, prepareAsync) {
1274 zend_error_handling zeh;
1275 zval *ztypes = NULL;
1276 char *name_str, *query_str;
1277 int name_len, *query_len;
1278 STATUS rv;
1279
1280 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1281 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes);
1282 zend_restore_error_handling(&zeh TSRMLS_CC);
1283
1284 if (SUCCESS == rv) {
1285 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1286
1287 if (!obj->intern) {
1288 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1289 } else {
1290 php_pq_params_t *params = php_pq_params_init(&obj->intern->converters, ztypes ? Z_ARRVAL_P(ztypes) : NULL, NULL TSRMLS_CC);
1291
1292 if (SUCCESS != php_pqconn_prepare_async(getThis(), obj, name_str, query_str, params TSRMLS_CC)) {
1293 php_pq_params_free(&params);
1294 } else {
1295 php_pqstm_t *stm = ecalloc(1, sizeof(*stm));
1296
1297 php_pq_object_addref(obj TSRMLS_CC);
1298 stm->conn = obj;
1299 stm->name = estrdup(name_str);
1300 stm->params = params;
1301 ZEND_INIT_SYMTABLE(&stm->bound);
1302
1303 return_value->type = IS_OBJECT;
1304 return_value->value.obj = php_pqstm_create_object_ex(php_pqstm_class_entry, stm, NULL TSRMLS_CC);
1305 }
1306 }
1307 }
1308 }
1309
1310 static inline char *declare_str(const char *name_str, size_t name_len, unsigned flags, const char *query_str, size_t query_len)
1311 {
1312 size_t decl_len = name_len + query_len + sizeof("DECLARE BINARY INSENSITIVE NO SCROLL CURSOR WITHOUT HOLD FOR ");
1313 char *decl_str;
1314
1315 decl_str = emalloc(decl_len);
1316 decl_len = slprintf(decl_str, decl_len, "DECLARE %s %s %s %s CURSOR %s FOR %s",
1317 name_str,
1318 (flags & PHP_PQ_DECLARE_BINARY) ? "BINARY" : "",
1319 (flags & PHP_PQ_DECLARE_INSENSITIVE) ? "INSENSITIVE" : "",
1320 (flags & PHP_PQ_DECLARE_NO_SCROLL) ? "NO SCROLL" :
1321 (flags & PHP_PQ_DECLARE_SCROLL) ? "SCROLL" : "",
1322 (flags & PHP_PQ_DECLARE_WITH_HOLD) ? "WITH HOLD" : "",
1323 query_str
1324 );
1325 return decl_str;
1326 }
1327
1328 STATUS php_pqconn_declare(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC)
1329 {
1330 PGresult *res;
1331 STATUS rv;
1332
1333 if (!obj) {
1334 obj = zend_object_store_get_object(object TSRMLS_CC);
1335 }
1336
1337 res = PQexec(obj->intern->conn, decl);
1338
1339 if (!res) {
1340 rv = FAILURE;
1341 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
1342 } else {
1343 rv = php_pqres_success(res TSRMLS_CC);
1344 PHP_PQclear(res);
1345 php_pqconn_notify_listeners(obj TSRMLS_CC);
1346 }
1347
1348 return rv;
1349 }
1350
1351 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare, 0, 0, 3)
1352 ZEND_ARG_INFO(0, name)
1353 ZEND_ARG_INFO(0, flags)
1354 ZEND_ARG_INFO(0, query)
1355 ZEND_END_ARG_INFO();
1356 static PHP_METHOD(pqconn, declare) {
1357 zend_error_handling zeh;
1358 char *name_str, *query_str;
1359 int name_len, query_len;
1360 long flags;
1361 STATUS rv;
1362
1363 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1364 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &name_str, &name_len, &flags, &query_str, &query_len);
1365 zend_restore_error_handling(&zeh TSRMLS_CC);
1366
1367 if (SUCCESS == rv) {
1368 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1369
1370 if (!obj->intern) {
1371 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1372 } else {
1373 char *decl = declare_str(name_str, name_len, flags, query_str, query_len);
1374
1375 if (SUCCESS != php_pqconn_declare(getThis(), obj, decl TSRMLS_CC)) {
1376 efree(decl);
1377 } else {
1378 php_pqcur_t *cur = ecalloc(1, sizeof(*cur));
1379
1380 php_pq_object_addref(obj TSRMLS_CC);
1381 cur->conn = obj;
1382 cur->open = 1;
1383 cur->name = estrdup(name_str);
1384 cur->decl = decl;
1385
1386 return_value->type = IS_OBJECT;
1387 return_value->value.obj = php_pqcur_create_object_ex(php_pqcur_class_entry, cur, NULL TSRMLS_CC);
1388 }
1389 }
1390 }
1391 }
1392
1393 STATUS php_pqconn_declare_async(zval *object, php_pqconn_object_t *obj, const char *decl TSRMLS_DC)
1394 {
1395 STATUS rv;
1396
1397 if (!obj) {
1398 obj = zend_object_store_get_object(object TSRMLS_CC);
1399 }
1400
1401 if (!PQsendQuery(obj->intern->conn, decl)) {
1402 rv = FAILURE;
1403 throw_exce(EX_IO TSRMLS_CC, "Failed to declare cursor (%s)", PHP_PQerrorMessage(obj->intern->conn));
1404 } else if (obj->intern->unbuffered && !PQsetSingleRowMode(obj->intern->conn)) {
1405 rv = FAILURE;
1406 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to enable unbuffered mode (%s)", PHP_PQerrorMessage(obj->intern->conn));
1407 } else {
1408 rv = SUCCESS;
1409 obj->intern->poller = PQconsumeInput;
1410 php_pqconn_notify_listeners(obj TSRMLS_CC);
1411 }
1412
1413 return rv;
1414 }
1415
1416 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_declare_async, 0, 0, 2)
1417 ZEND_ARG_INFO(0, name)
1418 ZEND_ARG_INFO(0, flags)
1419 ZEND_ARG_INFO(0, query)
1420 ZEND_END_ARG_INFO();
1421 static PHP_METHOD(pqconn, declareAsync) {
1422 zend_error_handling zeh;
1423 char *name_str, *query_str;
1424 int name_len, query_len;
1425 long flags;
1426 STATUS rv;
1427
1428 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1429 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &name_str, &name_len, &flags, &query_str, &query_len);
1430 zend_restore_error_handling(&zeh TSRMLS_CC);
1431
1432 if (SUCCESS == rv) {
1433 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1434
1435 if (!obj->intern) {
1436 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1437 } else {
1438 char *decl = declare_str(name_str, name_len, flags, query_str, query_len);
1439
1440 if (SUCCESS != php_pqconn_declare_async(getThis(), obj, decl TSRMLS_CC)) {
1441 efree(decl);
1442 } else {
1443 php_pqcur_t *cur = ecalloc(1, sizeof(*cur));
1444
1445 php_pq_object_addref(obj TSRMLS_CC);
1446 cur->conn = obj;
1447 cur->open = 1;
1448 cur->name = estrdup(name_str);
1449 cur->decl = decl;
1450
1451 return_value->type = IS_OBJECT;
1452 return_value->value.obj = php_pqcur_create_object_ex(php_pqcur_class_entry, cur, NULL TSRMLS_CC);
1453 }
1454 }
1455 }
1456 }
1457
1458 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote, 0, 0, 1)
1459 ZEND_ARG_INFO(0, string)
1460 ZEND_END_ARG_INFO();
1461 static PHP_METHOD(pqconn, quote) {
1462 char *str;
1463 int len;
1464
1465 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) {
1466 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1467
1468 if (!obj->intern) {
1469 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1470 } else {
1471 char *quoted = PQescapeLiteral(obj->intern->conn, str, len);
1472
1473 if (!quoted) {
1474 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to quote string (%s)", PHP_PQerrorMessage(obj->intern->conn));
1475 RETVAL_FALSE;
1476 } else {
1477 RETVAL_STRING(quoted, 1);
1478 PQfreemem(quoted);
1479 }
1480 }
1481 }
1482 }
1483
1484 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_quote_name, 0, 0, 1)
1485 ZEND_ARG_INFO(0, type)
1486 ZEND_END_ARG_INFO();
1487 static PHP_METHOD(pqconn, quoteName) {
1488 char *str;
1489 int len;
1490
1491 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) {
1492 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1493
1494 if (!obj->intern) {
1495 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1496 } else {
1497 char *quoted = PQescapeIdentifier(obj->intern->conn, str, len);
1498
1499 if (!quoted) {
1500 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to quote name (%s)", PHP_PQerrorMessage(obj->intern->conn));
1501 RETVAL_FALSE;
1502 } else {
1503 RETVAL_STRING(quoted, 1);
1504 PQfreemem(quoted);
1505 }
1506 }
1507 }
1508 }
1509
1510 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_escape_bytea, 0, 0, 1)
1511 ZEND_ARG_INFO(0, bytea)
1512 ZEND_END_ARG_INFO();
1513 static PHP_METHOD(pqconn, escapeBytea) {
1514 char *str;
1515 int len;
1516
1517 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) {
1518 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1519
1520 if (!obj->intern) {
1521 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1522 } else {
1523 size_t escaped_len;
1524 char *escaped_str = (char *) PQescapeByteaConn(obj->intern->conn, (unsigned char *) str, len, &escaped_len);
1525
1526 if (!escaped_str) {
1527 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to escape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn));
1528 RETVAL_FALSE;
1529 } else {
1530 RETVAL_STRINGL(escaped_str, escaped_len - 1, 1);
1531 PQfreemem(escaped_str);
1532 }
1533 }
1534 }
1535 }
1536
1537 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unescape_bytea, 0, 0, 1)
1538 ZEND_ARG_INFO(0, bytea)
1539 ZEND_END_ARG_INFO();
1540 static PHP_METHOD(pqconn, unescapeBytea) {
1541 char *str;
1542 int len;
1543
1544 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len)) {
1545 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1546
1547 if (!obj->intern) {
1548 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1549 } else {
1550 size_t unescaped_len;
1551 char *unescaped_str = (char *) PQunescapeBytea((unsigned char *)str, &unescaped_len);
1552
1553 if (!unescaped_str) {
1554 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to unescape bytea (%s)", PHP_PQerrorMessage(obj->intern->conn));
1555 RETVAL_FALSE;
1556 } else {
1557 RETVAL_STRINGL(unescaped_str, unescaped_len, 1);
1558 PQfreemem(unescaped_str);
1559 }
1560 }
1561 }
1562 }
1563
1564 STATUS php_pqconn_start_transaction(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable TSRMLS_DC)
1565 {
1566 STATUS rv = FAILURE;
1567
1568 if (!conn_obj) {
1569 conn_obj = zend_object_store_get_object(zconn TSRMLS_CC);
1570 }
1571
1572 if (!conn_obj->intern) {
1573 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1574 } else {
1575 PGresult *res;
1576 smart_str cmd = {0};
1577 const char *il = isolation_level(&isolation);
1578
1579 smart_str_appends(&cmd, "START TRANSACTION ISOLATION LEVEL ");
1580 smart_str_appends(&cmd, il);
1581 smart_str_appends(&cmd, ", READ ");
1582 smart_str_appends(&cmd, readonly ? "ONLY" : "WRITE");
1583 smart_str_appends(&cmd, ",");
1584 smart_str_appends(&cmd, deferrable ? "" : " NOT");
1585 smart_str_appends(&cmd, " DEFERRABLE");
1586 smart_str_0(&cmd);
1587
1588 res = PQexec(conn_obj->intern->conn, cmd.c);
1589
1590 if (!res) {
1591 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn));
1592 } else {
1593 rv = php_pqres_success(res TSRMLS_CC);
1594 PHP_PQclear(res);
1595 php_pqconn_notify_listeners(conn_obj TSRMLS_CC);
1596 }
1597
1598 smart_str_free(&cmd);
1599 }
1600
1601 return rv;
1602 }
1603
1604 STATUS php_pqconn_start_transaction_async(zval *zconn, php_pqconn_object_t *conn_obj, long isolation, zend_bool readonly, zend_bool deferrable TSRMLS_DC)
1605 {
1606 STATUS rv = FAILURE;
1607
1608 if (!conn_obj) {
1609 conn_obj = zend_object_store_get_object(zconn TSRMLS_CC);
1610 }
1611
1612 if (!conn_obj->intern) {
1613 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1614 } else {
1615 smart_str cmd = {0};
1616 const char *il = isolation_level(&isolation);
1617
1618 smart_str_appends(&cmd, "START TRANSACTION ISOLATION LEVEL ");
1619 smart_str_appends(&cmd, il);
1620 smart_str_appends(&cmd, ", READ ");
1621 smart_str_appends(&cmd, readonly ? "ONLY" : "WRITE");
1622 smart_str_appends(&cmd, ",");
1623 smart_str_appends(&cmd, deferrable ? "" : "NOT ");
1624 smart_str_appends(&cmd, " DEFERRABLE");
1625 smart_str_0(&cmd);
1626
1627 if (!PQsendQuery(conn_obj->intern->conn, cmd.c)) {
1628 throw_exce(EX_IO TSRMLS_CC, "Failed to start transaction (%s)", PHP_PQerrorMessage(conn_obj->intern->conn));
1629 } else {
1630 rv = SUCCESS;
1631 conn_obj->intern->poller = PQconsumeInput;
1632 php_pqconn_notify_listeners(conn_obj TSRMLS_CC);
1633 }
1634
1635 smart_str_free(&cmd);
1636 }
1637
1638 return rv;
1639 }
1640
1641 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction, 0, 0, 0)
1642 ZEND_ARG_INFO(0, isolation)
1643 ZEND_ARG_INFO(0, readonly)
1644 ZEND_ARG_INFO(0, deferrable)
1645 ZEND_END_ARG_INFO();
1646 static PHP_METHOD(pqconn, startTransaction) {
1647 zend_error_handling zeh;
1648 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1649 long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED;
1650 zend_bool readonly = obj->intern ? obj->intern->default_txn_readonly : 0;
1651 zend_bool deferrable = obj->intern ? obj->intern->default_txn_deferrable : 0;
1652 STATUS rv;
1653
1654 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1655 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lbb", &isolation, &readonly, &deferrable);
1656 zend_restore_error_handling(&zeh TSRMLS_CC);
1657
1658 if (SUCCESS == rv) {
1659 rv = php_pqconn_start_transaction(getThis(), obj, isolation, readonly, deferrable TSRMLS_CC);
1660
1661 if (SUCCESS == rv) {
1662 php_pqtxn_t *txn = ecalloc(1, sizeof(*txn));
1663
1664 php_pq_object_addref(obj TSRMLS_CC);
1665 txn->conn = obj;
1666 txn->open = 1;
1667 txn->isolation = isolation;
1668 txn->readonly = readonly;
1669 txn->deferrable = deferrable;
1670
1671 return_value->type = IS_OBJECT;
1672 return_value->value.obj = php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn, NULL TSRMLS_CC);
1673 }
1674 }
1675 }
1676
1677 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_start_transaction_async, 0, 0, 0)
1678 ZEND_ARG_INFO(0, isolation)
1679 ZEND_ARG_INFO(0, readonly)
1680 ZEND_ARG_INFO(0, deferrable)
1681 ZEND_END_ARG_INFO();
1682 static PHP_METHOD(pqconn, startTransactionAsync) {
1683 zend_error_handling zeh;
1684 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1685 long isolation = obj->intern ? obj->intern->default_txn_isolation : PHP_PQTXN_READ_COMMITTED;
1686 zend_bool readonly = obj->intern ? obj->intern->default_txn_readonly : 0;
1687 zend_bool deferrable = obj->intern ? obj->intern->default_txn_deferrable : 0;
1688 STATUS rv;
1689
1690 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1691 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lbb", &isolation, &readonly, &deferrable);
1692 zend_restore_error_handling(&zeh TSRMLS_CC);
1693
1694 if (SUCCESS == rv) {
1695 rv = php_pqconn_start_transaction_async(getThis(), obj, isolation, readonly, deferrable TSRMLS_CC);
1696
1697 if (SUCCESS == rv) {
1698 php_pqtxn_t *txn = ecalloc(1, sizeof(*txn));
1699
1700 php_pq_object_addref(obj TSRMLS_CC);
1701 txn->conn = obj;
1702 txn->isolation = isolation;
1703 txn->readonly = readonly;
1704 txn->deferrable = deferrable;
1705
1706 return_value->type = IS_OBJECT;
1707 return_value->value.obj = php_pqtxn_create_object_ex(php_pqtxn_class_entry, txn, NULL TSRMLS_CC);
1708 }
1709 }
1710 }
1711
1712 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_trace, 0, 0, 0)
1713 ZEND_ARG_INFO(0, stdio_stream)
1714 ZEND_END_ARG_INFO();
1715 static PHP_METHOD(pqconn, trace) {
1716 zval *zstream = NULL;
1717
1718 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r!", &zstream)) {
1719 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1720
1721 if (!obj->intern) {
1722 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1723 } else {
1724 if (!zstream) {
1725 PQuntrace(obj->intern->conn);
1726 RETVAL_TRUE;
1727 } else {
1728 FILE *fp;
1729 php_stream *stream = NULL;
1730
1731 php_stream_from_zval(stream, &zstream);
1732
1733 if (SUCCESS != php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) {
1734 RETVAL_FALSE;
1735 } else {
1736 stream->flags |= PHP_STREAM_FLAG_NO_CLOSE;
1737 PQtrace(obj->intern->conn, fp);
1738 RETVAL_TRUE;
1739 }
1740 }
1741 }
1742 }
1743 }
1744
1745 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_off, 0, 0, 1)
1746 ZEND_ARG_INFO(0, type)
1747 ZEND_END_ARG_INFO();
1748 static PHP_METHOD(pqconn, off) {
1749 zend_error_handling zeh;
1750 char *type_str;
1751 int type_len;
1752 STATUS rv;
1753
1754 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1755 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &type_str, &type_len);
1756 zend_restore_error_handling(&zeh TSRMLS_CC);
1757
1758 if (SUCCESS == rv) {
1759 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1760
1761 if (!obj->intern) {
1762 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1763 } else {
1764 RETURN_BOOL(SUCCESS == zend_hash_del(&obj->intern->eventhandlers, type_str, type_len + 1));
1765 }
1766 }
1767 }
1768
1769 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_on, 0, 0, 2)
1770 ZEND_ARG_INFO(0, type)
1771 ZEND_ARG_INFO(0, callable)
1772 ZEND_END_ARG_INFO();
1773 static PHP_METHOD(pqconn, on) {
1774 zend_error_handling zeh;
1775 char *type_str;
1776 int type_len;
1777 php_pq_callback_t cb = {{0}};
1778 STATUS rv;
1779
1780 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1781 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sf", &type_str, &type_len, &cb.fci, &cb.fcc);
1782 zend_restore_error_handling(&zeh TSRMLS_CC);
1783
1784 if (SUCCESS == rv) {
1785 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1786
1787 if (!obj->intern) {
1788 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1789 } else {
1790 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1791
1792 RETVAL_LONG(php_pqconn_add_eventhandler(obj, type_str, type_len, &cb TSRMLS_CC));
1793 }
1794 }
1795 }
1796
1797 static int apply_set_converter(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
1798 {
1799 zval *tmp, **zoid = p, **zcnv = va_arg(argv, zval **);
1800 HashTable *converters = va_arg(argv, HashTable *);
1801 int add = va_arg(argv, int);
1802
1803 tmp = *zoid;
1804 Z_ADDREF_P(tmp);
1805 convert_to_long_ex(&tmp);
1806 if (add) {
1807 Z_ADDREF_PP(zcnv);
1808 zend_hash_index_update(converters, Z_LVAL_P(tmp), zcnv, sizeof(zval *), NULL);
1809 } else {
1810 zend_hash_index_del(converters, Z_LVAL_P(tmp));
1811 }
1812 zval_ptr_dtor(&tmp);
1813
1814 return ZEND_HASH_APPLY_KEEP;
1815 }
1816
1817 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_set_converter, 0, 0, 1)
1818 ZEND_ARG_OBJ_INFO(0, converter, pq\\ConverterInterface, 0)
1819 ZEND_END_ARG_INFO();
1820 static PHP_METHOD(pqconn, setConverter) {
1821 STATUS rv;
1822 zend_error_handling zeh;
1823 zval *zcnv;
1824
1825 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1826 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zcnv, php_pqconv_class_entry);
1827 zend_restore_error_handling(&zeh TSRMLS_CC);
1828
1829 if (SUCCESS == rv) {
1830 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1831
1832 if (!obj->intern) {
1833 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1834 } else {
1835 zval *tmp, *zoids = NULL;
1836
1837 zend_call_method_with_0_params(&zcnv, NULL, NULL, "converttypes", &zoids);
1838 tmp = zoids;
1839 Z_ADDREF_P(tmp);
1840 convert_to_array_ex(&tmp);
1841 zend_hash_apply_with_arguments(Z_ARRVAL_P(tmp) TSRMLS_CC, apply_set_converter, 3, &zcnv, &obj->intern->converters, 1);
1842 zval_ptr_dtor(&tmp);
1843 zval_ptr_dtor(&zoids);
1844 }
1845 }
1846 }
1847
1848 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_unset_converter, 0, 0, 1)
1849 ZEND_ARG_OBJ_INFO(0, converter, pq\\ConverterInterface, 0)
1850 ZEND_END_ARG_INFO();
1851 static PHP_METHOD(pqconn, unsetConverter) {
1852 STATUS rv;
1853 zend_error_handling zeh;
1854 zval *zcnv;
1855
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);
1859
1860 if (SUCCESS == rv) {
1861 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1862
1863 if (!obj->intern) {
1864 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Connection not initialized");
1865 } else {
1866 zval *tmp, *zoids = NULL;
1867
1868 zend_call_method_with_0_params(&zcnv, NULL, NULL, "converttypes", &zoids);
1869 tmp = zoids;
1870 Z_ADDREF_P(tmp);
1871 convert_to_array_ex(&tmp);
1872 zend_hash_apply_with_arguments(Z_ARRVAL_P(tmp) TSRMLS_CC, apply_set_converter, 3, &zcnv, &obj->intern->converters, 0);
1873 zval_ptr_dtor(&tmp);
1874 zval_ptr_dtor(&zoids);
1875 }
1876 }
1877 }
1878
1879 static zend_function_entry php_pqconn_methods[] = {
1880 PHP_ME(pqconn, __construct, ai_pqconn_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
1881 PHP_ME(pqconn, reset, ai_pqconn_reset, ZEND_ACC_PUBLIC)
1882 PHP_ME(pqconn, resetAsync, ai_pqconn_reset_async, ZEND_ACC_PUBLIC)
1883 PHP_ME(pqconn, poll, ai_pqconn_poll, ZEND_ACC_PUBLIC)
1884 PHP_ME(pqconn, exec, ai_pqconn_exec, ZEND_ACC_PUBLIC)
1885 PHP_ME(pqconn, execAsync, ai_pqconn_exec_async, ZEND_ACC_PUBLIC)
1886 PHP_ME(pqconn, execParams, ai_pqconn_exec_params, ZEND_ACC_PUBLIC)
1887 PHP_ME(pqconn, execParamsAsync, ai_pqconn_exec_params_async, ZEND_ACC_PUBLIC)
1888 PHP_ME(pqconn, prepare, ai_pqconn_prepare, ZEND_ACC_PUBLIC)
1889 PHP_ME(pqconn, prepareAsync, ai_pqconn_prepare_async, ZEND_ACC_PUBLIC)
1890 PHP_ME(pqconn, declare, ai_pqconn_declare, ZEND_ACC_PUBLIC)
1891 PHP_ME(pqconn, declareAsync, ai_pqconn_declare_async, ZEND_ACC_PUBLIC)
1892 PHP_ME(pqconn, unlisten, ai_pqconn_unlisten, ZEND_ACC_PUBLIC)
1893 PHP_ME(pqconn, unlistenAsync, ai_pqconn_unlisten_async, ZEND_ACC_PUBLIC)
1894 PHP_ME(pqconn, listen, ai_pqconn_listen, ZEND_ACC_PUBLIC)
1895 PHP_ME(pqconn, listenAsync, ai_pqconn_listen_async, ZEND_ACC_PUBLIC)
1896 PHP_ME(pqconn, notify, ai_pqconn_notify, ZEND_ACC_PUBLIC)
1897 PHP_ME(pqconn, notifyAsync, ai_pqconn_notify_async, ZEND_ACC_PUBLIC)
1898 PHP_ME(pqconn, getResult, ai_pqconn_get_result, ZEND_ACC_PUBLIC)
1899 PHP_ME(pqconn, quote, ai_pqconn_quote, ZEND_ACC_PUBLIC)
1900 PHP_ME(pqconn, quoteName, ai_pqconn_quote_name, ZEND_ACC_PUBLIC)
1901 PHP_ME(pqconn, escapeBytea, ai_pqconn_escape_bytea, ZEND_ACC_PUBLIC)
1902 PHP_ME(pqconn, unescapeBytea, ai_pqconn_unescape_bytea, ZEND_ACC_PUBLIC)
1903 PHP_ME(pqconn, startTransaction, ai_pqconn_start_transaction, ZEND_ACC_PUBLIC)
1904 PHP_ME(pqconn, startTransactionAsync, ai_pqconn_start_transaction_async, ZEND_ACC_PUBLIC)
1905 PHP_ME(pqconn, trace, ai_pqconn_trace, ZEND_ACC_PUBLIC)
1906 PHP_ME(pqconn, off, ai_pqconn_off, ZEND_ACC_PUBLIC)
1907 PHP_ME(pqconn, on, ai_pqconn_on, ZEND_ACC_PUBLIC)
1908 PHP_ME(pqconn, setConverter, ai_pqconn_set_converter, ZEND_ACC_PUBLIC)
1909 PHP_ME(pqconn, unsetConverter, ai_pqconn_unset_converter, ZEND_ACC_PUBLIC)
1910 {0}
1911 };
1912
1913 PHP_MSHUTDOWN_FUNCTION(pqconn)
1914 {
1915 zend_hash_destroy(&php_pqconn_object_prophandlers);
1916 return SUCCESS;
1917 }
1918
1919 PHP_MINIT_FUNCTION(pqconn)
1920 {
1921 zend_class_entry ce = {0};
1922 php_pq_object_prophandler_t ph = {0};
1923
1924 INIT_NS_CLASS_ENTRY(ce, "pq", "Connection", php_pqconn_methods);
1925 php_pqconn_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
1926 php_pqconn_class_entry->create_object = php_pqconn_create_object;
1927
1928 memcpy(&php_pqconn_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1929 php_pqconn_object_handlers.read_property = php_pq_object_read_prop;
1930 php_pqconn_object_handlers.write_property = php_pq_object_write_prop;
1931 php_pqconn_object_handlers.clone_obj = NULL;
1932 php_pqconn_object_handlers.get_property_ptr_ptr = NULL;
1933 php_pqconn_object_handlers.get_gc = NULL;
1934 php_pqconn_object_handlers.get_properties = php_pq_object_properties;
1935 php_pqconn_object_handlers.get_debug_info = php_pq_object_debug_info;
1936
1937 zend_hash_init(&php_pqconn_object_prophandlers, 14, NULL, NULL, 1);
1938
1939 zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC TSRMLS_CC);
1940 ph.read = php_pqconn_object_read_status;
1941 zend_hash_add(&php_pqconn_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL);
1942
1943 zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC TSRMLS_CC);
1944 ph.read = php_pqconn_object_read_transaction_status;
1945 zend_hash_add(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus"), (void *) &ph, sizeof(ph), NULL);
1946
1947 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC);
1948 ph.read = NULL; /* forward to std prophandler */
1949 zend_hash_add(&php_pqconn_object_prophandlers, "socket", sizeof("socket"), (void *) &ph, sizeof(ph), NULL);
1950
1951 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC);
1952 ph.read = php_pqconn_object_read_error_message;
1953 zend_hash_add(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL);
1954
1955 zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("busy"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1956 ph.read = php_pqconn_object_read_busy;
1957 zend_hash_add(&php_pqconn_object_prophandlers, "busy", sizeof("busy"), (void *) &ph, sizeof(ph), NULL);
1958
1959 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("encoding"), ZEND_ACC_PUBLIC TSRMLS_CC);
1960 ph.read = php_pqconn_object_read_encoding;
1961 ph.write = php_pqconn_object_write_encoding;
1962 zend_hash_add(&php_pqconn_object_prophandlers, "encoding", sizeof("encoding"), (void *) &ph, sizeof(ph), NULL);
1963 ph.write = NULL;
1964
1965 zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("unbuffered"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1966 ph.read = php_pqconn_object_read_unbuffered;
1967 ph.write = php_pqconn_object_write_unbuffered;
1968 zend_hash_add(&php_pqconn_object_prophandlers, "unbuffered", sizeof("unbuffered"), (void *) &ph, sizeof(ph), NULL);
1969 ph.write = NULL;
1970
1971 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("db"), ZEND_ACC_PUBLIC TSRMLS_CC);
1972 ph.read = php_pqconn_object_read_db;
1973 zend_hash_add(&php_pqconn_object_prophandlers, "db", sizeof("db"), (void *) &ph, sizeof(ph), NULL);
1974
1975 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC);
1976 ph.read = php_pqconn_object_read_user;
1977 zend_hash_add(&php_pqconn_object_prophandlers, "user", sizeof("user"), (void *) &ph, sizeof(ph), NULL);
1978
1979 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC);
1980 ph.read = php_pqconn_object_read_pass;
1981 zend_hash_add(&php_pqconn_object_prophandlers, "pass", sizeof("pass"), (void *) &ph, sizeof(ph), NULL);
1982
1983 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC);
1984 ph.read = php_pqconn_object_read_host;
1985 zend_hash_add(&php_pqconn_object_prophandlers, "host", sizeof("host"), (void *) &ph, sizeof(ph), NULL);
1986
1987 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC);
1988 ph.read = php_pqconn_object_read_port;
1989 zend_hash_add(&php_pqconn_object_prophandlers, "port", sizeof("port"), (void *) &ph, sizeof(ph), NULL);
1990
1991 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("options"), ZEND_ACC_PUBLIC TSRMLS_CC);
1992 ph.read = php_pqconn_object_read_options;
1993 zend_hash_add(&php_pqconn_object_prophandlers, "options", sizeof("options"), (void *) &ph, sizeof(ph), NULL);
1994
1995 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("eventHandlers"), ZEND_ACC_PUBLIC TSRMLS_CC);
1996 ph.read = php_pqconn_object_read_event_handlers;
1997 zend_hash_add(&php_pqconn_object_prophandlers, "eventHandlers", sizeof("eventHandlers"), (void *) &ph, sizeof(ph), NULL);
1998
1999 zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultFetchType"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
2000 ph.read = php_pqconn_object_read_def_fetch_type;
2001 ph.write = php_pqconn_object_write_def_fetch_type;
2002 zend_hash_add(&php_pqconn_object_prophandlers, "defaultFetchType", sizeof("defaultFetchType"), (void *) &ph, sizeof(ph), NULL);
2003 ph.write = NULL;
2004
2005 zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultTransactionIsolation"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
2006 ph.read = php_pqconn_object_read_def_txn_isolation;
2007 ph.write = php_pqconn_object_write_def_txn_isolation;
2008 zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionIsolation", sizeof("defaultTransactionIsolation"), (void *) &ph, sizeof(ph), NULL);
2009 ph.write = NULL;
2010
2011 zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionReadonly"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
2012 ph.read = php_pqconn_object_read_def_txn_readonly;
2013 ph.write = php_pqconn_object_write_def_txn_readonly;
2014 zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionReadonly", sizeof("defaultTransactionReadonly"), (void *) &ph, sizeof(ph), NULL);
2015 ph.write = NULL;
2016
2017 zend_declare_property_bool(php_pqconn_class_entry, ZEND_STRL("defaultTransactionDeferrable"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
2018 ph.read = php_pqconn_object_read_def_txn_deferrable;
2019 ph.write = php_pqconn_object_write_def_txn_deferrable;
2020 zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable"), (void *) &ph, sizeof(ph), NULL);
2021 ph.write = NULL;
2022
2023 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC);
2024 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC);
2025 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC);
2026 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC);
2027 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC);
2028 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC);
2029 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC);
2030 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC);
2031
2032 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC);
2033 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC);
2034 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC);
2035 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC);
2036 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC);
2037
2038 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC);
2039 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC);
2040 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC);
2041 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC);
2042
2043 zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_NOTICE"), ZEND_STRL("notice") TSRMLS_CC);
2044 zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESULT"), ZEND_STRL("result") TSRMLS_CC);
2045 zend_declare_class_constant_stringl(php_pqconn_class_entry, ZEND_STRL("EVENT_RESET"), ZEND_STRL("reset") TSRMLS_CC);
2046
2047 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("ASYNC"), 0x1 TSRMLS_CC);
2048 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("PERSISTENT"), 0x2 TSRMLS_CC);
2049
2050 return SUCCESS;
2051 }
2052
2053 /*
2054 * Local variables:
2055 * tab-width: 4
2056 * c-basic-offset: 4
2057 * End:
2058 * vim600: noet sw=4 ts=4 fdm=marker
2059 * vim<600: noet sw=4 ts=4
2060 */