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