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