adding library for basic JSON conversions
[oweals/gnunet.git] / src / include / gnunet_pq_lib.h
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 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 include/gnunet_pq_lib.h
18  * @brief helper functions for DB interactions
19  * @author Christian Grothoff
20  */
21 #ifndef GNUNET_PQ_LIB_H_
22 #define GNUNET_PQ_LIB_H_
23
24 #include <libpq-fe.h>
25 #include "gnunet_util_lib.h"
26
27
28 /**
29  * Function called to convert input argument into SQL parameters.
30  *
31  * @param cls closure
32  * @param data pointer to input argument
33  * @param data_len number of bytes in @a data (if applicable)
34  * @param[out] param_values SQL data to set
35  * @param[out] param_lengths SQL length data to set
36  * @param[out] param_formats SQL format data to set
37  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
38  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
39  * @param scratch_length number of entries left in @a scratch
40  * @return -1 on error, number of offsets used in @a scratch otherwise
41  */
42 typedef int
43 (*GNUNET_PQ_QueryConverter)(void *cls,
44                             const void *data,
45                             size_t data_len,
46                             void *param_values[],
47                             int param_lengths[],
48                             int param_formats[],
49                             unsigned int param_length,
50                             void *scratch[],
51                             unsigned int scratch_length);
52
53
54 /**
55  * @brief Description of a DB query parameter.
56  */
57 struct GNUNET_PQ_QueryParam
58 {
59
60   /**
61    * Function for how to handle this type of entry.
62    */
63   GNUNET_PQ_QueryConverter conv;
64
65   /**
66    * Closure for @e conv.
67    */
68   void *conv_cls;
69
70   /**
71    * Data or NULL.
72    */
73   const void *data;
74
75   /**
76    * Size of @e data
77    */
78   size_t size;
79
80   /**
81    * Number of parameters eaten by this operation.
82    */
83   unsigned int num_params;
84 };
85
86
87 /**
88  * End of query parameter specification.
89  */
90 #define GNUNET_PQ_query_param_end { NULL, NULL, NULL, 0, 0 }
91
92
93 /**
94  * Generate query parameter for a buffer @a ptr of
95  * @a ptr_size bytes.
96  *
97  * @param ptr pointer to the query parameter to pass
98  * @oaran ptr_size number of bytes in @a ptr
99  */
100 struct GNUNET_PQ_QueryParam
101 GNUNET_PQ_query_param_fixed_size (const void *ptr,
102                                   size_t ptr_size);
103
104
105 /**
106  * Generate fixed-size query parameter with size determined
107  * by variable type.
108  *
109  * @param x pointer to the query parameter to pass.
110  */
111 #define GNUNET_PQ_query_param_auto_from_type(x) GNUNET_PQ_query_param_fixed_size ((x), sizeof (*(x)))
112
113
114 /**
115  * Generate query parameter for an RSA public key.  The
116  * database must contain a BLOB type in the respective position.
117  *
118  * @param x the query parameter to pass.
119  */
120 struct GNUNET_PQ_QueryParam
121 GNUNET_PQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_rsa_PublicKey *x);
122
123
124 /**
125  * Generate query parameter for an RSA signature.  The
126  * database must contain a BLOB type in the respective position.
127  *
128  * @param x the query parameter to pass
129  */
130 struct GNUNET_PQ_QueryParam
131 GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_rsa_Signature *x);
132
133
134 /**
135  * Generate query parameter for an absolute time value.
136  * The database must store a 64-bit integer.
137  *
138  * @param x pointer to the query parameter to pass
139  */
140 struct GNUNET_PQ_QueryParam
141 GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
142
143
144 /**
145  * Generate query parameter for an absolute time value.
146  * The database must store a 64-bit integer.
147  *
148  * @param x pointer to the query parameter to pass
149  */
150 struct GNUNET_PQ_QueryParam
151 GNUNET_PQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x);
152
153
154 /**
155  * Generate query parameter for an uint16_t in host byte order.
156  *
157  * @param x pointer to the query parameter to pass
158  */
159 struct GNUNET_PQ_QueryParam
160 GNUNET_PQ_query_param_uint16 (const uint16_t *x);
161
162
163 /**
164  * Generate query parameter for an uint32_t in host byte order.
165  *
166  * @param x pointer to the query parameter to pass
167  */
168 struct GNUNET_PQ_QueryParam
169 GNUNET_PQ_query_param_uint32 (const uint32_t *x);
170
171
172 /**
173  * Generate query parameter for an uint16_t in host byte order.
174  *
175  * @param x pointer to the query parameter to pass
176  */
177 struct GNUNET_PQ_QueryParam
178 GNUNET_PQ_query_param_uint64 (const uint64_t *x);
179
180
181 /**
182  * Extract data from a Postgres database @a result at row @a row.
183  *
184  * @param cls closure
185  * @param result where to extract data from
186  * @param int row to extract data from
187  * @param fname name (or prefix) of the fields to extract from
188  * @param[in,out] dst_size where to store size of result, may be NULL
189  * @param[out] dst where to store the result
190  * @return
191  *   #GNUNET_YES if all results could be extracted
192  *   #GNUNET_NO if at least one result was NULL
193  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
194  */
195 typedef int
196 (*GNUNET_PQ_ResultConverter)(void *cls,
197                              PGresult *result,
198                              int row,
199                              const char *fname,
200                              size_t *dst_size,
201                              void *dst);
202
203
204 /**
205  * Function called to clean up memory allocated
206  * by a #GNUNET_PQ_ResultConverter.
207  *
208  * @param cls closure
209  * @param rd result data to clean up
210  */
211 typedef void
212 (*GNUNET_PQ_ResultCleanup)(void *cls,
213                            void *rd);
214
215
216 /**
217  * @brief Description of a DB result cell.
218  */
219 struct GNUNET_PQ_ResultSpec
220 {
221
222   /**
223    * What is the format of the result?
224    */
225   GNUNET_PQ_ResultConverter conv;
226
227   /**
228    * Function to clean up result data, NULL if cleanup is
229    * not necessary.
230    */
231   GNUNET_PQ_ResultCleanup cleaner;
232
233   /**
234    * Closure for @e conv and @e cleaner.
235    */
236   void *cls;
237
238   /**
239    * Destination for the data.
240    */
241   void *dst;
242
243   /**
244    * Allowed size for the data, 0 for variable-size
245    * (in this case, the type of @e dst is a `void **`
246    * and we need to allocate a buffer of the right size).
247    */
248   size_t dst_size;
249
250   /**
251    * Field name of the desired result.
252    */
253   const char *fname;
254
255   /**
256    * Where to store actual size of the result.
257    */
258   size_t *result_size;
259
260 };
261
262
263 /**
264  * End of result parameter specification.
265  *
266  * @return array last entry for the result specification to use
267  */
268 #define GNUNET_PQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, NULL }
269
270
271 /**
272  * Variable-size result expected.
273  *
274  * @param name name of the field in the table
275  * @param[out] dst where to store the result, allocated
276  * @param[out] sptr where to store the size of @a dst
277  * @return array entry for the result specification to use
278  */
279 struct GNUNET_PQ_ResultSpec
280 GNUNET_PQ_result_spec_variable_size (const char *name,
281                                      void **dst,
282                                      size_t *sptr);
283
284
285 /**
286  * Fixed-size result expected.
287  *
288  * @param name name of the field in the table
289  * @param[out] dst where to store the result
290  * @param dst_size number of bytes in @a dst
291  * @return array entry for the result specification to use
292  */
293 struct GNUNET_PQ_ResultSpec
294 GNUNET_PQ_result_spec_fixed_size (const char *name,
295                                   void *dst,
296                                   size_t dst_size);
297
298
299
300 /**
301  * We expect a fixed-size result, with size determined by the type of `* dst`
302  *
303  * @param name name of the field in the table
304  * @param dst point to where to store the result, type fits expected result size
305  * @return array entry for the result specification to use
306  */
307 #define GNUNET_PQ_result_spec_auto_from_type(name, dst) GNUNET_PQ_result_spec_fixed_size (name, (dst), sizeof (*(dst)))
308
309
310 /**
311  * Variable-size result expected.
312  *
313  * @param name name of the field in the table
314  * @param[out] dst where to store the result, allocated
315  * @param[out] sptr where to store the size of @a dst
316  * @return array entry for the result specification to use
317  */
318 struct GNUNET_PQ_ResultSpec
319 GNUNET_PQ_result_spec_variable_size (const char *name,
320                                      void **dst,
321                                      size_t *sptr);
322
323
324 /**
325  * RSA public key expected.
326  *
327  * @param name name of the field in the table
328  * @param[out] rsa where to store the result
329  * @return array entry for the result specification to use
330  */
331 struct GNUNET_PQ_ResultSpec
332 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
333                                       struct GNUNET_CRYPTO_rsa_PublicKey **rsa);
334
335
336 /**
337  * RSA signature expected.
338  *
339  * @param name name of the field in the table
340  * @param[out] sig where to store the result;
341  * @return array entry for the result specification to use
342  */
343 struct GNUNET_PQ_ResultSpec
344 GNUNET_PQ_result_spec_rsa_signature (const char *name,
345                                      struct GNUNET_CRYPTO_rsa_Signature **sig);
346
347
348 /**
349  * Absolute time expected.
350  *
351  * @param name name of the field in the table
352  * @param[out] at where to store the result
353  * @return array entry for the result specification to use
354  */
355 struct GNUNET_PQ_ResultSpec
356 GNUNET_PQ_result_spec_absolute_time (const char *name,
357                                      struct GNUNET_TIME_Absolute *at);
358
359
360 /**
361  * Absolute time expected.
362  *
363  * @param name name of the field in the table
364  * @param[out] at where to store the result
365  * @return array entry for the result specification to use
366  */
367 struct GNUNET_PQ_ResultSpec
368 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
369                                          struct GNUNET_TIME_AbsoluteNBO *at);
370
371
372 /**
373  * uint16_t expected.
374  *
375  * @param name name of the field in the table
376  * @param[out] u16 where to store the result
377  * @return array entry for the result specification to use
378  */
379 struct GNUNET_PQ_ResultSpec
380 GNUNET_PQ_result_spec_uint16 (const char *name,
381                               uint16_t *u16);
382
383
384 /**
385  * uint32_t expected.
386  *
387  * @param name name of the field in the table
388  * @param[out] u32 where to store the result
389  * @return array entry for the result specification to use
390  */
391 struct GNUNET_PQ_ResultSpec
392 GNUNET_PQ_result_spec_uint32 (const char *name,
393                               uint32_t *u32);
394
395
396 /**
397  * uint64_t expected.
398  *
399  * @param name name of the field in the table
400  * @param[out] u64 where to store the result
401  * @return array entry for the result specification to use
402  */
403 struct GNUNET_PQ_ResultSpec
404 GNUNET_PQ_result_spec_uint64 (const char *name,
405                               uint64_t *u64);
406
407
408 /**
409  * Execute a prepared statement.
410  *
411  * @param db_conn database connection
412  * @param name name of the prepared statement
413  * @param params parameters to the statement
414  * @return postgres result
415  */
416 PGresult *
417 GNUNET_PQ_exec_prepared (PGconn *db_conn,
418                          const char *name,
419                          const struct GNUNET_PQ_QueryParam *params);
420
421
422 /**
423  * Extract results from a query result according to the given specification.
424  * If colums are NULL, the destination is not modified, and #GNUNET_NO
425  * is returned.
426  *
427  * @param result result to process
428  * @param[in,out] rs result specification to extract for
429  * @param row row from the result to extract
430  * @return
431  *   #GNUNET_YES if all results could be extracted
432  *   #GNUNET_NO if at least one result was NULL
433  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
434  */
435 int
436 GNUNET_PQ_extract_result (PGresult *result,
437                           struct GNUNET_PQ_ResultSpec *rs,
438                           int row);
439
440
441 /**
442  * Free all memory that was allocated in @a rs during
443  * #GNUNET_PQ_extract_result().
444  *
445  * @param rs reult specification to clean up
446  */
447 void
448 GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs);
449
450
451 #endif  /* GNUNET_PQ_LIB_H_ */
452
453 /* end of include/gnunet_pq_lib.h */