2 This file is part of GNUnet
3 Copyright (C) 2017 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
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 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * @file include/gnunet_sq_lib.h
20 * @brief helper functions for Sqlite3 DB interactions
21 * @author Christian Grothoff
23 #ifndef GNUNET_SQ_LIB_H
24 #define GNUNET_SQ_LIB_H
27 #include "gnunet_util_lib.h"
31 * Function called to convert input argument into SQL parameters.
34 * @param data pointer to input argument
35 * @param data_len number of bytes in @a data (if applicable)
36 * @param stmt sqlite statement to bind parameters for
37 * @param off offset of the argument to bind in @a stmt, numbered from 1,
38 * so immediately suitable for passing to `sqlite3_bind`-functions.
39 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
42 (*GNUNET_SQ_QueryConverter)(void *cls,
50 * @brief Description of a DB query parameter.
52 struct GNUNET_SQ_QueryParam
56 * Function for how to handle this type of entry.
58 GNUNET_SQ_QueryConverter conv;
61 * Closure for @e conv.
76 * Number of parameters eaten by this operation.
78 unsigned int num_params;
83 * End of query parameter specification.
85 #define GNUNET_SQ_query_param_end { NULL, NULL, NULL, 0, 0 }
89 * Generate query parameter for a buffer @a ptr of
92 * @param ptr pointer to the query parameter to pass
93 * @oaran ptr_size number of bytes in @a ptr
95 struct GNUNET_SQ_QueryParam
96 GNUNET_SQ_query_param_fixed_size (const void *ptr,
102 * Generate query parameter for a string.
104 * @param ptr pointer to the string query parameter to pass
106 struct GNUNET_SQ_QueryParam
107 GNUNET_SQ_query_param_string (const char *ptr);
111 * Generate fixed-size query parameter with size determined
114 * @param x pointer to the query parameter to pass.
116 #define GNUNET_SQ_query_param_auto_from_type(x) GNUNET_SQ_query_param_fixed_size ((x), sizeof (*(x)))
120 * Generate query parameter for an RSA public key. The
121 * database must contain a BLOB type in the respective position.
123 * @param x the query parameter to pass.
125 struct GNUNET_SQ_QueryParam
126 GNUNET_SQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x);
130 * Generate query parameter for an RSA signature. The
131 * database must contain a BLOB type in the respective position.
133 * @param x the query parameter to pass
135 struct GNUNET_SQ_QueryParam
136 GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x);
140 * Generate query parameter for an absolute time value.
141 * The database must store a 64-bit integer.
143 * @param x pointer to the query parameter to pass
145 struct GNUNET_SQ_QueryParam
146 GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
150 * Generate query parameter for an absolute time value.
151 * The database must store a 64-bit integer.
153 * @param x pointer to the query parameter to pass
155 struct GNUNET_SQ_QueryParam
156 GNUNET_SQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x);
160 * Generate query parameter for an uint16_t in host byte order.
162 * @param x pointer to the query parameter to pass
164 struct GNUNET_SQ_QueryParam
165 GNUNET_SQ_query_param_uint16 (const uint16_t *x);
169 * Generate query parameter for an uint32_t in host byte order.
171 * @param x pointer to the query parameter to pass
173 struct GNUNET_SQ_QueryParam
174 GNUNET_SQ_query_param_uint32 (const uint32_t *x);
178 * Generate query parameter for an uint16_t in host byte order.
180 * @param x pointer to the query parameter to pass
182 struct GNUNET_SQ_QueryParam
183 GNUNET_SQ_query_param_uint64 (const uint64_t *x);
187 * Execute binding operations for a prepared statement.
189 * @param db_conn database connection
190 * @param params parameters to the statement
191 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
194 GNUNET_SQ_bind (sqlite3_stmt *stmt,
195 const struct GNUNET_SQ_QueryParam *params);
199 * Reset @a stmt and log error.
201 * @param dbh database handle
202 * @param stmt statement to reset
205 GNUNET_SQ_reset (sqlite3 *dbh,
210 * Extract data from a Postgres database @a result at row @a row.
213 * @param result where to extract data from
214 * @param column column to extract data from
215 * @param[in,out] dst_size where to store size of result, may be NULL
216 * @param[out] dst where to store the result
218 * #GNUNET_YES if all results could be extracted
219 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
222 (*GNUNET_SQ_ResultConverter)(void *cls,
223 sqlite3_stmt *result,
230 * @brief Description of a DB result cell.
232 struct GNUNET_SQ_ResultSpec;
236 * Function called to clean up memory allocated
237 * by a #GNUNET_SQ_ResultConverter.
242 (*GNUNET_SQ_ResultCleanup)(void *cls);
246 * @brief Description of a DB result cell.
248 struct GNUNET_SQ_ResultSpec
252 * What is the format of the result?
254 GNUNET_SQ_ResultConverter conv;
257 * Function to clean up result data, NULL if cleanup is
260 GNUNET_SQ_ResultCleanup cleaner;
263 * Closure for @e conv and @e cleaner.
268 * Destination for the data.
273 * Allowed size for the data, 0 for variable-size
274 * (in this case, the type of @e dst is a `void **`
275 * and we need to allocate a buffer of the right size).
280 * Where to store actual size of the result. If left at
281 * NULL, will be made to point to @e dst_size before
287 * Number of parameters (columns) eaten by this operation.
289 unsigned int num_params;
295 * End of result parameter specification.
297 * @return array last entry for the result specification to use
299 #define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, 0 }
303 * Variable-size result expected.
305 * @param[out] dst where to store the result, allocated
306 * @param[out] sptr where to store the size of @a dst
307 * @return array entry for the result specification to use
309 struct GNUNET_SQ_ResultSpec
310 GNUNET_SQ_result_spec_variable_size (void **dst,
315 * Fixed-size result expected.
317 * @param[out] dst where to store the result
318 * @param dst_size number of bytes in @a dst
319 * @return array entry for the result specification to use
321 struct GNUNET_SQ_ResultSpec
322 GNUNET_SQ_result_spec_fixed_size (void *dst,
327 * We expect a fixed-size result, with size determined by the type of `* dst`
329 * @param dst point to where to store the result, type fits expected result size
330 * @return array entry for the result specification to use
332 #define GNUNET_SQ_result_spec_auto_from_type(dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof (*(dst)))
336 * Variable-size result expected.
338 * @param[out] dst where to store the result, allocated
339 * @param[out] sptr where to store the size of @a dst
340 * @return array entry for the result specification to use
342 struct GNUNET_SQ_ResultSpec
343 GNUNET_SQ_result_spec_variable_size (void **dst,
348 * 0-terminated string expected.
350 * @param[out] dst where to store the result, allocated
351 * @return array entry for the result specification to use
353 struct GNUNET_SQ_ResultSpec
354 GNUNET_SQ_result_spec_string (char **dst);
358 * RSA public key expected.
360 * @param[out] rsa where to store the result
361 * @return array entry for the result specification to use
363 struct GNUNET_SQ_ResultSpec
364 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa);
368 * RSA signature expected.
370 * @param[out] sig where to store the result;
371 * @return array entry for the result specification to use
373 struct GNUNET_SQ_ResultSpec
374 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig);
378 * Absolute time expected.
380 * @param[out] at where to store the result
381 * @return array entry for the result specification to use
383 struct GNUNET_SQ_ResultSpec
384 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at);
388 * Absolute time expected.
390 * @param[out] at where to store the result
391 * @return array entry for the result specification to use
393 struct GNUNET_SQ_ResultSpec
394 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at);
400 * @param[out] u16 where to store the result
401 * @return array entry for the result specification to use
403 struct GNUNET_SQ_ResultSpec
404 GNUNET_SQ_result_spec_uint16 (uint16_t *u16);
410 * @param[out] u32 where to store the result
411 * @return array entry for the result specification to use
413 struct GNUNET_SQ_ResultSpec
414 GNUNET_SQ_result_spec_uint32 (uint32_t *u32);
420 * @param[out] u64 where to store the result
421 * @return array entry for the result specification to use
423 struct GNUNET_SQ_ResultSpec
424 GNUNET_SQ_result_spec_uint64 (uint64_t *u64);
428 * Extract results from a query result according to the given specification.
430 * @param result result to process
431 * @param[in,out] rs result specification to extract for
433 * #GNUNET_OK if all results could be extracted
434 * #GNUNET_SYSERR if a result was invalid (non-existing field)
437 GNUNET_SQ_extract_result (sqlite3_stmt *result,
438 struct GNUNET_SQ_ResultSpec *rs);
442 * Free all memory that was allocated in @a rs during
443 * #GNUNET_SQ_extract_result().
445 * @param rs reult specification to clean up
448 GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs);
452 /* ******************** sq_prepare.c functions ************** */
456 * Information needed to run a list of SQL statements using
457 * #GNUNET_SQ_exec_statements().
459 struct GNUNET_SQ_PrepareStatement {
462 * Actual SQL statement.
467 * Where to store handle?
469 sqlite3_stmt **pstmt;
475 * Terminator for executable statement list.
477 #define GNUNET_SQ_PREPARE_END { NULL, NULL }
481 * Create a `struct GNUNET_SQ_PrepareStatement`
483 * @param sql actual SQL statement
484 * @param pstmt where to store the handle
485 * @return initialized struct
487 struct GNUNET_SQ_PrepareStatement
488 GNUNET_SQ_make_prepare (const char *sql,
489 sqlite3_stmt **pstmt);
494 * Prepare all statements given in the (NULL,NULL)-terminated
497 * @param dbh database handle
498 * @param ps array of statements to prepare
499 * @return #GNUNET_OK on success
502 GNUNET_SQ_prepare (sqlite3 *dbh,
503 const struct GNUNET_SQ_PrepareStatement *ps);
506 /* ******************** sq_exec.c functions ************** */
510 * Information needed to run a list of SQL statements using
511 * #GNUNET_SQ_exec_statements().
513 struct GNUNET_SQ_ExecuteStatement {
516 * Actual SQL statement.
521 * Should we ignore errors?
529 * Terminator for executable statement list.
531 #define GNUNET_SQ_EXECUTE_STATEMENT_END { NULL, GNUNET_SYSERR }
535 * Create a `struct GNUNET_SQ_ExecuteStatement` where errors are fatal.
537 * @param sql actual SQL statement
538 * @return initialized struct
540 struct GNUNET_SQ_ExecuteStatement
541 GNUNET_SQ_make_execute (const char *sql);
545 * Create a `struct GNUNET_SQ_ExecuteStatement` where errors should
548 * @param sql actual SQL statement
549 * @return initialized struct
551 struct GNUNET_SQ_ExecuteStatement
552 GNUNET_SQ_make_try_execute (const char *sql);
556 * Request execution of an array of statements @a es from Postgres.
558 * @param dbh database to execute the statements over
559 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
561 * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
562 * #GNUNET_SYSERR on error
565 GNUNET_SQ_exec_statements (sqlite3 *dbh,
566 const struct GNUNET_SQ_ExecuteStatement *es);
570 #endif /* GNUNET_SQ_LIB_H_ */
572 /* end of include/gnunet_sq_lib.h */