GNUnet  0.11.x
Functions
pq_connect.c File Reference

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

#include "platform.h"
#include "pq.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...
 
int 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...
 
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...
 
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

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

Referenced by GNUNET_PQ_reconnect().

40 {
41  /* do nothing, intentionally */
42  (void) arg;
43  (void) res;
44 }
static int res
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 55 of file pq_connect.c.

References GNUNET_ERROR_TYPE_INFO, and GNUNET_log_from.

Referenced by GNUNET_PQ_reconnect().

57 {
58  (void) arg;
60  "pq",
61  "%s",
62  message);
63 }
#define GNUNET_log_from(kind, comp,...)
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 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 89 of file pq_connect.c.

References GNUNET_PQ_Context::config_str, GNUNET_PQ_Context::conn, db, GNUNET_PQ_Context::es, GNUNET_free, GNUNET_free_non_null, GNUNET_new, GNUNET_new_array, GNUNET_PQ_reconnect(), GNUNET_strdup, GNUNET_PQ_Context::load_path, name, and GNUNET_PQ_Context::ps.

Referenced by GNUNET_PQ_connect_with_cfg().

93 {
94  struct GNUNET_PQ_Context *db;
95  unsigned int elen = 0;
96  unsigned int plen = 0;
97 
98  if (NULL != es)
99  while (NULL != es[elen].sql)
100  elen++;
101  if (NULL != ps)
102  while (NULL != ps[plen].name)
103  plen++;
104 
105  db = GNUNET_new (struct GNUNET_PQ_Context);
107  if (NULL != load_path)
109  if (0 != elen)
110  {
111  db->es = GNUNET_new_array (elen + 1,
113  memcpy (db->es,
114  es,
115  elen * sizeof (struct GNUNET_PQ_ExecuteStatement));
116  }
117  if (0 != plen)
118  {
119  db->ps = GNUNET_new_array (plen + 1,
121  memcpy (db->ps,
122  ps,
123  plen * sizeof (struct GNUNET_PQ_PreparedStatement));
124  }
125  GNUNET_PQ_reconnect (db);
126  if (NULL == db->conn)
127  {
129  GNUNET_free (db->config_str);
130  GNUNET_free (db);
131  return NULL;
132  }
133  return db;
134 }
void GNUNET_PQ_reconnect(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition: pq_connect.c:225
struct GNUNET_PQ_PreparedStatement * ps
Prepared statements.
Definition: pq.h:49
char * load_path
Path to load SQL files from.
Definition: pq.h:59
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().
struct GNUNET_PQ_ExecuteStatement * es
Statements to execute upon connection.
Definition: pq.h:44
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
PGconn * conn
Actual connection.
Definition: pq.h:39
char * config_str
Configuration to use to connect to the DB.
Definition: pq.h:54
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
static struct GNUNET_FS_DirectoryBuilder * db
Definition: gnunet-search.c:41
const char * name
Handle to Postgres database.
Definition: pq.h:34
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_run_sql()

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

References buf, GNUNET_PQ_Context::config_str, GNUNET_assert, GNUNET_DISK_file_test(), GNUNET_ERROR_TYPE_ERROR, 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_wait_status(), GNUNET_OS_start_process(), GNUNET_snprintf(), GNUNET_SYSERR, GNUNET_YES, GNUNET_PQ_Context::load_path, and type.

Referenced by GNUNET_PQ_reconnect().

149 {
150  size_t slen = strlen (db->load_path) + 10;
151 
152  for (unsigned int i = 0; i<10000; i++)
153  {
154  char buf[slen];
155  struct GNUNET_OS_Process *psql;
157  unsigned long code;
158 
159  GNUNET_snprintf (buf,
160  sizeof (buf),
161  "%s%04u.sql",
162  db->load_path,
163  i);
164  if (GNUNET_YES !=
165  GNUNET_DISK_file_test (buf))
166  break; /* We are done */
169  NULL,
170  NULL,
171  NULL,
172  "psql",
173  "psql",
174  db->config_str,
175  "-f",
176  buf,
177  "-q",
178  NULL);
179  if (NULL == psql)
180  {
182  "exec",
183  "psql");
184  return GNUNET_SYSERR;
185  }
188  &type,
189  &code));
191  if ( (GNUNET_OS_PROCESS_EXITED != type) ||
192  (0 != code) )
193  {
195  "Could not run PSQL on file %s: %d",
196  buf,
197  (int) code);
198  return GNUNET_SYSERR;
199  }
200  }
201  return GNUNET_OK;
202 }
int 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:544
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:287
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
char * load_path
Path to load SQL files from.
Definition: pq.h:59
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_OS_Process * GNUNET_OS_start_process(int pipe_control, 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:687
#define GNUNET_NO
Definition: gnunet_common.h:86
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
char * config_str
Configuration to use to connect to the DB.
Definition: pq.h:54
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
No standard streams should be inherited.
Definition: gnunet_os_lib.h:73
GNUNET_OS_ProcessStatusType
Process status types.
int 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:981
static char buf[2048]
The process exited with a return code.
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
#define GNUNET_log(kind,...)
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_YES
Definition: gnunet_common.h:85
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 211 of file pq_connect.c.

References GNUNET_PQ_Context::conn, and GNUNET_PQ_reconnect().

212 {
213  if (CONNECTION_BAD != PQstatus (db->conn))
214  return;
215  GNUNET_PQ_reconnect (db);
216 }
void GNUNET_PQ_reconnect(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition: pq_connect.c:225
PGconn * conn
Actual connection.
Definition: pq.h:39
Here is the call 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 225 of file pq_connect.c.

References GNUNET_PQ_Context::config_str, GNUNET_PQ_Context::conn, GNUNET_PQ_Context::es, GNUNET_ERROR_TYPE_ERROR, GNUNET_log_from, GNUNET_OK, GNUNET_PQ_exec_statements(), GNUNET_PQ_prepare_statements(), GNUNET_PQ_run_sql(), GNUNET_PQ_Context::load_path, pq_notice_processor_cb(), pq_notice_receiver_cb(), and GNUNET_PQ_Context::ps.

Referenced by GNUNET_PQ_connect(), GNUNET_PQ_eval_result(), GNUNET_PQ_exec_prepared(), and GNUNET_PQ_reconnect_if_down().

226 {
227  if (NULL != db->conn)
228  PQfinish (db->conn);
229  db->conn = PQconnectdb (db->config_str);
230  if ((NULL == db->conn) ||
231  (CONNECTION_OK != PQstatus (db->conn)))
232  {
234  "pq",
235  "Database connection to '%s' failed: %s\n",
236  db->config_str,
237  (NULL != db->conn) ?
238  PQerrorMessage (db->conn)
239  : "PQconnectdb returned NULL");
240  if (NULL != db->conn)
241  {
242  PQfinish (db->conn);
243  db->conn = NULL;
244  }
245  return;
246  }
247  PQsetNoticeReceiver (db->conn,
249  db);
250  PQsetNoticeProcessor (db->conn,
252  db);
253  if ( (NULL != db->load_path) &&
254  (GNUNET_OK !=
255  GNUNET_PQ_run_sql (db,
256  db->load_path)) )
257  {
258  PQfinish (db->conn);
259  db->conn = NULL;
260  return;
261  }
262  if ( (NULL != db->es) &&
263  (GNUNET_OK !=
265  db->es)) )
266  {
267  PQfinish (db->conn);
268  db->conn = NULL;
269  return;
270  }
271  if ( (NULL != db->ps) &&
272  (GNUNET_OK !=
274  db->ps)) )
275  {
276  PQfinish (db->conn);
277  db->conn = NULL;
278  return;
279  }
280 }
struct GNUNET_PQ_PreparedStatement * ps
Prepared statements.
Definition: pq.h:49
char * load_path
Path to load SQL files from.
Definition: pq.h:59
struct GNUNET_PQ_ExecuteStatement * es
Statements to execute upon connection.
Definition: pq.h:44
int 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:62
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
PGconn * conn
Actual connection.
Definition: pq.h:39
int 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:76
char * config_str
Configuration to use to connect to the DB.
Definition: pq.h:54
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:38
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:55
#define GNUNET_log_from(kind, comp,...)
int 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:147
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 301 of file pq_connect.c.

References db, GNUNET_asprintf(), GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_free_non_null, GNUNET_OK, GNUNET_PQ_connect(), and GNUNET_PQ_Context::load_path.

Referenced by database_setup(), and init_connection().

306 {
307  struct GNUNET_PQ_Context *db;
308  char *conninfo;
309  char *load_path;
310  char *sp;
311 
312  if (GNUNET_OK !=
314  section,
315  "CONFIG",
316  &conninfo))
317  conninfo = NULL;
318  load_path = NULL;
319  sp = NULL;
320  if (GNUNET_OK ==
322  section,
323  "SQL_DIR",
324  &sp))
325  GNUNET_asprintf (&load_path,
326  "%s%s",
327  sp,
328  load_path_suffix);
329  db = GNUNET_PQ_connect (conninfo == NULL ? "" : conninfo,
330  load_path,
331  es,
332  ps);
333  GNUNET_free_non_null (load_path);
335  GNUNET_free_non_null (conninfo);
336  return db;
337 }
char * load_path
Path to load SQL files from.
Definition: pq.h:59
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static char * section
Name of the section.
Definition: gnunet-config.c:33
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.
Definition: pq_connect.c:89
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
int 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.
static struct GNUNET_FS_DirectoryBuilder * db
Definition: gnunet-search.c:41
int 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.
Handle to Postgres database.
Definition: pq.h:34
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 347 of file pq_connect.c.

References GNUNET_PQ_Context::config_str, GNUNET_PQ_Context::conn, GNUNET_PQ_Context::es, GNUNET_free, GNUNET_free_non_null, GNUNET_PQ_Context::load_path, and GNUNET_PQ_Context::ps.

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

348 {
349  GNUNET_free_non_null (db->es);
350  GNUNET_free_non_null (db->ps);
353  PQfinish (db->conn);
354  GNUNET_free (db);
355 }
struct GNUNET_PQ_PreparedStatement * ps
Prepared statements.
Definition: pq.h:49
char * load_path
Path to load SQL files from.
Definition: pq.h:59
struct GNUNET_PQ_ExecuteStatement * es
Statements to execute upon connection.
Definition: pq.h:44
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
PGconn * conn
Actual connection.
Definition: pq.h:39
char * config_str
Configuration to use to connect to the DB.
Definition: pq.h:54
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function: