GNUnet  0.11.x
plugin_datastore_postgres.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2009-2017 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #include "platform.h"
28 #include "gnunet_pq_lib.h"
29 
30 
41 #define BUSY_TIMEOUT GNUNET_TIME_UNIT_SECONDS
42 
43 
47 struct Plugin
48 {
53 
57  struct GNUNET_PQ_Context *dbh;
58 };
59 
60 
67 static int
69 {
70  struct GNUNET_PQ_ExecuteStatement es[] = {
71  /* FIXME: PostgreSQL does not have unsigned integers! This is ok for the type column because
72  * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel
73  * we do math or inequality tests, so we can't handle the entire range of uint32_t.
74  * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC.
75  */
77  "CREATE SEQUENCE IF NOT EXISTS gn090_oid_seq"),
78  GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS gn090 ("
79  " repl INTEGER NOT NULL DEFAULT 0,"
80  " type INTEGER NOT NULL DEFAULT 0,"
81  " prio INTEGER NOT NULL DEFAULT 0,"
82  " anonLevel INTEGER NOT NULL DEFAULT 0,"
83  " expire BIGINT NOT NULL DEFAULT 0,"
84  " rvalue BIGINT NOT NULL DEFAULT 0,"
85  " hash BYTEA NOT NULL DEFAULT '',"
86  " vhash BYTEA NOT NULL DEFAULT '',"
87  " value BYTEA NOT NULL DEFAULT '',"
88  " oid OID NOT NULL DEFAULT nextval('gn090_oid_seq'))"),
90  "ALTER SEQUENCE gn090_oid_seq OWNED BY gn090.oid"),
92  "CREATE INDEX IF NOT EXISTS oid_hash ON gn090 (oid)"),
94  "CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)"),
96  "CREATE INDEX IF NOT EXISTS idx_prio ON gn090 (prio)"),
98  "CREATE INDEX IF NOT EXISTS idx_expire ON gn090 (expire)"),
100  "CREATE INDEX IF NOT EXISTS idx_prio_anon ON gn090 (prio,anonLevel)"),
102  "CREATE INDEX IF NOT EXISTS idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)"),
104  "CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn090 (repl,rvalue)"),
106  "CREATE INDEX IF NOT EXISTS idx_expire_hash ON gn090 (expire,hash)"),
108  "ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"),
109  GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"),
110  GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"),
112  };
113 
114 #define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid"
115  struct GNUNET_PQ_PreparedStatement ps[] = {
116  GNUNET_PQ_make_prepare ("get",
117  "SELECT " RESULT_COLUMNS " FROM gn090"
118  " WHERE oid >= $1::bigint AND"
119  " (rvalue >= $2 OR 0 = $3::smallint) AND"
120  " (hash = $4 OR 0 = $5::smallint) AND"
121  " (type = $6 OR 0 = $7::smallint)"
122  " ORDER BY oid ASC LIMIT 1",
123  7),
124  GNUNET_PQ_make_prepare ("put",
125  "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
126  "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
127  9),
128  GNUNET_PQ_make_prepare ("update",
129  "UPDATE gn090"
130  " SET prio = prio + $1,"
131  " repl = repl + $2,"
132  " expire = GREATEST(expire, $3)"
133  " WHERE hash = $4 AND vhash = $5",
134  5),
135  GNUNET_PQ_make_prepare ("decrepl",
136  "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
137  "WHERE oid = $1",
138  1),
139  GNUNET_PQ_make_prepare ("select_non_anonymous",
140  "SELECT " RESULT_COLUMNS " FROM gn090 "
141  "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint "
142  "ORDER BY oid ASC LIMIT 1",
143  2),
144  GNUNET_PQ_make_prepare ("select_expiration_order",
145  "(SELECT " RESULT_COLUMNS " FROM gn090 "
146  "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) "
147  "UNION "
148  "(SELECT " RESULT_COLUMNS " FROM gn090 "
149  "ORDER BY prio ASC LIMIT 1) "
150  "ORDER BY expire ASC LIMIT 1",
151  1),
152  GNUNET_PQ_make_prepare ("select_replication_order",
153  "SELECT " RESULT_COLUMNS " FROM gn090 "
154  "ORDER BY repl DESC,RANDOM() LIMIT 1",
155  0),
156  GNUNET_PQ_make_prepare ("delrow",
157  "DELETE FROM gn090 "
158  "WHERE oid=$1",
159  1),
160  GNUNET_PQ_make_prepare ("remove",
161  "DELETE FROM gn090"
162  " WHERE hash = $1 AND"
163  " value = $2",
164  2),
165  GNUNET_PQ_make_prepare ("get_keys",
166  "SELECT hash FROM gn090",
167  0),
168  GNUNET_PQ_make_prepare ("estimate_size",
169  "SELECT CASE WHEN NOT EXISTS"
170  " (SELECT 1 FROM gn090)"
171  " THEN 0"
172  " ELSE (SELECT SUM(LENGTH(value))+256*COUNT(*) FROM gn090)"
173  "END AS total",
174  0),
176  };
177 #undef RESULT_COLUMNS
178 
179  plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg,
180  "datastore-postgres",
181  NULL,
182  es,
183  ps);
184  if (NULL == plugin->dbh)
185  return GNUNET_SYSERR;
186  return GNUNET_OK;
187 }
188 
189 
197 static void
199  unsigned long long *estimate)
200 {
201  struct Plugin *plugin = cls;
202  uint64_t total;
203  struct GNUNET_PQ_QueryParam params[] = {
205  };
206  struct GNUNET_PQ_ResultSpec rs[] = {
208  &total),
210  };
212 
213  if (NULL == estimate)
214  return;
216  "estimate_size",
217  params,
218  rs);
220  {
221  *estimate = 0LL;
222  return;
223  }
224  *estimate = total;
225 }
226 
227 
244 static void
246  const struct GNUNET_HashCode *key,
247  bool absent,
248  uint32_t size,
249  const void *data,
250  enum GNUNET_BLOCK_Type type,
251  uint32_t priority,
252  uint32_t anonymity,
253  uint32_t replication,
255  PluginPutCont cont,
256  void *cont_cls)
257 {
258  struct Plugin *plugin = cls;
259  struct GNUNET_HashCode vhash;
261 
262  GNUNET_CRYPTO_hash (data,
263  size,
264  &vhash);
265  if (! absent)
266  {
267  struct GNUNET_PQ_QueryParam params[] = {
268  GNUNET_PQ_query_param_uint32 (&priority),
269  GNUNET_PQ_query_param_uint32 (&replication),
274  };
276  "update",
277  params);
278  if (0 > ret)
279  {
280  cont (cont_cls,
281  key,
282  size,
284  _ ("Postgress exec failure"));
285  return;
286  }
287  bool affected = (0 != ret);
288  if (affected)
289  {
290  cont (cont_cls,
291  key,
292  size,
293  GNUNET_NO,
294  NULL);
295  return;
296  }
297  }
298 
299  {
300  uint32_t utype = (uint32_t) type;
302  UINT64_MAX);
303  struct GNUNET_PQ_QueryParam params[] = {
304  GNUNET_PQ_query_param_uint32 (&replication),
306  GNUNET_PQ_query_param_uint32 (&priority),
307  GNUNET_PQ_query_param_uint32 (&anonymity),
314  };
315 
317  "put",
318  params);
319  if (0 > ret)
320  {
321  cont (cont_cls,
322  key,
323  size,
325  "Postgress exec failure");
326  return;
327  }
328  }
329  plugin->env->duc (plugin->env->cls,
332  "datastore-postgres",
333  "Stored %u bytes in database\n",
334  (unsigned int) size);
335  cont (cont_cls,
336  key,
337  size,
338  GNUNET_OK,
339  NULL);
340 }
341 
342 
347 {
351  struct Plugin *plugin;
352 
357 
361  void *proc_cls;
362 };
363 
364 
373 static void
374 process_result (void *cls,
375  PGresult *res,
376  unsigned int num_results)
377 {
378  struct ProcessResultContext *prc = cls;
379  struct Plugin *plugin = prc->plugin;
380 
381  if (0 == num_results)
382  {
383  /* no result */
385  "datastore-postgres",
386  "Ending iteration (no more results)\n");
387  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
389  return;
390  }
391  if (1 != num_results)
392  {
393  GNUNET_break (0);
394  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
396  return;
397  }
398  /* Technically we don't need the loop here, but nicer in case
399  we ever relax the condition above. */
400  for (unsigned int i = 0; i < num_results; i++)
401  {
402  int iret;
403  uint32_t rowid;
404  uint32_t utype;
405  uint32_t anonymity;
406  uint32_t replication;
407  uint32_t priority;
408  size_t size;
409  void *data;
410  struct GNUNET_TIME_Absolute expiration_time;
411  struct GNUNET_HashCode key;
412  struct GNUNET_PQ_ResultSpec rs[] = {
413  GNUNET_PQ_result_spec_uint32 ("repl", &replication),
414  GNUNET_PQ_result_spec_uint32 ("type", &utype),
415  GNUNET_PQ_result_spec_uint32 ("prio", &priority),
416  GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity),
417  GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
419  GNUNET_PQ_result_spec_variable_size ("value", &data, &size),
420  GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
422  };
423 
424  if (GNUNET_OK !=
426  rs,
427  i))
428  {
429  GNUNET_break (0);
430  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
432  return;
433  }
434 
436  "datastore-postgres",
437  "Found result of size %u bytes and type %u in database\n",
438  (unsigned int) size,
439  (unsigned int) utype);
440  iret = prc->proc (prc->proc_cls,
441  &key,
442  size,
443  data,
444  (enum GNUNET_BLOCK_Type) utype,
445  priority,
446  anonymity,
447  replication,
448  expiration_time,
449  rowid);
450  if (iret == GNUNET_NO)
451  {
452  struct GNUNET_PQ_QueryParam param[] = {
455  };
456 
458  "Processor asked for item %u to be removed.\n",
459  (unsigned int) rowid);
460  if (0 <
462  "delrow",
463  param))
464  {
466  "datastore-postgres",
467  "Deleting %u bytes from database\n",
468  (unsigned int) size);
469  plugin->env->duc (plugin->env->cls,
472  "datastore-postgres",
473  "Deleted %u bytes from database\n",
474  (unsigned int) size);
475  }
476  }
478  } /* for (i) */
479 }
480 
481 
495 static void
497  uint64_t next_uid,
498  bool random,
499  const struct GNUNET_HashCode *key,
500  enum GNUNET_BLOCK_Type type,
502  void *proc_cls)
503 {
504  struct Plugin *plugin = cls;
505  uint32_t utype = type;
506  uint16_t use_rvalue = random;
507  uint16_t use_key = NULL != key;
508  uint16_t use_type = GNUNET_BLOCK_TYPE_ANY != type;
509  uint64_t rvalue;
510  struct GNUNET_PQ_QueryParam params[] = {
511  GNUNET_PQ_query_param_uint64 (&next_uid),
513  GNUNET_PQ_query_param_uint16 (&use_rvalue),
515  GNUNET_PQ_query_param_uint16 (&use_key),
517  GNUNET_PQ_query_param_uint16 (&use_type),
519  };
520  struct ProcessResultContext prc;
522 
523  if (random)
524  {
526  UINT64_MAX);
527  next_uid = 0;
528  }
529  else
530  {
531  rvalue = 0;
532  }
533  prc.plugin = plugin;
534  prc.proc = proc;
535  prc.proc_cls = proc_cls;
536 
538  "get",
539  params,
541  &prc);
542  if (0 > res)
543  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
545 }
546 
547 
560 static void
562  uint64_t next_uid,
563  enum GNUNET_BLOCK_Type type,
565  void *proc_cls)
566 {
567  struct Plugin *plugin = cls;
568  uint32_t utype = type;
569  struct GNUNET_PQ_QueryParam params[] = {
571  GNUNET_PQ_query_param_uint64 (&next_uid),
573  };
574  struct ProcessResultContext prc;
576 
577  prc.plugin = plugin;
578  prc.proc = proc;
579  prc.proc_cls = proc_cls;
581  "select_non_anonymous",
582  params,
584  &prc);
585  if (0 > res)
586  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
588 }
589 
590 
594 struct ReplCtx
595 {
599  struct Plugin *plugin;
600 
605 
609  void *proc_cls;
610 };
611 
612 
634 static int
635 repl_proc (void *cls,
636  const struct GNUNET_HashCode *key,
637  uint32_t size,
638  const void *data,
639  enum GNUNET_BLOCK_Type type,
640  uint32_t priority,
641  uint32_t anonymity,
642  uint32_t replication,
644  uint64_t uid)
645 {
646  struct ReplCtx *rc = cls;
647  struct Plugin *plugin = rc->plugin;
648  int ret;
649  uint32_t oid = (uint32_t) uid;
650  struct GNUNET_PQ_QueryParam params[] = {
653  };
654  enum GNUNET_DB_QueryStatus qret;
655 
656  ret = rc->proc (rc->proc_cls,
657  key,
658  size,
659  data,
660  type,
661  priority,
662  anonymity,
663  replication,
664  expiration,
665  uid);
666  if (NULL == key)
667  return ret;
668  qret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
669  "decrepl",
670  params);
671  if (0 > qret)
672  return GNUNET_SYSERR;
673  return ret;
674 }
675 
676 
688 static void
691  void *proc_cls)
692 {
693  struct Plugin *plugin = cls;
694  struct GNUNET_PQ_QueryParam params[] = {
696  };
697  struct ReplCtx rc;
698  struct ProcessResultContext prc;
700 
701  rc.plugin = plugin;
702  rc.proc = proc;
703  rc.proc_cls = proc_cls;
704  prc.plugin = plugin;
705  prc.proc = &repl_proc;
706  prc.proc_cls = &rc;
708  "select_replication_order",
709  params,
711  &prc);
712  if (0 > res)
713  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
715 }
716 
717 
726 static void
729  void *proc_cls)
730 {
731  struct Plugin *plugin = cls;
732  struct GNUNET_TIME_Absolute now;
733  struct GNUNET_PQ_QueryParam params[] = {
736  };
737  struct ProcessResultContext prc;
738 
739  now = GNUNET_TIME_absolute_get ();
740  prc.plugin = plugin;
741  prc.proc = proc;
742  prc.proc_cls = proc_cls;
744  "select_expiration_order",
745  params,
747  &prc);
748 }
749 
750 
755 {
760 
764  void *proc_cls;
765 };
766 
767 
776 static void
777 process_keys (void *cls,
778  PGresult *result,
779  unsigned int num_results)
780 {
781  struct ProcessKeysContext *pkc = cls;
782 
783  for (unsigned i = 0; i < num_results; i++)
784  {
785  struct GNUNET_HashCode key;
786  struct GNUNET_PQ_ResultSpec rs[] = {
788  &key),
790  };
791 
792  if (GNUNET_OK !=
793  GNUNET_PQ_extract_result (result,
794  rs,
795  i))
796  {
797  GNUNET_break (0);
798  continue;
799  }
800  pkc->proc (pkc->proc_cls,
801  &key,
802  1);
804  }
805 }
806 
807 
815 static void
817  PluginKeyProcessor proc,
818  void *proc_cls)
819 {
820  struct Plugin *plugin = cls;
821  struct GNUNET_PQ_QueryParam params[] = {
823  };
824  struct ProcessKeysContext pkc;
825 
826  pkc.proc = proc;
827  pkc.proc_cls = proc_cls;
829  "get_keys",
830  params,
831  &process_keys,
832  &pkc);
833  proc (proc_cls,
834  NULL,
835  0);
836 }
837 
838 
844 static void
846 {
847  struct Plugin *plugin = cls;
848  struct GNUNET_PQ_ExecuteStatement es[] = {
849  GNUNET_PQ_make_execute ("DROP TABLE gn090"),
851  };
852 
853  if (GNUNET_OK !=
855  es))
857  "postgres",
858  _ ("Failed to drop table from database.\n"));
859 }
860 
861 
872 static void
874  const struct GNUNET_HashCode *key,
875  uint32_t size,
876  const void *data,
877  PluginRemoveCont cont,
878  void *cont_cls)
879 {
880  struct Plugin *plugin = cls;
882  struct GNUNET_PQ_QueryParam params[] = {
886  };
887 
889  "remove",
890  params);
891  if (0 > ret)
892  {
893  cont (cont_cls,
894  key,
895  size,
897  _ ("Postgress exec failure"));
898  return;
899  }
901  {
902  cont (cont_cls,
903  key,
904  size,
905  GNUNET_NO,
906  NULL);
907  return;
908  }
909  plugin->env->duc (plugin->env->cls,
912  "datastore-postgres",
913  "Deleted %u bytes from database\n",
914  (unsigned int) size);
915  cont (cont_cls,
916  key,
917  size,
918  GNUNET_OK,
919  NULL);
920 }
921 
922 
929 void *
931 {
934  struct Plugin *plugin;
935 
936  plugin = GNUNET_new (struct Plugin);
937  plugin->env = env;
938  if (GNUNET_OK != init_connection (plugin))
939  {
940  GNUNET_free (plugin);
941  return NULL;
942  }
944  api->cls = plugin;
946  api->put = &postgres_plugin_put;
952  api->drop = &postgres_plugin_drop;
955  "datastore-postgres",
956  _ ("Postgres database running\n"));
957  return api;
958 }
959 
960 
967 void *
969 {
971  struct Plugin *plugin = api->cls;
972 
973  GNUNET_PQ_disconnect (plugin->dbh);
974  GNUNET_free (plugin);
975  GNUNET_free (api);
976  return NULL;
977 }
978 
979 
980 /* end of plugin_datastore_postgres.c */
PluginGetKeys get_keys
Iterate over all keys in the database.
PluginDatumProcessor proc
Function to call on each result.
PluginPut put
Function to store an item in the datastore.
int(* PluginDatumProcessor)(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)
An processor over a set of items stored in the datastore.
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:513
void * proc_cls
Closure for proc.
PluginGetType get_zero_anonymity
Get datum (of the specified type) with anonymity level zero.
struct Plugin * plugin
Plugin handle.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
Any type of block, used as a wildcard when searching.
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...
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:36
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
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:209
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint16(const uint16_t *x)
Generate query parameter for an uint16_t in host byte order.
Information needed to run a list of SQL statements using GNUNET_PQ_exec_statements().
PluginRemoveKey remove_key
Function to remove an item from the database.
Information needed to prepare a list of SQL statements using GNUNET_PQ_prepare_statements().
char * key
TLS key.
static unsigned int replication
Description of a DB result cell.
PluginEstimateSize estimate_size
Calculate the current on-disk size of the SQ store.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
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.
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 Plugin * plugin
The plugin handle.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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 &#39;sqlite_plugin_replication_get&#39;.
void(* PluginPutCont)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Put continuation.
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_expiration(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for expiration.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
PluginKeyProcessor proc
Function to call for each key.
PluginGetRandom get_replication
Function to get a random item with high replication score from the database, lowering the item&#39;s repl...
PluginDrop drop
Delete the database.
void * cls
Closure for conv and cleaner.
#define GNUNET_PQ_result_spec_end
End of result parameter specification.
#define GNUNET_PQ_query_param_end
End of query parameter specification.
Definition: gnunet_pq_lib.h:97
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_variable_size(const char *name, void **dst, size_t *sptr)
Variable-size result expected.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32(const char *name, uint32_t *u32)
uint32_t expected.
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:258
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
void * proc_cls
Closure for proc.
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_absolute_time(const char *name, struct GNUNET_TIME_Absolute *at)
Absolute time expected.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
void * libgnunet_plugin_datastore_postgres_init(void *cls)
Entry point for the plugin.
void(* PluginKeyProcessor)(void *cls, const struct GNUNET_HashCode *key, unsigned int count)
An processor over a set of keys stored in the datastore.
PluginGetRandom get_expiration
Function to get a random expired item or, if none are expired, either the oldest entry or one with a ...
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
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.
#define GNUNET_PQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
static int result
Global testing status.
Closure for process_result.
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
A 512-bit hashcode.
#define GNUNET_DATASTORE_ENTRY_OVERHEAD
How many bytes of overhead will we assume per entry in any DB (for reservations)? ...
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static int res
static char * plugin
Solver plugin name as string.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static void postgres_plugin_drop(void *cls)
Drop database.
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.
Definition: pq_connect.c:466
#define GNUNET_PQ_result_spec_auto_from_type(name, dst)
We expect a fixed-size result, with size determined by the type of * dst
#define GNUNET_PQ_PREPARED_STATEMENT_END
Terminator for prepared statement list.
Context for repl_proc() function.
helper functions for Postgres DB interactions
Closure for process_keys.
void(* PluginRemoveCont)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Remove continuation.
static void postgres_plugin_get_replication(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for replication.
void * cls
Closure to use for all of the following callbacks (except "next_request").
void * libgnunet_plugin_datastore_postgres_done(void *cls)
Exit point from the plugin.
The transaction succeeded, and yielded one result.
Definition: gnunet_db_lib.h:58
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 connnection using the given para...
Definition: pq_eval.c:164
#define RESULT_COLUMNS
static void postgres_plugin_get_keys(void *cls, PluginKeyProcessor proc, void *proc_cls)
Get all of the keys in the datastore.
unsigned long long size
Size of all values we&#39;re storing.
void * proc_cls
Closure for proc.
Handle for a plugin.
Definition: block.c:37
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint16_t in host byte order.
PluginDatumProcessor proc
Function to call for the result (or the NULL).
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:64
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.
#define GNUNET_log(kind,...)
#define GNUNET_PQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
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 int init_connection(struct Plugin *plugin)
Get a database handle.
void * cls
Closure to use for callbacks.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Time for absolute times used by GNUnet, in microseconds.
static unsigned int anonymity
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:34
struct GNUNET_PQ_ExecuteStatement GNUNET_PQ_make_try_execute(const char *sql)
Create a struct GNUNET_PQ_ExecuteStatement where errors should be tolerated.
Definition: pq_exec.c:55
struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint64(const char *name, uint64_t *u64)
uint64_t expected.
#define GNUNET_log_from(kind, comp,...)
PluginGetKey get_key
Get a particular datum matching a given hash from the datastore.
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:53
uint32_t data
The data value.
Handle to Postgres database.
Definition: pq.h:34
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_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.
struct GNUNET_PQ_PreparedStatement GNUNET_PQ_make_prepare(const char *name, const char *sql, unsigned int num_args)
Create a struct GNUNET_PQ_PreparedStatement.
Definition: pq_prepare.c:38
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
int 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:127
#define GNUNET_free(ptr)
Wrapper around free.
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:117