GNUnet 0.29.1-dev.1-3-g346358e26
 
Loading...
Searching...
No Matches
pq_connect.c File Reference

functions to connect to libpq (PostGres) More...

#include "platform.h"
#include "pq.h"
#include <poll.h>
#include <pthread.h>
Include dependency graph for pq_connect.c:

Go to the source code of this file.

Macros

#define PSQL_OUTPUT_BYTES   (64 * 1024)
 Maximum stderr tail retained from one psql invocation.
 
#define PSQL_OUTPUT_LINES   250
 Maximum number of retained stderr lines emitted on failure.
 

Functions

static void reset_connection (struct GNUNET_PQ_Context *db)
 Close connection to db and mark it as uninitialized.
 
static enum GNUNET_GenericReturnValue prepare_check_patch (struct GNUNET_PQ_Context *db)
 Prepare the "gnunet_pq_check_patch" statement.
 
static enum GNUNET_GenericReturnValue prepare_get_oid_by_name (struct GNUNET_PQ_Context *db)
 Prepare the "gnunet_pq_get_oid_by_name" statement.
 
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).
 
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.
 
static void pq_notice_receiver_cb (void *arg, const PGresult *res)
 Function called by libpq whenever it wants to log something.
 
static void pq_notice_processor_cb (void *arg, const char *message)
 Function called by libpq whenever it wants to log something.
 
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.
 
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.
 
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.
 
static void log_psql_output (char *output, size_t size, bool truncated)
 Log the last lines of captured psql stderr through the component logger.
 
enum GNUNET_GenericReturnValue GNUNET_PQ_exec_sql (struct GNUNET_PQ_Context *db, const char *buf)
 Execute SQL statements from buf against db.
 
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.
 
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_suffix and ends with consecutive numbers from "[0000-9999].sql".
 
void GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
 Reinitialize the database db if the connection is down.
 
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.
 
static enum GNUNET_GenericReturnValue load_initial_oids (struct GNUNET_PQ_Context *db)
 Load the initial set of OIDs for the supported array-datatypes.
 
void GNUNET_PQ_reconnect_ (struct GNUNET_PQ_Context *db)
 Reinitialize the database db.
 
enum GNUNET_GenericReturnValue GNUNET_PQ_load_versioning (struct GNUNET_PQ_Context *db)
 Setup database versioning.
 
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)
 
void GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db)
 Disconnect from the database, destroying the prepared statements and releasing other associated resources.
 

Detailed Description

functions to connect to libpq (PostGres)

Author
Christian Grothoff
Özgür Kesim

Definition in file pq_connect.c.

Macro Definition Documentation

◆ PSQL_OUTPUT_BYTES

#define PSQL_OUTPUT_BYTES   (64 * 1024)

Maximum stderr tail retained from one psql invocation.

Definition at line 33 of file pq_connect.c.

◆ PSQL_OUTPUT_LINES

#define PSQL_OUTPUT_LINES   250

Maximum number of retained stderr lines emitted on failure.

Definition at line 36 of file pq_connect.c.

Function Documentation

◆ reset_connection()

static void reset_connection ( struct GNUNET_PQ_Context *  db)
static

Close connection to db and mark it as uninitialized.

Parameters
[in,out]dbconnection to close

Definition at line 45 of file pq_connect.c.

46{
47 if (NULL == db->conn)
48 return;
49 PQfinish (db->conn);
50 db->conn = NULL;
51 db->prepared_check_patch = false;
52 db->prepared_get_oid_by_name = false;
53}
static struct GNUNET_FS_DirectoryBuilder * db

References db.

Referenced by GNUNET_PQ_reconnect_(), prepare_check_patch(), and prepare_get_oid_by_name().

Here is the caller graph for this function:

◆ prepare_check_patch()

static enum GNUNET_GenericReturnValue prepare_check_patch ( struct GNUNET_PQ_Context *  db)
static

Prepare the "gnunet_pq_check_patch" statement.

Parameters
[in,out]dbdatabase to prepare statement for
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 64 of file pq_connect.c.

65{
66 PGresult *res;
67
68 if (db->prepared_check_patch)
69 return GNUNET_OK;
70 res = PQprepare (db->conn,
71 "gnunet_pq_check_patch",
72 "SELECT"
73 " applied_by"
74 " FROM _v.patches"
75 " WHERE patch_name = $1"
76 " LIMIT 1",
77 1,
78 NULL);
79 if (PGRES_COMMAND_OK !=
80 PQresultStatus (res))
81 {
83 "Failed to run SQL logic to setup database versioning logic: %s/%s\n",
84 PQresultErrorMessage (res),
85 PQerrorMessage (db->conn));
86 PQclear (res);
88 return GNUNET_SYSERR;
89 }
90 PQclear (res);
91 db->prepared_check_patch = true;
92 return GNUNET_OK;
93}
static char * res
Currently read line or NULL on EOF.
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_ERROR
static void reset_connection(struct GNUNET_PQ_Context *db)
Close connection to db and mark it as uninitialized.
Definition pq_connect.c:45

References db, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, GNUNET_SYSERR, res, and reset_connection().

Referenced by check_patch_applied().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_get_oid_by_name()

static enum GNUNET_GenericReturnValue prepare_get_oid_by_name ( struct GNUNET_PQ_Context *  db)
static

Prepare the "gnunet_pq_get_oid_by_name" statement.

Parameters
[in,out]dbdatabase to prepare statement for
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 104 of file pq_connect.c.

105{
106 PGresult *res;
107
108 if (db->prepared_get_oid_by_name)
109 return GNUNET_OK;
110 res = PQprepare (db->conn,
111 "gnunet_pq_get_oid_by_name",
112 "SELECT typname, oid"
113 " FROM pg_type"
114 " WHERE oid = to_regtype($1)",
115 1,
116 NULL);
117 if (PGRES_COMMAND_OK != PQresultStatus (res))
118 {
120 "Failed to run SQL statement prepare OID lookups: %s/%s\n",
121 PQresultErrorMessage (res),
122 PQerrorMessage (db->conn));
123 PQclear (res);
125 return GNUNET_SYSERR;
126 }
127 PQclear (res);
128 db->prepared_get_oid_by_name = true;
129 return GNUNET_OK;
130}

References db, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, GNUNET_SYSERR, res, and reset_connection().

Referenced by GNUNET_PQ_reconnect_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_versioning_ok()

static enum GNUNET_GenericReturnValue check_versioning_ok ( struct GNUNET_PQ_Context *  db)
static

Check if the "_v" versioning schema exists (and cache the result in db).

Parameters
[in,out]dbconnection to check
Returns
GNUNET_OK if versioning is OK GNUNET_NO if it is not loaded GNUNET_SYSERR if we encountered an error

Definition at line 143 of file pq_connect.c.

144{
145 PGresult *res;
146 ExecStatusType est;
147
148 if (GNUNET_OK == db->versioning_ok)
149 return GNUNET_OK;
150 if (GNUNET_NO == db->versioning_ok)
151 return GNUNET_NO;
152 res = PQexec (db->conn,
153 "SELECT"
154 " schema_name"
155 " FROM information_schema.schemata"
156 " WHERE schema_name='_v';");
157 est = PQresultStatus (res);
158 if ( (PGRES_COMMAND_OK != est) &&
159 (PGRES_TUPLES_OK != est) )
160 {
162 "Failed to run statement to check versioning schema. Bad!\n");
163 PQclear (res);
164 return GNUNET_SYSERR;
165 }
166 if (0 == PQntuples (res))
167 {
168 PQclear (res);
169 db->versioning_ok = GNUNET_NO;
171 "_v schema not found\n");
172 return GNUNET_NO;
173 }
174 PQclear (res);
175 db->versioning_ok = GNUNET_OK;
176 return GNUNET_OK;
177}
@ GNUNET_NO
@ GNUNET_ERROR_TYPE_INFO

References db, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, and res.

Referenced by check_patch_applied(), and GNUNET_PQ_load_versioning().

Here is the caller graph for this function:

◆ check_patch_applied()

static enum GNUNET_GenericReturnValue check_patch_applied ( struct GNUNET_PQ_Context *  db,
const char *  load_path,
unsigned int  patch_number 
)
static

Check if the patch with patch_number from the given load_path was already applied on the db.

Parameters
[in]dbdatabase to check
load_pathfile system path to database setup files
patch_numbernumber of the patch to check
Returns
GNUNET_OK if patch is applied GNUNET_NO if patch is not applied GNUNET_SYSERR on internal error (DB failure)

Definition at line 192 of file pq_connect.c.

195{
196 const char *load_path_suffix;
197 size_t slen = strlen (load_path) + 10;
198 char patch_name[slen];
199
200 if (GNUNET_SYSERR ==
202 {
203 GNUNET_break (0);
204 return GNUNET_SYSERR; /* no versioning, cannot check */
205 }
206 load_path_suffix = strrchr (load_path,
207 '/');
208 if (NULL == load_path_suffix)
209 load_path_suffix = load_path;
210 else
211 load_path_suffix++; /* skip '/' */
212 GNUNET_snprintf (patch_name,
213 sizeof (patch_name),
214 "%s%04u",
215 load_path_suffix,
216 patch_number);
217 {
218 struct GNUNET_PQ_QueryParam params[] = {
219 GNUNET_PQ_query_param_string (patch_name),
221 };
222 char *applied_by;
223 struct GNUNET_PQ_ResultSpec rs[] = {
224 GNUNET_PQ_result_spec_string ("applied_by",
225 &applied_by),
227 };
228 enum GNUNET_DB_QueryStatus qs;
229
230 if (GNUNET_OK !=
232 {
233 GNUNET_break (0);
234 return GNUNET_SYSERR;
235 }
237 "gnunet_pq_check_patch",
238 params,
239 rs);
240 switch (qs)
241 {
244 "Database version %s already applied by %s\n",
245 patch_name,
246 applied_by);
248 return GNUNET_OK;
250 return GNUNET_NO;
252 GNUNET_break (0);
253 return GNUNET_SYSERR;
255 GNUNET_break (0);
256 return GNUNET_SYSERR;
257 }
258 GNUNET_assert (0);
259 return GNUNET_SYSERR;
260 }
261}
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.
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
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:143
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_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.
@ GNUNET_ERROR_TYPE_DEBUG
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.
static enum GNUNET_GenericReturnValue prepare_check_patch(struct GNUNET_PQ_Context *db)
Prepare the "gnunet_pq_check_patch" statement.
Definition pq_connect.c:64
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:143
Description of a DB query parameter.
Description of a DB result cell.

References check_versioning_ok(), db, GNUNET_assert, GNUNET_break, GNUNET_DB_STATUS_HARD_ERROR, GNUNET_DB_STATUS_SOFT_ERROR, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_PQ_cleanup_result(), GNUNET_PQ_eval_prepared_singleton_select(), GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_string(), GNUNET_PQ_result_spec_end, GNUNET_PQ_result_spec_string(), GNUNET_snprintf(), GNUNET_SYSERR, and prepare_check_patch().

Referenced by GNUNET_PQ_check_current(), and GNUNET_PQ_run_sql().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pq_notice_receiver_cb()

static void pq_notice_receiver_cb ( void *  arg,
const PGresult *  res 
)
static

Function called by libpq whenever it wants to log something.

We already log whenever we care, so this function does nothing and merely exists to silence the libpq logging.

Parameters
argthe SQL connection that was used
resinformation about some libpq event

Definition at line 273 of file pq_connect.c.

275{
276 /* do nothing, intentionally */
277 (void) arg;
278 (void) res;
279}

References res.

Referenced by GNUNET_PQ_reconnect_().

Here is the caller graph for this function:

◆ pq_notice_processor_cb()

static void pq_notice_processor_cb ( void *  arg,
const char *  message 
)
static

Function called by libpq whenever it wants to log something.

We log those using the GNUnet logger.

Parameters
argthe SQL connection that was used
messageinformation about some libpq event

Definition at line 290 of file pq_connect.c.

292{
293 (void) arg;
295 "pq",
296 "%s",
297 message);
298}
#define GNUNET_log_from(kind, comp,...)

References GNUNET_ERROR_TYPE_INFO, and GNUNET_log_from.

Referenced by GNUNET_PQ_reconnect_().

Here is the caller graph for this function:

◆ get_sql_file_name()

static char * get_sql_file_name ( const struct GNUNET_PQ_Context *  db,
const char *  infix 
)
static

Construct the name of the SQL file with the given filename infix in the load path of db.

This is the one place where the mapping from a filename infix to an actual file on disk is defined; all callers must use it, or they risk probing for files that are never loaded (and vice versa).

Parameters
dbdatabase context to get the load path from
infixfilename infix (!) identifying the SQL file
Returns
name of the SQL file, to be freed by the caller

Definition at line 313 of file pq_connect.c.

315{
316 char *fn;
317
318 GNUNET_asprintf (&fn,
319 "%s%s.sql",
320 db->load_path,
321 infix);
322 return fn;
323}
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.

References db, and GNUNET_asprintf().

Referenced by GNUNET_PQ_exec_sql(), and patch_file_exists().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ patch_file_exists()

static enum GNUNET_GenericReturnValue patch_file_exists ( const struct GNUNET_PQ_Context *  db,
const char *  load_suffix,
unsigned int  patch_number 
)
static

Check if the SQL file for the patch with the given patch_number exists in the load path of db.

Parameters
dbdatabase context to get the load path from
load_suffixsuffix to append to the load path, usually "subsystem-"
patch_numbernumber of the patch to look for
Returns
GNUNET_YES if the file exists and is readable, GNUNET_NO if it does not exist, GNUNET_SYSERR on error

Definition at line 339 of file pq_connect.c.

342{
343 size_t slen = strlen (load_suffix) + 10;
344 char patch_name[slen];
345 char *fn;
347
348 GNUNET_snprintf (patch_name,
349 sizeof (patch_name),
350 "%s%04u",
351 load_suffix,
352 patch_number);
353 fn = get_sql_file_name (db,
354 patch_name);
356 GNUNET_free (fn);
357 return ret;
358}
static int ret
Final status code.
Definition gnunet-arm.c:93
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
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_free(ptr)
Wrapper around free.
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:313

References db, get_sql_file_name(), GNUNET_DISK_file_test_read(), GNUNET_free, GNUNET_snprintf(), and ret.

Referenced by find_next_patch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_next_patch()

static bool find_next_patch ( const struct GNUNET_PQ_Context *  db,
const char *  load_suffix,
unsigned int  from,
unsigned int *  found 
)
static

Find the lowest patch number of at least from for which an SQL file exists in the load path of db.

Used to tell "we ran out of patches" apart from "there is a hole in the numbering": the latter must never be treated as the end of the sequence, as we would then silently ignore all patches beyond the hole.

Parameters
dbdatabase context to get the load path from
load_suffixsuffix to append to the load path, usually "subsystem-"
frompatch number to start searching at
[out]foundset to the number of the patch that was found
Returns
true if a patch with a number of at least from exists

Definition at line 376 of file pq_connect.c.

380{
381 for (unsigned int i = from; i<5; i++)
382 {
383 if (GNUNET_YES !=
385 load_suffix,
386 i))
387 continue;
388 *found = i;
389 return true;
390 }
391 return false;
392}
@ GNUNET_YES
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:339

References db, GNUNET_YES, and patch_file_exists().

Referenced by GNUNET_PQ_check_current(), and GNUNET_PQ_run_sql().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ log_psql_output()

static void log_psql_output ( char *  output,
size_t  size,
bool  truncated 
)
static

Log the last lines of captured psql stderr through the component logger.

Parameters
outputcaptured bytes, modified in place, with room for a terminator
sizenumber of captured bytes
truncatedwhether earlier bytes have already been discarded

Definition at line 403 of file pq_connect.c.

406{
407 size_t start = 0;
408 unsigned int lines = 0;
409
410 for (size_t i = size; i > 0; i--)
411 {
412 /* A trailing newline terminates the last line, not an extra empty one. */
413 if ( ('\n' == output[i - 1]) &&
414 (i < size) &&
415 (PSQL_OUTPUT_LINES == ++lines) )
416 {
417 start = i;
418 truncated = true;
419 break;
420 }
421 }
422 if (truncated)
424 "psql stderr truncated to the last %u lines and %u bytes; earlier output omitted\n",
427 output[size] = '\0';
428 for (size_t i = start; i < size; i++)
429 {
430 /* Do not let an embedded NUL hide the remaining diagnostics. */
431 if ('\0' == output[i])
432 output[i] = '?';
433 if ('\n' != output[i])
434 continue;
435 output[i] = '\0';
437 "psql: %s\n",
438 &output[start]);
439 start = i + 1;
440 }
441 if (start < size)
443 "psql: %s\n",
444 &output[start]);
445}
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static unsigned int size
Size of the "table".
Definition peer.c:68
#define PSQL_OUTPUT_LINES
Maximum number of retained stderr lines emitted on failure.
Definition pq_connect.c:36
#define PSQL_OUTPUT_BYTES
Maximum stderr tail retained from one psql invocation.
Definition pq_connect.c:33

References GNUNET_ERROR_TYPE_ERROR, GNUNET_log, PSQL_OUTPUT_BYTES, PSQL_OUTPUT_LINES, size, and start.

Referenced by GNUNET_PQ_exec_sql().

Here is the caller graph for this function:

◆ GNUNET_PQ_exec_sql()

enum GNUNET_GenericReturnValue GNUNET_PQ_exec_sql ( struct GNUNET_PQ_Context *  db,
const char *  buf 
)

Execute SQL statements from buf against db.

The given filename infix in buf is prefixed with the "load_path" and ".sql" is appended to construct the full filename.

Parameters
[in,out]dbdatabase context to use
buffilename infix (!) with the SQL code to run
Returns
GNUNET_OK on success GNUNET_NO if patch buf does not exist GNUNET_SYSERR on error

Definition at line 449 of file pq_connect.c.

451{
452 struct GNUNET_Process *psql;
454 unsigned long code;
455 char *fn;
456 struct GNUNET_DISK_PipeHandle *errors;
457 char *output;
458 size_t used = 0;
459 bool truncated = false;
460 bool capture_failed = false;
461 bool child_exited = false;
462 int queued = 0;
463 const struct GNUNET_DISK_FileHandle *reader;
464 struct pollfd ready;
466
467 fn = get_sql_file_name (db,
468 buf);
469 if (GNUNET_YES !=
471 {
472 GNUNET_free (fn);
473 return GNUNET_NO;
474 }
476 "Applying SQL file `%s' on database %s\n",
477 fn,
478 db->config_str);
480 if (NULL == errors)
481 {
483 "pipe for psql stderr",
484 fn);
485 GNUNET_free (fn);
486 return GNUNET_SYSERR;
487 }
488 output = GNUNET_malloc (PSQL_OUTPUT_BYTES + 1);
489 reader = GNUNET_DISK_pipe_handle (errors,
491 ready = (struct pollfd) {
493 .events = POLLIN
494 };
496 if (GNUNET_OK !=
498 psql,
500 STDERR_FILENO)))
501 {
503 "Failed to configure psql stderr capture for SQL file `%s'\n",
504 fn);
505 goto cleanup;
506 }
507 if (GNUNET_OK !=
509 "psql",
510 "psql",
511 db->config_str,
512 "-f",
513 fn,
514 "-q",
515 "--set",
516 "ON_ERROR_STOP=1",
517 NULL))
518 {
520 "exec",
521 "psql");
522 goto cleanup;
523 }
524 /* Drain while psql is running so verbose scripts cannot fill the pipe.
525 Descendants may inherit stderr: once psql exits, drain only the bytes
526 already queued instead of waiting for every inherited writer to close. */
527 while (true)
528 {
529 char chunk[4096];
530 ssize_t count;
531 size_t wanted = sizeof (chunk);
532
533 if (! child_exited)
534 {
536
538 false,
539 &type,
540 &code);
541 if (GNUNET_SYSERR == status)
542 goto wait_failed;
543 if (GNUNET_OK == status)
544 {
545 child_exited = true;
546 while (0 > ioctl (ready.fd, FIONREAD, &queued))
547 {
548 if (EINTR == errno)
549 continue;
551 "inspect queued psql stderr",
552 fn);
553 capture_failed = true;
554 break;
555 }
556 if (capture_failed)
557 break;
558 }
559 }
560 if (child_exited)
561 {
562 if (0 == queued)
563 break;
564 wanted = GNUNET_MIN (wanted, (size_t) queued);
565 }
566 count = GNUNET_DISK_file_read (reader,
567 chunk,
568 wanted);
569 if (0 == count)
570 break;
571 if (0 > count)
572 {
573 if (EINTR == errno)
574 continue;
575 if ( (EAGAIN == errno) || (EWOULDBLOCK == errno) )
576 {
577 if (child_exited)
578 break;
579 /* Periodically recheck the child even if an inherited writer keeps
580 the pipe open without producing output. */
581 if ( (0 > poll (&ready, 1, 100)) && (EINTR != errno) )
582 {
584 "poll psql stderr",
585 fn);
586 capture_failed = true;
587 break;
588 }
589 continue;
590 }
592 "read psql stderr",
593 fn);
594 capture_failed = true;
595 break;
596 }
597 if (child_exited)
598 queued -= count;
599 if (used + count > PSQL_OUTPUT_BYTES)
600 {
601 size_t discard = used + count - PSQL_OUTPUT_BYTES;
602
603 memmove (output,
604 output + discard,
605 used - discard);
606 used -= discard;
607 truncated = true;
608 }
609 memcpy (output + used,
610 chunk,
611 count);
612 used += count;
613 }
614 if (capture_failed && (! child_exited))
615 (void) GNUNET_process_kill (psql,
616 SIGKILL);
617 if (GNUNET_OK !=
619 true,
620 &type,
621 &code))
622 goto wait_failed;
623 if ( (GNUNET_OS_PROCESS_EXITED != type) ||
624 (0 != code) )
625 {
628 "Failed to execute SQL file `%s': psql terminated by signal %lu\n",
629 fn,
630 code);
631 else
633 "Failed to execute SQL file `%s': psql exit code was %lu\n",
634 fn,
635 code);
636 capture_failed = true;
637 }
638 if (capture_failed)
639 log_psql_output (output,
640 used,
641 truncated);
642 else
643 ret = GNUNET_OK;
644 goto cleanup;
645wait_failed:
646 /* ECHILD means another reaper already collected the process; its PID
647 must not be signalled since it could have been reused. */
648 {
649 int eno = errno;
650
652 "wait for psql",
653 fn);
654 if (ECHILD != eno)
655 {
656 (void) GNUNET_process_kill (psql,
657 SIGKILL);
658 (void) GNUNET_process_wait (psql,
659 true,
660 NULL,
661 NULL);
662 }
663 }
664 log_psql_output (output,
665 used,
666 truncated);
667cleanup:
669 GNUNET_DISK_pipe_close (errors);
670 GNUNET_free (output);
671 GNUNET_free (fn);
672 return ret;
673}
static uint32_t type
Type string converted to DNS type value.
static int status
The program status; 0 for success.
Definition gnunet-nse.c:39
static void cleanup()
Cleanup task.
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition disk.c:1703
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition disk.c:1524
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition disk.c:1671
int GNUNET_DISK_internal_file_handle(const struct GNUNET_DISK_FileHandle *fh)
Retrieve OS file handle.
Definition disk.c:1731
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition disk.c:704
@ GNUNET_DISK_PF_BLOCKING_WRITE
Configure write end to block when writing if set.
@ GNUNET_DISK_PIPE_END_READ
The reading-end of a pipe.
#define GNUNET_MIN(a, b)
#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...
#define GNUNET_malloc(size)
Wrapper around malloc.
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
#define GNUNET_process_set_options(proc,...)
Set the requested options for the process.
GNUNET_OS_ProcessStatusType
Process status types.
#define GNUNET_process_option_inherit_wpipe(wpipe, child_fd)
Have child process inherit a pipe for writing.
enum GNUNET_GenericReturnValue GNUNET_process_kill(struct GNUNET_Process *proc, int sig)
Sends a signal to the process.
Definition os_process.c:307
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_SIGNALED
The process was killed by a signal.
@ GNUNET_OS_PROCESS_EXITED
The process exited with a return code.
static void log_psql_output(char *output, size_t size, bool truncated)
Log the last lines of captured psql stderr through the component logger.
Definition pq_connect.c:403
Handle used to access files (and pipes).
Handle used to manage a pipe.
Definition disk.c:69

References cleanup(), db, get_sql_file_name(), GNUNET_DISK_file_read(), GNUNET_DISK_file_test_read(), GNUNET_DISK_internal_file_handle(), GNUNET_DISK_PF_BLOCKING_WRITE, GNUNET_DISK_pipe(), GNUNET_DISK_pipe_close(), GNUNET_DISK_PIPE_END_READ, GNUNET_DISK_pipe_handle(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_MIN, GNUNET_NO, GNUNET_OK, GNUNET_OS_INHERIT_STD_NONE, GNUNET_OS_PROCESS_EXITED, GNUNET_OS_PROCESS_SIGNALED, GNUNET_process_create(), GNUNET_process_destroy(), GNUNET_process_kill(), GNUNET_process_option_inherit_wpipe, GNUNET_process_run_command_va(), GNUNET_process_set_options, GNUNET_process_wait(), GNUNET_SYSERR, GNUNET_YES, log_psql_output(), PSQL_OUTPUT_BYTES, ret, status, and type.

Referenced by GNUNET_PQ_load_versioning(), GNUNET_PQ_run_sql(), libgnunet_plugin_datacache_postgres_done(), and namestore_postgres_drop_tables().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_check_current()

enum GNUNET_GenericReturnValue GNUNET_PQ_check_current ( struct GNUNET_PQ_Context *  db,
const char *  prefix 
)

Check if the database is current with respect to database migrations using prefix.

Parameters
[in,out]dbdatabase to check versioning for
prefixprefix to use to check migrations
Returns
GNUNET_OK on success GNUNET_NO if migrations are pending GNUNET_SYSERR on failure

Definition at line 677 of file pq_connect.c.

679{
681 "Loading SQL resources from `%s'\n",
682 load_suffix);
683 for (unsigned int i = 1; i<10000; i++)
684 {
686 unsigned int next;
687
689 load_suffix,
690 i);
691 if (GNUNET_SYSERR == ret)
692 {
693 GNUNET_break (0);
694 return GNUNET_SYSERR;
695 }
696 if (GNUNET_OK == ret)
697 continue; /* patch already applied, skip it */
698 /* patch not applied, check if it (or, in case the numbering
699 has a hole, any later patch) exists... */
700 if (find_next_patch (db,
701 load_suffix,
702 i,
703 &next))
704 return GNUNET_NO;
705 return GNUNET_OK;
706 }
707 GNUNET_break (0); /* 10k patches applied!? */
708 return GNUNET_OK;
709}
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:192
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:376

References check_patch_applied(), db, find_next_patch(), GNUNET_break, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, and ret.

Here is the call graph for this function:

◆ GNUNET_PQ_run_sql()

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_suffix and ends with consecutive numbers from "[0000-9999].sql".

The numbering must have no gaps: if a patch file is missing but a higher-numbered one exists, this is an error, as we must not skip patches.

Parameters
dbdatabase context to use
load_suffixsuffix to append to the load path to find the XXXX.sql files, usually "subsystem-".
Returns
GNUNET_OK on success GNUNET_NO if no upgrade was needed GNUNET_SYSERR if the upgrade failed or the patch numbering has a gap

Definition at line 713 of file pq_connect.c.

715{
716 size_t slen = strlen (load_suffix) + 10;
717 char patch_name[slen];
718
720 "Loading SQL resources from `%s'\n",
721 load_suffix);
722 for (unsigned int i = 1; i<10000; i++)
723 {
725
727 load_suffix,
728 i);
729 if (GNUNET_SYSERR == ret)
730 {
731 GNUNET_break (0);
732 return GNUNET_SYSERR;
733 }
734 if (GNUNET_OK == ret)
735 continue; /* patch already applied, skip it */
736
737 GNUNET_snprintf (patch_name,
738 sizeof (patch_name),
739 "%s%04u",
740 load_suffix,
741 i);
743 patch_name);
744 if (GNUNET_NO == ret)
745 {
746 unsigned int next;
747
748 /* No such file. Before we conclude that we are done, make sure
749 this really is the end of the sequence and not a hole in the
750 numbering: applying the patches beyond the hole (or, worse,
751 silently not applying them) would leave the database in an
752 undefined state. */
753 if (find_next_patch (db,
754 load_suffix,
755 i + 1,
756 &next))
757 {
759 "Gap in SQL patch sequence: `%s%04u' is missing, but `%s%04u' exists; refusing to apply patches out of order\n",
760 load_suffix,
761 i,
762 load_suffix,
763 next);
764 return GNUNET_SYSERR;
765 }
766 break; /* no such file, we are done */
767 }
768 if (GNUNET_SYSERR == ret)
769 return GNUNET_SYSERR;
770 }
771 return GNUNET_OK;
772}
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:449

References check_patch_applied(), db, find_next_patch(), GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_PQ_exec_sql(), GNUNET_snprintf(), GNUNET_SYSERR, and ret.

Referenced by reconnect_cb(), reconnect_setup(), reconnect_setup(), and reconnect_setup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_reconnect_if_down()

void GNUNET_PQ_reconnect_if_down ( struct GNUNET_PQ_Context *  db)

Reinitialize the database db if the connection is down.

Parameters
[in,out]dbdatabase connection to reinitialize

Definition at line 776 of file pq_connect.c.

777{
778 if (1 ==
779 PQconsumeInput (db->conn))
780 return;
781 if (CONNECTION_BAD != PQstatus (db->conn))
782 return;
784}
void GNUNET_PQ_reconnect_(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition pq_connect.c:889

References db, and GNUNET_PQ_reconnect_().

Here is the call graph for this function:

◆ GNUNET_PQ_get_oid_by_name()

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.

Parameters
dbThe db-connection
nameThe name of the datatype
[out]oidThe OID of the datatype.
Returns
GNUNET_OK when the datatype was found, GNUNET_SYSERR otherwise

Definition at line 788 of file pq_connect.c.

792{
793 /* Check if the entry is in the cache already */
794 for (unsigned int i = 0; i < db->oids.num; i++)
795 {
796 /* Pointer comparison */
797 if (name == db->oids.table[i].name)
798 {
799 *oid = db->oids.table[i].oid;
800 return GNUNET_OK;
801 }
802 }
803
804 /* No entry found in cache, ask database */
805 {
806 enum GNUNET_DB_QueryStatus qs;
807 struct GNUNET_PQ_QueryParam params[] = {
810 };
811 struct GNUNET_PQ_ResultSpec spec[] = {
813 oid),
815 };
816
817 GNUNET_assert (NULL != db);
818
820 "gnunet_pq_get_oid_by_name",
821 params,
822 spec);
824 return GNUNET_SYSERR;
825 }
826
827 /* Add the entry to the cache */
828 if (NULL == db->oids.table)
829 {
830 db->oids.table = GNUNET_new_array (8,
831 typeof(*db->oids.table));
832 db->oids.cap = 8;
833 db->oids.num = 0;
834 }
835
836 if (db->oids.cap <= db->oids.num)
837 GNUNET_array_grow (db->oids.table,
838 db->oids.cap,
839 db->oids.cap + 8);
840
841 db->oids.table[db->oids.num].name = name;
842 db->oids.table[db->oids.num].oid = *oid;
843 db->oids.num++;
844
845 return GNUNET_OK;
846}
static char * name
Name (label) of the records to list.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32(const char *name, uint32_t *u32)
uint32_t expected.
uint32_t oid
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.

References db, GNUNET_array_grow, GNUNET_assert, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT, GNUNET_new_array, GNUNET_OK, GNUNET_PQ_eval_prepared_singleton_select(), GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_string(), GNUNET_PQ_result_spec_end, GNUNET_PQ_result_spec_uint32(), GNUNET_SYSERR, name, and oid.

Referenced by GNUNET_PQ_query_param_array_abs_time(), GNUNET_PQ_query_param_array_bool(), GNUNET_PQ_query_param_array_bytes(), GNUNET_PQ_query_param_array_bytes_same_size(), GNUNET_PQ_query_param_array_int16(), GNUNET_PQ_query_param_array_ptrs_abs_time(), GNUNET_PQ_query_param_array_ptrs_bytes(), GNUNET_PQ_query_param_array_ptrs_bytes_same_size(), GNUNET_PQ_query_param_array_ptrs_rel_time(), GNUNET_PQ_query_param_array_ptrs_string(), GNUNET_PQ_query_param_array_ptrs_timestamp(), GNUNET_PQ_query_param_array_rel_time(), GNUNET_PQ_query_param_array_string(), GNUNET_PQ_query_param_array_timestamp(), GNUNET_PQ_query_param_array_uint16(), GNUNET_PQ_query_param_array_uint32(), GNUNET_PQ_query_param_array_uint64(), GNUNET_PQ_result_spec_array_abs_time(), GNUNET_PQ_result_spec_array_bool(), GNUNET_PQ_result_spec_array_fixed_size(), GNUNET_PQ_result_spec_array_int16(), GNUNET_PQ_result_spec_array_rel_time(), GNUNET_PQ_result_spec_array_string(), GNUNET_PQ_result_spec_array_timestamp(), GNUNET_PQ_result_spec_array_uint16(), GNUNET_PQ_result_spec_array_uint32(), GNUNET_PQ_result_spec_array_uint64(), GNUNET_PQ_result_spec_array_variable_size(), and load_initial_oids().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_initial_oids()

static enum GNUNET_GenericReturnValue load_initial_oids ( struct GNUNET_PQ_Context *  db)
static

Load the initial set of OIDs for the supported array-datatypes.

Parameters
dbThe database context
Returns
GNUNET_OK on success, GNUNET_SYSERR if any of the types couldn't be found

Definition at line 858 of file pq_connect.c.

859{
860 static const char *typnames[] = {
861 "bool",
862 "int2",
863 "int4",
864 "int8",
865 "bytea",
866 "varchar"
867 };
868 Oid oid;
869
870 for (size_t i = 0; i< sizeof(typnames) / sizeof(*typnames); i++)
871 {
872 if (GNUNET_OK !=
874 typnames[i],
875 &oid))
876 {
878 "pq",
879 "Couldn't retrieve OID for type %s\n",
880 typnames[i]);
881 return GNUNET_SYSERR;
882 }
883 }
884 return GNUNET_OK;
885}
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:788

References db, GNUNET_ERROR_TYPE_ERROR, GNUNET_log_from, GNUNET_OK, GNUNET_PQ_get_oid_by_name(), GNUNET_SYSERR, and oid.

Referenced by GNUNET_PQ_reconnect_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_reconnect_()

void GNUNET_PQ_reconnect_ ( struct GNUNET_PQ_Context *  db)

Reinitialize the database db.

Parameters
dbdatabase connection to reinitialize
Deprecated:

Definition at line 889 of file pq_connect.c.

890{
892 -1);
894 db->versioning_ok = GNUNET_SYSERR; /* new connection, new game */
895 db->conn = PQconnectdb (db->config_str);
896 if ( (NULL == db->conn) ||
897 (CONNECTION_OK != PQstatus (db->conn)) )
898 {
900 "pq",
901 "Database connection to '%s' failed: %s\n",
902 db->config_str,
903 (NULL != db->conn)
904 ? PQerrorMessage (db->conn)
905 : "PQconnectdb returned NULL");
907 return;
908 }
909 PQsetNoticeReceiver (db->conn,
911 db);
912 PQsetNoticeProcessor (db->conn,
914 db);
915 if (NULL != db->rc)
916 db->rc (db->rc_cls,
917 db);
918
919 /* Prepare statement for OID lookup by name */
920 if (GNUNET_OK !=
922 return;
923
924 /* Reset the OID-cache and retrieve the OIDs for the supported Array types */
925 db->oids.num = 0;
927 {
929 "Failed to retrieve OID information for array types!\n");
931 return;
932 }
934 PQsocket (db->conn));
935}
void GNUNET_PQ_event_reconnect_(struct GNUNET_PQ_Context *db, int fd)
Internal API.
Definition pq_event.c:446
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:273
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:104
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:290
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:858

References db, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_log_from, GNUNET_OK, GNUNET_PQ_event_reconnect_(), GNUNET_SYSERR, load_initial_oids(), pq_notice_processor_cb(), pq_notice_receiver_cb(), prepare_get_oid_by_name(), and reset_connection().

Referenced by do_scheduler_notify(), GNUNET_PQ_eval_result(), GNUNET_PQ_event_do_poll(), GNUNET_PQ_exec_prepared(), GNUNET_PQ_init(), and GNUNET_PQ_reconnect_if_down().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_load_versioning()

enum GNUNET_GenericReturnValue GNUNET_PQ_load_versioning ( struct GNUNET_PQ_Context *  db)

Setup database versioning.

Parameters
[in,out]dbdatabase to load versioning for
Returns
GNUNET_OK on success GNUNET_NO if it was already loaded GNUNET_SYSERR on failure

Definition at line 939 of file pq_connect.c.

940{
942
944 if (GNUNET_SYSERR == ret)
945 return GNUNET_SYSERR;
946 if (GNUNET_YES == ret)
947 return GNUNET_NO; /* already setup */
949 "versioning");
950 if (GNUNET_NO == ret)
951 {
953 "Failed to find SQL file to load database versioning logic\n");
954 return GNUNET_SYSERR;
955 }
956 if (GNUNET_SYSERR == ret)
957 {
959 "Failed to run SQL logic to setup database versioning logic\n");
960 return GNUNET_SYSERR;
961 }
962 db->versioning_ok = GNUNET_YES;
963 return GNUNET_OK;
964}

References check_versioning_ok(), db, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_PQ_exec_sql(), GNUNET_SYSERR, GNUNET_YES, and ret.

Referenced by reconnect_setup(), and reconnect_setup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_init()

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 at line 968 of file pq_connect.c.

972{
973 struct GNUNET_PQ_Context *db;
974 char *conninfo;
975 char *load_path;
976
977 if (GNUNET_OK !=
979 section,
980 "CONFIG",
981 &conninfo))
982 conninfo = GNUNET_strdup ("");
983 load_path = NULL;
984 if (GNUNET_OK !=
986 section,
987 "SQL_DIR",
988 &load_path))
989 {
991 section,
992 "SQL_DIR");
993 }
995 db->versioning_ok = GNUNET_SYSERR;
996 db->config_str = conninfo;
997 db->load_path = load_path;
998 db->rc = rc;
999 db->rc_cls = rc_cls;
1000 db->channel_map = GNUNET_CONTAINER_multishortmap_create (16,
1001 true);
1003 if (NULL == db->conn)
1004 {
1006 GNUNET_free (db->config_str);
1007 GNUNET_free (db);
1008 return NULL;
1009 }
1010 return db;
1011}
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
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.
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.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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

References cfg, db, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONTAINER_multishortmap_create(), GNUNET_CONTAINER_multishortmap_destroy(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log_config_missing(), GNUNET_new, GNUNET_OK, GNUNET_PQ_reconnect_(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_PQ_Context::load_path, GNUNET_PQ_Context::rc, and GNUNET_PQ_Context::rc_cls.

Here is the call graph for this function:

◆ GNUNET_PQ_disconnect()

void GNUNET_PQ_disconnect ( struct GNUNET_PQ_Context *  db)

Disconnect from the database, destroying the prepared statements and releasing other associated resources.

Parameters
dbdatabase handle to disconnect (will be free'd)

Definition at line 1015 of file pq_connect.c.

1016{
1017 if (NULL == db)
1018 return;
1019 GNUNET_assert (0 ==
1022 if (NULL != db->poller_task)
1023 {
1024 GNUNET_SCHEDULER_cancel (db->poller_task);
1025 db->poller_task = NULL;
1026 }
1027 GNUNET_free (db->load_path);
1028 GNUNET_free (db->config_str);
1029 GNUNET_free (db->oids.table);
1030 db->oids.num = 0;
1031 db->oids.cap = 0;
1032 PQfinish (db->conn);
1033 GNUNET_free (db);
1034}
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986

References db, GNUNET_assert, GNUNET_CONTAINER_multishortmap_destroy(), GNUNET_CONTAINER_multishortmap_size(), GNUNET_free, and GNUNET_SCHEDULER_cancel().

Referenced by database_shutdown(), database_shutdown(), libgnunet_plugin_datacache_postgres_done(), libgnunet_plugin_datastore_postgres_done(), namestore_postgres_create_tables(), and namestore_postgres_drop_tables().

Here is the call graph for this function:
Here is the caller graph for this function: