add function for string parameters
[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 /**
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_NO if at least one result was NULL
203  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
204  */
205 typedef int
206 (*GNUNET_PQ_ResultConverter)(void *cls,
207                              PGresult *result,
208                              int row,
209                              const char *fname,
210                              size_t *dst_size,
211                              void *dst);
212
213
214 /**
215  * Function called to clean up memory allocated
216  * by a #GNUNET_PQ_ResultConverter.
217  *
218  * @param cls closure
219  * @param rd result data to clean up
220  */
221 typedef void
222 (*GNUNET_PQ_ResultCleanup)(void *cls,
223                            void *rd);
224
225
226 /**
227  * @brief Description of a DB result cell.
228  */
229 struct GNUNET_PQ_ResultSpec
230 {
231
232   /**
233    * What is the format of the result?
234    */
235   GNUNET_PQ_ResultConverter conv;
236
237   /**
238    * Function to clean up result data, NULL if cleanup is
239    * not necessary.
240    */
241   GNUNET_PQ_ResultCleanup cleaner;
242
243   /**
244    * Closure for @e conv and @e cleaner.
245    */
246   void *cls;
247
248   /**
249    * Destination for the data.
250    */
251   void *dst;
252
253   /**
254    * Allowed size for the data, 0 for variable-size
255    * (in this case, the type of @e dst is a `void **`
256    * and we need to allocate a buffer of the right size).
257    */
258   size_t dst_size;
259
260   /**
261    * Field name of the desired result.
262    */
263   const char *fname;
264
265   /**
266    * Where to store actual size of the result.
267    */
268   size_t *result_size;
269
270 };
271
272
273 /**
274  * End of result parameter specification.
275  *
276  * @return array last entry for the result specification to use
277  */
278 #define GNUNET_PQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, NULL }
279
280
281 /**
282  * Variable-size result expected.
283  *
284  * @param name name of the field in the table
285  * @param[out] dst where to store the result, allocated
286  * @param[out] sptr where to store the size of @a dst
287  * @return array entry for the result specification to use
288  */
289 struct GNUNET_PQ_ResultSpec
290 GNUNET_PQ_result_spec_variable_size (const char *name,
291                                      void **dst,
292                                      size_t *sptr);
293
294
295 /**
296  * Fixed-size result expected.
297  *
298  * @param name name of the field in the table
299  * @param[out] dst where to store the result
300  * @param dst_size number of bytes in @a dst
301  * @return array entry for the result specification to use
302  */
303 struct GNUNET_PQ_ResultSpec
304 GNUNET_PQ_result_spec_fixed_size (const char *name,
305                                   void *dst,
306                                   size_t dst_size);
307
308
309
310 /**
311  * We expect a fixed-size result, with size determined by the type of `* dst`
312  *
313  * @param name name of the field in the table
314  * @param dst point to where to store the result, type fits expected result size
315  * @return array entry for the result specification to use
316  */
317 #define GNUNET_PQ_result_spec_auto_from_type(name, dst) GNUNET_PQ_result_spec_fixed_size (name, (dst), sizeof (*(dst)))
318
319
320 /**
321  * Variable-size result expected.
322  *
323  * @param name name of the field in the table
324  * @param[out] dst where to store the result, allocated
325  * @param[out] sptr where to store the size of @a dst
326  * @return array entry for the result specification to use
327  */
328 struct GNUNET_PQ_ResultSpec
329 GNUNET_PQ_result_spec_variable_size (const char *name,
330                                      void **dst,
331                                      size_t *sptr);
332
333
334 /**
335  * RSA public key expected.
336  *
337  * @param name name of the field in the table
338  * @param[out] rsa where to store the result
339  * @return array entry for the result specification to use
340  */
341 struct GNUNET_PQ_ResultSpec
342 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
343                                       struct GNUNET_CRYPTO_RsaPublicKey **rsa);
344
345
346 /**
347  * RSA signature expected.
348  *
349  * @param name name of the field in the table
350  * @param[out] sig where to store the result;
351  * @return array entry for the result specification to use
352  */
353 struct GNUNET_PQ_ResultSpec
354 GNUNET_PQ_result_spec_rsa_signature (const char *name,
355                                      struct GNUNET_CRYPTO_RsaSignature **sig);
356
357
358 /**
359  * Absolute time expected.
360  *
361  * @param name name of the field in the table
362  * @param[out] at where to store the result
363  * @return array entry for the result specification to use
364  */
365 struct GNUNET_PQ_ResultSpec
366 GNUNET_PQ_result_spec_absolute_time (const char *name,
367                                      struct GNUNET_TIME_Absolute *at);
368
369
370 /**
371  * Absolute time expected.
372  *
373  * @param name name of the field in the table
374  * @param[out] at where to store the result
375  * @return array entry for the result specification to use
376  */
377 struct GNUNET_PQ_ResultSpec
378 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
379                                          struct GNUNET_TIME_AbsoluteNBO *at);
380
381
382 /**
383  * uint16_t expected.
384  *
385  * @param name name of the field in the table
386  * @param[out] u16 where to store the result
387  * @return array entry for the result specification to use
388  */
389 struct GNUNET_PQ_ResultSpec
390 GNUNET_PQ_result_spec_uint16 (const char *name,
391                               uint16_t *u16);
392
393
394 /**
395  * uint32_t expected.
396  *
397  * @param name name of the field in the table
398  * @param[out] u32 where to store the result
399  * @return array entry for the result specification to use
400  */
401 struct GNUNET_PQ_ResultSpec
402 GNUNET_PQ_result_spec_uint32 (const char *name,
403                               uint32_t *u32);
404
405
406 /**
407  * uint64_t expected.
408  *
409  * @param name name of the field in the table
410  * @param[out] u64 where to store the result
411  * @return array entry for the result specification to use
412  */
413 struct GNUNET_PQ_ResultSpec
414 GNUNET_PQ_result_spec_uint64 (const char *name,
415                               uint64_t *u64);
416
417
418 /**
419  * Execute a prepared statement.
420  *
421  * @param db_conn database connection
422  * @param name name of the prepared statement
423  * @param params parameters to the statement
424  * @return postgres result
425  */
426 PGresult *
427 GNUNET_PQ_exec_prepared (PGconn *db_conn,
428                          const char *name,
429                          const struct GNUNET_PQ_QueryParam *params);
430
431
432 /**
433  * Extract results from a query result according to the given specification.
434  * If colums are NULL, the destination is not modified, and #GNUNET_NO
435  * is returned.
436  *
437  * @param result result to process
438  * @param[in,out] rs result specification to extract for
439  * @param row row from the result to extract
440  * @return
441  *   #GNUNET_YES if all results could be extracted
442  *   #GNUNET_NO if at least one result was NULL
443  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
444  */
445 int
446 GNUNET_PQ_extract_result (PGresult *result,
447                           struct GNUNET_PQ_ResultSpec *rs,
448                           int row);
449
450
451 /**
452  * Free all memory that was allocated in @a rs during
453  * #GNUNET_PQ_extract_result().
454  *
455  * @param rs reult specification to clean up
456  */
457 void
458 GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs);
459
460
461 #endif  /* GNUNET_PQ_LIB_H_ */
462
463 /* end of include/gnunet_pq_lib.h */