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  * PostgreSQL also recommends against using WITH OIDS.
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"),
88  "CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)"),
90  "CREATE INDEX IF NOT EXISTS idx_prio ON gn090 (prio)"),
92  "CREATE INDEX IF NOT EXISTS idx_expire ON gn090 (expire)"),
94  "CREATE INDEX IF NOT EXISTS idx_prio_anon ON gn090 (prio,anonLevel)"),
96  "CREATE INDEX IF NOT EXISTS idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)"),
98  "CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn090 (repl,rvalue)"),
100  "CREATE INDEX IF NOT EXISTS idx_expire_hash ON gn090 (expire,hash)"),
102  "ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"),
103  GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"),
104  GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"),
106  };
107 
108 #define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid"
109  struct GNUNET_PQ_PreparedStatement ps[] = {
110  GNUNET_PQ_make_prepare ("get",
111  "SELECT " RESULT_COLUMNS " FROM gn090"
112  " WHERE oid >= $1::bigint AND"
113  " (rvalue >= $2 OR 0 = $3::smallint) AND"
114  " (hash = $4 OR 0 = $5::smallint) AND"
115  " (type = $6 OR 0 = $7::smallint)"
116  " ORDER BY oid ASC LIMIT 1",
117  7),
118  GNUNET_PQ_make_prepare ("put",
119  "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
120  "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
121  9),
122  GNUNET_PQ_make_prepare ("update",
123  "UPDATE gn090"
124  " SET prio = prio + $1,"
125  " repl = repl + $2,"
126  " expire = GREATEST(expire, $3)"
127  " WHERE hash = $4 AND vhash = $5",
128  5),
129  GNUNET_PQ_make_prepare ("decrepl",
130  "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
131  "WHERE oid = $1",
132  1),
133  GNUNET_PQ_make_prepare ("select_non_anonymous",
134  "SELECT " RESULT_COLUMNS " FROM gn090 "
135  "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint "
136  "ORDER BY oid ASC LIMIT 1",
137  2),
138  GNUNET_PQ_make_prepare ("select_expiration_order",
139  "(SELECT " RESULT_COLUMNS " FROM gn090 "
140  "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) "
141  "UNION "
142  "(SELECT " RESULT_COLUMNS " FROM gn090 "
143  "ORDER BY prio ASC LIMIT 1) "
144  "ORDER BY expire ASC LIMIT 1",
145  1),
146  GNUNET_PQ_make_prepare ("select_replication_order",
147  "SELECT " RESULT_COLUMNS " FROM gn090 "
148  "ORDER BY repl DESC,RANDOM() LIMIT 1",
149  0),
150  GNUNET_PQ_make_prepare ("delrow",
151  "DELETE FROM gn090 "
152  "WHERE oid=$1",
153  1),
154  GNUNET_PQ_make_prepare ("remove",
155  "DELETE FROM gn090"
156  " WHERE hash = $1 AND"
157  " value = $2",
158  2),
159  GNUNET_PQ_make_prepare ("get_keys",
160  "SELECT hash FROM gn090",
161  0),
162  GNUNET_PQ_make_prepare ("estimate_size",
163  "SELECT CASE WHEN NOT EXISTS"
164  " (SELECT 1 FROM gn090)"
165  " THEN 0"
166  " ELSE (SELECT SUM(LENGTH(value))+256*COUNT(*) FROM gn090)"
167  "END AS total",
168  0),
170  };
171 #undef RESULT_COLUMNS
172 
173  plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg,
174  "datastore-postgres",
175  NULL,
176  es,
177  ps);
178  if (NULL == plugin->dbh)
179  return GNUNET_SYSERR;
180  return GNUNET_OK;
181 }
182 
183 
191 static void
193  unsigned long long *estimate)
194 {
195  struct Plugin *plugin = cls;
196  uint64_t total;
197  struct GNUNET_PQ_QueryParam params[] = {
199  };
200  struct GNUNET_PQ_ResultSpec rs[] = {
202  &total),
204  };
206 
207  if (NULL == estimate)
208  return;
210  "estimate_size",
211  params,
212  rs);
214  {
215  *estimate = 0LL;
216  return;
217  }
218  *estimate = total;
219 }
220 
221 
238 static void
240  const struct GNUNET_HashCode *key,
241  bool absent,
242  uint32_t size,
243  const void *data,
244  enum GNUNET_BLOCK_Type type,
245  uint32_t priority,
246  uint32_t anonymity,
247  uint32_t replication,
249  PluginPutCont cont,
250  void *cont_cls)
251 {
252  struct Plugin *plugin = cls;
253  struct GNUNET_HashCode vhash;
255 
256  GNUNET_CRYPTO_hash (data,
257  size,
258  &vhash);
259  if (! absent)
260  {
261  struct GNUNET_PQ_QueryParam params[] = {
262  GNUNET_PQ_query_param_uint32 (&priority),
263  GNUNET_PQ_query_param_uint32 (&replication),
268  };
270  "update",
271  params);
272  if (0 > ret)
273  {
274  cont (cont_cls,
275  key,
276  size,
278  _ ("Postgress exec failure"));
279  return;
280  }
281  bool affected = (0 != ret);
282  if (affected)
283  {
284  cont (cont_cls,
285  key,
286  size,
287  GNUNET_NO,
288  NULL);
289  return;
290  }
291  }
292 
293  {
294  uint32_t utype = (uint32_t) type;
296  UINT64_MAX);
297  struct GNUNET_PQ_QueryParam params[] = {
298  GNUNET_PQ_query_param_uint32 (&replication),
300  GNUNET_PQ_query_param_uint32 (&priority),
301  GNUNET_PQ_query_param_uint32 (&anonymity),
308  };
309 
311  "put",
312  params);
313  if (0 > ret)
314  {
315  cont (cont_cls,
316  key,
317  size,
319  "Postgress 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 }
335 
336 
341 {
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),
509  GNUNET_PQ_query_param_uint16 (&use_key),
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
589 {
593  struct Plugin *plugin;
594 
599 
603  void *proc_cls;
604 };
605 
606 
628 static int
629 repl_proc (void *cls,
630  const struct GNUNET_HashCode *key,
631  uint32_t size,
632  const void *data,
633  enum GNUNET_BLOCK_Type type,
634  uint32_t priority,
635  uint32_t anonymity,
636  uint32_t replication,
638  uint64_t uid)
639 {
640  struct ReplCtx *rc = cls;
641  struct Plugin *plugin = rc->plugin;
642  int ret;
643  uint32_t oid = (uint32_t) uid;
644  struct GNUNET_PQ_QueryParam params[] = {
647  };
648  enum GNUNET_DB_QueryStatus qret;
649 
650  ret = rc->proc (rc->proc_cls,
651  key,
652  size,
653  data,
654  type,
655  priority,
656  anonymity,
657  replication,
658  expiration,
659  uid);
660  if (NULL == key)
661  return ret;
662  qret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
663  "decrepl",
664  params);
665  if (0 > qret)
666  return GNUNET_SYSERR;
667  return ret;
668 }
669 
670 
682 static void
685  void *proc_cls)
686 {
687  struct Plugin *plugin = cls;
688  struct GNUNET_PQ_QueryParam params[] = {
690  };
691  struct ReplCtx rc;
692  struct ProcessResultContext prc;
694 
695  rc.plugin = plugin;
696  rc.proc = proc;
697  rc.proc_cls = proc_cls;
698  prc.plugin = plugin;
699  prc.proc = &repl_proc;
700  prc.proc_cls = &rc;
702  "select_replication_order",
703  params,
705  &prc);
706  if (0 > res)
707  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
709 }
710 
711 
720 static void
723  void *proc_cls)
724 {
725  struct Plugin *plugin = cls;
726  struct GNUNET_TIME_Absolute now;
727  struct GNUNET_PQ_QueryParam params[] = {
730  };
731  struct ProcessResultContext prc;
732 
733  now = GNUNET_TIME_absolute_get ();
734  prc.plugin = plugin;
735  prc.proc = proc;
736  prc.proc_cls = proc_cls;
738  "select_expiration_order",
739  params,
741  &prc);
742 }
743 
744 
749 {
754 
758  void *proc_cls;
759 };
760 
761 
770 static void
771 process_keys (void *cls,
772  PGresult *result,
773  unsigned int num_results)
774 {
775  struct ProcessKeysContext *pkc = cls;
776 
777  for (unsigned i = 0; i < num_results; i++)
778  {
779  struct GNUNET_HashCode key;
780  struct GNUNET_PQ_ResultSpec rs[] = {
782  &key),
784  };
785 
786  if (GNUNET_OK !=
787  GNUNET_PQ_extract_result (result,
788  rs,
789  i))
790  {
791  GNUNET_break (0);
792  continue;
793  }
794  pkc->proc (pkc->proc_cls,
795  &key,
796  1);
798  }
799 }
800 
801 
809 static void
811  PluginKeyProcessor proc,
812  void *proc_cls)
813 {
814  struct Plugin *plugin = cls;
815  struct GNUNET_PQ_QueryParam params[] = {
817  };
818  struct ProcessKeysContext pkc;
819 
820  pkc.proc = proc;
821  pkc.proc_cls = proc_cls;
823  "get_keys",
824  params,
825  &process_keys,
826  &pkc);
827  proc (proc_cls,
828  NULL,
829  0);
830 }
831 
832 
838 static void
840 {
841  struct Plugin *plugin = cls;
842  struct GNUNET_PQ_ExecuteStatement es[] = {
843  GNUNET_PQ_make_execute ("DROP TABLE gn090"),
845  };
846 
847  if (GNUNET_OK !=
849  es))
851  "postgres",
852  _ ("Failed to drop table from database.\n"));
853 }
854 
855 
866 static void
868  const struct GNUNET_HashCode *key,
869  uint32_t size,
870  const void *data,
871  PluginRemoveCont cont,
872  void *cont_cls)
873 {
874  struct Plugin *plugin = cls;
876  struct GNUNET_PQ_QueryParam params[] = {
880  };
881 
883  "remove",
884  params);
885  if (0 > ret)
886  {
887  cont (cont_cls,
888  key,
889  size,
891  _ ("Postgress exec failure"));
892  return;
893  }
895  {
896  cont (cont_cls,
897  key,
898  size,
899  GNUNET_NO,
900  NULL);
901  return;
902  }
903  plugin->env->duc (plugin->env->cls,
906  "datastore-postgres",
907  "Deleted %u bytes from database\n",
908  (unsigned int) size);
909  cont (cont_cls,
910  key,
911  size,
912  GNUNET_OK,
913  NULL);
914 }
915 
916 
923 void *
925 {
928  struct Plugin *plugin;
929 
930  plugin = GNUNET_new (struct Plugin);
931  plugin->env = env;
932  if (GNUNET_OK != init_connection (plugin))
933  {
934  GNUNET_free (plugin);
935  return NULL;
936  }
938  api->cls = plugin;
940  api->put = &postgres_plugin_put;
946  api->drop = &postgres_plugin_drop;
949  "datastore-postgres",
950  _ ("Postgres database running\n"));
951  return api;
952 }
953 
954 
961 void *
963 {
965  struct Plugin *plugin = api->cls;
966 
967  GNUNET_PQ_disconnect (plugin->dbh);
968  GNUNET_free (plugin);
969  GNUNET_free (api);
970  return NULL;
971 }
972 
973 
974 /* 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:512
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:96
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:465
#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:151
#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:130