GNUnet  0.20.0
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 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_path)
 Within the db context, run all the SQL files from the load_path from 0000-9999.sql (as long as the files exist contiguously). 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

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

42 {
43  /* do nothing, intentionally */
44  (void) arg;
45  (void) res;
46 }
static int res

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

59 {
60  (void) arg;
62  "pq",
63  "%s",
64  message);
65 }
#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 69 of file pq_connect.c.

73 {
74  return GNUNET_PQ_connect2 (config_str,
75  load_path,
76  NULL == load_path
77  ? NULL
78  : "",
79  es,
80  ps,
82 }
@ 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:86

References GNUNET_PQ_Context::config_str, GNUNET_PQ_Context::es, GNUNET_PQ_connect2(), GNUNET_PQ_FLAG_NONE, GNUNET_PQ_Context::load_path, and GNUNET_PQ_Context::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 (consequtive).
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 86 of file pq_connect.c.

92 {
93  struct GNUNET_PQ_Context *db;
94  unsigned int elen = 0;
95  unsigned int plen = 0;
96 
97  if (NULL != es)
98  while (NULL != es[elen].sql)
99  elen++;
100  if (NULL != ps)
101  while (NULL != ps[plen].name)
102  plen++;
103 
104  db = GNUNET_new (struct GNUNET_PQ_Context);
105  db->flags = flags;
106  db->config_str = GNUNET_strdup (config_str);
107  if (NULL != load_path)
108  db->load_path = GNUNET_strdup (load_path);
109  if (NULL != auto_suffix)
110  db->auto_suffix = GNUNET_strdup (auto_suffix);
111  if (0 != elen)
112  {
113  db->es = GNUNET_new_array (elen + 1,
115  memcpy (db->es,
116  es,
117  elen * sizeof (struct GNUNET_PQ_ExecuteStatement));
118  }
119  if (0 != plen)
120  {
121  db->ps = GNUNET_new_array (plen + 1,
123  memcpy (db->ps,
124  ps,
125  plen * sizeof (struct GNUNET_PQ_PreparedStatement));
126  }
127  db->channel_map = GNUNET_CONTAINER_multishortmap_create (16,
128  GNUNET_YES);
130  if (NULL == db->conn)
131  {
133  GNUNET_free (db->load_path);
134  GNUNET_free (db->auto_suffix);
135  GNUNET_free (db->config_str);
136  GNUNET_free (db);
137  return NULL;
138  }
139  return db;
140 }
static struct GNUNET_FS_DirectoryBuilder * db
Definition: gnunet-search.c:97
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.
const char * name
void GNUNET_PQ_reconnect(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition: pq_connect.c:427
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
struct GNUNET_PQ_PreparedStatement * ps
Prepared statements.
Definition: pq.h:50
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 GNUNET_PQ_Context::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 86 of file pq_connect.c.

146 {
147  struct GNUNET_OS_Process *psql;
149  unsigned long code;
151  char *fn;
152 
153  GNUNET_asprintf (&fn,
154  "%s%s.sql",
155  db->load_path,
156  buf);
157  if (GNUNET_YES !=
159  {
161  "SQL resource `%s' does not exist\n",
162  fn);
163  GNUNET_free (fn);
164  return GNUNET_NO;
165  }
167  "Applying SQL file `%s' on database %s\n",
168  fn,
169  db->config_str);
171  NULL,
172  NULL,
173  NULL,
174  "psql",
175  "psql",
176  db->config_str,
177  "-f",
178  fn,
179  "-q",
180  "--set",
181  "ON_ERROR_STOP=1",
182  NULL);
183  if (NULL == psql)
184  {
186  "exec",
187  "psql");
188  GNUNET_free (fn);
189  return GNUNET_SYSERR;
190  }
192  &type,
193  &code);
194  if (GNUNET_OK != ret)
195  {
197  "psql on file %s did not finish, killed it!\n",
198  fn);
199  /* can happen if we got a signal, like CTRL-C, before
200  psql was complete */
201  (void) GNUNET_OS_process_kill (psql,
202  SIGKILL);
204  GNUNET_free (fn);
205  return GNUNET_SYSERR;
206  }
208  if ( (GNUNET_OS_PROCESS_EXITED != type) ||
209  (0 != code) )
210  {
212  "Could not run PSQL on file %s: psql exit code was %d\n",
213  fn,
214  (int) code);
215  GNUNET_free (fn);
216  return GNUNET_SYSERR;
217  }
218  GNUNET_free (fn);
219  return GNUNET_OK;
220 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static char buf[2048]
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
#define GNUNET_log(kind,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#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
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
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
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
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.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

Referenced by GNUNET_PQ_reconnect(), and libgnunet_plugin_datacache_postgres_done().

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_path 
)

Within the db context, run all the SQL files from the load_path from 0000-9999.sql (as long as the files exist contiguously).

Parameters
dbdatabase context to use
load_pathwhere to find the XXXX.sql files
Returns
GNUNET_OK on success

Definition at line 86 of file pq_connect.c.

226 {
227  const char *load_path_suffix;
228  size_t slen = strlen (load_path) + 10;
229 
230  load_path_suffix = strrchr (load_path, '/');
231  if (NULL == load_path_suffix)
232  load_path_suffix = load_path;
233  else
234  load_path_suffix++; /* skip '/' */
236  "Loading SQL resources from `%s'\n",
237  load_path);
238  for (unsigned int i = 1; i<10000; i++)
239  {
240  char patch_name[slen];
241  enum GNUNET_DB_QueryStatus qs;
242 
243  /* Check with DB versioning schema if this patch was already applied,
244  if so, skip it. */
245  GNUNET_snprintf (patch_name,
246  sizeof (patch_name),
247  "%s%04u",
248  load_path_suffix,
249  i);
250  {
251  char *applied_by;
252  struct GNUNET_PQ_QueryParam params[] = {
253  GNUNET_PQ_query_param_string (patch_name),
255  };
256  struct GNUNET_PQ_ResultSpec rs[] = {
257  GNUNET_PQ_result_spec_string ("applied_by",
258  &applied_by),
260  };
261 
263  "gnunet_pq_check_patch",
264  params,
265  rs);
267  {
269  "Database version %s already applied by %s, skipping\n",
270  patch_name,
271  applied_by);
273  }
274  if (GNUNET_DB_STATUS_HARD_ERROR == qs)
275  {
276  GNUNET_break (0);
277  return GNUNET_SYSERR;
278  }
279  }
281  continue; /* patch already applied, skip it */
282 
283  if (0 != (GNUNET_PQ_FLAG_CHECK_CURRENT & db->flags))
284  {
285  /* We are only checking, found unapplied patch, bad! */
287  "Database outdated, patch %s missing. Aborting!\n",
288  patch_name);
289  return GNUNET_SYSERR;
290  }
291  else
292  {
293  /* patch not yet applied, run it! */
295 
296  GNUNET_snprintf (patch_name,
297  sizeof (patch_name),
298  "%s%04u",
299  load_path,
300  i);
302  patch_name);
303  if (GNUNET_NO == ret)
304  break;
305  if (GNUNET_SYSERR == ret)
306  return GNUNET_SYSERR;
307  }
308  }
309  return GNUNET_OK;
310 }
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
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.
@ GNUNET_PQ_FLAG_CHECK_CURRENT
Check database version is current.
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:139
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_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.
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:144
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:83
Description of a DB result cell.

Referenced by GNUNET_PQ_reconnect().

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

315 {
316  if (1 ==
317  PQconsumeInput (db->conn))
318  return;
319  if (CONNECTION_BAD != PQstatus (db->conn))
320  return;
322 }

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

330 {
331  /* Check if the entry is in the cache already */
332  for (unsigned int i = 0; i < db->oids.num; i++)
333  {
334  /* Pointer comparison */
335  if (name == db->oids.table[i].name)
336  {
337  *oid = db->oids.table[i].oid;
338  return GNUNET_OK;
339  }
340  }
341 
342  /* No entry found in cache, ask database */
343  {
344  enum GNUNET_DB_QueryStatus qs;
345  struct GNUNET_PQ_QueryParam params[] = {
348  };
349  struct GNUNET_PQ_ResultSpec spec[] = {
351  oid),
353  };
354 
355  GNUNET_assert (NULL != db);
356 
358  "gnunet_pq_get_oid_by_name",
359  params,
360  spec);
362  return GNUNET_SYSERR;
363  }
364 
365  /* Add the entry to the cache */
366  if (NULL == db->oids.table)
367  {
368  db->oids.table = GNUNET_new_array (8,
369  typeof(*db->oids.table));
370  db->oids.cap = 8;
371  db->oids.num = 0;
372  }
373 
374  if (db->oids.cap <= db->oids.num)
375  GNUNET_array_grow (db->oids.table,
376  db->oids.cap,
377  db->oids.cap + 8);
378 
379  db->oids.table[db->oids.num].name = name;
380  db->oids.table[db->oids.num].oid = *oid;
381  db->oids.num++;
382 
383  return GNUNET_OK;
384 }
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_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.

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

397 {
398  static const char *typnames[] = {
399  "bool",
400  "int2",
401  "int4",
402  "int8",
403  "bytea",
404  "varchar"
405  };
406  Oid oid;
407 
408  for (size_t i = 0; i< sizeof(typnames) / sizeof(*typnames); i++)
409  {
410  if (GNUNET_OK !=
412  typnames[i],
413  &oid))
414  {
416  "pq",
417  "Couldn't retrieve OID for type %s\n",
418  typnames[i]);
419  return GNUNET_SYSERR;
420  }
421  }
422  return GNUNET_OK;
423 }
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:326

References db, and GNUNET_PQ_reconnect().

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

428 {
430  -1);
431  if (NULL != db->conn)
432  PQfinish (db->conn);
433  db->conn = PQconnectdb (db->config_str);
434  if ( (NULL == db->conn) ||
435  (CONNECTION_OK != PQstatus (db->conn)) )
436  {
438  "pq",
439  "Database connection to '%s' failed: %s\n",
440  db->config_str,
441  (NULL != db->conn)
442  ? PQerrorMessage (db->conn)
443  : "PQconnectdb returned NULL");
444  if (NULL != db->conn)
445  {
446  PQfinish (db->conn);
447  db->conn = NULL;
448  }
449  return;
450  }
451  PQsetNoticeReceiver (db->conn,
453  db);
454  PQsetNoticeProcessor (db->conn,
456  db);
457  if (NULL != db->load_path)
458  {
459  PGresult *res;
460  ExecStatusType est;
461 
462  res = PQexec (db->conn,
463  "SELECT"
464  " schema_name"
465  " FROM information_schema.schemata"
466  " WHERE schema_name='_v';");
467  est = PQresultStatus (res);
468  if ( (PGRES_COMMAND_OK != est) &&
469  (PGRES_TUPLES_OK != est) )
470  {
472  "Failed to run statement to check versioning schema. Bad!\n");
473  PQclear (res);
474  PQfinish (db->conn);
475  db->conn = NULL;
476  return;
477  }
478  if (0 == PQntuples (res))
479  {
481 
482  PQclear (res);
483  if (0 != (db->flags & GNUNET_PQ_FLAG_DROP))
484  {
486  "Versioning schema does not exist yet. Not attempting drop!\n");
487  PQfinish (db->conn);
488  db->conn = NULL;
489  return;
490  }
492  "versioning");
493  if (GNUNET_NO == ret)
494  {
496  "Failed to find SQL file to load database versioning logic\n");
497  PQfinish (db->conn);
498  db->conn = NULL;
499  return;
500  }
501  if (GNUNET_SYSERR == ret)
502  {
504  "Failed to run SQL logic to setup database versioning logic\n");
505  PQfinish (db->conn);
506  db->conn = NULL;
507  return;
508  }
509  }
510  else
511  {
512  PQclear (res);
513  }
514  }
515 
516  /* Prepare statement for OID lookup by name */
517  {
518  PGresult *res;
519 
520  res = PQprepare (db->conn,
521  "gnunet_pq_get_oid_by_name",
522  "SELECT"
523  " typname, oid"
524  " FROM pg_type"
525  " WHERE typname = $1"
526  " LIMIT 1",
527  1,
528  NULL);
529  if (PGRES_COMMAND_OK != PQresultStatus (res))
530  {
532  "Failed to run SQL statement prepare OID lookups: %s/%s\n",
533  PQresultErrorMessage (res),
534  PQerrorMessage (db->conn));
535  PQclear (res);
536  PQfinish (db->conn);
537  db->conn = NULL;
538  return;
539  }
540  PQclear (res);
541  }
542 
543  /* Reset the OID-cache and retrieve the OIDs for the supported Array types */
544  db->oids.num = 0;
546  {
548  "Failed to retrieve OID information for array types!\n");
549  PQfinish (db->conn);
550  db->conn = NULL;
551  return;
552  }
553 
554 
555  if (NULL != db->auto_suffix)
556  {
557  PGresult *res;
558 
559  GNUNET_assert (NULL != db->load_path);
560  res = PQprepare (db->conn,
561  "gnunet_pq_check_patch",
562  "SELECT"
563  " applied_by"
564  " FROM _v.patches"
565  " WHERE patch_name = $1"
566  " LIMIT 1",
567  1,
568  NULL);
569  if (PGRES_COMMAND_OK != PQresultStatus (res))
570  {
572  "Failed to run SQL logic to setup database versioning logic: %s/%s\n",
573  PQresultErrorMessage (res),
574  PQerrorMessage (db->conn));
575  PQclear (res);
576  PQfinish (db->conn);
577  db->conn = NULL;
578  return;
579  }
580  PQclear (res);
581 
582  if (GNUNET_SYSERR ==
584  db->auto_suffix))
585  {
587  "Failed to load SQL statements from `%s*'\n",
588  db->auto_suffix);
589  PQfinish (db->conn);
590  db->conn = NULL;
591  return;
592  }
593  }
594 
595  if ( (NULL != db->es) &&
596  (GNUNET_OK !=
598  db->es)) )
599  {
600  PQfinish (db->conn);
601  db->conn = NULL;
602  return;
603  }
604  if ( (NULL != db->ps) &&
605  (GNUNET_OK !=
607  db->ps)) )
608  {
609  PQfinish (db->conn);
610  db->conn = NULL;
611  return;
612  }
614  PQsocket (db->conn));
615 }
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
enum GNUNET_GenericReturnValue GNUNET_PQ_run_sql(struct GNUNET_PQ_Context *db, const char *load_path)
Within the db context, run all the SQL files from the load_path from 0000-9999.sql (as long as the fi...
Definition: pq_connect.c:224
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:40
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:57
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:396

References db, GNUNET_assert, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_from, GNUNET_NO, GNUNET_OK, GNUNET_PQ_event_reconnect_(), GNUNET_PQ_exec_sql(), GNUNET_PQ_exec_statements(), 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(), res, and ret.

Referenced by do_scheduler_notify(), GNUNET_PQ_connect2(), GNUNET_PQ_event_do_poll(), GNUNET_PQ_exec_prepared(), and load_initial_oids().

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

624 {
626  section,
627  load_path_suffix,
628  es,
629  ps,
631 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
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:635

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

Here is the call 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 635 of file pq_connect.c.

641 {
642  struct GNUNET_PQ_Context *db;
643  char *conninfo;
644  char *load_path;
645 
646  if (GNUNET_OK !=
648  section,
649  "CONFIG",
650  &conninfo))
651  conninfo = NULL;
652  load_path = NULL;
653  if (GNUNET_OK !=
655  section,
656  "SQL_DIR",
657  &load_path))
658  {
660  section,
661  "SQL_DIR");
662  }
663  if ( (NULL != load_path_suffix) &&
664  (NULL == load_path) )
665  {
667  section,
668  "SQL_DIR");
669  return NULL;
670  }
671  db = GNUNET_PQ_connect2 (conninfo == NULL ? "" : conninfo,
672  load_path,
673  load_path_suffix,
674  es,
675  ps,
676  flags);
678  GNUNET_free (conninfo);
679  return db;
680 }
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 GNUNET_PQ_Context::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 684 of file pq_connect.c.

685 {
686  if (NULL == db)
687  return;
688  GNUNET_assert (0 ==
689  GNUNET_CONTAINER_multishortmap_size (db->channel_map));
691  GNUNET_free (db->es);
692  GNUNET_free (db->ps);
693  GNUNET_free (db->load_path);
694  GNUNET_free (db->auto_suffix);
695  GNUNET_free (db->config_str);
696  GNUNET_free (db->oids.table);
697  db->oids.table = NULL;
698  db->oids.num = 0;
699  db->oids.cap = 0;
700  PQfinish (db->conn);
701  GNUNET_free (db);
702 }
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(), and libgnunet_plugin_datastore_postgres_done().

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