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 #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_diag(zval *object, void *o, zval *return_value)
481 {
482 php_pqres_object_t *obj = o;
483 int i;
484 struct {
485 char code;
486 const char *const name;
487 } diag[] = {
488 #ifdef PG_DIAG_SEVERITY
489 {PG_DIAG_SEVERITY, "severity"},
490 #endif
491 #ifdef PG_DIAG_SQLSTATE
492 {PG_DIAG_SQLSTATE, "sqlstate"},
493 #endif
494 #ifdef PG_DIAG_MESSAGE_PRIMARY
495 {PG_DIAG_MESSAGE_PRIMARY, "message_primary"},
496 #endif
497 #ifdef PG_DIAG_MESSAGE_DETAIL
498 {PG_DIAG_MESSAGE_DETAIL, "message_detail"},
499 #endif
500 #ifdef PG_DIAG_MESSAGE_HINT
501 {PG_DIAG_MESSAGE_HINT, "message_hint"},
502 #endif
503 #ifdef PG_DIAG_STATEMENT_POSITION
504 {PG_DIAG_STATEMENT_POSITION,"statement_position"},
505 #endif
506 #ifdef PG_DIAG_INTERNAL_POSITION
507 {PG_DIAG_INTERNAL_POSITION, "internal_position"},
508 #endif
509 #ifdef PG_DIAG_INTERNAL_QUERY
510 {PG_DIAG_INTERNAL_QUERY, "internal_query"},
511 #endif
512 #ifdef PG_DIAG_CONTEXT
513 {PG_DIAG_CONTEXT, "context"},
514 #endif
515 #ifdef PG_DIAG_SCHEMA_NAME
516 {PG_DIAG_SCHEMA_NAME, "schema_name"},
517 #endif
518 #ifdef PG_DIAG_TABLE_NAME
519 {PG_DIAG_TABLE_NAME, "table_name"},
520 #endif
521 #ifdef PG_DIAG_COLUMN_NAME
522 {PG_DIAG_COLUMN_NAME, "column_name"},
523 #endif
524 #ifdef PG_DIAG_DATATYPE_NAME
525 {PG_DIAG_DATATYPE_NAME, "datatype_name"},
526 #endif
527 #ifdef PG_DIAG_CONSTRAINT_NAME
528 {PG_DIAG_CONSTRAINT_NAME, "constraint_name"},
529 #endif
530 #ifdef PG_DIAG_SOURCE_FILE
531 {PG_DIAG_SOURCE_FILE, "source_file"},
532 #endif
533 #ifdef PG_DIAG_SOURCE_LINE
534 {PG_DIAG_SOURCE_LINE, "source_line"},
535 #endif
536 #ifdef PG_DIAG_SOURCE_FUNCTION
537 {PG_DIAG_SOURCE_FUNCTION, "source_function"},
538 #endif
539 };
540
541 array_init_size(return_value, 32);
542 for (i = 0; i < sizeof(diag)/sizeof(diag[0]); ++i) {
543 char *value = PQresultErrorField(obj->intern->res, diag[i].code);
544
545 if (value) {
546 add_assoc_string(return_value, diag[i].name, value);
547 } else {
548 add_assoc_null(return_value, diag[i].name);
549 }
550 }
551 }
552
553 static void php_pqres_object_read_num_rows(zval *object, void *o, zval *return_value)
554 {
555 php_pqres_object_t *obj = o;
556
557 RETVAL_LONG(PQntuples(obj->intern->res));
558 }
559
560 static void php_pqres_object_read_num_cols(zval *object, void *o, zval *return_value)
561 {
562 php_pqres_object_t *obj = o;
563
564 RETVAL_LONG(PQnfields(obj->intern->res));
565 }
566
567 static void php_pqres_object_read_affected_rows(zval *object, void *o, zval *return_value)
568 {
569 php_pqres_object_t *obj = o;
570
571 RETVAL_LONG(atoi(PQcmdTuples(obj->intern->res)));
572 }
573
574 static void php_pqres_object_read_fetch_type(zval *object, void *o, zval *return_value)
575 {
576 php_pqres_object_t *obj = o;
577
578 RETVAL_LONG(php_pqres_fetch_type(obj->intern));
579 }
580
581 static void php_pqres_object_write_fetch_type(zval *object, void *o, zval *value)
582 {
583 php_pqres_object_t *obj = o;
584
585 if (!obj->intern->iter) {
586 php_pqres_internal_iterator_init(object);
587 }
588 obj->intern->iter->fetch_type = zval_get_long(value);
589 }
590
591 static void php_pqres_object_read_auto_conv(zval *object, void *o, zval *return_value)
592 {
593 php_pqres_object_t *obj = o;
594
595 RETVAL_LONG(obj->intern->auto_convert);
596 }
597
598 static void php_pqres_object_write_auto_conv(zval *object, void *o, zval *value)
599 {
600 php_pqres_object_t *obj = o;
601
602 obj->intern->auto_convert = zval_get_long(value);
603 }
604
605 static ZEND_RESULT_CODE php_pqres_iteration(zval *zobj, php_pqres_object_t *obj, php_pqres_fetch_t fetch_type, zval *row)
606 {
607 ZEND_RESULT_CODE rv;
608 php_pqres_fetch_t orig_fetch;
609
610 if (!obj) {
611 obj = PHP_PQ_OBJ(zobj, NULL);
612 }
613
614 if (obj->intern->iter) {
615 obj->intern->iter->zi.funcs->move_forward((zend_object_iterator *) obj->intern->iter);
616 } else {
617 php_pqres_internal_iterator_init(zobj);
618 }
619 orig_fetch = obj->intern->iter->fetch_type;
620 obj->intern->iter->fetch_type = fetch_type;
621 if (SUCCESS == (rv = obj->intern->iter->zi.funcs->valid((zend_object_iterator *) obj->intern->iter))) {
622 zval *tmp = obj->intern->iter->zi.funcs->get_current_data((zend_object_iterator *) obj->intern->iter);
623 ZVAL_COPY_VALUE(row, tmp);
624 }
625 obj->intern->iter->fetch_type = orig_fetch;
626
627 return rv;
628 }
629
630 typedef struct php_pqres_col {
631 char *name;
632 int num;
633 } php_pqres_col_t;
634
635 static ZEND_RESULT_CODE column_nn(php_pqres_object_t *obj, zval *zcol, php_pqres_col_t *col)
636 {
637 zend_long index = -1;
638 char *name = NULL;
639
640 if (!zcol) {
641 index = 0;
642 } else {
643 switch (Z_TYPE_P(zcol)) {
644 case IS_NULL:
645 index = 0;
646 break;
647
648 case IS_LONG:
649 index = Z_LVAL_P(zcol);
650 break;
651
652 default:
653 convert_to_string(zcol);
654 /* no break */
655
656 case IS_STRING:
657 if (!is_numeric_string(Z_STRVAL_P(zcol), Z_STRLEN_P(zcol), &index, NULL, 0)) {
658 name = Z_STRVAL_P(zcol);
659 }
660 break;
661 }
662 }
663
664 if (name) {
665 col->name = name;
666 col->num = PQfnumber(obj->intern->res, name);
667 } else {
668 col->name = PQfname(obj->intern->res, index);
669 col->num = index;
670 }
671
672 if (!col->name) {
673 php_error_docref(NULL, E_WARNING, "Failed to find column at index %ld", index);
674 return FAILURE;
675 }
676 if (col->num == -1) {
677 php_error_docref(NULL, E_WARNING, "Failed to find column with name '%s'", name);
678 return FAILURE;
679 }
680 return SUCCESS;
681 }
682
683 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_bind, 0, 0, 2)
684 ZEND_ARG_INFO(0, col)
685 ZEND_ARG_INFO(1, ref)
686 ZEND_END_ARG_INFO();
687 static PHP_METHOD(pqres, bind) {
688 zval *zcol, *zref;
689 zend_error_handling zeh;
690 ZEND_RESULT_CODE rv;
691
692 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
693 rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z/z", &zcol, &zref);
694 zend_restore_error_handling(&zeh);
695
696 if (SUCCESS == rv) {
697 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
698
699 if (!obj->intern) {
700 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
701 } else {
702 php_pqres_col_t col;
703
704 if (SUCCESS != column_nn(obj, zcol, &col)) {
705 RETVAL_FALSE;
706 } else {
707 Z_TRY_ADDREF_P(zref);
708
709 if (!zend_hash_index_update(&obj->intern->bound, col.num, zref)) {
710 php_error_docref(NULL, E_WARNING, "Failed to bind column %s@%d", col.name, col.num);
711 RETVAL_FALSE;
712 } else {
713 zend_hash_sort(&obj->intern->bound, php_pq_compare_index, 0);
714 RETVAL_TRUE;
715 }
716 }
717 }
718 }
719 }
720
721 static int apply_bound(zval *zbound, int argc, va_list argv, zend_hash_key *key)
722 {
723 zval *zvalue;
724 zval *zrow = va_arg(argv, zval *);
725 ZEND_RESULT_CODE *rv = va_arg(argv, ZEND_RESULT_CODE *);
726
727 if (!(zvalue = zend_hash_index_find(Z_ARRVAL_P(zrow), key->h))) {
728 php_error_docref(NULL, E_WARNING, "Failed to find column ad index %lu", key->h);
729 *rv = FAILURE;
730 return ZEND_HASH_APPLY_STOP;
731 } else {
732 ZVAL_DEREF(zbound);
733 zval_dtor(zbound);
734 ZVAL_COPY(zbound, zvalue);
735 *rv = SUCCESS;
736 return ZEND_HASH_APPLY_KEEP;
737 }
738 }
739
740 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_bound, 0, 0, 0)
741 ZEND_END_ARG_INFO();
742 static PHP_METHOD(pqres, fetchBound) {
743 zend_error_handling zeh;
744 ZEND_RESULT_CODE rv;
745
746 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
747 rv = zend_parse_parameters_none();
748 zend_restore_error_handling(&zeh);
749
750 if (SUCCESS == rv) {
751 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
752
753 if (!obj->intern) {
754 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
755 } else {
756 zval row;
757
758 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
759 if (SUCCESS == php_pqres_iteration(getThis(), obj, PHP_PQRES_FETCH_ARRAY, &row)) {
760 zend_hash_apply_with_arguments(&obj->intern->bound, apply_bound, 2, &row, &rv);
761
762 if (SUCCESS == rv) {
763 RETVAL_ZVAL(&row, 1, 0);
764 }
765 }
766 zend_restore_error_handling(&zeh);
767 }
768 }
769 }
770
771 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_row, 0, 0, 0)
772 ZEND_ARG_INFO(0, fetch_type)
773 ZEND_END_ARG_INFO();
774 static PHP_METHOD(pqres, fetchRow) {
775 zend_error_handling zeh;
776 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
777 zend_long fetch_type = -1;
778 ZEND_RESULT_CODE rv;
779
780 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
781 rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type);
782 zend_restore_error_handling(&zeh);
783
784 if (SUCCESS == rv) {
785 if (!obj->intern) {
786 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
787 } else {
788 zval row;
789
790 if (fetch_type == -1) {
791 fetch_type = php_pqres_fetch_type(obj->intern);
792 }
793
794 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
795 if (SUCCESS == php_pqres_iteration(getThis(), obj, fetch_type, &row)) {
796 RETVAL_ZVAL(&row, 1, 0);
797 }
798 zend_restore_error_handling(&zeh);
799 }
800 }
801 }
802
803 static zval *column_at(zval *row, int col)
804 {
805 zval *data = NULL;
806 HashTable *ht = HASH_OF(row);
807 int count = zend_hash_num_elements(ht);
808
809 if (col >= count) {
810 php_error_docref(NULL, E_WARNING, "Column index %d exceeds column count %d", col, count);
811 } else {
812 zend_hash_internal_pointer_reset(ht);
813 while (col-- > 0) {
814 zend_hash_move_forward(ht);
815 }
816 data = zend_hash_get_current_data(ht);
817 }
818 return data;
819 }
820
821 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_col, 0, 0, 1)
822 ZEND_ARG_INFO(1, ref)
823 ZEND_ARG_INFO(0, col)
824 ZEND_END_ARG_INFO();
825 static PHP_METHOD(pqres, fetchCol) {
826 zend_error_handling zeh;
827 zval *zcol = NULL, *zref;
828 ZEND_RESULT_CODE rv;
829
830 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
831 rv = zend_parse_parameters(ZEND_NUM_ARGS(), "z|z/!", &zref, &zcol);
832 zend_restore_error_handling(&zeh);
833
834 if (SUCCESS == rv) {
835 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
836
837 if (!obj->intern) {
838 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
839 } else {
840 zval row;
841
842 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
843 if (SUCCESS == php_pqres_iteration(getThis(), obj, php_pqres_fetch_type(obj->intern), &row)) {
844 php_pqres_col_t col;
845
846 if (SUCCESS != column_nn(obj, zcol, &col)) {
847 RETVAL_FALSE;
848 } else {
849 zval *zres = column_at(&row, col.num);
850
851 if (!zres) {
852 RETVAL_FALSE;
853 } else {
854 ZVAL_DEREF(zref);
855 zval_dtor(zref);
856 ZVAL_ZVAL(zref, zres, 1, 0);
857 RETVAL_TRUE;
858 }
859 }
860 }
861 zend_restore_error_handling(&zeh);
862 }
863 }
864 }
865
866 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all_cols, 0, 0, 0)
867 ZEND_ARG_INFO(0, col)
868 ZEND_END_ARG_INFO();
869 static PHP_METHOD(pqres, fetchAllCols) {
870 zend_error_handling zeh;
871 zval *zcol = NULL;
872 ZEND_RESULT_CODE rv;
873
874 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
875 rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z!", &zcol);
876 zend_restore_error_handling(&zeh);
877
878 if (SUCCESS == rv) {
879 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
880
881 if (!obj->intern) {
882 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
883 } else {
884 php_pqres_col_t col;
885
886 zend_replace_error_handling(EH_THROW, exce(EX_RUNTIME), &zeh);
887 if (SUCCESS == column_nn(obj, zcol, &col)) {
888 int r, rows = PQntuples(obj->intern->res);
889 zval tmp;
890
891 array_init(return_value);
892 for (r = 0; r < rows; ++r) {
893 add_next_index_zval(return_value, php_pqres_get_col(obj->intern, r, col.num, &tmp));
894 }
895 }
896 zend_restore_error_handling(&zeh);
897 }
898 }
899 }
900
901 struct apply_to_col_arg {
902 php_pqres_object_t *obj;
903 php_pqres_col_t *cols;
904 ZEND_RESULT_CODE status;
905 };
906
907 static int apply_to_col(zval *c, void *a)
908 {
909 struct apply_to_col_arg *arg = a;
910
911 if (SUCCESS != column_nn(arg->obj, c, arg->cols)) {
912 arg->status = FAILURE;
913 return ZEND_HASH_APPLY_STOP;
914 } else {
915 arg->status = SUCCESS;
916 ++arg->cols;
917 return ZEND_HASH_APPLY_KEEP;
918 }
919 }
920
921 static php_pqres_col_t *php_pqres_convert_to_cols(php_pqres_object_t *obj, HashTable *ht)
922 {
923 struct apply_to_col_arg arg = {NULL};
924 php_pqres_col_t *tmp;
925
926 arg.obj = obj;
927 arg.cols = ecalloc(zend_hash_num_elements(ht), sizeof(*tmp));
928 tmp = arg.cols;
929 zend_hash_apply_with_argument(ht, apply_to_col, &arg);
930
931 if (SUCCESS == arg.status) {
932 return tmp;
933 } else {
934 efree(tmp);
935 return NULL;
936 }
937 }
938
939 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_map, 0, 0, 0)
940 ZEND_ARG_INFO(0, keys)
941 ZEND_ARG_INFO(0, vals)
942 ZEND_ARG_INFO(0, fetch_type)
943 ZEND_END_ARG_INFO();
944 static PHP_METHOD(pqres, map) {
945 zend_error_handling zeh;
946 zval *zkeys = 0, *zvals = 0;
947 zend_long fetch_type = -1;
948 ZEND_RESULT_CODE rv;
949
950 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
951 rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|z/!z/!l", &zkeys, &zvals, &fetch_type);
952 zend_restore_error_handling(&zeh);
953
954 if (SUCCESS == rv) {
955 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
956
957 if (!obj->intern) {
958 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
959 } else {
960 int ks = 0, vs = 0;
961 php_pqres_col_t def = {PQfname(obj->intern->res, 0), 0}, *keys = NULL, *vals = NULL;
962
963 if (zkeys) {
964 convert_to_array(zkeys);
965
966 if ((ks = zend_hash_num_elements(Z_ARRVAL_P(zkeys)))) {
967 keys = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zkeys));
968 } else {
969 ks = 1;
970 keys = &def;
971 }
972 } else {
973 ks = 1;
974 keys = &def;
975 }
976 if (zvals) {
977 convert_to_array(zvals);
978
979 if ((vs = zend_hash_num_elements(Z_ARRVAL_P(zvals)))) {
980 vals = php_pqres_convert_to_cols(obj, Z_ARRVAL_P(zvals));
981 }
982 }
983
984 if (fetch_type == -1) {
985 fetch_type = php_pqres_fetch_type(obj->intern);
986 }
987
988 if (keys) {
989 int rows, r;
990 zval *cur;
991
992 switch (fetch_type) {
993 case PHP_PQRES_FETCH_ARRAY:
994 case PHP_PQRES_FETCH_ASSOC:
995 array_init(return_value);
996 break;
997 case PHP_PQRES_FETCH_OBJECT:
998 object_init(return_value);
999 break;
1000 }
1001 for (r = 0, rows = PQntuples(obj->intern->res); r < rows; ++r) {
1002 int k, v;
1003 zval *ptr;
1004
1005 cur = return_value;
1006 for (k = 0; k < ks; ++k) {
1007 char *key = PQgetvalue(obj->intern->res, r, keys[k].num);
1008 int len = PQgetlength(obj->intern->res, r, keys[k].num);
1009
1010 if (!(ptr = zend_symtable_str_find(HASH_OF(cur), key, len))) {
1011 zval tmp;
1012
1013 switch (fetch_type) {
1014 case PHP_PQRES_FETCH_ARRAY:
1015 case PHP_PQRES_FETCH_ASSOC:
1016 array_init(&tmp);
1017 break;
1018 case PHP_PQRES_FETCH_OBJECT:
1019 object_init(&tmp);
1020 break;
1021 }
1022 if (!(ptr = zend_symtable_str_update(HASH_OF(cur), key, len, &tmp))) {
1023 throw_exce(EX_RUNTIME, "Failed to create map");
1024 goto err;
1025 }
1026 cur = ptr;
1027 }
1028 cur = ptr;
1029 }
1030 if (vals && vs) {
1031 for (v = 0; v < vs; ++v) {
1032 char *val = PQgetvalue(obj->intern->res, r, vals[v].num);
1033 int len = PQgetlength(obj->intern->res, r, vals[v].num);
1034
1035 switch (fetch_type) {
1036 case PHP_PQRES_FETCH_ARRAY:
1037 add_index_stringl(cur, vals[v].num, val, len);
1038 break;
1039 case PHP_PQRES_FETCH_ASSOC:
1040 add_assoc_stringl(cur, vals[v].name, val, len);
1041 break;
1042 case PHP_PQRES_FETCH_OBJECT:
1043 add_property_stringl(cur, vals[v].name, val, len);
1044 break;
1045 }
1046 }
1047 } else {
1048 php_pqres_row_to_zval(obj->intern->res, r, fetch_type, cur);
1049 }
1050 }
1051 }
1052
1053 err:
1054 if (keys && keys != &def) {
1055 efree(keys);
1056 }
1057 if (vals) {
1058 efree(vals);
1059 }
1060 }
1061 }
1062 }
1063
1064 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_fetch_all, 0, 0, 0)
1065 ZEND_ARG_INFO(0, fetch_type)
1066 ZEND_END_ARG_INFO();
1067 static PHP_METHOD(pqres, fetchAll) {
1068 zend_error_handling zeh;
1069 zend_long fetch_type = -1;
1070 ZEND_RESULT_CODE rv;
1071
1072 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
1073 rv = zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &fetch_type);
1074 zend_restore_error_handling(&zeh);
1075
1076 if (SUCCESS == rv) {
1077 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
1078
1079 if (!obj->intern) {
1080 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
1081 } else {
1082 int r, rows = PQntuples(obj->intern->res);
1083 zval tmp;
1084
1085 if (fetch_type == -1) {
1086 fetch_type = php_pqres_fetch_type(obj->intern);
1087 }
1088
1089 array_init(return_value);
1090 for (r = 0; r < rows; ++r) {
1091 ZVAL_NULL(&tmp);
1092 add_next_index_zval(return_value, php_pqres_row_to_zval(obj->intern->res, r, fetch_type, &tmp));
1093 }
1094 }
1095 }
1096 }
1097
1098 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_count, 0, 0, 0)
1099 ZEND_END_ARG_INFO();
1100 static PHP_METHOD(pqres, count) {
1101 zend_error_handling zeh;
1102 ZEND_RESULT_CODE rv;
1103
1104 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
1105 rv = zend_parse_parameters_none();
1106 zend_restore_error_handling(&zeh);
1107
1108 if (SUCCESS == rv) {
1109 long count;
1110
1111 if (SUCCESS != php_pqres_count_elements(getThis(), &count)) {
1112 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
1113 } else {
1114 RETVAL_LONG(count);
1115 }
1116 }
1117 }
1118
1119 ZEND_BEGIN_ARG_INFO_EX(ai_pqres_desc, 0, 0, 0)
1120 ZEND_END_ARG_INFO();
1121 static PHP_METHOD(pqres, desc) {
1122 zend_error_handling zeh;
1123 ZEND_RESULT_CODE rv;
1124
1125 zend_replace_error_handling(EH_THROW, exce(EX_INVALID_ARGUMENT), &zeh);
1126 rv = zend_parse_parameters_none();
1127 zend_restore_error_handling(&zeh);
1128
1129 if (SUCCESS == rv) {
1130 php_pqres_object_t *obj = PHP_PQ_OBJ(getThis(), NULL);
1131
1132 if (!obj->intern) {
1133 throw_exce(EX_UNINITIALIZED, "pq\\Result not initialized");
1134 } else {
1135 int p, params;
1136
1137 array_init(return_value);
1138 for (p = 0, params = PQnparams(obj->intern->res); p < params; ++p) {
1139 add_next_index_long(return_value, PQparamtype(obj->intern->res, p));
1140 }
1141 }
1142 }
1143 }
1144
1145 static zend_function_entry php_pqres_methods[] = {
1146 PHP_ME(pqres, bind, ai_pqres_bind, ZEND_ACC_PUBLIC)
1147 PHP_ME(pqres, fetchBound, ai_pqres_fetch_bound, ZEND_ACC_PUBLIC)
1148 PHP_ME(pqres, fetchRow, ai_pqres_fetch_row, ZEND_ACC_PUBLIC)
1149 PHP_ME(pqres, fetchCol, ai_pqres_fetch_col, ZEND_ACC_PUBLIC)
1150 PHP_ME(pqres, fetchAll, ai_pqres_fetch_all, ZEND_ACC_PUBLIC)
1151 PHP_ME(pqres, fetchAllCols, ai_pqres_fetch_all_cols, ZEND_ACC_PUBLIC)
1152 PHP_ME(pqres, count, ai_pqres_count, ZEND_ACC_PUBLIC)
1153 PHP_ME(pqres, map, ai_pqres_map, ZEND_ACC_PUBLIC)
1154 PHP_ME(pqres, desc, ai_pqres_desc, ZEND_ACC_PUBLIC)
1155 {0}
1156 };
1157
1158 PHP_MSHUTDOWN_FUNCTION(pqres)
1159 {
1160 zend_hash_destroy(&php_pqres_object_prophandlers);
1161 return SUCCESS;
1162 }
1163
1164 PHP_MINIT_FUNCTION(pqres)
1165 {
1166 zend_class_entry ce = {0};
1167 php_pq_object_prophandler_t ph = {0};
1168
1169 INIT_NS_CLASS_ENTRY(ce, "pq", "Result", php_pqres_methods);
1170 php_pqres_class_entry = zend_register_internal_class_ex(&ce, NULL);
1171 php_pqres_class_entry->create_object = php_pqres_create_object;
1172 php_pqres_class_entry->get_iterator = php_pqres_iterator_init;
1173 zend_class_implements(php_pqres_class_entry, 2, zend_ce_traversable, spl_ce_Countable);
1174
1175 memcpy(&php_pqres_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1176 php_pqres_object_handlers.offset = XtOffsetOf(php_pqres_object_t, zo);
1177 php_pqres_object_handlers.free_obj = php_pqres_object_free;
1178 php_pqres_object_handlers.read_property = php_pq_object_read_prop;
1179 php_pqres_object_handlers.write_property = php_pq_object_write_prop;
1180 php_pqres_object_handlers.clone_obj = NULL;
1181 php_pqres_object_handlers.get_property_ptr_ptr = NULL;
1182 php_pqres_object_handlers.get_gc = php_pq_object_get_gc;
1183 php_pqres_object_handlers.get_debug_info = php_pq_object_debug_info;
1184 php_pqres_object_handlers.get_properties = php_pq_object_properties;
1185 php_pqres_object_handlers.count_elements = php_pqres_count_elements;
1186
1187 zend_hash_init(&php_pqres_object_prophandlers, 9, NULL, php_pq_object_prophandler_dtor, 1);
1188
1189 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("status"), ZEND_ACC_PUBLIC);
1190 ph.read = php_pqres_object_read_status;
1191 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "status", sizeof("status")-1, (void *) &ph, sizeof(ph));
1192
1193 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("statusMessage"), ZEND_ACC_PUBLIC);
1194 ph.read = php_pqres_object_read_status_message;
1195 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "statusMessage", sizeof("statusMessage")-1, (void *) &ph, sizeof(ph));
1196
1197 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("errorMessage"), ZEND_ACC_PUBLIC);
1198 ph.read = php_pqres_object_read_error_message;
1199 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "errorMessage", sizeof("errorMessage")-1, (void *) &ph, sizeof(ph));
1200
1201 zend_declare_property_null(php_pqres_class_entry, ZEND_STRL("diag"), ZEND_ACC_PUBLIC);
1202 ph.read = php_pqres_object_read_diag;
1203 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "diag", sizeof("diag")-1, (void *) &ph, sizeof(ph));
1204
1205 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numRows"), 0, ZEND_ACC_PUBLIC);
1206 ph.read = php_pqres_object_read_num_rows;
1207 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numRows", sizeof("numRows")-1, (void *) &ph, sizeof(ph));
1208
1209 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("numCols"), 0, ZEND_ACC_PUBLIC);
1210 ph.read = php_pqres_object_read_num_cols;
1211 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "numCols", sizeof("numCols")-1, (void *) &ph, sizeof(ph));
1212
1213 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("affectedRows"), 0, ZEND_ACC_PUBLIC);
1214 ph.read = php_pqres_object_read_affected_rows;
1215 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "affectedRows", sizeof("affectedRows")-1, (void *) &ph, sizeof(ph));
1216
1217 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("fetchType"), PHP_PQRES_FETCH_ARRAY, ZEND_ACC_PUBLIC);
1218 ph.read = php_pqres_object_read_fetch_type;
1219 ph.write = php_pqres_object_write_fetch_type;
1220 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "fetchType", sizeof("fetchType")-1, (void *) &ph, sizeof(ph));
1221 ph.write = NULL;
1222
1223 zend_declare_property_long(php_pqres_class_entry, ZEND_STRL("autoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC);
1224 ph.read = php_pqres_object_read_auto_conv;
1225 ph.write = php_pqres_object_write_auto_conv;
1226 zend_hash_str_add_mem(&php_pqres_object_prophandlers, "autoConvert", sizeof("autoConvert")-1, (void *) &ph, sizeof(ph));
1227 ph.write = NULL;
1228
1229 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("EMPTY_QUERY"), PGRES_EMPTY_QUERY);
1230 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COMMAND_OK"), PGRES_COMMAND_OK);
1231 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("TUPLES_OK"), PGRES_TUPLES_OK);
1232 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_OUT"), PGRES_COPY_OUT);
1233 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_IN"), PGRES_COPY_IN);
1234 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("BAD_RESPONSE"), PGRES_BAD_RESPONSE);
1235 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("NONFATAL_ERROR"), PGRES_NONFATAL_ERROR);
1236 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FATAL_ERROR"), PGRES_FATAL_ERROR);
1237 #ifdef HAVE_PGRES_COPY_BOTH
1238 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("COPY_BOTH"), PGRES_COPY_BOTH);
1239 #endif
1240 #ifdef HAVE_PGRES_SINGLE_TUPLE
1241 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("SINGLE_TUPLE"), PGRES_SINGLE_TUPLE);
1242 #endif
1243
1244 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ARRAY"), PHP_PQRES_FETCH_ARRAY);
1245 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_ASSOC"), PHP_PQRES_FETCH_ASSOC);
1246 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("FETCH_OBJECT"), PHP_PQRES_FETCH_OBJECT);
1247
1248 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_BOOL"), PHP_PQRES_CONV_BOOL);
1249 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_INT"), PHP_PQRES_CONV_INT);
1250 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_FLOAT"), PHP_PQRES_CONV_FLOAT);
1251 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_SCALAR"), PHP_PQRES_CONV_SCALAR);
1252 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ARRAY"), PHP_PQRES_CONV_ARRAY);
1253 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_DATETIME"), PHP_PQRES_CONV_DATETIME);
1254 #if PHP_PQ_HAVE_PHP_JSON_H
1255 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_JSON"), PHP_PQRES_CONV_JSON);
1256 #endif
1257 zend_declare_class_constant_long(php_pqres_class_entry, ZEND_STRL("CONV_ALL"), PHP_PQRES_CONV_ALL);
1258
1259 return SUCCESS;
1260 }
1261
1262 /*
1263 * Local variables:
1264 * tab-width: 4
1265 * c-basic-offset: 4
1266 * End:
1267 * vim600: noet sw=4 ts=4 fdm=marker
1268 * vim<600: noet sw=4 ts=4
1269 */