GNUnet 0.21.1
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 char * res
Currently read line or NULL on EOF.

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

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 (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
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 char * name
Name (label) of the records to list.
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.
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
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 144 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
Final status code.
Definition: gnunet-arm.c:94
static uint32_t type
Type string converted to DNS type value.
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.
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:626
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:868
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(), 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_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_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 224 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 }
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.

References db, GNUNET_break, GNUNET_DB_STATUS_HARD_ERROR, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_PQ_cleanup_result(), GNUNET_PQ_eval_prepared_singleton_select(), GNUNET_PQ_exec_sql(), GNUNET_PQ_FLAG_CHECK_CURRENT, 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 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 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}

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 326 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.

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 396 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, 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 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 (NULL != db->auto_suffix) )
459 {
460 PGresult *res;
461 ExecStatusType est;
462
463 res = PQexec (db->conn,
464 "SELECT"
465 " schema_name"
466 " FROM information_schema.schemata"
467 " WHERE schema_name='_v';");
468 est = PQresultStatus (res);
469 if ( (PGRES_COMMAND_OK != est) &&
470 (PGRES_TUPLES_OK != est) )
471 {
473 "Failed to run statement to check versioning schema. Bad!\n");
474 PQclear (res);
475 PQfinish (db->conn);
476 db->conn = NULL;
477 return;
478 }
479 if (0 == PQntuples (res))
480 {
482
483 PQclear (res);
484 if (0 != (db->flags & GNUNET_PQ_FLAG_DROP))
485 {
487 "Versioning schema does not exist yet. Not attempting drop!\n");
488 PQfinish (db->conn);
489 db->conn = NULL;
490 return;
491 }
493 "versioning");
494 if (GNUNET_NO == ret)
495 {
497 "Failed to find SQL file to load database versioning logic\n");
498 PQfinish (db->conn);
499 db->conn = NULL;
500 return;
501 }
502 if (GNUNET_SYSERR == ret)
503 {
505 "Failed to run SQL logic to setup database versioning logic\n");
506 PQfinish (db->conn);
507 db->conn = NULL;
508 return;
509 }
510 }
511 else
512 {
513 PQclear (res);
514 }
515 }
516
517 /* Prepare statement for OID lookup by name */
518 {
519 PGresult *res;
520
521 res = PQprepare (db->conn,
522 "gnunet_pq_get_oid_by_name",
523 "SELECT"
524 " typname, oid"
525 " FROM pg_type"
526 " WHERE typname = $1"
527 " LIMIT 1",
528 1,
529 NULL);
530 if (PGRES_COMMAND_OK != PQresultStatus (res))
531 {
533 "Failed to run SQL statement prepare OID lookups: %s/%s\n",
534 PQresultErrorMessage (res),
535 PQerrorMessage (db->conn));
536 PQclear (res);
537 PQfinish (db->conn);
538 db->conn = NULL;
539 return;
540 }
541 PQclear (res);
542 }
543
544 /* Reset the OID-cache and retrieve the OIDs for the supported Array types */
545 db->oids.num = 0;
547 {
549 "Failed to retrieve OID information for array types!\n");
550 PQfinish (db->conn);
551 db->conn = NULL;
552 return;
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_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 619 of file pq_connect.c.

624{
626 section,
627 load_path_suffix,
628 es,
629 ps,
631}
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
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 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 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 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 ==
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(), 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: