GNUnet 0.28.0-dev.3-19-gec988fcc8
 
Loading...
Searching...
No Matches
plugin_datastore_postgres.c File Reference

postgres-based datastore backend More...

#include "platform.h"
#include "gnunet_datastore_plugin.h"
#include "gnunet_pq_lib.h"
Include dependency graph for plugin_datastore_postgres.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
 
struct  ProcessResultContext
 Closure for process_result. More...
 
struct  ReplCtx
 Context for #repl_iter() function. More...
 
struct  ProcessKeysContext
 Closure for process_keys. More...
 

Macros

#define BUSY_TIMEOUT   GNUNET_TIME_UNIT_SECONDS
 After how many ms "busy" should a DB operation fail for good? A low value makes sure that we are more responsive to requests (especially PUTs).
 
#define RESULT_COLUMNS   "repl, type, prio, anonLevel, expire, hash, value, oid"
 

Functions

static void reconnect_setup (void *cls, struct GNUNET_PQ_Context *pq)
 Function called whenever we reconnect to the DB.
 
static enum GNUNET_GenericReturnValue init_connection (struct Plugin *plugin)
 Get a database handle.
 
static void postgres_plugin_estimate_size (void *cls, unsigned long long *estimate)
 Get an estimate of how much space the database is currently using.
 
static void postgres_plugin_put (void *cls, const struct GNUNET_HashCode *key, bool absent, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, PluginPutCont cont, void *cont_cls)
 Store an item in the datastore.
 
static void process_result (void *cls, PGresult *res, unsigned int num_results)
 Function invoked to process the result and call the processor of cls.
 
static void postgres_plugin_get_key (void *cls, uint64_t next_uid, bool random, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
 Get one of the results for a particular key in the datastore.
 
static void postgres_plugin_get_zero_anonymity (void *cls, uint64_t next_uid, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
 Select a subset of the items in the datastore and call the given iterator for each of them.
 
static int repl_proc (void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
 Wrapper for the iterator for 'sqlite_plugin_replication_get'.
 
static void postgres_plugin_get_replication (void *cls, PluginDatumProcessor proc, void *proc_cls)
 Get a random item for replication.
 
static void postgres_plugin_get_expiration (void *cls, PluginDatumProcessor proc, void *proc_cls)
 Get a random item for expiration.
 
static void process_keys (void *cls, PGresult *result, unsigned int num_results)
 Function to be called with the results of a SELECT statement that has returned num_results results.
 
static void postgres_plugin_get_keys (void *cls, PluginKeyProcessor proc, void *proc_cls)
 Get all of the keys in the datastore.
 
static void postgres_plugin_drop (void *cls)
 Drop database.
 
static void postgres_plugin_remove_key (void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, PluginRemoveCont cont, void *cont_cls)
 Remove a particular key in the datastore.
 
void * libgnunet_plugin_datastore_postgres_init (void *cls)
 Entry point for the plugin.
 
void * libgnunet_plugin_datastore_postgres_done (void *cls)
 Exit point from the plugin.
 

Detailed Description

postgres-based datastore backend

Author
Christian Grothoff

Definition in file plugin_datastore_postgres.c.

Macro Definition Documentation

◆ BUSY_TIMEOUT

#define BUSY_TIMEOUT   GNUNET_TIME_UNIT_SECONDS

After how many ms "busy" should a DB operation fail for good? A low value makes sure that we are more responsive to requests (especially PUTs).

A high value guarantees a higher success rate (SELECTs in iterate can take several seconds despite LIMIT=1).

The default value of 1s should ensure that users do not experience huge latencies while at the same time allowing operations to succeed with reasonable probability.

Definition at line 41 of file plugin_datastore_postgres.c.

◆ RESULT_COLUMNS

#define RESULT_COLUMNS   "repl, type, prio, anonLevel, expire, hash, value, oid"

Function Documentation

◆ reconnect_setup()

static void reconnect_setup ( void *  cls,
struct GNUNET_PQ_Context pq 
)
static

Function called whenever we reconnect to the DB.

Sets up the options, possibly the tables and the prepared statements.

Parameters
clsthe struct Plugin
pqdatabase handle

Definition at line 74 of file plugin_datastore_postgres.c.

76{
77 struct Plugin *plugin = cls;
78#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid"
81 "SELECT " RESULT_COLUMNS
82 " FROM datastore.gn090"
83 " WHERE oid >= $1::bigint AND"
84 " (rvalue >= $2 OR 0 = $3::smallint) AND"
85 " (hash = $4 OR 0 = $5::smallint) AND"
86 " (type = $6 OR 0 = $7::smallint)"
87 " ORDER BY oid ASC LIMIT 1"),
89 "INSERT INTO datastore.gn090"
90 " (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
91 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)"),
92 GNUNET_PQ_make_prepare ("update",
93 "UPDATE datastore.gn090"
94 " SET prio = prio + $1,"
95 " repl = repl + $2,"
96 " expire = GREATEST(expire, $3)"
97 " WHERE hash = $4 AND vhash = $5"),
98 GNUNET_PQ_make_prepare ("decrepl",
99 "UPDATE datastore.gn090"
100 " SET repl = GREATEST (repl - 1, 0)"
101 " WHERE oid = $1"),
102 GNUNET_PQ_make_prepare ("select_non_anonymous",
103 "SELECT " RESULT_COLUMNS
104 " FROM datastore.gn090"
105 " WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint"
106 " ORDER BY oid ASC LIMIT 1"),
107 GNUNET_PQ_make_prepare ("select_expiration_order",
108 "(SELECT " RESULT_COLUMNS
109 " FROM datastore.gn090"
110 " WHERE expire < $1 ORDER BY prio ASC LIMIT 1) "
111 "UNION "
112 "(SELECT " RESULT_COLUMNS
113 " FROM datastore.gn090"
114 " ORDER BY prio ASC LIMIT 1)"
115 " ORDER BY expire ASC LIMIT 1"),
116 GNUNET_PQ_make_prepare ("select_replication_order",
117 "SELECT " RESULT_COLUMNS
118 " FROM datastore.gn090"
119 " ORDER BY repl DESC,RANDOM() LIMIT 1"),
120 GNUNET_PQ_make_prepare ("delrow",
121 "DELETE FROM datastore.gn090"
122 " WHERE oid=$1"),
123 GNUNET_PQ_make_prepare ("remove",
124 "DELETE FROM datastore.gn090"
125 " WHERE hash = $1 AND"
126 " value = $2"),
127 GNUNET_PQ_make_prepare ("get_keys",
128 "SELECT hash"
129 " FROM datastore.gn090"),
130 GNUNET_PQ_make_prepare ("estimate_size",
131 "SELECT CASE WHEN NOT EXISTS"
132 " (SELECT 1 FROM datastore.gn090)"
133 " THEN 0"
134 " ELSE (SELECT SUM(LENGTH(value))+256*COUNT(*)"
135 " FROM datastore.gn090)"
136 "END AS total"),
138 };
139#undef RESULT_COLUMNS
140
141 if (GNUNET_SYSERR ==
143 {
144 plugin->ready = false;
145 return;
146 }
147 if (GNUNET_OK !=
149 "datastore-"))
150 {
151 plugin->ready = false;
152 return;
153 }
154 if (GNUNET_OK !=
156 ps))
157 {
158 plugin->ready = false;
159 return;
160 }
161 plugin->ready = true;
162}
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
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:73
struct GNUNET_PQ_PreparedStatement GNUNET_PQ_make_prepare(const char *name, const char *sql)
Create a struct GNUNET_PQ_PreparedStatement.
Definition pq_prepare.c:30
#define GNUNET_PQ_PREPARED_STATEMENT_END
Terminator for prepared statement list.
enum GNUNET_GenericReturnValue GNUNET_PQ_load_versioning(struct GNUNET_PQ_Context *db)
Setup database versioning.
Definition pq_connect.c:602
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:398
@ GNUNET_OK
@ GNUNET_SYSERR
#define RESULT_COLUMNS
Information needed to prepare a list of SQL statements using GNUNET_PQ_prepare_statements().
Handle for a plugin.
Definition block.c:38

References GNUNET_OK, GNUNET_PQ_load_versioning(), GNUNET_PQ_make_prepare(), GNUNET_PQ_prepare_statements(), GNUNET_PQ_PREPARED_STATEMENT_END, GNUNET_PQ_run_sql(), GNUNET_SYSERR, plugin, ps, and RESULT_COLUMNS.

Referenced by init_connection().

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

◆ init_connection()

static enum GNUNET_GenericReturnValue init_connection ( struct Plugin plugin)
static

Get a database handle.

Parameters
pluginglobal context
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 172 of file plugin_datastore_postgres.c.

173{
174 plugin->dbh = GNUNET_PQ_init (plugin->env->cfg,
175 "datastore-postgres",
177 plugin);
178 if (NULL == plugin->dbh)
179 return GNUNET_SYSERR;
180 if (! plugin->ready)
181 return GNUNET_NO;
182 return GNUNET_OK;
183}
struct GNUNET_PQ_Context * GNUNET_PQ_init(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_PQ_ReconnectCallback rc, void *rc_cls)
Connect to a postgres database using the configuration option "CONFIG" in section.
@ GNUNET_NO
static void reconnect_setup(void *cls, struct GNUNET_PQ_Context *pq)
Function called whenever we reconnect to the DB.

References GNUNET_NO, GNUNET_OK, GNUNET_PQ_init(), GNUNET_SYSERR, plugin, and reconnect_setup().

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ postgres_plugin_estimate_size()

static void postgres_plugin_estimate_size ( void *  cls,
unsigned long long *  estimate 
)
static

Get an estimate of how much space the database is currently using.

Parameters
clsour struct Plugin *
Returns
number of bytes used on disk

Definition at line 194 of file plugin_datastore_postgres.c.

196{
197 struct Plugin *plugin = cls;
198 uint64_t total;
199 struct GNUNET_PQ_QueryParam params[] = {
201 };
202 struct GNUNET_PQ_ResultSpec rs[] = {
204 &total),
206 };
208
209 if (NULL == estimate)
210 return;
212 "estimate_size",
213 params,
214 rs);
216 {
217 *estimate = 0LL;
218 return;
219 }
220 *estimate = total;
221}
static int ret
Final status code.
Definition gnunet-arm.c:93
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
@ GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
The transaction succeeded, and yielded one result.
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_uint64(const char *name, uint64_t *u64)
uint64_t expected.
#define GNUNET_PQ_query_param_end
End of query parameter specification.
#define GNUNET_PQ_result_spec_end
End of result parameter specification.
Description of a DB query parameter.
Description of a DB result cell.

References GNUNET_DB_STATUS_SUCCESS_ONE_RESULT, GNUNET_PQ_eval_prepared_singleton_select(), GNUNET_PQ_query_param_end, GNUNET_PQ_result_spec_end, GNUNET_PQ_result_spec_uint64(), plugin, and ret.

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ postgres_plugin_put()

static void postgres_plugin_put ( void *  cls,
const struct GNUNET_HashCode key,
bool  absent,
uint32_t  size,
const void *  data,
enum GNUNET_BLOCK_Type  type,
uint32_t  priority,
uint32_t  anonymity,
uint32_t  replication,
struct GNUNET_TIME_Absolute  expiration,
PluginPutCont  cont,
void *  cont_cls 
)
static

Store an item in the datastore.

Parameters
clsclosure with the struct Plugin
keykey for the item
absenttrue if the key was not found in the bloom filter
sizenumber of bytes in data
datacontent stored
typetype of the content
prioritypriority of the content
anonymityanonymity-level for the content
replicationreplication-level for the content
expirationexpiration time for the content
contcontinuation called with success or failure status
cont_clscontinuation closure

Definition at line 241 of file plugin_datastore_postgres.c.

253{
254 struct Plugin *plugin = cls;
255 struct GNUNET_HashCode vhash;
257
259 size,
260 &vhash);
261 if (! absent)
262 {
263 struct GNUNET_PQ_QueryParam params[] = {
270 };
272 "update",
273 params);
274 if (0 > ret)
275 {
276 cont (cont_cls,
277 key,
278 size,
280 _ ("Postgresql exec failure"));
281 return;
282 }
283 if (0 != ret)
284 {
285 cont (cont_cls,
286 key,
287 size,
288 GNUNET_NO,
289 NULL);
290 return;
291 }
292 }
293
294 {
295 uint32_t utype = (uint32_t) type;
296 uint64_t rvalue = GNUNET_CRYPTO_random_u64 (UINT64_MAX);
297 struct GNUNET_PQ_QueryParam params[] = {
308 };
309
311 "put",
312 params);
313 if (0 > ret)
314 {
315 cont (cont_cls,
316 key,
317 size,
319 "Postgresql exec failure");
320 return;
321 }
322 }
323 plugin->env->duc (plugin->env->cls,
326 "datastore-postgres",
327 "Stored %u bytes in database\n",
328 (unsigned int) size);
329 cont (cont_cls,
330 key,
331 size,
332 GNUNET_OK,
333 NULL);
334}
static unsigned int replication
Desired replication level.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
static unsigned int anonymity
static uint32_t type
Type string converted to DNS type value.
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_fixed_size(const void *ptr, size_t ptr_size)
Generate query parameter for a buffer ptr of ptr_size bytes.
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint64_t in host byte order.
#define GNUNET_PQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_non_select(struct GNUNET_PQ_Context *db, const char *statement_name, const struct GNUNET_PQ_QueryParam *params)
Execute a named prepared statement that is NOT a SELECT statement in connection using the given param...
Definition pq_eval.c:135
uint64_t GNUNET_CRYPTO_random_u64(uint64_t max)
Generate a random unsigned 64-bit value.
#define GNUNET_DATASTORE_ENTRY_OVERHEAD
How many bytes of overhead will we assume per entry in any DB (for reservations)?
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
#define GNUNET_log_from(kind, comp,...)
@ GNUNET_ERROR_TYPE_DEBUG
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
A 512-bit hashcode.
void * cls
Closure to pass to start_testcase.

References _, anonymity, GNUNET_TESTING_PluginFunctions::cls, data, expiration, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_random_u64(), GNUNET_DATASTORE_ENTRY_OVERHEAD, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log_from, GNUNET_NO, GNUNET_OK, GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_query_param_absolute_time(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_fixed_size(), GNUNET_PQ_query_param_uint32(), GNUNET_PQ_query_param_uint64(), GNUNET_SYSERR, key, plugin, replication, ret, size, and type.

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ process_result()

static void process_result ( void *  cls,
PGresult *  res,
unsigned int  num_results 
)
static

Function invoked to process the result and call the processor of cls.

Parameters
clsour struct ProcessResultContext
resresult from exec
num_resultsnumber of results in res

Definition at line 368 of file plugin_datastore_postgres.c.

371{
372 struct ProcessResultContext *prc = cls;
373 struct Plugin *plugin = prc->plugin;
374
375 if (0 == num_results)
376 {
377 /* no result */
379 "datastore-postgres",
380 "Ending iteration (no more results)\n");
381 prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
383 return;
384 }
385 if (1 != num_results)
386 {
387 GNUNET_break (0);
388 prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
390 return;
391 }
392 /* Technically we don't need the loop here, but nicer in case
393 we ever relax the condition above. */
394 for (unsigned int i = 0; i < num_results; i++)
395 {
396 int iret;
397 uint64_t rowid;
398 uint32_t utype;
399 uint32_t anonymity;
400 uint32_t replication;
401 uint32_t priority;
402 size_t size;
403 void *data;
404 struct GNUNET_TIME_Absolute expiration_time;
405 struct GNUNET_HashCode key;
406 struct GNUNET_PQ_ResultSpec rs[] = {
408 GNUNET_PQ_result_spec_uint32 ("type", &utype),
409 GNUNET_PQ_result_spec_uint32 ("prio", &priority),
411 GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
414 GNUNET_PQ_result_spec_uint64 ("oid", &rowid),
416 };
417
418 if (GNUNET_OK !=
420 rs,
421 i))
422 {
423 GNUNET_break (0);
424 prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
426 return;
427 }
428
430 "datastore-postgres",
431 "Found result of size %u bytes and type %u in database\n",
432 (unsigned int) size,
433 (unsigned int) utype);
434 iret = prc->proc (prc->proc_cls,
435 &key,
436 size,
437 data,
438 (enum GNUNET_BLOCK_Type) utype,
439 priority,
440 anonymity,
442 expiration_time,
443 rowid);
444 if (iret == GNUNET_NO)
445 {
446 struct GNUNET_PQ_QueryParam param[] = {
449 };
450
452 "Processor asked for item %u to be removed.\n",
453 (unsigned int) rowid);
454 if (0 <
456 "delrow",
457 param))
458 {
460 "datastore-postgres",
461 "Deleting %u bytes from database\n",
462 (unsigned int) size);
463 plugin->env->duc (plugin->env->cls,
466 "datastore-postgres",
467 "Deleted %u bytes from database\n",
468 (unsigned int) size);
469 }
470 }
472 } /* for (i) */
473}
static char * res
Currently read line or NULL on EOF.
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32(const char *name, uint32_t *u32)
uint32_t expected.
#define GNUNET_PQ_result_spec_auto_from_type(name, dst)
We expect a fixed-size result, with size determined by the type of * dst
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_absolute_time(const char *name, struct GNUNET_TIME_Absolute *at)
Absolute time expected.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_variable_size(const char *name, void **dst, size_t *sptr)
Variable-size result expected.
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
enum GNUNET_GenericReturnValue GNUNET_PQ_extract_result(PGresult *result, struct GNUNET_PQ_ResultSpec *rs, int row)
Extract results from a query result according to the given specification.
Definition pq.c:152
#define GNUNET_log(kind,...)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
Time for absolute times used by GNUnet, in microseconds.
Closure for process_result.
struct Plugin * plugin
The plugin handle.
void * proc_cls
Closure for proc.
PluginDatumProcessor proc
Function to call on each result.

References anonymity, GNUNET_TESTING_PluginFunctions::cls, data, GNUNET_break, GNUNET_DATASTORE_ENTRY_OVERHEAD, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_log_from, GNUNET_NO, GNUNET_OK, GNUNET_PQ_cleanup_result(), GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_extract_result(), GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_uint64(), GNUNET_PQ_result_spec_absolute_time(), GNUNET_PQ_result_spec_auto_from_type, GNUNET_PQ_result_spec_end, GNUNET_PQ_result_spec_uint32(), GNUNET_PQ_result_spec_uint64(), GNUNET_PQ_result_spec_variable_size(), GNUNET_TIME_UNIT_ZERO_ABS, key, plugin, ProcessResultContext::plugin, ProcessResultContext::proc, ProcessResultContext::proc_cls, replication, res, and size.

Referenced by postgres_plugin_get_expiration(), postgres_plugin_get_key(), postgres_plugin_get_replication(), and postgres_plugin_get_zero_anonymity().

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

◆ postgres_plugin_get_key()

static void postgres_plugin_get_key ( void *  cls,
uint64_t  next_uid,
bool  random,
const struct GNUNET_HashCode key,
enum GNUNET_BLOCK_Type  type,
PluginDatumProcessor  proc,
void *  proc_cls 
)
static

Get one of the results for a particular key in the datastore.

Parameters
clsclosure with the struct Plugin
next_uidreturn the result with lowest uid >= next_uid
randomif true, return a random result instead of using next_uid
keymaybe NULL (to match all entries)
typeentries of which type are relevant? Use 0 for any type.
procfunction to call on the matching value; will be called with NULL if nothing matches
proc_clsclosure for proc

Definition at line 490 of file plugin_datastore_postgres.c.

497{
498 struct Plugin *plugin = cls;
499 uint32_t utype = type;
500 uint16_t use_rvalue = random;
501 uint16_t use_key = NULL != key;
502 uint16_t use_type = GNUNET_BLOCK_TYPE_ANY != type;
503 uint64_t rvalue;
504 struct ProcessResultContext prc;
506
507 if (random)
508 {
509 rvalue = GNUNET_CRYPTO_random_u64 (UINT64_MAX);
510 next_uid = 0;
511 }
512 else
513 {
514 rvalue = 0;
515 }
516
517 {
518 struct GNUNET_PQ_QueryParam params[] = {
521 GNUNET_PQ_query_param_uint16 (&use_rvalue),
527 };
528 prc.plugin = plugin;
529 prc.proc = proc;
530 prc.proc_cls = proc_cls;
531
533 "get",
534 params,
536 &prc);
537 }
538 if (0 > res)
539 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
541}
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_multi_select(struct GNUNET_PQ_Context *db, const char *statement_name, const struct GNUNET_PQ_QueryParam *params, GNUNET_PQ_PostgresResultHandler rh, void *rh_cls)
Execute a named prepared statement that is a SELECT statement which may return multiple results in co...
Definition pq_eval.c:165
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint16(const uint16_t *x)
Generate query parameter for an uint16_t in host byte order.
static void process_result(void *cls, PGresult *res, unsigned int num_results)
Function invoked to process the result and call the processor of cls.

References GNUNET_BLOCK_TYPE_ANY, GNUNET_CRYPTO_random_u64(), GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_uint16(), GNUNET_PQ_query_param_uint32(), GNUNET_PQ_query_param_uint64(), GNUNET_TIME_UNIT_ZERO_ABS, key, plugin, ProcessResultContext::plugin, ProcessResultContext::proc, ProcessResultContext::proc_cls, process_result(), res, and type.

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ postgres_plugin_get_zero_anonymity()

static void postgres_plugin_get_zero_anonymity ( void *  cls,
uint64_t  next_uid,
enum GNUNET_BLOCK_Type  type,
PluginDatumProcessor  proc,
void *  proc_cls 
)
static

Select a subset of the items in the datastore and call the given iterator for each of them.

Parameters
clsour struct Plugin *
next_uidreturn the result with lowest uid >= next_uid
typeentries of which type should be considered? Must not be zero (ANY).
procfunction to call on the matching value; will be called with NULL if no value matches
proc_clsclosure for proc

Definition at line 557 of file plugin_datastore_postgres.c.

562{
563 struct Plugin *plugin = cls;
564 uint32_t utype = type;
565 struct GNUNET_PQ_QueryParam params[] = {
569 };
570 struct ProcessResultContext prc;
572
573 prc.plugin = plugin;
574 prc.proc = proc;
575 prc.proc_cls = proc_cls;
577 "select_non_anonymous",
578 params,
580 &prc);
581 if (0 > res)
582 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
584}

References GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_uint32(), GNUNET_PQ_query_param_uint64(), GNUNET_TIME_UNIT_ZERO_ABS, plugin, ProcessResultContext::plugin, ProcessResultContext::proc, ProcessResultContext::proc_cls, process_result(), res, and type.

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ repl_proc()

static int repl_proc ( void *  cls,
const struct GNUNET_HashCode key,
uint32_t  size,
const void *  data,
enum GNUNET_BLOCK_Type  type,
uint32_t  priority,
uint32_t  anonymity,
uint32_t  replication,
struct GNUNET_TIME_Absolute  expiration,
uint64_t  uid 
)
static

Wrapper for the iterator for 'sqlite_plugin_replication_get'.

Decrements the replication counter and calls the original iterator.

Parameters
clsclosure with the struct ReplCtx *
keykey for the content
sizenumber of bytes in data
datacontent stored
typetype of the content
prioritypriority of the content
anonymityanonymity-level for the content
replicationreplication-level for the content
expirationexpiration time for the content
uidunique identifier for the datum; maybe 0 if no unique identifier is available
Returns
GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue (continue on call to "next", of course), GNUNET_NO to delete the item and continue (if supported)

Definition at line 631 of file plugin_datastore_postgres.c.

641{
642 struct ReplCtx *rc = cls;
643 struct Plugin *plugin = rc->plugin;
644 int ret;
645 struct GNUNET_PQ_QueryParam params[] = {
648 };
649 enum GNUNET_DB_QueryStatus qret;
650
651 ret = rc->proc (rc->proc_cls,
652 key,
653 size,
654 data,
655 type,
656 priority,
657 anonymity,
660 uid);
661 if (NULL == key)
662 return ret;
664 "decrepl",
665 params);
666 if (0 > qret)
667 return GNUNET_SYSERR;
668 return ret;
669}
Context for #repl_iter() function.
void * proc_cls
Closure for proc.
struct Plugin * plugin
Plugin handle.
PluginDatumProcessor proc
Function to call for the result (or the NULL).

References anonymity, data, expiration, GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_uint64(), GNUNET_SYSERR, key, plugin, ReplCtx::plugin, ReplCtx::proc, ReplCtx::proc_cls, replication, ret, size, and type.

Referenced by postgres_plugin_get_replication().

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

◆ postgres_plugin_get_replication()

static void postgres_plugin_get_replication ( void *  cls,
PluginDatumProcessor  proc,
void *  proc_cls 
)
static

Get a random item for replication.

Returns a single, not expired, random item from those with the highest replication counters. The item's replication counter is decremented by one IF it was positive before. Call proc with all values ZERO or NULL if the datastore is empty.

Parameters
clsclosure with the struct Plugin
procfunction to call the value (once only).
proc_clsclosure for proc

Definition at line 684 of file plugin_datastore_postgres.c.

687{
688 struct Plugin *plugin = cls;
689 struct GNUNET_PQ_QueryParam params[] = {
691 };
692 struct ReplCtx rc;
693 struct ProcessResultContext prc;
695
696 rc.plugin = plugin;
697 rc.proc = proc;
698 rc.proc_cls = proc_cls;
699 prc.plugin = plugin;
700 prc.proc = &repl_proc;
701 prc.proc_cls = &rc;
703 "select_replication_order",
704 params,
706 &prc);
707 if (0 > res)
708 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
710}
static int repl_proc(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
Wrapper for the iterator for 'sqlite_plugin_replication_get'.

References GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_end, GNUNET_TIME_UNIT_ZERO_ABS, plugin, ProcessResultContext::plugin, ReplCtx::plugin, ProcessResultContext::proc, ReplCtx::proc, ProcessResultContext::proc_cls, ReplCtx::proc_cls, process_result(), repl_proc(), and res.

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ postgres_plugin_get_expiration()

static void postgres_plugin_get_expiration ( void *  cls,
PluginDatumProcessor  proc,
void *  proc_cls 
)
static

Get a random item for expiration.

Call proc with all values ZERO or NULL if the datastore is empty.

Parameters
clsclosure with the struct Plugin
procfunction to call the value (once only).
proc_clsclosure for proc

Definition at line 722 of file plugin_datastore_postgres.c.

725{
726 struct Plugin *plugin = cls;
727 struct GNUNET_TIME_Absolute now = { 0 };
728 struct GNUNET_PQ_QueryParam params[] = {
731 };
732 struct ProcessResultContext prc;
733
735 prc.plugin = plugin;
736 prc.proc = proc;
737 prc.proc_cls = proc_cls;
739 "select_expiration_order",
740 params,
742 &prc);
743}
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111

References GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_absolute_time(), GNUNET_PQ_query_param_end, GNUNET_TIME_absolute_get(), plugin, ProcessResultContext::plugin, ProcessResultContext::proc, ProcessResultContext::proc_cls, and process_result().

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ process_keys()

static void process_keys ( void *  cls,
PGresult *  result,
unsigned int  num_results 
)
static

Function to be called with the results of a SELECT statement that has returned num_results results.

Parameters
clsclosure with a struct ProcessKeysContext
resultthe postgres result
num_resultsthe number of results in result

Definition at line 772 of file plugin_datastore_postgres.c.

775{
776 struct ProcessKeysContext *pkc = cls;
777
778 for (unsigned i = 0; i < num_results; i++)
779 {
780 struct GNUNET_HashCode key;
781 struct GNUNET_PQ_ResultSpec rs[] = {
783 &key),
785 };
786
787 if (GNUNET_OK !=
789 rs,
790 i))
791 {
792 GNUNET_break (0);
793 continue;
794 }
795 pkc->proc (pkc->proc_cls,
796 &key,
797 1);
799 }
800}
static int result
Global testing status.
Closure for process_keys.
PluginKeyProcessor proc
Function to call for each key.
void * proc_cls
Closure for proc.

References GNUNET_break, GNUNET_OK, GNUNET_PQ_cleanup_result(), GNUNET_PQ_extract_result(), GNUNET_PQ_result_spec_auto_from_type, GNUNET_PQ_result_spec_end, key, ProcessKeysContext::proc, ProcessKeysContext::proc_cls, and result.

Referenced by postgres_plugin_get_keys().

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

◆ postgres_plugin_get_keys()

static void postgres_plugin_get_keys ( void *  cls,
PluginKeyProcessor  proc,
void *  proc_cls 
)
static

Get all of the keys in the datastore.

Parameters
clsclosure with the struct Plugin *
procfunction to call on each key
proc_clsclosure for proc

Definition at line 811 of file plugin_datastore_postgres.c.

814{
815 struct Plugin *plugin = cls;
816 struct GNUNET_PQ_QueryParam params[] = {
818 };
819 struct ProcessKeysContext pkc;
820
821 pkc.proc = proc;
822 pkc.proc_cls = proc_cls;
824 "get_keys",
825 params,
827 &pkc);
828 proc (proc_cls,
829 NULL,
830 0);
831}
static void process_keys(void *cls, PGresult *result, unsigned int num_results)
Function to be called with the results of a SELECT statement that has returned num_results results.

References GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_query_param_end, plugin, ProcessKeysContext::proc, ProcessKeysContext::proc_cls, and process_keys().

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ postgres_plugin_drop()

static void postgres_plugin_drop ( void *  cls)
static

Drop database.

Parameters
clsclosure with the struct Plugin *

Definition at line 840 of file plugin_datastore_postgres.c.

841{
842 struct Plugin *plugin = cls;
843 struct GNUNET_PQ_ExecuteStatement es[] = {
844 GNUNET_PQ_make_execute ("DROP TABLE gn090"),
846 };
847
848 if (GNUNET_OK !=
850 es))
852 "postgres",
853 "Failed to drop table from database.\n");
854}
struct GNUNET_PQ_ExecuteStatement GNUNET_PQ_make_execute(const char *sql)
Create a struct GNUNET_PQ_ExecuteStatement where errors are fatal.
Definition pq_exec.c:30
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
#define GNUNET_PQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
@ GNUNET_ERROR_TYPE_WARNING
Information needed to run a list of SQL statements using GNUNET_PQ_exec_statements().

References GNUNET_ERROR_TYPE_WARNING, GNUNET_log_from, GNUNET_OK, GNUNET_PQ_exec_statements(), GNUNET_PQ_EXECUTE_STATEMENT_END, GNUNET_PQ_make_execute(), and plugin.

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ postgres_plugin_remove_key()

static void postgres_plugin_remove_key ( void *  cls,
const struct GNUNET_HashCode key,
uint32_t  size,
const void *  data,
PluginRemoveCont  cont,
void *  cont_cls 
)
static

Remove a particular key in the datastore.

Parameters
clsclosure
keykey for the content
sizenumber of bytes in data
datacontent stored
contcontinuation called with success or failure status
cont_clscontinuation closure for cont

Definition at line 868 of file plugin_datastore_postgres.c.

874{
875 struct Plugin *plugin = cls;
877 struct GNUNET_PQ_QueryParam params[] = {
881 };
882
884 "remove",
885 params);
886 if (0 > ret)
887 {
888 cont (cont_cls,
889 key,
890 size,
892 _ ("Postgresql exec failure"));
893 return;
894 }
896 {
897 cont (cont_cls,
898 key,
899 size,
900 GNUNET_NO,
901 NULL);
902 return;
903 }
904 plugin->env->duc (plugin->env->cls,
907 "datastore-postgres",
908 "Deleted %u bytes from database\n",
909 (unsigned int) size);
910 cont (cont_cls,
911 key,
912 size,
913 GNUNET_OK,
914 NULL);
915}
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.

References _, GNUNET_TESTING_PluginFunctions::cls, data, GNUNET_DATASTORE_ENTRY_OVERHEAD, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log_from, GNUNET_NO, GNUNET_OK, GNUNET_PQ_eval_prepared_non_select(), GNUNET_PQ_query_param_auto_from_type, GNUNET_PQ_query_param_end, GNUNET_PQ_query_param_fixed_size(), GNUNET_SYSERR, key, plugin, ret, and size.

Referenced by libgnunet_plugin_datastore_postgres_init().

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

◆ libgnunet_plugin_datastore_postgres_init()

void * libgnunet_plugin_datastore_postgres_init ( void *  cls)

Entry point for the plugin.

Parameters
clsthe struct GNUNET_DATASTORE_PluginEnvironment*
Returns
our struct Plugin *

Definition at line 928 of file plugin_datastore_postgres.c.

929{
932 struct Plugin *plugin;
933
934 plugin = GNUNET_new (struct Plugin);
935 plugin->env = env;
937 {
939 return NULL;
940 }
942 api->cls = plugin;
943 api->estimate_size = &postgres_plugin_estimate_size;
944 api->put = &postgres_plugin_put;
946 api->get_replication = &postgres_plugin_get_replication;
947 api->get_expiration = &postgres_plugin_get_expiration;
948 api->get_zero_anonymity = &postgres_plugin_get_zero_anonymity;
949 api->get_keys = &postgres_plugin_get_keys;
950 api->drop = &postgres_plugin_drop;
951 api->remove_key = &postgres_plugin_remove_key;
952 return api;
953}
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
static void postgres_plugin_get_replication(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for replication.
static void postgres_plugin_estimate_size(void *cls, unsigned long long *estimate)
Get an estimate of how much space the database is currently using.
static void postgres_plugin_drop(void *cls)
Drop database.
static void postgres_plugin_get_key(void *cls, uint64_t next_uid, bool random, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
Get one of the results for a particular key in the datastore.
static void postgres_plugin_get_zero_anonymity(void *cls, uint64_t next_uid, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
Select a subset of the items in the datastore and call the given iterator for each of them.
static enum GNUNET_GenericReturnValue init_connection(struct Plugin *plugin)
Get a database handle.
static void postgres_plugin_remove_key(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, PluginRemoveCont cont, void *cont_cls)
Remove a particular key in the datastore.
static void postgres_plugin_get_expiration(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for expiration.
static void postgres_plugin_get_keys(void *cls, PluginKeyProcessor proc, void *proc_cls)
Get all of the keys in the datastore.
static void postgres_plugin_put(void *cls, const struct GNUNET_HashCode *key, bool absent, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, PluginPutCont cont, void *cont_cls)
Store an item in the datastore.
GNUNET_BLOCK_GetKeyFunction get_key
Obtain the key for a given block (if possible).
void * cls
Closure for all of the callbacks.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition block.c:47

References Plugin::api, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_DATASTORE_PluginEnvironment::cls, env, GNUNET_BLOCK_PluginFunctions::get_key, GNUNET_free, GNUNET_new, GNUNET_OK, init_connection(), plugin, postgres_plugin_drop(), postgres_plugin_estimate_size(), postgres_plugin_get_expiration(), postgres_plugin_get_key(), postgres_plugin_get_keys(), postgres_plugin_get_replication(), postgres_plugin_get_zero_anonymity(), postgres_plugin_put(), and postgres_plugin_remove_key().

Here is the call graph for this function:

◆ libgnunet_plugin_datastore_postgres_done()

void * libgnunet_plugin_datastore_postgres_done ( void *  cls)

Exit point from the plugin.

Parameters
clsour struct Plugin *
Returns
always NULL

Definition at line 966 of file plugin_datastore_postgres.c.

967{
969 struct Plugin *plugin = api->cls;
970
974 return NULL;
975}
void GNUNET_PQ_disconnect(struct GNUNET_PQ_Context *db)
Disconnect from the database, destroying the prepared statements and releasing other associated resou...
Definition pq_connect.c:678
void * cls
Closure to use for all of the following callbacks (except "next_request").

References Plugin::api, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_DATASTORE_PluginFunctions::cls, GNUNET_free, GNUNET_PQ_disconnect(), and plugin.

Here is the call graph for this function: