GNUnet 0.22.2
pq_connect.c File Reference

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

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

Go to the source code of this file.

Functions

static void reset_connection (struct GNUNET_PQ_Context *db)
 Close connection to db and mark it as uninitialized. More...
 
static enum GNUNET_GenericReturnValue prepare_check_patch (struct GNUNET_PQ_Context *db)
 Prepare the "gnunet_pq_check_patch" statement. More...
 
static enum GNUNET_GenericReturnValue prepare_get_oid_by_name (struct GNUNET_PQ_Context *db)
 Prepare the "gnunet_pq_get_oid_by_name" statement. More...
 
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. More...
 
static void pq_notice_receiver_cb (void *arg, const PGresult *res)
 Function called by libpq whenever it wants to log something. More...
 
static void pq_notice_processor_cb (void *arg, const char *message)
 Function called by libpq whenever it wants to log something. More...
 
struct GNUNET_PQ_ContextGNUNET_PQ_connect (const char *config_str, const char *load_path, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps)
 Create a connection to the Postgres database using config_str for the configuration. More...
 
struct GNUNET_PQ_ContextGNUNET_PQ_connect2 (const char *config_str, const char *load_path, const char *auto_suffix, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps, enum GNUNET_PQ_Options flags)
 Create a connection to the Postgres database using config_str for the configuration. More...
 
enum GNUNET_GenericReturnValue GNUNET_PQ_exec_sql (struct GNUNET_PQ_Context *db, const char *buf)
 Execute SQL statements from buf against db. More...
 
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". More...
 
void GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
 Reinitialize the database db if the connection is down. More...
 
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. More...
 
static enum GNUNET_GenericReturnValue load_initial_oids (struct GNUNET_PQ_Context *db)
 Load the initial set of OIDs for the supported array-datatypes. More...
 
void GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
 Reinitialize the database db. More...
 
struct GNUNET_PQ_ContextGNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *load_path_suffix, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps)
 Connect to a postgres database using the configuration option "CONFIG" in section. More...
 
struct GNUNET_PQ_ContextGNUNET_PQ_connect_with_cfg2 (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *load_path_suffix, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps, enum GNUNET_PQ_Options flags)
 Connect to a postgres database using the configuration option "CONFIG" in section. More...
 
void GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db)
 Disconnect from the database, destroying the prepared statements and releasing other associated resources. More...
 

Detailed Description

functions to connect to libpq (PostGres)

Author
Christian Grothoff
Özgür Kesim

Definition in 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 37 of file pq_connect.c.

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}
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 56 of file pq_connect.c.

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}
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:37

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

Referenced by check_patch_applied(), and GNUNET_PQ_reconnect().

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 96 of file pq_connect.c.

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"
105 " typname, oid"
106 " FROM pg_type"
107 " WHERE typname = $1"
108 " LIMIT 1",
109 1,
110 NULL);
111 if (PGRES_COMMAND_OK != PQresultStatus (res))
112 {
114 "Failed to run SQL statement prepare OID lookups: %s/%s\n",
115 PQresultErrorMessage (res),
116 PQerrorMessage (db->conn));
117 PQclear (res);
119 return GNUNET_SYSERR;
120 }
121 PQclear (res);
122 db->prepared_get_oid_by_name = true;
123 return GNUNET_OK;
124}

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_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 139 of file pq_connect.c.

142{
143 const char *load_path_suffix;
144 size_t slen = strlen (load_path) + 10;
145 char patch_name[slen];
146
147 load_path_suffix = strrchr (load_path,
148 '/');
149 if (NULL == load_path_suffix)
150 load_path_suffix = load_path;
151 else
152 load_path_suffix++; /* skip '/' */
153 GNUNET_snprintf (patch_name,
154 sizeof (patch_name),
155 "%s%04u",
156 load_path_suffix,
157 patch_number);
158 {
159 struct GNUNET_PQ_QueryParam params[] = {
160 GNUNET_PQ_query_param_string (patch_name),
162 };
163 char *applied_by;
164 struct GNUNET_PQ_ResultSpec rs[] = {
165 GNUNET_PQ_result_spec_string ("applied_by",
166 &applied_by),
168 };
169 enum GNUNET_DB_QueryStatus qs;
170
171 if (GNUNET_OK !=
173 {
174 GNUNET_break (0);
175 return GNUNET_SYSERR;
176 }
178 "gnunet_pq_check_patch",
179 params,
180 rs);
181 switch (qs)
182 {
185 "Database version %s already applied by %s\n",
186 patch_name,
187 applied_by);
189 return GNUNET_OK;
191 return GNUNET_NO;
193 GNUNET_break (0);
194 return GNUNET_SYSERR;
196 GNUNET_break (0);
197 return GNUNET_SYSERR;
198 }
199 GNUNET_assert (0);
200 return GNUNET_SYSERR;
201 }
202}
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:37
@ GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
The transaction succeeded, and yielded one result.
Definition: gnunet_db_lib.h:60
@ GNUNET_DB_STATUS_HARD_ERROR
A hard error occurred, retrying will not help.
Definition: gnunet_db_lib.h:41
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:55
@ GNUNET_DB_STATUS_SOFT_ERROR
A soft error occurred, retrying the transaction may succeed.
Definition: gnunet_db_lib.h:47
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:142
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.
@ GNUNET_NO
#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:56
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:83
Description of a DB result cell.

References 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_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 214 of file pq_connect.c.

216{
217 /* do nothing, intentionally */
218 (void) arg;
219 (void) res;
220}

References find_typedefs::arg, and 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 231 of file pq_connect.c.

233{
234 (void) arg;
236 "pq",
237 "%s",
238 message);
239}
#define GNUNET_log_from(kind, comp,...)
@ GNUNET_ERROR_TYPE_INFO

References find_typedefs::arg, GNUNET_ERROR_TYPE_INFO, and GNUNET_log_from.

Referenced by GNUNET_PQ_reconnect().

Here is the caller graph for this function:

◆ GNUNET_PQ_connect()

struct GNUNET_PQ_Context * GNUNET_PQ_connect ( const char *  config_str,
const char *  load_path,
const struct GNUNET_PQ_ExecuteStatement es,
const struct GNUNET_PQ_PreparedStatement ps 
)

Create a connection to the Postgres database using config_str for the configuration.

Initialize logging via GNUnet's log routines and disable Postgres's logger. Also ensures that the statements in load_path and es are executed whenever we (re)connect to the database, and that the prepared statements in ps are "ready". If statements in es fail that were created with GNUNET_PQ_make_execute(), then the entire operation fails.

In load_path, a list of "$XXXX.sql" files is expected where $XXXX must be a sequence of contiguous integer values starting at 0000. These files are then loaded in sequence using "psql $config_str" before running statements from es. The directory is inspected again on reconnect.

Parameters
config_strconfiguration to use
load_pathpath to directory with SQL transactions to run, can be NULL
esGNUNET_PQ_PREPARED_STATEMENT_END-terminated array of statements to execute upon EACH connection, can be NULL
psarray of prepared statements to prepare, can be NULL
Returns
NULL on error

Definition at line 243 of file pq_connect.c.

247{
248 return GNUNET_PQ_connect2 (config_str,
249 load_path,
250 NULL == load_path
251 ? NULL
252 : "",
253 es,
254 ps,
256}
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
@ GNUNET_PQ_FLAG_NONE
Traditional default.
struct GNUNET_PQ_Context * GNUNET_PQ_connect2(const char *config_str, const char *load_path, const char *auto_suffix, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps, enum GNUNET_PQ_Options flags)
Create a connection to the Postgres database using config_str for the configuration.
Definition: pq_connect.c:260

References GNUNET_PQ_Context::config_str, GNUNET_PQ_Context::es, GNUNET_PQ_connect2(), GNUNET_PQ_FLAG_NONE, GNUNET_PQ_Context::load_path, and ps.

Here is the call graph for this function:

◆ GNUNET_PQ_connect2()

struct GNUNET_PQ_Context * GNUNET_PQ_connect2 ( const char *  config_str,
const char *  load_path,
const char *  auto_suffix,
const struct GNUNET_PQ_ExecuteStatement es,
const struct GNUNET_PQ_PreparedStatement ps,
enum GNUNET_PQ_Options  flags 
)

Create a connection to the Postgres database using config_str for the configuration.

Initialize logging via GNUnet's log routines and disable Postgres's logger. Also ensures that the statements in load_path and es are executed whenever we (re)connect to the database, and that the prepared statements in ps are "ready". If statements in es fail that were created with GNUNET_PQ_make_execute(), then the entire operation fails.

In load_path, a list of "$XXXX.sql" files is expected where $XXXX must be a sequence of contiguous integer values starting at 0000. These files are then loaded in sequence using "psql $config_str" before running statements from es. The directory is inspected again on reconnect.

Parameters
config_strconfiguration to use
load_pathpath to directory with SQL transactions to run, can be NULL
auto_suffixinfix of SQL series to run on every reconnect; runs multiple (!) files, of the form auto_suffix-XXXX where XXXX is from 0 to 9999 (consecutive).
esGNUNET_PQ_PREPARED_STATEMENT_END-terminated array of statements to execute upon EACH connection, can be NULL
psarray of prepared statements to prepare, can be NULL
flagsconnection flags
Returns
NULL on error

Definition at line 260 of file pq_connect.c.

266{
267 struct GNUNET_PQ_Context *db;
268 unsigned int elen = 0;
269 unsigned int plen = 0;
270
271 if (NULL != es)
272 while (NULL != es[elen].sql)
273 elen++;
274 if (NULL != ps)
275 while (NULL != ps[plen].name)
276 plen++;
277
279 db->flags = flags;
280 db->config_str = GNUNET_strdup (config_str);
281 if (NULL != load_path)
282 db->load_path = GNUNET_strdup (load_path);
283 if (NULL != auto_suffix)
284 db->auto_suffix = GNUNET_strdup (auto_suffix);
285 if (0 != elen)
286 {
287 db->es = GNUNET_new_array (elen + 1,
289 memcpy (db->es,
290 es,
291 elen * sizeof (struct GNUNET_PQ_ExecuteStatement));
292 }
293 if (0 != plen)
294 {
295 db->ps = GNUNET_new_array (plen + 1,
297 memcpy (db->ps,
298 ps,
299 plen * sizeof (struct GNUNET_PQ_PreparedStatement));
300 }
301 db->channel_map = GNUNET_CONTAINER_multishortmap_create (16,
302 GNUNET_YES);
304 if (NULL == db->conn)
305 {
307 GNUNET_free (db->load_path);
308 GNUNET_free (db->auto_suffix);
309 GNUNET_free (db->config_str);
310 GNUNET_free (db);
311 return NULL;
312 }
313 return db;
314}
static char * name
Name (label) of the records to list.
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.
@ GNUNET_YES
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#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.
void GNUNET_PQ_reconnect(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition: pq_connect.c:562
Handle to Postgres database.
Definition: pq.h:36
struct GNUNET_PQ_ExecuteStatement * es
Statements to execute upon connection.
Definition: pq.h:45
enum GNUNET_PQ_Options flags
Flags controlling the connection.
Definition: pq.h:100
char * load_path
Path to load SQL files from.
Definition: pq.h:70
char * config_str
Configuration to use to connect to the DB.
Definition: pq.h:65
char * auto_suffix
Suffix to append to path to load on startup.
Definition: pq.h:75
Information needed to run a list of SQL statements using GNUNET_PQ_exec_statements().
Information needed to prepare a list of SQL statements using GNUNET_PQ_prepare_statements().

References GNUNET_PQ_Context::auto_suffix, GNUNET_PQ_Context::config_str, db, GNUNET_PQ_Context::es, GNUNET_PQ_Context::flags, GNUNET_CONTAINER_multishortmap_create(), GNUNET_CONTAINER_multishortmap_destroy(), GNUNET_free, GNUNET_new, GNUNET_new_array, GNUNET_PQ_reconnect(), GNUNET_strdup, GNUNET_YES, GNUNET_PQ_Context::load_path, name, and ps.

Referenced by GNUNET_PQ_connect(), and GNUNET_PQ_connect_with_cfg2().

Here is the call graph for this function:
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
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 318 of file pq_connect.c.

320{
321 struct GNUNET_OS_Process *psql;
323 unsigned long code;
325 char *fn;
326
327 GNUNET_asprintf (&fn,
328 "%s%s.sql",
329 db->load_path,
330 buf);
331 if (GNUNET_YES !=
333 {
335 "SQL resource `%s' does not exist\n",
336 fn);
337 GNUNET_free (fn);
338 return GNUNET_NO;
339 }
340 if (0 != (GNUNET_PQ_FLAG_CHECK_CURRENT & db->flags))
341 return GNUNET_SYSERR;
343 "Applying SQL file `%s' on database %s\n",
344 fn,
345 db->config_str);
347 NULL,
348 NULL,
349 NULL,
350 "psql",
351 "psql",
352 db->config_str,
353 "-f",
354 fn,
355 "-q",
356 "--set",
357 "ON_ERROR_STOP=1",
358 NULL);
359 if (NULL == psql)
360 {
362 "exec",
363 "psql");
364 GNUNET_free (fn);
365 return GNUNET_SYSERR;
366 }
368 &type,
369 &code);
370 if (GNUNET_OK != ret)
371 {
373 "psql on file %s did not finish, killed it!\n",
374 fn);
375 /* can happen if we got a signal, like CTRL-C, before
376 psql was complete */
377 (void) GNUNET_OS_process_kill (psql,
378 SIGKILL);
380 GNUNET_free (fn);
381 return GNUNET_SYSERR;
382 }
384 if ( (GNUNET_OS_PROCESS_EXITED != type) ||
385 (0 != code) )
386 {
388 "Could not run PSQL on file %s: psql exit code was %d\n",
389 fn,
390 (int) code);
391 GNUNET_free (fn);
392 return GNUNET_SYSERR;
393 }
394 GNUNET_free (fn);
395 return GNUNET_OK;
396}
static int ret
Final status code.
Definition: gnunet-arm.c:93
static uint32_t type
Type string converted to DNS type value.
@ GNUNET_PQ_FLAG_CHECK_CURRENT
Check database version is current.
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:527
GNUNET_GenericReturnValue
Named constants for return values.
#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
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
struct GNUNET_OS_Process * GNUNET_OS_start_process(enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename,...)
Start a process.
Definition: os_priority.c:620
enum GNUNET_GenericReturnValue GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Retrieve the status of a process, waiting on it if dead.
Definition: os_priority.c:862
GNUNET_OS_ProcessStatusType
Process status types.
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:260
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:210
@ GNUNET_OS_INHERIT_STD_NONE
No standard streams should be inherited.
Definition: gnunet_os_lib.h:77
@ GNUNET_OS_PROCESS_EXITED
The process exited with a return code.

References db, GNUNET_asprintf(), GNUNET_DISK_file_test_read(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_log_strerror_file, GNUNET_NO, GNUNET_OK, GNUNET_OS_INHERIT_STD_NONE, GNUNET_OS_process_destroy(), GNUNET_OS_PROCESS_EXITED, GNUNET_OS_process_kill(), GNUNET_OS_process_wait_status(), GNUNET_OS_start_process(), GNUNET_PQ_FLAG_CHECK_CURRENT, GNUNET_SYSERR, GNUNET_YES, ret, and type.

Referenced by GNUNET_PQ_reconnect(), 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_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".

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

Definition at line 400 of file pq_connect.c.

402{
403 size_t slen = strlen (load_suffix) + 10;
404 char patch_name[slen];
405
407 "Loading SQL resources from `%s'\n",
408 load_suffix);
409 for (unsigned int i = 1; i<10000; i++)
410 {
412
414 load_suffix,
415 i);
416 if (GNUNET_SYSERR == ret)
417 {
418 GNUNET_break (0);
419 return GNUNET_SYSERR;
420 }
421 if (GNUNET_OK == ret)
422 continue; /* patch already applied, skip it */
423
424 GNUNET_snprintf (patch_name,
425 sizeof (patch_name),
426 "%s%04u",
427 load_suffix,
428 i);
430 patch_name);
431 if (GNUNET_NO == ret)
432 break;
433 if ( (GNUNET_SYSERR == ret) &&
434 (0 != (GNUNET_PQ_FLAG_CHECK_CURRENT & db->flags)) )
435 {
436 /* We are only checking, found unapplied patch, bad! */
438 "Database outdated, patch %s missing. Aborting!\n",
439 patch_name);
440 }
441 if (GNUNET_SYSERR == ret)
442 return GNUNET_SYSERR;
443 }
444 return GNUNET_OK;
445}
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:139
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:318

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

Referenced by GNUNET_PQ_reconnect().

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
dbdatabase connection to reinitialize

Definition at line 449 of file pq_connect.c.

450{
451 if (1 ==
452 PQconsumeInput (db->conn))
453 return;
454 if (CONNECTION_BAD != PQstatus (db->conn))
455 return;
457}

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 461 of file pq_connect.c.

465{
466 /* Check if the entry is in the cache already */
467 for (unsigned int i = 0; i < db->oids.num; i++)
468 {
469 /* Pointer comparison */
470 if (name == db->oids.table[i].name)
471 {
472 *oid = db->oids.table[i].oid;
473 return GNUNET_OK;
474 }
475 }
476
477 /* No entry found in cache, ask database */
478 {
479 enum GNUNET_DB_QueryStatus qs;
480 struct GNUNET_PQ_QueryParam params[] = {
483 };
484 struct GNUNET_PQ_ResultSpec spec[] = {
486 oid),
488 };
489
490 GNUNET_assert (NULL != db);
491
493 "gnunet_pq_get_oid_by_name",
494 params,
495 spec);
497 return GNUNET_SYSERR;
498 }
499
500 /* Add the entry to the cache */
501 if (NULL == db->oids.table)
502 {
503 db->oids.table = GNUNET_new_array (8,
504 typeof(*db->oids.table));
505 db->oids.cap = 8;
506 db->oids.num = 0;
507 }
508
509 if (db->oids.cap <= db->oids.num)
510 GNUNET_array_grow (db->oids.table,
511 db->oids.cap,
512 db->oids.cap + 8);
513
514 db->oids.table[db->oids.num].name = name;
515 db->oids.table[db->oids.num].oid = *oid;
516 db->oids.num++;
517
518 return GNUNET_OK;
519}
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32(const char *name, uint32_t *u32)
uint32_t expected.
uint32_t oid
Definition: gnunet_pq_lib.h:2
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.

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_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_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 531 of file pq_connect.c.

532{
533 static const char *typnames[] = {
534 "bool",
535 "int2",
536 "int4",
537 "int8",
538 "bytea",
539 "varchar"
540 };
541 Oid oid;
542
543 for (size_t i = 0; i< sizeof(typnames) / sizeof(*typnames); i++)
544 {
545 if (GNUNET_OK !=
547 typnames[i],
548 &oid))
549 {
551 "pq",
552 "Couldn't retrieve OID for type %s\n",
553 typnames[i]);
554 return GNUNET_SYSERR;
555 }
556 }
557 return GNUNET_OK;
558}
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:461

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

Definition at line 562 of file pq_connect.c.

563{
565 -1);
567 db->conn = PQconnectdb (db->config_str);
568 if ( (NULL == db->conn) ||
569 (CONNECTION_OK != PQstatus (db->conn)) )
570 {
572 "pq",
573 "Database connection to '%s' failed: %s\n",
574 db->config_str,
575 (NULL != db->conn)
576 ? PQerrorMessage (db->conn)
577 : "PQconnectdb returned NULL");
579 return;
580 }
581 PQsetNoticeReceiver (db->conn,
583 db);
584 PQsetNoticeProcessor (db->conn,
586 db);
587 if ( (NULL != db->load_path) &&
588 (NULL != db->auto_suffix) )
589 {
590 PGresult *res;
591 ExecStatusType est;
592
593 res = PQexec (db->conn,
594 "SELECT"
595 " schema_name"
596 " FROM information_schema.schemata"
597 " WHERE schema_name='_v';");
598 est = PQresultStatus (res);
599 if ( (PGRES_COMMAND_OK != est) &&
600 (PGRES_TUPLES_OK != est) )
601 {
603 "Failed to run statement to check versioning schema. Bad!\n");
604 PQclear (res);
606 return;
607 }
608 if (0 == PQntuples (res))
609 {
611
612 PQclear (res);
613 if (0 != (db->flags & GNUNET_PQ_FLAG_DROP))
614 {
616 "Versioning schema does not exist yet. Not attempting drop!\n");
618 return;
619 }
621 "versioning");
622 if (GNUNET_NO == ret)
623 {
625 "Failed to find SQL file to load database versioning logic\n");
627 return;
628 }
629 if (GNUNET_SYSERR == ret)
630 {
632 "Failed to run SQL logic to setup database versioning logic\n");
634 return;
635 }
636 }
637 else
638 {
639 PQclear (res);
640 }
641 }
642
643 /* Prepare statement for OID lookup by name */
644 if (GNUNET_OK !=
646 return;
647
648 /* Reset the OID-cache and retrieve the OIDs for the supported Array types */
649 db->oids.num = 0;
651 {
653 "Failed to retrieve OID information for array types!\n");
655 return;
656 }
657
658 if (NULL != db->auto_suffix)
659 {
660 GNUNET_assert (NULL != db->load_path);
661 if (GNUNET_OK !=
663 return;
664
665 if (GNUNET_SYSERR ==
667 db->auto_suffix))
668 {
669 if (0 == (GNUNET_PQ_FLAG_CHECK_CURRENT & db->flags))
671 "Failed to load SQL statements from `%s*'\n",
672 db->auto_suffix);
674 return;
675 }
676 }
677
678 if ( (NULL != db->es) &&
679 (GNUNET_OK !=
681 db->es)) )
682 {
684 return;
685 }
686 if ( (NULL != db->ps) &&
687 (GNUNET_OK !=
689 db->ps)) )
690 {
692 return;
693 }
695 PQsocket (db->conn));
696}
enum GNUNET_GenericReturnValue GNUNET_PQ_exec_statements(struct GNUNET_PQ_Context *db, const struct GNUNET_PQ_ExecuteStatement *es)
Request execution of an array of statements es from Postgres.
Definition: pq_exec.c:54
enum GNUNET_GenericReturnValue GNUNET_PQ_prepare_statements(struct GNUNET_PQ_Context *db, const struct GNUNET_PQ_PreparedStatement *ps)
Request creation of prepared statements ps from Postgres.
Definition: pq_prepare.c:88
@ GNUNET_PQ_FLAG_DROP
Dropping database.
void GNUNET_PQ_event_reconnect_(struct GNUNET_PQ_Context *db, int fd)
Internal API.
Definition: pq_event.c:412
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:214
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
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:231
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:531
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:400

References db, GNUNET_assert, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_log_from, GNUNET_NO, GNUNET_OK, GNUNET_PQ_event_reconnect_(), GNUNET_PQ_exec_sql(), GNUNET_PQ_exec_statements(), GNUNET_PQ_FLAG_CHECK_CURRENT, GNUNET_PQ_FLAG_DROP, GNUNET_PQ_prepare_statements(), GNUNET_PQ_run_sql(), GNUNET_SYSERR, load_initial_oids(), pq_notice_processor_cb(), pq_notice_receiver_cb(), prepare_check_patch(), prepare_get_oid_by_name(), res, reset_connection(), and ret.

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

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

◆ GNUNET_PQ_connect_with_cfg()

struct GNUNET_PQ_Context * GNUNET_PQ_connect_with_cfg ( const struct GNUNET_CONFIGURATION_Handle cfg,
const char *  section,
const char *  load_path_suffix,
const struct GNUNET_PQ_ExecuteStatement es,
const struct GNUNET_PQ_PreparedStatement ps 
)

Connect to a postgres database using the configuration option "CONFIG" in section.

Also ensures that the statements in es are executed whenever we (re)connect to the database, and that the prepared statements in ps are "ready".

The caller does not have to ensure that es and ps remain allocated and initialized in memory until GNUNET_PQ_disconnect() is called, as a copy will be made.

Parameters
cfgconfiguration
sectionconfiguration section to use to get Postgres configuration options
load_path_suffixsuffix to append to the SQL_DIR in the configuration
esGNUNET_PQ_PREPARED_STATEMENT_END-terminated array of statements to execute upon EACH connection, can be NULL
psarray of prepared statements to prepare, can be NULL
Returns
the postgres handle, NULL on error

Definition at line 700 of file pq_connect.c.

705{
707 section,
708 load_path_suffix,
709 es,
710 ps,
712}
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
struct GNUNET_PQ_Context * GNUNET_PQ_connect_with_cfg2(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *load_path_suffix, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps, enum GNUNET_PQ_Options flags)
Connect to a postgres database using the configuration option "CONFIG" in section.
Definition: pq_connect.c:716

References cfg, GNUNET_PQ_Context::es, GNUNET_PQ_connect_with_cfg2(), GNUNET_PQ_FLAG_NONE, and ps.

Referenced by database_connect(), database_setup(), init_connection(), 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:

◆ GNUNET_PQ_connect_with_cfg2()

struct GNUNET_PQ_Context * GNUNET_PQ_connect_with_cfg2 ( const struct GNUNET_CONFIGURATION_Handle cfg,
const char *  section,
const char *  load_path_suffix,
const struct GNUNET_PQ_ExecuteStatement es,
const struct GNUNET_PQ_PreparedStatement ps,
enum GNUNET_PQ_Options  flags 
)

Connect to a postgres database using the configuration option "CONFIG" in section.

Also ensures that the statements in es are executed whenever we (re)connect to the database, and that the prepared statements in ps are "ready".

The caller does not have to ensure that es and ps remain allocated and initialized in memory until GNUNET_PQ_disconnect() is called, as a copy will be made.

Parameters
cfgconfiguration
sectionconfiguration section to use to get Postgres configuration options
load_path_suffixsuffix to append to the SQL_DIR in the configuration
esGNUNET_PQ_PREPARED_STATEMENT_END-terminated array of statements to execute upon EACH connection, can be NULL
psarray of prepared statements to prepare, can be NULL
flagsconnection flags
Returns
the postgres handle, NULL on error

Definition at line 716 of file pq_connect.c.

722{
723 struct GNUNET_PQ_Context *db;
724 char *conninfo;
725 char *load_path;
726
727 if (GNUNET_OK !=
729 section,
730 "CONFIG",
731 &conninfo))
732 conninfo = NULL;
733 load_path = NULL;
734 if (GNUNET_OK !=
736 section,
737 "SQL_DIR",
738 &load_path))
739 {
741 section,
742 "SQL_DIR");
743 }
744 if ( (NULL != load_path_suffix) &&
745 (NULL == load_path) )
746 {
748 section,
749 "SQL_DIR");
750 return NULL;
751 }
752 db = GNUNET_PQ_connect2 (conninfo == NULL ? "" : conninfo,
753 load_path,
754 load_path_suffix,
755 es,
756 ps,
757 flags);
759 GNUNET_free (conninfo);
760 return db;
761}
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.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.

References cfg, db, GNUNET_PQ_Context::es, GNUNET_PQ_Context::flags, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log_config_missing(), GNUNET_OK, GNUNET_PQ_connect2(), GNUNET_PQ_Context::load_path, and ps.

Referenced by GNUNET_PQ_connect_with_cfg().

Here is the call graph for this function:
Here is the caller 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 765 of file pq_connect.c.

766{
767 if (NULL == db)
768 return;
769 GNUNET_assert (0 ==
772 GNUNET_free (db->es);
773 GNUNET_free (db->ps);
774 GNUNET_free (db->load_path);
775 GNUNET_free (db->auto_suffix);
776 GNUNET_free (db->config_str);
777 GNUNET_free (db->oids.table);
778 db->oids.table = NULL;
779 db->oids.num = 0;
780 db->oids.cap = 0;
781 PQfinish (db->conn);
782 GNUNET_free (db);
783}
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.

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

Referenced by 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: