d629d251188de57db55ca588bb158bf025388a9d
[m6w6/ext-pq] / src / php_pqres.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 #include <ext/spl/spl_iterators.h>
20 #include <ext/json/php_json.h>
21 #include <libpq-events.h>
22
23 #include "php_pq.h"
24 #include "php_pq_misc.h"
25 #include "php_pq_object.h"
26 #include "php_pqexc.h"
27 #include "php_pqres.h"
28 #undef PHP_PQ_TYPE
29 #include "php_pq_type.h"
30
31 zend_class_entry *php_pqres_class_entry;
32 static zend_object_handlers php_pqres_object_handlers;
33 static HashTable php_pqres_object_prophandlers;
34 static zend_object_iterator_funcs php_pqres_iterator_funcs;
35
36 static zend_object_iterator *php_pqres_iterator_init(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
37 {
38 php_pqres_iterator_t *iter;
39 zval *prop, *zfetch_type;
40
41 iter = ecalloc(1, sizeof(*iter));
42 iter->zi.funcs = &php_pqres_iterator_funcs;
43 iter->zi.data = object;
44 /* do not addref, because the iterator lives inside this object anyway */
45
46 zfetch_type = prop = zend_read_property(ce, object, ZEND_STRL("fetchType"), 0 TSRMLS_CC);
47 if (Z_TYPE_P(zfetch_type) != IS_LONG) {
48 convert_to_long_ex(&zfetch_type);
49 }
50 iter->fetch_type = Z_LVAL_P(zfetch_type);
51 if (zfetch_type != prop) {
52 zval_ptr_dtor(&zfetch_type);
53 }
54 if (Z_REFCOUNT_P(prop)) {
55 zval_ptr_dtor(&prop);
56 } else {
57 zval_dtor(prop);
58 FREE_ZVAL(prop);
59 }
60
61 return (zend_object_iterator *) iter;
62 }
63
64 static void php_pqres_iterator_dtor(zend_object_iterator *i TSRMLS_DC)
65 {
66 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
67
68 if (iter->current_val) {
69 zval_ptr_dtor(&iter->current_val);
70 iter->current_val = NULL;
71 }
72 efree(iter);
73 }
74
75 static STATUS php_pqres_iterator_valid(zend_object_iterator *i TSRMLS_DC)
76 {
77 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
78 php_pqres_object_t *obj = zend_object_store_get_object(iter->zi.data TSRMLS_CC);
79
80 switch (PQresultStatus(obj->intern->res)) {
81 case PGRES_TUPLES_OK:
82 case PGRES_SINGLE_TUPLE:
83 if (PQntuples(obj->intern->res) <= iter->index) {
84 return FAILURE;
85 }
86 break;
87 default:
88 return FAILURE;
89 }
90
91 return SUCCESS;
92 }
93
94 zval *php_pqres_typed_zval(php_pqres_t *res, char *val, size_t len, Oid typ TSRMLS_DC)
95 {
96 zval *zv, **zconv;
97
98 MAKE_STD_ZVAL(zv);
99
100 if (SUCCESS == zend_hash_index_find(&res->converters, typ, (void *) &zconv)) {
101 zval *ztype, *tmp = NULL;
102
103 MAKE_STD_ZVAL(ztype);
104 ZVAL_LONG(ztype, typ);
105 ZVAL_STRINGL(zv, val, len, 1);
106 zend_call_method_with_2_params(zconv, NULL, NULL, "convertfromstring", &tmp, zv, ztype);
107 zval_ptr_dtor(&ztype);
108
109 if (tmp) {
110 zval_ptr_dtor(&zv);
111 zv = tmp;
112 }
113
114 return zv;
115 }
116
117 switch (typ) {
118 case PHP_PQ_OID_BOOL:
119 if (!(res->auto_convert & PHP_PQRES_CONV_BOOL)) {
120 goto noconversion;
121 }
122 ZVAL_BOOL(zv, *val == 't');
123 break;
124 #if SIZEOF_LONG >= 8
125 case PHP_PQ_OID_INT8:
126 case PHP_PQ_OID_TID:
127 #endif
128 case PHP_PQ_OID_INT4:
129 case PHP_PQ_OID_INT2:
130 case PHP_PQ_OID_XID:
131 case PHP_PQ_OID_OID:
132 if (!(res->auto_convert & PHP_PQRES_CONV_INT)) {
133 goto noconversion;
134 }
135 ZVAL_LONG(zv, zend_atol(val, len));
136 break;
137
138 case PHP_PQ_OID_FLOAT4:
139 case PHP_PQ_OID_FLOAT8:
140 if (!(res->auto_convert & PHP_PQRES_CONV_FLOAT)) {
141 goto noconversion;
142 }
143 ZVAL_DOUBLE(zv, zend_strtod(val, NULL));
144 break;
145
146 case PHP_PQ_OID_DATE:
147 if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
148 goto noconversion;
149 }
150 php_pqdt_from_string(val, len, "Y-m-d", zv TSRMLS_CC);
151 break;
152
153 case PHP_PQ_OID_ABSTIME:
154 if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
155 goto noconversion;
156 }
157 php_pqdt_from_string(val, len, "Y-m-d H:i:s", zv TSRMLS_CC);
158 break;
159
160 case PHP_PQ_OID_TIMESTAMP:
161 if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
162 goto noconversion;
163 }
164 php_pqdt_from_string(val, len, "Y-m-d H:i:s.u", zv TSRMLS_CC);
165 break;
166
167 case PHP_PQ_OID_TIMESTAMPTZ:
168 if (!(res->auto_convert & PHP_PQRES_CONV_DATETIME)) {
169 goto noconversion;
170 }
171 php_pqdt_from_string(val, len, "Y-m-d H:i:s.uO", zv TSRMLS_CC);
172 break;
173
174 #ifdef PHP_PQ_OID_JSON
175 # ifdef PHP_PQ_OID_JSONB
176 case PHP_PQ_OID_JSONB:
177 # endif
178 case PHP_PQ_OID_JSON:
179 if (!(res->auto_convert & PHP_PQRES_CONV_JSON)) {
180 goto noconversion;
181 }
182 php_json_decode_ex(zv, val, len, 0, 512 /* PHP_JSON_DEFAULT_DEPTH */ TSRMLS_CC);
183 break;
184 #endif
185
186 default:
187 if (!(res->auto_convert & PHP_PQRES_CONV_ARRAY)) {
188 goto noconversion;
189 }
190 if (PHP_PQ_TYPE_IS_ARRAY(typ) && (Z_ARRVAL_P(zv) = php_pq_parse_array(res, val, len, PHP_PQ_TYPE_OF_ARRAY(typ) TSRMLS_CC))) {
191 Z_TYPE_P(zv) = IS_ARRAY;
192 } else {
193 noconversion:
194 ZVAL_STRINGL(zv, val, len, 1);
195 }
196 break;
197 }
198
199 return zv;
200 }
201
202 static inline zval *php_pqres_get_col(php_pqres_t *r, unsigned row, unsigned col TSRMLS_DC)
203 {
204 zval *zv;
205
206 if (PQgetisnull(r->res, row, col)) {
207 MAKE_STD_ZVAL(zv);
208 ZVAL_NULL(zv);
209 } else {
210 zv = php_pqres_typed_zval(r, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col), PQftype(r->res, col) TSRMLS_CC);
211 }
212
213 return zv;
214 }
215
216 static inline void php_pqres_add_col_to_zval(php_pqres_t *r, unsigned row, unsigned col, php_pqres_fetch_t fetch_type, zval *data TSRMLS_DC)
217 {
218 if (PQgetisnull(r->res, row, col)) {
219 switch (fetch_type) {
220 case PHP_PQRES_FETCH_OBJECT:
221 add_property_null(data, PQfname(r->res, col));
222 break;
223
224 case PHP_PQRES_FETCH_ASSOC:
225 add_assoc_null(data, PQfname(r->res, col));
226 break;
227
228 case PHP_PQRES_FETCH_ARRAY:
229 add_index_null(data, col);
230 break;
231 }
232 } else {
233 zval *zv;
234
235 zv = php_pqres_typed_zval(r, PQgetvalue(r->res, row, col), PQgetlength(r->res, row, col), PQftype(r->res, col) TSRMLS_CC);
236
237 switch (fetch_type) {
238 case PHP_PQRES_FETCH_OBJECT:
239 add_property_zval(data, PQfname(r->res, col), zv);
240 zval_ptr_dtor(&zv);
241 break;
242
243 case PHP_PQRES_FETCH_ASSOC:
244 add_assoc_zval(data, PQfname(r->res, col), zv);
245 break;
246
247 case PHP_PQRES_FETCH_ARRAY:
248 add_index_zval(data, col, zv);
249 break;
250 }
251 }
252 }
253
254 zval *php_pqres_row_to_zval(PGresult *res, unsigned row, php_pqres_fetch_t fetch_type, zval **data_ptr TSRMLS_DC)
255 {
256 zval *data = NULL;
257 int c, cols;
258 php_pqres_object_t *res_obj = PQresultInstanceData(res, php_pqconn_event);
259
260 if (data_ptr) {
261 data = *data_ptr;
262 }
263 if (!data) {
264 MAKE_STD_ZVAL(data);
265 if (PHP_PQRES_FETCH_OBJECT == fetch_type) {
266 object_init(data);
267 } else {
268 array_init(data);
269 }
270 if (data_ptr) {
271 *data_ptr = data;
272 }
273 }
274
275 if (PQntuples(res) > row) {
276 for (c = 0, cols = PQnfields(res); c < cols; ++c) {
277 php_pqres_add_col_to_zval(res_obj->intern, row, c, fetch_type, data TSRMLS_CC);
278 }
279 }
280
281 return data;
282 }
283
284 static void php_pqres_iterator_current(zend_object_iterator *i, zval ***data_ptr TSRMLS_DC)
285 {
286 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
287 php_pqres_object_t *obj = zend_object_store_get_object(iter->zi.data TSRMLS_CC);
288
289 if (!iter->current_val) {
290 iter->current_val = php_pqres_row_to_zval(obj->intern->res, iter->index, iter->fetch_type, NULL TSRMLS_CC);
291 }
292 *data_ptr = &iter->current_val;
293 }
294
295 #if PHP_VERSION_ID >= 50500
296 static void php_pqres_iterator_key(zend_object_iterator *i, zval *key TSRMLS_DC)
297 {
298 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
299
300 ZVAL_LONG(key, iter->index);
301 }
302 #else
303 static int php_pqres_iterator_key(zend_object_iterator *i, char **key_str, uint *key_len, ulong *key_num TSRMLS_DC)
304 {
305 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
306
307 *key_num = (ulong) iter->index;
308
309 return HASH_KEY_IS_LONG;
310 }
311 #endif
312
313 static void php_pqres_iterator_invalidate(zend_object_iterator *i TSRMLS_DC)
314 {
315 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
316
317 if (iter->current_val) {
318 zval_ptr_dtor(&iter->current_val);
319 iter->current_val = NULL;
320 }
321 }
322
323 static void php_pqres_iterator_next(zend_object_iterator *i TSRMLS_DC)
324 {
325 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
326
327 php_pqres_iterator_invalidate(i TSRMLS_CC);
328 ++iter->index;
329 }
330
331 static void php_pqres_iterator_rewind(zend_object_iterator *i TSRMLS_DC)
332 {
333 php_pqres_iterator_t *iter = (php_pqres_iterator_t *) i;
334
335 php_pqres_iterator_invalidate(i TSRMLS_CC);
336 iter->index = 0;
337 }
338
339 static zend_object_iterator_funcs php_pqres_iterator_funcs = {
340 php_pqres_iterator_dtor,
341 /* check for end of iteration (FAILURE or SUCCESS if data is valid) */
342 php_pqres_iterator_valid,
343 /* fetch the item data for the current element */
344 php_pqres_iterator_current,
345 /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
346 php_pqres_iterator_key,
347 /* step forwards to next element */
348 php_pqres_iterator_next,
349 /* rewind to start of data (optional, may be NULL) */
350 php_pqres_iterator_rewind,
351 /* invalidate current value/key (optional, may be NULL) */
352 php_pqres_iterator_invalidate
353 };
354
355 static int php_pqres_count_elements(zval *object, long *count TSRMLS_DC)
356 {
357 php_pqres_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
358
359 if (!obj->intern) {
360 return FAILURE;
361 } else {
362 *count = (long) PQntuples(obj->intern->res);
363 return SUCCESS;
364 }
365 }
366
367 STATUS php_pqres_success(PGresult *res TSRMLS_DC)
368 {
369 zval *zexc;
370
371 switch (PQresultStatus(res)) {
372 case PGRES_BAD_RESPONSE:
373 case PGRES_NONFATAL_ERROR:
374 case PGRES_FATAL_ERROR:
375 zexc = throw_exce(EX_SQL TSRMLS_CC, "%s", PHP_PQresultErrorMessage(res));
376 zend_update_property_string(Z_OBJCE_P(zexc), zexc, ZEND_STRL("sqlstate"), PQresultErrorField(res, PG_DIAG_SQLSTATE) TSRMLS_CC);
377 return FAILURE;
378 default:
379 return SUCCESS;
380 }
381 }
382
383 void php_pqres_init_instance_data(PGresult *res, php_pqconn_object_t *conn_obj, php_pqres_object_t **ptr TSRMLS_DC)
384 {
385 php_pqres_object_t *obj;
386 php_pqres_t *r = ecalloc(1, sizeof(*r));
387
388 r->res = res;
389 zend_hash_init(&r->bound, 0, 0, ZVAL_PTR_DTOR, 0);
390 zend_hash_init(&r->converters, 0, 0, ZVAL_PTR_DTOR, 0);
391 zend_hash_copy(&r->converters, &conn_obj->intern->converters, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
392
393 r->auto_convert = conn_obj->intern->default_auto_convert;
394 r->default_fetch_type = conn_obj->intern->default_fetch_type;
395
396 php_pqres_create_object_ex(php_pqres_class_entry, r, &obj TSRMLS_CC);
397 PQresultSetInstanceData(res, php_pqconn_event, obj);
398
399 if (ptr) {
400 *ptr = obj;
401 }
402 }
403
404 static void php_pqres_object_free(void *o TSRMLS_DC)
405 {
406 php_pqres_object_t *obj = o;
407 #if DBG_GC
408 fprintf(stderr, "FREE res(#%d) %p\n", obj->zv.handle, obj);
409 #endif
410 if (obj->intern) {
411 if (obj->intern->res) {
412 PQresultSetInstanceData(obj->intern->res, php_pqconn_event, NULL);
413 PQclear(obj->intern->res);
414 obj->intern->res = NULL;
415 }
416
417 if (obj->intern->iter) {
418 php_pqres_iterator_dtor((zend_object_iterator *) obj->intern->iter TSRMLS_CC);
419 obj->intern->iter = NULL;
420 }
421
422 zend_hash_destroy(&obj->intern->bound);
423 zend_hash_destroy(&obj->intern->converters);
424
425 efree(obj->intern);
426 obj->intern = NULL;
427 }
428 zend_object_std_dtor((zend_object *) o TSRMLS_CC);
429 efree(obj);
430 }
431
432 zend_object_value php_pqres_create_object_ex(zend_class_entry *ce, php_pqres_t *intern, php_pqres_object_t **ptr TSRMLS_DC)
433 {
434 php_pqres_object_t *o;
435
436 o = ecalloc(1, sizeof(*o));
437 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
438 object_properties_init((zend_object *) o, ce);
439 o->prophandler = &php_pqres_object_prophandlers;
440
441 if (ptr) {
442 *ptr = o;
443 }
444
445 if (intern) {
446 o->intern = intern;
447 }
448
449 o->zv.handle = zend_objects_store_put((zend_object *) o, NULL, php_pqres_object_free, NULL TSRMLS_CC);
450 o->zv.handlers = &php_pqres_object_handlers;
451
452 return o->zv;
453 }
454
455 static zend_object_value php_pqres_create_object(zend_class_entry *class_type TSRMLS_DC)
456 {
457 return php_pqres_create_object_ex(class_type, NULL, NULL TSRMLS_CC);
458 }
459
460 static void php_pqres_object_read_status(zval *object, void *o, zval *return_value TSRMLS_DC)
461 {
462 php_pqres_object_t *obj = o;
463
464 RETVAL_LONG(PQresultStatus(obj->intern->res));
465 }
466
467 static void php_pqres_object_read_status_message(zval *object, void *o, zval *return_value TSRMLS_DC)
468 {
469 php_pqres_object_t *obj = o;
470
471 RETVAL_STRING(PQresStatus(PQresultStatus(obj->intern->res))+sizeof("PGRES"), 1);
472 }
473
474 static void php_pqres_object_read_error_message(zval *object, void *o, zval *return_value TSRMLS_DC)
475 {
476 php_pqres_object_t *obj = o;
477 char *error = PHP_PQresultErrorMessage(obj->intern->res);
478
479 if (error) {
480 RETVAL_STRING(error, 1);
481 } else {
482 RETVAL_NULL();
483 }
484 }
485
486 static void php_pqres_object_read_num_rows(zval *object, void *o, zval *return_value TSRMLS_DC)
487 {
488 php_pqres_object_t *obj = o;
489
490 RETVAL_LONG(PQntuples(obj->intern->res));
491 }
492
493 static void php_pqres_object_read_num_cols(zval *object, void *o, zval *return_value TSRMLS_DC)
494 {
495 php_pqres_object_t *obj = o;
496
497 RETVAL_LONG(PQnfields(obj->intern->res));
498 }
499
500 static void php_pqres_object_read_affected_rows(zval *object, void *o, zval *return_value TSRMLS_DC)
501 {
502 php_pqres_object_t *obj = o;
503
504 RETVAL_LONG(atoi(PQcmdTuples(obj->intern->res)));
505 }
506
507 static void php_pqres_object_read_fetch_type(zval *object, void *o, zval *return_value TSRMLS_DC)
508 {
509 php_pqres_object_t *obj = o;
510
511 if (obj->intern->iter) {
512 RETVAL_LONG(obj->intern->iter->fetch_type);
513 } else {
514 RETVAL_LONG(obj->intern->default_fetch_type);
515 }
516 }
517
518 static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value TSRMLS_DC)
519 {
520 php_pqres_object_t *obj = o;
521 zval *zfetch_type = value;
522
523 if (Z_TYPE_P(value) != IS_LONG) {
524 if (Z_REFCOUNT_P(value) > 1) {
525 zval *tmp;
526 MAKE_STD_ZVAL(tmp);
527 ZVAL_ZVAL(tmp, zfetch_type, 1, 0);
528 convert_to_long(tmp);
529 zfetch_type = tmp;
530 } else {
531 convert_to_long_ex(&zfetch_type);
532 }
533 }
534
535 if (!obj->intern->iter) {
536 obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(object), object, 0 TSRMLS_CC);
537 obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter TSRMLS_CC);
538 }
539 obj->intern->iter->fetch_type = Z_LVAL_P(zfetch_type);
540
541 if (zfetch_type != value) {
542 zval_ptr_dtor(&zfetch_type);
543 }
544 }
545
546 static void php_pqres_object_read_auto_conv(zval *object, void *o, zval *return_value TSRMLS_DC)
547 {
548 php_pqres_object_t *obj = o;
549
550 RETVAL_LONG(obj->intern->auto_convert);
551 }
552
553 static void php_pqres_object_write_auto_conv(zval *object, void *o, zval *value TSRMLS_DC)
554 {
555 php_pqres_object_t *obj = o;
556 zval *zauto_conv = value;
557
558 if (Z_TYPE_P(value) != IS_LONG) {
559 if (Z_REFCOUNT_P(value) > 1) {
560 zval *tmp;
561 MAKE_STD_ZVAL(tmp);
562 ZVAL_ZVAL(tmp, zauto_conv, 1, 0);
563 convert_to_long(tmp);
564 zauto_conv = tmp;
565 } else {
566 convert_to_long_ex(&zauto_conv);
567 }
568 }
569
570 obj->intern->auto_convert = Z_LVAL_P(zauto_conv);
571
572 if (zauto_conv != value) {
573 zval_ptr_dtor(&zauto_conv);
574 }
575 }
576
577 static STATUS php_pqres_iteration(zval *this_ptr, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval ***row TSRMLS_DC)
578 {
579 STATUS rv;
580 php_pqres_fetch_t orig_fetch;
581
582 if (!obj) {
583 obj = zend_object_store_get_object(getThis() TSRMLS_CC);
584 }
585
586 if (obj->intern->iter) {
587 obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter TSRMLS_CC);
588 } else {
589 obj->intern->iter = (php_pqres_iterator_t *) php_pqres_iterator_init(Z_OBJCE_P(getThis()), getThis(), 0 TSRMLS_CC);
590 obj->intern->iter->zi.funcs->rewind((zend_object_iterator *) obj->intern->iter TSRMLS_CC);
591 }
592 orig_fetch = obj->intern->iter->fetch_type;
593 obj->intern->iter->fetch_type = fetch_type;
594 if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter TSRMLS_CC))) {
595 obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter, row TSRMLS_CC);
596 }
597 obj->intern->iter->fetch_type = orig_fetch;
598
599 return rv;
600 }
601
602 typedef struct php_pqres_col {
603 char *name;
604 int num;
605 } php_pqres_col_t;
606
607 static STATUS column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col TSRMLS_DC)
608 {
609 long index = -1;
610 char *name = NULL;
611
612 if (!zcol) {
613 index = 0;
614 } else {
615 switch (Z_TYPE_P(zcol)) {
616 case IS_NULL:
617 index = 0;
618 break;
619
620 case IS_LONG:
621 index = Z_LVAL_P(zcol);
622 break;
623
624 default:
625 convert_to_string(zcol);
626 /* no break */
627
628 case IS_STRING:
629 if (!is_numeric_string(Z_STRVAL_P(zcol), Z_STRLEN_P(zcol), &index, NULL, 0)) {
630 name = Z_STRVAL_P(zcol);
631 }
632 break;
633 }
634 }
635
636 if (name) {
637 col->name = name;
638 col->num = PQfnumber(obj->intern->res, name);
639 } else {
640 col->name = PQfname(obj->intern->res, index);
641 col->num = index;
642 }
643
644 if (!col->name) {
645 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column at index %ld", index);
646 return FAILURE;
647 }
648 if (col->num == -1) {
649 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column with name '%s'", name);
650 return FAILURE;
651 }
652 return SUCCESS;
653 }
654
655 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind, 0, 0, 2)
656 ZEND_ARG_INFO(0, col)
657 ZEND_ARG_INFO(1, ref)
658 ZEND_END_ARG_INFO();
659 static PHP_METHOD(pqres, bind) {
660 zval *zcol, *zref;
661 zend_error_handling zeh;
662 STATUS rv;
663
664 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
665 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z", &zcol, &zref);
666 zend_restore_error_handling(&zeh TSRMLS_CC);
667
668 if (SUCCESS == rv) {
669 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
670
671 if (!obj->intern) {
672 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
673 } else {
674 php_pqres_col_t col;
675
676 if (SUCCESS != column_nn(obj, zcol, &col TSRMLS_CC)) {
677 RETVAL_FALSE;
678 } else {
679 Z_ADDREF_P(zref);
680
681 if (SUCCESS != zend_hash_index_update(&obj->intern->bound, col.num, (void *) &zref, sizeof(zval *), NULL)) {
682 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to bind column %s@%d", col.name, col.num);
683 RETVAL_FALSE;
684 } else {
685 zend_hash_sort(&obj->intern->bound, zend_qsort, compare_index, 0 TSRMLS_CC);
686 RETVAL_TRUE;
687 }
688 }
689 }
690 }
691 }
692
693 static int apply_bound(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
694 {
695 zval **zvalue, **zbound = p;
696 zval **zrow = va_arg(argv, zval **);
697 STATUS *rv = va_arg(argv, STATUS *);
698
699 if (SUCCESS != zend_hash_index_find(Z_ARRVAL_PP(zrow), key->h, (void *) &zvalue)) {
700 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to find column ad index %lu", key->h);
701 *rv = FAILURE;
702 return ZEND_HASH_APPLY_STOP;
703 } else {
704 zval_dtor(*zbound);
705 ZVAL_COPY_VALUE(*zbound, *zvalue);
706 ZVAL_NULL(*zvalue);
707 zval_ptr_dtor(zvalue);
708 Z_ADDREF_P(*zbound);
709 *zvalue = *zbound;
710 *rv = SUCCESS;
711 return ZEND_HASH_APPLY_KEEP;
712 }
713 }
714
715 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound, 0, 0, 0)
716 ZEND_END_ARG_INFO();
717 static PHP_METHOD(pqres, fetchBound) {
718 zend_error_handling zeh;
719 STATUS rv;
720
721 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
722 rv = zend_parse_parameters_none();
723 zend_restore_error_handling(&zeh TSRMLS_CC);
724
725 if (SUCCESS == rv) {
726 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
727
728 if (!obj->intern) {
729 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
730 } else {
731 zval **row = NULL;
732
733 if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row TSRMLS_CC) && row) {
734 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC);
735 zend_hash_apply_with_arguments(&obj->intern->bound TSRMLS_CC, apply_bound, 2, row, &rv);
736 zend_restore_error_handling(&zeh TSRMLS_CC);
737
738 if (SUCCESS != rv) {
739 zval_ptr_dtor(row);
740 } else {
741 RETVAL_ZVAL(*row, 1, 0);
742 }
743 }
744 }
745 }
746 }
747
748 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row, 0, 0, 0)
749 ZEND_ARG_INFO(0, fetch_type)
750 ZEND_END_ARG_INFO();
751 static PHP_METHOD(pqres, fetchRow) {
752 zend_error_handling zeh;
753 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
754 long fetch_type = -1;
755 STATUS rv;
756
757 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
758 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type);
759 zend_restore_error_handling(&zeh TSRMLS_CC);
760
761 if (SUCCESS == rv) {
762 if (!obj->intern) {
763 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
764 } else {
765 zval **row = NULL;
766
767 if (fetch_type == -1) {
768 fetch_type = obj->intern->iter ? obj->intern->iter->fetch_type : obj->intern->default_fetch_type;
769 }
770
771 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC);
772 php_pqres_iteration(getThis(), obj, fetch_type, &row TSRMLS_CC);
773 zend_restore_error_handling(&zeh TSRMLS_CC);
774
775 if (row) {
776 RETVAL_ZVAL(*row, 1, 0);
777 }
778 }
779 }
780 }
781
782 static zval **column_at(zval *row, int col TSRMLS_DC)
783 {
784 zval **data = NULL;
785 HashTable *ht = HASH_OF(row);
786 int count = zend_hash_num_elements(ht);
787
788 if (col >= count) {
789 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Column index %d exceeds column count %d", col, count);
790 } else {
791 zend_hash_internal_pointer_reset(ht);
792 while (col-- > 0) {
793 zend_hash_move_forward(ht);
794 }
795 zend_hash_get_current_data(ht, (void *) &data);
796 }
797 return data;
798 }
799
800 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col, 0, 0, 1)
801 ZEND_ARG_INFO(1, ref)
802 ZEND_ARG_INFO(0, col)
803 ZEND_END_ARG_INFO();
804 static PHP_METHOD(pqres, fetchCol) {
805 zend_error_handling zeh;
806 zval *zcol = NULL, *zref;
807 STATUS rv;
808
809 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
810 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z/!", &zref, &zcol);
811 zend_restore_error_handling(&zeh TSRMLS_CC);
812
813 if (SUCCESS == rv) {
814 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
815
816 if (!obj->intern) {
817 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
818 } else {
819 zval **row = NULL;
820
821 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC);
822 php_pqres_iteration(getThis(), obj, obj->intern->iter ? obj->intern->iter->fetch_type : 0, &row TSRMLS_CC);
823 if (row) {
824 php_pqres_col_t col;
825
826 if (SUCCESS != column_nn(obj, zcol, &col TSRMLS_CC)) {
827 RETVAL_FALSE;
828 } else {
829 zval **zres = column_at(*row, col.num TSRMLS_CC);
830
831 if (!zres) {
832 RETVAL_FALSE;
833 } else {
834 zval_dtor(zref);
835 ZVAL_ZVAL(zref, *zres, 1, 0);
836 RETVAL_TRUE;
837 }
838 }
839 }
840 zend_restore_error_handling(&zeh TSRMLS_CC);
841 }
842 }
843 }
844
845 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all_cols, 0, 0, 0)
846 ZEND_ARG_INFO(0, col)
847 ZEND_END_ARG_INFO();
848 static PHP_METHOD(pqres, fetchAllCols) {
849 zend_error_handling zeh;
850 zval *zcol = NULL;
851 STATUS rv;
852
853 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
854 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &zcol);
855 zend_restore_error_handling(&zeh TSRMLS_CC);
856
857 if (SUCCESS == rv) {
858 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
859
860 if (!obj->intern) {
861 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
862 } else {
863 php_pqres_col_t col;
864
865 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh TSRMLS_CC);
866 if (SUCCESS == column_nn(obj, zcol, &col TSRMLS_CC)) {
867 int r, rows = PQntuples(obj->intern->res);
868
869 array_init(return_value);
870 for (r = 0; r < rows; ++r) {
871 add_next_index_zval(return_value, php_pqres_get_col(obj->intern, r, col.num TSRMLS_CC));
872 }
873 }
874 zend_restore_error_handling(&zeh TSRMLS_CC);
875 }
876 }
877 }
878
879 struct apply_to_col_arg {
880 php_pqres_object_t *obj;
881 php_pqres_col_t *cols;
882 STATUS status;
883 };
884
885 static int apply_to_col(void *p, void *a TSRMLS_DC)
886 {
887 zval **c = p;
888 struct apply_to_col_arg *arg = a;
889
890 if (SUCCESS != column_nn(arg->obj, *c, arg->cols TSRMLS_CC)) {
891 arg->status = FAILURE;
892 return ZEND_HASH_APPLY_STOP;
893 } else {
894 arg->status = SUCCESS;
895 ++arg->cols;
896 return ZEND_HASH_APPLY_KEEP;
897 }
898 }
899
900 static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashTable *ht TSRMLS_DC)
901 {
902 struct apply_to_col_arg arg = {NULL};
903 php_pqres_col_t *tmp;
904
905 arg.obj = obj;
906 arg.cols = ecalloc(zend_hash_num_elements(ht), sizeof(*tmp));
907 tmp = arg.cols;
908 zend_hash_apply_with_argument(ht, apply_to_col, &arg TSRMLS_CC);
909
910 if (SUCCESS == arg.status) {
911 return tmp;
912 } else {
913 efree(tmp);
914 return NULL;
915 }
916 }
917
918 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map, 0, 0, 0)
919 ZEND_ARG_INFO(0, keys)
920 ZEND_ARG_INFO(0, vals)
921 ZEND_ARG_INFO(0, fetch_type)
922 ZEND_END_ARG_INFO();
923 static PHP_METHOD(pqres, map) {
924 zend_error_handling zeh;
925 zval *zkeys = 0, *zvals = 0;
926 long fetch_type = -1;
927 STATUS rv;
928
929 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
930 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/!z/!l", &zkeys, &zvals, &fetch_type);
931 zend_restore_error_handling(&zeh TSRMLS_CC);
932
933 if (SUCCESS == rv) {
934 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
935
936 if (!obj->intern) {
937 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
938 } else {
939 int ks = 0, vs = 0;
940 php_pqres_col_t def = {PQfname(obj->intern->res, 0), 0}, *keys = NULL, *vals = NULL;
941
942 if (zkeys) {
943 convert_to_array(zkeys);
944
945 if ((ks = zend_hash_num_elements(Z_ARRVAL_P(zkeys)))) {
946 keys = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zkeys) TSRMLS_CC);
947 } else {
948 ks = 1;
949 keys = &def;
950 }
951 } else {
952 ks = 1;
953 keys = &def;
954 }
955 if (zvals) {
956 convert_to_array(zvals);
957
958 if ((vs = zend_hash_num_elements(Z_ARRVAL_P(zvals)))) {
959 vals = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zvals) TSRMLS_CC);
960 }
961 }
962
963 if (fetch_type == -1) {
964 fetch_type = obj->intern->iter ? obj->intern->iter->fetch_type : obj->intern->default_fetch_type;
965 }
966
967 if (keys) {
968 int rows, r;
969 zval **cur;
970
971 switch (fetch_type) {
972 case PHP_PQRES_FETCH_ARRAY:
973 case PHP_PQRES_FETCH_ASSOC:
974 array_init(return_value);
975 break;
976 case PHP_PQRES_FETCH_OBJECT:
977 object_init(return_value);
978 break;
979 }
980 for (r = 0, rows = PQntuples(obj->intern->res); r < rows; ++r) {
981 int k, v;
982
983 cur = &return_value;
984 for (k = 0; k < ks; ++k) {
985 char *key = PQgetvalue(obj->intern->res, r, keys[k].num);
986 int len = PQgetlength(obj->intern->res, r, keys[k].num);
987
988 if (SUCCESS != zend_symtable_find(HASH_OF(*cur), key, len + 1, (void *) &cur)) {
989 zval *tmp;
990
991 MAKE_STD_ZVAL(tmp);
992 switch (fetch_type) {
993 case PHP_PQRES_FETCH_ARRAY:
994 case PHP_PQRES_FETCH_ASSOC:
995 array_init(tmp);
996 break;
997 case PHP_PQRES_FETCH_OBJECT:
998 object_init(tmp);
999 break;
1000 }
1001 if (SUCCESS != zend_symtable_update(HASH_OF(*cur), key, len + 1, (void *) &tmp, sizeof(zval *), (void *) &cur)) {
1002 throw_exce(EX_RUNTIME TSRMLS_CC, "Failed to create map");
1003 goto err;
1004 }
1005 }
1006 }
1007 if (vals && vs) {
1008 for (v = 0; v < vs; ++v) {
1009 char *val = PQgetvalue(obj->intern->res, r, vals[v].num);
1010 int len = PQgetlength(obj->intern->res, r, vals[v].num);
1011
1012 switch (fetch_type) {
1013 case PHP_PQRES_FETCH_ARRAY:
1014 add_index_stringl(*cur, vals[v].num, val, len, 1);
1015 break;
1016 case PHP_PQRES_FETCH_ASSOC:
1017 add_assoc_stringl(*cur, vals[v].name, val, len, 1);
1018 break;
1019 case PHP_PQRES_FETCH_OBJECT:
1020 add_property_stringl(*cur, vals[v].name, val, len, 1);
1021 break;
1022 }
1023 }
1024 } else {
1025 php_pqres_row_to_zval(obj->intern->res, r, fetch_type, cur TSRMLS_CC);
1026 }
1027 }
1028 }
1029
1030 err:
1031 if (keys && keys != &def) {
1032 efree(keys);
1033 }
1034 if (vals) {
1035 efree(vals);
1036 }
1037 }
1038 }
1039 }
1040
1041 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all, 0, 0, 0)
1042 ZEND_ARG_INFO(0, fetch_type)
1043 ZEND_END_ARG_INFO();
1044 static PHP_METHOD(pqres, fetchAll) {
1045 zend_error_handling zeh;
1046 long fetch_type = -1;
1047 STATUS rv;
1048
1049 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1050 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &fetch_type);
1051 zend_restore_error_handling(&zeh TSRMLS_CC);
1052
1053 if (SUCCESS == rv) {
1054 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1055 if (!obj->intern) {
1056 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
1057 } else {
1058 int r, rows = PQntuples(obj->intern->res);
1059
1060 if (fetch_type == -1) {
1061 fetch_type = obj->intern->iter ? obj->intern->iter->fetch_type : obj->intern->default_fetch_type;
1062 }
1063
1064 array_init(return_value);
1065 for (r = 0; r < rows; ++r) {
1066 add_next_index_zval(return_value, php_pqres_row_to_zval(obj->intern->res, r, fetch_type, NULL TSRMLS_CC));
1067 }
1068 }
1069 }
1070 }
1071
1072 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count, 0, 0, 0)
1073 ZEND_END_ARG_INFO();
1074 static PHP_METHOD(pqres, count) {
1075 zend_error_handling zeh;
1076 STATUS rv;
1077
1078 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1079 rv = zend_parse_parameters_none();
1080 zend_restore_error_handling(&zeh TSRMLS_CC);
1081
1082 if (SUCCESS == rv) {
1083 long count;
1084
1085 if (SUCCESS != php_pqres_count_elements(getThis(), &count TSRMLS_CC)) {
1086 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
1087 } else {
1088 RETVAL_LONG(count);
1089 }
1090 }
1091 }
1092
1093 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_desc, 0, 0, 0)
1094 ZEND_END_ARG_INFO();
1095 static PHP_METHOD(pqres, desc) {
1096 zend_error_handling zeh;
1097 STATUS rv;
1098
1099 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh TSRMLS_CC);
1100 rv = zend_parse_parameters_none();
1101 zend_restore_error_handling(&zeh TSRMLS_CC);
1102
1103 if (SUCCESS == rv) {
1104 php_pqres_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
1105
1106 if (!obj->intern) {
1107 throw_exce(EX_UNINITIALIZED TSRMLS_CC, "pq\\Result not initialized");
1108 } else {
1109 int p, params;
1110
1111 array_init(return_value);
1112 for (p = 0, params = PQnparams(obj->intern->res); p < params; ++p) {
1113 add_next_index_long(return_value, PQparamtype(obj->intern->res, p));
1114 }
1115 }
1116 }
1117 }
1118
1119 static zend_function_entry php_pqres_methods[] = {
1120 PHP_ME(pqres, bind, ai_pqres_bind, ZEND_ACC_PUBLIC)
1121 PHP_ME(pqres, fetchBound, ai_pqres_fetch_bound, ZEND_ACC_PUBLIC)
1122 PHP_ME(pqres, fetchRow, ai_pqres_fetch_row, ZEND_ACC_PUBLIC)
1123 PHP_ME(pqres, fetchCol, ai_pqres_fetch_col, ZEND_ACC_PUBLIC)
1124 PHP_ME(pqres, fetchAll, ai_pqres_fetch_all, ZEND_ACC_PUBLIC)
1125 PHP_ME(pqres, fetchAllCols, ai_pqres_fetch_all_cols, ZEND_ACC_PUBLIC)
1126 PHP_ME(pqres, count, ai_pqres_count, ZEND_ACC_PUBLIC)
1127 PHP_ME(pqres, map, ai_pqres_map, ZEND_ACC_PUBLIC)
1128 PHP_ME(pqres, desc, ai_pqres_desc, ZEND_ACC_PUBLIC)
1129 {0}
1130 };
1131
1132 PHP_MSHUTDOWN_FUNCTION(pqres)
1133 {
1134 zend_hash_destroy(&php_pqres_object_prophandlers);
1135 return SUCCESS;
1136 }
1137
1138 PHP_MINIT_FUNCTION(pqres)
1139 {
1140 zend_class_entry ce = {0};
1141 php_pq_object_prophandler_t ph = {0};
1142
1143 INIT_NS_CLASS_ENTRY(ce, "pq", "Result", php_pqres_methods);
1144 php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
1145 php_pqres_class_entry->create_object = php_pqres_create_object;
1146 php_pqres_class_entry->iterator_funcs.funcs = &php_pqres_iterator_funcs;
1147 php_pqres_class_entry->get_iterator = php_pqres_iterator_init;
1148 zend_class_implements(php_pqres_class_entry TSRMLS_CC, 2, zend_ce_traversable, spl_ce_Countable);
1149
1150 memcpy(&php_pqres_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1151 php_pqres_object_handlers.read_property = php_pq_object_read_prop;
1152 php_pqres_object_handlers.write_property = php_pq_object_write_prop;
1153 php_pqres_object_handlers.clone_obj = NULL;
1154 php_pqres_object_handlers.get_property_ptr_ptr = NULL;
1155 php_pqres_object_handlers.get_gc = NULL;
1156 php_pqres_object_handlers.get_debug_info = php_pq_object_debug_info;
1157 php_pqres_object_handlers.get_properties = php_pq_object_properties;
1158 php_pqres_object_handlers.count_elements = php_pqres_count_elements;
1159
1160 zend_hash_init(&php_pqres_object_prophandlers, 8, NULL, NULL, 1);
1161
1162 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC TSRMLS_CC);
1163 ph.read = php_pqres_object_read_status;
1164 zend_hash_add(&php_pqres_object_prophandlers, "status", sizeof("status"), (void *) &ph, sizeof(ph), NULL);
1165
1166 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC TSRMLS_CC);
1167 ph.read = php_pqres_object_read_status_message;
1168 zend_hash_add(&php_pqres_object_prophandlers, "statusMessage", sizeof("statusMessage"), (void *) &ph, sizeof(ph), NULL);
1169
1170 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC TSRMLS_CC);
1171 ph.read = php_pqres_object_read_error_message;
1172 zend_hash_add(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage"), (void *) &ph, sizeof(ph), NULL);
1173
1174 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1175 ph.read = php_pqres_object_read_num_rows;
1176 zend_hash_add(&php_pqres_object_prophandlers, "numRows", sizeof("numRows"), (void *) &ph, sizeof(ph), NULL);
1177
1178 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1179 ph.read = php_pqres_object_read_num_cols;
1180 zend_hash_add(&php_pqres_object_prophandlers, "numCols", sizeof("numCols"), (void *) &ph, sizeof(ph), NULL);
1181
1182 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
1183 ph.read = php_pqres_object_read_affected_rows;
1184 zend_hash_add(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows"), (void *) &ph, sizeof(ph), NULL);
1185
1186 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC TSRMLS_CC);
1187 ph.read = php_pqres_object_read_fetch_type;
1188 ph.write = php_pqres_object_write_fetch_type;
1189 zend_hash_add(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType"), (void *) &ph, sizeof(ph), NULL);
1190 ph.write = NULL;
1191
1192 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC TSRMLS_CC);
1193 ph.read = php_pqres_object_read_auto_conv;
1194 ph.write = php_pqres_object_write_auto_conv;
1195 zend_hash_add(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert"), (void *) &ph, sizeof(ph), NULL);
1196 ph.write = NULL;
1197
1198 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY TSRMLS_CC);
1199 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK TSRMLS_CC);
1200 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK TSRMLS_CC);
1201 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT TSRMLS_CC);
1202 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN TSRMLS_CC);
1203 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE TSRMLS_CC);
1204 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR TSRMLS_CC);
1205 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR TSRMLS_CC);
1206 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH TSRMLS_CC);
1207 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE TSRMLS_CC);
1208
1209 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY TSRMLS_CC);
1210 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC TSRMLS_CC);
1211 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT TSRMLS_CC);
1212
1213 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL TSRMLS_CC);
1214 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT TSRMLS_CC);
1215 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT TSRMLS_CC);
1216 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR TSRMLS_CC);
1217 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY TSRMLS_CC);
1218 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME TSRMLS_CC);
1219 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON TSRMLS_CC);
1220 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL TSRMLS_CC);
1221
1222 return SUCCESS;
1223 }
1224
1225 /*
1226 * Local variables:
1227 * tab-width: 4
1228 * c-basic-offset: 4
1229 * End:
1230 * vim600: noet sw=4 ts=4 fdm=marker
1231 * vim<600: noet sw=4 ts=4
1232 */