GNUnet  0.10.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 {
52 
56  PGconn *dbh;
57 };
58 
59 
66 static int
68 {
69  struct GNUNET_PQ_ExecuteStatement es[] = {
70  /* FIXME: PostgreSQL does not have unsigned integers! This is ok for the type column because
71  * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel
72  * we do math or inequality tests, so we can't handle the entire range of uint32_t.
73  * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC.
74  * PostgreSQL also recommends against using WITH OIDS.
75  */
76  GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS gn090 ("
77  " repl INTEGER NOT NULL DEFAULT 0,"
78  " type INTEGER NOT NULL DEFAULT 0,"
79  " prio INTEGER NOT NULL DEFAULT 0,"
80  " anonLevel INTEGER NOT NULL DEFAULT 0,"
81  " expire BIGINT NOT NULL DEFAULT 0,"
82  " rvalue BIGINT NOT NULL DEFAULT 0,"
83  " hash BYTEA NOT NULL DEFAULT '',"
84  " vhash BYTEA NOT NULL DEFAULT '',"
85  " value BYTEA NOT NULL DEFAULT '')"
86  "WITH OIDS"),
87  GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)"),
88  GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_prio ON gn090 (prio)"),
89  GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_expire ON gn090 (expire)"),
90  GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_prio_anon ON gn090 (prio,anonLevel)"),
91  GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)"),
92  GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn090 (repl,rvalue)"),
93  GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_expire_hash ON gn090 (expire,hash)"),
94  GNUNET_PQ_make_execute("ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"),
95  GNUNET_PQ_make_execute("ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"),
96  GNUNET_PQ_make_execute("ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"),
98  };
99 
100 #define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid"
101  struct GNUNET_PQ_PreparedStatement ps[] = {
103  "SELECT " RESULT_COLUMNS " FROM gn090"
104  " WHERE oid >= $1::bigint AND"
105  " (rvalue >= $2 OR 0 = $3::smallint) AND"
106  " (hash = $4 OR 0 = $5::smallint) AND"
107  " (type = $6 OR 0 = $7::smallint)"
108  " ORDER BY oid ASC LIMIT 1",
109  7),
111  "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
112  "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
113  9),
114  GNUNET_PQ_make_prepare("update",
115  "UPDATE gn090"
116  " SET prio = prio + $1,"
117  " repl = repl + $2,"
118  " expire = GREATEST(expire, $3)"
119  " WHERE hash = $4 AND vhash = $5",
120  5),
121  GNUNET_PQ_make_prepare("decrepl",
122  "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
123  "WHERE oid = $1",
124  1),
125  GNUNET_PQ_make_prepare("select_non_anonymous",
126  "SELECT " RESULT_COLUMNS " FROM gn090 "
127  "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint "
128  "ORDER BY oid ASC LIMIT 1",
129  2),
130  GNUNET_PQ_make_prepare("select_expiration_order",
131  "(SELECT " RESULT_COLUMNS " FROM gn090 "
132  "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) "
133  "UNION "
134  "(SELECT " RESULT_COLUMNS " FROM gn090 "
135  "ORDER BY prio ASC LIMIT 1) "
136  "ORDER BY expire ASC LIMIT 1",
137  1),
138  GNUNET_PQ_make_prepare("select_replication_order",
139  "SELECT " RESULT_COLUMNS " FROM gn090 "
140  "ORDER BY repl DESC,RANDOM() LIMIT 1",
141  0),
142  GNUNET_PQ_make_prepare("delrow",
143  "DELETE FROM gn090 "
144  "WHERE oid=$1",
145  1),
146  GNUNET_PQ_make_prepare("remove",
147  "DELETE FROM gn090"
148  " WHERE hash = $1 AND"
149  " value = $2",
150  2),
151  GNUNET_PQ_make_prepare("get_keys",
152  "SELECT hash FROM gn090",
153  0),
154  GNUNET_PQ_make_prepare("estimate_size",
155  "SELECT CASE WHEN NOT EXISTS"
156  " (SELECT 1 FROM gn090)"
157  " THEN 0"
158  " ELSE (SELECT SUM(LENGTH(value))+256*COUNT(*) FROM gn090)"
159  "END AS total",
160  0),
162  };
163 #undef RESULT_COLUMNS
164 
165  plugin->dbh = GNUNET_PQ_connect_with_cfg(plugin->env->cfg,
166  "datastore-postgres");
167  if (NULL == plugin->dbh)
168  return GNUNET_SYSERR;
169 
170  if ((GNUNET_OK !=
172  es)) ||
173  (GNUNET_OK !=
175  ps)))
176  {
177  PQfinish(plugin->dbh);
178  plugin->dbh = NULL;
179  return GNUNET_SYSERR;
180  }
181  return GNUNET_OK;
182 }
183 
184 
192 static void
194  unsigned long long *estimate)
195 {
196  struct Plugin *plugin = cls;
197  uint64_t total;
198  struct GNUNET_PQ_QueryParam params[] = {
200  };
201  struct GNUNET_PQ_ResultSpec rs[] = {
203  &total),
205  };
207 
208  if (NULL == estimate)
209  return;
211  "estimate_size",
212  params,
213  rs);
215  {
216  *estimate = 0LL;
217  return;
218  }
219  *estimate = total;
220 }
221 
222 
239 static void
241  const struct GNUNET_HashCode *key,
242  bool absent,
243  uint32_t size,
244  const void *data,
245  enum GNUNET_BLOCK_Type type,
246  uint32_t priority,
247  uint32_t anonymity,
248  uint32_t replication,
250  PluginPutCont cont,
251  void *cont_cls)
252 {
253  struct Plugin *plugin = cls;
254  struct GNUNET_HashCode vhash;
256 
257  GNUNET_CRYPTO_hash(data,
258  size,
259  &vhash);
260  if (!absent)
261  {
262  struct GNUNET_PQ_QueryParam params[] = {
263  GNUNET_PQ_query_param_uint32(&priority),
264  GNUNET_PQ_query_param_uint32(&replication),
269  };
271  "update",
272  params);
273  if (0 > ret)
274  {
275  cont(cont_cls,
276  key,
277  size,
279  _("Postgress exec failure"));
280  return;
281  }
282  bool affected = (0 != ret);
283  if (affected)
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;
297  UINT64_MAX);
298  struct GNUNET_PQ_QueryParam params[] = {
299  GNUNET_PQ_query_param_uint32(&replication),
301  GNUNET_PQ_query_param_uint32(&priority),
302  GNUNET_PQ_query_param_uint32(&anonymity),
309  };
310 
312  "put",
313  params);
314  if (0 > ret)
315  {
316  cont(cont_cls,
317  key,
318  size,
320  "Postgress exec failure");
321  return;
322  }
323  }
324  plugin->env->duc(plugin->env->cls,
327  "datastore-postgres",
328  "Stored %u bytes in database\n",
329  (unsigned int)size);
330  cont(cont_cls,
331  key,
332  size,
333  GNUNET_OK,
334  NULL);
335 }
336 
337 
345  struct Plugin *plugin;
346 
351 
355  void *proc_cls;
356 };
357 
358 
367 static void
368 process_result(void *cls,
369  PGresult *res,
370  unsigned int num_results)
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  uint32_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[] = {
407  GNUNET_PQ_result_spec_uint32("repl", &replication),
408  GNUNET_PQ_result_spec_uint32("type", &utype),
409  GNUNET_PQ_result_spec_uint32("prio", &priority),
410  GNUNET_PQ_result_spec_uint32("anonLevel", &anonymity),
411  GNUNET_PQ_result_spec_absolute_time("expire", &expiration_time),
413  GNUNET_PQ_result_spec_variable_size("value", &data, &size),
414  GNUNET_PQ_result_spec_uint32("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,
441  replication,
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 }
474 
475 
489 static void
491  uint64_t next_uid,
492  bool random,
493  const struct GNUNET_HashCode *key,
494  enum GNUNET_BLOCK_Type type,
496  void *proc_cls)
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 GNUNET_PQ_QueryParam params[] = {
505  GNUNET_PQ_query_param_uint64(&next_uid),
507  GNUNET_PQ_query_param_uint16(&use_rvalue),
511  GNUNET_PQ_query_param_uint16(&use_type),
513  };
514  struct ProcessResultContext prc;
516 
517  if (random)
518  {
520  UINT64_MAX);
521  next_uid = 0;
522  }
523  else
524  {
525  rvalue = 0;
526  }
527  prc.plugin = plugin;
528  prc.proc = proc;
529  prc.proc_cls = proc_cls;
530 
532  "get",
533  params,
535  &prc);
536  if (0 > res)
537  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
539 }
540 
541 
554 static void
556  uint64_t next_uid,
557  enum GNUNET_BLOCK_Type type,
559  void *proc_cls)
560 {
561  struct Plugin *plugin = cls;
562  uint32_t utype = type;
563  struct GNUNET_PQ_QueryParam params[] = {
565  GNUNET_PQ_query_param_uint64(&next_uid),
567  };
568  struct ProcessResultContext prc;
570 
571  prc.plugin = plugin;
572  prc.proc = proc;
573  prc.proc_cls = proc_cls;
575  "select_non_anonymous",
576  params,
578  &prc);
579  if (0 > res)
580  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
582 }
583 
584 
588 struct ReplCtx {
592  struct Plugin *plugin;
593 
598 
602  void *proc_cls;
603 };
604 
605 
627 static int
628 repl_proc(void *cls,
629  const struct GNUNET_HashCode *key,
630  uint32_t size,
631  const void *data,
632  enum GNUNET_BLOCK_Type type,
633  uint32_t priority,
634  uint32_t anonymity,
635  uint32_t replication,
637  uint64_t uid)
638 {
639  struct ReplCtx *rc = cls;
640  struct Plugin *plugin = rc->plugin;
641  int ret;
642  uint32_t oid = (uint32_t)uid;
643  struct GNUNET_PQ_QueryParam params[] = {
646  };
647  enum GNUNET_DB_QueryStatus qret;
648 
649  ret = rc->proc(rc->proc_cls,
650  key,
651  size,
652  data,
653  type,
654  priority,
655  anonymity,
656  replication,
657  expiration,
658  uid);
659  if (NULL == key)
660  return ret;
662  "decrepl",
663  params);
664  if (0 > qret)
665  return GNUNET_SYSERR;
666  return ret;
667 }
668 
669 
681 static void
684  void *proc_cls)
685 {
686  struct Plugin *plugin = cls;
687  struct GNUNET_PQ_QueryParam params[] = {
689  };
690  struct ReplCtx rc;
691  struct ProcessResultContext prc;
693 
694  rc.plugin = plugin;
695  rc.proc = proc;
696  rc.proc_cls = proc_cls;
697  prc.plugin = plugin;
698  prc.proc = &repl_proc;
699  prc.proc_cls = &rc;
701  "select_replication_order",
702  params,
704  &prc);
705  if (0 > res)
706  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
708 }
709 
710 
719 static void
722  void *proc_cls)
723 {
724  struct Plugin *plugin = cls;
725  struct GNUNET_TIME_Absolute now;
726  struct GNUNET_PQ_QueryParam params[] = {
729  };
730  struct ProcessResultContext prc;
731 
732  now = GNUNET_TIME_absolute_get();
733  prc.plugin = plugin;
734  prc.proc = proc;
735  prc.proc_cls = proc_cls;
737  "select_expiration_order",
738  params,
740  &prc);
741 }
742 
743 
752 
756  void *proc_cls;
757 };
758 
759 
768 static void
769 process_keys(void *cls,
770  PGresult *result,
771  unsigned int num_results)
772 {
773  struct ProcessKeysContext *pkc = cls;
774 
775  for (unsigned i = 0; i < num_results; i++)
776  {
777  struct GNUNET_HashCode key;
778  struct GNUNET_PQ_ResultSpec rs[] = {
780  &key),
782  };
783 
784  if (GNUNET_OK !=
786  rs,
787  i))
788  {
789  GNUNET_break(0);
790  continue;
791  }
792  pkc->proc(pkc->proc_cls,
793  &key,
794  1);
796  }
797 }
798 
799 
807 static void
809  PluginKeyProcessor proc,
810  void *proc_cls)
811 {
812  struct Plugin *plugin = cls;
813  struct GNUNET_PQ_QueryParam params[] = {
815  };
816  struct ProcessKeysContext pkc;
817 
818  pkc.proc = proc;
819  pkc.proc_cls = proc_cls;
821  "get_keys",
822  params,
823  &process_keys,
824  &pkc);
825  proc(proc_cls,
826  NULL,
827  0);
828 }
829 
830 
836 static void
838 {
839  struct Plugin *plugin = cls;
840  struct GNUNET_PQ_ExecuteStatement es[] = {
841  GNUNET_PQ_make_execute("DROP TABLE gn090"),
843  };
844 
845  if (GNUNET_OK !=
847  es))
849  "postgres",
850  _("Failed to drop table from database.\n"));
851 }
852 
853 
864 static void
866  const struct GNUNET_HashCode *key,
867  uint32_t size,
868  const void *data,
869  PluginRemoveCont cont,
870  void *cont_cls)
871 {
872  struct Plugin *plugin = cls;
874  struct GNUNET_PQ_QueryParam params[] = {
878  };
879 
881  "remove",
882  params);
883  if (0 > ret)
884  {
885  cont(cont_cls,
886  key,
887  size,
889  _("Postgress exec failure"));
890  return;
891  }
893  {
894  cont(cont_cls,
895  key,
896  size,
897  GNUNET_NO,
898  NULL);
899  return;
900  }
901  plugin->env->duc(plugin->env->cls,
904  "datastore-postgres",
905  "Deleted %u bytes from database\n",
906  (unsigned int)size);
907  cont(cont_cls,
908  key,
909  size,
910  GNUNET_OK,
911  NULL);
912 }
913 
914 
921 void *
923 {
926  struct Plugin *plugin;
927 
928  plugin = GNUNET_new(struct Plugin);
929  plugin->env = env;
930  if (GNUNET_OK != init_connection(plugin))
931  {
932  GNUNET_free(plugin);
933  return NULL;
934  }
936  api->cls = plugin;
938  api->put = &postgres_plugin_put;
944  api->drop = &postgres_plugin_drop;
947  "datastore-postgres",
948  _("Postgres database running\n"));
949  return api;
950 }
951 
952 
959 void *
961 {
963  struct Plugin *plugin = api->cls;
964 
965  PQfinish(plugin->dbh);
966  GNUNET_free(plugin);
967  GNUNET_free(api);
968  return NULL;
969 }
970 
971 /* 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 * proc_cls
Closure for proc.
PluginGetType get_zero_anonymity
Get datum (of the specified type) with anonymity level zero.
static char * expiration
Credential TTL.
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:37
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.
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 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.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct Plugin * plugin
The plugin handle.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_singleton_select(PGconn *connection, 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:241
#define GNUNET_new(type)
Allocate a struct or union of the given type.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_non_select(PGconn *connection, 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:151
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;.
static int ret
Final status code.
Definition: gnunet-arm.c:89
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:46
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
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:94
int GNUNET_PQ_prepare_statements(PGconn *connection, const struct GNUNET_PQ_PreparedStatement *ps)
Request creation of prepared statements ps from Postgres.
Definition: pq_prepare.c:63
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.
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:44
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 int res
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.
#define GNUNET_PQ_result_spec_auto_from_type(name, dst)
We expect a fixed-size result, with size determined by the type of * dst
PGconn * GNUNET_PQ_connect_with_cfg(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Connect to a postgres database using the configuration option "CONFIG" in section.
Definition: pq_connect.c:112
#define GNUNET_PQ_PREPARED_STATEMENT_END
Terminator for prepared statement list.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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.
int GNUNET_PQ_exec_statements(PGconn *connection, const struct GNUNET_PQ_ExecuteStatement *es)
Request execution of an array of statements es from Postgres.
Definition: pq_exec.c:77
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:57
#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
PGconn * 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:63
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:56
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:52
uint32_t data
The data value.
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_multi_select(PGconn *connection, 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:194
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:39
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:144
#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:121