GNUnet  0.20.0
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 { \
54  GNUNET_log_from (level, \
55  "namestore-sqlite", _ ( \
56  "`%s' failed at %s:%d with error: %s\n"), \
57  cmd, \
58  __FILE__, __LINE__, \
59  sqlite3_errmsg ( \
60  db->dbh)); \
61 } while (0)
62 
63 #define LOG(kind, ...) GNUNET_log_from (kind, "namestore-sqlite", __VA_ARGS__)
64 
65 
69 struct Plugin
70 {
71  const struct GNUNET_CONFIGURATION_Handle *cfg;
72 
76  char *fn;
77 
81  bool ready;
82 
86  sqlite3 *dbh;
87 
91  sqlite3_stmt *store_records;
92 
96  sqlite3_stmt *delete_records;
97 
101  sqlite3_stmt *iterate_zone;
102 
106  sqlite3_stmt *iterate_all_zones;
107 
111  sqlite3_stmt *zone_to_name;
112 
116  sqlite3_stmt *lookup_label;
117 };
118 
119 
128 static enum GNUNET_GenericReturnValue
130 {
131  if (plugin->ready)
132  return GNUNET_OK;
133  struct GNUNET_SQ_ExecuteStatement es[] = {
134  GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
135  GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
136  GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
137  GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
138  GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
139  GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=NORMAL"),
140  GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
141  GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
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),
163  "SELECT uid,record_count,record_data,label,zone_private_key"
164  " FROM ns098records"
165  " WHERE uid > ?"
166  " ORDER BY uid ASC"
167  " LIMIT ?",
168  &plugin->iterate_all_zones),
169  GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
170  " FROM ns098records"
171  " WHERE zone_private_key=? AND label=?",
172  &plugin->lookup_label),
174  };
175 
176  if (GNUNET_OK !=
178  es))
179  {
181  _ ("Failed to setup database with: `%s'\n"),
182  sqlite3_errmsg (plugin->dbh));
183  return GNUNET_SYSERR;
184  }
185  if (GNUNET_OK !=
187  ps))
188  {
189  GNUNET_break (0);
191  _ ("Failed to setup database with: `%s'\n"),
192  sqlite3_errmsg (plugin->dbh));
193  return GNUNET_SYSERR;
194  }
195  plugin->ready = GNUNET_YES;
196  return GNUNET_OK;
197 }
198 
199 
205 static void
207 {
208  int result;
209  sqlite3_stmt *stmt;
210 
211  if (NULL != plugin->store_records)
212  sqlite3_finalize (plugin->store_records);
213  if (NULL != plugin->delete_records)
214  sqlite3_finalize (plugin->delete_records);
215  if (NULL != plugin->iterate_zone)
216  sqlite3_finalize (plugin->iterate_zone);
217  if (NULL != plugin->iterate_all_zones)
218  sqlite3_finalize (plugin->iterate_all_zones);
219  if (NULL != plugin->zone_to_name)
220  sqlite3_finalize (plugin->zone_to_name);
221  if (NULL != plugin->lookup_label)
222  sqlite3_finalize (plugin->lookup_label);
223  result = sqlite3_close (plugin->dbh);
224  if (result == SQLITE_BUSY)
225  {
227  _ (
228  "Tried to close sqlite without finalizing all prepared statements.\n"));
229  stmt = sqlite3_next_stmt (plugin->dbh,
230  NULL);
231  while (NULL != stmt)
232  {
234  "sqlite",
235  "Closing statement %p\n",
236  stmt);
237  result = sqlite3_finalize (stmt);
238  if (result != SQLITE_OK)
240  "sqlite",
241  "Failed to close statement %p: %d\n",
242  stmt,
243  result);
244  stmt = sqlite3_next_stmt (plugin->dbh,
245  NULL);
246  }
247  result = sqlite3_close (plugin->dbh);
248  }
249  if (SQLITE_OK != result)
252  "sqlite3_close");
253 
254 }
255 
256 
268 static enum GNUNET_GenericReturnValue
270  const struct
272  const char *label,
273  unsigned int rd_count,
274  const struct GNUNET_GNSRECORD_Data *rd)
275 {
276  struct Plugin *plugin = cls;
277  int n;
279  uint64_t rvalue;
280  ssize_t data_size;
281 
283  memset (&pkey,
284  0,
285  sizeof(pkey));
286  for (unsigned int i = 0; i < rd_count; i++)
287  {
289  "Checking if `%d' is zonekey type\n",
290  rd[i].record_type);
291 
292  if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type))
293  {
296  rd[i].data_size,
297  rd[i].record_type,
298  &pkey));
300  "Storing delegation zone record value `%s'\n",
302 
303  break;
304  }
305  }
307  UINT64_MAX);
309  rd);
310  if (data_size < 0)
311  {
312  GNUNET_break (0);
313  return GNUNET_SYSERR;
314  }
315  if (data_size > 64 * 65536)
316  {
317  GNUNET_break (0);
318  return GNUNET_SYSERR;
319  }
320  {
321  /* First delete 'old' records */
322  char data[data_size];
323  struct GNUNET_SQ_QueryParam dparams[] = {
327  };
328  ssize_t ret;
329 
331  rd,
332  data_size,
333  data);
334  if ((ret < 0) ||
335  (data_size != ret))
336  {
337  GNUNET_break (0);
338  return GNUNET_SYSERR;
339  }
340  if (GNUNET_OK !=
341  GNUNET_SQ_bind (plugin->delete_records,
342  dparams))
343  {
346  "sqlite3_bind_XXXX");
347  GNUNET_SQ_reset (plugin->dbh,
348  plugin->delete_records);
349  return GNUNET_SYSERR;
350  }
351  n = sqlite3_step (plugin->delete_records);
352  GNUNET_SQ_reset (plugin->dbh,
353  plugin->delete_records);
354 
355  if (0 != rd_count)
356  {
357  uint32_t rd_count32 = (uint32_t) rd_count;
358  struct GNUNET_SQ_QueryParam sparams[] = {
362  GNUNET_SQ_query_param_uint32 (&rd_count32),
366  };
367 
368  if (GNUNET_OK !=
369  GNUNET_SQ_bind (plugin->store_records,
370  sparams))
371  {
374  "sqlite3_bind_XXXX");
375  GNUNET_SQ_reset (plugin->dbh,
376  plugin->store_records);
377  return GNUNET_SYSERR;
378  }
379  n = sqlite3_step (plugin->store_records);
380  GNUNET_SQ_reset (plugin->dbh,
381  plugin->store_records);
382  }
383  }
384  switch (n)
385  {
386  case SQLITE_DONE:
387  if (0 != rd_count)
389  "sqlite",
390  "Record stored\n");
391  else
393  "sqlite",
394  "Record deleted\n");
395  return GNUNET_OK;
396 
397  case SQLITE_BUSY:
400  "sqlite3_step");
401  return GNUNET_NO;
402 
403  default:
406  "sqlite3_step");
407  return GNUNET_SYSERR;
408  }
409 }
410 
411 
425 static enum GNUNET_GenericReturnValue
427  sqlite3_stmt *stmt,
428  const struct
430  uint64_t limit,
432  void *iter_cls)
433 {
434  int ret;
435  int sret;
436 
437  ret = GNUNET_OK;
438  for (uint64_t i = 0; i < limit; i++)
439  {
440  sret = sqlite3_step (stmt);
441 
442  if (SQLITE_DONE == sret)
443  {
445  "Iteration done (no results)\n");
446  ret = GNUNET_NO;
447  break;
448  }
449  if (SQLITE_ROW != sret)
450  {
453  "sqlite_step");
454  ret = GNUNET_SYSERR;
455  break;
456  }
457 
458  {
459  uint64_t seq;
460  uint32_t record_count;
461  size_t data_size;
462  void *data;
463  char *label;
464  struct GNUNET_IDENTITY_PrivateKey zk;
465  struct GNUNET_SQ_ResultSpec rs[] = {
469  &data_size),
472  };
473  struct GNUNET_SQ_ResultSpec rsx[] = {
477  &data_size),
481  };
482 
484  (NULL == zone_key)
485  ? rsx
486  : rs);
487  if ((GNUNET_OK != ret) ||
488  (record_count > 64 * 1024))
489  {
490  /* sanity check, don't stack allocate far too much just
491  because database might contain a large value here */
492  GNUNET_break (0);
493  ret = GNUNET_SYSERR;
494  break;
495  }
496  else
497  {
499 
500  GNUNET_assert (0 != seq);
501  if (GNUNET_OK !=
503  data,
504  record_count,
505  rd))
506  {
507  GNUNET_break (0);
508  ret = GNUNET_SYSERR;
509  break;
510  }
511  else
512  {
513  if (NULL != zone_key)
514  zk = *zone_key;
515  if (NULL != iter)
516  iter (iter_cls,
517  seq,
518  &zk,
519  label,
520  record_count,
521  rd);
522  }
523  }
525  }
526  }
527  GNUNET_SQ_reset (plugin->dbh,
528  stmt);
529  return ret;
530 }
531 
532 
543 static enum GNUNET_GenericReturnValue
545  const struct
547  const char *label,
549  void *iter_cls)
550 {
551  struct Plugin *plugin = cls;
553  struct GNUNET_SQ_QueryParam params[] = {
557  };
558 
559  if (NULL == zone)
560  {
561  GNUNET_break (0);
562  return GNUNET_SYSERR;
563  }
564  if (GNUNET_OK !=
565  GNUNET_SQ_bind (plugin->lookup_label,
566  params))
567  {
569  "sqlite3_bind_XXXX");
570  GNUNET_SQ_reset (plugin->dbh,
571  plugin->lookup_label);
572  return GNUNET_SYSERR;
573  }
575  plugin->lookup_label,
576  zone,
577  1,
578  iter,
579  iter_cls);
580 }
581 
582 
595 static enum GNUNET_GenericReturnValue
597  const struct
599  uint64_t serial,
600  uint64_t limit,
602  void *iter_cls)
603 {
604  struct Plugin *plugin = cls;
605  sqlite3_stmt *stmt;
606  int err;
607 
609  if (NULL == zone)
610  {
611  struct GNUNET_SQ_QueryParam params[] = {
615  };
616 
617  stmt = plugin->iterate_all_zones;
618  err = GNUNET_SQ_bind (stmt,
619  params);
620  }
621  else
622  {
623  struct GNUNET_SQ_QueryParam params[] = {
628  };
629 
630  stmt = plugin->iterate_zone;
631  err = GNUNET_SQ_bind (stmt,
632  params);
633  }
634  if (GNUNET_OK != err)
635  {
638  "sqlite3_bind_XXXX");
639  GNUNET_SQ_reset (plugin->dbh,
640  stmt);
641  return GNUNET_SYSERR;
642  }
644  stmt,
645  zone,
646  limit,
647  iter,
648  iter_cls);
649 }
650 
651 
663 static enum GNUNET_GenericReturnValue
665  const struct GNUNET_IDENTITY_PrivateKey *zone,
666  const struct
667  GNUNET_IDENTITY_PublicKey *value_zone,
669  void *iter_cls)
670 {
671  struct Plugin *plugin = cls;
673  struct GNUNET_SQ_QueryParam params[] = {
677  };
678 
679  if (GNUNET_OK !=
680  GNUNET_SQ_bind (plugin->zone_to_name,
681  params))
682  {
685  "sqlite3_bind_XXXX");
686  GNUNET_SQ_reset (plugin->dbh,
687  plugin->zone_to_name);
688  return GNUNET_SYSERR;
689  }
691  "Performing reverse lookup for `%s'\n",
692  GNUNET_GNSRECORD_z2s (value_zone));
694  plugin->zone_to_name,
695  zone,
696  1,
697  iter,
698  iter_cls);
699 }
700 
701 
712 static enum GNUNET_GenericReturnValue
714  char **emsg)
715 {
716  struct Plugin *plugin = cls;
717  int rc;
718  char *sqlEmsg;
719 
721  rc = sqlite3_exec (plugin->dbh, "BEGIN IMMEDIATE TRANSACTION;",
722  NULL, NULL, &sqlEmsg);
723  if (SQLITE_OK != rc)
724  {
725  *emsg = GNUNET_strdup (sqlEmsg);
726  sqlite3_free (sqlEmsg);
727  }
728  return (SQLITE_OK != rc) ? GNUNET_SYSERR : GNUNET_YES;
729 }
730 
731 
740 static enum GNUNET_GenericReturnValue
742  char **emsg)
743 {
744  struct Plugin *plugin = cls;
745  int rc;
746  char *sqlEmsg;
747 
749  rc = sqlite3_exec (plugin->dbh, "ROLLBACK;",
750  NULL, NULL, &sqlEmsg);
751  if (SQLITE_OK != rc)
752  {
753  *emsg = GNUNET_strdup (sqlEmsg);
754  sqlite3_free (sqlEmsg);
755  }
756  return (SQLITE_OK != rc) ? GNUNET_SYSERR : GNUNET_YES;
757 }
758 
759 
768 static enum GNUNET_GenericReturnValue
770  char **emsg)
771 {
772  struct Plugin *plugin = cls;
773  int rc;
774  char *sqlEmsg;
775 
777  rc = sqlite3_exec (plugin->dbh, "END TRANSACTION;",
778  NULL, NULL, &sqlEmsg);
779  if (SQLITE_OK != rc)
780  {
781  *emsg = GNUNET_strdup (sqlEmsg);
782  sqlite3_free (sqlEmsg);
783  }
784  return (SQLITE_OK != rc) ? GNUNET_SYSERR : GNUNET_YES;
785 }
786 
787 
788 static enum GNUNET_GenericReturnValue
790 {
791  struct Plugin *plugin = cls;
792  struct GNUNET_SQ_ExecuteStatement es[] = {
793  GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
794  GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
795  GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
796  GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
797  GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
798  GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=NORMAL"),
799  GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
800  GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
801  GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
802  " uid INTEGER PRIMARY KEY,"
803  " zone_private_key BLOB NOT NULL,"
804  " pkey BLOB,"
805  " rvalue INT8 NOT NULL,"
806  " record_count INT NOT NULL,"
807  " record_data BLOB NOT NULL,"
808  " label TEXT NOT NULL"
809  ")"),
810  GNUNET_SQ_make_try_execute ("CREATE INDEX ir_pkey_reverse "
811  "ON ns098records (zone_private_key,pkey)"),
812  GNUNET_SQ_make_try_execute ("CREATE INDEX ir_pkey_iter "
813  "ON ns098records (zone_private_key,uid)"),
815  };
816 
817  if (GNUNET_OK !=
819  es))
820  {
822  "Failed to setup database with: `%s'\n",
823  sqlite3_errmsg (plugin->dbh));
824  return GNUNET_SYSERR;
825  }
826  return GNUNET_OK;
827 }
828 
829 
830 static enum GNUNET_GenericReturnValue
832 {
833  struct Plugin *plugin = cls;
834  struct GNUNET_SQ_ExecuteStatement es_drop[] = {
835  GNUNET_SQ_make_execute ("DROP TABLE IF EXISTS ns098records"),
837  };
838 
839  if (GNUNET_OK !=
841  es_drop))
842  {
844  "Failed to drop database with: `%s'\n",
845  sqlite3_errmsg (plugin->dbh));
846  return GNUNET_SYSERR;
847  }
848  return GNUNET_OK;
849 }
850 
851 
860 static enum GNUNET_GenericReturnValue
862 {
863  char *sqlite_filename;
864 
865  if (GNUNET_OK !=
867  "namestore-sqlite",
868  "FILENAME",
869  &sqlite_filename))
870  {
872  "namestore-sqlite",
873  "FILENAME");
874  return GNUNET_SYSERR;
875  }
876  if (GNUNET_OK !=
877  GNUNET_DISK_file_test (sqlite_filename))
878  {
879  if (GNUNET_OK !=
880  GNUNET_DISK_directory_create_for_file (sqlite_filename))
881  {
882  GNUNET_break (0);
883  GNUNET_free (sqlite_filename);
884  return GNUNET_SYSERR;
885  }
886  }
887 
888  /* Open database and precompile statements */
889  if ((NULL == plugin->dbh) &&
890  (SQLITE_OK != sqlite3_open (sqlite_filename,
891  &plugin->dbh)))
892  {
894  _ ("Unable to initialize SQLite: %s.\n"),
895  sqlite3_errmsg (plugin->dbh));
896  GNUNET_free (sqlite_filename);
897  return GNUNET_SYSERR;
898  }
899  GNUNET_free (sqlite_filename);
900  GNUNET_break (SQLITE_OK ==
901  sqlite3_busy_timeout (plugin->dbh,
902  BUSY_TIMEOUT_MS));
903  if (GNUNET_YES ==
905  "namestore-sqlite",
906  "INIT_ON_CONNECT"))
907  {
908  if (GNUNET_OK !=
910  return GNUNET_SYSERR;
911  }
912  return GNUNET_OK;
913 }
914 
915 
922 void *
924 {
925  struct Plugin *plugin;
926  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
928 
929  plugin = GNUNET_new (struct Plugin);
930  plugin->cfg = cfg;
932  {
934  "Database could not be connected to.\n");
936  return NULL;
937  }
939  api->cls = plugin;
956  _ ("SQlite database running\n"));
957  return api;
958 }
959 
960 
967 void *
969 {
971  struct Plugin *plugin = api->cls;
972 
974  plugin->cfg = NULL;
976  GNUNET_free (api);
978  "SQlite plugin is finished\n");
979  return NULL;
980 }
981 
982 
983 /* end of plugin_namestore_sqlite.c */
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct TestcasePlugin * plugin
The process handle to the testbed service.
static uint64_t record_count
Record count.
uint32_t data
The data value.
static char * pkey
Public key of the zone to look in, in ASCII.
static char * zone
Name of the zone being managed.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static int result
Global testing status.
API that can be used to manipulate GNS record data.
Plugin API for the namestore database backend.
API that can be used to store naming information on a GNUnet node;.
helper functions for Sqlite3 DB interactions
struct GNUNET_SQ_PrepareStatement GNUNET_SQ_make_prepare(const char *sql, sqlite3_stmt **pstmt)
Create a struct GNUNET_SQ_PrepareStatement
Definition: sq_prepare.c:38
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_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
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_PREPARE_END
Terminator for executable statement list.
enum GNUNET_GenericReturnValue 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:76
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:105
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_string(char **dst)
0-terminated string expected.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint16_t in host byte order.
enum GNUNET_GenericReturnValue 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
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t expected.
enum GNUNET_GenericReturnValue 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:51
#define GNUNET_SQ_EXECUTE_STATEMENT_END
Terminator for executable statement list.
#define GNUNET_SQ_result_spec_end
End of result parameter specification.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_variable_size(void **dst, size_t *sptr)
Variable-size result expected.
#define GNUNET_SQ_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
enum GNUNET_GenericReturnValue GNUNET_SQ_bind(sqlite3_stmt *stmt, const struct GNUNET_SQ_QueryParam *params)
Execute binding operations for a prepared statement.
Definition: sq.c:31
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
Definition: sq.c:120
#define GNUNET_SQ_query_param_end
End of query parameter specification.
Definition: gnunet_sq_lib.h:87
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_string(const char *ptr)
Generate query parameter for a string.
#define GNUNET_SQ_result_spec_auto_from_type(dst)
We expect a fixed-size result, with size determined by the type of * dst
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint64(uint64_t *u64)
uint64_t expected.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue 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".
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
enum GNUNET_GenericReturnValue 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:482
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_IDENTITY_PublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
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.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_is_zonekey_type(uint32_t type)
Check if this type is one of the supported GNS zone types.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_IDENTITY_PublicKey *z)
Convert a zone to a string (for printing debug messages).
#define GNUNET_log(kind,...)
#define GNUNET_log_from(kind, comp,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void(* GNUNET_NAMESTORE_RecordIterator)(void *cls, uint64_t serial, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called for each matching record.
common internal definitions for namestore service
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
#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...
static enum GNUNET_GenericReturnValue namestore_sqlite_transaction_begin(void *cls, char **emsg)
Begin a transaction for a client.
static enum GNUNET_GenericReturnValue get_records_and_call_iterator(struct Plugin *plugin, sqlite3_stmt *stmt, const struct GNUNET_IDENTITY_PrivateKey *zone_key, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
The given 'sqlite' statement has been prepared to be run.
static enum GNUNET_GenericReturnValue database_prepare(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
#define LOG_SQLITE(db, level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' on file 'file...
static enum GNUNET_GenericReturnValue namestore_sqlite_lookup_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
static enum GNUNET_GenericReturnValue namestore_sqlite_create_tables(void *cls)
static void database_shutdown(struct Plugin *plugin)
Shutdown database connection and associate data structures.
static enum GNUNET_GenericReturnValue namestore_sqlite_drop_tables(void *cls)
void * libgnunet_plugin_namestore_sqlite_init(void *cls)
Entry point for the plugin.
static enum GNUNET_GenericReturnValue namestore_sqlite_store_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore.
static enum GNUNET_GenericReturnValue namestore_sqlite_iterate_records(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
#define LOG(kind,...)
static enum GNUNET_GenericReturnValue namestore_sqlite_transaction_rollback(void *cls, char **emsg)
Commit a transaction for a client.
static enum GNUNET_GenericReturnValue namestore_sqlite_zone_to_name(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
static enum GNUNET_GenericReturnValue namestore_sqlite_transaction_commit(void *cls, char **emsg)
Roll back a transaction for a client.
void * libgnunet_plugin_namestore_sqlite_done(void *cls)
Exit point from the plugin.
static enum GNUNET_GenericReturnValue database_connect(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
void * cls
Closure for all of the callbacks.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
struct returned by the initialization function of the plugin
enum GNUNET_GenericReturnValue(* create_tables)(void *cls)
Setup the database.
enum GNUNET_GenericReturnValue(* store_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
enum GNUNET_GenericReturnValue(* lookup_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
enum GNUNET_GenericReturnValue(* transaction_begin)(void *cls, char **emsg)
Transaction-based API draft.
enum GNUNET_GenericReturnValue(* iterate_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
enum GNUNET_GenericReturnValue(* zone_to_name)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
enum GNUNET_GenericReturnValue(* drop_tables)(void *cls)
Drop existing tables.
enum GNUNET_GenericReturnValue(* transaction_commit)(void *cls, char **emsg)
Commit a transaction in the database.
void * cls
Closure to pass to all plugin functions.
enum GNUNET_GenericReturnValue(* transaction_rollback)(void *cls, char **emsg)
Abort and roll back a transaction in the database.
enum GNUNET_GenericReturnValue(* edit_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Edit records in the datastore for which we are the authority.
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
Information needed to run a list of SQL statements using GNUNET_SQ_exec_statements().
Description of a DB query parameter.
Definition: gnunet_sq_lib.h:56
Description of a DB result cell.
Handle for a plugin.
Definition: block.c:38
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
sqlite3_stmt * iterate_all_zones
Precompiled SQL for iterate all records within all zones.
sqlite3_stmt * delete_records
Precompiled SQL to deltete existing records.
bool ready
Database is prepared and ready.
char * fn
Filename used for the DB.
sqlite3_stmt * store_records
Precompiled SQL to store records.
sqlite3_stmt * zone_to_name
Precompiled SQL to for reverse lookup based on PKEY.
sqlite3_stmt * lookup_label
Precompiled SQL to lookup records based on label.
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
sqlite3_stmt * iterate_zone
Precompiled SQL for iterate records within a zone.