GNUnet 0.28.1-dev.3-2-g4c5d45bb5
 
Loading...
Searching...
No Matches
pq_connect.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2017, 2019, 2020, 2021, 2023 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 */
26#include "platform.h"
27#include "pq.h"
28#include <pthread.h>
29
30
36static void
38{
39 if (NULL == db->conn)
40 return;
41 PQfinish (db->conn);
42 db->conn = NULL;
43 db->prepared_check_patch = false;
44 db->prepared_get_oid_by_name = false;
45}
46
47
57{
58 PGresult *res;
59
60 if (db->prepared_check_patch)
61 return GNUNET_OK;
62 res = PQprepare (db->conn,
63 "gnunet_pq_check_patch",
64 "SELECT"
65 " applied_by"
66 " FROM _v.patches"
67 " WHERE patch_name = $1"
68 " LIMIT 1",
69 1,
70 NULL);
71 if (PGRES_COMMAND_OK !=
72 PQresultStatus (res))
73 {
75 "Failed to run SQL logic to setup database versioning logic: %s/%s\n",
76 PQresultErrorMessage (res),
77 PQerrorMessage (db->conn));
78 PQclear (res);
80 return GNUNET_SYSERR;
81 }
82 PQclear (res);
83 db->prepared_check_patch = true;
84 return GNUNET_OK;
85}
86
87
97{
98 PGresult *res;
99
100 if (db->prepared_get_oid_by_name)
101 return GNUNET_OK;
102 res = PQprepare (db->conn,
103 "gnunet_pq_get_oid_by_name",
104 "SELECT typname, oid"
105 " FROM pg_type"
106 " WHERE oid = to_regtype($1)",
107 1,
108 NULL);
109 if (PGRES_COMMAND_OK != PQresultStatus (res))
110 {
112 "Failed to run SQL statement prepare OID lookups: %s/%s\n",
113 PQresultErrorMessage (res),
114 PQerrorMessage (db->conn));
115 PQclear (res);
117 return GNUNET_SYSERR;
118 }
119 PQclear (res);
120 db->prepared_get_oid_by_name = true;
121 return GNUNET_OK;
122}
123
124
136{
137 PGresult *res;
138 ExecStatusType est;
139
140 if (GNUNET_OK == db->versioning_ok)
141 return GNUNET_OK;
142 if (GNUNET_NO == db->versioning_ok)
143 return GNUNET_NO;
144 res = PQexec (db->conn,
145 "SELECT"
146 " schema_name"
147 " FROM information_schema.schemata"
148 " WHERE schema_name='_v';");
149 est = PQresultStatus (res);
150 if ( (PGRES_COMMAND_OK != est) &&
151 (PGRES_TUPLES_OK != est) )
152 {
154 "Failed to run statement to check versioning schema. Bad!\n");
155 PQclear (res);
156 return GNUNET_SYSERR;
157 }
158 if (0 == PQntuples (res))
159 {
160 PQclear (res);
161 db->versioning_ok = GNUNET_NO;
163 "_v schema not found\n");
164 return GNUNET_NO;
165 }
166 PQclear (res);
167 db->versioning_ok = GNUNET_OK;
168 return GNUNET_OK;
169}
170
171
185 const char *load_path,
186 unsigned int patch_number)
187{
188 const char *load_path_suffix;
189 size_t slen = strlen (load_path) + 10;
190 char patch_name[slen];
191
192 if (GNUNET_SYSERR ==
194 {
195 GNUNET_break (0);
196 return GNUNET_SYSERR; /* no versioning, cannot check */
197 }
198 load_path_suffix = strrchr (load_path,
199 '/');
200 if (NULL == load_path_suffix)
201 load_path_suffix = load_path;
202 else
203 load_path_suffix++; /* skip '/' */
204 GNUNET_snprintf (patch_name,
205 sizeof (patch_name),
206 "%s%04u",
207 load_path_suffix,
208 patch_number);
209 {
210 struct GNUNET_PQ_QueryParam params[] = {
211 GNUNET_PQ_query_param_string (patch_name),
213 };
214 char *applied_by;
215 struct GNUNET_PQ_ResultSpec rs[] = {
216 GNUNET_PQ_result_spec_string ("applied_by",
217 &applied_by),
219 };
220 enum GNUNET_DB_QueryStatus qs;
221
222 if (GNUNET_OK !=
224 {
225 GNUNET_break (0);
226 return GNUNET_SYSERR;
227 }
229 "gnunet_pq_check_patch",
230 params,
231 rs);
232 switch (qs)
233 {
236 "Database version %s already applied by %s\n",
237 patch_name,
238 applied_by);
240 return GNUNET_OK;
242 return GNUNET_NO;
244 GNUNET_break (0);
245 return GNUNET_SYSERR;
247 GNUNET_break (0);
248 return GNUNET_SYSERR;
249 }
250 GNUNET_assert (0);
251 return GNUNET_SYSERR;
252 }
253}
254
255
264static void
266 const PGresult *res)
267{
268 /* do nothing, intentionally */
269 (void) arg;
270 (void) res;
271}
272
273
281static void
283 const char *message)
284{
285 (void) arg;
287 "pq",
288 "%s",
289 message);
290}
291
292
304static char *
306 const char *infix)
307{
308 char *fn;
309
310 GNUNET_asprintf (&fn,
311 "%s%s.sql",
312 db->load_path,
313 infix);
314 return fn;
315}
316
317
332 const char *load_suffix,
333 unsigned int patch_number)
334{
335 size_t slen = strlen (load_suffix) + 10;
336 char patch_name[slen];
337 char *fn;
339
340 GNUNET_snprintf (patch_name,
341 sizeof (patch_name),
342 "%s%04u",
343 load_suffix,
344 patch_number);
345 fn = get_sql_file_name (db,
346 patch_name);
348 GNUNET_free (fn);
349 return ret;
350}
351
352
367static bool
369 const char *load_suffix,
370 unsigned int from,
371 unsigned int *found)
372{
373 for (unsigned int i = from; i<5; i++)
374 {
375 if (GNUNET_YES !=
377 load_suffix,
378 i))
379 continue;
380 *found = i;
381 return true;
382 }
383 return false;
384}
385
386
389 const char *buf)
390{
391 struct GNUNET_Process *psql;
393 unsigned long code;
394 char *fn;
395
396 fn = get_sql_file_name (db,
397 buf);
398 if (GNUNET_YES !=
400 {
401 GNUNET_free (fn);
402 return GNUNET_NO;
403 }
405 "Applying SQL file `%s' on database %s\n",
406 fn,
407 db->config_str);
409 if (GNUNET_OK !=
411 "psql",
412 "psql",
413 db->config_str,
414 "-f",
415 fn,
416 "-q",
417 "--set",
418 "ON_ERROR_STOP=1",
419 NULL))
420 {
422 "exec",
423 "psql");
425 GNUNET_free (fn);
426 return GNUNET_SYSERR;
427 }
430 true,
431 &type,
432 &code));
434 if ( (GNUNET_OS_PROCESS_EXITED != type) ||
435 (0 != code) )
436 {
438 "Could not run PSQL on file %s: psql exit code was %d\n",
439 fn,
440 (int) code);
441 GNUNET_free (fn);
442 return GNUNET_SYSERR;
443 }
444 GNUNET_free (fn);
445 return GNUNET_OK;
446}
447
448
451 const char *load_suffix)
452{
454 "Loading SQL resources from `%s'\n",
455 load_suffix);
456 for (unsigned int i = 1; i<10000; i++)
457 {
459 unsigned int next;
460
462 load_suffix,
463 i);
464 if (GNUNET_SYSERR == ret)
465 {
466 GNUNET_break (0);
467 return GNUNET_SYSERR;
468 }
469 if (GNUNET_OK == ret)
470 continue; /* patch already applied, skip it */
471 /* patch not applied, check if it (or, in case the numbering
472 has a hole, any later patch) exists... */
473 if (find_next_patch (db,
474 load_suffix,
475 i,
476 &next))
477 return GNUNET_NO;
478 return GNUNET_OK;
479 }
480 GNUNET_break (0); /* 10k patches applied!? */
481 return GNUNET_OK;
482}
483
484
487 const char *load_suffix)
488{
489 size_t slen = strlen (load_suffix) + 10;
490 char patch_name[slen];
491
493 "Loading SQL resources from `%s'\n",
494 load_suffix);
495 for (unsigned int i = 1; i<10000; i++)
496 {
498
500 load_suffix,
501 i);
502 if (GNUNET_SYSERR == ret)
503 {
504 GNUNET_break (0);
505 return GNUNET_SYSERR;
506 }
507 if (GNUNET_OK == ret)
508 continue; /* patch already applied, skip it */
509
510 GNUNET_snprintf (patch_name,
511 sizeof (patch_name),
512 "%s%04u",
513 load_suffix,
514 i);
516 patch_name);
517 if (GNUNET_NO == ret)
518 {
519 unsigned int next;
520
521 /* No such file. Before we conclude that we are done, make sure
522 this really is the end of the sequence and not a hole in the
523 numbering: applying the patches beyond the hole (or, worse,
524 silently not applying them) would leave the database in an
525 undefined state. */
526 if (find_next_patch (db,
527 load_suffix,
528 i + 1,
529 &next))
530 {
532 "Gap in SQL patch sequence: `%s%04u' is missing, but `%s%04u' exists; refusing to apply patches out of order\n",
533 load_suffix,
534 i,
535 load_suffix,
536 next);
537 return GNUNET_SYSERR;
538 }
539 break; /* no such file, we are done */
540 }
541 if (GNUNET_SYSERR == ret)
542 return GNUNET_SYSERR;
543 }
544 return GNUNET_OK;
545}
546
547
548void
550{
551 if (1 ==
552 PQconsumeInput (db->conn))
553 return;
554 if (CONNECTION_BAD != PQstatus (db->conn))
555 return;
557}
558
559
562 struct GNUNET_PQ_Context *db,
563 const char *name,
564 Oid *oid)
565{
566 /* Check if the entry is in the cache already */
567 for (unsigned int i = 0; i < db->oids.num; i++)
568 {
569 /* Pointer comparison */
570 if (name == db->oids.table[i].name)
571 {
572 *oid = db->oids.table[i].oid;
573 return GNUNET_OK;
574 }
575 }
576
577 /* No entry found in cache, ask database */
578 {
579 enum GNUNET_DB_QueryStatus qs;
580 struct GNUNET_PQ_QueryParam params[] = {
583 };
584 struct GNUNET_PQ_ResultSpec spec[] = {
586 oid),
588 };
589
590 GNUNET_assert (NULL != db);
591
593 "gnunet_pq_get_oid_by_name",
594 params,
595 spec);
597 return GNUNET_SYSERR;
598 }
599
600 /* Add the entry to the cache */
601 if (NULL == db->oids.table)
602 {
603 db->oids.table = GNUNET_new_array (8,
604 typeof(*db->oids.table));
605 db->oids.cap = 8;
606 db->oids.num = 0;
607 }
608
609 if (db->oids.cap <= db->oids.num)
610 GNUNET_array_grow (db->oids.table,
611 db->oids.cap,
612 db->oids.cap + 8);
613
614 db->oids.table[db->oids.num].name = name;
615 db->oids.table[db->oids.num].oid = *oid;
616 db->oids.num++;
617
618 return GNUNET_OK;
619}
620
621
632{
633 static const char *typnames[] = {
634 "bool",
635 "int2",
636 "int4",
637 "int8",
638 "bytea",
639 "varchar"
640 };
641 Oid oid;
642
643 for (size_t i = 0; i< sizeof(typnames) / sizeof(*typnames); i++)
644 {
645 if (GNUNET_OK !=
647 typnames[i],
648 &oid))
649 {
651 "pq",
652 "Couldn't retrieve OID for type %s\n",
653 typnames[i]);
654 return GNUNET_SYSERR;
655 }
656 }
657 return GNUNET_OK;
658}
659
660
661void
663{
665 -1);
667 db->versioning_ok = GNUNET_SYSERR; /* new connection, new game */
668 db->conn = PQconnectdb (db->config_str);
669 if ( (NULL == db->conn) ||
670 (CONNECTION_OK != PQstatus (db->conn)) )
671 {
673 "pq",
674 "Database connection to '%s' failed: %s\n",
675 db->config_str,
676 (NULL != db->conn)
677 ? PQerrorMessage (db->conn)
678 : "PQconnectdb returned NULL");
680 return;
681 }
682 PQsetNoticeReceiver (db->conn,
684 db);
685 PQsetNoticeProcessor (db->conn,
687 db);
688 if (NULL != db->rc)
689 db->rc (db->rc_cls,
690 db);
691
692 /* Prepare statement for OID lookup by name */
693 if (GNUNET_OK !=
695 return;
696
697 /* Reset the OID-cache and retrieve the OIDs for the supported Array types */
698 db->oids.num = 0;
700 {
702 "Failed to retrieve OID information for array types!\n");
704 return;
705 }
707 PQsocket (db->conn));
708}
709
710
713{
715
717 if (GNUNET_SYSERR == ret)
718 return GNUNET_SYSERR;
719 if (GNUNET_YES == ret)
720 return GNUNET_NO; /* already setup */
722 "versioning");
723 if (GNUNET_NO == ret)
724 {
726 "Failed to find SQL file to load database versioning logic\n");
727 return GNUNET_SYSERR;
728 }
729 if (GNUNET_SYSERR == ret)
730 {
732 "Failed to run SQL logic to setup database versioning logic\n");
733 return GNUNET_SYSERR;
734 }
735 db->versioning_ok = GNUNET_YES;
736 return GNUNET_OK;
737}
738
739
740struct GNUNET_PQ_Context *
742 const char *section,
745{
746 struct GNUNET_PQ_Context *db;
747 char *conninfo;
748 char *load_path;
749
750 if (GNUNET_OK !=
752 section,
753 "CONFIG",
754 &conninfo))
755 conninfo = GNUNET_strdup ("");
756 load_path = NULL;
757 if (GNUNET_OK !=
759 section,
760 "SQL_DIR",
761 &load_path))
762 {
764 section,
765 "SQL_DIR");
766 }
768 db->versioning_ok = GNUNET_SYSERR;
769 db->config_str = conninfo;
770 db->load_path = load_path;
771 db->rc = rc;
772 db->rc_cls = rc_cls;
773 db->channel_map = GNUNET_CONTAINER_multishortmap_create (16,
774 true);
776 if (NULL == db->conn)
777 {
779 GNUNET_free (db->config_str);
780 GNUNET_free (db);
781 return NULL;
782 }
783 return db;
784}
785
786
787void
789{
790 if (NULL == db)
791 return;
792 GNUNET_assert (0 ==
795 if (NULL != db->poller_task)
796 {
797 GNUNET_SCHEDULER_cancel (db->poller_task);
798 db->poller_task = NULL;
799 }
800 GNUNET_free (db->load_path);
801 GNUNET_free (db->config_str);
802 GNUNET_free (db->oids.table);
803 db->oids.num = 0;
804 db->oids.cap = 0;
805 PQfinish (db->conn);
806 GNUNET_free (db);
807}
808
809
810/* end of pq/pq_connect.c */
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static char * name
Name (label) of the records to list.
static char * res
Currently read line or NULL on EOF.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_FS_DirectoryBuilder * db
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
@ GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
The transaction succeeded, and yielded one result.
@ GNUNET_DB_STATUS_HARD_ERROR
A hard error occurred, retrying will not help.
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.
@ GNUNET_DB_STATUS_SOFT_ERROR
A soft error occurred, retrying the transaction may succeed.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32(const char *name, uint32_t *u32)
uint32_t expected.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_singleton_select(struct GNUNET_PQ_Context *db, const char *statement_name, const struct GNUNET_PQ_QueryParam *params, struct GNUNET_PQ_ResultSpec *rs)
Execute a named prepared statement that is a SELECT statement which must return a single result in co...
Definition pq_eval.c:199
void(* GNUNET_PQ_ReconnectCallback)(void *cls, struct GNUNET_PQ_Context *pq)
Function called each time we connect or reconnect to the database.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_string(const char *name, char **dst)
0-terminated string expected.
#define GNUNET_PQ_query_param_end
End of query parameter specification.
void GNUNET_PQ_cleanup_result(struct GNUNET_PQ_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_PQ_extract_result().
Definition pq.c:142
uint32_t oid
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_string(const char *ptr)
Generate query parameter for a string.
#define GNUNET_PQ_result_spec_end
End of result parameter specification.
#define GNUNET_PQ_RECONNECT_CALLBACK_CLOSURE
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test_read(const char *fil)
Check that fil corresponds to a filename and the file has read permissions.
Definition disk.c:565
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
#define GNUNET_log(kind,...)
#define GNUNET_log_from(kind, comp,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_process_run_command_va(struct GNUNET_Process *p, const char *filename,...)
Set the command and start a process.
Definition os_process.c:906
enum GNUNET_GenericReturnValue GNUNET_process_wait(struct GNUNET_Process *proc, bool blocking, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Wait for a process to terminate.
void GNUNET_process_destroy(struct GNUNET_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition os_process.c:363
GNUNET_OS_ProcessStatusType
Process status types.
struct GNUNET_Process * GNUNET_process_create(enum GNUNET_OS_InheritStdioFlags std_inheritance)
Create a process handle.
Definition os_process.c:465
@ GNUNET_OS_INHERIT_STD_NONE
No standard streams should be inherited.
@ GNUNET_OS_PROCESS_EXITED
The process exited with a return code.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
shared internal data structures of libgnunetpq
void GNUNET_PQ_event_reconnect_(struct GNUNET_PQ_Context *db, int fd)
Internal API.
Definition pq_event.c:434
static enum GNUNET_GenericReturnValue check_patch_applied(struct GNUNET_PQ_Context *db, const char *load_path, unsigned int patch_number)
Check if the patch with patch_number from the given load_path was already applied on the db.
Definition pq_connect.c:184
static char * get_sql_file_name(const struct GNUNET_PQ_Context *db, const char *infix)
Construct the name of the SQL file with the given filename infix in the load path of db.
Definition pq_connect.c:305
static enum GNUNET_GenericReturnValue prepare_check_patch(struct GNUNET_PQ_Context *db)
Prepare the "gnunet_pq_check_patch" statement.
Definition pq_connect.c:56
enum GNUNET_GenericReturnValue GNUNET_PQ_check_current(struct GNUNET_PQ_Context *db, const char *load_suffix)
Check if the database is current with respect to database migrations using prefix.
Definition pq_connect.c:450
static bool find_next_patch(const struct GNUNET_PQ_Context *db, const char *load_suffix, unsigned int from, unsigned int *found)
Find the lowest patch number of at least from for which an SQL file exists in the load path of db.
Definition pq_connect.c:368
static void pq_notice_receiver_cb(void *arg, const PGresult *res)
Function called by libpq whenever it wants to log something.
Definition pq_connect.c:265
static void reset_connection(struct GNUNET_PQ_Context *db)
Close connection to db and mark it as uninitialized.
Definition pq_connect.c:37
static enum GNUNET_GenericReturnValue prepare_get_oid_by_name(struct GNUNET_PQ_Context *db)
Prepare the "gnunet_pq_get_oid_by_name" statement.
Definition pq_connect.c:96
void GNUNET_PQ_reconnect_if_down(struct GNUNET_PQ_Context *db)
Reinitialize the database db if the connection is down.
Definition pq_connect.c:549
void GNUNET_PQ_disconnect(struct GNUNET_PQ_Context *db)
Disconnect from the database, destroying the prepared statements and releasing other associated resou...
Definition pq_connect.c:788
struct GNUNET_PQ_Context * GNUNET_PQ_init(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_PQ_ReconnectCallback rc, GNUNET_PQ_RECONNECT_CALLBACK_CLOSURE *rc_cls)
Definition pq_connect.c:741
static enum GNUNET_GenericReturnValue check_versioning_ok(struct GNUNET_PQ_Context *db)
Check if the "_v" versioning schema exists (and cache the result in db).
Definition pq_connect.c:135
void GNUNET_PQ_reconnect_(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition pq_connect.c:662
enum GNUNET_GenericReturnValue GNUNET_PQ_load_versioning(struct GNUNET_PQ_Context *db)
Setup database versioning.
Definition pq_connect.c:712
static void pq_notice_processor_cb(void *arg, const char *message)
Function called by libpq whenever it wants to log something.
Definition pq_connect.c:282
enum GNUNET_GenericReturnValue GNUNET_PQ_get_oid_by_name(struct GNUNET_PQ_Context *db, const char *name, Oid *oid)
Returns the oid for a given datatype by name.
Definition pq_connect.c:561
enum GNUNET_GenericReturnValue GNUNET_PQ_exec_sql(struct GNUNET_PQ_Context *db, const char *buf)
Execute SQL statements from buf against db.
Definition pq_connect.c:388
static enum GNUNET_GenericReturnValue patch_file_exists(const struct GNUNET_PQ_Context *db, const char *load_suffix, unsigned int patch_number)
Check if the SQL file for the patch with the given patch_number exists in the load path of db.
Definition pq_connect.c:331
static enum GNUNET_GenericReturnValue load_initial_oids(struct GNUNET_PQ_Context *db)
Load the initial set of OIDs for the supported array-datatypes.
Definition pq_connect.c:631
enum GNUNET_GenericReturnValue GNUNET_PQ_run_sql(struct GNUNET_PQ_Context *db, const char *load_suffix)
Within the db context, run all the SQL files in the load path where the name starts with the load_suf...
Definition pq_connect.c:486
Handle to Postgres database.
Definition pq.h:36
GNUNET_PQ_ReconnectCallback rc
Function to call whenever we needed to reconnect conn.
Definition pq.h:45
char * load_path
Path to load SQL files from.
Definition pq.h:60
GNUNET_PQ_RECONNECT_CALLBACK_CLOSURE * rc_cls
Closure for rc.
Definition pq.h:50
Description of a DB query parameter.
Description of a DB result cell.