gnunet-android

GNUnet for Android
Log | Files | Refs | README

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 */