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