bitch more if NULL rows cause PQ result extraction to fail
[oweals/gnunet.git] / src / pq / pq_query_helper.c
1  /*
2   This file is part of GNUnet
3   Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4
5   GNUnet is free software; you can redistribute it and/or modify it under the
6   terms of the GNU General Public License as published by the Free Software
7   Foundation; either version 3, or (at your option) any later version.
8
9   GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License along with
14   GNUnet; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/>
15 */
16 /**
17  * @file pq/pq_query_helper.c
18  * @brief functions to initialize parameter arrays
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_util_lib.h"
23 #include "gnunet_pq_lib.h"
24
25
26 /**
27  * Function called to convert input argument into SQL parameters.
28  *
29  * @param cls closure
30  * @param data pointer to input argument
31  * @param data_len number of bytes in @a data (if applicable)
32  * @param[out] param_values SQL data to set
33  * @param[out] param_lengths SQL length data to set
34  * @param[out] param_formats SQL format data to set
35  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
36  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
37  * @param scratch_length number of entries left in @a scratch
38  * @return -1 on error, number of offsets used in @a scratch otherwise
39  */
40 static int
41 qconv_fixed (void *cls,
42              const void *data,
43              size_t data_len,
44              void *param_values[],
45              int param_lengths[],
46              int param_formats[],
47              unsigned int param_length,
48              void *scratch[],
49              unsigned int scratch_length)
50 {
51   GNUNET_break (NULL == cls);
52   if (1 != param_length)
53     return -1;
54   param_values[0] = (void *) data;
55   param_lengths[0] = data_len;
56   param_formats[0] = 1;
57   return 0;
58 }
59
60
61 /**
62  * Generate query parameter for a buffer @a ptr of
63  * @a ptr_size bytes.
64  *
65  * @param ptr pointer to the query parameter to pass
66  * @oaran ptr_size number of bytes in @a ptr
67  */
68 struct GNUNET_PQ_QueryParam
69 GNUNET_PQ_query_param_fixed_size (const void *ptr,
70                                   size_t ptr_size)
71 {
72   struct GNUNET_PQ_QueryParam res =
73     { &qconv_fixed, NULL, ptr, ptr_size, 1 };
74   return res;
75 }
76
77
78 /**
79  * Generate query parameter for a string.
80  *
81  * @param ptr pointer to the string query parameter to pass
82  */
83 struct GNUNET_PQ_QueryParam
84 GNUNET_PQ_query_param_string (const char *ptr)
85 {
86   return GNUNET_PQ_query_param_fixed_size (ptr, strlen (ptr));
87 }
88
89
90 /**
91  * Function called to convert input argument into SQL parameters.
92  *
93  * @param cls closure
94  * @param data pointer to input argument
95  * @param data_len number of bytes in @a data (if applicable)
96  * @param[out] param_values SQL data to set
97  * @param[out] param_lengths SQL length data to set
98  * @param[out] param_formats SQL format data to set
99  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
100  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
101  * @param scratch_length number of entries left in @a scratch
102  * @return -1 on error, number of offsets used in @a scratch otherwise
103  */
104 static int
105 qconv_uint16 (void *cls,
106               const void *data,
107               size_t data_len,
108               void *param_values[],
109               int param_lengths[],
110               int param_formats[],
111               unsigned int param_length,
112               void *scratch[],
113               unsigned int scratch_length)
114 {
115   const uint16_t *u_hbo = data;
116   uint16_t *u_nbo;
117
118   GNUNET_break (NULL == cls);
119   if (1 != param_length)
120     return -1;
121   u_nbo = GNUNET_new (uint16_t);
122   scratch[0] = u_nbo;
123   *u_nbo = htons (*u_hbo);
124   param_values[0] = (void *) u_nbo;
125   param_lengths[0] = sizeof (uint16_t);
126   param_formats[0] = 1;
127   return 1;
128 }
129
130
131 /**
132  * Generate query parameter for an uint16_t in host byte order.
133  *
134  * @param x pointer to the query parameter to pass
135  */
136 struct GNUNET_PQ_QueryParam
137 GNUNET_PQ_query_param_uint16 (const uint16_t *x)
138 {
139   struct GNUNET_PQ_QueryParam res =
140     { &qconv_uint16, NULL, x, sizeof (*x), 1 };
141   return res;
142 }
143
144
145 /**
146  * Function called to convert input argument into SQL parameters.
147  *
148  * @param cls closure
149  * @param data pointer to input argument
150  * @param data_len number of bytes in @a data (if applicable)
151  * @param[out] param_values SQL data to set
152  * @param[out] param_lengths SQL length data to set
153  * @param[out] param_formats SQL format data to set
154  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
155  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
156  * @param scratch_length number of entries left in @a scratch
157  * @return -1 on error, number of offsets used in @a scratch otherwise
158  */
159 static int
160 qconv_uint32 (void *cls,
161               const void *data,
162               size_t data_len,
163               void *param_values[],
164               int param_lengths[],
165               int param_formats[],
166               unsigned int param_length,
167               void *scratch[],
168               unsigned int scratch_length)
169 {
170   const uint32_t *u_hbo = data;
171   uint32_t *u_nbo;
172
173   GNUNET_break (NULL == cls);
174   if (1 != param_length)
175     return -1;
176   u_nbo = GNUNET_new (uint32_t);
177   scratch[0] = u_nbo;
178   *u_nbo = htonl (*u_hbo);
179   param_values[0] = (void *) u_nbo;
180   param_lengths[0] = sizeof (uint32_t);
181   param_formats[0] = 1;
182   return 1;
183 }
184
185
186 /**
187  * Generate query parameter for an uint32_t in host byte order.
188  *
189  * @param x pointer to the query parameter to pass
190  */
191 struct GNUNET_PQ_QueryParam
192 GNUNET_PQ_query_param_uint32 (const uint32_t *x)
193 {
194   struct GNUNET_PQ_QueryParam res =
195     { &qconv_uint32, NULL, x, sizeof (*x), 1 };
196   return res;
197 }
198
199
200 /**
201  * Function called to convert input argument into SQL parameters.
202  *
203  * @param cls closure
204  * @param data pointer to input argument
205  * @param data_len number of bytes in @a data (if applicable)
206  * @param[out] param_values SQL data to set
207  * @param[out] param_lengths SQL length data to set
208  * @param[out] param_formats SQL format data to set
209  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
210  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
211  * @param scratch_length number of entries left in @a scratch
212  * @return -1 on error, number of offsets used in @a scratch otherwise
213  */
214 static int
215 qconv_uint64 (void *cls,
216               const void *data,
217               size_t data_len,
218               void *param_values[],
219               int param_lengths[],
220               int param_formats[],
221               unsigned int param_length,
222               void *scratch[],
223               unsigned int scratch_length)
224 {
225   const uint64_t *u_hbo = data;
226   uint64_t *u_nbo;
227
228   GNUNET_break (NULL == cls);
229   if (1 != param_length)
230     return -1;
231   u_nbo = GNUNET_new (uint64_t);
232   scratch[0] = u_nbo;
233   *u_nbo = GNUNET_htonll (*u_hbo);
234   param_values[0] = (void *) u_nbo;
235   param_lengths[0] = sizeof (uint64_t);
236   param_formats[0] = 1;
237   return 1;
238 }
239
240
241 /**
242  * Generate query parameter for an uint64_t in host byte order.
243  *
244  * @param x pointer to the query parameter to pass
245  */
246 struct GNUNET_PQ_QueryParam
247 GNUNET_PQ_query_param_uint64 (const uint64_t *x)
248 {
249   struct GNUNET_PQ_QueryParam res =
250     { &qconv_uint64, NULL, x, sizeof (*x), 1 };
251   return res;
252 }
253
254
255 /**
256  * Function called to convert input argument into SQL parameters.
257  *
258  * @param cls closure
259  * @param data pointer to input argument
260  * @param data_len number of bytes in @a data (if applicable)
261  * @param[out] param_values SQL data to set
262  * @param[out] param_lengths SQL length data to set
263  * @param[out] param_formats SQL format data to set
264  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
265  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
266  * @param scratch_length number of entries left in @a scratch
267  * @return -1 on error, number of offsets used in @a scratch otherwise
268  */
269 static int
270 qconv_rsa_public_key (void *cls,
271                       const void *data,
272                       size_t data_len,
273                       void *param_values[],
274                       int param_lengths[],
275                       int param_formats[],
276                       unsigned int param_length,
277                       void *scratch[],
278                       unsigned int scratch_length)
279 {
280   const struct GNUNET_CRYPTO_RsaPublicKey *rsa = data;
281   char *buf;
282   size_t buf_size;
283
284   GNUNET_break (NULL == cls);
285   if (1 != param_length)
286     return -1;
287   buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa,
288                                                   &buf);
289   scratch[0] = buf;
290   param_values[0] = (void *) buf;
291   param_lengths[0] = buf_size - 1; /* DB doesn't like the trailing \0 */
292   param_formats[0] = 1;
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_PQ_QueryParam
305 GNUNET_PQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x)
306 {
307   struct GNUNET_PQ_QueryParam res =
308     { &qconv_rsa_public_key, NULL, (x), 0, 1 };
309   return res;
310 }
311
312
313 /**
314  * Function called to convert input argument into SQL parameters.
315  *
316  * @param cls closure
317  * @param data pointer to input argument
318  * @param data_len number of bytes in @a data (if applicable)
319  * @param[out] param_values SQL data to set
320  * @param[out] param_lengths SQL length data to set
321  * @param[out] param_formats SQL format data to set
322  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
323  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
324  * @param scratch_length number of entries left in @a scratch
325  * @return -1 on error, number of offsets used in @a scratch otherwise
326  */
327 static int
328 qconv_rsa_signature (void *cls,
329                      const void *data,
330                      size_t data_len,
331                      void *param_values[],
332                      int param_lengths[],
333                      int param_formats[],
334                      unsigned int param_length,
335                      void *scratch[],
336                      unsigned int scratch_length)
337 {
338   const struct GNUNET_CRYPTO_RsaSignature *sig = data;
339   char *buf;
340   size_t buf_size;
341
342   GNUNET_break (NULL == cls);
343   if (1 != param_length)
344     return -1;
345   buf_size = GNUNET_CRYPTO_rsa_signature_encode (sig,
346                                                  &buf);
347   scratch[0] = buf;
348   param_values[0] = (void *) buf;
349   param_lengths[0] = buf_size - 1; /* DB doesn't like the trailing \0 */
350   param_formats[0] = 1;
351   return 1;
352 }
353
354
355 /**
356  * Generate query parameter for an RSA signature.  The
357  * database must contain a BLOB type in the respective position.
358  *
359  * @param x the query parameter to pass
360  * @return array entry for the query parameters to use
361  */
362 struct GNUNET_PQ_QueryParam
363 GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
364 {
365   struct GNUNET_PQ_QueryParam res =
366     { &qconv_rsa_signature, NULL, (x), 0, 1 };
367   return res;
368 }
369
370
371 /**
372  * Generate query parameter for an absolute time value.
373  * The database must store a 64-bit integer.
374  *
375  * @param x pointer to the query parameter to pass
376  * @return array entry for the query parameters to use
377  */
378 struct GNUNET_PQ_QueryParam
379 GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
380 {
381   return GNUNET_PQ_query_param_uint64 (&x->abs_value_us);
382 }
383
384
385 /**
386  * Generate query parameter for an absolute time value.
387  * The database must store a 64-bit integer.
388  *
389  * @param x pointer to the query parameter to pass
390  */
391 struct GNUNET_PQ_QueryParam
392 GNUNET_PQ_query_param_absolute_time_nbo(const struct GNUNET_TIME_AbsoluteNBO *x)
393 {
394   return GNUNET_PQ_query_param_auto_from_type (&x->abs_value_us__);
395 }
396
397
398 /* end of pq_query_helper.c */