GNUnet 0.28.0-dev.2-27-gc87478450
 
Loading...
Searching...
No Matches
plugin_datacache_sqlite.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2006, 2009, 2015, 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
26#include "platform.h"
27#include "gnunet_util_lib.h"
29#include "gnunet_sq_lib.h"
30#include <sqlite3.h>
31
32#define LOG(kind, ...) GNUNET_log_from (kind, "datacache-sqlite", __VA_ARGS__)
33
34#define LOG_STRERROR_FILE(kind, op, fn) \
35 GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn)
36
37
42#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36)
43
47struct Plugin
48{
53
57 sqlite3 *dbh;
58
62 char *fn;
63
67 sqlite3_stmt *insert_stmt;
68
72 sqlite3_stmt *get_count_stmt;
73
77 sqlite3_stmt *get_count_any_stmt;
78
82 sqlite3_stmt *get_stmt;
83
87 sqlite3_stmt *get_any_stmt;
88
92 sqlite3_stmt *del_select_stmt;
93
97 sqlite3_stmt *del_expired_stmt;
98
102 sqlite3_stmt *del_stmt;
103
107 sqlite3_stmt *get_closest_stmt;
108
112 unsigned int num_items;
113};
114
115
124#define LOG_SQLITE(db, level, cmd) \
125 do \
126 { \
127 LOG (level, \
128 _ ("`%s' failed at %s:%d with error: %s\n"), \
129 cmd, \
130 __FILE__, \
131 __LINE__, \
132 sqlite3_errmsg (db)); \
133 } while (0)
134
135
142#define SQLITE3_EXEC(db, cmd) \
143 do \
144 { \
145 emsg = NULL; \
146 if (SQLITE_OK != \
147 sqlite3_exec (db, cmd, NULL, NULL, &emsg)) \
148 { \
149 LOG (GNUNET_ERROR_TYPE_ERROR, \
150 _ ("`%s' failed at %s:%d with error: %s\n"), \
151 "sqlite3_exec", \
152 __FILE__, \
153 __LINE__, \
154 emsg); \
155 sqlite3_free (emsg); \
156 } \
157 } while (0)
158
159
168static int
169sq_prepare (sqlite3 *dbh,
170 const char *zSql, /* SQL statement, UTF-8 encoded */
171 sqlite3_stmt **ppStmt)
172{ /* OUT: Statement handle */
173 char *dummy;
174
175 return sqlite3_prepare (dbh,
176 zSql,
177 strlen (zSql),
178 ppStmt,
179 (const char **) &dummy);
180}
181
182
191static ssize_t
193 uint32_t xor_distance,
194 const struct GNUNET_DATACACHE_Block *block)
195{
196 struct Plugin *plugin = cls;
197 uint32_t type32 = (uint32_t) block->type;
198 uint32_t ro32 = (uint32_t) block->ro;
199 struct GNUNET_SQ_QueryParam params[] = {
204 GNUNET_SQ_query_param_uint32 (&xor_distance),
206 block->data_size),
208 block->put_path_length
209 * sizeof(struct GNUNET_DHT_PathElement)),
212 };
213
215 "Processing PUT of %u bytes with key `%s' and expiration %s\n",
216 (unsigned int) block->data_size,
217 GNUNET_h2s (&block->key),
220 block->expiration_time),
221 GNUNET_YES));
222 if (GNUNET_OK !=
223 GNUNET_SQ_bind (plugin->insert_stmt,
224 params))
225 {
226 LOG_SQLITE (plugin->dbh,
228 "sqlite3_bind_xxx");
230 plugin->insert_stmt);
231 return -1;
232 }
233 if (SQLITE_DONE !=
234 sqlite3_step (plugin->insert_stmt))
235 {
236 LOG_SQLITE (plugin->dbh,
238 "sqlite3_step");
240 plugin->insert_stmt);
241 return -1;
242 }
243 plugin->num_items++;
245 plugin->insert_stmt);
246 return block->data_size + OVERHEAD;
247}
248
249
260static unsigned int
261get_any (void *cls,
262 const struct GNUNET_HashCode *key,
264 void *iter_cls)
265{
266 struct Plugin *plugin = cls;
267 struct GNUNET_TIME_Absolute now;
268 unsigned int cnt;
269 uint32_t off;
270 uint32_t btype32;
271 uint32_t bro32;
272 unsigned int total;
273 struct GNUNET_DATACACHE_Block block;
274 void *path;
275 void *data;
276 size_t path_size;
277
279 {
280 struct GNUNET_SQ_QueryParam params_count[] = {
284 };
286 "Processing GET for key `%s'\n",
287 GNUNET_h2s (key));
288
289 if (GNUNET_OK !=
290 GNUNET_SQ_bind (plugin->get_count_any_stmt,
291 params_count))
292 {
293 LOG_SQLITE (plugin->dbh,
295 "sqlite3_bind_xxx");
297 plugin->get_count_any_stmt);
298 return 0;
299 }
300 if (SQLITE_ROW !=
301 sqlite3_step (plugin->get_count_any_stmt))
302 {
303 LOG_SQLITE (plugin->dbh,
305 "sqlite_step");
307 plugin->get_count_any_stmt);
309 "No content found when processing GET for key `%s'\n",
310 GNUNET_h2s (key));
311 return 0;
312 }
313 total = sqlite3_column_int (plugin->get_count_any_stmt,
314 0);
316 plugin->get_count_any_stmt);
317 if ( (0 == total) ||
318 (NULL == iter) )
319 {
320 if (0 == total)
322 "No content found when processing GET for key `%s'\n",
323 GNUNET_h2s (key));
324 return total;
325 }
326 }
327 cnt = 0;
328 block.key = *key;
329 off = GNUNET_CRYPTO_random_u32 (total);
330 {
331 struct GNUNET_SQ_QueryParam params_select[] = {
336 };
337 struct GNUNET_SQ_ResultSpec rs[] = {
339 &block.data_size),
342 &path_size),
347 };
348
349 while (cnt < total)
350 {
351 off = (off + 1) % total;
352 if (GNUNET_OK !=
353 GNUNET_SQ_bind (plugin->get_any_stmt,
354 params_select))
355 {
356 LOG_SQLITE (plugin->dbh,
358 "sqlite3_bind_xxx");
360 plugin->get_any_stmt);
361 return cnt;
362 }
363 if (SQLITE_ROW !=
364 sqlite3_step (plugin->get_any_stmt))
365 break;
366 if (GNUNET_OK !=
367 GNUNET_SQ_extract_result (plugin->get_any_stmt,
368 rs))
369 {
370 GNUNET_break (0);
372 plugin->get_any_stmt);
373 break;
374 }
375 if (0 != path_size % sizeof(struct GNUNET_DHT_PathElement))
376 {
377 GNUNET_break (0);
378 path_size = 0;
379 path = NULL;
380 }
381 block.data = data;
382 block.put_path = path;
383 block.put_path_length = path_size / sizeof(struct GNUNET_DHT_PathElement);
384 block.type = (enum GNUNET_BLOCK_Type) btype32;
385 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
386 cnt++;
388 "Found %u-byte result when processing GET for key `%s'\n",
389 (unsigned int) block.data_size,
390 GNUNET_h2s (&block.key));
391 if (GNUNET_OK !=
392 iter (iter_cls,
393 &block))
394 {
397 plugin->get_any_stmt);
398 break;
399 }
402 plugin->get_any_stmt);
403 }
405 plugin->get_any_stmt);
406 }
407
408 return cnt;
409}
410
411
423static unsigned int
424get_typed (void *cls,
425 const struct GNUNET_HashCode *key,
428 void *iter_cls)
429{
430 struct Plugin *plugin = cls;
431 uint32_t type32 = type;
432 struct GNUNET_TIME_Absolute now;
433 unsigned int cnt;
434 uint32_t off;
435 uint32_t bro32;
436 unsigned int total;
437 struct GNUNET_DATACACHE_Block block;
438 void *path;
439 void *data;
440 size_t path_size;
441 struct GNUNET_SQ_ResultSpec rs[] = {
443 &block.data_size),
446 &path_size),
450 };
451
454 "Processing GET for key `%s'\n",
455 GNUNET_h2s (key));
456 {
457 struct GNUNET_SQ_QueryParam params_count[] = {
462 };
463
464 if (GNUNET_OK !=
465 GNUNET_SQ_bind (plugin->get_count_stmt,
466 params_count))
467 {
468 LOG_SQLITE (plugin->dbh,
470 "sqlite3_bind_xxx");
472 plugin->get_count_stmt);
473 return 0;
474 }
475 }
476 if (SQLITE_ROW !=
477 sqlite3_step (plugin->get_count_stmt))
478 {
479 LOG_SQLITE (plugin->dbh,
481 "sqlite_step");
483 plugin->get_count_stmt);
485 "No content found when processing GET for key `%s'\n",
486 GNUNET_h2s (key));
487 return 0;
488 }
489 total = sqlite3_column_int (plugin->get_count_stmt,
490 0);
492 plugin->get_count_stmt);
493 if ( (0 == total) ||
494 (NULL == iter) )
495 {
496 if (0 == total)
498 "No content found when processing GET for key `%s'\n",
499 GNUNET_h2s (key));
500 return total;
501 }
502
503 cnt = 0;
504 block.key = *key;
505 off = GNUNET_CRYPTO_random_u32 (total);
506 {
507 struct GNUNET_SQ_QueryParam params_select[] = {
513 };
514 while (cnt < total)
515 {
516 off = (off + 1) % total;
517 if (GNUNET_OK !=
518 GNUNET_SQ_bind (plugin->get_stmt,
519 params_select))
520 {
521 LOG_SQLITE (plugin->dbh,
523 "sqlite3_bind_xxx");
525 plugin->get_stmt);
526 return cnt;
527 }
528 if (SQLITE_ROW !=
529 sqlite3_step (plugin->get_stmt))
530 break;
531 if (GNUNET_OK !=
533 rs))
534 {
535 GNUNET_break (0);
537 plugin->get_stmt);
538 break;
539 }
540 if (0 != path_size % sizeof(struct GNUNET_DHT_PathElement))
541 {
542 GNUNET_break (0);
543 path_size = 0;
544 path = NULL;
545 }
546 block.data = data;
547 block.put_path = path;
548 block.put_path_length = path_size / sizeof(struct GNUNET_DHT_PathElement);
549 block.type = type;
550 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
551 cnt++;
553 "Found %u-byte result when processing GET for key `%s'\n",
554 (unsigned int) block.data_size,
555 GNUNET_h2s (&block.key));
556 if ( (NULL != iter) &&
557 (GNUNET_OK !=
558 iter (iter_cls,
559 &block)) )
560 {
563 plugin->get_stmt);
564 break;
565 }
568 plugin->get_stmt);
569 }
571 plugin->get_stmt);
572 }
573 return cnt;
574}
575
576
588static unsigned int
590 const struct GNUNET_HashCode *key,
593 void *iter_cls)
594{
596 return get_any (cls,
597 key,
598 iter,
599 iter_cls);
600 return get_typed (cls,
601 key,
602 type,
603 iter,
604 iter_cls);
605}
606
607
617{
618 struct Plugin *plugin = cls;
619 uint64_t rowid;
620 void *data;
621 size_t data_size;
622 struct GNUNET_HashCode hc;
623 struct GNUNET_TIME_Absolute now;
624 struct GNUNET_SQ_ResultSpec rs[] = {
628 &data_size),
630 };
631 struct GNUNET_SQ_QueryParam params[] = {
634 };
636 "Processing DEL\n");
638 {
639 struct GNUNET_SQ_QueryParam time_params[] = {
642 };
643
644 if (GNUNET_OK !=
645 GNUNET_SQ_bind (plugin->del_expired_stmt,
646 time_params))
647 {
648 LOG_SQLITE (plugin->dbh,
650 "sqlite3_bind");
652 plugin->del_expired_stmt);
653 return GNUNET_SYSERR;
654 }
655 }
656 if ( (SQLITE_ROW !=
657 sqlite3_step (plugin->del_expired_stmt)) ||
658 (GNUNET_OK !=
659 GNUNET_SQ_extract_result (plugin->del_expired_stmt,
660 rs)))
661 {
663 plugin->del_expired_stmt);
664 if (SQLITE_ROW !=
665 sqlite3_step (plugin->del_select_stmt))
666 {
667 LOG_SQLITE (plugin->dbh,
669 "sqlite3_step");
671 plugin->del_select_stmt);
672 return GNUNET_SYSERR;
673 }
674 if (GNUNET_OK !=
675 GNUNET_SQ_extract_result (plugin->del_select_stmt,
676 rs))
677 {
679 plugin->del_select_stmt);
680 GNUNET_break (0);
681 return GNUNET_SYSERR;
682 }
683 }
686 plugin->del_select_stmt);
687 if (GNUNET_OK !=
688 GNUNET_SQ_bind (plugin->del_stmt,
689 params))
690 {
691 LOG_SQLITE (plugin->dbh,
693 "sqlite3_bind");
695 plugin->del_stmt);
696 return GNUNET_SYSERR;
697 }
698 if (SQLITE_DONE !=
699 sqlite3_step (plugin->del_stmt))
700 {
701 LOG_SQLITE (plugin->dbh,
703 "sqlite3_step");
705 plugin->del_stmt);
706 return GNUNET_SYSERR;
707 }
708 plugin->num_items--;
709 plugin->env->delete_notify (plugin->env->cls,
710 &hc,
713 plugin->del_stmt);
714 return GNUNET_OK;
715}
716
717
732static unsigned int
734 const struct GNUNET_HashCode *key,
736 unsigned int num_results,
738 void *iter_cls)
739{
740 struct Plugin *plugin = cls;
741 uint32_t type32 = type;
742 uint32_t num_results32 = num_results;
743 struct GNUNET_TIME_Absolute now;
744 void *data;
745 void *path;
746 size_t path_size;
747 unsigned int cnt;
748 uint32_t bro32;
749 struct GNUNET_DATACACHE_Block block;
750 uint32_t rtype32;
751 struct GNUNET_SQ_ResultSpec rs[] = {
753 &block.data_size),
756 &path_size),
762 };
763
766 "Processing GET_CLOSEST for key `%s'\n",
767 GNUNET_h2s (key));
768 {
769 struct GNUNET_SQ_QueryParam params[] = {
773 GNUNET_SQ_query_param_uint32 (&num_results32),
775 };
776 if (GNUNET_OK !=
777 GNUNET_SQ_bind (plugin->get_closest_stmt,
778 params))
779 {
780 LOG_SQLITE (plugin->dbh,
782 "sqlite3_bind_xxx");
784 plugin->get_closest_stmt);
785 return 0;
786 }
787 }
788 cnt = 0;
789 while (SQLITE_ROW ==
790 sqlite3_step (plugin->get_closest_stmt))
791 {
792 if (GNUNET_OK !=
793 GNUNET_SQ_extract_result (plugin->get_closest_stmt,
794 rs))
795 {
796 GNUNET_break (0);
797 break;
798 }
799 if (0 != path_size % sizeof(struct GNUNET_DHT_PathElement))
800 {
801 GNUNET_break (0);
802 path_size = 0;
803 path = NULL;
804 }
805 block.put_path_length
806 = path_size / sizeof(struct GNUNET_DHT_PathElement);
807 block.put_path = path;
808 block.data = data;
809 block.type = (enum GNUNET_BLOCK_Type) rtype32;
810 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
811 cnt++;
813 "Found %u-byte result at %s when processing GET_CLOSE\n",
814 (unsigned int) block.data_size,
815 GNUNET_h2s (&block.key));
816
817 if (GNUNET_OK !=
818 iter (iter_cls,
819 &block))
820 {
822 break;
823 }
825 }
827 plugin->get_closest_stmt);
828 return cnt;
829}
830
831
832void *
834
841void *
843{
846 struct Plugin *plugin;
847 char *fn;
848 char *fn_utf8;
849 sqlite3 *dbh;
850 char *emsg;
851
852 if (GNUNET_YES ==
854 "datacache-sqlite",
855 "IN_MEMORY"))
856 {
857 if (SQLITE_OK !=
858 sqlite3_open (":memory:",
859 &dbh))
860 return NULL;
861 fn_utf8 = NULL;
862 }
863 else
864 {
865 fn = GNUNET_DISK_mktemp ("gnunet-datacache");
866 if (NULL == fn)
867 {
868 GNUNET_break (0);
869 return NULL;
870 }
871 /* fn should be UTF-8-encoded. If it isn't, it's a bug. */
872 fn_utf8 = GNUNET_strdup (fn);
873 if (SQLITE_OK !=
874 sqlite3_open (fn_utf8,
875 &dbh))
876 {
877 GNUNET_free (fn);
878 GNUNET_free (fn_utf8);
879 return NULL;
880 }
881 GNUNET_free (fn);
882 }
883
884 SQLITE3_EXEC (dbh, "PRAGMA temp_store=MEMORY");
885 SQLITE3_EXEC (dbh, "PRAGMA locking_mode=EXCLUSIVE");
886 SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF");
887 SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF");
888 SQLITE3_EXEC (dbh, "PRAGMA page_size=4092");
889 if (GNUNET_YES ==
891 "datacache-sqlite",
892 "IN_MEMORY"))
893 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
894
896 "CREATE TABLE ds180 ("
897 " type INTEGER NOT NULL DEFAULT 0,"
898 " ro INTEGER NOT NULL DEFAULT 0,"
899 " expire INTEGER NOT NULL,"
900 " key BLOB NOT NULL DEFAULT '',"
901 " prox INTEGER NOT NULL,"
902 " value BLOB NOT NULL,"
903 " trunc BLOB NOT NULL,"
904 " path BLOB DEFAULT '')");
906 "CREATE INDEX idx_hashidx"
907 " ON ds180 (key,type,expire)");
909 "CREATE INDEX idx_prox_expire"
910 " ON ds180 (prox,expire)");
912 "CREATE INDEX idx_expire_only"
913 " ON ds180 (expire)");
914 plugin = GNUNET_new (struct Plugin);
915 plugin->env = env;
916 plugin->dbh = dbh;
917 plugin->fn = fn_utf8;
918
919 if ((SQLITE_OK !=
920 sq_prepare (plugin->dbh,
921 "INSERT INTO ds180"
922 " (type, ro, expire, key, prox, value, path, trunc)"
923 " VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
924 &plugin->insert_stmt)) ||
925 (SQLITE_OK !=
926 sq_prepare (plugin->dbh,
927 "SELECT COUNT(*) FROM ds180 "
928 "WHERE key=?"
929 " AND type=?"
930 " AND expire >= ?",
931 &plugin->get_count_stmt)) ||
932 (SQLITE_OK !=
933 sq_prepare (plugin->dbh,
934 "SELECT COUNT(*) FROM ds180 "
935 "WHERE key=? AND expire >= ?",
936 &plugin->get_count_any_stmt)) ||
937 (SQLITE_OK !=
938 sq_prepare (plugin->dbh,
939 "SELECT value,expire,path,trunc,ro"
940 " FROM ds180"
941 " WHERE key=?"
942 " AND type=?"
943 " AND expire >= ?"
944 " LIMIT 1 OFFSET ?",
945 &plugin->get_stmt)) ||
946 (SQLITE_OK !=
947 sq_prepare (plugin->dbh,
948 "SELECT value,expire,path,trunc,type,ro"
949 " FROM ds180"
950 " WHERE key=?"
951 " AND expire >= ?"
952 " LIMIT 1 OFFSET ?",
953 &plugin->get_any_stmt)) ||
954 (SQLITE_OK !=
955 sq_prepare (plugin->dbh,
956 "SELECT _ROWID_,key,value FROM ds180"
957 " WHERE expire < ?1"
958 " ORDER BY expire ASC LIMIT 1",
959 &plugin->del_expired_stmt)) ||
960 (SQLITE_OK !=
961 sq_prepare (plugin->dbh,
962 "SELECT _ROWID_,key,value FROM ds180"
963 " ORDER BY prox ASC, expire ASC LIMIT 1",
964 &plugin->del_select_stmt)) ||
965 (SQLITE_OK !=
966 sq_prepare (plugin->dbh,
967 "DELETE FROM ds180 WHERE _ROWID_=?",
968 &plugin->del_stmt)) ||
969 (SQLITE_OK !=
970 sq_prepare (plugin->dbh,
971 "SELECT * FROM ("
972 " SELECT value,expire,path,trunc,type,ro,key"
973 " FROM ds180 "
974 " WHERE key>=?1 "
975 " AND expire >= ?2"
976 " AND ( (type=?3) or (0 == ?3) )"
977 " ORDER BY KEY ASC LIMIT ?4)"
978 "UNION "
979 "SELECT * FROM ("
980 " SELECT value,expire,path,trunc,type,ro,key"
981 " FROM ds180 "
982 " WHERE key<=?1 "
983 " AND expire >= ?2"
984 " AND ( (type=?3) or (0 == ?3) )"
985 " ORDER BY KEY DESC LIMIT ?4)",
986 &plugin->get_closest_stmt)))
987 {
988 LOG_SQLITE (plugin->dbh,
990 "sq_prepare");
991 GNUNET_break (SQLITE_OK ==
992 sqlite3_close (plugin->dbh));
994 return NULL;
995 }
996
998 api->cls = plugin;
999 api->get = &sqlite_plugin_get;
1000 api->put = &sqlite_plugin_put;
1001 api->del = &sqlite_plugin_del;
1002 api->get_closest = &sqlite_plugin_get_closest;
1004 "Sqlite datacache running\n");
1005 return api;
1006}
1007
1008
1009void *
1011
1018void *
1020{
1022 struct Plugin *plugin = api->cls;
1023 int result;
1024
1025#if SQLITE_VERSION_NUMBER >= 3007000
1026 sqlite3_stmt *stmt;
1027#endif
1028
1029#if ! WINDOWS || defined(__CYGWIN__)
1030 if ( (NULL != plugin->fn) &&
1031 (0 != unlink (plugin->fn)) )
1033 "unlink",
1034 plugin->fn);
1035 GNUNET_free (plugin->fn);
1036#endif
1037 sqlite3_finalize (plugin->insert_stmt);
1038 sqlite3_finalize (plugin->get_count_stmt);
1039 sqlite3_finalize (plugin->get_count_any_stmt);
1040 sqlite3_finalize (plugin->get_stmt);
1041 sqlite3_finalize (plugin->get_any_stmt);
1042 sqlite3_finalize (plugin->del_select_stmt);
1043 sqlite3_finalize (plugin->del_expired_stmt);
1044 sqlite3_finalize (plugin->del_stmt);
1045 sqlite3_finalize (plugin->get_closest_stmt);
1046 result = sqlite3_close (plugin->dbh);
1047#if SQLITE_VERSION_NUMBER >= 3007000
1048 if (SQLITE_BUSY == result)
1049 {
1051 _ (
1052 "Tried to close sqlite without finalizing all prepared statements.\n"));
1053 stmt = sqlite3_next_stmt (plugin->dbh,
1054 NULL);
1055 while (NULL != stmt)
1056 {
1057 result = sqlite3_finalize (stmt);
1058 if (result != SQLITE_OK)
1060 "Failed to close statement %p: %d\n",
1061 stmt,
1062 result);
1063 stmt = sqlite3_next_stmt (plugin->dbh,
1064 NULL);
1065 }
1066 result = sqlite3_close (plugin->dbh);
1067 }
1068#endif
1069 if (SQLITE_OK != result)
1070 LOG_SQLITE (plugin->dbh,
1072 "sqlite3_close");
1073
1075 GNUNET_free (api);
1076 return NULL;
1077}
1078
1079
1080/* end of plugin_datacache_sqlite.c */
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
static int result
Global testing status.
API for database backends for the datacache.
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
helper functions for Sqlite3 DB interactions
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.
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_QueryParam GNUNET_SQ_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint16_t in host byte order.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_absolute_time(struct GNUNET_TIME_Absolute *at)
Absolute time expected.
struct GNUNET_SQ_ResultSpec GNUNET_SQ_result_spec_uint32(uint32_t *u32)
uint32_t expected.
struct GNUNET_SQ_QueryParam GNUNET_SQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
#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.
#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_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
enum GNUNET_GenericReturnValue(* GNUNET_DATACACHE_Iterator)(void *cls, const struct GNUNET_DATACACHE_Block *block)
An iterator over a set of items stored in the datacache.
GNUNET_DHT_RouteOption
Options for routing.
char * GNUNET_DISK_mktemp(const char *t)
Create an (empty) temporary file on disk.
Definition disk.c:439
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_SYSERR
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#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.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:610
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static ssize_t sqlite_plugin_put(void *cls, uint32_t xor_distance, const struct GNUNET_DATACACHE_Block *block)
Store an item in the datastore.
#define OVERHEAD
How much overhead do we assume per entry in the datacache?
#define SQLITE3_EXEC(db, cmd)
Execute SQL statement.
void * libgnunet_plugin_datacache_sqlite_init(void *cls)
Entry point for the plugin.
#define LOG_SQLITE(db, level, cmd)
Log an error message at log-level level that indicates a failure of the command cmd with the error fr...
static unsigned int sqlite_plugin_get(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
static int sq_prepare(sqlite3 *dbh, const char *zSql, sqlite3_stmt **ppStmt)
Prepare a SQL statement.
static enum GNUNET_GenericReturnValue sqlite_plugin_del(void *cls)
Delete the entry with the lowest expiration value from the datacache right now.
static unsigned int get_any(void *cls, const struct GNUNET_HashCode *key, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
#define LOG_STRERROR_FILE(kind, op, fn)
static unsigned int get_typed(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
void * libgnunet_plugin_datacache_sqlite_done(void *cls)
Exit point from the plugin.
#define LOG(kind,...)
static unsigned int sqlite_plugin_get_closest(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results that are "close" to a particular key in the datacache.
void * cls
Closure for all of the callbacks.
Information about a block stored in the datacache.
const struct GNUNET_DHT_PathElement * put_path
PUT path taken by the block, array of peer identities.
enum GNUNET_BLOCK_Type type
Type of the block.
const void * data
Actual block data.
enum GNUNET_DHT_RouteOption ro
Options for routing for the block.
struct GNUNET_PeerIdentity trunc_peer
If the path was truncated, this is the peer ID at which the path was truncated.
struct GNUNET_HashCode key
Key of the block.
size_t data_size
Number of bytes in data.
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure to use for callbacks.
struct returned by the initialization function of the plugin
void * cls
Closure to pass to all plugin functions.
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
A 512-bit hashcode.
Description of a DB query parameter.
Description of a DB result cell.
void * cls
Closure to pass to start_testcase.
Time for absolute times used by GNUnet, in microseconds.
Handle for a plugin.
Definition block.c:38
sqlite3 * dbh
Handle to the sqlite database.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition block.c:47
sqlite3_stmt * get_any_stmt
Prepared statement for sqlite_plugin_get.
unsigned int num_items
Number of key-value pairs in the database.
sqlite3_stmt * get_stmt
Prepared statement for sqlite_plugin_get.
sqlite3_stmt * insert_stmt
Prepared statement for sqlite_plugin_put.
sqlite3_stmt * del_select_stmt
Prepared statement for sqlite_plugin_del.
sqlite3_stmt * get_count_stmt
Prepared statement for sqlite_plugin_get.
sqlite3_stmt * del_expired_stmt
Prepared statement for sqlite_plugin_del.
char * fn
Filename used for the DB.
sqlite3_stmt * get_closest_stmt
Prepared statement for sqlite_plugin_get_closest.
sqlite3_stmt * del_stmt
Prepared statement for sqlite_plugin_del.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
sqlite3_stmt * get_count_any_stmt
Prepared statement for sqlite_plugin_get.
struct GNUNET_PQ_Context * dbh
Native Postgres database handle.