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) GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn)
35 
36 
41 #define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36)
42 
46 struct Plugin
47 {
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) do { LOG (level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db)); } while(0)
119 
120 
127 #define SQLITE3_EXEC(db, cmd) do { emsg = NULL; if (SQLITE_OK != sqlite3_exec(db, cmd, NULL, NULL, &emsg)) { LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sqlite3_exec", __FILE__, __LINE__, emsg); sqlite3_free(emsg); } } while(0)
128 
129 
138 static int
139 sq_prepare (sqlite3 *dbh,
140  const char *zSql, /* SQL statement, UTF-8 encoded */
141  sqlite3_stmt **ppStmt)
142 { /* OUT: Statement handle */
143  char *dummy;
144 
145  return sqlite3_prepare (dbh,
146  zSql,
147  strlen (zSql),
148  ppStmt,
149  (const char **) &dummy);
150 }
151 
152 
167 static ssize_t
169  const struct GNUNET_HashCode *key,
170  uint32_t xor_distance,
171  size_t size,
172  const char *data,
173  enum GNUNET_BLOCK_Type type,
174  struct GNUNET_TIME_Absolute discard_time,
175  unsigned int path_info_len,
176  const struct GNUNET_PeerIdentity *path_info)
177 {
178  struct Plugin *plugin = cls;
179  uint32_t type32 = type;
180  struct GNUNET_SQ_QueryParam params[] = {
182  GNUNET_SQ_query_param_absolute_time (&discard_time),
184  GNUNET_SQ_query_param_uint32 (&xor_distance),
187  path_info_len * sizeof (struct GNUNET_PeerIdentity)),
189  };
190 
192  "Processing PUT of %u bytes with key `%s' and expiration %s\n",
193  (unsigned int) size,
194  GNUNET_h2s (key),
196  GNUNET_YES));
197  if (GNUNET_OK !=
198  GNUNET_SQ_bind (plugin->insert_stmt,
199  params))
200  {
201  LOG_SQLITE (plugin->dbh,
203  "sqlite3_bind_xxx");
204  GNUNET_SQ_reset (plugin->dbh,
205  plugin->insert_stmt);
206  return -1;
207  }
208  if (SQLITE_DONE !=
209  sqlite3_step (plugin->insert_stmt))
210  {
211  LOG_SQLITE (plugin->dbh,
213  "sqlite3_step");
214  GNUNET_SQ_reset (plugin->dbh,
215  plugin->insert_stmt);
216  return -1;
217  }
218  plugin->num_items++;
219  GNUNET_SQ_reset (plugin->dbh,
220  plugin->insert_stmt);
221  return size + OVERHEAD;
222 }
223 
224 
236 static unsigned int
237 sqlite_plugin_get (void *cls,
238  const struct GNUNET_HashCode *key,
239  enum GNUNET_BLOCK_Type type,
241  void *iter_cls)
242 {
243  struct Plugin *plugin = cls;
244  uint32_t type32 = type;
245  struct GNUNET_TIME_Absolute now;
246  struct GNUNET_TIME_Absolute exp;
247  size_t size;
248  void *dat;
249  unsigned int cnt;
250  uint32_t off;
251  unsigned int total;
252  size_t psize;
253  struct GNUNET_PeerIdentity *path;
254  struct GNUNET_SQ_QueryParam params_count[] = {
259  };
260  struct GNUNET_SQ_QueryParam params_select[] = {
266  };
267  struct GNUNET_SQ_ResultSpec rs[] = {
269  &size),
271  GNUNET_SQ_result_spec_variable_size ((void **) &path,
272  &psize),
274  };
275 
276  now = GNUNET_TIME_absolute_get ();
278  "Processing GET for key `%s'\n",
279  GNUNET_h2s (key));
280 
281  if (GNUNET_OK !=
283  params_count))
284  {
285  LOG_SQLITE (plugin->dbh,
287  "sqlite3_bind_xxx");
288  GNUNET_SQ_reset (plugin->dbh,
289  plugin->get_count_stmt);
290  return 0;
291  }
292  if (SQLITE_ROW !=
293  sqlite3_step (plugin->get_count_stmt))
294  {
296  "sqlite_step");
297  GNUNET_SQ_reset (plugin->dbh,
298  plugin->get_count_stmt);
300  "No content found when processing GET for key `%s'\n",
301  GNUNET_h2s (key));
302  return 0;
303  }
304  total = sqlite3_column_int (plugin->get_count_stmt,
305  0);
306  GNUNET_SQ_reset (plugin->dbh,
307  plugin->get_count_stmt);
308  if ( (0 == total) ||
309  (NULL == iter) )
310  {
311  if (0 == total)
313  "No content found when processing GET for key `%s'\n",
314  GNUNET_h2s (key));
315  return total;
316  }
317 
318  cnt = 0;
320  total);
321  while (cnt < total)
322  {
323  off = (off + 1) % total;
324  if (GNUNET_OK !=
325  GNUNET_SQ_bind (plugin->get_stmt,
326  params_select))
327  {
328  LOG_SQLITE (plugin->dbh,
330  "sqlite3_bind_xxx");
331  GNUNET_SQ_reset (plugin->dbh,
332  plugin->get_stmt);
333  return cnt;
334  }
335  if (SQLITE_ROW !=
336  sqlite3_step (plugin->get_stmt))
337  break;
338  if (GNUNET_OK !=
340  rs))
341  {
342  GNUNET_break (0);
343  GNUNET_SQ_reset (plugin->dbh,
344  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,
360  key,
361  size,
362  dat,
363  type,
364  exp,
365  psize,
366  path))
367  {
369  GNUNET_SQ_reset (plugin->dbh,
370  plugin->get_stmt);
371  break;
372  }
374  GNUNET_SQ_reset (plugin->dbh,
375  plugin->get_stmt);
376  }
377  GNUNET_SQ_reset (plugin->dbh,
378  plugin->get_stmt);
379  return cnt;
380 }
381 
382 
390 static int
391 sqlite_plugin_del (void *cls)
392 {
393  struct Plugin *plugin = cls;
394  uint64_t rowid;
395  void *data;
396  size_t dsize;
397  struct GNUNET_HashCode hc;
398  struct GNUNET_TIME_Absolute now;
399  struct GNUNET_SQ_ResultSpec rs[] = {
402  GNUNET_SQ_result_spec_variable_size ((void **) &data,
403  &dsize),
405  };
406  struct GNUNET_SQ_QueryParam params[] = {
409  };
410  struct GNUNET_SQ_QueryParam time_params[] = {
413  };
414 
416  "Processing DEL\n");
417  now = GNUNET_TIME_absolute_get ();
418  if (GNUNET_OK !=
420  time_params))
421  {
422  LOG_SQLITE (plugin->dbh,
424  "sqlite3_bind");
425  GNUNET_SQ_reset (plugin->dbh,
426  plugin->del_expired_stmt);
427  return GNUNET_SYSERR;
428  }
429  if ( (SQLITE_ROW !=
430  sqlite3_step (plugin->del_expired_stmt)) ||
431  (GNUNET_OK !=
433  rs)) )
434  {
435  GNUNET_SQ_reset (plugin->dbh,
436  plugin->del_expired_stmt);
437  if (SQLITE_ROW !=
438  sqlite3_step (plugin->del_select_stmt))
439  {
440  LOG_SQLITE (plugin->dbh,
442  "sqlite3_step");
443  GNUNET_SQ_reset (plugin->dbh,
444  plugin->del_select_stmt);
445  return GNUNET_SYSERR;
446  }
447  if (GNUNET_OK !=
449  rs))
450  {
451  GNUNET_SQ_reset (plugin->dbh,
452  plugin->del_select_stmt);
453  GNUNET_break (0);
454  return GNUNET_SYSERR;
455  }
456  }
458  GNUNET_SQ_reset (plugin->dbh,
459  plugin->del_select_stmt);
460  if (GNUNET_OK !=
461  GNUNET_SQ_bind (plugin->del_stmt,
462  params))
463  {
464  LOG_SQLITE (plugin->dbh,
466  "sqlite3_bind");
467  GNUNET_SQ_reset (plugin->dbh,
468  plugin->del_stmt);
469  return GNUNET_SYSERR;
470  }
471  if (SQLITE_DONE !=
472  sqlite3_step (plugin->del_stmt))
473  {
474  LOG_SQLITE (plugin->dbh,
476  "sqlite3_step");
477  GNUNET_SQ_reset (plugin->dbh,
478  plugin->del_stmt);
479  return GNUNET_SYSERR;
480  }
481  plugin->num_items--;
482  plugin->env->delete_notify (plugin->env->cls,
483  &hc,
484  dsize + OVERHEAD);
485  GNUNET_SQ_reset (plugin->dbh,
486  plugin->del_stmt);
487  return GNUNET_OK;
488 }
489 
490 
499 static unsigned int
502  void *iter_cls)
503 {
504  struct Plugin *plugin = cls;
505  struct GNUNET_TIME_Absolute exp;
506  size_t size;
507  void *dat;
508  uint32_t off;
509  size_t psize;
510  uint32_t type;
511  struct GNUNET_PeerIdentity *path;
512  struct GNUNET_HashCode key;
513  struct GNUNET_SQ_QueryParam params[] = {
516  };
517  struct GNUNET_SQ_ResultSpec rs[] = {
519  &size),
521  GNUNET_SQ_result_spec_variable_size ((void **) &path,
522  &psize),
526  };
527 
528  if (0 == plugin->num_items)
529  return 0;
530  if (NULL == iter)
531  return 1;
533  plugin->num_items);
534  if (GNUNET_OK !=
536  params))
537  {
538  return 0;
539  }
540  if (SQLITE_ROW !=
541  sqlite3_step (plugin->get_random_stmt))
542  {
543  GNUNET_break (0);
544  GNUNET_SQ_reset (plugin->dbh,
545  plugin->get_random_stmt);
546  return 0;
547  }
548  if (GNUNET_OK !=
550  rs))
551  {
552  GNUNET_break (0);
553  GNUNET_SQ_reset (plugin->dbh,
554  plugin->get_random_stmt);
555  return 0;
556  }
557  if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
558  {
559  GNUNET_break (0);
560  psize = 0;
561  path = NULL;
562  }
563  psize /= sizeof (struct GNUNET_PeerIdentity);
565  "Found %u-byte result with key %s when processing GET-RANDOM\n",
566  (unsigned int) size,
567  GNUNET_h2s (&key));
568  (void) iter (iter_cls,
569  &key,
570  size,
571  dat,
572  (enum GNUNET_BLOCK_Type) type,
573  exp,
574  psize,
575  path);
577  GNUNET_SQ_reset (plugin->dbh,
578  plugin->get_random_stmt);
579  return 1;
580 }
581 
582 
596 static unsigned int
598  const struct GNUNET_HashCode *key,
599  unsigned int num_results,
601  void *iter_cls)
602 {
603  struct Plugin *plugin = cls;
604  uint32_t num_results32 = num_results;
605  struct GNUNET_TIME_Absolute now;
606  struct GNUNET_TIME_Absolute exp;
607  size_t size;
608  void *dat;
609  unsigned int cnt;
610  size_t psize;
611  uint32_t type;
612  struct GNUNET_HashCode hc;
613  struct GNUNET_PeerIdentity *path;
614  struct GNUNET_SQ_QueryParam params[] = {
617  GNUNET_SQ_query_param_uint32 (&num_results32),
619  };
620  struct GNUNET_SQ_ResultSpec rs[] = {
622  &size),
624  GNUNET_SQ_result_spec_variable_size ((void **) &path,
625  &psize),
629  };
630 
631  now = GNUNET_TIME_absolute_get ();
633  "Processing GET_CLOSEST for key `%s'\n",
634  GNUNET_h2s (key));
635  if (GNUNET_OK !=
637  params))
638  {
639  LOG_SQLITE (plugin->dbh,
641  "sqlite3_bind_xxx");
642  GNUNET_SQ_reset (plugin->dbh,
643  plugin->get_closest_stmt);
644  return 0;
645  }
646  cnt = 0;
647  while (SQLITE_ROW ==
648  sqlite3_step (plugin->get_closest_stmt))
649  {
650  if (GNUNET_OK !=
652  rs))
653  {
654  GNUNET_break (0);
655  break;
656  }
657  if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
658  {
659  GNUNET_break (0);
660  psize = 0;
661  path = NULL;
662  }
663  psize /= sizeof (struct GNUNET_PeerIdentity);
664  cnt++;
666  "Found %u-byte result at %s when processing GET_CLOSE\n",
667  (unsigned int) size,
668  GNUNET_h2s (&hc));
669  if (GNUNET_OK != iter (iter_cls,
670  &hc,
671  size,
672  dat,
673  type,
674  exp,
675  psize,
676  path))
677  {
679  break;
680  }
682  }
683  GNUNET_SQ_reset (plugin->dbh,
684  plugin->get_closest_stmt);
685  return cnt;
686 }
687 
688 
695 void *
697 {
700  struct Plugin *plugin;
701  char *fn;
702  char *fn_utf8;
703  sqlite3 *dbh;
704  char *emsg;
705 
706  if (GNUNET_YES ==
708  "datacache-sqlite",
709  "IN_MEMORY"))
710  {
711  if (SQLITE_OK != sqlite3_open (":memory:", &dbh))
712  return NULL;
713  fn_utf8 = NULL;
714  }
715  else
716  {
717  fn = GNUNET_DISK_mktemp ("gnunet-datacache");
718  if (fn == NULL)
719  {
720  GNUNET_break (0);
721  return NULL;
722  }
723  /* fn should be UTF-8-encoded. If it isn't, it's a bug. */
724  fn_utf8 = GNUNET_strdup (fn);
725  if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh))
726  {
727  GNUNET_free (fn);
728  GNUNET_free (fn_utf8);
729  return NULL;
730  }
731  GNUNET_free (fn);
732  }
733 
734  SQLITE3_EXEC (dbh, "PRAGMA temp_store=MEMORY");
735  SQLITE3_EXEC (dbh, "PRAGMA locking_mode=EXCLUSIVE");
736  SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF");
737  SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF");
738  SQLITE3_EXEC (dbh, "PRAGMA page_size=4092");
739  if (GNUNET_YES ==
741  "datacache-sqlite",
742  "IN_MEMORY"))
743  SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
744 
745  SQLITE3_EXEC (dbh,
746  "CREATE TABLE ds091 ("
747  " type INTEGER NOT NULL DEFAULT 0,"
748  " expire INTEGER NOT NULL,"
749  " key BLOB NOT NULL DEFAULT '',"
750  " prox INTEGER NOT NULL,"
751  " value BLOB NOT NULL,"
752  " path BLOB DEFAULT '')");
753  SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)");
754  SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)");
755  SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)");
756  plugin = GNUNET_new (struct Plugin);
757  plugin->env = env;
758  plugin->dbh = dbh;
759  plugin->fn = fn_utf8;
760 
761  if ( (SQLITE_OK !=
762  sq_prepare (plugin->dbh,
763  "INSERT INTO ds091 (type, expire, key, prox, value, path) "
764  "VALUES (?, ?, ?, ?, ?, ?)",
765  &plugin->insert_stmt)) ||
766  (SQLITE_OK !=
767  sq_prepare (plugin->dbh,
768  "SELECT count(*) FROM ds091 "
769  "WHERE key=? AND type=? AND expire >= ?",
770  &plugin->get_count_stmt)) ||
771  (SQLITE_OK !=
772  sq_prepare (plugin->dbh,
773  "SELECT value,expire,path FROM ds091"
774  " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
775  &plugin->get_stmt)) ||
776  (SQLITE_OK !=
777  sq_prepare (plugin->dbh,
778  "SELECT _ROWID_,key,value FROM ds091"
779  " WHERE expire < ?"
780  " ORDER BY expire ASC LIMIT 1",
781  &plugin->del_expired_stmt)) ||
782  (SQLITE_OK !=
783  sq_prepare (plugin->dbh,
784  "SELECT _ROWID_,key,value FROM ds091"
785  " ORDER BY prox ASC, expire ASC LIMIT 1",
786  &plugin->del_select_stmt)) ||
787  (SQLITE_OK !=
788  sq_prepare (plugin->dbh,
789  "DELETE FROM ds091 WHERE _ROWID_=?",
790  &plugin->del_stmt)) ||
791  (SQLITE_OK !=
792  sq_prepare (plugin->dbh,
793  "SELECT value,expire,path,key,type FROM ds091 "
794  "ORDER BY key LIMIT 1 OFFSET ?",
795  &plugin->get_random_stmt)) ||
796  (SQLITE_OK !=
797  sq_prepare (plugin->dbh,
798  "SELECT value,expire,path,type,key FROM ds091 "
799  "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
800  &plugin->get_closest_stmt))
801  )
802  {
803  LOG_SQLITE (plugin->dbh,
805  "sq_prepare");
806  GNUNET_break (SQLITE_OK ==
807  sqlite3_close (plugin->dbh));
808  GNUNET_free (plugin);
809  return NULL;
810  }
811 
813  api->cls = plugin;
814  api->get = &sqlite_plugin_get;
815  api->put = &sqlite_plugin_put;
816  api->del = &sqlite_plugin_del;
820  "Sqlite datacache running\n");
821  return api;
822 }
823 
824 
831 void *
833 {
835  struct Plugin *plugin = api->cls;
836  int result;
837 
838 #if SQLITE_VERSION_NUMBER >= 3007000
839  sqlite3_stmt *stmt;
840 #endif
841 
842 #if !WINDOWS || defined(__CYGWIN__)
843  if ( (NULL != plugin->fn) &&
844  (0 != UNLINK (plugin->fn)) )
846  "unlink",
847  plugin->fn);
848  GNUNET_free_non_null (plugin->fn);
849 #endif
850  sqlite3_finalize (plugin->insert_stmt);
851  sqlite3_finalize (plugin->get_count_stmt);
852  sqlite3_finalize (plugin->get_stmt);
853  sqlite3_finalize (plugin->del_select_stmt);
854  sqlite3_finalize (plugin->del_expired_stmt);
855  sqlite3_finalize (plugin->del_stmt);
856  sqlite3_finalize (plugin->get_random_stmt);
857  sqlite3_finalize (plugin->get_closest_stmt);
858  result = sqlite3_close (plugin->dbh);
859 #if SQLITE_VERSION_NUMBER >= 3007000
860  if (SQLITE_BUSY == result)
861  {
863  _("Tried to close sqlite without finalizing all prepared statements.\n"));
864  stmt = sqlite3_next_stmt (plugin->dbh, NULL);
865  while (NULL != stmt)
866  {
867  result = sqlite3_finalize (stmt);
868  if (result != SQLITE_OK)
870  "Failed to close statement %p: %d\n",
871  stmt,
872  result);
873  stmt = sqlite3_next_stmt (plugin->dbh, NULL);
874  }
875  result = sqlite3_close (plugin->dbh);
876  }
877 #endif
878  if (SQLITE_OK != result)
879  LOG_SQLITE (plugin->dbh,
881  "sqlite3_close");
882 
883 #if WINDOWS && !defined(__CYGWIN__)
884  if ( (NULL != plugin->fn) &&
885  (0 != UNLINK (plugin->fn)) )
887  "unlink",
888  plugin->fn);
889  GNUNET_free_non_null (plugin->fn);
890 #endif
891  GNUNET_free (plugin);
892  GNUNET_free (api);
893  return NULL;
894 }
895 
896 
897 
898 /* 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.
static struct in_addr dummy
Target "dummy" address.
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:78
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 UNLINK(f)
Definition: plibc.h:666
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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:593
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:727
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:79
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.
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:80
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:87
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.