error handling
[oweals/gnunet.git] / src / my / my_query_helper.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2016 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 /**
21  * @file my/my_query_helper.c
22  * @brief library to help with access to a MySQL database
23  * @author Christian Grothoff
24  * @author Christophe Genevey
25  */
26 #include "platform.h"
27 #include <mysql/mysql.h>
28 #include "gnunet_my_lib.h"
29
30
31 /**
32  * Function called to clean up memory allocated
33  * by a #GNUNET_MY_QueryConverter.
34  *
35  * @param cls closure
36  * @param qbind array of parameter to clean up
37  */
38 static void
39 my_clean_query (void *cls,
40                 MYSQL_BIND *qbind)
41 {
42   (void) cls;
43   GNUNET_free (qbind[0].buffer);
44 }
45
46
47 /**
48  * Function called to convert input argument into SQL parameters.
49  *
50  * @param cls closure
51  * @param pq data about the query
52  * @param qbind array of parameters to initialize
53  * @return -1 on error
54  */
55 static int
56 my_conv_fixed_size (void *cls,
57                     const struct GNUNET_MY_QueryParam *qp,
58                     MYSQL_BIND *qbind)
59 {
60   (void) cls;
61   GNUNET_assert (1 == qp->num_params);
62   qbind->buffer = (void *) qp->data;
63   qbind->buffer_length = qp->data_len;
64   qbind->buffer_type = MYSQL_TYPE_BLOB;
65
66   return 1;
67 }
68
69
70 /**
71  * Generate query parameter for a buffer @a ptr of
72  * @a ptr_size bytes.
73  *
74  * @param ptr pointer to the query parameter to pass
75  * @param ptr_size number of bytes in @a ptr
76  */
77 struct GNUNET_MY_QueryParam
78 GNUNET_MY_query_param_fixed_size (const void *ptr,
79                                   size_t ptr_size)
80 {
81   struct GNUNET_MY_QueryParam qp = {
82     .conv = &my_conv_fixed_size,
83     .cleaner = NULL,
84     .conv_cls = NULL,
85     .num_params = 1,
86     .data = ptr,
87     .data_len = (unsigned long) ptr_size
88   };
89
90   return qp;
91 }
92
93
94 /**
95  * Function called to convert input argument into SQL parameters.
96  *
97  * @param cls closure
98  * @param pq data about the query
99  * @param qbind array of parameters to initialize
100  * @return -1 on error
101  */
102 static int
103 my_conv_string (void *cls,
104                 const struct GNUNET_MY_QueryParam *qp,
105                 MYSQL_BIND *qbind)
106 {
107   (void) cls;
108   GNUNET_assert (1 == qp->num_params);
109   qbind->buffer = (void *) qp->data;
110   qbind->buffer_length = qp->data_len;
111   qbind->buffer_type = MYSQL_TYPE_STRING;
112   return 1;
113 }
114
115
116 /**
117  * Generate query parameter for a string
118  *
119  * @param ptr pointer to the string query parameter to pass
120  */
121 struct GNUNET_MY_QueryParam
122 GNUNET_MY_query_param_string (const char *ptr)
123 {
124   struct GNUNET_MY_QueryParam qp = {
125     .conv = &my_conv_string,
126     .cleaner = NULL,
127     .conv_cls = NULL,
128     .num_params = 1,
129     .data = ptr,
130     .data_len = strlen (ptr)
131   };
132
133   return qp;
134 }
135
136
137 /**
138  * Function called to convert input argument into SQL parameters
139  *
140  * @param cls closure
141  * @param pq data about the query
142  * @param qbind array of parameters to initialize
143  * @return -1 on error
144  */
145 static int
146 my_conv_uint16 (void *cls,
147                 const struct GNUNET_MY_QueryParam *qp,
148                 MYSQL_BIND *qbind)
149 {
150   (void) cls;
151   GNUNET_assert (1 == qp->num_params);
152   qbind->buffer = (void *) qp->data;
153   qbind->buffer_length = sizeof(uint16_t);
154   qbind->buffer_type = MYSQL_TYPE_SHORT;
155   qbind->is_unsigned = 1;
156   return 1;
157 }
158
159
160 /**
161  * Generate query parameter for an uint16_t in host byte order.
162  *
163  * @param x pointer to the query parameter to pass
164  */
165 struct GNUNET_MY_QueryParam
166 GNUNET_MY_query_param_uint16 (const uint16_t *x)
167 {
168   struct GNUNET_MY_QueryParam res = {
169     .conv = &my_conv_uint16,
170     .cleaner = NULL,
171     .conv_cls = NULL,
172     .num_params = 1,
173     .data = x,
174     .data_len = sizeof(*x)
175   };
176
177   return res;
178 }
179
180
181 /**
182  * Function called to convert input argument into SQL parameters
183  *
184  * @param cls closure
185  * @param pq data about the query
186  * @param qbind array of parameters to initialize
187  * @return -1 on error
188  */
189 static int
190 my_conv_uint32 (void *cls,
191                 const struct GNUNET_MY_QueryParam *qp,
192                 MYSQL_BIND *qbind)
193 {
194   (void) cls;
195   GNUNET_assert (1 == qp->num_params);
196   qbind->buffer = (void *) qp->data;
197   qbind->buffer_length = sizeof(uint32_t);
198   qbind->buffer_type = MYSQL_TYPE_LONG;
199   qbind->is_unsigned = 1;
200   return 1;
201 }
202
203
204 /**
205  * Generate query parameter for an uint32_t in host byte order
206  *
207  * @param x pointer to the query parameter to pass
208  */
209 struct GNUNET_MY_QueryParam
210 GNUNET_MY_query_param_uint32 (const uint32_t *x)
211 {
212   struct GNUNET_MY_QueryParam res = {
213     .conv = &my_conv_uint32,
214     .cleaner = NULL,
215     .conv_cls = NULL,
216     .num_params = 1,
217     .data = x,
218     .data_len = sizeof(*x)
219   };
220
221   return res;
222 }
223
224
225 /**
226  * Function called to convert input argument into SQL parameters
227  *
228  * @param cls closure
229  * @param pq data about the query
230  * @param qbind array of parameters to initialize
231  * @return -1 on error
232  */
233 static int
234 my_conv_uint64 (void *cls,
235                 const struct GNUNET_MY_QueryParam *qp,
236                 MYSQL_BIND *qbind)
237 {
238   (void) cls;
239   GNUNET_assert (1 == qp->num_params);
240   qbind->buffer = (void *) qp->data;
241   qbind->buffer_length = sizeof(uint64_t);
242   qbind->buffer_type = MYSQL_TYPE_LONGLONG;
243   qbind->is_unsigned = 1;
244   return 1;
245 }
246
247
248 /**
249  * Generate query parameter for an uint64_t in host byte order
250  *
251  * @param x pointer to the query parameter to pass
252  */
253 struct GNUNET_MY_QueryParam
254 GNUNET_MY_query_param_uint64 (const uint64_t *x)
255 {
256   struct GNUNET_MY_QueryParam res = {
257     .conv = &my_conv_uint64,
258     .cleaner = NULL,
259     .conv_cls = NULL,
260     .num_params = 1,
261     .data = x,
262     .data_len = sizeof(*x)
263   };
264
265   return res;
266 }
267
268
269 /**
270  * Function called to convert input argument into SQL parameters
271  *
272  * @param cls closure
273  * @param pq data about the query
274  * @param qbind array of parameters to initialize
275  * @return -1 on error
276  */
277 static int
278 my_conv_rsa_public_key (void *cls,
279                         const struct GNUNET_MY_QueryParam *qp,
280                         MYSQL_BIND *qbind)
281 {
282   const struct GNUNET_CRYPTO_RsaPublicKey *rsa = qp->data;
283   char *buf;
284   size_t buf_size;
285
286   (void) cls;
287   GNUNET_assert (1 == qp->num_params);
288   buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa,
289                                                   &buf);
290   qbind->buffer = (void *) buf;
291   qbind->buffer_length = buf_size;
292   qbind->buffer_type = MYSQL_TYPE_BLOB;
293   return 1;
294 }
295
296
297 /**
298  * Generate query parameter for an RSA public key. The
299  * database must contain a BLOB type in the respective position.
300  *
301  * @param x the query parameter to pass
302  * @return array entry for the query parameters to use
303  */
304 struct GNUNET_MY_QueryParam
305 GNUNET_MY_query_param_rsa_public_key (const struct
306                                       GNUNET_CRYPTO_RsaPublicKey *x)
307 {
308   struct GNUNET_MY_QueryParam res = {
309     .conv = &my_conv_rsa_public_key,
310     .cleaner = &my_clean_query,
311     .conv_cls = NULL,
312     .num_params = 1,
313     .data = x,
314     .data_len = 0
315   };
316
317   return res;
318 }
319
320
321 /**
322  * Function called to convert input argument into SQL parameters
323  *
324  *@param cls closure
325  *@param pq data about the query
326  *@param qbind array of parameters to initialize
327  *@return -1 on error
328  */
329 static int
330 my_conv_rsa_signature (void *cls,
331                        const struct GNUNET_MY_QueryParam *qp,
332                        MYSQL_BIND *qbind)
333 {
334   const struct GNUNET_CRYPTO_RsaSignature *sig = qp->data;
335   char *buf;
336   size_t buf_size;
337
338   (void) cls;
339   GNUNET_assert (1 == qp->num_params);
340   buf_size = GNUNET_CRYPTO_rsa_signature_encode (sig,
341                                                  &buf);
342   qbind->buffer = (void *) buf;
343   qbind->buffer_length = buf_size;
344   qbind->buffer_type = MYSQL_TYPE_BLOB;
345   return 1;
346 }
347
348
349 /**
350  * Generate query parameter for an RSA signature. The
351  * database must contain a BLOB type in the respective position
352  *
353  * @param x the query parameter to pass
354  * @return array entry for the query parameters to use
355  */
356 struct GNUNET_MY_QueryParam
357 GNUNET_MY_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
358 {
359   struct GNUNET_MY_QueryParam res = {
360     .conv = &my_conv_rsa_signature,
361     .cleaner = &my_clean_query,
362     .conv_cls = NULL,
363     .num_params = 1,
364     .data = (x),
365     .data_len = 0
366   };
367
368   return res;
369 }
370
371
372 /**
373  * Generate query parameter for an absolute time value.
374  * The database must store a 64-bit integer.
375  *
376  * @param x pointer to the query parameter to pass
377  * @return array entry for the query parameters to use
378  */
379 struct GNUNET_MY_QueryParam
380 GNUNET_MY_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
381 {
382   return GNUNET_MY_query_param_uint64 (&x->abs_value_us);
383 }
384
385
386 /**
387  * Generate query parameter for an absolute time value.
388  * The database must store a 64-bit integer.
389  *
390  * @param x pointer to the query parameter to pass
391  */
392 struct GNUNET_MY_QueryParam
393 GNUNET_MY_query_param_absolute_time_nbo (const struct
394                                          GNUNET_TIME_AbsoluteNBO *x)
395 {
396   return GNUNET_MY_query_param_auto_from_type (&x->abs_value_us__);
397 }
398
399
400 /* end of my_query_helper.c */