1 #include <assert.h> |
1 #include <assert.h> |
2 |
2 |
3 #include "evsql.h" |
3 #include "evsql.h" |
4 #include "../lib/error.h" |
4 #include "../lib/log.h" |
5 #include "../lib/misc.h" |
5 #include "../lib/misc.h" |
|
6 |
|
7 #define _PARAM_TYPE_CASE(typenam) case EVSQL_PARAM_ ## typenam: return #typenam |
|
8 |
|
9 #define _PARAM_VAL_BUF_MAX 120 |
|
10 #define _PARAM_VAL_CASE(typenam, ...) case EVSQL_PARAM_ ## typenam: if (param->data_raw) ret = snprintf(buf, _PARAM_VAL_BUF_MAX, __VA_ARGS__); else return "(null)"; break |
|
11 |
|
12 const char *evsql_param_type (const struct evsql_query_param *param) { |
|
13 switch (param->type) { |
|
14 _PARAM_TYPE_CASE (INVALID ); |
|
15 _PARAM_TYPE_CASE (NULL_ ); |
|
16 _PARAM_TYPE_CASE (BINARY ); |
|
17 _PARAM_TYPE_CASE (STRING ); |
|
18 _PARAM_TYPE_CASE (UINT16 ); |
|
19 _PARAM_TYPE_CASE (UINT32 ); |
|
20 _PARAM_TYPE_CASE (UINT64 ); |
|
21 default: return "???"; |
|
22 } |
|
23 } |
|
24 |
|
25 |
|
26 static const char *evsql_param_val (const struct evsql_query_param *param) { |
|
27 static char buf[_PARAM_VAL_BUF_MAX]; |
|
28 int ret; |
|
29 |
|
30 switch (param->type) { |
|
31 _PARAM_VAL_CASE (INVALID, "???" ); |
|
32 _PARAM_VAL_CASE (NULL_, "(null)" ); |
|
33 _PARAM_VAL_CASE (BINARY, "%zu:%s", param->length, "..." ); |
|
34 _PARAM_VAL_CASE (STRING, "%s", param->data_raw ); |
|
35 _PARAM_VAL_CASE (UINT16, "%hu", (unsigned short int) ntohs(param->data.uint16) ); |
|
36 _PARAM_VAL_CASE (UINT32, "%lu", (unsigned long int) ntohl(param->data.uint32) ); |
|
37 _PARAM_VAL_CASE (UINT64, "%llu", (unsigned long long int) ntohq(param->data.uint64) ); |
|
38 default: return "???"; |
|
39 } |
|
40 |
|
41 return buf; |
|
42 } |
|
43 |
|
44 int evsql_params_clear (struct evsql_query_params *params) { |
|
45 struct evsql_query_param *param; |
|
46 |
|
47 for (param = params->list; param->type; param++) |
|
48 param->data_raw = NULL; |
|
49 |
|
50 return 0; |
|
51 } |
|
52 |
|
53 int evsql_param_binary (struct evsql_query_params *params, size_t param, const char *ptr, size_t len) { |
|
54 struct evsql_query_param *p = ¶ms->list[param]; |
|
55 |
|
56 assert(p->type == EVSQL_PARAM_BINARY); |
|
57 |
|
58 p->data_raw = ptr; |
|
59 p->length = len; |
|
60 |
|
61 return 0; |
|
62 } |
6 |
63 |
7 int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr) { |
64 int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr) { |
8 struct evsql_query_param *p = ¶ms->list[param]; |
65 struct evsql_query_param *p = ¶ms->list[param]; |
9 |
66 |
10 assert(p->type == EVSQL_PARAM_STRING); |
67 assert(p->type == EVSQL_PARAM_STRING); |
11 |
68 |
12 p->data_raw = ptr; |
69 p->data_raw = ptr; |
13 p->length = 0; |
70 p->length = 0; |
|
71 |
|
72 return 0; |
|
73 } |
|
74 |
|
75 int evsql_param_uint16 (struct evsql_query_params *params, size_t param, uint16_t uval) { |
|
76 struct evsql_query_param *p = ¶ms->list[param]; |
|
77 |
|
78 assert(p->type == EVSQL_PARAM_UINT16); |
|
79 |
|
80 p->data.uint16 = htons(uval); |
|
81 p->data_raw = (const char *) &p->data.uint16; |
|
82 p->length = sizeof(uval); |
14 |
83 |
15 return 0; |
84 return 0; |
16 } |
85 } |
17 |
86 |
18 int evsql_param_uint32 (struct evsql_query_params *params, size_t param, uint32_t uval) { |
87 int evsql_param_uint32 (struct evsql_query_params *params, size_t param, uint32_t uval) { |
23 p->data.uint32 = htonl(uval); |
92 p->data.uint32 = htonl(uval); |
24 p->data_raw = (const char *) &p->data.uint32; |
93 p->data_raw = (const char *) &p->data.uint32; |
25 p->length = sizeof(uval); |
94 p->length = sizeof(uval); |
26 |
95 |
27 return 0; |
96 return 0; |
|
97 } |
|
98 |
|
99 void evsql_query_debug (const char *sql, const struct evsql_query_params *params) { |
|
100 const struct evsql_query_param *param; |
|
101 size_t param_count = 0, idx = 0; |
|
102 |
|
103 // count the params |
|
104 for (param = params->list; param->type; param++) |
|
105 param_count++; |
|
106 |
|
107 DEBUG("sql: %s", sql); |
|
108 DEBUG("params: %zu", param_count); |
|
109 |
|
110 for (param = params->list; param->type; param++) { |
|
111 DEBUG("\t%2zu : %8s = %s", ++idx, evsql_param_type(param), evsql_param_val(param)); |
|
112 } |
28 } |
113 } |
29 |
114 |
30 const char *evsql_result_error (const struct evsql_result_info *res) { |
115 const char *evsql_result_error (const struct evsql_result_info *res) { |
31 if (!res->error) |
116 if (!res->error) |
32 return "No error"; |
117 return "No error"; |
62 default: |
147 default: |
63 FATAL("res->evsql->type"); |
148 FATAL("res->evsql->type"); |
64 } |
149 } |
65 } |
150 } |
66 |
151 |
67 int evsql_result_buf (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t *size, int nullok) { |
152 int evsql_result_binary (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t *size, int nullok) { |
68 *ptr = NULL; |
153 *ptr = NULL; |
69 |
154 |
70 switch (res->evsql->type) { |
155 switch (res->evsql->type) { |
71 case EVSQL_EVPQ: |
156 case EVSQL_EVPQ: |
72 if (PQgetisnull(res->result.pq, row, col)) { |
157 if (PQgetisnull(res->result.pq, row, col)) { |
90 |
175 |
91 error: |
176 error: |
92 return -1; |
177 return -1; |
93 } |
178 } |
94 |
179 |
95 int evsql_result_binary (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t size, int nullok) { |
180 int evsql_result_binlen (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t size, int nullok) { |
96 size_t real_size; |
181 size_t real_size = 0; |
97 |
182 |
98 if (evsql_result_buf(res, row, col, ptr, &real_size, nullok)) |
183 if (evsql_result_binary(res, row, col, ptr, &real_size, nullok)) |
99 goto error; |
184 goto error; |
|
185 |
|
186 if (*ptr == NULL) { |
|
187 assert(nullok); |
|
188 return 0; |
|
189 } |
100 |
190 |
101 if (size && real_size != size) |
191 if (size && real_size != size) |
102 ERROR("[%zu:%zu] field size mismatch: %zu -> %zu", row, col, size, real_size); |
192 ERROR("[%zu:%zu] field size mismatch: %zu -> %zu", row, col, size, real_size); |
103 |
193 |
104 return 0; |
194 return 0; |
106 error: |
196 error: |
107 return -1; |
197 return -1; |
108 } |
198 } |
109 |
199 |
110 int evsql_result_string (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, int nullok) { |
200 int evsql_result_string (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, int nullok) { |
111 return evsql_result_binary(res, row, col, ptr, 0, nullok); |
201 size_t real_size; |
|
202 |
|
203 if (evsql_result_binary(res, row, col, ptr, &real_size, nullok)) |
|
204 goto error; |
|
205 |
|
206 assert(real_size == strlen(*ptr)); |
|
207 |
|
208 return 0; |
|
209 |
|
210 error: |
|
211 return -1; |
112 } |
212 } |
113 |
213 |
114 int evsql_result_uint16 (const struct evsql_result_info *res, size_t row, size_t col, uint16_t *uval, int nullok) { |
214 int evsql_result_uint16 (const struct evsql_result_info *res, size_t row, size_t col, uint16_t *uval, int nullok) { |
115 const char *data; |
215 const char *data; |
116 int16_t sval; |
216 int16_t sval; |
117 |
217 |
118 if (evsql_result_binary(res, row, col, &data, sizeof(*uval), nullok)) |
218 if (evsql_result_binlen(res, row, col, &data, sizeof(*uval), nullok)) |
119 goto error; |
219 goto error; |
120 |
220 |
121 if (!data) |
221 if (!data) |
122 return 0; |
222 return 0; |
123 |
223 |