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  es,
176  ps);
177  if (NULL == plugin->dbh)
178  return GNUNET_SYSERR;
179  return GNUNET_OK;
180 }
181 
182 
190 static void
192  unsigned long long *estimate)
193 {
194  struct Plugin *plugin = cls;
195  uint64_t total;
196  struct GNUNET_PQ_QueryParam params[] = {
198  };
199  struct GNUNET_PQ_ResultSpec rs[] = {
201  &total),
203  };
205 
206  if (NULL == estimate)
207  return;
209  "estimate_size",
210  params,
211  rs);
213  {
214  *estimate = 0LL;
215  return;
216  }
217  *estimate = total;
218 }
219 
220 
237 static void
239  const struct GNUNET_HashCode *key,
240  bool absent,
241  uint32_t size,
242  const void *data,
243  enum GNUNET_BLOCK_Type type,
244  uint32_t priority,
245  uint32_t anonymity,
246  uint32_t replication,
248  PluginPutCont cont,
249  void *cont_cls)
250 {
251  struct Plugin *plugin = cls;
252  struct GNUNET_HashCode vhash;
254 
255  GNUNET_CRYPTO_hash (data,
256  size,
257  &vhash);
258  if (! absent)
259  {
260  struct GNUNET_PQ_QueryParam params[] = {
261  GNUNET_PQ_query_param_uint32 (&priority),
262  GNUNET_PQ_query_param_uint32 (&replication),
267  };
269  "update",
270  params);
271  if (0 > ret)
272  {
273  cont (cont_cls,
274  key,
275  size,
277  _ ("Postgress exec failure"));
278  return;
279  }
280  bool affected = (0 != ret);
281  if (affected)
282  {
283  cont (cont_cls,
284  key,
285  size,
286  GNUNET_NO,
287  NULL);
288  return;
289  }
290  }
291 
292  {
293  uint32_t utype = (uint32_t) type;
295  UINT64_MAX);
296  struct GNUNET_PQ_QueryParam params[] = {
297  GNUNET_PQ_query_param_uint32 (&replication),
299  GNUNET_PQ_query_param_uint32 (&priority),
300  GNUNET_PQ_query_param_uint32 (&anonymity),
307  };
308 
310  "put",
311  params);
312  if (0 > ret)
313  {
314  cont (cont_cls,
315  key,
316  size,
318  "Postgress exec failure");
319  return;
320  }
321  }
322  plugin->env->duc (plugin->env->cls,
325  "datastore-postgres",
326  "Stored %u bytes in database\n",
327  (unsigned int) size);
328  cont (cont_cls,
329  key,
330  size,
331  GNUNET_OK,
332  NULL);
333 }
334 
335 
340 {
344  struct Plugin *plugin;
345 
350 
354  void *proc_cls;
355 };
356 
357 
366 static void
367 process_result (void *cls,
368  PGresult *res,
369  unsigned int num_results)
370 {
371  struct ProcessResultContext *prc = cls;
372  struct Plugin *plugin = prc->plugin;
373 
374  if (0 == num_results)
375  {
376  /* no result */
378  "datastore-postgres",
379  "Ending iteration (no more results)\n");
380  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
382  return;
383  }
384  if (1 != num_results)
385  {
386  GNUNET_break (0);
387  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
389  return;
390  }
391  /* Technically we don't need the loop here, but nicer in case
392  we ever relax the condition above. */
393  for (unsigned int i = 0; i < num_results; i++)
394  {
395  int iret;
396  uint32_t rowid;
397  uint32_t utype;
398  uint32_t anonymity;
399  uint32_t replication;
400  uint32_t priority;
401  size_t size;
402  void *data;
403  struct GNUNET_TIME_Absolute expiration_time;
404  struct GNUNET_HashCode key;
405  struct GNUNET_PQ_ResultSpec rs[] = {
406  GNUNET_PQ_result_spec_uint32 ("repl", &replication),
407  GNUNET_PQ_result_spec_uint32 ("type", &utype),
408  GNUNET_PQ_result_spec_uint32 ("prio", &priority),
409  GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity),
410  GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
412  GNUNET_PQ_result_spec_variable_size ("value", &data, &size),
413  GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
415  };
416 
417  if (GNUNET_OK !=
419  rs,
420  i))
421  {
422  GNUNET_break (0);
423  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
425  return;
426  }
427 
429  "datastore-postgres",
430  "Found result of size %u bytes and type %u in database\n",
431  (unsigned int) size,
432  (unsigned int) utype);
433  iret = prc->proc (prc->proc_cls,
434  &key,
435  size,
436  data,
437  (enum GNUNET_BLOCK_Type) utype,
438  priority,
439  anonymity,
440  replication,
441  expiration_time,
442  rowid);
443  if (iret == GNUNET_NO)
444  {
445  struct GNUNET_PQ_QueryParam param[] = {
448  };
449 
451  "Processor asked for item %u to be removed.\n",
452  (unsigned int) rowid);
453  if (0 <
455  "delrow",
456  param))
457  {
459  "datastore-postgres",
460  "Deleting %u bytes from database\n",
461  (unsigned int) size);
462  plugin->env->duc (plugin->env->cls,
465  "datastore-postgres",
466  "Deleted %u bytes from database\n",
467  (unsigned int) size);
468  }
469  }
471  } /* for (i) */
472 }
473 
474 
488 static void
490  uint64_t next_uid,
491  bool random,
492  const struct GNUNET_HashCode *key,
493  enum GNUNET_BLOCK_Type type,
495  void *proc_cls)
496 {
497  struct Plugin *plugin = cls;
498  uint32_t utype = type;
499  uint16_t use_rvalue = random;
500  uint16_t use_key = NULL != key;
501  uint16_t use_type = GNUNET_BLOCK_TYPE_ANY != type;
502  uint64_t rvalue;
503  struct GNUNET_PQ_QueryParam params[] = {
504  GNUNET_PQ_query_param_uint64 (&next_uid),
506  GNUNET_PQ_query_param_uint16 (&use_rvalue),
508  GNUNET_PQ_query_param_uint16 (&use_key),
510  GNUNET_PQ_query_param_uint16 (&use_type),
512  };
513  struct ProcessResultContext prc;
515 
516  if (random)
517  {
519  UINT64_MAX);
520  next_uid = 0;
521  }
522  else
523  {
524  rvalue = 0;
525  }
526  prc.plugin = plugin;
527  prc.proc = proc;
528  prc.proc_cls = proc_cls;
529 
531  "get",
532  params,
534  &prc);
535  if (0 > res)
536  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
538 }
539 
540 
553 static void
555  uint64_t next_uid,
556  enum GNUNET_BLOCK_Type type,
558  void *proc_cls)
559 {
560  struct Plugin *plugin = cls;
561  uint32_t utype = type;
562  struct GNUNET_PQ_QueryParam params[] = {
564  GNUNET_PQ_query_param_uint64 (&next_uid),
566  };
567  struct ProcessResultContext prc;
569 
570  prc.plugin = plugin;
571  prc.proc = proc;
572  prc.proc_cls = proc_cls;
574  "select_non_anonymous",
575  params,
577  &prc);
578  if (0 > res)
579  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
581 }
582 
583 
587 struct ReplCtx
588 {
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;
661  qret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
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 
748 {
753 
757  void *proc_cls;
758 };
759 
760 
769 static void
770 process_keys (void *cls,
771  PGresult *result,
772  unsigned int num_results)
773 {
774  struct ProcessKeysContext *pkc = cls;
775 
776  for (unsigned i = 0; i < num_results; i++)
777  {
778  struct GNUNET_HashCode key;
779  struct GNUNET_PQ_ResultSpec rs[] = {
781  &key),
783  };
784 
785  if (GNUNET_OK !=
786  GNUNET_PQ_extract_result (result,
787  rs,
788  i))
789  {
790  GNUNET_break (0);
791  continue;
792  }
793  pkc->proc (pkc->proc_cls,
794  &key,
795  1);
797  }
798 }
799 
800 
808 static void
810  PluginKeyProcessor proc,
811  void *proc_cls)
812 {
813  struct Plugin *plugin = cls;
814  struct GNUNET_PQ_QueryParam params[] = {
816  };
817  struct ProcessKeysContext pkc;
818 
819  pkc.proc = proc;
820  pkc.proc_cls = proc_cls;
822  "get_keys",
823  params,
824  &process_keys,
825  &pkc);
826  proc (proc_cls,
827  NULL,
828  0);
829 }
830 
831 
837 static void
839 {
840  struct Plugin *plugin = cls;
841  struct GNUNET_PQ_ExecuteStatement es[] = {
842  GNUNET_PQ_make_execute ("DROP TABLE gn090"),
844  };
845 
846  if (GNUNET_OK !=
848  es))
850  "postgres",
851  _ ("Failed to drop table from database.\n"));
852 }
853 
854 
865 static void
867  const struct GNUNET_HashCode *key,
868  uint32_t size,
869  const void *data,
870  PluginRemoveCont cont,
871  void *cont_cls)
872 {
873  struct Plugin *plugin = cls;
875  struct GNUNET_PQ_QueryParam params[] = {
879  };
880 
882  "remove",
883  params);
884  if (0 > ret)
885  {
886  cont (cont_cls,
887  key,
888  size,
890  _ ("Postgress exec failure"));
891  return;
892  }
894  {
895  cont (cont_cls,
896  key,
897  size,
898  GNUNET_NO,
899  NULL);
900  return;
901  }
902  plugin->env->duc (plugin->env->cls,
905  "datastore-postgres",
906  "Deleted %u bytes from database\n",
907  (unsigned int) size);
908  cont (cont_cls,
909  key,
910  size,
911  GNUNET_OK,
912  NULL);
913 }
914 
915 
922 void *
924 {
927  struct Plugin *plugin;
928 
929  plugin = GNUNET_new (struct Plugin);
930  plugin->env = env;
931  if (GNUNET_OK != init_connection (plugin))
932  {
933  GNUNET_free (plugin);
934  return NULL;
935  }
937  api->cls = plugin;
939  api->put = &postgres_plugin_put;
945  api->drop = &postgres_plugin_drop;
948  "datastore-postgres",
949  _ ("Postgres database running\n"));
950  return api;
951 }
952 
953 
960 void *
962 {
964  struct Plugin *plugin = api->cls;
965 
966  GNUNET_PQ_disconnect (plugin->dbh);
967  GNUNET_free (plugin);
968  GNUNET_free (api);
969  return NULL;
970 }
971 
972 
973 /* end of plugin_datastore_postgres.c */
struct GNUNET_PQ_Context * GNUNET_PQ_connect_with_cfg(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, 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:217
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:246
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.
#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.
#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: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.
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.
#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.
#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.
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