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
48 {
53 
57  PGconn *dbh;
58 
59 };
60 
61 
68 static int
70 {
71  struct GNUNET_PQ_ExecuteStatement es[] = {
72  /* FIXME: PostgreSQL does not have unsigned integers! This is ok for the type column because
73  * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel
74  * we do math or inequality tests, so we can't handle the entire range of uint32_t.
75  * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC.
76  * PostgreSQL also recommends against using WITH OIDS.
77  */
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  "WITH OIDS"),
89  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)"),
90  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_prio ON gn090 (prio)"),
91  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_expire ON gn090 (expire)"),
92  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_prio_anon ON gn090 (prio,anonLevel)"),
93  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)"),
94  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn090 (repl,rvalue)"),
95  GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_expire_hash ON gn090 (expire,hash)"),
96  GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"),
97  GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"),
98  GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"),
100  };
101 #define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid"
102  struct GNUNET_PQ_PreparedStatement ps[] = {
103  GNUNET_PQ_make_prepare ("get",
104  "SELECT " RESULT_COLUMNS " FROM gn090"
105  " WHERE oid >= $1::bigint AND"
106  " (rvalue >= $2 OR 0 = $3::smallint) AND"
107  " (hash = $4 OR 0 = $5::smallint) AND"
108  " (type = $6 OR 0 = $7::smallint)"
109  " ORDER BY oid ASC LIMIT 1",
110  7),
111  GNUNET_PQ_make_prepare ("put",
112  "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
113  "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
114  9),
115  GNUNET_PQ_make_prepare ("update",
116  "UPDATE gn090"
117  " SET prio = prio + $1,"
118  " repl = repl + $2,"
119  " expire = GREATEST(expire, $3)"
120  " WHERE hash = $4 AND vhash = $5",
121  5),
122  GNUNET_PQ_make_prepare ("decrepl",
123  "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
124  "WHERE oid = $1",
125  1),
126  GNUNET_PQ_make_prepare ("select_non_anonymous",
127  "SELECT " RESULT_COLUMNS " FROM gn090 "
128  "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint "
129  "ORDER BY oid ASC LIMIT 1",
130  2),
131  GNUNET_PQ_make_prepare ("select_expiration_order",
132  "(SELECT " RESULT_COLUMNS " FROM gn090 "
133  "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) "
134  "UNION "
135  "(SELECT " RESULT_COLUMNS " FROM gn090 "
136  "ORDER BY prio ASC LIMIT 1) "
137  "ORDER BY expire ASC LIMIT 1",
138  1),
139  GNUNET_PQ_make_prepare ("select_replication_order",
140  "SELECT " RESULT_COLUMNS " FROM gn090 "
141  "ORDER BY repl DESC,RANDOM() LIMIT 1",
142  0),
143  GNUNET_PQ_make_prepare ("delrow",
144  "DELETE FROM gn090 "
145  "WHERE oid=$1",
146  1),
147  GNUNET_PQ_make_prepare ("remove",
148  "DELETE FROM gn090"
149  " WHERE hash = $1 AND"
150  " value = $2",
151  2),
152  GNUNET_PQ_make_prepare ("get_keys",
153  "SELECT hash FROM gn090",
154  0),
155  GNUNET_PQ_make_prepare ("estimate_size",
156  "SELECT CASE WHEN NOT EXISTS"
157  " (SELECT 1 FROM gn090)"
158  " THEN 0"
159  " ELSE (SELECT SUM(LENGTH(value))+256*COUNT(*) FROM gn090)"
160  "END AS total",
161  0),
163  };
164 #undef RESULT_COLUMNS
165 
166  plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg,
167  "datastore-postgres");
168  if (NULL == plugin->dbh)
169  return GNUNET_SYSERR;
170 
171  if ( (GNUNET_OK !=
173  es)) ||
174  (GNUNET_OK !=
176  ps)) )
177  {
178  PQfinish (plugin->dbh);
179  plugin->dbh = NULL;
180  return GNUNET_SYSERR;
181  }
182  return GNUNET_OK;
183 }
184 
185 
193 static void
195  unsigned long long *estimate)
196 {
197  struct Plugin *plugin = cls;
198  uint64_t total;
199  struct GNUNET_PQ_QueryParam params[] = {
201  };
202  struct GNUNET_PQ_ResultSpec rs[] = {
204  &total),
206  };
208 
209  if (NULL == estimate)
210  return;
212  "estimate_size",
213  params,
214  rs);
216  {
217  *estimate = 0LL;
218  return;
219  }
220  *estimate = total;
221 }
222 
223 
240 static void
242  const struct GNUNET_HashCode *key,
243  bool absent,
244  uint32_t size,
245  const void *data,
246  enum GNUNET_BLOCK_Type type,
247  uint32_t priority,
248  uint32_t anonymity,
249  uint32_t replication,
251  PluginPutCont cont,
252  void *cont_cls)
253 {
254  struct Plugin *plugin = cls;
255  struct GNUNET_HashCode vhash;
257 
258  GNUNET_CRYPTO_hash (data,
259  size,
260  &vhash);
261  if (! absent)
262  {
263  struct GNUNET_PQ_QueryParam params[] = {
264  GNUNET_PQ_query_param_uint32 (&priority),
265  GNUNET_PQ_query_param_uint32 (&replication),
270  };
272  "update",
273  params);
274  if (0 > ret)
275  {
276  cont (cont_cls,
277  key,
278  size,
280  _("Postgress exec failure"));
281  return;
282  }
283  bool affected = (0 != ret);
284  if (affected)
285  {
286  cont (cont_cls,
287  key,
288  size,
289  GNUNET_NO,
290  NULL);
291  return;
292  }
293  }
294 
295  {
296  uint32_t utype = (uint32_t) type;
298  UINT64_MAX);
299  struct GNUNET_PQ_QueryParam params[] = {
300  GNUNET_PQ_query_param_uint32 (&replication),
302  GNUNET_PQ_query_param_uint32 (&priority),
303  GNUNET_PQ_query_param_uint32 (&anonymity),
310  };
311 
313  "put",
314  params);
315  if (0 > ret)
316  {
317  cont (cont_cls,
318  key,
319  size,
321  "Postgress exec failure");
322  return;
323  }
324  }
325  plugin->env->duc (plugin->env->cls,
328  "datastore-postgres",
329  "Stored %u bytes in database\n",
330  (unsigned int) size);
331  cont (cont_cls,
332  key,
333  size,
334  GNUNET_OK,
335  NULL);
336 }
337 
338 
343 {
344 
348  struct Plugin *plugin;
349 
354 
358  void *proc_cls;
359 
360 };
361 
362 
371 static void
372 process_result (void *cls,
373  PGresult *res,
374  unsigned int num_results)
375 {
376  struct ProcessResultContext *prc = cls;
377  struct Plugin *plugin = prc->plugin;
378 
379  if (0 == num_results)
380  {
381  /* no result */
383  "datastore-postgres",
384  "Ending iteration (no more results)\n");
385  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
387  return;
388  }
389  if (1 != num_results)
390  {
391  GNUNET_break (0);
392  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
394  return;
395  }
396  /* Technically we don't need the loop here, but nicer in case
397  we ever relax the condition above. */
398  for (unsigned int i=0;i<num_results;i++)
399  {
400  int iret;
401  uint32_t rowid;
402  uint32_t utype;
403  uint32_t anonymity;
404  uint32_t replication;
405  uint32_t priority;
406  size_t size;
407  void *data;
408  struct GNUNET_TIME_Absolute expiration_time;
409  struct GNUNET_HashCode key;
410  struct GNUNET_PQ_ResultSpec rs[] = {
411  GNUNET_PQ_result_spec_uint32 ("repl", &replication),
412  GNUNET_PQ_result_spec_uint32 ("type", &utype),
413  GNUNET_PQ_result_spec_uint32 ("prio", &priority),
414  GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity),
415  GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
417  GNUNET_PQ_result_spec_variable_size ("value", &data, &size),
418  GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
420  };
421 
422  if (GNUNET_OK !=
424  rs,
425  i))
426  {
427  GNUNET_break (0);
428  prc->proc (prc->proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
430  return;
431  }
432 
434  "datastore-postgres",
435  "Found result of size %u bytes and type %u in database\n",
436  (unsigned int) size,
437  (unsigned int) utype);
438  iret = prc->proc (prc->proc_cls,
439  &key,
440  size,
441  data,
442  (enum GNUNET_BLOCK_Type) utype,
443  priority,
444  anonymity,
445  replication,
446  expiration_time,
447  rowid);
448  if (iret == GNUNET_NO)
449  {
450  struct GNUNET_PQ_QueryParam param[] = {
453  };
454 
456  "Processor asked for item %u to be removed.\n",
457  (unsigned int) rowid);
458  if (0 <
460  "delrow",
461  param))
462  {
464  "datastore-postgres",
465  "Deleting %u bytes from database\n",
466  (unsigned int) size);
467  plugin->env->duc (plugin->env->cls,
470  "datastore-postgres",
471  "Deleted %u bytes from database\n",
472  (unsigned int) size);
473  }
474  }
476  } /* for (i) */
477 }
478 
479 
493 static void
495  uint64_t next_uid,
496  bool random,
497  const struct GNUNET_HashCode *key,
498  enum GNUNET_BLOCK_Type type,
500  void *proc_cls)
501 {
502  struct Plugin *plugin = cls;
503  uint32_t utype = type;
504  uint16_t use_rvalue = random;
505  uint16_t use_key = NULL != key;
506  uint16_t use_type = GNUNET_BLOCK_TYPE_ANY != type;
507  uint64_t rvalue;
508  struct GNUNET_PQ_QueryParam params[] = {
509  GNUNET_PQ_query_param_uint64 (&next_uid),
511  GNUNET_PQ_query_param_uint16 (&use_rvalue),
513  GNUNET_PQ_query_param_uint16 (&use_key),
515  GNUNET_PQ_query_param_uint16 (&use_type),
517  };
518  struct ProcessResultContext prc;
520 
521  if (random)
522  {
524  UINT64_MAX);
525  next_uid = 0;
526  }
527  else
528  {
529  rvalue = 0;
530  }
531  prc.plugin = plugin;
532  prc.proc = proc;
533  prc.proc_cls = proc_cls;
534 
536  "get",
537  params,
539  &prc);
540  if (0 > res)
541  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
543 }
544 
545 
558 static void
560  uint64_t next_uid,
561  enum GNUNET_BLOCK_Type type,
563  void *proc_cls)
564 {
565  struct Plugin *plugin = cls;
566  uint32_t utype = type;
567  struct GNUNET_PQ_QueryParam params[] = {
569  GNUNET_PQ_query_param_uint64 (&next_uid),
571  };
572  struct ProcessResultContext prc;
574 
575  prc.plugin = plugin;
576  prc.proc = proc;
577  prc.proc_cls = proc_cls;
579  "select_non_anonymous",
580  params,
582  &prc);
583  if (0 > res)
584  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
586 }
587 
588 
592 struct ReplCtx
593 {
594 
598  struct Plugin *plugin;
599 
604 
608  void *proc_cls;
609 };
610 
611 
633 static int
634 repl_proc (void *cls,
635  const struct GNUNET_HashCode *key,
636  uint32_t size,
637  const void *data,
638  enum GNUNET_BLOCK_Type type,
639  uint32_t priority,
640  uint32_t anonymity,
641  uint32_t replication,
643  uint64_t uid)
644 {
645  struct ReplCtx *rc = cls;
646  struct Plugin *plugin = rc->plugin;
647  int ret;
648  uint32_t oid = (uint32_t) uid;
649  struct GNUNET_PQ_QueryParam params[] = {
652  };
653  enum GNUNET_DB_QueryStatus qret;
654 
655  ret = rc->proc (rc->proc_cls,
656  key,
657  size,
658  data,
659  type,
660  priority,
661  anonymity,
662  replication,
663  expiration,
664  uid);
665  if (NULL == key)
666  return ret;
667  qret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
668  "decrepl",
669  params);
670  if (0 > qret)
671  return GNUNET_SYSERR;
672  return ret;
673 }
674 
675 
687 static void
690  void *proc_cls)
691 {
692  struct Plugin *plugin = cls;
693  struct GNUNET_PQ_QueryParam params[] = {
695  };
696  struct ReplCtx rc;
697  struct ProcessResultContext prc;
699 
700  rc.plugin = plugin;
701  rc.proc = proc;
702  rc.proc_cls = proc_cls;
703  prc.plugin = plugin;
704  prc.proc = &repl_proc;
705  prc.proc_cls = &rc;
707  "select_replication_order",
708  params,
710  &prc);
711  if (0 > res)
712  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0,
714 }
715 
716 
725 static void
728  void *proc_cls)
729 {
730  struct Plugin *plugin = cls;
731  struct GNUNET_TIME_Absolute now;
732  struct GNUNET_PQ_QueryParam params[] = {
735  };
736  struct ProcessResultContext prc;
737 
738  now = GNUNET_TIME_absolute_get ();
739  prc.plugin = plugin;
740  prc.proc = proc;
741  prc.proc_cls = proc_cls;
743  "select_expiration_order",
744  params,
746  &prc);
747 }
748 
749 
754 {
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  PQfinish (plugin->dbh);
974  GNUNET_free (plugin);
975  GNUNET_free (api);
976  return NULL;
977 }
978 
979 /* 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:81
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:78
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:47
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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:96
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:79
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:58
#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:53
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