gnunet_sq_lib.h (13828B)
1 /* 2 This file is part of GNUnet 3 Copyright (C) 2017 GNUnet e.V. 4 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. 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 Affero General Public License for more details. 14 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/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 /** 21 * @file include/gnunet_sq_lib.h 22 * @brief helper functions for Sqlite3 DB interactions 23 * @author Christian Grothoff 24 */ 25 #ifndef GNUNET_SQ_LIB_H 26 #define GNUNET_SQ_LIB_H 27 28 29 #include <sqlite3.h> 30 #include "gnunet_util_lib.h" 31 32 33 /** 34 * Function called to convert input argument into SQL parameters. 35 * 36 * @param cls closure 37 * @param data pointer to input argument 38 * @param data_len number of bytes in @a data (if applicable) 39 * @param stmt sqlite statement to bind parameters for 40 * @param off offset of the argument to bind in @a stmt, numbered from 1, 41 * so immediately suitable for passing to `sqlite3_bind`-functions. 42 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success 43 */ 44 typedef enum GNUNET_GenericReturnValue 45 (*GNUNET_SQ_QueryConverter)(void *cls, 46 const void *data, 47 size_t data_len, 48 sqlite3_stmt *stmt, 49 unsigned int off); 50 51 52 /** 53 * @brief Description of a DB query parameter. 54 */ 55 struct GNUNET_SQ_QueryParam 56 { 57 /** 58 * Function for how to handle this type of entry. 59 */ 60 GNUNET_SQ_QueryConverter conv; 61 62 /** 63 * Closure for @e conv. 64 */ 65 void *conv_cls; 66 67 /** 68 * Data or NULL. 69 */ 70 const void *data; 71 72 /** 73 * Size of @e data 74 */ 75 size_t size; 76 77 /** 78 * Number of parameters eaten by this operation. 79 */ 80 unsigned int num_params; 81 }; 82 83 84 /** 85 * End of query parameter specification. 86 */ 87 #define GNUNET_SQ_query_param_end { NULL, NULL, NULL, 0, 0 } 88 89 90 /** 91 * Generate query parameter for a buffer @a ptr of 92 * @a ptr_size bytes. 93 * 94 * @param ptr pointer to the query parameter to pass 95 * @param ptr_size number of bytes in @a ptr 96 */ 97 struct GNUNET_SQ_QueryParam 98 GNUNET_SQ_query_param_fixed_size (const void *ptr, 99 size_t ptr_size); 100 101 102 /** 103 * Generate query parameter for a string. 104 * 105 * @param ptr pointer to the string query parameter to pass 106 */ 107 struct GNUNET_SQ_QueryParam 108 GNUNET_SQ_query_param_string (const char *ptr); 109 110 111 /** 112 * Generate fixed-size query parameter with size determined 113 * by variable type. 114 * 115 * @param x pointer to the query parameter to pass. 116 */ 117 #define GNUNET_SQ_query_param_auto_from_type( \ 118 x) GNUNET_SQ_query_param_fixed_size ((x), sizeof(*(x))) 119 120 121 /** 122 * Generate query parameter for an RSA public key. The 123 * database must contain a BLOB type in the respective position. 124 * 125 * @param x the query parameter to pass. 126 */ 127 struct GNUNET_SQ_QueryParam 128 GNUNET_SQ_query_param_rsa_public_key (const struct 129 GNUNET_CRYPTO_RsaPublicKey *x); 130 131 132 /** 133 * Generate query parameter for an RSA signature. The 134 * database must contain a BLOB type in the respective position. 135 * 136 * @param x the query parameter to pass 137 */ 138 struct GNUNET_SQ_QueryParam 139 GNUNET_SQ_query_param_rsa_signature (const struct 140 GNUNET_CRYPTO_RsaSignature *x); 141 142 143 /** 144 * Generate query parameter for an absolute time value. 145 * The database must store a 64-bit integer. 146 * 147 * @param x pointer to the query parameter to pass 148 */ 149 struct GNUNET_SQ_QueryParam 150 GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); 151 152 153 /** 154 * Generate query parameter for an absolute time value. 155 * The database must store a 64-bit integer. 156 * 157 * @param x pointer to the query parameter to pass 158 */ 159 struct GNUNET_SQ_QueryParam 160 GNUNET_SQ_query_param_absolute_time_nbo ( 161 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_SQ_QueryParam 170 GNUNET_SQ_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_SQ_QueryParam 179 GNUNET_SQ_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_SQ_QueryParam 188 GNUNET_SQ_query_param_uint64 (const uint64_t *x); 189 190 191 /** 192 * Execute binding operations for a prepared statement. 193 * 194 * @param db_conn database connection 195 * @param params parameters to the statement 196 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 197 */ 198 enum GNUNET_GenericReturnValue 199 GNUNET_SQ_bind (sqlite3_stmt *stmt, 200 const struct GNUNET_SQ_QueryParam *params); 201 202 203 /** 204 * Reset @a stmt and log error. 205 * 206 * @param dbh database handle 207 * @param stmt statement to reset 208 */ 209 void 210 GNUNET_SQ_reset (sqlite3 *dbh, 211 sqlite3_stmt *stmt); 212 213 214 /** 215 * Extract data from a Postgres database @a result at row @a row. 216 * 217 * @param cls closure 218 * @param result where to extract data from 219 * @param column column to extract data from 220 * @param[in,out] dst_size where to store size of result, may be NULL 221 * @param[out] dst where to store the result 222 * @return 223 * #GNUNET_YES if all results could be extracted 224 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) 225 */ 226 typedef enum GNUNET_GenericReturnValue 227 (*GNUNET_SQ_ResultConverter)(void *cls, 228 sqlite3_stmt *result, 229 unsigned int column, 230 size_t *dst_size, 231 void *dst); 232 233 234 /** 235 * @brief Description of a DB result cell. 236 */ 237 struct GNUNET_SQ_ResultSpec; 238 239 240 /** 241 * Function called to clean up memory allocated 242 * by a #GNUNET_SQ_ResultConverter. 243 * 244 * @param cls closure 245 */ 246 typedef void 247 (*GNUNET_SQ_ResultCleanup)(void *cls); 248 249 250 /** 251 * @brief Description of a DB result cell. 252 */ 253 struct GNUNET_SQ_ResultSpec 254 { 255 /** 256 * What is the format of the result? 257 */ 258 GNUNET_SQ_ResultConverter conv; 259 260 /** 261 * Function to clean up result data, NULL if cleanup is 262 * not necessary. 263 */ 264 GNUNET_SQ_ResultCleanup cleaner; 265 266 /** 267 * Closure for @e conv and @e cleaner. 268 */ 269 void *cls; 270 271 /** 272 * Destination for the data. 273 */ 274 void *dst; 275 276 /** 277 * Allowed size for the data, 0 for variable-size 278 * (in this case, the type of @e dst is a `void **` 279 * and we need to allocate a buffer of the right size). 280 */ 281 size_t dst_size; 282 283 /** 284 * Where to store actual size of the result. If left at 285 * NULL, will be made to point to @e dst_size before 286 * @a conv is called. 287 */ 288 size_t *result_size; 289 290 /** 291 * Number of parameters (columns) eaten by this operation. 292 */ 293 unsigned int num_params; 294 }; 295 296 297 /** 298 * End of result parameter specification. 299 * 300 * @return array last entry for the result specification to use 301 */ 302 #define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, 0 } 303 304 305 /** 306 * Variable-size result expected. 307 * 308 * @param[out] dst where to store the result, allocated 309 * @param[out] sptr where to store the size of @a dst 310 * @return array entry for the result specification to use 311 */ 312 struct GNUNET_SQ_ResultSpec 313 GNUNET_SQ_result_spec_variable_size (void **dst, 314 size_t *sptr); 315 316 317 /** 318 * Fixed-size result expected. 319 * 320 * @param[out] dst where to store the result 321 * @param dst_size number of bytes in @a dst 322 * @return array entry for the result specification to use 323 */ 324 struct GNUNET_SQ_ResultSpec 325 GNUNET_SQ_result_spec_fixed_size (void *dst, 326 size_t dst_size); 327 328 329 /** 330 * We expect a fixed-size result, with size determined by the type of `* dst` 331 * 332 * @param dst point to where to store the result, type fits expected result size 333 * @return array entry for the result specification to use 334 */ 335 #define GNUNET_SQ_result_spec_auto_from_type( \ 336 dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof(*(dst))) 337 338 339 /** 340 * Variable-size result expected. 341 * 342 * @param[out] dst where to store the result, allocated 343 * @param[out] sptr where to store the size of @a dst 344 * @return array entry for the result specification to use 345 */ 346 struct GNUNET_SQ_ResultSpec 347 GNUNET_SQ_result_spec_variable_size (void **dst, 348 size_t *sptr); 349 350 351 /** 352 * 0-terminated string expected. 353 * 354 * @param[out] dst where to store the result, allocated 355 * @return array entry for the result specification to use 356 */ 357 struct GNUNET_SQ_ResultSpec 358 GNUNET_SQ_result_spec_string (char **dst); 359 360 361 /** 362 * RSA public key expected. 363 * 364 * @param[out] rsa where to store the result 365 * @return array entry for the result specification to use 366 */ 367 struct GNUNET_SQ_ResultSpec 368 GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa); 369 370 371 /** 372 * RSA signature expected. 373 * 374 * @param[out] sig where to store the result; 375 * @return array entry for the result specification to use 376 */ 377 struct GNUNET_SQ_ResultSpec 378 GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig); 379 380 381 /** 382 * Absolute time expected. 383 * 384 * @param[out] at where to store the result 385 * @return array entry for the result specification to use 386 */ 387 struct GNUNET_SQ_ResultSpec 388 GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at); 389 390 391 /** 392 * Absolute time expected. 393 * 394 * @param[out] at where to store the result 395 * @return array entry for the result specification to use 396 */ 397 struct GNUNET_SQ_ResultSpec 398 GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at); 399 400 401 /** 402 * uint16_t expected. 403 * 404 * @param[out] u16 where to store the result 405 * @return array entry for the result specification to use 406 */ 407 struct GNUNET_SQ_ResultSpec 408 GNUNET_SQ_result_spec_uint16 (uint16_t *u16); 409 410 411 /** 412 * uint32_t expected. 413 * 414 * @param[out] u32 where to store the result 415 * @return array entry for the result specification to use 416 */ 417 struct GNUNET_SQ_ResultSpec 418 GNUNET_SQ_result_spec_uint32 (uint32_t *u32); 419 420 421 /** 422 * uint64_t expected. 423 * 424 * @param[out] u64 where to store the result 425 * @return array entry for the result specification to use 426 */ 427 struct GNUNET_SQ_ResultSpec 428 GNUNET_SQ_result_spec_uint64 (uint64_t *u64); 429 430 431 /** 432 * Extract results from a query result according to the given specification. 433 * 434 * @param result result to process 435 * @param[in,out] rs result specification to extract for 436 * @return 437 * #GNUNET_OK if all results could be extracted 438 * #GNUNET_SYSERR if a result was invalid (non-existing field) 439 */ 440 enum GNUNET_GenericReturnValue 441 GNUNET_SQ_extract_result (sqlite3_stmt *result, 442 struct GNUNET_SQ_ResultSpec *rs); 443 444 445 /** 446 * Free all memory that was allocated in @a rs during 447 * #GNUNET_SQ_extract_result(). 448 * 449 * @param rs reult specification to clean up 450 */ 451 void 452 GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs); 453 454 455 /* ******************** sq_prepare.c functions ************** */ 456 457 458 /** 459 * Information needed to run a list of SQL statements using 460 * #GNUNET_SQ_exec_statements(). 461 */ 462 struct GNUNET_SQ_PrepareStatement 463 { 464 /** 465 * Actual SQL statement. 466 */ 467 const char *sql; 468 469 /** 470 * Where to store handle? 471 */ 472 sqlite3_stmt **pstmt; 473 }; 474 475 476 /** 477 * Terminator for executable statement list. 478 */ 479 #define GNUNET_SQ_PREPARE_END { NULL, NULL } 480 481 482 /** 483 * Create a `struct GNUNET_SQ_PrepareStatement` 484 * 485 * @param sql actual SQL statement 486 * @param pstmt where to store the handle 487 * @return initialized struct 488 */ 489 struct GNUNET_SQ_PrepareStatement 490 GNUNET_SQ_make_prepare (const char *sql, 491 sqlite3_stmt **pstmt); 492 493 494 /** 495 * Prepare all statements given in the (NULL,NULL)-terminated 496 * array at @a ps 497 * 498 * @param dbh database handle 499 * @param ps array of statements to prepare 500 * @return #GNUNET_OK on success 501 */ 502 enum GNUNET_GenericReturnValue 503 GNUNET_SQ_prepare (sqlite3 *dbh, 504 const struct GNUNET_SQ_PrepareStatement *ps); 505 506 507 /* ******************** sq_exec.c functions ************** */ 508 509 510 /** 511 * Information needed to run a list of SQL statements using 512 * #GNUNET_SQ_exec_statements(). 513 */ 514 struct GNUNET_SQ_ExecuteStatement 515 { 516 /** 517 * Actual SQL statement. 518 */ 519 const char *sql; 520 521 /** 522 * Should we ignore errors? 523 */ 524 bool ignore_errors; 525 }; 526 527 528 /** 529 * Terminator for executable statement list. 530 */ 531 #define GNUNET_SQ_EXECUTE_STATEMENT_END { NULL, GNUNET_SYSERR } 532 533 534 /** 535 * Create a `struct GNUNET_SQ_ExecuteStatement` where errors are fatal. 536 * 537 * @param sql actual SQL statement 538 * @return initialized struct 539 */ 540 struct GNUNET_SQ_ExecuteStatement 541 GNUNET_SQ_make_execute (const char *sql); 542 543 544 /** 545 * Create a `struct GNUNET_SQ_ExecuteStatement` where errors should 546 * be tolerated. 547 * 548 * @param sql actual SQL statement 549 * @return initialized struct 550 */ 551 struct GNUNET_SQ_ExecuteStatement 552 GNUNET_SQ_make_try_execute (const char *sql); 553 554 555 /** 556 * Request execution of an array of statements @a es from Postgres. 557 * 558 * @param dbh database to execute the statements over 559 * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared 560 * statements. 561 * @return #GNUNET_OK on success (modulo statements where errors can be ignored) 562 * #GNUNET_SYSERR on error 563 */ 564 enum GNUNET_GenericReturnValue 565 GNUNET_SQ_exec_statements (sqlite3 *dbh, 566 const struct GNUNET_SQ_ExecuteStatement *es); 567 568 569 #endif /* GNUNET_SQ_LIB_H_ */ 570 571 /* end of include/gnunet_sq_lib.h */