progress++
[m6w6/ext-pq] / src / php_pq.c
1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2012 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <php.h>
26 #include <Zend/zend_interfaces.h>
27 #include <ext/standard/info.h>
28 #include <ext/spl/spl_array.h>
29
30 #include <libpq-events.h>
31
32 #include "php_pq.h"
33
34 typedef int STATUS; /* SUCCESS/FAILURE */
35
36 /*
37 ZEND_DECLARE_MODULE_GLOBALS(pq)
38 */
39
40 const zend_function_entry pq_functions[] = {
41 {0}
42 };
43
44 /* {{{ pq_module_entry
45 */
46 zend_module_entry pq_module_entry = {
47 STANDARD_MODULE_HEADER,
48 "pq",
49 pq_functions,
50 PHP_MINIT(pq),
51 PHP_MSHUTDOWN(pq),
52 NULL,/*PHP_RINIT(pq),*/
53 NULL,/*PHP_RSHUTDOWN(pq),*/
54 PHP_MINFO(pq),
55 PHP_PQ_EXT_VERSION,
56 STANDARD_MODULE_PROPERTIES
57 };
58 /* }}} */
59
60 #ifdef COMPILE_DL_PQ
61 ZEND_GET_MODULE(pq)
62 #endif
63
64 /* {{{ PHP_INI
65 */
66 /* Remove comments and fill if you need to have entries in php.ini
67 PHP_INI_BEGIN()
68 STD_PHP_INI_ENTRY("pq.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pq_globals, pq_globals)
69 STD_PHP_INI_ENTRY("pq.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_pq_globals, pq_globals)
70 PHP_INI_END()
71 */
72 /* }}} */
73
74 /* {{{ php_pq_init_globals
75 */
76 /* Uncomment this function if you have INI entries
77 static void php_pq_init_globals(zend_pq_globals *pq_globals)
78 {
79 pq_globals->global_value = 0;
80 pq_globals->global_string = NULL;
81 }
82 */
83 /* }}} */
84
85 static zend_class_entry *php_pqconn_class_entry;
86 static zend_class_entry *php_pqres_class_entry;
87 static zend_class_entry *php_pqstm_class_entry;
88
89 static zend_object_handlers php_pqconn_object_handlers;
90 static zend_object_handlers php_pqres_object_handlers;
91 static zend_object_handlers php_pqstm_object_handlers;
92
93 typedef struct php_pqconn_object {
94 zend_object zo;
95 PGconn *conn;
96 int (*poller)(PGconn *);
97 unsigned blocking:1;
98 } php_pqconn_object_t;
99
100 typedef enum php_pqres_fetch {
101 PHP_PQRES_FETCH_ARRAY,
102 PHP_PQRES_FETCH_ASSOC,
103 PHP_PQRES_FETCH_OBJECT
104 } php_pqres_fetch_t;
105
106 typedef struct php_pqres_iterator {
107 zend_object_iterator zi;
108 zval *current_val;
109 unsigned index;
110 php_pqres_fetch_t fetch_type;
111 } php_pqres_iterator_t;
112
113 typedef struct php_pqres_object {
114 zend_object zo;
115 PGresult *res;
116 php_pqres_iterator_t *iter;
117 } php_pqres_object_t;
118
119 typedef struct php_pqstm_intern {
120 char *name;
121 zval *conn;
122 } php_pqstm_intern_t;
123
124 typedef struct php_pqstm_object {
125 zend_object zo;
126 char *name;
127 zval *conn;
128 } php_pqstm_object_t;
129
130 static zend_object_iterator_funcs php_pqres_iterator_funcs;
131
132 static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
133 {
134 php_pqres_iterator_t *iter;
135 zval *prop, *zfetch_type;
136
137 iter = ecalloc(1, sizeof(*iter));
138 iter->zi.funcs = &php_pqres_iterator_funcs;
139 iter->zi.data = object;
140 Z_ADDREF_P(object);
141
142 zfetch_type = prop = zend_read_property(ce, object, ZEND_STRL("fetchType"), 0 TSRMLS_CC);
143 if (Z_TYPE_P(zfetch_type) != IS_LONG) {
144 convert_to_long_ex(&zfetch_type);
145 }
146 iter->fetch_type = Z_LVAL_P(zfetch_type);
147 if (zfetch_type != prop) {
148 zval_ptr_dtor(&zfetch_type);
149 }
150 if (Z_REFCOUNT_P(prop)) {
151 zval_ptr_dtor(&prop);
152 } else {
153 zval_dtor(prop);
154 FREE_ZVAL(prop);
155 }
156
157 return (zend_object_iterator *) iter;
158 }
159
160 static void php_pqres_iterator_dtor(zend_object_iterator *i TSRMLS_DC)
161 {
162 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
163
164 if (iter->current_val) {
165 zval_ptr_dtor(&iter->current_val);
166 iter->current_val = NULL;
167 }
168 zval_ptr_dtor((zval **) &iter->zi.data);
169 efree(iter);
170 }
171
172 static STATUS php_pqres_iterator_valid(zend_object_iterator *i TSRMLS_DC)
173 {
174 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
175 php_pqres_object_t *obj = zend_object_store_get_object(iter->zi.data TSRMLS_CC);
176
177 if (PQresultStatus(obj->res) != PGRES_TUPLES_OK) {
178 return FAILURE;
179 }
180 if (PQntuples(obj->res) <= iter->index) {
181 return FAILURE;
182 }
183
184 return SUCCESS;
185 }
186
187 static zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type TSRMLS_DC)
188 {
189 zval *data;
190 int c, cols;
191
192 MAKE_STD_ZVAL(data);
193 if (PHP_PQRES_FETCH_OBJECT == fetch_type) {
194 object_init(data);
195 } else {
196 array_init(data);
197 }
198
199 for (c = 0, cols = PQnfields(res); c < cols; ++c) {
200 if (PQgetisnull(res, row, c)) {
201 switch (fetch_type) {
202 case PHP_PQRES_FETCH_OBJECT:
203 add_property_null(data, PQfname(res, c));
204 break;
205
206 case PHP_PQRES_FETCH_ASSOC:
207 add_assoc_null(data, PQfname(res, c));
208 break;
209
210 case PHP_PQRES_FETCH_ARRAY:
211 add_index_null(data, c);
212 break;
213 }
214 } else {
215 char *val = PQgetvalue(res, row, c);
216 int len = PQgetlength(res, row, c);
217
218 switch (fetch_type) {
219 case PHP_PQRES_FETCH_OBJECT:
220 add_property_stringl(data, PQfname(res, c), val, len, 1);
221 break;
222
223 case PHP_PQRES_FETCH_ASSOC:
224 add_assoc_stringl(data, PQfname(res, c), val, len, 1);
225 break;
226
227 case PHP_PQRES_FETCH_ARRAY:
228 add_index_stringl(data, c, val, len ,1);
229 break;
230 }
231 }
232 }
233
234 return data;
235 }
236
237 static void php_pqres_iterator_current(zend_object_iterator *i, zval ***data_ptr TSRMLS_DC)
238 {
239 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
240 php_pqres_object_t *obj = zend_object_store_get_object(iter->zi.data TSRMLS_CC);
241
242 if (iter->current_val) {
243 zval_ptr_dtor(&iter->current_val);
244 }
245 iter->current_val = php_pqres_row_to_zval(obj->res, iter->index, iter->fetch_type TSRMLS_CC);
246 *data_ptr = &iter->current_val;
247 }
248
249 static int php_pqres_iterator_key(zend_object_iterator *i, char **key_str, uint *key_len, ulong *key_num TSRMLS_DC)
250 {
251 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
252
253 *key_num = (ulong) iter->index;
254
255 return HASH_KEY_IS_LONG;
256 }
257
258 static void php_pqres_iterator_next(zend_object_iterator *i TSRMLS_DC)
259 {
260 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
261
262 ++iter->index;
263 }
264
265 static void php_pqres_iterator_rewind(zend_object_iterator *i TSRMLS_DC)
266 {
267 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
268
269 iter->index = 0;
270 }
271
272 static zend_object_iterator_funcs php_pqres_iterator_funcs = {
273 php_pqres_iterator_dtor,
274 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
275 php_pqres_iterator_valid,
276 /* fetch the item data for the current element */
277 php_pqres_iterator_current,
278 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
279 php_pqres_iterator_key,
280 /* step forwards to next element */
281 php_pqres_iterator_next,
282 /* rewind to start of data (optional, may be NULL) */
283 php_pqres_iterator_rewind,
284 /* invalidate current value/key (optional, may be NULL) */
285 NULL
286 };
287
288 static void php_pqconn_object_free(void *o TSRMLS_DC)
289 {
290 php_pqconn_object_t *obj = o;
291
292 if (obj->conn) {
293 PQfinish(obj->conn);
294 obj->conn = NULL;
295 }
296 zend_object_std_dtor((zend_object *) o TSRMLS_CC);
297 efree(obj);
298 }
299
300 static void php_pqres_object_free(void *o TSRMLS_DC)
301 {
302 php_pqres_object_t *obj = o;
303
304 if (obj->res) {
305 PQclear(obj->res);
306 obj->res = NULL;
307 }
308 if (obj->iter) {
309 php_pqres_iterator_dtor((zend_object_iterator *) obj->iter TSRMLS_CC);
310 obj->iter = NULL;
311 }
312 zend_object_std_dtor((zend_object *) o TSRMLS_CC);
313 efree(obj);
314 }
315
316 static void php_pqstm_object_free(void *o TSRMLS_DC)
317 {
318 php_pqstm_object_t *obj = o;
319
320 if (obj->name) {
321 efree(obj->name);
322 obj->name = NULL;
323 }
324 if (obj->conn) {
325 zval_ptr_dtor(&obj->conn);
326 obj->conn = NULL;
327 }
328 zend_object_std_dtor((zend_object *) o TSRMLS_CC);
329 efree(obj);
330 }
331
332 static zend_object_value php_pqconn_create_object_ex(zend_class_entry *ce, PGconn *conn, php_pqconn_object_t **ptr TSRMLS_DC)
333 {
334 zend_object_value ov;
335 php_pqconn_object_t *o;
336
337 o = ecalloc(1, sizeof(*o));
338 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
339 object_properties_init((zend_object *) o, ce);
340
341 if (ptr) {
342 *ptr = o;
343 }
344
345 if (conn) {
346 o->conn = conn;
347 o->blocking = !PQisnonblocking(o->conn);
348 }
349
350 ov.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqconn_object_free, NULL TSRMLS_CC);
351 ov.handlers = &php_pqconn_object_handlers;
352
353 return ov;
354 }
355
356 static zend_object_value php_pqres_create_object_ex(zend_class_entry *ce, PGresult *res, php_pqres_object_t **ptr TSRMLS_DC)
357 {
358 zend_object_value ov;
359 php_pqres_object_t *o;
360
361 o = ecalloc(1, sizeof(*o));
362 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
363 object_properties_init((zend_object *) o, ce);
364
365 if (ptr) {
366 *ptr = o;
367 }
368
369 if (res) {
370 o->res = res;
371 }
372
373 ov.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqres_object_free, NULL TSRMLS_CC);
374 ov.handlers = &php_pqres_object_handlers;
375
376 return ov;
377 }
378
379 static zend_object_value php_pqstm_create_object_ex(zend_class_entry *ce, zval *conn, const char *name, php_pqstm_object_t **ptr TSRMLS_DC)
380 {
381 zend_object_value ov;
382 php_pqstm_object_t *o;
383
384 o = ecalloc(1, sizeof(*o));
385 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
386 object_properties_init((zend_object *) o, ce);
387
388 if (ptr) {
389 *ptr = o;
390 }
391
392 if (conn) {
393 Z_ADDREF_P(conn);
394 o->conn = conn;
395 }
396
397 if (name) {
398 o->name = estrdup(name);
399 }
400
401 ov.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqstm_object_free, NULL TSRMLS_CC);
402 ov.handlers = &php_pqstm_object_handlers;
403
404 return ov;
405 }
406
407 static zend_object_value php_pqconn_create_object(zend_class_entry *class_type TSRMLS_DC)
408 {
409 return php_pqconn_create_object_ex(class_type, NULL, NULL TSRMLS_CC);
410 }
411
412 static zend_object_value php_pqres_create_object(zend_class_entry *class_type TSRMLS_DC)
413 {
414 return php_pqres_create_object_ex(class_type, NULL, NULL TSRMLS_CC);
415 }
416
417 static zend_object_value php_pqstm_create_object(zend_class_entry *class_type TSRMLS_DC)
418 {
419 return php_pqstm_create_object_ex(class_type, NULL, NULL, NULL TSRMLS_CC);
420 }
421
422 static HashTable php_pqconn_object_prophandlers;
423 static HashTable php_pqres_object_prophandlers;
424 static HashTable php_pqstm_object_prophandlers;
425
426 typedef void (*php_pq_object_prophandler_func_t)(void *o, zval *return_value TSRMLS_DC);
427
428 typedef struct php_pq_object_prophandler {
429 php_pq_object_prophandler_func_t read;
430 php_pq_object_prophandler_func_t write;
431 } php_pq_object_prophandler_t;
432
433 static void php_pqconn_object_read_status(void *o, zval *return_value TSRMLS_DC)
434 {
435 php_pqconn_object_t *obj = o;
436
437 RETVAL_LONG(PQstatus(obj->conn));
438 }
439
440 static void php_pqconn_object_read_transaction_status(void *o, zval *return_value TSRMLS_DC)
441 {
442 php_pqconn_object_t *obj = o;
443
444 RETVAL_LONG(PQtransactionStatus(obj->conn));
445 }
446
447 static void php_pqconn_object_read_socket(void *o, zval *return_value TSRMLS_DC)
448 {
449 php_pqconn_object_t *obj = o;
450 php_stream *stream;
451 int socket = PQsocket(obj->conn);
452
453 if ((stream = php_stream_fopen_from_fd(socket, "r+b", NULL))) {
454 php_stream_to_zval(stream, return_value);
455 } else {
456 RETVAL_NULL();
457 }
458 }
459
460 static void php_pqconn_object_read_error_message(void *o, zval *return_value TSRMLS_DC)
461 {
462 php_pqconn_object_t *obj = o;
463 char *error = PQerrorMessage(obj->conn);
464
465 if (error) {
466 RETVAL_STRING(error, 1);
467 } else {
468 RETVAL_NULL();
469 }
470 }
471
472 /* FIXME: extend to types->nspname->typname */
473 #define PHP_PQ_TYPES_QUERY \
474 "select t.oid, t.* " \
475 "from pg_type t join pg_namespace n on t.typnamespace=n.oid " \
476 "where typisdefined " \
477 "and typrelid=0 " \
478 "and nspname in ('public', 'pg_catalog')"
479 static void php_pqconn_object_read_types(void *o, zval *return_value TSRMLS_DC)
480 {
481 php_pqconn_object_t *obj = o;
482 PGresult *res = PQexec(obj->conn, PHP_PQ_TYPES_QUERY);
483
484 /* FIXME: cache that */
485 if (res) {
486 if (PGRES_TUPLES_OK == PQresultStatus(res)) {
487 int r, rows;
488
489 object_init(return_value);
490 for (r = 0, rows = PQntuples(res); r < rows; ++r) {
491 zval *row = php_pqres_row_to_zval(res, r, PHP_PQRES_FETCH_OBJECT TSRMLS_CC);
492
493 add_property_zval(return_value, PQgetvalue(res, r, 1), row);
494 zval_ptr_dtor(&row);
495 }
496 } else {
497 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch types: %s", PQresultErrorMessage(res));
498 }
499 PQclear(res);
500 } else {
501 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch types: %s", PQerrorMessage(obj->conn));
502 }
503 }
504
505 static void php_pqres_object_read_status(void *o, zval *return_value TSRMLS_DC)
506 {
507 php_pqres_object_t *obj = o;
508
509 RETVAL_LONG(PQresultStatus(obj->res));
510 }
511
512 static void php_pqres_object_read_error_message(void *o, zval *return_value TSRMLS_DC)
513 {
514 php_pqres_object_t *obj = o;
515 char *error = PQresultErrorMessage(obj->res);
516
517 if (error) {
518 RETVAL_STRING(error, 1);
519 } else {
520 RETVAL_NULL();
521 }
522 }
523
524 static void php_pqres_object_read_num_rows(void *o, zval *return_value TSRMLS_DC)
525 {
526 php_pqres_object_t *obj = o;
527
528 RETVAL_LONG(PQntuples(obj->res));
529 }
530
531 static void php_pqres_object_read_num_cols(void *o, zval *return_value TSRMLS_DC)
532 {
533 php_pqres_object_t *obj = o;
534
535 RETVAL_LONG(PQnfields(obj->res));
536 }
537
538 static void php_pqres_object_read_affected_rows(void *o, zval *return_value TSRMLS_DC)
539 {
540 php_pqres_object_t *obj = o;
541
542 RETVAL_LONG(atoi(PQcmdTuples(obj->res)));
543 }
544
545 static void php_pqres_object_read_fetch_type(void *o, zval *return_value TSRMLS_DC)
546 {
547 php_pqres_object_t *obj = o;
548
549 if (obj->iter) {
550 RETVAL_LONG(obj->iter->fetch_type);
551 } else {
552 RETVAL_LONG(PHP_PQRES_FETCH_ARRAY);
553 }
554 }
555
556 static void php_pqres_object_write_fetch_type(void *o, zval *value TSRMLS_DC)
557 {
558 php_pqres_object_t *obj = o;
559 zval *zfetch_type = value;
560
561 if (Z_TYPE_P(zfetch_type) != IS_LONG) {
562 convert_to_long_ex(&zfetch_type);
563 }
564
565 obj->iter->fetch_type = Z_LVAL_P(zfetch_type);
566
567 if (zfetch_type != value) {
568 zval_ptr_dtor(&zfetch_type);
569 }
570 }
571
572 static void php_pqstm_object_read_name(void *o, zval *return_value TSRMLS_DC)
573 {
574 php_pqstm_object_t *obj = o;
575
576 RETVAL_STRING(obj->name, 1);
577 }
578
579 static void php_pqstm_object_read_connection(void *o, zval *return_value TSRMLS_DC)
580 {
581 php_pqstm_object_t *obj = o;
582
583 RETVAL_ZVAL(obj->conn, 1, 0);
584 }
585
586 static zval *php_pqconn_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
587 {
588 php_pqconn_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
589 php_pq_object_prophandler_t *handler;
590 zval *return_value;
591
592 if (!obj->conn) {
593 zend_error(E_WARNING, "Connection not initialized");
594 } else if (SUCCESS == zend_hash_find(&php_pqconn_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
595 if (type == BP_VAR_R) {
596 ALLOC_ZVAL(return_value);
597 Z_SET_REFCOUNT_P(return_value, 0);
598 Z_UNSET_ISREF_P(return_value);
599
600 handler->read(obj, return_value TSRMLS_CC);
601 } else {
602 zend_error(E_ERROR, "Cannot access pq\\Connection properties by reference or array key/index");
603 return_value = NULL;
604 }
605 } else {
606 return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC);
607 }
608
609 return return_value;
610 }
611
612 static void php_pqconn_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
613 {
614 php_pqconn_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
615 php_pq_object_prophandler_t *handler;
616
617 if (SUCCESS == zend_hash_find(&php_pqconn_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
618 if (handler->write) {
619 handler->write(obj, value TSRMLS_CC);
620 }
621 } else {
622 zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC);
623 }
624 }
625
626 static zval *php_pqres_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
627 {
628 php_pqres_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
629 php_pq_object_prophandler_t *handler;
630 zval *return_value;
631
632 if (!obj->res) {
633 zend_error(E_WARNING, "Result not initialized");
634 } else if (SUCCESS == zend_hash_find(&php_pqres_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
635 if (type == BP_VAR_R) {
636 ALLOC_ZVAL(return_value);
637 Z_SET_REFCOUNT_P(return_value, 0);
638 Z_UNSET_ISREF_P(return_value);
639
640 handler->read(obj, return_value TSRMLS_CC);
641 } else {
642 zend_error(E_ERROR, "Cannot access pq\\Result properties by reference or array key/index");
643 return_value = NULL;
644 }
645 } else {
646 return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC);
647 }
648
649 return return_value;
650 }
651
652 static void php_pqres_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
653 {
654 php_pqres_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
655 php_pq_object_prophandler_t *handler;
656
657 if (!obj->res) {
658 zend_error(E_WARNING, "Result not initialized");
659 } else if (SUCCESS == zend_hash_find(&php_pqres_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
660 if (handler->write) {
661 /* ensure obj->iter is initialized, for e.g. write_fetch_type */
662 if (!obj->iter) {
663 obj->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(object), object, 0 TSRMLS_CC);
664 obj->iter->zi.funcs->rewind((zend_object_iterator *) obj->iter TSRMLS_CC);
665 }
666 handler->write(obj, value TSRMLS_CC);
667 }
668 } else {
669 zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC);
670 }
671 }
672
673 static zval *php_pqstm_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
674 {
675 php_pqstm_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
676 php_pq_object_prophandler_t *handler;
677 zval *return_value;
678
679 if (!obj->conn) {
680 zend_error(E_WARNING, "Statement not initialized");
681 } else if (SUCCESS == zend_hash_find(&php_pqstm_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
682 if (type == BP_VAR_R) {
683 ALLOC_ZVAL(return_value);
684 Z_SET_REFCOUNT_P(return_value, 0);
685 Z_UNSET_ISREF_P(return_value);
686
687 handler->read(obj, return_value TSRMLS_CC);
688 } else {
689 zend_error(E_ERROR, "Cannot access pq\\Statement properties by reference or array key/index");
690 return_value = NULL;
691 }
692 } else {
693 return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC);
694 }
695
696 return return_value;
697 }
698
699 static void php_pqstm_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
700 {
701 php_pqstm_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
702 php_pq_object_prophandler_t *handler;
703
704 if (!obj->conn) {
705 zend_error(E_WARNING, "Result not initialized");
706 } else if (SUCCESS == zend_hash_find(&php_pqstm_object_prophandlers, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
707 if (handler->write) {
708 handler->write(obj, value TSRMLS_CC);
709 }
710 } else {
711 zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC);
712 }
713 }
714
715 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_construct, 0, 0, 1)
716 ZEND_ARG_INFO(0, dsn)
717 ZEND_ARG_INFO(0, block)
718 ZEND_END_ARG_INFO();
719 static PHP_METHOD(pqconn, __construct) {
720 zend_error_handling zeh;
721 char *dsn_str;
722 int dsn_len;
723 zend_bool block = 1;
724
725 zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
726 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &dsn_str, &dsn_len, &block)) {
727 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
728
729 if (obj->conn) {
730 PQfinish(obj->conn);
731 }
732 if ((obj->blocking = block)) {
733 obj->conn = PQconnectdb(dsn_str);
734 } else {
735 obj->conn = PQconnectStart(dsn_str);
736 obj->poller = (int (*)(PGconn*)) PQconnectPoll;
737 }
738
739 if (CONNECTION_BAD == PQstatus(obj->conn)) {
740 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection failed: %s", PQerrorMessage(obj->conn));
741 }
742 }
743 zend_restore_error_handling(&zeh TSRMLS_CC);
744 }
745
746 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_reset, 0, 0, 0)
747 ZEND_END_ARG_INFO();
748 static PHP_METHOD(pqconn, reset) {
749 if (SUCCESS == zend_parse_parameters_none()) {
750 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
751
752 if (obj->conn) {
753 if (obj->blocking) {
754 PQreset(obj->conn);
755 RETURN_TRUE; /* probably ;) */
756 } if (PQresetStart(obj->conn)) {
757 obj->poller = (int (*)(PGconn*)) PQresetPoll;
758 RETURN_TRUE;
759 }
760 } else {
761 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized");
762 }
763 RETURN_FALSE;
764 }
765 }
766
767 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_poll, 0, 0, 0)
768 ZEND_END_ARG_INFO();
769 static PHP_METHOD(pqconn, poll) {
770 if (SUCCESS == zend_parse_parameters_none()) {
771 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
772
773 if (obj->conn) {
774 if (obj->poller) {
775 RETURN_LONG(obj->poller(obj->conn));
776 } else {
777 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No asynchronous operation active");
778 }
779 } else {
780 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized");
781 }
782 RETURN_FALSE;
783 }
784 }
785
786 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec, 0, 0, 1)
787 ZEND_ARG_INFO(0, query)
788 ZEND_END_ARG_INFO();
789 static PHP_METHOD(pqconn, exec) {
790 zend_error_handling zeh;
791 char *query_str;
792 int query_len;
793
794 zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
795 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query_str, &query_len)) {
796 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
797
798 if (obj->conn) {
799 PGresult *res = PQexec(obj->conn, query_str);
800
801 if (res) {
802 return_value->type = IS_OBJECT;
803 return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, res, NULL TSRMLS_CC);
804 } else {
805 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute query: %s", PQerrorMessage(obj->conn));
806 }
807 } else {
808 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized");
809 }
810 }
811 zend_restore_error_handling(&zeh TSRMLS_CC);
812 }
813
814 static int apply_to_oid(void *p, void *arg TSRMLS_DC)
815 {
816 Oid **types = arg;
817 zval **ztype = p;
818
819 if (Z_TYPE_PP(ztype) != IS_LONG) {
820 convert_to_long_ex(ztype);
821 }
822
823 **types = Z_LVAL_PP(ztype);
824 ++*types;
825
826 if (*ztype != *(zval **)p) {
827 zval_ptr_dtor(ztype);
828 }
829 return ZEND_HASH_APPLY_KEEP;
830 }
831
832 static int apply_to_param(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
833 {
834 char ***params;
835 HashTable *zdtor;
836 zval **zparam = p;
837
838 params = (char ***) va_arg(argv, char ***);
839 zdtor = (HashTable *) va_arg(argv, HashTable *);
840
841 if (Z_TYPE_PP(zparam) == IS_NULL) {
842 **params = NULL;
843 ++*params;
844 } else {
845 if (Z_TYPE_PP(zparam) != IS_STRING) {
846 convert_to_string_ex(zparam);
847 }
848
849 **params = Z_STRVAL_PP(zparam);
850 ++*params;
851
852 if (*zparam != *(zval **)p) {
853 zend_hash_next_index_insert(zdtor, zparam, sizeof(zval *), NULL);
854 }
855 }
856 return ZEND_HASH_APPLY_KEEP;
857 }
858
859 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_exec_params, 0, 0, 2)
860 ZEND_ARG_INFO(0, query)
861 ZEND_ARG_ARRAY_INFO(0, params, 0)
862 ZEND_ARG_ARRAY_INFO(0, types, 1)
863 ZEND_END_ARG_INFO();
864 static PHP_METHOD(pqconn, execParams) {
865 zend_error_handling zeh;
866 char *query_str;
867 int query_len;
868 zval *zparams;
869 zval *ztypes = NULL;
870
871 zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
872 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/|a/!", &query_str, &query_len, &zparams, &ztypes)) {
873 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
874
875 if (obj->conn) {
876 PGresult *res;
877 int count = 0;
878 Oid *types = NULL;
879 char **params = NULL;
880 HashTable zdtor;
881
882 ZEND_INIT_SYMTABLE(&zdtor);
883
884 if (ztypes && zend_hash_num_elements(Z_ARRVAL_P(ztypes))) {
885 Oid *tmp;
886
887 tmp = types = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(ztypes)), sizeof(Oid));
888 zend_hash_apply_with_argument(Z_ARRVAL_P(ztypes), apply_to_oid, &tmp TSRMLS_CC);
889 }
890 if ((count = zend_hash_num_elements(Z_ARRVAL_P(zparams)))) {
891 char **tmp;
892
893 tmp = params = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(zparams)), sizeof(char *));
894 zend_hash_apply_with_arguments(Z_ARRVAL_P(zparams) TSRMLS_CC, apply_to_param, 2, &tmp, &zdtor);
895 }
896
897 res = PQexecParams(obj->conn, query_str, count, types, params, NULL, NULL, 0);
898
899 zend_hash_destroy(&zdtor);
900 if (types) {
901 efree(types);
902 }
903 if (params) {
904 efree(params);
905 }
906
907 if (res) {
908 return_value->type = IS_OBJECT;
909 return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, res, NULL TSRMLS_CC);
910 } else {
911 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute query: %s", PQerrorMessage(obj->conn));
912 }
913 } else {
914 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized");
915 }
916 }
917 zend_restore_error_handling(&zeh TSRMLS_CC);
918 }
919
920 static STATUS php_pqconn_prepare(PGconn *conn, const char *name, const char *query, HashTable *typest TSRMLS_DC)
921 {
922 Oid *types = NULL;
923 int count = 0;
924 PGresult *res;
925
926 if (typest && (count = zend_hash_num_elements(typest))) {
927 Oid *tmp;
928
929 tmp = types = ecalloc(count, sizeof(Oid));
930 zend_hash_apply_with_argument(typest, apply_to_oid, &tmp TSRMLS_CC);
931 }
932
933 res = PQprepare(conn, name, query, count, types);
934
935 if (types) {
936 efree(types);
937 }
938
939 if (res) {
940 if (PGRES_COMMAND_OK == PQresultStatus(res)) {
941 return SUCCESS;
942 } else {
943 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not prepare statement: %s", PQresultErrorMessage(res));
944 }
945 PQclear(res);
946 } else {
947 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not prepare statement: %s", PQerrorMessage(conn));
948 }
949 return FAILURE;
950 }
951
952 ZEND_BEGIN_ARG_INFO_EX(ai_pqconn_prepare, 0, 0, 2)
953 ZEND_ARG_INFO(0, "name")
954 ZEND_ARG_INFO(0, "query")
955 ZEND_ARG_ARRAY_INFO(0, "types", 1)
956 ZEND_END_ARG_INFO();
957 static PHP_METHOD(pqconn, prepare) {
958 zend_error_handling zeh;
959 zval *ztypes = NULL;
960 char *name_str, *query_str;
961 int name_len, *query_len;
962
963 zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
964 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a/!", &name_str, &name_len, &query_str, &query_len, &ztypes)) {
965 php_pqconn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
966
967 if (obj->conn) {
968 if (SUCCESS == php_pqconn_prepare(obj->conn, name_str, query_str, ztypes ? Z_ARRVAL_P(ztypes) : NULL TSRMLS_CC)) {
969 return_value->type = IS_OBJECT;
970 return_value->value.obj = php_pqstm_create_object_ex(php_pqstm_class_entry, getThis(), name_str, NULL TSRMLS_CC);
971 }
972 } else {
973 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized");
974 }
975 }
976 }
977
978 static zend_function_entry php_pqconn_methods[] = {
979 PHP_ME(pqconn, __construct, ai_pqconn_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
980 PHP_ME(pqconn, reset, ai_pqconn_reset, ZEND_ACC_PUBLIC)
981 PHP_ME(pqconn, poll, ai_pqconn_poll, ZEND_ACC_PUBLIC)
982 PHP_ME(pqconn, exec, ai_pqconn_exec, ZEND_ACC_PUBLIC)
983 PHP_ME(pqconn, execParams, ai_pqconn_exec_params, ZEND_ACC_PUBLIC)
984 PHP_ME(pqconn, prepare, ai_pqconn_prepare, ZEND_ACC_PUBLIC)
985 {0}
986 };
987
988 static zval **php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type TSRMLS_DC)
989 {
990 zval **row = NULL;
991 php_pqres_fetch_t orig_fetch;
992
993 if (!obj) {
994 obj = zend_object_store_get_object(getThis() TSRMLS_CC);
995 }
996
997 if (!obj->iter) {
998 obj->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC);
999 obj->iter->zi.funcs->rewind((zend_object_iterator *) obj->iter TSRMLS_CC);
1000 }
1001 orig_fetch = obj->iter->fetch_type;
1002 obj->iter->fetch_type = fetch_type;
1003 if (SUCCESS == obj->iter->zi.funcs->valid((zend_object_iterator *) obj->iter TSRMLS_CC)) {
1004 obj->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->iter, &row TSRMLS_CC);
1005 obj->iter->zi.funcs->move_forward((zend_object_iterator *) obj->iter TSRMLS_CC);
1006 }
1007 obj->iter->fetch_type = orig_fetch;
1008
1009 return row ? row : NULL;
1010 }
1011
1012 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch, 0, 0, 0)
1013 ZEND_ARG_INFO(0, fetch_type)
1014 ZEND_END_ARG_INFO();
1015 static PHP_METHOD(pqres, fetchRow) {
1016 zend_error_handling zeh;
1017 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1018 long fetch_type = obj->iter ? obj->iter->fetch_type : PHP_PQRES_FETCH_ARRAY;
1019
1020 zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
1021 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type)) {
1022 zval **row = php_pqres_iteration(getThis(), obj, fetch_type TSRMLS_CC);
1023
1024 if (row) {
1025 RETVAL_ZVAL(*row, 1, 0);
1026 } else {
1027 RETVAL_FALSE;
1028 }
1029 }
1030 zend_restore_error_handling(&zeh TSRMLS_CC);
1031 }
1032
1033 static zend_function_entry php_pqres_methods[] = {
1034 PHP_ME(pqres, fetchRow, ai_pqres_fetch, ZEND_ACC_PUBLIC)
1035 {0}
1036 };
1037
1038 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_construct, 0, 0, 3)
1039 ZEND_ARG_OBJ_INFO(0, "Connection", "pq\\Connection", 0)
1040 ZEND_ARG_INFO(0, "name")
1041 ZEND_ARG_INFO(0, "query")
1042 ZEND_ARG_ARRAY_INFO(0, "types", 1)
1043 ZEND_END_ARG_INFO();
1044 static PHP_METHOD(pqstm, __construct) {
1045 zend_error_handling zeh;
1046 zval *zconn, *ztypes = NULL;
1047 char *name_str, *query_str;
1048 int name_len, *query_len;
1049
1050 zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
1051 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oss|a/!", &zconn, php_pqconn_class_entry, &name_str, &name_len, &query_str, &query_len, &ztypes)) {
1052 php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1053 php_pqconn_object_t *conn_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1054
1055 if (conn_obj->conn) {
1056 if (SUCCESS == php_pqconn_prepare(conn_obj->conn, name_str, query_str, ztypes ? Z_ARRVAL_P(ztypes) : NULL TSRMLS_CC)) {
1057 Z_ADDREF_P(zconn);
1058 obj->conn = zconn;
1059 obj->name = estrdup(name_str);
1060 }
1061 } else {
1062 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized");
1063 }
1064 }
1065 }
1066
1067 ZEND_BEGIN_ARG_INFO_EX(ai_pqstm_exec, 0, 0, 0)
1068 ZEND_ARG_ARRAY_INFO(0, "params", 1)
1069 ZEND_END_ARG_INFO();
1070 static PHP_METHOD(pqstm, exec) {
1071 zend_error_handling zeh;
1072 zval *zparams = NULL;
1073
1074 zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
1075 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a/!", &zparams)) {
1076 php_pqstm_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1077
1078 if (obj->conn && obj->name) {
1079 php_pqconn_object_t *conn_obj = zend_object_store_get_object(obj->conn TSRMLS_CC);
1080
1081 if (conn_obj->conn) {
1082 int count = 0;
1083 char **params = NULL;
1084 HashTable zdtor;
1085 PGresult *res;
1086
1087 ZEND_INIT_SYMTABLE(&zdtor);
1088
1089 if (zparams && (count = zend_hash_num_elements(Z_ARRVAL_P(zparams)))) {
1090 char **tmp;
1091
1092 tmp = params = ecalloc(count, sizeof(char *));
1093 zend_hash_apply_with_arguments(Z_ARRVAL_P(zparams) TSRMLS_CC, apply_to_param, 2, &tmp, &zdtor);
1094 }
1095
1096 res = PQexecPrepared(conn_obj->conn, obj->name, count, params, NULL, NULL, 0);
1097
1098 if (params) {
1099 efree(params);
1100 }
1101 zend_hash_destroy(&zdtor);
1102
1103 if (res) {
1104 return_value->type = IS_OBJECT;
1105 return_value->value.obj = php_pqres_create_object_ex(php_pqres_class_entry, res, NULL TSRMLS_CC);
1106 } else {
1107 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute statement: %s", PQerrorMessage(conn_obj->conn));
1108 }
1109 } else {
1110 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not initialized");
1111 }
1112 } else {
1113 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Statement not initialized");
1114 }
1115 }
1116 zend_restore_error_handling(&zeh TSRMLS_CC);
1117 }
1118
1119 static zend_function_entry php_pqstm_methods[] = {
1120 PHP_ME(pqstm, __construct, ai_pqstm_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
1121 PHP_ME(pqstm, exec, ai_pqstm_exec, ZEND_ACC_PUBLIC)
1122 {0}
1123 };
1124
1125 /* {{{ PHP_MINIT_FUNCTION
1126 */
1127 PHP_MINIT_FUNCTION(pq)
1128 {
1129 zend_class_entry ce = {0};
1130 php_pq_object_prophandler_t ph = {0};
1131
1132 zend_hash_init(&php_pqconn_object_prophandlers, 1, NULL, NULL, 1);
1133 INIT_NS_CLASS_ENTRY(ce, "pq", "Connection", php_pqconn_methods);
1134 php_pqconn_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
1135 php_pqconn_class_entry->create_object = php_pqconn_create_object;
1136 memcpy(&php_pqconn_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1137 php_pqconn_object_handlers.read_property = php_pqconn_object_read_prop;
1138 php_pqconn_object_handlers.write_property = php_pqconn_object_write_prop;
1139
1140 zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("status"), CONNECTION_BAD, ZEND_ACC_PUBLIC TSRMLS_CC);
1141 ph.read = php_pqconn_object_read_status;
1142 zend_hash_add(&php_pqconn_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL);
1143
1144 zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("transactionStatus"), PQTRANS_UNKNOWN, ZEND_ACC_PUBLIC TSRMLS_CC);
1145 ph.read = php_pqconn_object_read_transaction_status;
1146 zend_hash_add(&php_pqconn_object_prophandlers, "transactionStatus", sizeof("transactionStatus"), (void *) &ph, sizeof(ph), NULL);
1147
1148 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("socket"), ZEND_ACC_PUBLIC TSRMLS_CC);
1149 ph.read = php_pqconn_object_read_socket;
1150 zend_hash_add(&php_pqconn_object_prophandlers, "socket", sizeof("socket"), (void *) &ph, sizeof(ph), NULL);
1151
1152 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC);
1153 ph.read = php_pqconn_object_read_error_message;
1154 zend_hash_add(&php_pqconn_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL);
1155
1156 zend_declare_property_null(php_pqconn_class_entry, ZEND_STRL("types"), ZEND_ACC_PUBLIC TSRMLS_CC);
1157 ph.read = php_pqconn_object_read_types;
1158 zend_hash_add(&php_pqconn_object_prophandlers, "types", sizeof("types"), (void *) &ph, sizeof(ph), NULL);
1159
1160 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC);
1161 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC);
1162 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC);
1163 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("MADE"), CONNECTION_MADE TSRMLS_CC);
1164 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AWAITING_RESPONSE"), CONNECTION_AWAITING_RESPONSE TSRMLS_CC);
1165 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("AUTH_OK"), CONNECTION_AUTH_OK TSRMLS_CC);
1166 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SSL_STARTUP"), CONNECTION_SSL_STARTUP TSRMLS_CC);
1167 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("SETENV"), CONNECTION_SETENV TSRMLS_CC);
1168
1169 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_IDLE"), PQTRANS_IDLE TSRMLS_CC);
1170 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_ACTIVE"), PQTRANS_ACTIVE TSRMLS_CC);
1171 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INTRANS"), PQTRANS_INTRANS TSRMLS_CC);
1172 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_INERROR"), PQTRANS_INERROR TSRMLS_CC);
1173 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("TRANS_UNKNOWN"), PQTRANS_UNKNOWN TSRMLS_CC);
1174
1175 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_FAILED"), PGRES_POLLING_FAILED TSRMLS_CC);
1176 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_READING"), PGRES_POLLING_READING TSRMLS_CC);
1177 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_WRITING"), PGRES_POLLING_WRITING TSRMLS_CC);
1178 zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("POLLING_OK"), PGRES_POLLING_OK TSRMLS_CC);
1179
1180 zend_hash_init(&php_pqres_object_prophandlers, 1, NULL, NULL, 1);
1181 memset(&ce, 0, sizeof(ce));
1182 INIT_NS_CLASS_ENTRY(ce, "pq", "Result", php_pqres_methods);
1183 php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
1184 php_pqres_class_entry->create_object = php_pqres_create_object;
1185 php_pqres_class_entry->iterator_funcs.funcs = &php_pqres_iterator_funcs;
1186 php_pqres_class_entry->get_iterator = php_pqres_iterator_init;
1187
1188 memcpy(&php_pqres_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1189 php_pqres_object_handlers.read_property = php_pqres_object_read_prop;
1190 php_pqres_object_handlers.write_property = php_pqres_object_write_prop;
1191
1192 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC);
1193 ph.read = php_pqres_object_read_status;
1194 zend_hash_add(&php_pqres_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL);
1195
1196 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC);
1197 ph.read = php_pqres_object_read_error_message;
1198 zend_hash_add(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL);
1199
1200 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1201 ph.read = php_pqres_object_read_num_rows;
1202 zend_hash_add(&php_pqres_object_prophandlers, "numRows", sizeof("numRows"), (void *) &ph, sizeof(ph), NULL);
1203
1204 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1205 ph.read = php_pqres_object_read_num_cols;
1206 zend_hash_add(&php_pqres_object_prophandlers, "numCols", sizeof("numCols"), (void *) &ph, sizeof(ph), NULL);
1207
1208 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1209 ph.read = php_pqres_object_read_affected_rows;
1210 zend_hash_add(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows"), (void *) &ph, sizeof(ph), NULL);
1211
1212 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC TSRMLS_CC);
1213 ph.read = php_pqres_object_read_fetch_type;
1214 ph.write = php_pqres_object_write_fetch_type;
1215 zend_hash_add(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType"), (void *) &ph, sizeof(ph), NULL);
1216 ph.write = NULL;
1217
1218 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC);
1219 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC);
1220 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC);
1221 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC);
1222 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC);
1223 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC);
1224 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC);
1225 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC);
1226 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC);
1227 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC);
1228
1229 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC);
1230 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC);
1231 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC);
1232
1233 zend_hash_init(&php_pqstm_object_prophandlers, 1, NULL, NULL, 1);
1234 memset(&ce, 0, sizeof(ce));
1235 INIT_NS_CLASS_ENTRY(ce, "pq", "Statement", php_pqstm_methods);
1236 php_pqstm_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
1237 php_pqstm_class_entry->create_object = php_pqstm_create_object;
1238
1239 memcpy(&php_pqstm_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1240 php_pqstm_object_handlers.read_property = php_pqstm_object_read_prop;
1241 php_pqstm_object_handlers.write_property = php_pqstm_object_write_prop;
1242
1243 zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("name"), ZEND_ACC_PUBLIC TSRMLS_CC);
1244 ph.read = php_pqstm_object_read_name;
1245 zend_hash_add(&php_pqstm_object_prophandlers, "name", sizeof("name"), (void *) &ph, sizeof(ph), NULL);
1246
1247 zend_declare_property_null(php_pqstm_class_entry, ZEND_STRL("connection"), ZEND_ACC_PUBLIC TSRMLS_CC);
1248 ph.read = php_pqstm_object_read_connection;
1249 zend_hash_add(&php_pqstm_object_prophandlers, "connection", sizeof("connection"), (void *) &ph, sizeof(ph), NULL);
1250
1251 /*
1252 REGISTER_INI_ENTRIES();
1253 */
1254 return SUCCESS;
1255 }
1256 /* }}} */
1257
1258 /* {{{ PHP_MSHUTDOWN_FUNCTION
1259 */
1260 PHP_MSHUTDOWN_FUNCTION(pq)
1261 {
1262 /* uncomment this line if you have INI entries
1263 UNREGISTER_INI_ENTRIES();
1264 */
1265 return SUCCESS;
1266 }
1267 /* }}} */
1268
1269 /* {{{ PHP_MINFO_FUNCTION
1270 */
1271 PHP_MINFO_FUNCTION(pq)
1272 {
1273 php_info_print_table_start();
1274 php_info_print_table_header(2, "pq support", "enabled");
1275 php_info_print_table_end();
1276
1277 /* Remove comments if you have entries in php.ini
1278 DISPLAY_INI_ENTRIES();
1279 */
1280 }
1281 /* }}} */
1282
1283
1284
1285 /*
1286 * Local variables:
1287 * tab-width: 4
1288 * c-basic-offset: 4
1289 * End:
1290 * vim600: noet sw=4 ts=4 fdm=marker
1291 * vim<600: noet sw=4 ts=4
1292 */