Merge branch 'master' of ssh://gnunet.org/gnunet
[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 Postgres 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 /**
107  * Generate query parameter for a string.
108  *
109  * @param ptr pointer to the string query parameter to pass
110  */
111 struct GNUNET_PQ_QueryParam
112 GNUNET_PQ_query_param_string (const char *ptr);
113
114
115 /**
116  * Generate fixed-size query parameter with size determined
117  * by variable type.
118  *
119  * @param x pointer to the query parameter to pass.
120  */
121 #define GNUNET_PQ_query_param_auto_from_type(x) GNUNET_PQ_query_param_fixed_size ((x), sizeof (*(x)))
122
123
124 /**
125  * Generate query parameter for an RSA public key.  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_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x);
132
133
134 /**
135  * Generate query parameter for an RSA signature.  The
136  * database must contain a BLOB type in the respective position.
137  *
138  * @param x the query parameter to pass
139  */
140 struct GNUNET_PQ_QueryParam
141 GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *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 (const struct GNUNET_TIME_Absolute *x);
152
153
154 /**
155  * Generate query parameter for an absolute time value.
156  * The database must store a 64-bit integer.
157  *
158  * @param x pointer to the query parameter to pass
159  */
160 struct GNUNET_PQ_QueryParam
161 GNUNET_PQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x);
162
163
164 /**
165  * Generate query parameter for an uint16_t in host byte order.
166  *
167  * @param x pointer to the query parameter to pass
168  */
169 struct GNUNET_PQ_QueryParam
170 GNUNET_PQ_query_param_uint16 (const uint16_t *x);
171
172
173 /**
174  * Generate query parameter for an uint32_t in host byte order.
175  *
176  * @param x pointer to the query parameter to pass
177  */
178 struct GNUNET_PQ_QueryParam
179 GNUNET_PQ_query_param_uint32 (const uint32_t *x);
180
181
182 /**
183  * Generate query parameter for an uint16_t in host byte order.
184  *
185  * @param x pointer to the query parameter to pass
186  */
187 struct GNUNET_PQ_QueryParam
188 GNUNET_PQ_query_param_uint64 (const uint64_t *x);
189
190
191 /**
192  * Extract data from a Postgres database @a result at row @a row.
193  *
194  * @param cls closure
195  * @param result where to extract data from
196  * @param int row to extract data from
197  * @param fname name (or prefix) of the fields to extract from
198  * @param[in,out] dst_size where to store size of result, may be NULL
199  * @param[out] dst where to store the result
200  * @return
201  *   #GNUNET_YES if all results could be extracted
202  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
203  */
204 typedef int
205 (*GNUNET_PQ_ResultConverter)(void *cls,
206                              PGresult *result,
207                              int row,
208                              const char *fname,
209                              size_t *dst_size,
210                              void *dst);
211
212
213 /**
214  * Function called to clean up memory allocated
215  * by a #GNUNET_PQ_ResultConverter.
216  *
217  * @param cls closure
218  * @param rd result data to clean up
219  */
220 typedef void
221 (*GNUNET_PQ_ResultCleanup)(void *cls,
222                            void *rd);
223
224
225 /**
226  * @brief Description of a DB result cell.
227  */
228 struct GNUNET_PQ_ResultSpec
229 {
230
231   /**
232    * What is the format of the result?
233    */
234   GNUNET_PQ_ResultConverter conv;
235
236   /**
237    * Function to clean up result data, NULL if cleanup is
238    * not necessary.
239    */
240   GNUNET_PQ_ResultCleanup cleaner;
241
242   /**
243    * Closure for @e conv and @e cleaner.
244    */
245   void *cls;
246
247   /**
248    * Destination for the data.
249    */
250   void *dst;
251
252   /**
253    * Allowed size for the data, 0 for variable-size
254    * (in this case, the type of @e dst is a `void **`
255    * and we need to allocate a buffer of the right size).
256    */
257   size_t dst_size;
258
259   /**
260    * Field name of the desired result.
261    */
262   const char *fname;
263
264   /**
265    * Where to store actual size of the result.
266    */
267   size_t *result_size;
268
269 };
270
271
272 /**
273  * End of result parameter specification.
274  *
275  * @return array last entry for the result specification to use
276  */
277 #define GNUNET_PQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, NULL }
278
279
280 /**
281  * Variable-size result expected.
282  *
283  * @param name name of the field in the table
284  * @param[out] dst where to store the result, allocated
285  * @param[out] sptr where to store the size of @a dst
286  * @return array entry for the result specification to use
287  */
288 struct GNUNET_PQ_ResultSpec
289 GNUNET_PQ_result_spec_variable_size (const char *name,
290                                      void **dst,
291                                      size_t *sptr);
292
293
294 /**
295  * Fixed-size result expected.
296  *
297  * @param name name of the field in the table
298  * @param[out] dst where to store the result
299  * @param dst_size number of bytes in @a dst
300  * @return array entry for the result specification to use
301  */
302 struct GNUNET_PQ_ResultSpec
303 GNUNET_PQ_result_spec_fixed_size (const char *name,
304                                   void *dst,
305                                   size_t dst_size);
306
307
308
309 /**
310  * We expect a fixed-size result, with size determined by the type of `* dst`
311  *
312  * @param name name of the field in the table
313  * @param dst point to where to store the result, type fits expected result size
314  * @return array entry for the result specification to use
315  */
316 #define GNUNET_PQ_result_spec_auto_from_type(name, dst) GNUNET_PQ_result_spec_fixed_size (name, (dst), sizeof (*(dst)))
317
318
319 /**
320  * 0-terminated string expected.
321  *
322  * @param name name of the field in the table
323  * @param[out] dst where to store the result, allocated
324  * @return array entry for the result specification to use
325  */
326 struct GNUNET_PQ_ResultSpec
327 GNUNET_PQ_result_spec_string (const char *name,
328                               char **dst);
329
330
331 /**
332  * RSA public key expected.
333  *
334  * @param name name of the field in the table
335  * @param[out] rsa where to store the result
336  * @return array entry for the result specification to use
337  */
338 struct GNUNET_PQ_ResultSpec
339 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
340                                       struct GNUNET_CRYPTO_RsaPublicKey **rsa);
341
342
343 /**
344  * RSA signature expected.
345  *
346  * @param name name of the field in the table
347  * @param[out] sig where to store the result;
348  * @return array entry for the result specification to use
349  */
350 struct GNUNET_PQ_ResultSpec
351 GNUNET_PQ_result_spec_rsa_signature (const char *name,
352                                      struct GNUNET_CRYPTO_RsaSignature **sig);
353
354
355 /**
356  * Absolute time expected.
357  *
358  * @param name name of the field in the table
359  * @param[out] at where to store the result
360  * @return array entry for the result specification to use
361  */
362 struct GNUNET_PQ_ResultSpec
363 GNUNET_PQ_result_spec_absolute_time (const char *name,
364                                      struct GNUNET_TIME_Absolute *at);
365
366
367 /**
368  * Absolute time expected.
369  *
370  * @param name name of the field in the table
371  * @param[out] at where to store the result
372  * @return array entry for the result specification to use
373  */
374 struct GNUNET_PQ_ResultSpec
375 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
376                                          struct GNUNET_TIME_AbsoluteNBO *at);
377
378
379 /**
380  * uint16_t expected.
381  *
382  * @param name name of the field in the table
383  * @param[out] u16 where to store the result
384  * @return array entry for the result specification to use
385  */
386 struct GNUNET_PQ_ResultSpec
387 GNUNET_PQ_result_spec_uint16 (const char *name,
388                               uint16_t *u16);
389
390
391 /**
392  * uint32_t expected.
393  *
394  * @param name name of the field in the table
395  * @param[out] u32 where to store the result
396  * @return array entry for the result specification to use
397  */
398 struct GNUNET_PQ_ResultSpec
399 GNUNET_PQ_result_spec_uint32 (const char *name,
400                               uint32_t *u32);
401
402
403 /**
404  * uint64_t expected.
405  *
406  * @param name name of the field in the table
407  * @param[out] u64 where to store the result
408  * @return array entry for the result specification to use
409  */
410 struct GNUNET_PQ_ResultSpec
411 GNUNET_PQ_result_spec_uint64 (const char *name,
412                               uint64_t *u64);
413
414
415 /**
416  * Execute a prepared statement.
417  *
418  * @param db_conn database connection
419  * @param name name of the prepared statement
420  * @param params parameters to the statement
421  * @return postgres result
422  */
423 PGresult *
424 GNUNET_PQ_exec_prepared (PGconn *db_conn,
425                          const char *name,
426                          const struct GNUNET_PQ_QueryParam *params);
427
428
429 /**
430  * Extract results from a query result according to the given specification.
431  *
432  * @param result result to process
433  * @param[in,out] rs result specification to extract for
434  * @param row row from the result to extract
435  * @return
436  *   #GNUNET_YES if all results could be extracted
437  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
438  */
439 int
440 GNUNET_PQ_extract_result (PGresult *result,
441                           struct GNUNET_PQ_ResultSpec *rs,
442                           int row);
443
444
445 /**
446  * Free all memory that was allocated in @a rs during
447  * #GNUNET_PQ_extract_result().
448  *
449  * @param rs reult specification to clean up
450  */
451 void
452 GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs);
453
454
455 #endif  /* GNUNET_PQ_LIB_H_ */
456
457 /* end of include/gnunet_pq_lib.h */