diff options
Diffstat (limited to 'src/my/my.c')
-rw-r--r-- | src/my/my.c | 202 |
1 files changed, 89 insertions, 113 deletions
diff --git a/src/my/my.c b/src/my/my.c index 54b2a49b0..1d78a08cf 100644 --- a/src/my/my.c +++ b/src/my/my.c | |||
@@ -35,7 +35,7 @@ | |||
35 | * @param mc mysql context | 35 | * @param mc mysql context |
36 | * @param sh handle to SELECT statment | 36 | * @param sh handle to SELECT statment |
37 | * @param params parameters to the statement | 37 | * @param params parameters to the statement |
38 | * @return | 38 | * @return |
39 | #GNUNET_YES if we can prepare all statement | 39 | #GNUNET_YES if we can prepare all statement |
40 | #GNUNET_SYSERR if we can't prepare all statement | 40 | #GNUNET_SYSERR if we can't prepare all statement |
41 | */ | 41 | */ |
@@ -98,37 +98,24 @@ GNUNET_MY_exec_prepared (struct GNUNET_MYSQL_Context *mc, | |||
98 | 98 | ||
99 | 99 | ||
100 | /** | 100 | /** |
101 | * Extract results from a query result according | 101 | * Extract results from a query result according to the given |
102 | * to the given specification. If colums are NULL, | 102 | * specification. Always fetches the next row. |
103 | * the destination is not modified, and #GNUNET_NO is returned4 | ||
104 | * | 103 | * |
105 | * | 104 | * |
106 | * @param result | 105 | * @param sh statement that returned results |
107 | * @param row, the row from the result to extract | 106 | * @param rs specification to extract for |
108 | * @param result specificatio to extract for | ||
109 | * @return | 107 | * @return |
110 | #GNUNET_YES if all results could be extracted | 108 | * #GNUNET_YES if all results could be extracted |
111 | #GNUNET_NO if at least one result was NULL | 109 | * #GNUNET_NO if there is no more data in the result set |
112 | #GNUNET_SYSERR if a result was invalid | 110 | * #GNUNET_SYSERR if a result was invalid |
113 | */ | 111 | */ |
114 | int | 112 | int |
115 | GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, | 113 | GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, |
116 | struct GNUNET_MY_QueryParam *qp, | 114 | struct GNUNET_MY_ResultSpec *rs) |
117 | struct GNUNET_MY_ResultSpec *rs, | ||
118 | int row) | ||
119 | { | 115 | { |
120 | MYSQL_BIND *result; | 116 | unsigned int num_fields; |
121 | |||
122 | int num_fields; | ||
123 | MYSQL_FIELD *fields; | ||
124 | MYSQL_RES *res; | ||
125 | |||
126 | unsigned int i; | 117 | unsigned int i; |
127 | unsigned int j; | ||
128 | int had_null = GNUNET_NO; | ||
129 | int ret; | 118 | int ret; |
130 | |||
131 | result = NULL; | ||
132 | MYSQL_STMT *stmt; | 119 | MYSQL_STMT *stmt; |
133 | 120 | ||
134 | stmt = GNUNET_MYSQL_statement_get_stmt (NULL /* FIXME */, sh); | 121 | stmt = GNUNET_MYSQL_statement_get_stmt (NULL /* FIXME */, sh); |
@@ -141,115 +128,104 @@ GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, | |||
141 | return GNUNET_SYSERR; | 128 | return GNUNET_SYSERR; |
142 | } | 129 | } |
143 | 130 | ||
131 | num_fields = 0; | ||
132 | for (i=0;NULL != rs[i].conv;i++) | ||
133 | num_fields += rs[i].num_fields; | ||
144 | 134 | ||
145 | num_fields = mysql_stmt_field_count (stmt); | 135 | if (mysql_stmt_field_count (stmt) != num_fields) |
146 | res = mysql_stmt_result_metadata (stmt); | ||
147 | fields = mysql_fetch_fields (res); | ||
148 | |||
149 | int int_data[num_fields]; | ||
150 | long int long_data[num_fields]; | ||
151 | short short_data[num_fields]; | ||
152 | char str_data[STRING_SIZE]; | ||
153 | int error[num_fields]; | ||
154 | |||
155 | result = (MYSQL_BIND *)malloc (sizeof (MYSQL_BIND)*num_fields); | ||
156 | if(!result) | ||
157 | { | 136 | { |
158 | fprintf(stderr, "Error to allocate output buffers\n"); | 137 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
138 | "Number of fields missmatch between SQL result and result specification\n"); | ||
159 | return GNUNET_SYSERR; | 139 | return GNUNET_SYSERR; |
160 | } | 140 | } |
161 | 141 | ||
162 | memset(result, 0, sizeof (MYSQL_BIND) * num_fields); | ||
163 | |||
164 | /** INITIALISER LE MYSQL_BIND ****/ | ||
165 | |||
166 | for(i = 0 ; i< num_fields ;i++) | ||
167 | { | 142 | { |
168 | result[i].buffer_type = fields[i].type; | 143 | MYSQL_BIND result[num_fields]; |
169 | result[i].is_null = 0; | 144 | unsigned int field_off; |
170 | result[i].error = &error[i]; | ||
171 | 145 | ||
172 | switch (fields[i].type) | 146 | memset (result, 0, sizeof (MYSQL_BIND) * num_fields); |
147 | field_off = 0; | ||
148 | for (i=0;NULL != rs[i].conv;i++) | ||
173 | { | 149 | { |
174 | case MYSQL_TYPE_LONG: | 150 | struct GNUNET_MY_ResultSpec *rp = &rs[i]; |
175 | result[i].buffer = &(int_data[i]); | ||
176 | result[i].buffer_length = sizeof (int_data); | ||
177 | break; | ||
178 | |||
179 | case MYSQL_TYPE_LONGLONG: | ||
180 | result[i].buffer = &(long_data[i]); | ||
181 | result[i].buffer_length = sizeof (long_data); | ||
182 | break; | ||
183 | |||
184 | case MYSQL_TYPE_STRING: | ||
185 | result[i].buffer = (char *)str_data; | ||
186 | result[i].buffer_length = sizeof (str_data); | ||
187 | break; | ||
188 | |||
189 | case MYSQL_TYPE_SHORT: | ||
190 | result[i].buffer = &(short_data[i]); | ||
191 | result[i].buffer_length = sizeof (short_data); | ||
192 | break; | ||
193 | |||
194 | default: | ||
195 | fprintf(stderr, "Failed : wrong type : %d!\n", fields[i].type); | ||
196 | } | ||
197 | } | ||
198 | 151 | ||
199 | if (mysql_stmt_bind_result(stmt, result)) | 152 | if (GNUNET_OK != |
200 | { | 153 | rp->pre_conv (rp->cls, |
201 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", | 154 | rp, |
155 | stmt, | ||
156 | field_off, | ||
157 | &result[field_off])) | ||
158 | { | ||
159 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
160 | "Pre-conversion for MySQL result failed at offset %u\n", | ||
161 | i); | ||
162 | GNUNET_MY_cleanup_result (rs); | ||
163 | return GNUNET_SYSERR; | ||
164 | } | ||
165 | field_off += rp->num_fields; | ||
166 | } | ||
167 | if (mysql_stmt_bind_result (stmt, result)) | ||
168 | { | ||
169 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
170 | "my", | ||
202 | _("`%s' failed at %s:%d with error: %s\n"), | 171 | _("`%s' failed at %s:%d with error: %s\n"), |
203 | "mysql_stmt_bind_result", __FILE__, __LINE__, | 172 | "mysql_stmt_bind_result", __FILE__, __LINE__, |
204 | mysql_stmt_error (stmt)); | 173 | mysql_stmt_error (stmt)); |
205 | return GNUNET_SYSERR; | 174 | return GNUNET_SYSERR; |
206 | } | ||
207 | |||
208 | /*** FAILED HERE ***/ | ||
209 | if (mysql_stmt_fetch (stmt)) | ||
210 | { | ||
211 | for(j = 0 ; j < num_fields ;j++) | ||
212 | { | ||
213 | fprintf(stderr, "Error Bind [%d] : %d\n", j, error[j]); | ||
214 | } | 175 | } |
215 | 176 | ret = mysql_stmt_fetch (stmt); | |
216 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", | 177 | if (MYSQL_NO_DATA == ret) |
217 | _("`%s' failed at %s:%d with error: %s\n"), | 178 | return GNUNET_NO; |
218 | "mysql_stmt_fetch", __FILE__, __LINE__, | 179 | if (0 != ret) |
180 | { | ||
181 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
182 | "my", | ||
183 | _("mysql_stmt_fetch failed at %s:%d with error: %s\n"), | ||
184 | __FILE__, __LINE__, | ||
219 | mysql_stmt_error (stmt)); | 185 | mysql_stmt_error (stmt)); |
220 | return GNUNET_SYSERR; | 186 | return GNUNET_SYSERR; |
221 | } | 187 | } |
222 | 188 | field_off = 0; | |
223 | /* | 189 | for (i=0;NULL != rs[i].conv;i++) |
224 | while (1) | ||
225 | { | ||
226 | mysql_stmt_fetch (stmt); | ||
227 | |||
228 | for (i = 0 ; NULL != rs[i].conv ; i++) | ||
229 | { | 190 | { |
230 | struct GNUNET_MY_ResultSpec *spec; | 191 | struct GNUNET_MY_ResultSpec *rp = &rs[i]; |
231 | 192 | ||
232 | spec = &rs[i]; | 193 | if (NULL != rp->post_conv) |
233 | ret = spec->conv (spec->conv_cls, | 194 | if (GNUNET_OK != |
234 | spec, | 195 | rp->post_conv (rp->cls, |
235 | result); | 196 | rp, |
236 | 197 | stmt, | |
237 | if (GNUNET_SYSERR == ret) | 198 | field_off, |
238 | { | 199 | &result[field_off])) |
239 | return GNUNET_SYSERR; | 200 | { |
240 | } | 201 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
241 | 202 | "Post-conversion for MySQL result failed at offset %u\n", | |
242 | if (NULL != spec->result_size) | 203 | i); |
243 | *spec->result_size = spec->dst_size; | 204 | GNUNET_MY_cleanup_result (rs); |
205 | return GNUNET_SYSERR; | ||
206 | } | ||
207 | field_off += rp->num_fields; | ||
244 | } | 208 | } |
245 | } | 209 | } |
210 | return GNUNET_OK; | ||
211 | } | ||
246 | 212 | ||
247 | if (GNUNET_YES == had_null) | ||
248 | return GNUNET_NO; | ||
249 | */ | ||
250 | 213 | ||
251 | free (result); | 214 | /** |
252 | return GNUNET_OK; | 215 | * Free all memory that was allocated in @a rs during |
216 | * #GNUNET_MY_extract_result(). | ||
217 | * | ||
218 | * @param rs reult specification to clean up | ||
219 | */ | ||
220 | void | ||
221 | GNUNET_MY_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) | ||
222 | { | ||
223 | unsigned int i; | ||
224 | |||
225 | for (i=0;NULL != rs[i].conv;i++) | ||
226 | rs[i].cleaner (rs[i].cls, | ||
227 | &rs[i]); | ||
253 | } | 228 | } |
254 | 229 | ||
230 | |||
255 | /* end of my.c */ | 231 | /* end of my.c */ |