GNUnet  0.10.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, "namestore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0)
54 
55 #define LOG(kind,...) GNUNET_log_from (kind, "namestore-sqlite", __VA_ARGS__)
56 
57 
61 struct Plugin
62 {
63 
64  const struct GNUNET_CONFIGURATION_Handle *cfg;
65 
69  char *fn;
70 
74  sqlite3 *dbh;
75 
79  sqlite3_stmt *store_records;
80 
84  sqlite3_stmt *delete_records;
85 
89  sqlite3_stmt *iterate_zone;
90 
94  sqlite3_stmt *iterate_all_zones;
95 
99  sqlite3_stmt *zone_to_name;
100 
104  sqlite3_stmt *lookup_label;
105 };
106 
107 
116 static int
118 {
119  char *sqlite_filename;
120  struct GNUNET_SQ_ExecuteStatement es[] = {
121  GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
122  GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
123  GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
124  GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
125  GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
126  GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"),
127  GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
128  GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
129  GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
130  " uid INTEGER PRIMARY KEY,"
131  " zone_private_key BLOB NOT NULL,"
132  " pkey BLOB,"
133  " rvalue INT8 NOT NULL,"
134  " record_count INT NOT NULL,"
135  " record_data BLOB NOT NULL,"
136  " label TEXT NOT NULL"
137  ")"),
138  GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse "
139  "ON ns098records (zone_private_key,pkey)"),
140  GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter "
141  "ON ns098records (zone_private_key,uid)"),
143  };
144  struct GNUNET_SQ_PrepareStatement ps[] = {
145  GNUNET_SQ_make_prepare ("INSERT INTO ns098records "
146  "(zone_private_key,pkey,rvalue,record_count,record_data,label)"
147  " VALUES (?, ?, ?, ?, ?, ?)",
148  &plugin->store_records),
149  GNUNET_SQ_make_prepare ("DELETE FROM ns098records "
150  "WHERE zone_private_key=? AND label=?",
151  &plugin->delete_records),
152  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
153  " FROM ns098records"
154  " WHERE zone_private_key=? AND pkey=?",
155  &plugin->zone_to_name),
156  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
157  " FROM ns098records"
158  " WHERE zone_private_key=? AND uid > ?"
159  " ORDER BY uid ASC"
160  " LIMIT ?",
161  &plugin->iterate_zone),
162  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label,zone_private_key"
163  " FROM ns098records"
164  " WHERE uid > ?"
165  " ORDER BY uid ASC"
166  " LIMIT ?",
167  &plugin->iterate_all_zones),
168  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
169  " FROM ns098records"
170  " WHERE zone_private_key=? AND label=?",
171  &plugin->lookup_label),
173  };
174 
175  if (GNUNET_OK !=
177  "namestore-sqlite",
178  "FILENAME",
179  &sqlite_filename))
180  {
182  "namestore-sqlite",
183  "FILENAME");
184  return GNUNET_SYSERR;
185  }
186  if (GNUNET_OK !=
187  GNUNET_DISK_file_test (sqlite_filename))
188  {
189  if (GNUNET_OK !=
190  GNUNET_DISK_directory_create_for_file (sqlite_filename))
191  {
192  GNUNET_break (0);
193  GNUNET_free (sqlite_filename);
194  return GNUNET_SYSERR;
195  }
196  }
197  /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */
198  plugin->fn = sqlite_filename;
199 
200  /* Open database and precompile statements */
201  if (SQLITE_OK !=
202  sqlite3_open (plugin->fn,
203  &plugin->dbh))
204  {
206  _("Unable to initialize SQLite: %s.\n"),
207  sqlite3_errmsg (plugin->dbh));
208  return GNUNET_SYSERR;
209  }
210  GNUNET_break (SQLITE_OK ==
211  sqlite3_busy_timeout (plugin->dbh,
212  BUSY_TIMEOUT_MS));
213  if (GNUNET_OK !=
215  es))
216  {
217  GNUNET_break (0);
219  _("Failed to setup database at `%s'\n"),
220  plugin->fn);
221  return GNUNET_SYSERR;
222  }
223 
224  if (GNUNET_OK !=
225  GNUNET_SQ_prepare (plugin->dbh,
226  ps))
227  {
228  GNUNET_break (0);
230  _("Failed to setup database at `%s'\n"),
231  plugin->fn);
232  return GNUNET_SYSERR;
233  }
234  return GNUNET_OK;
235 }
236 
237 
243 static void
245 {
246  int result;
247  sqlite3_stmt *stmt;
248 
249  if (NULL != plugin->store_records)
250  sqlite3_finalize (plugin->store_records);
251  if (NULL != plugin->delete_records)
252  sqlite3_finalize (plugin->delete_records);
253  if (NULL != plugin->iterate_zone)
254  sqlite3_finalize (plugin->iterate_zone);
255  if (NULL != plugin->iterate_all_zones)
256  sqlite3_finalize (plugin->iterate_all_zones);
257  if (NULL != plugin->zone_to_name)
258  sqlite3_finalize (plugin->zone_to_name);
259  if (NULL != plugin->lookup_label)
260  sqlite3_finalize (plugin->lookup_label);
261  result = sqlite3_close (plugin->dbh);
262  if (result == SQLITE_BUSY)
263  {
265  _("Tried to close sqlite without finalizing all prepared statements.\n"));
266  stmt = sqlite3_next_stmt (plugin->dbh,
267  NULL);
268  while (NULL != stmt)
269  {
271  "sqlite",
272  "Closing statement %p\n",
273  stmt);
274  result = sqlite3_finalize (stmt);
275  if (result != SQLITE_OK)
277  "sqlite",
278  "Failed to close statement %p: %d\n",
279  stmt,
280  result);
281  stmt = sqlite3_next_stmt (plugin->dbh,
282  NULL);
283  }
284  result = sqlite3_close (plugin->dbh);
285  }
286  if (SQLITE_OK != result)
287  LOG_SQLITE (plugin,
289  "sqlite3_close");
290 
291  GNUNET_free_non_null (plugin->fn);
292 }
293 
294 
306 static int
308  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
309  const char *label,
310  unsigned int rd_count,
311  const struct GNUNET_GNSRECORD_Data *rd)
312 {
313  struct Plugin *plugin = cls;
314  int n;
315  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
316  uint64_t rvalue;
317  ssize_t data_size;
318 
319  memset (&pkey,
320  0,
321  sizeof (pkey));
322  for (unsigned int i=0;i<rd_count;i++)
323  if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type)
324  {
325  GNUNET_break (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) ==
326  rd[i].data_size);
327  GNUNET_memcpy (&pkey,
328  rd[i].data,
329  rd[i].data_size);
330  break;
331  }
333  UINT64_MAX);
334  data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
335  rd);
336  if (data_size < 0)
337  {
338  GNUNET_break (0);
339  return GNUNET_SYSERR;
340  }
341  if (data_size > 64 * 65536)
342  {
343  GNUNET_break (0);
344  return GNUNET_SYSERR;
345  }
346  {
347  /* First delete 'old' records */
348  char data[data_size];
349  struct GNUNET_SQ_QueryParam dparams[] = {
353  };
354  ssize_t ret;
355 
356  ret = GNUNET_GNSRECORD_records_serialize (rd_count,
357  rd,
358  data_size,
359  data);
360  if ( (ret < 0) ||
361  (data_size != ret) )
362  {
363  GNUNET_break (0);
364  return GNUNET_SYSERR;
365  }
366  if (GNUNET_OK !=
368  dparams))
369  {
370  LOG_SQLITE (plugin,
372  "sqlite3_bind_XXXX");
373  GNUNET_SQ_reset (plugin->dbh,
374  plugin->delete_records);
375  return GNUNET_SYSERR;
376 
377  }
378  n = sqlite3_step (plugin->delete_records);
379  GNUNET_SQ_reset (plugin->dbh,
380  plugin->delete_records);
381 
382  if (0 != rd_count)
383  {
384  uint32_t rd_count32 = (uint32_t) rd_count;
385  struct GNUNET_SQ_QueryParam sparams[] = {
389  GNUNET_SQ_query_param_uint32 (&rd_count32),
390  GNUNET_SQ_query_param_fixed_size (data, data_size),
393  };
394 
395  if (GNUNET_OK !=
396  GNUNET_SQ_bind (plugin->store_records,
397  sparams))
398  {
399  LOG_SQLITE (plugin,
401  "sqlite3_bind_XXXX");
402  GNUNET_SQ_reset (plugin->dbh,
403  plugin->store_records);
404  return GNUNET_SYSERR;
405  }
406  n = sqlite3_step (plugin->store_records);
407  GNUNET_SQ_reset (plugin->dbh,
408  plugin->store_records);
409  }
410  }
411  switch (n)
412  {
413  case SQLITE_DONE:
414  if (0 != rd_count)
416  "sqlite",
417  "Record stored\n");
418  else
420  "sqlite",
421  "Record deleted\n");
422  return GNUNET_OK;
423  case SQLITE_BUSY:
424  LOG_SQLITE (plugin,
426  "sqlite3_step");
427  return GNUNET_NO;
428  default:
429  LOG_SQLITE (plugin,
431  "sqlite3_step");
432  return GNUNET_SYSERR;
433  }
434 }
435 
436 
450 static int
452  sqlite3_stmt *stmt,
453  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
454  uint64_t limit,
456  void *iter_cls)
457 {
458  int ret;
459  int sret;
460 
461  ret = GNUNET_OK;
462  for (uint64_t i = 0;i<limit;i++)
463  {
464  sret = sqlite3_step (stmt);
465 
466  if (SQLITE_DONE == sret)
467  {
469  "Iteration done (no results)\n");
470  ret = GNUNET_NO;
471  break;
472  }
473  if (SQLITE_ROW != sret)
474  {
475  LOG_SQLITE (plugin,
477  "sqlite_step");
478  ret = GNUNET_SYSERR;
479  break;
480  }
481 
482  {
483  uint64_t seq;
484  uint32_t record_count;
485  size_t data_size;
486  void *data;
487  char *label;
489  struct GNUNET_SQ_ResultSpec rs[] = {
491  GNUNET_SQ_result_spec_uint32 (&record_count),
493  &data_size),
496  };
497  struct GNUNET_SQ_ResultSpec rsx[] = {
499  GNUNET_SQ_result_spec_uint32 (&record_count),
501  &data_size),
505  };
506 
507  ret = GNUNET_SQ_extract_result (stmt,
508  (NULL == zone_key)
509  ? rsx
510  : rs);
511  if ( (GNUNET_OK != ret) ||
512  (record_count > 64 * 1024) )
513  {
514  /* sanity check, don't stack allocate far too much just
515  because database might contain a large value here */
516  GNUNET_break (0);
517  ret = GNUNET_SYSERR;
518  break;
519  }
520  else
521  {
522  struct GNUNET_GNSRECORD_Data rd[record_count];
523 
524  GNUNET_assert (0 != seq);
525  if (GNUNET_OK !=
527  data,
528  record_count,
529  rd))
530  {
531  GNUNET_break (0);
532  ret = GNUNET_SYSERR;
533  break;
534  }
535  else
536  {
537  if (NULL != zone_key)
538  zk = *zone_key;
539  if (NULL != iter)
540  iter (iter_cls,
541  seq,
542  &zk,
543  label,
544  record_count,
545  rd);
546  }
547  }
549  }
550  }
551  GNUNET_SQ_reset (plugin->dbh,
552  stmt);
553  return ret;
554 }
555 
556 
567 static int
569  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
570  const char *label,
572  void *iter_cls)
573 {
574  struct Plugin *plugin = cls;
575  struct GNUNET_SQ_QueryParam params[] = {
579  };
580 
581  if (NULL == zone)
582  {
583  GNUNET_break (0);
584  return GNUNET_SYSERR;
585  }
586  if (GNUNET_OK !=
587  GNUNET_SQ_bind (plugin->lookup_label,
588  params))
589  {
591  "sqlite3_bind_XXXX");
592  GNUNET_SQ_reset (plugin->dbh,
593  plugin->lookup_label);
594  return GNUNET_SYSERR;
595  }
596  return get_records_and_call_iterator (plugin,
597  plugin->lookup_label,
598  zone,
599  1,
600  iter,
601  iter_cls);
602 }
603 
604 
617 static int
619  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
620  uint64_t serial,
621  uint64_t limit,
623  void *iter_cls)
624 {
625  struct Plugin *plugin = cls;
626  sqlite3_stmt *stmt;
627  int err;
628 
629  if (NULL == zone)
630  {
631  struct GNUNET_SQ_QueryParam params[] = {
635  };
636 
637  stmt = plugin->iterate_all_zones;
638  err = GNUNET_SQ_bind (stmt,
639  params);
640  }
641  else
642  {
643  struct GNUNET_SQ_QueryParam params[] = {
648  };
649 
650  stmt = plugin->iterate_zone;
651  err = GNUNET_SQ_bind (stmt,
652  params);
653  }
654  if (GNUNET_OK != err)
655  {
656  LOG_SQLITE (plugin,
658  "sqlite3_bind_XXXX");
659  GNUNET_SQ_reset (plugin->dbh,
660  stmt);
661  return GNUNET_SYSERR;
662  }
663  return get_records_and_call_iterator (plugin,
664  stmt,
665  zone,
666  limit,
667  iter,
668  iter_cls);
669 }
670 
671 
683 static int
685  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
686  const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
688  void *iter_cls)
689 {
690  struct Plugin *plugin = cls;
691  struct GNUNET_SQ_QueryParam params[] = {
695  };
696 
697  if (GNUNET_OK !=
698  GNUNET_SQ_bind (plugin->zone_to_name,
699  params))
700  {
701  LOG_SQLITE (plugin,
703  "sqlite3_bind_XXXX");
704  GNUNET_SQ_reset (plugin->dbh,
705  plugin->zone_to_name);
706  return GNUNET_SYSERR;
707  }
709  "Performing reverse lookup for `%s'\n",
710  GNUNET_GNSRECORD_z2s (value_zone));
711  return get_records_and_call_iterator (plugin,
712  plugin->zone_to_name,
713  zone,
714  1,
715  iter,
716  iter_cls);
717 }
718 
719 
726 void *
728 {
729  static struct Plugin plugin;
730  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
732 
733  if (NULL != plugin.cfg)
734  return NULL; /* can only initialize once! */
735  memset (&plugin,
736  0,
737  sizeof (struct Plugin));
738  plugin.cfg = cfg;
739  if (GNUNET_OK != database_setup (&plugin))
740  {
741  database_shutdown (&plugin);
742  return NULL;
743  }
745  api->cls = &plugin;
751  _("Sqlite database running\n"));
752  return api;
753 }
754 
755 
762 void *
764 {
766  struct Plugin *plugin = api->cls;
767 
768  database_shutdown (plugin);
769  plugin->cfg = NULL;
770  GNUNET_free (api);
772  "sqlite plugin is finished\n");
773  return NULL;
774 }
775 
776 /* 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:669
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.
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.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
#define GNUNET_SQ_result_spec_end
End of result parameter specification.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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
static int ret
Final status code.
Definition: gnunet-arm.c:89
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:208
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.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
#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
#define GNUNET_memcpy(dst, src, n)
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:77
#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
#define LOG(kind,...)
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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
PGconn * 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:59
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:87
#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.
static size_t data_size
Number of bytes in data.
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:56
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.