GNUnet  0.10.x
plugin_datacache_sqlite.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2006, 2009, 2015 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"
27 #include "gnunet_util_lib.h"
29 #include "gnunet_sq_lib.h"
30 #include <sqlite3.h>
31 
32 #define LOG(kind, ...) GNUNET_log_from(kind, "datacache-sqlite", __VA_ARGS__)
33 
34 #define LOG_STRERROR_FILE(kind, op, fn) \
35  GNUNET_log_from_strerror_file(kind, "datacache-sqlite", op, fn)
36 
37 
42 #define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36)
43 
47 struct Plugin {
52 
56  sqlite3 *dbh;
57 
61  char *fn;
62 
66  sqlite3_stmt *insert_stmt;
67 
71  sqlite3_stmt *get_count_stmt;
72 
76  sqlite3_stmt *get_stmt;
77 
81  sqlite3_stmt *del_select_stmt;
82 
86  sqlite3_stmt *del_expired_stmt;
87 
91  sqlite3_stmt *del_stmt;
92 
96  sqlite3_stmt *get_random_stmt;
97 
101  sqlite3_stmt *get_closest_stmt;
102 
106  unsigned int num_items;
107 };
108 
109 
118 #define LOG_SQLITE(db, level, cmd) \
119  do \
120  { \
121  LOG(level, \
122  _("`%s' failed at %s:%d with error: %s\n"), \
123  cmd, \
124  __FILE__, \
125  __LINE__, \
126  sqlite3_errmsg(db)); \
127  } while (0)
128 
129 
136 #define SQLITE3_EXEC(db, cmd) \
137  do \
138  { \
139  emsg = NULL; \
140  if (SQLITE_OK != sqlite3_exec(db, cmd, NULL, NULL, &emsg)) \
141  { \
142  LOG(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, \
143  _("`%s' failed at %s:%d with error: %s\n"), \
144  "sqlite3_exec", \
145  __FILE__, \
146  __LINE__, \
147  emsg); \
148  sqlite3_free(emsg); \
149  } \
150  } while (0)
151 
152 
161 static int
162 sq_prepare(sqlite3 *dbh,
163  const char *zSql, /* SQL statement, UTF-8 encoded */
164  sqlite3_stmt **ppStmt)
165 { /* OUT: Statement handle */
166  char *dummy;
167 
168  return sqlite3_prepare(dbh,
169  zSql,
170  strlen(zSql),
171  ppStmt,
172  (const char **)&dummy);
173 }
174 
175 
190 static ssize_t
192  const struct GNUNET_HashCode *key,
193  uint32_t xor_distance,
194  size_t size,
195  const char *data,
196  enum GNUNET_BLOCK_Type type,
197  struct GNUNET_TIME_Absolute discard_time,
198  unsigned int path_info_len,
199  const struct GNUNET_PeerIdentity *path_info)
200 {
201  struct Plugin *plugin = cls;
202  uint32_t type32 = type;
203  struct GNUNET_SQ_QueryParam params[] =
204  { GNUNET_SQ_query_param_uint32(&type32),
207  GNUNET_SQ_query_param_uint32(&xor_distance),
210  path_info_len *
211  sizeof(struct GNUNET_PeerIdentity)),
213 
215  "Processing PUT of %u bytes with key `%s' and expiration %s\n",
216  (unsigned int)size,
217  GNUNET_h2s(key),
219  discard_time),
220  GNUNET_YES));
221  if (GNUNET_OK != GNUNET_SQ_bind(plugin->insert_stmt, params))
222  {
223  LOG_SQLITE(plugin->dbh,
225  "sqlite3_bind_xxx");
226  GNUNET_SQ_reset(plugin->dbh, plugin->insert_stmt);
227  return -1;
228  }
229  if (SQLITE_DONE != sqlite3_step(plugin->insert_stmt))
230  {
231  LOG_SQLITE(plugin->dbh,
233  "sqlite3_step");
234  GNUNET_SQ_reset(plugin->dbh, plugin->insert_stmt);
235  return -1;
236  }
237  plugin->num_items++;
238  GNUNET_SQ_reset(plugin->dbh, plugin->insert_stmt);
239  return size + OVERHEAD;
240 }
241 
242 
254 static unsigned int
256  const struct GNUNET_HashCode *key,
257  enum GNUNET_BLOCK_Type type,
259  void *iter_cls)
260 {
261  struct Plugin *plugin = cls;
262  uint32_t type32 = type;
263  struct GNUNET_TIME_Absolute now;
264  struct GNUNET_TIME_Absolute exp;
265  size_t size;
266  void *dat;
267  unsigned int cnt;
268  uint32_t off;
269  unsigned int total;
270  size_t psize;
271  struct GNUNET_PeerIdentity *path;
272  struct GNUNET_SQ_QueryParam params_count[] =
277  struct GNUNET_SQ_QueryParam params_select[] =
283  struct GNUNET_SQ_ResultSpec rs[] =
286  GNUNET_SQ_result_spec_variable_size((void **)&path, &psize),
288 
289  now = GNUNET_TIME_absolute_get();
291  "Processing GET for key `%s'\n",
292  GNUNET_h2s(key));
293 
294  if (GNUNET_OK != GNUNET_SQ_bind(plugin->get_count_stmt, params_count))
295  {
296  LOG_SQLITE(plugin->dbh,
298  "sqlite3_bind_xxx");
299  GNUNET_SQ_reset(plugin->dbh, plugin->get_count_stmt);
300  return 0;
301  }
302  if (SQLITE_ROW != sqlite3_step(plugin->get_count_stmt))
303  {
304  LOG_SQLITE(plugin->dbh,
306  "sqlite_step");
307  GNUNET_SQ_reset(plugin->dbh, plugin->get_count_stmt);
309  "No content found when processing GET for key `%s'\n",
310  GNUNET_h2s(key));
311  return 0;
312  }
313  total = sqlite3_column_int(plugin->get_count_stmt, 0);
314  GNUNET_SQ_reset(plugin->dbh, plugin->get_count_stmt);
315  if ((0 == total) || (NULL == iter))
316  {
317  if (0 == total)
319  "No content found when processing GET for key `%s'\n",
320  GNUNET_h2s(key));
321  return total;
322  }
323 
324  cnt = 0;
326  while (cnt < total)
327  {
328  off = (off + 1) % total;
329  if (GNUNET_OK != GNUNET_SQ_bind(plugin->get_stmt, params_select))
330  {
331  LOG_SQLITE(plugin->dbh,
333  "sqlite3_bind_xxx");
334  GNUNET_SQ_reset(plugin->dbh, plugin->get_stmt);
335  return cnt;
336  }
337  if (SQLITE_ROW != sqlite3_step(plugin->get_stmt))
338  break;
339  if (GNUNET_OK != GNUNET_SQ_extract_result(plugin->get_stmt, rs))
340  {
341  GNUNET_break(0);
342  GNUNET_SQ_reset(plugin->dbh, plugin->get_stmt);
343  break;
344  }
345  if (0 != psize % sizeof(struct GNUNET_PeerIdentity))
346  {
347  GNUNET_break(0);
348  psize = 0;
349  path = NULL;
350  }
351  psize /= sizeof(struct GNUNET_PeerIdentity);
352  cnt++;
354  "Found %u-byte result when processing GET for key `%s'\n",
355  (unsigned int)size,
356  GNUNET_h2s(key));
357  if (GNUNET_OK != iter(iter_cls, key, size, dat, type, exp, psize, path))
358  {
360  GNUNET_SQ_reset(plugin->dbh, plugin->get_stmt);
361  break;
362  }
364  GNUNET_SQ_reset(plugin->dbh, plugin->get_stmt);
365  }
366  GNUNET_SQ_reset(plugin->dbh, plugin->get_stmt);
367  return cnt;
368 }
369 
370 
378 static int
380 {
381  struct Plugin *plugin = cls;
382  uint64_t rowid;
383  void *data;
384  size_t dsize;
385  struct GNUNET_HashCode hc;
386  struct GNUNET_TIME_Absolute now;
387  struct GNUNET_SQ_ResultSpec rs[] =
390  GNUNET_SQ_result_spec_variable_size((void **)&data, &dsize),
392  struct GNUNET_SQ_QueryParam params[] = { GNUNET_SQ_query_param_uint64(&rowid),
394  struct GNUNET_SQ_QueryParam time_params[] =
396 
397  LOG(GNUNET_ERROR_TYPE_DEBUG, "Processing DEL\n");
398  now = GNUNET_TIME_absolute_get();
399  if (GNUNET_OK != GNUNET_SQ_bind(plugin->del_expired_stmt, time_params))
400  {
401  LOG_SQLITE(plugin->dbh,
403  "sqlite3_bind");
404  GNUNET_SQ_reset(plugin->dbh, plugin->del_expired_stmt);
405  return GNUNET_SYSERR;
406  }
407  if ((SQLITE_ROW != sqlite3_step(plugin->del_expired_stmt)) ||
409  {
410  GNUNET_SQ_reset(plugin->dbh, plugin->del_expired_stmt);
411  if (SQLITE_ROW != sqlite3_step(plugin->del_select_stmt))
412  {
413  LOG_SQLITE(plugin->dbh,
415  "sqlite3_step");
416  GNUNET_SQ_reset(plugin->dbh, plugin->del_select_stmt);
417  return GNUNET_SYSERR;
418  }
420  {
421  GNUNET_SQ_reset(plugin->dbh, plugin->del_select_stmt);
422  GNUNET_break(0);
423  return GNUNET_SYSERR;
424  }
425  }
427  GNUNET_SQ_reset(plugin->dbh, plugin->del_select_stmt);
428  if (GNUNET_OK != GNUNET_SQ_bind(plugin->del_stmt, params))
429  {
430  LOG_SQLITE(plugin->dbh,
432  "sqlite3_bind");
433  GNUNET_SQ_reset(plugin->dbh, plugin->del_stmt);
434  return GNUNET_SYSERR;
435  }
436  if (SQLITE_DONE != sqlite3_step(plugin->del_stmt))
437  {
438  LOG_SQLITE(plugin->dbh,
440  "sqlite3_step");
441  GNUNET_SQ_reset(plugin->dbh, plugin->del_stmt);
442  return GNUNET_SYSERR;
443  }
444  plugin->num_items--;
445  plugin->env->delete_notify(plugin->env->cls, &hc, dsize + OVERHEAD);
446  GNUNET_SQ_reset(plugin->dbh, plugin->del_stmt);
447  return GNUNET_OK;
448 }
449 
450 
459 static unsigned int
462  void *iter_cls)
463 {
464  struct Plugin *plugin = cls;
465  struct GNUNET_TIME_Absolute exp;
466  size_t size;
467  void *dat;
468  uint32_t off;
469  size_t psize;
470  uint32_t type;
471  struct GNUNET_PeerIdentity *path;
472  struct GNUNET_HashCode key;
473  struct GNUNET_SQ_QueryParam params[] = { GNUNET_SQ_query_param_uint32(&off),
475  struct GNUNET_SQ_ResultSpec rs[] =
478  GNUNET_SQ_result_spec_variable_size((void **)&path, &psize),
482 
483  if (0 == plugin->num_items)
484  return 0;
485  if (NULL == iter)
486  return 1;
487  off =
489  if (GNUNET_OK != GNUNET_SQ_bind(plugin->get_random_stmt, params))
490  {
491  return 0;
492  }
493  if (SQLITE_ROW != sqlite3_step(plugin->get_random_stmt))
494  {
495  GNUNET_break(0);
496  GNUNET_SQ_reset(plugin->dbh, plugin->get_random_stmt);
497  return 0;
498  }
500  {
501  GNUNET_break(0);
502  GNUNET_SQ_reset(plugin->dbh, plugin->get_random_stmt);
503  return 0;
504  }
505  if (0 != psize % sizeof(struct GNUNET_PeerIdentity))
506  {
507  GNUNET_break(0);
508  psize = 0;
509  path = NULL;
510  }
511  psize /= sizeof(struct GNUNET_PeerIdentity);
513  "Found %u-byte result with key %s when processing GET-RANDOM\n",
514  (unsigned int)size,
515  GNUNET_h2s(&key));
516  (void)iter(iter_cls,
517  &key,
518  size,
519  dat,
520  (enum GNUNET_BLOCK_Type)type,
521  exp,
522  psize,
523  path);
525  GNUNET_SQ_reset(plugin->dbh, plugin->get_random_stmt);
526  return 1;
527 }
528 
529 
543 static unsigned int
545  const struct GNUNET_HashCode *key,
546  unsigned int num_results,
548  void *iter_cls)
549 {
550  struct Plugin *plugin = cls;
551  uint32_t num_results32 = num_results;
552  struct GNUNET_TIME_Absolute now;
553  struct GNUNET_TIME_Absolute exp;
554  size_t size;
555  void *dat;
556  unsigned int cnt;
557  size_t psize;
558  uint32_t type;
559  struct GNUNET_HashCode hc;
560  struct GNUNET_PeerIdentity *path;
561  struct GNUNET_SQ_QueryParam params[] =
564  GNUNET_SQ_query_param_uint32(&num_results32),
566  struct GNUNET_SQ_ResultSpec rs[] =
569  GNUNET_SQ_result_spec_variable_size((void **)&path, &psize),
573 
574  now = GNUNET_TIME_absolute_get();
576  "Processing GET_CLOSEST for key `%s'\n",
577  GNUNET_h2s(key));
578  if (GNUNET_OK != GNUNET_SQ_bind(plugin->get_closest_stmt, params))
579  {
580  LOG_SQLITE(plugin->dbh,
582  "sqlite3_bind_xxx");
583  GNUNET_SQ_reset(plugin->dbh, plugin->get_closest_stmt);
584  return 0;
585  }
586  cnt = 0;
587  while (SQLITE_ROW == sqlite3_step(plugin->get_closest_stmt))
588  {
590  {
591  GNUNET_break(0);
592  break;
593  }
594  if (0 != psize % sizeof(struct GNUNET_PeerIdentity))
595  {
596  GNUNET_break(0);
597  psize = 0;
598  path = NULL;
599  }
600  psize /= sizeof(struct GNUNET_PeerIdentity);
601  cnt++;
603  "Found %u-byte result at %s when processing GET_CLOSE\n",
604  (unsigned int)size,
605  GNUNET_h2s(&hc));
606  if (GNUNET_OK != iter(iter_cls, &hc, size, dat, type, exp, psize, path))
607  {
609  break;
610  }
612  }
613  GNUNET_SQ_reset(plugin->dbh, plugin->get_closest_stmt);
614  return cnt;
615 }
616 
617 
624 void *
626 {
629  struct Plugin *plugin;
630  char *fn;
631  char *fn_utf8;
632  sqlite3 *dbh;
633  char *emsg;
634 
636  "datacache-sqlite",
637  "IN_MEMORY"))
638  {
639  if (SQLITE_OK != sqlite3_open(":memory:", &dbh))
640  return NULL;
641  fn_utf8 = NULL;
642  }
643  else
644  {
645  fn = GNUNET_DISK_mktemp("gnunet-datacache");
646  if (fn == NULL)
647  {
648  GNUNET_break(0);
649  return NULL;
650  }
651  /* fn should be UTF-8-encoded. If it isn't, it's a bug. */
652  fn_utf8 = GNUNET_strdup(fn);
653  if (SQLITE_OK != sqlite3_open(fn_utf8, &dbh))
654  {
655  GNUNET_free(fn);
656  GNUNET_free(fn_utf8);
657  return NULL;
658  }
659  GNUNET_free(fn);
660  }
661 
662  SQLITE3_EXEC(dbh, "PRAGMA temp_store=MEMORY");
663  SQLITE3_EXEC(dbh, "PRAGMA locking_mode=EXCLUSIVE");
664  SQLITE3_EXEC(dbh, "PRAGMA journal_mode=OFF");
665  SQLITE3_EXEC(dbh, "PRAGMA synchronous=OFF");
666  SQLITE3_EXEC(dbh, "PRAGMA page_size=4092");
668  "datacache-sqlite",
669  "IN_MEMORY"))
670  SQLITE3_EXEC(dbh, "PRAGMA sqlite_temp_store=3");
671 
672  SQLITE3_EXEC(dbh,
673  "CREATE TABLE ds091 ("
674  " type INTEGER NOT NULL DEFAULT 0,"
675  " expire INTEGER NOT NULL,"
676  " key BLOB NOT NULL DEFAULT '',"
677  " prox INTEGER NOT NULL,"
678  " value BLOB NOT NULL,"
679  " path BLOB DEFAULT '')");
680  SQLITE3_EXEC(dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)");
681  SQLITE3_EXEC(dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)");
682  SQLITE3_EXEC(dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)");
683  plugin = GNUNET_new(struct Plugin);
684  plugin->env = env;
685  plugin->dbh = dbh;
686  plugin->fn = fn_utf8;
687 
688  if ((SQLITE_OK !=
689  sq_prepare(plugin->dbh,
690  "INSERT INTO ds091 (type, expire, key, prox, value, path) "
691  "VALUES (?, ?, ?, ?, ?, ?)",
692  &plugin->insert_stmt)) ||
693  (SQLITE_OK != sq_prepare(plugin->dbh,
694  "SELECT count(*) FROM ds091 "
695  "WHERE key=? AND type=? AND expire >= ?",
696  &plugin->get_count_stmt)) ||
697  (SQLITE_OK !=
698  sq_prepare(plugin->dbh,
699  "SELECT value,expire,path FROM ds091"
700  " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
701  &plugin->get_stmt)) ||
702  (SQLITE_OK != sq_prepare(plugin->dbh,
703  "SELECT _ROWID_,key,value FROM ds091"
704  " WHERE expire < ?"
705  " ORDER BY expire ASC LIMIT 1",
706  &plugin->del_expired_stmt)) ||
707  (SQLITE_OK != sq_prepare(plugin->dbh,
708  "SELECT _ROWID_,key,value FROM ds091"
709  " ORDER BY prox ASC, expire ASC LIMIT 1",
710  &plugin->del_select_stmt)) ||
711  (SQLITE_OK != sq_prepare(plugin->dbh,
712  "DELETE FROM ds091 WHERE _ROWID_=?",
713  &plugin->del_stmt)) ||
714  (SQLITE_OK != sq_prepare(plugin->dbh,
715  "SELECT value,expire,path,key,type FROM ds091 "
716  "ORDER BY key LIMIT 1 OFFSET ?",
717  &plugin->get_random_stmt)) ||
718  (SQLITE_OK !=
719  sq_prepare(plugin->dbh,
720  "SELECT value,expire,path,type,key FROM ds091 "
721  "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
722  &plugin->get_closest_stmt)))
723  {
724  LOG_SQLITE(plugin->dbh,
726  "sq_prepare");
727  GNUNET_break(SQLITE_OK == sqlite3_close(plugin->dbh));
728  GNUNET_free(plugin);
729  return NULL;
730  }
731 
733  api->cls = plugin;
734  api->get = &sqlite_plugin_get;
735  api->put = &sqlite_plugin_put;
736  api->del = &sqlite_plugin_del;
739  LOG(GNUNET_ERROR_TYPE_INFO, "Sqlite datacache running\n");
740  return api;
741 }
742 
743 
750 void *
752 {
754  struct Plugin *plugin = api->cls;
755  int result;
756 
757 #if SQLITE_VERSION_NUMBER >= 3007000
758  sqlite3_stmt *stmt;
759 #endif
760 
761 #if !WINDOWS || defined(__CYGWIN__)
762  if ((NULL != plugin->fn) && (0 != unlink(plugin->fn)))
763  LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
764  GNUNET_free_non_null(plugin->fn);
765 #endif
766  sqlite3_finalize(plugin->insert_stmt);
767  sqlite3_finalize(plugin->get_count_stmt);
768  sqlite3_finalize(plugin->get_stmt);
769  sqlite3_finalize(plugin->del_select_stmt);
770  sqlite3_finalize(plugin->del_expired_stmt);
771  sqlite3_finalize(plugin->del_stmt);
772  sqlite3_finalize(plugin->get_random_stmt);
773  sqlite3_finalize(plugin->get_closest_stmt);
774  result = sqlite3_close(plugin->dbh);
775 #if SQLITE_VERSION_NUMBER >= 3007000
776  if (SQLITE_BUSY == result)
777  {
779  _(
780  "Tried to close sqlite without finalizing all prepared statements.\n"));
781  stmt = sqlite3_next_stmt(plugin->dbh, NULL);
782  while (NULL != stmt)
783  {
784  result = sqlite3_finalize(stmt);
785  if (result != SQLITE_OK)
787  "Failed to close statement %p: %d\n",
788  stmt,
789  result);
790  stmt = sqlite3_next_stmt(plugin->dbh, NULL);
791  }
792  result = sqlite3_close(plugin->dbh);
793  }
794 #endif
795  if (SQLITE_OK != result)
796  LOG_SQLITE(plugin->dbh, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
797 
798  GNUNET_free(plugin);
799  GNUNET_free(api);
800  return NULL;
801 }
802 
803 
804 /* end of plugin_datacache_sqlite.c */
#define SQLITE3_EXEC(db, cmd)
Execute SQL statement.
void * cls
Closure to pass to all plugin functions.
sqlite3_stmt * del_expired_stmt
Prepared statement for sqlite_plugin_del.
static unsigned int sqlite_plugin_get(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
Description of a DB result cell.
ssize_t(* put)(void *cls, const struct GNUNET_HashCode *key, uint32_t xor_distance, size_t size, const char *data, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute discard_time, unsigned int path_info_len, const struct GNUNET_PeerIdentity *path_info)
Store an item in the datastore.
int(* del)(void *cls)
Delete the entry with the lowest expiration value from the datacache right now.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t expected.
sqlite3_stmt * get_stmt
Prepared statement for sqlite_plugin_get.
void * libgnunet_plugin_datacache_sqlite_init(void *cls)
Entry point for the plugin.
sqlite3 * dbh
Handle to the sqlite database.
void * libgnunet_plugin_datacache_sqlite_done(void *cls)
Exit point from the plugin.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
#define LOG(kind,...)
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
static int sqlite_plugin_del(void *cls)
Delete the entry with the lowest expiration value from the datacache right now.
char * key
TLS key.
static ssize_t sqlite_plugin_put(void *cls, const struct GNUNET_HashCode *key, uint32_t xor_distance, size_t size, const char *data, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute discard_time, unsigned int path_info_len, const struct GNUNET_PeerIdentity *path_info)
Store an item in the datastore.
#define GNUNET_SQ_result_spec_end
End of result parameter specification.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define LOG_SQLITE(db, level, cmd)
Log an error message at log-level level that indicates a failure of the command cmd with the error fr...
#define GNUNET_SQ_result_spec_auto_from_type(dst)
We expect a fixed-size result, with size determined by the type of * dst
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_absolute_time(struct GNUNET_TIME_Absolute *at)
Absolute time expected.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:46
GNUNET_DATACACHE_DeleteNotifyCallback delete_notify
Function to call whenever the plugin needs to discard content that it was asked to store...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
int GNUNET_SQ_extract_result(sqlite3_stmt *result, struct GNUNET_SQ_ResultSpec *rs)
Extract results from a query result according to the given specification.
Definition: sq.c:82
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
static unsigned int sqlite_plugin_get_closest(void *cls, const struct GNUNET_HashCode *key, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results that are "close" to a particular key in the datacache.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
sqlite3_stmt * insert_stmt
Prepared statement for sqlite_plugin_put.
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition: disk.c:465
void GNUNET_SQ_cleanup_result(struct GNUNET_SQ_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_SQ_extract_result().
Definition: sq.c:117
sqlite3_stmt * get_random_stmt
Prepared statement for sqlite_plugin_get_random.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
unsigned int(* get_closest)(void *cls, const struct GNUNET_HashCode *key, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results that are "close" to a particular key in the datacache.
static int sq_prepare(sqlite3 *dbh, const char *zSql, sqlite3_stmt **ppStmt)
Prepare a SQL statement.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
static unsigned int sqlite_plugin_get_random(void *cls, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Obtain a random key-value pair from the datacache.
Randomness for IVs etc.
sqlite3_stmt * del_select_stmt
Prepared statement for sqlite_plugin_del.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_variable_size(void **dst, size_t *sptr)
Variable-size result expected.
struct returned by the initialization function of the plugin
static int result
Global testing status.
#define OVERHEAD
How much overhead do we assume per entry in the datacache?
sqlite3_stmt * get_closest_stmt
Prepared statement for sqlite_plugin_get_closest.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
A 512-bit hashcode.
int GNUNET_SQ_bind(sqlite3_stmt *stmt, const struct GNUNET_SQ_QueryParam *params)
Execute binding operations for a prepared statement.
Definition: sq.c:37
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
sqlite3_stmt * del_stmt
Prepared statement for sqlite_plugin_del.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
void * iter_cls
Iterator cls.
helper functions for Sqlite3 DB interactions
Description of a DB query parameter.
Definition: gnunet_sq_lib.h:54
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint64(uint64_t *u64)
uint64_t expected.
char * fn
Filename used for the DB.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
The identity of the host (wraps the signing key of the peer).
#define LOG_STRERROR_FILE(kind, op, fn)
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
Definition: sq.c:132
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint16_t in host byte order.
unsigned long long size
Size of all values we&#39;re storing.
Handle for a plugin.
Definition: block.c:37
PGconn * dbh
Native Postgres database handle.
sqlite3_stmt * get_count_stmt
Prepared statement for sqlite_plugin_get.
int(* GNUNET_DATACACHE_Iterator)(void *cls, const struct GNUNET_HashCode *key, size_t data_size, const char *data, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute exp, unsigned int path_info_len, const struct GNUNET_PeerIdentity *path_info)
An iterator over a set of items stored in the datacache.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
void * cls
Closure to use for callbacks.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_fixed_size(const void *ptr, size_t ptr_size)
Generate query parameter for a buffer ptr of ptr_size bytes.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int num_items
Number of key-value pairs in the database.
#define GNUNET_SQ_query_param_end
End of query parameter specification.
Definition: gnunet_sq_lib.h:85
unsigned int(* get_random)(void *cls, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Return a random value from the datastore.
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
uint32_t data
The data value.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
GNUNET_PEERSTORE_Processor iter
Iterator.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
unsigned int(* get)(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
#define GNUNET_free(ptr)
Wrapper around free.