61fd6459f24544d16561ccb16128d4a961c73ce9
[oweals/gnunet.git] / src / include / gnunet_my_lib.h
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2012 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20 /**
21  * @author Christian Grothoff
22  * @author Christophe Genevey
23  *
24  * @file
25  * Helper library to access a MySQL database
26  *
27  * @defgroup mysql  MySQL library
28  * Helper library to access a MySQL database.
29  * @{
30  */
31 #ifndef GNUNET_MY_LIB_H
32 #define GNUNET_MY_LIB_H
33
34 #include "gnunet_util_lib.h"
35 #include "gnunet_mysql_lib.h"
36 #include <mysql/mysql.h>
37
38 #ifdef __cplusplus
39 extern "C"
40 {
41 #if 0                           /* keep Emacsens' auto-indent happy */
42 }
43 #endif
44 #endif
45
46
47
48 /**
49  * Information we pass to #GNUNET_MY_exec_prepared() to
50  * initialize the arguments of the prepared statement.
51  */
52 struct GNUNET_MY_QueryParam;
53
54
55 /**
56  * Function called to convert input argument into SQL parameters.
57  *
58  * @param cls closure
59  * @param pq data about the query
60  * @param qbind array of parameters to initialize
61  * @return -1 on error
62  */
63 typedef int
64 (*GNUNET_MY_QueryConverter)(void *cls,
65                             const struct GNUNET_MY_QueryParam *qp,
66                             MYSQL_BIND *qbind);
67
68
69 /**
70  * Function called to cleanup result data.
71  *
72  * @param cls closure
73  * @param rs spec to clean up
74  */
75 typedef void
76 (*GNUNET_MY_QueryCleanup)(void *cls,
77                            MYSQL_BIND *qbind);
78 /**
79  * Information we pass to #GNUNET_MY_exec_prepared() to
80  * initialize the arguments of the prepared statement.
81  */
82
83
84 struct GNUNET_MY_QueryParam
85 {
86
87   /**
88    * Function to call for the type conversion.
89    */
90   GNUNET_MY_QueryConverter conv;
91
92    /**
93    * Function to call for cleaning up the query. Can be NULL.
94    */
95   GNUNET_MY_QueryCleanup cleaner;
96
97   /**
98    * Closure for @e conv.
99    */
100   void *conv_cls;
101
102   /**
103    * Number of arguments the @a conv converter expects to initialize.
104    */
105   unsigned int num_params;
106
107   /**
108    * Information to pass to @e conv.
109    */
110   const void *data;
111
112   /**
113    * Information to pass to @e conv.  Size of @a data.
114    */
115   unsigned long data_len;
116
117 };
118
119 /**
120  * End of query parameter specification.
121  *
122  * @return array last entry for the result specification to use
123  */
124 #define GNUNET_MY_query_param_end { NULL, NULL, NULL, 0, NULL, 0 }
125
126
127 /**
128  * Generate query parameter for a buffer @a ptr of
129  * @a ptr_size bytes.FG
130  *
131  * @param ptr pointer to the query parameter to pass
132  * @oaran ptr_size number of bytes in @a ptr
133  */
134 struct GNUNET_MY_QueryParam
135 GNUNET_MY_query_param_fixed_size (const void *ptr,
136                                   size_t ptr_size);
137
138
139 /**
140  * Run a prepared SELECT statement.
141  *
142  * @param mc mysql context
143  * @param sh handle to SELECT statment
144  * @param params parameters to the statement
145  * @return TBD
146  */
147 int
148 GNUNET_MY_exec_prepared (struct GNUNET_MYSQL_Context *mc,
149                          struct GNUNET_MYSQL_StatementHandle *sh,
150                          struct GNUNET_MY_QueryParam *params);
151
152
153 /**
154  * Information we pass to #GNUNET_MY_extract_result() to
155  * initialize the arguments of the prepared statement.
156  */
157 struct GNUNET_MY_ResultParam;
158
159 /**
160  * Information we pass to #GNUNET_MY_extract_result() to
161  * initialize the arguments of the prepared statement.
162  */
163 struct GNUNET_MY_ResultSpec;
164
165 /**
166  * Function called to convert input argument into SQL parameters.
167  *
168  * @param cls closure
169  * @param[in,out] rs
170  * @param stmt the mysql statement that is being run
171  * @param column the column that is being processed
172  * @param[out] results
173  * @return -1 on error
174  */
175 typedef int
176 (*GNUNET_MY_ResultConverter)(void *cls,
177                              struct GNUNET_MY_ResultSpec *rs,
178                              MYSQL_STMT *stmt,
179                              unsigned int column,
180                              MYSQL_BIND *results);
181
182 /**
183  * Function called to cleanup result data.
184  *
185  * @param cls closure
186  * @param rs spec to clean up
187  */
188 typedef void
189 (*GNUNET_MY_ResultCleanup)(void *cls,
190                            struct GNUNET_MY_ResultSpec *rs);
191
192
193 /**
194  * Information we pass to #GNUNET_MY_extract_result() to
195  * initialize the arguments of the prepared statement.
196  */
197 struct GNUNET_MY_ResultSpec
198 {
199
200   /**
201    * Function to call to initialize the MYSQL_BIND array.
202    */
203   GNUNET_MY_ResultConverter pre_conv;
204
205   /**
206    * Function to call for converting the result. Can be NULL.
207    */
208   GNUNET_MY_ResultConverter post_conv;
209
210     /**
211    * Function to call for cleaning up the result. Can be NULL.
212    */
213   GNUNET_MY_ResultCleanup cleaner;
214
215   /**
216    * Closure for @e conv.
217    */
218   void *conv_cls;
219
220   /**
221    * Destination for the data.
222    */
223   void *dst;
224
225   /**
226    * Allowed size for the data, 0 for variable-size
227    * (in this case, the type of @e dst is a `void **`
228    * and we need to allocate a buffer of the right size).
229    */
230   size_t dst_size;
231
232   /**
233    * Where to store actual size of the result.
234    */
235   size_t *result_size;
236
237   /**
238    * How many fields does this result specification occupy
239    * in the result returned by MySQL.
240    */
241   unsigned int num_fields;
242
243   /**
244    * Location where we temporarily store the output buffer
245    * length from MySQL.  Internal to libgnunetmy.
246    */
247   unsigned long mysql_bind_output_length;
248
249 };
250
251
252 /**
253  * End of result speceter specification.
254  *
255  * @return array last entry for the result specification to use
256  */
257 #define GNUNET_MY_result_spec_end { NULL, NULL, NULL, 0, NULL, 0 }
258
259
260
261 /**
262  * Obtain fixed size result of @a ptr_size bytes from
263  * MySQL, store in already allocated buffer at @a ptr.
264  *
265  * @spec ptr where to write the result
266  * @oaran ptr_size number of bytes available at @a ptr
267  */
268 struct GNUNET_MY_ResultSpec
269 GNUNET_MY_result_spec_fixed_size (void *ptr,
270                                   size_t ptr_size);
271
272 /**
273   * Generate query parameter for a string
274   *
275   *@param ptr pointer to the string query parameter to pass
276   */
277 struct GNUNET_MY_QueryParam
278 GNUNET_MY_query_param_string (const char *ptr);
279
280 /**
281   * Generate fixed-size query parameter with size determined
282   * by variable type.
283   *
284   * @param x pointer to the query parameter to pass
285   */
286 #define GNUNET_MY_query_param_auto_from_type(x) GNUNET_MY_query_param_fixed_size ((x), sizeof (*(x)))
287
288 /**
289   * Generate query parameter for an RSA public key. The
290   * database must contain a BLOB type in the respective position.
291   *
292   * @param x the query parameter to pass
293   * @return array entry for the query parameters to use
294   */
295 struct GNUNET_MY_QueryParam
296 GNUNET_MY_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x);
297
298 /**
299   * Generate query parameter for an RSA signature. The
300   * database must contain a BLOB type in the respective position
301   *
302   *@param x the query parameter to pass
303   *@return array entry for the query parameters to use
304   */
305 struct GNUNET_MY_QueryParam
306 GNUNET_MY_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x);
307
308 /**
309   * Generate query parameter for an absolute time value.
310   * The database must store a 64-bit integer.
311   *
312   *@param x pointer to the query parameter to pass
313   *@return array entry for the query parameters to use
314   */
315 struct GNUNET_MY_QueryParam
316 GNUNET_MY_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
317
318
319 /**
320   * Generate query parameter for an absolute time value.
321   * The database must store a 64-bit integer.
322   *
323   *@param x pointer to the query parameter to pass
324   */
325 struct GNUNET_MY_QueryParam
326 GNUNET_MY_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x);
327
328 /**
329   * Generate query parameter for an uint16_t in host byte order.
330   *
331   * @param x pointer to the query parameter to pass
332   */
333 struct GNUNET_MY_QueryParam
334 GNUNET_MY_query_param_uint16 (const uint16_t *x);
335
336 /**
337   * Generate query parameter for an uint32_t in host byte order
338   *
339   *@param x pointer to the query parameter to pass
340   */
341 struct GNUNET_MY_QueryParam
342 GNUNET_MY_query_param_uint32 (const uint32_t *x);
343
344 /**
345   * Generate query parameter for an uint64_t in host byte order
346   *
347   *@param x pointer to the query parameter to pass
348   */
349 struct GNUNET_MY_QueryParam
350 GNUNET_MY_query_param_uint64 (const uint64_t *x);
351
352 /**
353  * We expect a fixed-size result, with size determined by the type of `* dst`
354  *
355  * @spec name name of the field in the table
356  * @spec dst point to where to store the result, type fits expected result size
357  * @return array entry for the result specification to use
358  */
359 #define GNUNET_MY_result_spec_auto_from_type(dst) GNUNET_MY_result_spec_fixed_size ((dst), sizeof (*(dst)))
360
361
362 /**
363  * Variable-size result expected
364  *
365  * @param[out] dst where to store the result, allocated
366  * @param[out] sptr where to store the size of @a dst
367  * @return array entru for the result specification to use
368  */
369 struct GNUNET_MY_ResultSpec
370 GNUNET_MY_result_spec_variable_size (void **dst,
371                                      size_t *ptr_size);
372
373 /**
374  * RSA public key expected
375  *
376  * @param name name of the field in the table
377  * @param[out] rsa where to store the result
378  * @return array entry for the result specification to use
379  */
380 struct GNUNET_MY_ResultSpec
381 GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa);
382
383
384 /**
385  * RSA signature expected.
386  *
387  * @param[out] sig where to store the result;
388  * @return array entry for the result specification to use
389  */
390 struct GNUNET_MY_ResultSpec
391 GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig);
392
393 /**
394   * 0- terminated string exprected.
395   *
396   * @param[out] dst where to store the result, allocated
397   * @return array entry for the result specification to use
398   */
399 struct GNUNET_MY_ResultSpec
400 GNUNET_MY_result_spec_string (char **dst);
401
402 /**
403   * Absolute time expected
404   *
405   * @param name name of the field in the table
406   * @param[out] at where to store the result
407   * @return array entry for the result specification to use
408   */
409 struct GNUNET_MY_ResultSpec
410 GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at);
411
412 /**
413   * Absolute time in network byte order expected
414   *
415   * @param[out] at where to store the result
416   * @return array entry for the result specification to use
417   */
418 struct GNUNET_MY_ResultSpec
419 GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at);
420
421 /**
422   * uint16_t expected
423   *
424   * @param[out] u16 where to store the result
425   * @return array entry for the result specification to use
426   */
427 struct GNUNET_MY_ResultSpec
428 GNUNET_MY_result_spec_uint16 (uint16_t *u16);
429
430 /**
431   * uint32_t expected
432   *
433   * @param[out] u32 where to store the result
434   * @return array entry for the result specification to use
435   */
436 struct GNUNET_MY_ResultSpec
437 GNUNET_MY_result_spec_uint32 (uint32_t *u32);
438
439 /**
440   * uint64_t expected.
441   *
442   * @param[out] u64 where to store the result
443   * @return array entry for the result specification to use
444   */
445 struct GNUNET_MY_ResultSpec
446 GNUNET_MY_result_spec_uint64 (uint64_t *u64);
447
448
449 /**
450  * Extract results from a query result according to the given
451  * specification.  Always fetches the next row.
452  *
453  * @param sh statement that returned results
454  * @param rs specification to extract for
455  * @return
456  *  #GNUNET_YES if all results could be extracted
457  *  #GNUNET_NO if there is no more data in the result set
458  *  #GNUNET_SYSERR if a result was invalid
459  */
460 int
461 GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh,
462                           struct GNUNET_MY_ResultSpec *specs);
463
464
465 /**
466  * Free all memory that was allocated in @a qp during
467  * #GNUNET_MY_exect_prepared().
468  *
469  * @param qp query specification to clean up
470  * @param qbind mysql query
471  */
472 void
473 GNUNET_MY_cleanup_query (struct GNUNET_MY_QueryParam *qp,
474                         MYSQL_BIND *qbind);
475
476
477 /**
478  * Free all memory that was allocated in @a rs during
479  * #GNUNET_MY_extract_result().
480  *
481  * @param rs reult specification to clean up
482  */
483 void
484 GNUNET_MY_cleanup_result (struct GNUNET_MY_ResultSpec *rs);
485
486
487 #if 0                           /* keep Emacsens' auto-indent happy */
488 {
489 #endif
490 #ifdef __cplusplus
491 }
492 #endif
493
494 #endif
495
496 /** @} */  /* end of group */