GNUnet  0.11.x
plugin_namestore_sqlite.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 
27 #include "platform.h"
30 #include "gnunet_gnsrecord_lib.h"
31 #include "gnunet_sq_lib.h"
32 #include "namestore.h"
33 #include <sqlite3.h>
34 
45 #define BUSY_TIMEOUT_MS 1000
46 
47 
53 #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, \
54  "namestore-sqlite", _ ( \
55  "`%s' failed at %s:%d with error: %s\n"), \
56  cmd, \
57  __FILE__, __LINE__, \
58  sqlite3_errmsg ( \
59  db->dbh)); \
60 } while (0)
61 
62 #define LOG(kind, ...) GNUNET_log_from (kind, "namestore-sqlite", __VA_ARGS__)
63 
64 
68 struct Plugin
69 {
70  const struct GNUNET_CONFIGURATION_Handle *cfg;
71 
75  char *fn;
76 
80  sqlite3 *dbh;
81 
85  sqlite3_stmt *store_records;
86 
90  sqlite3_stmt *delete_records;
91 
95  sqlite3_stmt *iterate_zone;
96 
100  sqlite3_stmt *iterate_all_zones;
101 
105  sqlite3_stmt *zone_to_name;
106 
110  sqlite3_stmt *lookup_label;
111 };
112 
113 
122 static int
124 {
125  char *sqlite_filename;
126  struct GNUNET_SQ_ExecuteStatement es[] = {
127  GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
128  GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
129  GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
130  GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
131  GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
132  GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"),
133  GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
134  GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
135  GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
136  " uid INTEGER PRIMARY KEY,"
137  " zone_private_key BLOB NOT NULL,"
138  " pkey BLOB,"
139  " rvalue INT8 NOT NULL,"
140  " record_count INT NOT NULL,"
141  " record_data BLOB NOT NULL,"
142  " label TEXT NOT NULL"
143  ")"),
144  GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse "
145  "ON ns098records (zone_private_key,pkey)"),
146  GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter "
147  "ON ns098records (zone_private_key,uid)"),
149  };
150  struct GNUNET_SQ_PrepareStatement ps[] = {
151  GNUNET_SQ_make_prepare ("INSERT INTO ns098records "
152  "(zone_private_key,pkey,rvalue,record_count,record_data,label)"
153  " VALUES (?, ?, ?, ?, ?, ?)",
154  &plugin->store_records),
155  GNUNET_SQ_make_prepare ("DELETE FROM ns098records "
156  "WHERE zone_private_key=? AND label=?",
157  &plugin->delete_records),
158  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
159  " FROM ns098records"
160  " WHERE zone_private_key=? AND pkey=?",
161  &plugin->zone_to_name),
162  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
163  " FROM ns098records"
164  " WHERE zone_private_key=? AND uid > ?"
165  " ORDER BY uid ASC"
166  " LIMIT ?",
167  &plugin->iterate_zone),
169  "SELECT uid,record_count,record_data,label,zone_private_key"
170  " FROM ns098records"
171  " WHERE uid > ?"
172  " ORDER BY uid ASC"
173  " LIMIT ?",
174  &plugin->iterate_all_zones),
175  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
176  " FROM ns098records"
177  " WHERE zone_private_key=? AND label=?",
178  &plugin->lookup_label),
180  };
181 
182  if (GNUNET_OK !=
184  "namestore-sqlite",
185  "FILENAME",
186  &sqlite_filename))
187  {
189  "namestore-sqlite",
190  "FILENAME");
191  return GNUNET_SYSERR;
192  }
193  if (GNUNET_OK !=
194  GNUNET_DISK_file_test (sqlite_filename))
195  {
196  if (GNUNET_OK !=
197  GNUNET_DISK_directory_create_for_file (sqlite_filename))
198  {
199  GNUNET_break (0);
200  GNUNET_free (sqlite_filename);
201  return GNUNET_SYSERR;
202  }
203  }
204  /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */
205  plugin->fn = sqlite_filename;
206 
207  /* Open database and precompile statements */
208  if (SQLITE_OK !=
209  sqlite3_open (plugin->fn,
210  &plugin->dbh))
211  {
213  _ ("Unable to initialize SQLite: %s.\n"),
214  sqlite3_errmsg (plugin->dbh));
215  return GNUNET_SYSERR;
216  }
217  GNUNET_break (SQLITE_OK ==
218  sqlite3_busy_timeout (plugin->dbh,
219  BUSY_TIMEOUT_MS));
220  if (GNUNET_OK !=
222  es))
223  {
224  GNUNET_break (0);
226  _ ("Failed to setup database at `%s'\n"),
227  plugin->fn);
228  return GNUNET_SYSERR;
229  }
230 
231  if (GNUNET_OK !=
232  GNUNET_SQ_prepare (plugin->dbh,
233  ps))
234  {
235  GNUNET_break (0);
237  _ ("Failed to setup database at `%s'\n"),
238  plugin->fn);
239  return GNUNET_SYSERR;
240  }
241  return GNUNET_OK;
242 }
243 
244 
250 static void
252 {
253  int result;
254  sqlite3_stmt *stmt;
255 
256  if (NULL != plugin->store_records)
257  sqlite3_finalize (plugin->store_records);
258  if (NULL != plugin->delete_records)
259  sqlite3_finalize (plugin->delete_records);
260  if (NULL != plugin->iterate_zone)
261  sqlite3_finalize (plugin->iterate_zone);
262  if (NULL != plugin->iterate_all_zones)
263  sqlite3_finalize (plugin->iterate_all_zones);
264  if (NULL != plugin->zone_to_name)
265  sqlite3_finalize (plugin->zone_to_name);
266  if (NULL != plugin->lookup_label)
267  sqlite3_finalize (plugin->lookup_label);
268  result = sqlite3_close (plugin->dbh);
269  if (result == SQLITE_BUSY)
270  {
272  _ (
273  "Tried to close sqlite without finalizing all prepared statements.\n"));
274  stmt = sqlite3_next_stmt (plugin->dbh,
275  NULL);
276  while (NULL != stmt)
277  {
279  "sqlite",
280  "Closing statement %p\n",
281  stmt);
282  result = sqlite3_finalize (stmt);
283  if (result != SQLITE_OK)
285  "sqlite",
286  "Failed to close statement %p: %d\n",
287  stmt,
288  result);
289  stmt = sqlite3_next_stmt (plugin->dbh,
290  NULL);
291  }
292  result = sqlite3_close (plugin->dbh);
293  }
294  if (SQLITE_OK != result)
295  LOG_SQLITE (plugin,
297  "sqlite3_close");
298 
299  GNUNET_free_non_null (plugin->fn);
300 }
301 
302 
314 static int
316  const struct
318  const char *label,
319  unsigned int rd_count,
320  const struct GNUNET_GNSRECORD_Data *rd)
321 {
322  struct Plugin *plugin = cls;
323  int n;
324  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
325  uint64_t rvalue;
326  ssize_t data_size;
327 
328  memset (&pkey,
329  0,
330  sizeof(pkey));
331  for (unsigned int i = 0; i < rd_count; i++)
332  if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type)
333  {
334  GNUNET_break (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) ==
335  rd[i].data_size);
336  GNUNET_memcpy (&pkey,
337  rd[i].data,
338  rd[i].data_size);
339  break;
340  }
342  UINT64_MAX);
343  data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
344  rd);
345  if (data_size < 0)
346  {
347  GNUNET_break (0);
348  return GNUNET_SYSERR;
349  }
350  if (data_size > 64 * 65536)
351  {
352  GNUNET_break (0);
353  return GNUNET_SYSERR;
354  }
355  {
356  /* First delete 'old' records */
357  char data[data_size];
358  struct GNUNET_SQ_QueryParam dparams[] = {
362  };
363  ssize_t ret;
364 
365  ret = GNUNET_GNSRECORD_records_serialize (rd_count,
366  rd,
367  data_size,
368  data);
369  if ((ret < 0) ||
370  (data_size != ret))
371  {
372  GNUNET_break (0);
373  return GNUNET_SYSERR;
374  }
375  if (GNUNET_OK !=
377  dparams))
378  {
379  LOG_SQLITE (plugin,
381  "sqlite3_bind_XXXX");
382  GNUNET_SQ_reset (plugin->dbh,
383  plugin->delete_records);
384  return GNUNET_SYSERR;
385  }
386  n = sqlite3_step (plugin->delete_records);
387  GNUNET_SQ_reset (plugin->dbh,
388  plugin->delete_records);
389 
390  if (0 != rd_count)
391  {
392  uint32_t rd_count32 = (uint32_t) rd_count;
393  struct GNUNET_SQ_QueryParam sparams[] = {
397  GNUNET_SQ_query_param_uint32 (&rd_count32),
398  GNUNET_SQ_query_param_fixed_size (data, data_size),
401  };
402 
403  if (GNUNET_OK !=
404  GNUNET_SQ_bind (plugin->store_records,
405  sparams))
406  {
407  LOG_SQLITE (plugin,
409  "sqlite3_bind_XXXX");
410  GNUNET_SQ_reset (plugin->dbh,
411  plugin->store_records);
412  return GNUNET_SYSERR;
413  }
414  n = sqlite3_step (plugin->store_records);
415  GNUNET_SQ_reset (plugin->dbh,
416  plugin->store_records);
417  }
418  }
419  switch (n)
420  {
421  case SQLITE_DONE:
422  if (0 != rd_count)
424  "sqlite",
425  "Record stored\n");
426  else
428  "sqlite",
429  "Record deleted\n");
430  return GNUNET_OK;
431 
432  case SQLITE_BUSY:
433  LOG_SQLITE (plugin,
435  "sqlite3_step");
436  return GNUNET_NO;
437 
438  default:
439  LOG_SQLITE (plugin,
441  "sqlite3_step");
442  return GNUNET_SYSERR;
443  }
444 }
445 
446 
460 static int
462  sqlite3_stmt *stmt,
463  const struct
465  uint64_t limit,
467  void *iter_cls)
468 {
469  int ret;
470  int sret;
471 
472  ret = GNUNET_OK;
473  for (uint64_t i = 0; i < limit; i++)
474  {
475  sret = sqlite3_step (stmt);
476 
477  if (SQLITE_DONE == sret)
478  {
480  "Iteration done (no results)\n");
481  ret = GNUNET_NO;
482  break;
483  }
484  if (SQLITE_ROW != sret)
485  {
486  LOG_SQLITE (plugin,
488  "sqlite_step");
489  ret = GNUNET_SYSERR;
490  break;
491  }
492 
493  {
494  uint64_t seq;
495  uint32_t record_count;
496  size_t data_size;
497  void *data;
498  char *label;
500  struct GNUNET_SQ_ResultSpec rs[] = {
502  GNUNET_SQ_result_spec_uint32 (&record_count),
504  &data_size),
507  };
508  struct GNUNET_SQ_ResultSpec rsx[] = {
510  GNUNET_SQ_result_spec_uint32 (&record_count),
512  &data_size),
516  };
517 
518  ret = GNUNET_SQ_extract_result (stmt,
519  (NULL == zone_key)
520  ? rsx
521  : rs);
522  if ((GNUNET_OK != ret) ||
523  (record_count > 64 * 1024))
524  {
525  /* sanity check, don't stack allocate far too much just
526  because database might contain a large value here */
527  GNUNET_break (0);
528  ret = GNUNET_SYSERR;
529  break;
530  }
531  else
532  {
533  struct GNUNET_GNSRECORD_Data rd[record_count];
534 
535  GNUNET_assert (0 != seq);
536  if (GNUNET_OK !=
538  data,
539  record_count,
540  rd))
541  {
542  GNUNET_break (0);
543  ret = GNUNET_SYSERR;
544  break;
545  }
546  else
547  {
548  if (NULL != zone_key)
549  zk = *zone_key;
550  if (NULL != iter)
551  iter (iter_cls,
552  seq,
553  &zk,
554  label,
555  record_count,
556  rd);
557  }
558  }
560  }
561  }
562  GNUNET_SQ_reset (plugin->dbh,
563  stmt);
564  return ret;
565 }
566 
567 
578 static int
580  const struct
582  const char *label,
584  void *iter_cls)
585 {
586  struct Plugin *plugin = cls;
587  struct GNUNET_SQ_QueryParam params[] = {
591  };
592 
593  if (NULL == zone)
594  {
595  GNUNET_break (0);
596  return GNUNET_SYSERR;
597  }
598  if (GNUNET_OK !=
599  GNUNET_SQ_bind (plugin->lookup_label,
600  params))
601  {
603  "sqlite3_bind_XXXX");
604  GNUNET_SQ_reset (plugin->dbh,
605  plugin->lookup_label);
606  return GNUNET_SYSERR;
607  }
608  return get_records_and_call_iterator (plugin,
609  plugin->lookup_label,
610  zone,
611  1,
612  iter,
613  iter_cls);
614 }
615 
616 
629 static int
631  const struct
633  uint64_t serial,
634  uint64_t limit,
636  void *iter_cls)
637 {
638  struct Plugin *plugin = cls;
639  sqlite3_stmt *stmt;
640  int err;
641 
642  if (NULL == zone)
643  {
644  struct GNUNET_SQ_QueryParam params[] = {
648  };
649 
650  stmt = plugin->iterate_all_zones;
651  err = GNUNET_SQ_bind (stmt,
652  params);
653  }
654  else
655  {
656  struct GNUNET_SQ_QueryParam params[] = {
661  };
662 
663  stmt = plugin->iterate_zone;
664  err = GNUNET_SQ_bind (stmt,
665  params);
666  }
667  if (GNUNET_OK != err)
668  {
669  LOG_SQLITE (plugin,
671  "sqlite3_bind_XXXX");
672  GNUNET_SQ_reset (plugin->dbh,
673  stmt);
674  return GNUNET_SYSERR;
675  }
676  return get_records_and_call_iterator (plugin,
677  stmt,
678  zone,
679  limit,
680  iter,
681  iter_cls);
682 }
683 
684 
696 static int
698  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
699  const struct
700  GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
702  void *iter_cls)
703 {
704  struct Plugin *plugin = cls;
705  struct GNUNET_SQ_QueryParam params[] = {
709  };
710 
711  if (GNUNET_OK !=
712  GNUNET_SQ_bind (plugin->zone_to_name,
713  params))
714  {
715  LOG_SQLITE (plugin,
717  "sqlite3_bind_XXXX");
718  GNUNET_SQ_reset (plugin->dbh,
719  plugin->zone_to_name);
720  return GNUNET_SYSERR;
721  }
723  "Performing reverse lookup for `%s'\n",
724  GNUNET_GNSRECORD_z2s (value_zone));
725  return get_records_and_call_iterator (plugin,
726  plugin->zone_to_name,
727  zone,
728  1,
729  iter,
730  iter_cls);
731 }
732 
733 
740 void *
742 {
743  static struct Plugin plugin;
744  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
746 
747  if (NULL != plugin.cfg)
748  return NULL; /* can only initialize once! */
749  memset (&plugin,
750  0,
751  sizeof(struct Plugin));
752  plugin.cfg = cfg;
753  if (GNUNET_OK != database_setup (&plugin))
754  {
755  database_shutdown (&plugin);
756  return NULL;
757  }
759  api->cls = &plugin;
765  _ ("Sqlite database running\n"));
766  return api;
767 }
768 
769 
776 void *
778 {
780  struct Plugin *plugin = api->cls;
781 
782  database_shutdown (plugin);
783  plugin->cfg = NULL;
784  GNUNET_free (api);
786  "sqlite plugin is finished\n");
787  return NULL;
788 }
789 
790 
791 /* end of plugin_namestore_sqlite.c */
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:544
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
static int get_records_and_call_iterator(struct Plugin *plugin, sqlite3_stmt *stmt, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
The given &#39;sqlite&#39; statement has been prepared to be run.
sqlite3_stmt * iterate_all_zones
Precompiled SQL for iterate all records within all zones.
Description of a DB result cell.
#define GNUNET_SQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t expected.
static int namestore_sqlite_iterate_records(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Iterate over the results for a particular key and zone in the datastore.
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
int(* zone_to_name)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
static int namestore_sqlite_zone_to_name(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
sqlite3_stmt * lookup_label
Precompiled SQL to lookup records based on label.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
void * libgnunet_plugin_namestore_sqlite_done(void *cls)
Exit point from the plugin.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:684
#define GNUNET_SQ_result_spec_end
End of result parameter specification.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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.
Private ECC key encoded for transmission.
void(* GNUNET_NAMESTORE_RecordIterator)(void *cls, uint64_t serial, const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called for each matching record.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
#define GNUNET_SQ_result_spec_auto_from_type(dst)
We expect a fixed-size result, with size determined by the type of * dst
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
#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
struct GNUNET_SQ_PrepareStatement GNUNET_SQ_make_prepare(const char *sql, sqlite3_stmt **pstmt)
Create a struct GNUNET_SQ_PrepareStatement
Definition: sq_prepare.c:37
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
common internal definitions for namestore service
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
static char * zone
Name of the zone we manage.
void * cls
Closure to pass to all plugin functions.
static uint64_t record_count
Record count.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
#define LOG_SQLITE(db, level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; on file &#39;file...
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
static int database_setup(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
int GNUNET_SQ_exec_statements(sqlite3 *dbh, const struct GNUNET_SQ_ExecuteStatement *es)
Request execution of an array of statements es from Postgres.
Definition: sq_exec.c:76
#define GNUNET_GNSRECORD_TYPE_PKEY
Record type for GNS zone transfer ("PKEY").
struct GNUNET_SQ_ExecuteStatement GNUNET_SQ_make_execute(const char *sql)
Create a struct GNUNET_SQ_ExecuteStatement where errors are fatal.
Definition: sq_exec.c:36
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_variable_size(void **dst, size_t *sptr)
Variable-size result expected.
static int result
Global testing status.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
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.
#define LOG(kind,...)
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
sqlite3_stmt * store_records
Precompiled SQL to store records.
void * iter_cls
Iterator cls.
static int namestore_sqlite_lookup_records(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
void * libgnunet_plugin_namestore_sqlite_init(void *cls)
Entry point for the plugin.
helper functions for Sqlite3 DB interactions
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_string(const char *ptr)
Generate query parameter for a string.
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.
#define BUSY_TIMEOUT_MS
After how many ms "busy" should a DB operation fail for good? A low value makes sure that we are more...
char * fn
Filename used for the DB.
#define GNUNET_SQ_PREPARE_END
Terminator for executable statement list.
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.
int(* lookup_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
configuration data
Definition: configuration.c:85
Handle for a plugin.
Definition: block.c:37
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
sqlite3_stmt * delete_records
Precompiled SQL to deltete existing records.
int GNUNET_SQ_prepare(sqlite3 *dbh, const struct GNUNET_SQ_PrepareStatement *ps)
Prepare all statements given in the (NULL,NULL)-terminated array at ps.
Definition: sq_prepare.c:58
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
sqlite3_stmt * iterate_zone
Precompiled SQL for iterate records within a zone.
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
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.
#define GNUNET_SQ_query_param_end
End of query parameter specification.
Definition: gnunet_sq_lib.h:86
#define GNUNET_log_from(kind, comp,...)
sqlite3_stmt * zone_to_name
Precompiled SQL to for reverse lookup based on PKEY.
static int namestore_sqlite_store_records(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_string(char **dst)
0-terminated string expected.
uint32_t data
The data value.
int(* store_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore for which we are the authority.
GNUNET_PEERSTORE_Processor iter
Iterator.
struct returned by the initialization function of the plugin
struct GNUNET_SQ_ExecuteStatement GNUNET_SQ_make_try_execute(const char *sql)
Create a struct GNUNET_SQ_ExecuteStatement where errors should be tolerated.
Definition: sq_exec.c:55
int(* iterate_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Iterate over the results for a particular zone in the datastore.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_free(ptr)
Wrapper around free.