GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
Loading...
Searching...
No Matches
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_sq_lib.h"
31#include <sqlite3.h>
32
43#define BUSY_TIMEOUT_MS 1000
44
45
51#define LOG_SQLITE(db, level, cmd) do { \
52 GNUNET_log_from (level, \
53 "namestore-sqlite", _ ( \
54 "`%s' failed at %s:%d with error: %s\n"), \
55 cmd, \
56 __FILE__, __LINE__, \
57 sqlite3_errmsg ( \
58 db->dbh)); \
59} while (0)
60
61#define LOG(kind, ...) GNUNET_log_from (kind, "namestore-sqlite", __VA_ARGS__)
62
63
67struct Plugin
68{
69 const struct GNUNET_CONFIGURATION_Handle *cfg;
70
74 char *fn;
75
79 bool ready;
80
84 sqlite3 *dbh;
85
89 sqlite3_stmt *store_records;
90
94 sqlite3_stmt *delete_records;
95
99 sqlite3_stmt *iterate_zone;
100
104 sqlite3_stmt *iterate_all_zones;
105
109 sqlite3_stmt *zone_to_name;
110
114 sqlite3_stmt *lookup_label;
115
119 sqlite3_stmt *editor_hint_clear;
120};
121
122
133{
134 struct GNUNET_SQ_ExecuteStatement es[] = {
135 GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
136 GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
137 GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
138 GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
139 GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
140 GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=NORMAL"),
141 GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
142 GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
144 };
145 struct GNUNET_SQ_PrepareStatement ps[] = {
146 GNUNET_SQ_make_prepare ("INSERT INTO ns098records "
147 "(zone_private_key,pkey,rvalue,record_count,record_data,"
148 "label,editor_hint)"
149 " VALUES (?, ?, ?, ?, ?, ?, '')",
150 &plugin->store_records),
151 GNUNET_SQ_make_prepare ("DELETE FROM ns098records "
152 "WHERE zone_private_key=? AND label=?",
153 &plugin->delete_records),
155 "SELECT uid,record_count,record_data,label,editor_hint"
156 " FROM ns098records"
157 " WHERE zone_private_key=? AND pkey=?",
158 &plugin->zone_to_name),
160 "SELECT uid,record_count,record_data,label,editor_hint"
161 " FROM ns098records"
162 " WHERE zone_private_key=? AND uid > ?"
163 " ORDER BY uid ASC"
164 " LIMIT ?",
165 &plugin->iterate_zone),
167 "SELECT uid,record_count,record_data,label,editor_hint,zone_private_key"
168 " FROM ns098records"
169 " WHERE uid > ?"
170 " ORDER BY uid ASC"
171 " LIMIT ?",
172 &plugin->iterate_all_zones),
173 GNUNET_SQ_make_prepare ("UPDATE ns098records as x"
174 " SET editor_hint_old=x.editor_hint, editor_hint=?"
175 " WHERE zone_private_key=? AND label=?"
176 " RETURNING uid,record_count,record_data,label,editor_hint_old",
177 &plugin->lookup_label),
178 GNUNET_SQ_make_prepare ("UPDATE ns098records"
179 " SET editor_hint=?"
180 " FROM ns098records AS old_ns098records"
181 " WHERE ns098records.zone_private_key=? AND ns098records.label=? AND ns098records.editor_hint=?",
182 &plugin->editor_hint_clear),
184 };
185
186 if (plugin->ready)
187 return GNUNET_OK;
188 if (GNUNET_OK !=
190 es))
191 {
193 _ ("Failed to setup database with: `%s'\n"),
194 sqlite3_errmsg (plugin->dbh));
195 return GNUNET_SYSERR;
196 }
197 if (GNUNET_OK !=
199 ps))
200 {
201 GNUNET_break (0);
203 _ ("Failed to setup database with: `%s'\n"),
204 sqlite3_errmsg (plugin->dbh));
205 return GNUNET_SYSERR;
206 }
207 plugin->ready = GNUNET_YES;
208 return GNUNET_OK;
209}
210
211
217static void
219{
220 int result;
221 sqlite3_stmt *stmt;
222
223 if (NULL != plugin->store_records)
224 sqlite3_finalize (plugin->store_records);
225 if (NULL != plugin->delete_records)
226 sqlite3_finalize (plugin->delete_records);
227 if (NULL != plugin->iterate_zone)
228 sqlite3_finalize (plugin->iterate_zone);
229 if (NULL != plugin->iterate_all_zones)
230 sqlite3_finalize (plugin->iterate_all_zones);
231 if (NULL != plugin->zone_to_name)
232 sqlite3_finalize (plugin->zone_to_name);
233 if (NULL != plugin->lookup_label)
234 sqlite3_finalize (plugin->lookup_label);
235 if (NULL != plugin->editor_hint_clear)
236 sqlite3_finalize (plugin->editor_hint_clear);
237 result = sqlite3_close (plugin->dbh);
238 if (result == SQLITE_BUSY)
239 {
241 _ (
242 "Tried to close sqlite without finalizing all prepared statements.\n"));
243 stmt = sqlite3_next_stmt (plugin->dbh,
244 NULL);
245 while (NULL != stmt)
246 {
248 "sqlite",
249 "Closing statement %p\n",
250 stmt);
251 result = sqlite3_finalize (stmt);
252 if (result != SQLITE_OK)
254 "sqlite",
255 "Failed to close statement %p: %d\n",
256 stmt,
257 result);
258 stmt = sqlite3_next_stmt (plugin->dbh,
259 NULL);
260 }
261 result = sqlite3_close (plugin->dbh);
262 }
263 if (SQLITE_OK != result)
266 "sqlite3_close");
267
268}
269
270
284 const struct
286 const char *label,
287 unsigned int rd_count,
288 const struct GNUNET_GNSRECORD_Data *rd)
289{
290 struct Plugin *plugin = cls;
291 int n;
293 uint64_t rvalue;
294 ssize_t data_size;
295
297 memset (&pkey,
298 0,
299 sizeof(pkey));
300 for (unsigned int i = 0; i < rd_count; i++)
301 {
303 "Checking if `%d' is zonekey type\n",
304 rd[i].record_type);
305
306 if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type))
307 {
310 rd[i].data_size,
311 rd[i].record_type,
312 &pkey));
314 "Storing delegation zone record value `%s'\n",
316
317 break;
318 }
319 }
320 rvalue = GNUNET_CRYPTO_random_u64 (UINT64_MAX);
322 rd);
323 if (data_size < 0)
324 {
325 GNUNET_break (0);
326 return GNUNET_SYSERR;
327 }
328 if (data_size > 64 * 65536)
329 {
330 GNUNET_break (0);
331 return GNUNET_SYSERR;
332 }
333 {
334 /* First delete 'old' records */
335 char data[data_size];
336 struct GNUNET_SQ_QueryParam dparams[] = {
340 };
341 ssize_t ret;
342
344 rd,
345 data_size,
346 data);
347 if ((ret < 0) ||
348 (data_size != ret))
349 {
350 GNUNET_break (0);
351 return GNUNET_SYSERR;
352 }
353 if (GNUNET_OK !=
354 GNUNET_SQ_bind (plugin->delete_records,
355 dparams))
356 {
359 "sqlite3_bind_XXXX");
361 plugin->delete_records);
362 return GNUNET_SYSERR;
363 }
364 n = sqlite3_step (plugin->delete_records);
366 plugin->delete_records);
367
368 if (0 != rd_count)
369 {
370 uint32_t rd_count32 = (uint32_t) rd_count;
371 struct GNUNET_SQ_QueryParam sparams[] = {
375 GNUNET_SQ_query_param_uint32 (&rd_count32),
379 };
380
381 if (GNUNET_OK !=
382 GNUNET_SQ_bind (plugin->store_records,
383 sparams))
384 {
387 "sqlite3_bind_XXXX");
389 plugin->store_records);
390 return GNUNET_SYSERR;
391 }
392 n = sqlite3_step (plugin->store_records);
394 plugin->store_records);
395 }
396 }
397 switch (n)
398 {
399 case SQLITE_DONE:
400 if (0 != rd_count)
402 "sqlite",
403 "Record stored\n");
404 else
406 "sqlite",
407 "Record deleted\n");
408 return GNUNET_OK;
409
410 case SQLITE_BUSY:
413 "sqlite3_step");
414 return GNUNET_NO;
415
416 default:
419 "sqlite3_step");
420 return GNUNET_SYSERR;
421 }
422}
423
424
440 sqlite3_stmt *stmt,
441 const struct
443 uint64_t limit,
445 void *iter_cls)
446{
447 int ret;
448 int sret;
449
450 ret = GNUNET_OK;
451 for (uint64_t i = 0; i < limit; i++)
452 {
453 sret = sqlite3_step (stmt);
454
455 if (SQLITE_DONE == sret)
456 {
458 "Iteration done (no results)\n");
459 ret = GNUNET_NO;
460 break;
461 }
462 if (SQLITE_ROW != sret)
463 {
466 "sqlite_step");
468 break;
469 }
470
471 {
472 uint64_t seq;
473 uint32_t record_count;
474 size_t data_size;
475 void *data;
476 char *label;
477 char *editor_hint;
479 struct GNUNET_SQ_ResultSpec rs[] = {
483 &data_size),
485 GNUNET_SQ_result_spec_string (&editor_hint),
487 };
488 struct GNUNET_SQ_ResultSpec rsx[] = {
492 &data_size),
494 GNUNET_SQ_result_spec_string (&editor_hint),
497 };
498
500 (NULL == zone_key)
501 ? rsx
502 : rs);
503 if ((GNUNET_OK != ret) ||
504 (record_count > 64 * 1024))
505 {
506 /* sanity check, don't stack allocate far too much just
507 because database might contain a large value here */
508 GNUNET_break (0);
510 break;
511 }
512 else
513 {
515
516 GNUNET_assert (0 != seq);
517 if (GNUNET_OK !=
519 data,
521 rd))
522 {
523 GNUNET_break (0);
525 break;
526 }
527 else
528 {
529 if (NULL != zone_key)
530 zk = *zone_key;
531 if (NULL != iter)
532 iter (iter_cls,
533 seq,
534 editor_hint,
535 &zk,
536 label,
538 rd);
539 }
540 }
542 }
543 }
545 stmt);
546 return ret;
547}
548
549
561lookup_records (void *cls,
562 const struct
564 const char *label,
566 void *iter_cls,
567 const char *editor_hint)
568{
569 struct Plugin *plugin = cls;
570 struct GNUNET_SQ_QueryParam params[] = {
571 GNUNET_SQ_query_param_string (editor_hint),
575 };
576
578 if (NULL == zone)
579 {
580 GNUNET_break (0);
581 return GNUNET_SYSERR;
582 }
583 if (GNUNET_OK !=
584 GNUNET_SQ_bind (plugin->lookup_label,
585 params))
586 {
588 "sqlite3_bind_XXXX");
590 plugin->lookup_label);
591 return GNUNET_SYSERR;
592 }
594 plugin->lookup_label,
595 zone,
596 1,
597 iter,
598 iter_cls);
599}
600
601
614 const struct
616 const char *label,
618 void *iter_cls)
619{
620 return lookup_records (cls, zone, label, iter, iter_cls, "");
621}
622
623
638 const char *editor_hint,
639 const char *editor_hint_replacement,
640 const struct
642 const char *label)
643{
644 struct Plugin *plugin = cls;
645 int n;
646 struct GNUNET_SQ_QueryParam params[] = {
647 GNUNET_SQ_query_param_string ((NULL == editor_hint_replacement) ? "":
648 editor_hint_replacement),
651 GNUNET_SQ_query_param_string (editor_hint),
653 };
654
656 if (NULL == zone)
657 {
658 GNUNET_break (0);
659 return GNUNET_SYSERR;
660 }
661 if (GNUNET_OK !=
662 GNUNET_SQ_bind (plugin->editor_hint_clear,
663 params))
664 {
666 "sqlite3_bind_XXXX");
668 plugin->editor_hint_clear);
669 return GNUNET_SYSERR;
670 }
671 n = sqlite3_step (plugin->editor_hint_clear);
673 plugin->store_records);
674 switch (n)
675 {
676 case SQLITE_DONE:
678 "sqlite",
679 "Editor hint cleared\n");
680 return GNUNET_OK;
681
682 case SQLITE_BUSY:
685 "sqlite3_step");
686 return GNUNET_NO;
687
688 default:
691 "sqlite3_step");
692 return GNUNET_SYSERR;
693 }
694}
695
696
709 const char *editor_hint,
710 const struct
712 const char *label,
714 void *iter_cls)
715{
716 return lookup_records (cls, zone, label, iter, iter_cls, editor_hint);
717}
718
719
734 const struct
736 uint64_t serial,
737 uint64_t limit,
739 void *iter_cls)
740{
741 struct Plugin *plugin = cls;
742 sqlite3_stmt *stmt;
743 int err;
744
746 if (NULL == zone)
747 {
748 struct GNUNET_SQ_QueryParam params[] = {
752 };
753
754 stmt = plugin->iterate_all_zones;
755 err = GNUNET_SQ_bind (stmt,
756 params);
757 }
758 else
759 {
760 struct GNUNET_SQ_QueryParam params[] = {
765 };
766
767 stmt = plugin->iterate_zone;
768 err = GNUNET_SQ_bind (stmt,
769 params);
770 }
771 if (GNUNET_OK != err)
772 {
775 "sqlite3_bind_XXXX");
777 stmt);
778 return GNUNET_SYSERR;
779 }
781 stmt,
782 zone,
783 limit,
784 iter,
785 iter_cls);
786}
787
788
803 zone,
804 const struct
807 void *iter_cls)
808{
809 struct Plugin *plugin = cls;
810 struct GNUNET_SQ_QueryParam params[] = {
814 };
815
817 if (GNUNET_OK !=
818 GNUNET_SQ_bind (plugin->zone_to_name,
819 params))
820 {
823 "sqlite3_bind_XXXX");
825 plugin->zone_to_name);
826 return GNUNET_SYSERR;
827 }
829 "Performing reverse lookup for `%s'\n",
830 GNUNET_GNSRECORD_z2s (value_zone));
832 plugin->zone_to_name,
833 zone,
834 1,
835 iter,
836 iter_cls);
837}
838
839
842{
843 struct Plugin *plugin = cls;
844 struct GNUNET_SQ_ExecuteStatement es[] = {
845 GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
846 GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
847 GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
848 GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
849 GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
850 GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=NORMAL"),
851 GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
852 GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
853 GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
854 " uid INTEGER PRIMARY KEY,"
855 " zone_private_key BLOB NOT NULL,"
856 " pkey BLOB,"
857 " rvalue INT8 NOT NULL,"
858 " record_count INT NOT NULL,"
859 " record_data BLOB NOT NULL,"
860 " label TEXT NOT NULL,"
861 " editor_hint TEXT NOT NULL,"
862 " editor_hint_old TEXT"
863 ")"),
864 GNUNET_SQ_make_try_execute ("CREATE INDEX ir_pkey_reverse "
865 "ON ns098records (zone_private_key,pkey)"),
866 GNUNET_SQ_make_try_execute ("CREATE INDEX ir_pkey_iter "
867 "ON ns098records (zone_private_key,uid)"),
869 };
870
871 if (GNUNET_OK !=
873 es))
874 {
876 "Failed to setup database with: `%s'\n",
877 sqlite3_errmsg (plugin->dbh));
878 return GNUNET_SYSERR;
879 }
880 return GNUNET_OK;
881}
882
883
886{
887 struct Plugin *plugin = cls;
888 struct GNUNET_SQ_ExecuteStatement es_drop[] = {
889 GNUNET_SQ_make_execute ("DROP TABLE IF EXISTS ns098records"),
891 };
892
893 if (GNUNET_OK !=
895 es_drop))
896 {
898 "Failed to drop database with: `%s'\n",
899 sqlite3_errmsg (plugin->dbh));
900 return GNUNET_SYSERR;
901 }
902 return GNUNET_OK;
903}
904
905
908{
909 struct Plugin *plugin = cls;
910 struct GNUNET_SQ_ExecuteStatement es_drop[] = {
911 GNUNET_SQ_make_execute ("BEGIN"),
913 };
914
915 if (GNUNET_OK !=
917 es_drop))
918 {
920 "Failed to drop database with: `%s'\n",
921 sqlite3_errmsg (plugin->dbh));
922 return GNUNET_SYSERR;
923 }
924 return GNUNET_OK;
925}
926
927
930{
931 struct Plugin *plugin = cls;
932 struct GNUNET_SQ_ExecuteStatement es_drop[] = {
933 GNUNET_SQ_make_execute ("COMMIT"),
935 };
936
937 if (GNUNET_OK !=
939 es_drop))
940 {
942 "Failed to drop database with: `%s'\n",
943 sqlite3_errmsg (plugin->dbh));
944 return GNUNET_SYSERR;
945 }
946 return GNUNET_OK;
947}
948
949
952{
953 struct Plugin *plugin = cls;
954 struct GNUNET_SQ_ExecuteStatement es_drop[] = {
955 GNUNET_SQ_make_execute ("ROLLBACK"),
957 };
958
959 if (GNUNET_OK !=
961 es_drop))
962 {
964 "Failed to drop database with: `%s'\n",
965 sqlite3_errmsg (plugin->dbh));
966 return GNUNET_SYSERR;
967 }
968 return GNUNET_OK;
969}
970
971
982{
983 char *sqlite_filename;
984
985 if (GNUNET_OK !=
987 "namestore-sqlite",
988 "FILENAME",
989 &sqlite_filename))
990 {
992 "namestore-sqlite",
993 "FILENAME");
994 return GNUNET_SYSERR;
995 }
996 if (GNUNET_OK !=
997 GNUNET_DISK_file_test (sqlite_filename))
998 {
999 if (GNUNET_OK !=
1000 GNUNET_DISK_directory_create_for_file (sqlite_filename))
1001 {
1002 GNUNET_break (0);
1003 GNUNET_free (sqlite_filename);
1004 return GNUNET_SYSERR;
1005 }
1006 }
1007
1008 /* Open database and precompile statements */
1009 if ((NULL == plugin->dbh) &&
1010 (SQLITE_OK != sqlite3_open (sqlite_filename,
1011 &plugin->dbh)))
1012 {
1014 _ ("Unable to initialize SQLite: %s.\n"),
1015 sqlite3_errmsg (plugin->dbh));
1016 GNUNET_free (sqlite_filename);
1017 return GNUNET_SYSERR;
1018 }
1019 GNUNET_free (sqlite_filename);
1020 GNUNET_break (SQLITE_OK ==
1021 sqlite3_busy_timeout (plugin->dbh,
1023 if (GNUNET_YES ==
1025 "namestore-sqlite",
1026 "INIT_ON_CONNECT"))
1027 {
1028 if (GNUNET_OK !=
1030 return GNUNET_SYSERR;
1031 }
1032 return GNUNET_OK;
1033}
1034
1035
1036void *
1038
1045void *
1047{
1048 struct Plugin *plugin;
1049 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
1051
1052 plugin = GNUNET_new (struct Plugin);
1053 plugin->cfg = cfg;
1055 {
1057 "Database could not be connected to.\n");
1059 return NULL;
1060 }
1062 api->cls = plugin;
1075 _ ("SQlite database running\n"));
1076 return api;
1077}
1078
1079
1080void *
1082
1089void *
1091{
1093 struct Plugin *plugin = api->cls;
1094
1096 plugin->cfg = NULL;
1098 GNUNET_free (api);
1100 "SQlite plugin is finished\n");
1101 return NULL;
1102}
1103
1104
1105/* end of plugin_namestore_sqlite.c */
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
static uint64_t record_count
Record count.
static char * data
The data to insert into the dht.
static char * pkey
Public key of the zone to look in, in ASCII.
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 size_t data_size
Number of bytes in data.
static int result
Global testing status.
API that can be used to manipulate GNS record data.
Plugin API for the namestore database backend.
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:37
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:75
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:104
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:50
#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:30
void GNUNET_SQ_reset(sqlite3 *dbh, sqlite3_stmt *stmt)
Reset stmt and log error.
Definition sq.c:119
#define GNUNET_SQ_query_param_end
End of query parameter specification.
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(uint64_t max)
Generate a random unsigned 64-bit value.
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:557
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:664
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.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_BlindablePublicKey *z)
Convert a zone to a string (for printing debug messages).
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_CRYPTO_BlindablePublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
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.
#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_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 char *editor_hint, const struct GNUNET_CRYPTO_BlindablePrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called for each matching record.
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static enum GNUNET_GenericReturnValue namestore_sqlite_zone_to_name(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const struct GNUNET_CRYPTO_BlindablePublicKey *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_store_records(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore.
#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_lookup_records(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *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 database_prepare(struct Plugin *plugin)
Initialize the database connections and associated data structures (create tables and indices as need...
static enum GNUNET_GenericReturnValue namestore_sqlite_begin_tx(void *cls)
#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 lookup_records(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls, const char *editor_hint)
Lookup records in the datastore for which we are the authority.
void * libgnunet_plugin_namestore_sqlite_done(void *cls)
Exit point from the plugin.
static enum GNUNET_GenericReturnValue get_records_and_call_iterator(struct Plugin *plugin, sqlite3_stmt *stmt, const struct GNUNET_CRYPTO_BlindablePrivateKey *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 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)
static enum GNUNET_GenericReturnValue namestore_sqlite_commit_tx(void *cls)
static enum GNUNET_GenericReturnValue namestore_sqlite_iterate_records(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *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.
static enum GNUNET_GenericReturnValue namestore_sqlite_editor_hint_clear(void *cls, const char *editor_hint, const char *editor_hint_replacement, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label)
Clear editor hint.
static enum GNUNET_GenericReturnValue namestore_sqlite_edit_records(void *cls, const char *editor_hint, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
#define LOG(kind,...)
static enum GNUNET_GenericReturnValue namestore_sqlite_rollback_tx(void *cls)
void * libgnunet_plugin_namestore_sqlite_init(void *cls)
Entry point for 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(* lookup_records)(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *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(* create_tables)(void *cls)
Setup the database.
enum GNUNET_GenericReturnValue(* rollback_tx)(void *cls)
Tell plugin to rollback what we started with begin_tx This may be a NOP (and thus NOT roll anything b...
enum GNUNET_GenericReturnValue(* zone_to_name)(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const struct GNUNET_CRYPTO_BlindablePublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
enum GNUNET_GenericReturnValue(* begin_tx)(void *cls)
Tell plugin that a set of procedures are coming that are ideally handled within a single TX (BEGIN/CO...
enum GNUNET_GenericReturnValue(* commit_tx)(void *cls)
Tell plugin the we finished what we started with begin_tx.
enum GNUNET_GenericReturnValue(* drop_tables)(void *cls)
Drop existing tables.
enum GNUNET_GenericReturnValue(* store_records)(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *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(* clear_editor_hint)(void *cls, const char *editor_hint, const char *editor_hint_replacement, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label)
This clears the editor hint, unless it does not match the given editor hint, in which case this is a ...
enum GNUNET_GenericReturnValue(* edit_records)(void *cls, const char *editor_hint, const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Transaction-based API draft.
void * cls
Closure to pass to all plugin functions.
enum GNUNET_GenericReturnValue(* iterate_records)(void *cls, const struct GNUNET_CRYPTO_BlindablePrivateKey *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.
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.
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
Set to true if the DB is ready for action.
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 * editor_hint_clear
Precompiled SQL to clear editor hint.
sqlite3_stmt * iterate_zone
Precompiled SQL for iterate records within a zone.