GNUnet  0.11.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
48 {
53 
57  sqlite3 *dbh;
58 
62  char *fn;
63 
67  sqlite3_stmt *insert_stmt;
68 
72  sqlite3_stmt *get_count_stmt;
73 
77  sqlite3_stmt *get_stmt;
78 
82  sqlite3_stmt *del_select_stmt;
83 
87  sqlite3_stmt *del_expired_stmt;
88 
92  sqlite3_stmt *del_stmt;
93 
97  sqlite3_stmt *get_random_stmt;
98 
102  sqlite3_stmt *get_closest_stmt;
103 
107  unsigned int num_items;
108 };
109 
110 
119 #define LOG_SQLITE(db, level, cmd) \
120  do \
121  { \
122  LOG (level, \
123  _ ("`%s' failed at %s:%d with error: %s\n"), \
124  cmd, \
125  __FILE__, \
126  __LINE__, \
127  sqlite3_errmsg (db)); \
128  } while (0)
129 
130 
137 #define SQLITE3_EXEC(db, cmd) \
138  do \
139  { \
140  emsg = NULL; \
141  if (SQLITE_OK != sqlite3_exec (db, cmd, NULL, NULL, &emsg)) \
142  { \
143  LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, \
144  _ ("`%s' failed at %s:%d with error: %s\n"), \
145  "sqlite3_exec", \
146  __FILE__, \
147  __LINE__, \
148  emsg); \
149  sqlite3_free (emsg); \
150  } \
151  } while (0)
152 
153 
162 static int
163 sq_prepare (sqlite3 *dbh,
164  const char *zSql, /* SQL statement, UTF-8 encoded */
165  sqlite3_stmt **ppStmt)
166 { /* OUT: Statement handle */
167  char *dummy;
168 
169  return sqlite3_prepare (dbh,
170  zSql,
171  strlen (zSql),
172  ppStmt,
173  (const char **) &dummy);
174 }
175 
176 
191 static ssize_t
193  const struct GNUNET_HashCode *key,
194  uint32_t xor_distance,
195  size_t size,
196  const char *data,
197  enum GNUNET_BLOCK_Type type,
198  struct GNUNET_TIME_Absolute discard_time,
199  unsigned int path_info_len,
200  const struct GNUNET_PeerIdentity *path_info)
201 {
202  struct Plugin *plugin = cls;
203  uint32_t type32 = type;
204  struct GNUNET_SQ_QueryParam params[] =
205  { GNUNET_SQ_query_param_uint32 (&type32),
206  GNUNET_SQ_query_param_absolute_time (&discard_time),
208  GNUNET_SQ_query_param_uint32 (&xor_distance),
211  path_info_len
212  * sizeof(struct GNUNET_PeerIdentity)),
214 
216  "Processing PUT of %u bytes with key `%s' and expiration %s\n",
217  (unsigned int) size,
218  GNUNET_h2s (key),
221  discard_time),
222  GNUNET_YES));
223  if (GNUNET_OK != GNUNET_SQ_bind (plugin->insert_stmt, params))
224  {
225  LOG_SQLITE (plugin->dbh,
227  "sqlite3_bind_xxx");
228  GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
229  return -1;
230  }
231  if (SQLITE_DONE != sqlite3_step (plugin->insert_stmt))
232  {
233  LOG_SQLITE (plugin->dbh,
235  "sqlite3_step");
236  GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
237  return -1;
238  }
239  plugin->num_items++;
240  GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
241  return size + OVERHEAD;
242 }
243 
244 
256 static unsigned int
257 sqlite_plugin_get (void *cls,
258  const struct GNUNET_HashCode *key,
259  enum GNUNET_BLOCK_Type type,
261  void *iter_cls)
262 {
263  struct Plugin *plugin = cls;
264  uint32_t type32 = type;
265  struct GNUNET_TIME_Absolute now;
266  struct GNUNET_TIME_Absolute exp;
267  size_t size;
268  void *dat;
269  unsigned int cnt;
270  uint32_t off;
271  unsigned int total;
272  size_t psize;
273  struct GNUNET_PeerIdentity *path;
274  struct GNUNET_SQ_QueryParam params_count[] =
279  struct GNUNET_SQ_QueryParam params_select[] =
285  struct GNUNET_SQ_ResultSpec rs[] =
286  { GNUNET_SQ_result_spec_variable_size (&dat, &size),
288  GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
290 
291  now = GNUNET_TIME_absolute_get ();
293  "Processing GET for key `%s'\n",
294  GNUNET_h2s (key));
295 
296  if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_count_stmt, params_count))
297  {
298  LOG_SQLITE (plugin->dbh,
300  "sqlite3_bind_xxx");
301  GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
302  return 0;
303  }
304  if (SQLITE_ROW != sqlite3_step (plugin->get_count_stmt))
305  {
306  LOG_SQLITE (plugin->dbh,
308  "sqlite_step");
309  GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
311  "No content found when processing GET for key `%s'\n",
312  GNUNET_h2s (key));
313  return 0;
314  }
315  total = sqlite3_column_int (plugin->get_count_stmt, 0);
316  GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
317  if ((0 == total) || (NULL == iter))
318  {
319  if (0 == total)
321  "No content found when processing GET for key `%s'\n",
322  GNUNET_h2s (key));
323  return total;
324  }
325 
326  cnt = 0;
328  while (cnt < total)
329  {
330  off = (off + 1) % total;
331  if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_stmt, params_select))
332  {
333  LOG_SQLITE (plugin->dbh,
335  "sqlite3_bind_xxx");
336  GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
337  return cnt;
338  }
339  if (SQLITE_ROW != sqlite3_step (plugin->get_stmt))
340  break;
341  if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_stmt, rs))
342  {
343  GNUNET_break (0);
344  GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
345  break;
346  }
347  if (0 != psize % sizeof(struct GNUNET_PeerIdentity))
348  {
349  GNUNET_break (0);
350  psize = 0;
351  path = NULL;
352  }
353  psize /= sizeof(struct GNUNET_PeerIdentity);
354  cnt++;
356  "Found %u-byte result when processing GET for key `%s'\n",
357  (unsigned int) size,
358  GNUNET_h2s (key));
359  if (GNUNET_OK != iter (iter_cls, key, size, dat, type, exp, psize, path))
360  {
362  GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
363  break;
364  }
366  GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
367  }
368  GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
369  return cnt;
370 }
371 
372 
380 static int
381 sqlite_plugin_del (void *cls)
382 {
383  struct Plugin *plugin = cls;
384  uint64_t rowid;
385  void *data;
386  size_t dsize;
387  struct GNUNET_HashCode hc;
388  struct GNUNET_TIME_Absolute now;
389  struct GNUNET_SQ_ResultSpec rs[] =
390  { GNUNET_SQ_result_spec_uint64 (&rowid),
392  GNUNET_SQ_result_spec_variable_size ((void **) &data, &dsize),
395  &rowid),
397  struct GNUNET_SQ_QueryParam time_params[] =
399 
400  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing DEL\n");
401  now = GNUNET_TIME_absolute_get ();
402  if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_expired_stmt, time_params))
403  {
404  LOG_SQLITE (plugin->dbh,
406  "sqlite3_bind");
407  GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt);
408  return GNUNET_SYSERR;
409  }
410  if ((SQLITE_ROW != sqlite3_step (plugin->del_expired_stmt)) ||
412  {
413  GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt);
414  if (SQLITE_ROW != sqlite3_step (plugin->del_select_stmt))
415  {
416  LOG_SQLITE (plugin->dbh,
418  "sqlite3_step");
419  GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
420  return GNUNET_SYSERR;
421  }
423  {
424  GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
425  GNUNET_break (0);
426  return GNUNET_SYSERR;
427  }
428  }
430  GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
431  if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_stmt, params))
432  {
433  LOG_SQLITE (plugin->dbh,
435  "sqlite3_bind");
436  GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
437  return GNUNET_SYSERR;
438  }
439  if (SQLITE_DONE != sqlite3_step (plugin->del_stmt))
440  {
441  LOG_SQLITE (plugin->dbh,
443  "sqlite3_step");
444  GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
445  return GNUNET_SYSERR;
446  }
447  plugin->num_items--;
448  plugin->env->delete_notify (plugin->env->cls, &hc, dsize + OVERHEAD);
449  GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
450  return GNUNET_OK;
451 }
452 
453 
462 static unsigned int
465  void *iter_cls)
466 {
467  struct Plugin *plugin = cls;
468  struct GNUNET_TIME_Absolute exp;
469  size_t size;
470  void *dat;
471  uint32_t off;
472  size_t psize;
473  uint32_t type;
474  struct GNUNET_PeerIdentity *path;
475  struct GNUNET_HashCode key;
476  struct GNUNET_SQ_QueryParam params[] = { GNUNET_SQ_query_param_uint32 (&off),
478  struct GNUNET_SQ_ResultSpec rs[] =
479  { GNUNET_SQ_result_spec_variable_size (&dat, &size),
481  GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
485 
486  if (0 == plugin->num_items)
487  return 0;
488  if (NULL == iter)
489  return 1;
490  off =
492  if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_random_stmt, params))
493  {
494  return 0;
495  }
496  if (SQLITE_ROW != sqlite3_step (plugin->get_random_stmt))
497  {
498  GNUNET_break (0);
499  GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
500  return 0;
501  }
503  {
504  GNUNET_break (0);
505  GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
506  return 0;
507  }
508  if (0 != psize % sizeof(struct GNUNET_PeerIdentity))
509  {
510  GNUNET_break (0);
511  psize = 0;
512  path = NULL;
513  }
514  psize /= sizeof(struct GNUNET_PeerIdentity);
516  "Found %u-byte result with key %s when processing GET-RANDOM\n",
517  (unsigned int) size,
518  GNUNET_h2s (&key));
519  (void) iter (iter_cls,
520  &key,
521  size,
522  dat,
523  (enum GNUNET_BLOCK_Type) type,
524  exp,
525  psize,
526  path);
528  GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
529  return 1;
530 }
531 
532 
546 static unsigned int
548  const struct GNUNET_HashCode *key,
549  unsigned int num_results,
551  void *iter_cls)
552 {
553  struct Plugin *plugin = cls;
554  uint32_t num_results32 = num_results;
555  struct GNUNET_TIME_Absolute now;
556  struct GNUNET_TIME_Absolute exp;
557  size_t size;
558  void *dat;
559  unsigned int cnt;
560  size_t psize;
561  uint32_t type;
562  struct GNUNET_HashCode hc;
563  struct GNUNET_PeerIdentity *path;
564  struct GNUNET_SQ_QueryParam params[] =
567  GNUNET_SQ_query_param_uint32 (&num_results32),
569  struct GNUNET_SQ_ResultSpec rs[] =
570  { GNUNET_SQ_result_spec_variable_size (&dat, &size),
572  GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
576 
577  now = GNUNET_TIME_absolute_get ();
579  "Processing GET_CLOSEST for key `%s'\n",
580  GNUNET_h2s (key));
581  if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_closest_stmt, params))
582  {
583  LOG_SQLITE (plugin->dbh,
585  "sqlite3_bind_xxx");
586  GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt);
587  return 0;
588  }
589  cnt = 0;
590  while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt))
591  {
593  {
594  GNUNET_break (0);
595  break;
596  }
597  if (0 != psize % sizeof(struct GNUNET_PeerIdentity))
598  {
599  GNUNET_break (0);
600  psize = 0;
601  path = NULL;
602  }
603  psize /= sizeof(struct GNUNET_PeerIdentity);
604  cnt++;
606  "Found %u-byte result at %s when processing GET_CLOSE\n",
607  (unsigned int) size,
608  GNUNET_h2s (&hc));
609  if (GNUNET_OK != iter (iter_cls, &hc, size, dat, type, exp, psize, path))
610  {
612  break;
613  }
615  }
616  GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt);
617  return cnt;
618 }
619 
620 
627 void *
629 {
632  struct Plugin *plugin;
633  char *fn;
634  char *fn_utf8;
635  sqlite3 *dbh;
636  char *emsg;
637 
639  "datacache-sqlite",
640  "IN_MEMORY"))
641  {
642  if (SQLITE_OK != sqlite3_open (":memory:", &dbh))
643  return NULL;
644  fn_utf8 = NULL;
645  }
646  else
647  {
648  fn = GNUNET_DISK_mktemp ("gnunet-datacache");
649  if (fn == NULL)
650  {
651  GNUNET_break (0);
652  return NULL;
653  }
654  /* fn should be UTF-8-encoded. If it isn't, it's a bug. */
655  fn_utf8 = GNUNET_strdup (fn);
656  if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh))
657  {
658  GNUNET_free (fn);
659  GNUNET_free (fn_utf8);
660  return NULL;
661  }
662  GNUNET_free (fn);
663  }
664 
665  SQLITE3_EXEC (dbh, "PRAGMA temp_store=MEMORY");
666  SQLITE3_EXEC (dbh, "PRAGMA locking_mode=EXCLUSIVE");
667  SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF");
668  SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF");
669  SQLITE3_EXEC (dbh, "PRAGMA page_size=4092");
671  "datacache-sqlite",
672  "IN_MEMORY"))
673  SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
674 
675  SQLITE3_EXEC (dbh,
676  "CREATE TABLE ds091 ("
677  " type INTEGER NOT NULL DEFAULT 0,"
678  " expire INTEGER NOT NULL,"
679  " key BLOB NOT NULL DEFAULT '',"
680  " prox INTEGER NOT NULL,"
681  " value BLOB NOT NULL,"
682  " path BLOB DEFAULT '')");
683  SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)");
684  SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)");
685  SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)");
686  plugin = GNUNET_new (struct Plugin);
687  plugin->env = env;
688  plugin->dbh = dbh;
689  plugin->fn = fn_utf8;
690 
691  if ((SQLITE_OK !=
692  sq_prepare (plugin->dbh,
693  "INSERT INTO ds091 (type, expire, key, prox, value, path) "
694  "VALUES (?, ?, ?, ?, ?, ?)",
695  &plugin->insert_stmt)) ||
696  (SQLITE_OK != sq_prepare (plugin->dbh,
697  "SELECT count(*) FROM ds091 "
698  "WHERE key=? AND type=? AND expire >= ?",
699  &plugin->get_count_stmt)) ||
700  (SQLITE_OK !=
701  sq_prepare (plugin->dbh,
702  "SELECT value,expire,path FROM ds091"
703  " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
704  &plugin->get_stmt)) ||
705  (SQLITE_OK != sq_prepare (plugin->dbh,
706  "SELECT _ROWID_,key,value FROM ds091"
707  " WHERE expire < ?"
708  " ORDER BY expire ASC LIMIT 1",
709  &plugin->del_expired_stmt)) ||
710  (SQLITE_OK != sq_prepare (plugin->dbh,
711  "SELECT _ROWID_,key,value FROM ds091"
712  " ORDER BY prox ASC, expire ASC LIMIT 1",
713  &plugin->del_select_stmt)) ||
714  (SQLITE_OK != sq_prepare (plugin->dbh,
715  "DELETE FROM ds091 WHERE _ROWID_=?",
716  &plugin->del_stmt)) ||
717  (SQLITE_OK != sq_prepare (plugin->dbh,
718  "SELECT value,expire,path,key,type FROM ds091 "
719  "ORDER BY key LIMIT 1 OFFSET ?",
720  &plugin->get_random_stmt)) ||
721  (SQLITE_OK !=
722  sq_prepare (plugin->dbh,
723  "SELECT value,expire,path,type,key FROM ds091 "
724  "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
725  &plugin->get_closest_stmt)))
726  {
727  LOG_SQLITE (plugin->dbh,
729  "sq_prepare");
730  GNUNET_break (SQLITE_OK == sqlite3_close (plugin->dbh));
731  GNUNET_free (plugin);
732  return NULL;
733  }
734 
736  api->cls = plugin;
737  api->get = &sqlite_plugin_get;
738  api->put = &sqlite_plugin_put;
739  api->del = &sqlite_plugin_del;
742  LOG (GNUNET_ERROR_TYPE_INFO, "Sqlite datacache running\n");
743  return api;
744 }
745 
746 
753 void *
755 {
757  struct Plugin *plugin = api->cls;
758  int result;
759 
760 #if SQLITE_VERSION_NUMBER >= 3007000
761  sqlite3_stmt *stmt;
762 #endif
763 
764 #if ! WINDOWS || defined(__CYGWIN__)
765  if ((NULL != plugin->fn) && (0 != unlink (plugin->fn)))
766  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
767  GNUNET_free_non_null (plugin->fn);
768 #endif
769  sqlite3_finalize (plugin->insert_stmt);
770  sqlite3_finalize (plugin->get_count_stmt);
771  sqlite3_finalize (plugin->get_stmt);
772  sqlite3_finalize (plugin->del_select_stmt);
773  sqlite3_finalize (plugin->del_expired_stmt);
774  sqlite3_finalize (plugin->del_stmt);
775  sqlite3_finalize (plugin->get_random_stmt);
776  sqlite3_finalize (plugin->get_closest_stmt);
777  result = sqlite3_close (plugin->dbh);
778 #if SQLITE_VERSION_NUMBER >= 3007000
779  if (SQLITE_BUSY == result)
780  {
782  _ (
783  "Tried to close sqlite without finalizing all prepared statements.\n"));
784  stmt = sqlite3_next_stmt (plugin->dbh, NULL);
785  while (NULL != stmt)
786  {
787  result = sqlite3_finalize (stmt);
788  if (result != SQLITE_OK)
790  "Failed to close statement %p: %d\n",
791  stmt,
792  result);
793  stmt = sqlite3_next_stmt (plugin->dbh, NULL);
794  }
795  result = sqlite3_close (plugin->dbh);
796  }
797 #endif
798  if (SQLITE_OK != result)
799  LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
800 
801  GNUNET_free (plugin);
802  GNUNET_free (api);
803  return NULL;
804 }
805 
806 
807 /* 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:47
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.
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:468
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:687
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
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
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
struct GNUNET_PQ_Context * 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:86
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.