2 +--------------------------------------------------------------------+
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 +--------------------------------------------------------------------+
18 #include <ext/standard/php_string.h>
19 #include <ext/standard/php_smart_str.h>
21 #include <Zend/zend_interfaces.h>
26 #include "php_pq_params.h"
28 void php_pq_params_set_type_conv(php_pq_params_t
*p
, HashTable
*conv
)
30 zend_hash_clean(&p
->type
.conv
);
31 zend_hash_copy(&p
->type
.conv
, conv
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
34 static int apply_to_oid(void *p
, void *arg TSRMLS_DC
)
39 if (Z_TYPE_PP(ztype
) != IS_LONG
) {
40 convert_to_long_ex(ztype
);
43 **types
= Z_LVAL_PP(ztype
);
46 if (*ztype
!= *(zval
**)p
) {
49 return ZEND_HASH_APPLY_KEEP
;
52 unsigned php_pq_params_set_type_oids(php_pq_params_t
*p
, HashTable
*oids
)
54 p
->type
.count
= oids
? zend_hash_num_elements(oids
) : 0;
62 Oid
*ptr
= ecalloc(p
->type
.count
+ 1, sizeof(*p
->type
.oids
));
63 /* +1 for when less types than params are specified */
65 zend_hash_apply_with_argument(oids
, apply_to_oid
, &ptr TSRMLS_CC
);
70 unsigned php_pq_params_add_type_oid(php_pq_params_t
*p
, Oid type
)
72 p
->type
.oids
= safe_erealloc(p
->type
.oids
, ++p
->type
.count
, sizeof(*p
->type
.oids
), sizeof(*p
->type
.oids
));
73 p
->type
.oids
[p
->type
.count
] = 0;
74 p
->type
.oids
[p
->type
.count
-1] = type
;
78 static int apply_to_param_from_array(void *p TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
81 unsigned j
, *i
= va_arg(argv
, unsigned *);
82 smart_str
*s
= va_arg(argv
, smart_str
*);
83 zval
**zconv
= va_arg(argv
, zval
**);
89 smart_str_appendc(s
, ',');
95 zend_call_method_with_1_params(zconv
, NULL
, NULL
, "converttostring", &rv
, *zparam
);
96 convert_to_string(rv
);
97 smart_str_appendl(s
, Z_STRVAL_P(rv
), Z_STRLEN_P(rv
));
100 switch (Z_TYPE_PP(zparam
)) {
102 smart_str_appends(s
, "NULL");
106 smart_str_appends(s
, Z_BVAL_PP(zparam
) ? "t" : "f");
110 smart_str_append_long(s
, Z_LVAL_PP(zparam
));
114 len
= spprintf(&tmp
, 0, "%F", Z_DVAL_PP(zparam
));
115 smart_str_appendl(s
, tmp
, len
);
121 smart_str_appendc(s
, '{');
122 zend_hash_apply_with_arguments(Z_ARRVAL_PP(zparam
) TSRMLS_CC
, apply_to_param_from_array
, 2, &j
, s
, zconv
);
123 smart_str_appendc(s
, '}');
127 SEPARATE_ZVAL(zparam
);
128 if (Z_TYPE_PP(zparam
) != IS_STRING
) {
129 convert_to_string(*zparam
);
132 tmp
= php_addslashes(Z_STRVAL_PP(zparam
), Z_STRLEN_PP(zparam
), &tmp_len
, 0 TSRMLS_CC
);
133 smart_str_appendc(s
, '"');
134 smart_str_appendl(s
, tmp
, tmp_len
);
135 smart_str_appendc(s
, '"');
137 if (*zparam
!= *((zval
**) p
)) {
138 zval_ptr_dtor(zparam
);
144 return ZEND_HASH_APPLY_KEEP
;
147 static void array_param_to_string(zval
**zconv
, HashTable
*ht
, char **str
, int *len TSRMLS_DC
)
152 smart_str_appendc(&s
, '{');
153 zend_hash_apply_with_arguments(ht TSRMLS_CC
, apply_to_param_from_array
, 3, &i
, &s
, zconv
);
154 smart_str_appendc(&s
, '}');
161 static void php_pq_params_set_param(php_pq_params_t
*p
, unsigned index
, zval
**zp
)
164 Oid type
= p
->type
.count
> index
? p
->type
.oids
[index
] : 0;
167 if (type
&& SUCCESS
== zend_hash_index_find(&p
->type
.conv
, type
, (void *) &zconv
)) {
170 zend_call_method_with_1_params(zconv
, NULL
, NULL
, "converttostring", &rv
, *zp
);
171 convert_to_string(rv
);
172 p
->param
.strings
[index
] = Z_STRVAL_P(rv
);
173 zend_hash_next_index_insert(&p
->param
.dtor
, (void *) &rv
, sizeof(zval
*), NULL
);
177 switch (Z_TYPE_PP(zp
)) {
179 p
->param
.strings
[index
] = NULL
;
183 p
->param
.strings
[index
] = Z_BVAL_PP(zp
) ? "t" : "f";
188 Z_TYPE_PP(zp
) = IS_STRING
;
189 Z_STRLEN_PP(zp
) = spprintf(&Z_STRVAL_PP(zp
), 0, "%F", Z_DVAL_PP((zval
**)p
));
195 #if HAVE_PHP_PQ_TYPE_H
197 # include "php_pq_type.h"
199 # define PHP_PQ_TYPE_OF_ARRAY(oid) 0
204 Z_TYPE_P(tmp
) = IS_STRING
;
205 zend_hash_index_find(&p
->type
.conv
, PHP_PQ_TYPE_OF_ARRAY(type
), (void *) &zconv
);
206 array_param_to_string(zconv
, Z_ARRVAL_PP(zp
), &Z_STRVAL_P(tmp
), &Z_STRLEN_P(tmp
) TSRMLS_CC
);
212 convert_to_string_ex(zp
);
216 p
->param
.strings
[index
] = Z_STRVAL_PP(zp
);
219 zend_hash_next_index_insert(&p
->param
.dtor
, zp
, sizeof(zval
*), NULL
);
224 static int apply_to_params(void *zp TSRMLS_DC
, int argc
, va_list argv
, zend_hash_key
*key
)
226 php_pq_params_t
*p
= (php_pq_params_t
*) va_arg(argv
, php_pq_params_t
*);
227 unsigned *index
= (unsigned *) va_arg(argv
, unsigned *);
229 php_pq_params_set_param(p
, (*index
)++, zp
);
230 return ZEND_HASH_APPLY_KEEP
;
233 unsigned php_pq_params_add_param(php_pq_params_t
*p
, zval
*param
)
235 p
->param
.strings
= safe_erealloc(p
->param
.strings
, ++p
->param
.count
, sizeof(*p
->param
.strings
), 0);
236 php_pq_params_set_param(p
, p
->param
.count
-1, ¶m
);
237 return p
->type
.count
;
240 unsigned php_pq_params_set_params(php_pq_params_t
*p
, HashTable
*params
)
242 p
->param
.count
= params
? zend_hash_num_elements(params
) : 0;
245 if (p
->param
.strings
) {
246 efree(p
->param
.strings
);
247 p
->param
.strings
= NULL
;
249 zend_hash_clean(&p
->param
.dtor
);
250 if (p
->param
.count
) {
252 p
->param
.strings
= ecalloc(p
->param
.count
, sizeof(*p
->param
.strings
));
253 zend_hash_apply_with_arguments(params TSRMLS_CC
, apply_to_params
, 2, p
, &index
);
255 return p
->param
.count
;
258 void php_pq_params_free(php_pq_params_t
**p
)
261 php_pq_params_set_type_oids(*p
, NULL
);
262 php_pq_params_set_params(*p
, NULL
);
264 zend_hash_destroy(&(*p
)->param
.dtor
);
265 zend_hash_destroy(&(*p
)->type
.conv
);
272 php_pq_params_t
*php_pq_params_init(HashTable
*conv
, HashTable
*oids
, HashTable
*params TSRMLS_DC
)
274 php_pq_params_t
*p
= ecalloc(1, sizeof(*p
));
277 zend_hash_init(&p
->type
.conv
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
278 zend_hash_init(&p
->param
.dtor
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
281 php_pq_params_set_type_conv(p
, conv
);
284 php_pq_params_set_type_oids(p
, oids
);
287 php_pq_params_set_params(p
, params
);
298 * vim600: noet sw=4 ts=4 fdm=marker
299 * vim<600: noet sw=4 ts=4