skeleton for TCP communicator
[oweals/gnunet.git] / src / include / gnunet_pq_lib.h
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2016, 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_pq_lib.h
22  * @brief helper functions for Postgres DB interactions
23  * @author Christian Grothoff
24  */
25 #ifndef GNUNET_PQ_LIB_H
26 #define GNUNET_PQ_LIB_H
27
28 #include <libpq-fe.h>
29 #include "gnunet_util_lib.h"
30 #include "gnunet_db_lib.h"
31
32 /* ************************* pq_query_helper.c functions ************************ */
33
34
35 /**
36  * Function called to convert input argument into SQL parameters.
37  *
38  * @param cls closure
39  * @param data pointer to input argument
40  * @param data_len number of bytes in @a data (if applicable)
41  * @param[out] param_values SQL data to set
42  * @param[out] param_lengths SQL length data to set
43  * @param[out] param_formats SQL format data to set
44  * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
45  * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
46  * @param scratch_length number of entries left in @a scratch
47  * @return -1 on error, number of offsets used in @a scratch otherwise
48  */
49 typedef int
50 (*GNUNET_PQ_QueryConverter)(void *cls,
51                             const void *data,
52                             size_t data_len,
53                             void *param_values[],
54                             int param_lengths[],
55                             int param_formats[],
56                             unsigned int param_length,
57                             void *scratch[],
58                             unsigned int scratch_length);
59
60
61 /**
62  * @brief Description of a DB query parameter.
63  */
64 struct GNUNET_PQ_QueryParam
65 {
66
67   /**
68    * Function for how to handle this type of entry.
69    */
70   GNUNET_PQ_QueryConverter conv;
71
72   /**
73    * Closure for @e conv.
74    */
75   void *conv_cls;
76
77   /**
78    * Data or NULL.
79    */
80   const void *data;
81
82   /**
83    * Size of @e data
84    */
85   size_t size;
86
87   /**
88    * Number of parameters eaten by this operation.
89    */
90   unsigned int num_params;
91 };
92
93
94 /**
95  * End of query parameter specification.
96  */
97 #define GNUNET_PQ_query_param_end { NULL, NULL, NULL, 0, 0 }
98
99
100 /**
101  * Generate query parameter for a buffer @a ptr of
102  * @a ptr_size bytes.
103  *
104  * @param ptr pointer to the query parameter to pass
105  * @oaran ptr_size number of bytes in @a ptr
106  */
107 struct GNUNET_PQ_QueryParam
108 GNUNET_PQ_query_param_fixed_size (const void *ptr,
109                                   size_t ptr_size);
110
111
112
113 /**
114  * Generate query parameter for a string.
115  *
116  * @param ptr pointer to the string query parameter to pass
117  */
118 struct GNUNET_PQ_QueryParam
119 GNUNET_PQ_query_param_string (const char *ptr);
120
121
122 /**
123  * Generate fixed-size query parameter with size determined
124  * by variable type.
125  *
126  * @param x pointer to the query parameter to pass.
127  */
128 #define GNUNET_PQ_query_param_auto_from_type(x) GNUNET_PQ_query_param_fixed_size ((x), sizeof (*(x)))
129
130
131 /**
132  * Generate query parameter for an RSA public key.  The
133  * database must contain a BLOB type in the respective position.
134  *
135  * @param x the query parameter to pass.
136  */
137 struct GNUNET_PQ_QueryParam
138 GNUNET_PQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x);
139
140
141 /**
142  * Generate query parameter for an RSA signature.  The
143  * database must contain a BLOB type in the respective position.
144  *
145  * @param x the query parameter to pass
146  */
147 struct GNUNET_PQ_QueryParam
148 GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x);
149
150
151 /**
152  * Generate query parameter for an absolute time value.
153  * The database must store a 64-bit integer.
154  *
155  * @param x pointer to the query parameter to pass
156  */
157 struct GNUNET_PQ_QueryParam
158 GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
159
160
161 /**
162  * Generate query parameter for an absolute time value.
163  * The database must store a 64-bit integer.
164  *
165  * @param x pointer to the query parameter to pass
166  */
167 struct GNUNET_PQ_QueryParam
168 GNUNET_PQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x);
169
170
171 /**
172  * Generate query parameter for an uint16_t in host byte order.
173  *
174  * @param x pointer to the query parameter to pass
175  */
176 struct GNUNET_PQ_QueryParam
177 GNUNET_PQ_query_param_uint16 (const uint16_t *x);
178
179
180 /**
181  * Generate query parameter for an uint32_t in host byte order.
182  *
183  * @param x pointer to the query parameter to pass
184  */
185 struct GNUNET_PQ_QueryParam
186 GNUNET_PQ_query_param_uint32 (const uint32_t *x);
187
188
189 /**
190  * Generate query parameter for an uint16_t in host byte order.
191  *
192  * @param x pointer to the query parameter to pass
193  */
194 struct GNUNET_PQ_QueryParam
195 GNUNET_PQ_query_param_uint64 (const uint64_t *x);
196
197
198 /* ************************* pq_result_helper.c functions ************************ */
199
200
201 /**
202  * Extract data from a Postgres database @a result at row @a row.
203  *
204  * @param cls closure
205  * @param result where to extract data from
206  * @param int row to extract data from
207  * @param fname name (or prefix) of the fields to extract from
208  * @param[in,out] dst_size where to store size of result, may be NULL
209  * @param[out] dst where to store the result
210  * @return
211  *   #GNUNET_YES if all results could be extracted
212  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
213  */
214 typedef int
215 (*GNUNET_PQ_ResultConverter)(void *cls,
216                              PGresult *result,
217                              int row,
218                              const char *fname,
219                              size_t *dst_size,
220                              void *dst);
221
222
223 /**
224  * Function called to clean up memory allocated
225  * by a #GNUNET_PQ_ResultConverter.
226  *
227  * @param cls closure
228  * @param rd result data to clean up
229  */
230 typedef void
231 (*GNUNET_PQ_ResultCleanup)(void *cls,
232                            void *rd);
233
234
235 /**
236  * @brief Description of a DB result cell.
237  */
238 struct GNUNET_PQ_ResultSpec
239 {
240
241   /**
242    * What is the format of the result?
243    */
244   GNUNET_PQ_ResultConverter conv;
245
246   /**
247    * Function to clean up result data, NULL if cleanup is
248    * not necessary.
249    */
250   GNUNET_PQ_ResultCleanup cleaner;
251
252   /**
253    * Closure for @e conv and @e cleaner.
254    */
255   void *cls;
256
257   /**
258    * Destination for the data.
259    */
260   void *dst;
261
262   /**
263    * Allowed size for the data, 0 for variable-size
264    * (in this case, the type of @e dst is a `void **`
265    * and we need to allocate a buffer of the right size).
266    */
267   size_t dst_size;
268
269   /**
270    * Field name of the desired result.
271    */
272   const char *fname;
273
274   /**
275    * Where to store actual size of the result.
276    */
277   size_t *result_size;
278
279 };
280
281
282 /**
283  * End of result parameter specification.
284  *
285  * @return array last entry for the result specification to use
286  */
287 #define GNUNET_PQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, NULL }
288
289
290 /**
291  * Variable-size result expected.
292  *
293  * @param name name of the field in the table
294  * @param[out] dst where to store the result, allocated
295  * @param[out] sptr where to store the size of @a dst
296  * @return array entry for the result specification to use
297  */
298 struct GNUNET_PQ_ResultSpec
299 GNUNET_PQ_result_spec_variable_size (const char *name,
300                                      void **dst,
301                                      size_t *sptr);
302
303
304 /**
305  * Fixed-size result expected.
306  *
307  * @param name name of the field in the table
308  * @param[out] dst where to store the result
309  * @param dst_size number of bytes in @a dst
310  * @return array entry for the result specification to use
311  */
312 struct GNUNET_PQ_ResultSpec
313 GNUNET_PQ_result_spec_fixed_size (const char *name,
314                                   void *dst,
315                                   size_t dst_size);
316
317
318
319 /**
320  * We expect a fixed-size result, with size determined by the type of `* dst`
321  *
322  * @param name name of the field in the table
323  * @param dst point to where to store the result, type fits expected result size
324  * @return array entry for the result specification to use
325  */
326 #define GNUNET_PQ_result_spec_auto_from_type(name, dst) GNUNET_PQ_result_spec_fixed_size (name, (dst), sizeof (*(dst)))
327
328
329 /**
330  * 0-terminated string expected.
331  *
332  * @param name name of the field in the table
333  * @param[out] dst where to store the result, allocated
334  * @return array entry for the result specification to use
335  */
336 struct GNUNET_PQ_ResultSpec
337 GNUNET_PQ_result_spec_string (const char *name,
338                               char **dst);
339
340
341 /**
342  * RSA public key expected.
343  *
344  * @param name name of the field in the table
345  * @param[out] rsa where to store the result
346  * @return array entry for the result specification to use
347  */
348 struct GNUNET_PQ_ResultSpec
349 GNUNET_PQ_result_spec_rsa_public_key (const char *name,
350                                       struct GNUNET_CRYPTO_RsaPublicKey **rsa);
351
352
353 /**
354  * RSA signature expected.
355  *
356  * @param name name of the field in the table
357  * @param[out] sig where to store the result;
358  * @return array entry for the result specification to use
359  */
360 struct GNUNET_PQ_ResultSpec
361 GNUNET_PQ_result_spec_rsa_signature (const char *name,
362                                      struct GNUNET_CRYPTO_RsaSignature **sig);
363
364
365 /**
366  * Absolute time expected.
367  *
368  * @param name name of the field in the table
369  * @param[out] at where to store the result
370  * @return array entry for the result specification to use
371  */
372 struct GNUNET_PQ_ResultSpec
373 GNUNET_PQ_result_spec_absolute_time (const char *name,
374                                      struct GNUNET_TIME_Absolute *at);
375
376
377 /**
378  * Absolute time expected.
379  *
380  * @param name name of the field in the table
381  * @param[out] at where to store the result
382  * @return array entry for the result specification to use
383  */
384 struct GNUNET_PQ_ResultSpec
385 GNUNET_PQ_result_spec_absolute_time_nbo (const char *name,
386                                          struct GNUNET_TIME_AbsoluteNBO *at);
387
388
389 /**
390  * uint16_t expected.
391  *
392  * @param name name of the field in the table
393  * @param[out] u16 where to store the result
394  * @return array entry for the result specification to use
395  */
396 struct GNUNET_PQ_ResultSpec
397 GNUNET_PQ_result_spec_uint16 (const char *name,
398                               uint16_t *u16);
399
400
401 /**
402  * uint32_t expected.
403  *
404  * @param name name of the field in the table
405  * @param[out] u32 where to store the result
406  * @return array entry for the result specification to use
407  */
408 struct GNUNET_PQ_ResultSpec
409 GNUNET_PQ_result_spec_uint32 (const char *name,
410                               uint32_t *u32);
411
412
413 /**
414  * uint64_t expected.
415  *
416  * @param name name of the field in the table
417  * @param[out] u64 where to store the result
418  * @return array entry for the result specification to use
419  */
420 struct GNUNET_PQ_ResultSpec
421 GNUNET_PQ_result_spec_uint64 (const char *name,
422                               uint64_t *u64);
423
424
425 /* ************************* pq.c functions ************************ */
426
427 /**
428  * Execute a prepared statement.
429  *
430  * @param db_conn database connection
431  * @param name name of the prepared statement
432  * @param params parameters to the statement
433  * @return postgres result
434  * @deprecated (should become an internal API)
435  */
436 PGresult *
437 GNUNET_PQ_exec_prepared (PGconn *db_conn,
438                          const char *name,
439                          const struct GNUNET_PQ_QueryParam *params);
440
441
442 /**
443  * Extract results from a query result according to the given specification.
444  *
445  * @param result result to process
446  * @param[in,out] rs result specification to extract for
447  * @param row row from the result to extract
448  * @return
449  *   #GNUNET_YES if all results could be extracted
450  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
451  * @deprecated (should become an internal API)
452  */
453 int
454 GNUNET_PQ_extract_result (PGresult *result,
455                           struct GNUNET_PQ_ResultSpec *rs,
456                           int row);
457
458
459 /**
460  * Free all memory that was allocated in @a rs during
461  * #GNUNET_PQ_extract_result().
462  *
463  * @param rs reult specification to clean up
464  */
465 void
466 GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs);
467
468
469 /* ******************** pq_eval.c functions ************** */
470
471
472 /**
473  * Check the @a result's error code to see what happened.
474  * Also logs errors.
475  *
476  * @param connection connection to execute the statement in
477  * @param statement_name name of the statement that created @a result
478  * @param result result to check
479  * @return status code from the result, mapping PQ status
480  *         codes to `enum GNUNET_DB_QueryStatus`.  Never
481  *         returns positive values as this function does
482  *         not look at the result set.
483  * @deprecated (low level, let's see if we can do with just the high-level functions)
484  */
485 enum GNUNET_DB_QueryStatus
486 GNUNET_PQ_eval_result (PGconn *connection,
487                        const char *statement_name,
488                        PGresult *result);
489
490
491 /**
492  * Execute a named prepared @a statement that is NOT a SELECT
493  * statement in @a connnection using the given @a params.  Returns the
494  * resulting session state.
495  *
496  * @param connection connection to execute the statement in
497  * @param statement_name name of the statement
498  * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
499  * @return status code from the result, mapping PQ status
500  *         codes to `enum GNUNET_DB_QueryStatus`.   If the
501  *         statement was a DELETE or UPDATE statement, the
502  *         number of affected rows is returned; if the
503  *         statment was an INSERT statement, and no row
504  *         was added due to a UNIQUE violation, we return
505  *         zero; if INSERT was successful, we return one.
506  */
507 enum GNUNET_DB_QueryStatus
508 GNUNET_PQ_eval_prepared_non_select (PGconn *connection,
509                                     const char *statement_name,
510                                     const struct GNUNET_PQ_QueryParam *params);
511
512
513 /**
514  * Function to be called with the results of a SELECT statement
515  * that has returned @a num_results results.
516  *
517  * @param cls closure
518  * @param result the postgres result
519  * @param num_result the number of results in @a result
520  */
521 typedef void
522 (*GNUNET_PQ_PostgresResultHandler)(void *cls,
523                                    PGresult *result,
524                                    unsigned int num_results);
525
526
527 /**
528  * Execute a named prepared @a statement that is a SELECT statement
529  * which may return multiple results in @a connection using the given
530  * @a params.  Call @a rh with the results.  Returns the query
531  * status including the number of results given to @a rh (possibly zero).
532  * @a rh will not have been called if the return value is negative.
533  *
534  * @param connection connection to execute the statement in
535  * @param statement_name name of the statement
536  * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
537  * @param rh function to call with the result set, NULL to ignore
538  * @param rh_cls closure to pass to @a rh
539  * @return status code from the result, mapping PQ status
540  *         codes to `enum GNUNET_DB_QueryStatus`.
541  */
542 enum GNUNET_DB_QueryStatus
543 GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
544                                       const char *statement_name,
545                                       const struct GNUNET_PQ_QueryParam *params,
546                                       GNUNET_PQ_PostgresResultHandler rh,
547                                       void *rh_cls);
548
549
550 /**
551  * Execute a named prepared @a statement that is a SELECT statement
552  * which must return a single result in @a connection using the given
553  * @a params.  Stores the result (if any) in @a rs, which the caller
554  * must then clean up using #GNUNET_PQ_cleanup_result() if the return
555  * value was #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT.  Returns the
556  * resulting session status.
557  *
558  * @param connection connection to execute the statement in
559  * @param statement_name name of the statement
560  * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
561  * @param[in,out] rs result specification to use for storing the result of the query
562  * @return status code from the result, mapping PQ status
563  *         codes to `enum GNUNET_DB_QueryStatus`.
564  */
565 enum GNUNET_DB_QueryStatus
566 GNUNET_PQ_eval_prepared_singleton_select (PGconn *connection,
567                                           const char *statement_name,
568                                           const struct GNUNET_PQ_QueryParam *params,
569                                           struct GNUNET_PQ_ResultSpec *rs);
570
571
572 /* ******************** pq_prepare.c functions ************** */
573
574
575 /**
576  * Information needed to prepare a list of SQL statements using
577  * #GNUNET_PQ_prepare_statements().
578  */
579 struct GNUNET_PQ_PreparedStatement {
580
581   /**
582    * Name of the statement.
583    */
584   const char *name;
585
586   /**
587    * Actual SQL statement.
588    */
589   const char *sql;
590
591   /**
592    * Number of arguments included in @e sql.
593    */
594   unsigned int num_arguments;
595
596 };
597
598
599 /**
600  * Terminator for prepared statement list.
601  */
602 #define GNUNET_PQ_PREPARED_STATEMENT_END { NULL, NULL, 0 }
603
604
605 /**
606  * Create a `struct GNUNET_PQ_PreparedStatement`.
607  *
608  * @param name name of the statement
609  * @param sql actual SQL statement
610  * @param num_args number of arguments in the statement
611  * @return initialized struct
612  */
613 struct GNUNET_PQ_PreparedStatement
614 GNUNET_PQ_make_prepare (const char *name,
615                         const char *sql,
616                         unsigned int num_args);
617
618
619 /**
620  * Request creation of prepared statements @a ps from Postgres.
621  *
622  * @param connection connection to prepare the statements for
623  * @param ps #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
624  *            statements.
625  * @return #GNUNET_OK on success,
626  *         #GNUNET_SYSERR on error
627  */
628 int
629 GNUNET_PQ_prepare_statements (PGconn *connection,
630                               const struct GNUNET_PQ_PreparedStatement *ps);
631
632
633 /* ******************** pq_exec.c functions ************** */
634
635
636 /**
637  * Information needed to run a list of SQL statements using
638  * #GNUNET_PQ_exec_statements().
639  */
640 struct GNUNET_PQ_ExecuteStatement {
641
642   /**
643    * Actual SQL statement.
644    */
645   const char *sql;
646
647   /**
648    * Should we ignore errors?
649    */
650   int ignore_errors;
651
652 };
653
654
655 /**
656  * Terminator for executable statement list.
657  */
658 #define GNUNET_PQ_EXECUTE_STATEMENT_END { NULL, GNUNET_SYSERR }
659
660
661 /**
662  * Create a `struct GNUNET_PQ_ExecuteStatement` where errors are fatal.
663  *
664  * @param sql actual SQL statement
665  * @return initialized struct
666  */
667 struct GNUNET_PQ_ExecuteStatement
668 GNUNET_PQ_make_execute (const char *sql);
669
670
671 /**
672  * Create a `struct GNUNET_PQ_ExecuteStatement` where errors should
673  * be tolerated.
674  *
675  * @param sql actual SQL statement
676  * @return initialized struct
677  */
678 struct GNUNET_PQ_ExecuteStatement
679 GNUNET_PQ_make_try_execute (const char *sql);
680
681
682 /**
683  * Request execution of an array of statements @a es from Postgres.
684  *
685  * @param connection connection to execute the statements over
686  * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
687  *            statements.
688  * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
689  *         #GNUNET_SYSERR on error
690  */
691 int
692 GNUNET_PQ_exec_statements (PGconn *connection,
693                            const struct GNUNET_PQ_ExecuteStatement *es);
694
695
696 /* ******************** pq_connect.c functions ************** */
697
698
699 /**
700  * Create a connection to the Postgres database using @a config_str
701  * for the configuration.  Initialize logging via GNUnet's log
702  * routines and disable Postgres's logger.
703  *
704  * @param config_str configuration to use
705  * @return NULL on error
706  */
707 PGconn *
708 GNUNET_PQ_connect (const char *config_str);
709
710
711 /**
712  * Connect to a postgres database using the configuration
713  * option "CONFIG" in @a section.
714  *
715  * @param cfg configuration
716  * @param section configuration section to use to get Postgres configuration options
717  * @return the postgres handle, NULL on error
718  */
719 PGconn *
720 GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
721                             const char *section);
722
723
724
725 #endif  /* GNUNET_PQ_LIB_H_ */
726
727 /* end of include/gnunet_pq_lib.h */