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