aboutsummaryrefslogtreecommitdiff
path: root/src/psycstore/plugin_psycstore_sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/psycstore/plugin_psycstore_sqlite.c')
-rw-r--r--src/psycstore/plugin_psycstore_sqlite.c858
1 files changed, 858 insertions, 0 deletions
diff --git a/src/psycstore/plugin_psycstore_sqlite.c b/src/psycstore/plugin_psycstore_sqlite.c
new file mode 100644
index 000000000..8bec31f12
--- /dev/null
+++ b/src/psycstore/plugin_psycstore_sqlite.c
@@ -0,0 +1,858 @@
1 /*
2 * This file is part of GNUnet
3 * (C) 2009-2013 Christian Grothoff (and other contributing authors)
4 *
5 * GNUnet is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 3, or (at your
8 * 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
12t * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GNUnet; see the file COPYING. If not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file psycstore/plugin_psycstore_sqlite.c
23 * @brief sqlite-based psycstore backend
24 * @author Gabor X Toth
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "gnunet_psycstore_plugin.h"
30#include "gnunet_psycstore_service.h"
31#include "psycstore.h"
32#include <sqlite3.h>
33
34/**
35 * After how many ms "busy" should a DB operation fail for good? A
36 * low value makes sure that we are more responsive to requests
37 * (especially PUTs). A high value guarantees a higher success rate
38 * (SELECTs in iterate can take several seconds despite LIMIT=1).
39 *
40 * The default value of 1s should ensure that users do not experience
41 * huge latencies while at the same time allowing operations to
42 * succeed with reasonable probability.
43 */
44#define BUSY_TIMEOUT_MS 1000
45
46
47/**
48 * Log an error message at log-level 'level' that indicates
49 * a failure of the command 'cmd' on file 'filename'
50 * with the message given by strerror(errno).
51 */
52#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "psycstore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0)
53
54#define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__)
55
56
57/**
58 * Context for all functions in this plugin.
59 */
60struct Plugin
61{
62
63 const struct GNUNET_CONFIGURATION_Handle *cfg;
64
65 /**
66 * Database filename.
67 */
68 char *fn;
69
70 /**
71 * Native SQLite database handle.
72 */
73 sqlite3 *dbh;
74
75 /**
76 * Precompiled SQL for channel_key_store()
77 */
78 sqlite3_stmt *insert_channel_key;
79
80 /**
81 * Precompiled SQL for slave_key_store()
82 */
83 sqlite3_stmt *insert_slave_key;
84
85
86 /**
87 * Precompiled SQL for membership_store()
88 */
89 sqlite3_stmt *insert_membership;
90
91 /**
92 * Precompiled SQL for membership_test()
93 */
94 sqlite3_stmt *select_membership;
95
96
97 /**
98 * Precompiled SQL for fragment_store()
99 */
100 sqlite3_stmt *insert_fragment;
101
102 /**
103 * Precompiled SQL for fragment_add_flags()
104 */
105 sqlite3_stmt *update_fragment_flags;
106
107 /**
108 * Precompiled SQL for fragment_get()
109 */
110 sqlite3_stmt *select_fragment;
111
112 /**
113 * Precompiled SQL for message_get()
114 */
115 sqlite3_stmt *select_message;
116
117 /**
118 * Precompiled SQL for message_get_fragment()
119 */
120 sqlite3_stmt *select_message_fragment;
121
122 /**
123 * Precompiled SQL for counters_get_master()
124 */
125 sqlite3_stmt *select_master_counters;
126
127 /**
128 * Precompiled SQL for counters_get_slave()
129 */
130 sqlite3_stmt *select_slave_counters;
131
132
133 /**
134 * Precompiled SQL for state_set()
135 */
136 sqlite3_stmt *insert_state_current;
137
138 /**
139 * Precompiled SQL for state_set()
140 */
141 sqlite3_stmt *update_state_current;
142
143 /**
144 * Precompiled SQL for state_set_signed()
145 */
146 sqlite3_stmt *update_state_signed;
147
148 /**
149 * Precompiled SQL for state_sync()
150 */
151 sqlite3_stmt *insert_state_sync;
152
153 /**
154 * Precompiled SQL for state_sync()
155 */
156 sqlite3_stmt *delete_state;
157
158 /**
159 * Precompiled SQL for state_sync()
160 */
161 sqlite3_stmt *insert_state_from_sync;
162
163 /**
164 * Precompiled SQL for state_sync()
165 */
166 sqlite3_stmt *delete_state_sync;
167
168 /**
169 * Precompiled SQL for state_get()
170 */
171 sqlite3_stmt *select_state_one;
172
173 /**
174 * Precompiled SQL for state_get_all()
175 */
176 sqlite3_stmt *select_state_prefix;
177
178};
179
180
181/**
182 * @brief Prepare a SQL statement
183 *
184 * @param dbh handle to the database
185 * @param sql SQL statement, UTF-8 encoded
186 * @param stmt set to the prepared statement
187 * @return 0 on success
188 */
189static int
190sql_prepare (sqlite3 *dbh, const char *sql, sqlite3_stmt **stmt)
191{
192 char *tail;
193 int result;
194
195 result = sqlite3_prepare_v2 (dbh, sql, strlen (sql), stmt,
196 (const char **) &tail);
197 LOG (GNUNET_ERROR_TYPE_DEBUG,
198 "Prepared `%s' / %p: %d\n", sql, *stmt, result);
199 if (result != SQLITE_OK)
200 LOG (GNUNET_ERROR_TYPE_ERROR,
201 _("Error preparing SQL query: %s\n %s\n"),
202 sqlite3_errmsg (dbh), sql);
203 return result;
204}
205
206
207/**
208 * @brief Prepare a SQL statement
209 *
210 * @param dbh handle to the database
211 * @param zSql SQL statement, UTF-8 encoded
212 * @param ppStmt set to the prepared statement
213 * @return 0 on success
214 */
215static int
216sql_exec (sqlite3 *dbh, const char *sql)
217{
218 int result;
219
220 result = sqlite3_exec (dbh, sql, NULL, NULL, NULL);
221 LOG (GNUNET_ERROR_TYPE_DEBUG,
222 "Executed `%s' / %d\n", sql, result);
223 if (result != SQLITE_OK)
224 LOG (GNUNET_ERROR_TYPE_ERROR,
225 _("Error executing SQL query: %s\n %s\n"),
226 sqlite3_errmsg (dbh), sql);
227 return result;
228}
229
230
231/**
232 * Initialize the database connections and associated
233 * data structures (create tables and indices
234 * as needed as well).
235 *
236 * @param plugin the plugin context (state for this module)
237 * @return GNUNET_OK on success
238 */
239static int
240database_setup (struct Plugin *plugin)
241{
242 char *filename;
243
244 if (GNUNET_OK !=
245 GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "psycstore-sqlite",
246 "FILENAME", &filename))
247 {
248 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
249 "psycstore-sqlite", "FILENAME");
250 return GNUNET_SYSERR;
251 }
252 if (GNUNET_OK != GNUNET_DISK_file_test (filename))
253 {
254 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (filename))
255 {
256 GNUNET_break (0);
257 GNUNET_free (filename);
258 return GNUNET_SYSERR;
259 }
260 }
261 /* filename should be UTF-8-encoded. If it isn't, it's a bug */
262 plugin->fn = filename;
263
264 /* Open database and precompile statements */
265 if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
266 {
267 LOG (GNUNET_ERROR_TYPE_ERROR,
268 _("Unable to initialize SQLite: %s.\n"),
269 sqlite3_errmsg (plugin->dbh));
270 return GNUNET_SYSERR;
271 }
272
273 sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY");
274 sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL");
275 sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF");
276 sql_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL");
277 sql_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"");
278 sql_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE");
279 sql_exec (plugin->dbh, "PRAGMA count_changes=OFF");
280 sql_exec (plugin->dbh, "PRAGMA page_size=4096");
281
282 sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS);
283
284 /* Create tables */
285
286 sql_exec (plugin->dbh,
287 "CREATE TABLE IF NOT EXISTS channels ("
288 " id INTEGER PRIMARY KEY,"
289 " pub_key BLOB UNIQUE"
290 ");");
291
292 sql_exec (plugin->dbh,
293 "CREATE TABLE IF NOT EXISTS slaves ("
294 " id INTEGER PRIMARY KEY,"
295 " pub_key BLOB UNIQUE"
296 ");");
297
298 sql_exec (plugin->dbh,
299 "CREATE TABLE IF NOT EXISTS membership ("
300 " channel_id INTEGER NOT NULL REFERENCES channels(id),"
301 " slave_id INTEGER NOT NULL REFERENCES slaves(id),"
302 " did_join INTEGER NOT NULL,"
303 " announced_at INTEGER NOT NULL,"
304 " effective_since INTEGER NOT NULL,"
305 " group_generation INTEGER NOT NULL"
306 ");");
307 sql_exec (plugin->dbh,
308 "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id "
309 "ON membership (channel_id, slave_id);");
310
311 sql_exec (plugin->dbh,
312 "CREATE TABLE IF NOT EXISTS messages ("
313 " channel_id INTEGER NOT NULL,"
314 " hop_counter INTEGER NOT NULL,"
315 " signature BLOB,"
316 " purpose BLOB,"
317 " fragment_id INTEGER NOT NULL,"
318 " fragment_offset INTEGER NOT NULL,"
319 " message_id INTEGER NOT NULL,"
320 " group_generation INTEGER NOT NULL,"
321 " multicast_flags INTEGER NOT NULL,"
322 " psyc_flags INTEGER NOT NULL,"
323 " data BLOB,"
324 " PRIMARY KEY (channel_id, fragment_id),"
325 " UNIQUE (channel_id, message_id, fragment_offset)"
326 ");");
327
328 sql_exec (plugin->dbh,
329 "CREATE TABLE IF NOT EXISTS state ("
330 " channel_id INTEGER NOT NULL,"
331 " name TEXT NOT NULL,"
332 " value_current BLOB, "
333 " value_signed BLOB, "
334 " PRIMARY KEY (channel_id, name)"
335 ");");
336
337 sql_exec (plugin->dbh,
338 "CREATE TABLE IF NOT EXISTS state_sync ("
339 " channel_id INTEGER NOT NULL,"
340 " name TEXT NOT NULL,"
341 " value BLOB, "
342 " PRIMARY KEY (channel_id, name)"
343 ");");
344
345 /* Prepare statements */
346
347 sql_prepare (plugin->dbh,
348 "INSERT OR IGNORE INTO channels (pub_key) VALUES (?);",
349 &plugin->insert_channel_key);
350
351 sql_prepare (plugin->dbh,
352 "INSERT OR IGNORE INTO slaves (pub_key) VALUES (?);",
353 &plugin->insert_slave_key);
354
355 sql_prepare (plugin->dbh,
356 "INSERT INTO membership "
357 " (channel_id, slave_id, did_join, announced_at, "
358 " effective_since, group_generation) "
359 "VALUES ((SELECT id FROM channels WHERE pub_key = ?), "
360 " (SELECT id FROM slaves WHERE pub_key = ?), "
361 " ?, ?, ?, ?);",
362 &plugin->insert_membership);
363
364 sql_prepare (plugin->dbh,
365 "SELECT did_join FROM membership "
366 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
367 " AND slave_id = ? AND effective_since <= ? "
368 "ORDER BY announced_at DESC LIMIT 1;",
369 &plugin->select_membership);
370
371 sql_prepare (plugin->dbh,
372 "INSERT INTO messages "
373 " (channel_id, hop_counter, signature, purpose, "
374 " fragment_id, fragment_offset, message_id, "
375 " group_generation, multicast_flags, psyc_flags, data) "
376 "VALUES ((SELECT id FROM channels WHERE pub_key = ?), "
377 " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
378 &plugin->insert_fragment);
379
380 sql_prepare (plugin->dbh,
381 "UPDATE messages "
382 "SET multicast_flags = multicast_flags | ?, "
383 " psyc_flags = psyc_flags | ? "
384 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
385 " AND message_id = ?;",
386 &plugin->update_fragment_flags);
387
388 sql_prepare (plugin->dbh,
389 "SELECT hop_counter, signature, purpose, "
390 " fragment_offset, message_id, group_generation, "
391 " multicast_flags, psyc_flags, data "
392 "FROM messages "
393 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
394 " AND fragment_id = ?;",
395 &plugin->select_fragment);
396
397 sql_prepare (plugin->dbh,
398 "SELECT hop_counter, signature, purpose, "
399 " fragment_id, fragment_offset, group_generation, "
400 " multicast_flags, psyc_flags, data "
401 "FROM messages "
402 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
403 " AND message_id = ?;",
404 &plugin->select_message);
405
406 sql_prepare (plugin->dbh,
407 "SELECT hop_counter, signature, purpose, "
408 " fragment_id, message_id, group_generation, "
409 " multicast_flags, psyc_flags, data "
410 "FROM messages "
411 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
412 " AND message_id = ? AND fragment_offset = ?;",
413 &plugin->select_message_fragment);
414
415 sql_prepare (plugin->dbh,
416 "SELECT max(fragment_id), max(message_id), max(group_generation) "
417 "FROM messages "
418 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
419 &plugin->select_master_counters);
420
421 sql_prepare (plugin->dbh,
422 "SELECT max(message_id) "
423 "FROM messages "
424 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
425 " AND psyc_flags & ?;",
426 &plugin->select_slave_counters);
427
428 sql_prepare (plugin->dbh,
429 "INSERT OR REPLACE INTO state (channel_id, name, value_current) "
430 "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);",
431 &plugin->insert_state_current);
432
433 sql_prepare (plugin->dbh,
434 "UPDATE state "
435 "SET value_current = ? "
436 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
437 " AND name = ?;",
438 &plugin->update_state_current);
439
440 sql_prepare (plugin->dbh,
441 "UPDATE state "
442 "SET value_signed = value_current "
443 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) ",
444 &plugin->update_state_signed);
445
446 sql_prepare (plugin->dbh,
447 "INSERT INTO state_sync (channel_id, name, value) "
448 "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);",
449 &plugin->insert_state_sync);
450
451 sql_prepare (plugin->dbh,
452 "DELETE FROM state "
453 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
454 &plugin->delete_state);
455
456 sql_prepare (plugin->dbh,
457 "INSERT INTO state "
458 " (channel_id, name, value_current, value_signed) "
459 "SELECT channel_id, name, value, value "
460 "FROM state_sync "
461 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
462 &plugin->insert_state_from_sync);
463
464 sql_prepare (plugin->dbh,
465 "DELETE FROM state_sync "
466 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
467 &plugin->delete_state_sync);
468
469 sql_prepare (plugin->dbh,
470 "SELECT value_current "
471 "FROM state "
472 "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) "
473 " AND name = ?;",
474 &plugin->select_state_one);
475
476 sql_prepare (plugin->dbh,
477 "SELECT value_current "
478 "FROM state "
479 "WHERE name LIKE ? OR name LIKE ?;",
480 &plugin->select_state_prefix);
481
482 return GNUNET_OK;
483}
484
485
486/**
487 * Shutdown database connection and associate data
488 * structures.
489 * @param plugin the plugin context (state for this module)
490 */
491static void
492database_shutdown (struct Plugin *plugin)
493{
494 int result;
495 sqlite3_stmt *stmt;
496
497 if (NULL != plugin->insert_channel_key)
498 sqlite3_finalize (plugin->insert_channel_key);
499
500 if (NULL != plugin->insert_slave_key)
501 sqlite3_finalize (plugin->insert_slave_key);
502
503 if (NULL != plugin->insert_membership)
504 sqlite3_finalize (plugin->insert_membership);
505
506 if (NULL != plugin->select_membership)
507 sqlite3_finalize (plugin->select_membership);
508
509 if (NULL != plugin->insert_fragment)
510 sqlite3_finalize (plugin->insert_fragment);
511
512 if (NULL != plugin->update_fragment_flags)
513 sqlite3_finalize (plugin->update_fragment_flags);
514
515 if (NULL != plugin->select_fragment)
516 sqlite3_finalize (plugin->select_fragment);
517
518 if (NULL != plugin->select_message)
519 sqlite3_finalize (plugin->select_message);
520
521 if (NULL != plugin->select_message_fragment)
522 sqlite3_finalize (plugin->select_message_fragment);
523
524 if (NULL != plugin->select_master_counters)
525 sqlite3_finalize (plugin->select_master_counters);
526
527 if (NULL != plugin->select_slave_counters)
528 sqlite3_finalize (plugin->select_slave_counters);
529
530 if (NULL != plugin->insert_state_current)
531 sqlite3_finalize (plugin->insert_state_current);
532
533 if (NULL != plugin->update_state_current)
534 sqlite3_finalize (plugin->update_state_current);
535
536 if (NULL != plugin->update_state_signed)
537 sqlite3_finalize (plugin->update_state_signed);
538
539 if (NULL != plugin->insert_state_sync)
540 sqlite3_finalize (plugin->insert_state_sync);
541
542 if (NULL != plugin->delete_state)
543 sqlite3_finalize (plugin->delete_state);
544
545 if (NULL != plugin->insert_state_from_sync)
546 sqlite3_finalize (plugin->insert_state_from_sync);
547
548 if (NULL != plugin->delete_state_sync)
549 sqlite3_finalize (plugin->delete_state_sync);
550
551 if (NULL != plugin->select_state_one)
552 sqlite3_finalize (plugin->select_state_one);
553
554 if (NULL != plugin->select_state_prefix)
555 sqlite3_finalize (plugin->select_state_prefix);
556
557 result = sqlite3_close (plugin->dbh);
558 if (result == SQLITE_BUSY)
559 {
560 LOG (GNUNET_ERROR_TYPE_WARNING,
561 _("Tried to close sqlite without finalizing all prepared statements.\n"));
562 stmt = sqlite3_next_stmt (plugin->dbh, NULL);
563 while (stmt != NULL)
564 {
565 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
566 "Closing statement %p\n", stmt);
567 result = sqlite3_finalize (stmt);
568 if (result != SQLITE_OK)
569 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
570 "Failed to close statement %p: %d\n", stmt, result);
571 stmt = sqlite3_next_stmt (plugin->dbh, NULL);
572 }
573 result = sqlite3_close (plugin->dbh);
574 }
575 if (SQLITE_OK != result)
576 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
577
578 GNUNET_free_non_null (plugin->fn);
579}
580
581
582/**
583 * Store join/leave events for a PSYC channel in order to be able to answer
584 * membership test queries later.
585 *
586 * @see GNUNET_PSYCSTORE_membership_store()
587 *
588 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
589 */
590int
591libgnunet_plugin_psycstore_sqlite_membership_store
592 (void *cls,
593 const struct GNUNET_HashCode *channel_key,
594 const struct GNUNET_HashCode *slave_key,
595 int did_join,
596 uint64_t announced_at,
597 uint64_t effective_since,
598 uint64_t group_generation) {
599
600
601}
602
603/**
604 * Test if a member was admitted to the channel at the given message ID.
605 *
606 * @see GNUNET_PSYCSTORE_membership_test()
607 *
608 * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not,
609 * #GNUNET_SYSERR if there was en error.
610 */
611int
612libgnunet_plugin_psycstore_sqlite_membership_test
613 (void *cls,
614 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
615 const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
616 uint64_t message_id,
617 uint64_t group_generation) {
618
619}
620
621/**
622 * Store a message fragment sent to a channel.
623 *
624 * @see GNUNET_PSYCSTORE_fragment_store()
625 *
626 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
627 */
628int
629libgnunet_plugin_psycstore_sqlite_fragment_store
630 (void *cls,
631 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
632 const struct GNUNET_MULTICAST_MessageHeader *message) {
633
634}
635
636/**
637 * Set additional flags for a given message.
638 *
639 * @param message_id ID of the message.
640 * @param flags Flags to add.
641 *
642 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
643 */
644int
645libgnunet_plugin_psycstore_sqlite_fragment_add_flags
646 (void *cls,
647 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
648 uint64_t message_id,
649 uint64_t multicast_flags,
650 uint64_t psyc_flags) {
651
652}
653
654/**
655 * Retrieve a message fragment by fragment ID.
656 *
657 * @see GNUNET_PSYCSTORE_fragment_get()
658 *
659 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
660 */
661int
662libgnunet_plugin_psycstore_sqlite_fragment_get
663 (void *cls,
664 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
665 uint64_t fragment_id,
666 GNUNET_PSYCSTORE_FragmentCallback cb,
667 void *cb_cls) {
668
669}
670
671/**
672 * Retrieve all fragments of a message.
673 *
674 * @see GNUNET_PSYCSTORE_message_get()
675 *
676 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
677 */
678int
679libgnunet_plugin_psycstore_sqlite_message_get
680 (void *cls,
681 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
682 uint64_t message_id,
683 GNUNET_PSYCSTORE_FragmentCallback cb,
684 void *cb_cls) {
685
686}
687
688/**
689 * Retrieve a fragment of message specified by its message ID and fragment
690 * offset.
691 *
692 * @see GNUNET_PSYCSTORE_message_get_fragment()
693 *
694 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
695 */
696int
697libgnunet_plugin_psycstore_sqlite_message_get_fragment
698 (void *cls,
699 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
700 uint64_t message_id,
701 uint64_t fragment_offset,
702 GNUNET_PSYCSTORE_FragmentCallback cb,
703 void *cb_cls)
704{
705
706}
707
708/**
709 * Retrieve latest values of counters for a channel master.
710 *
711 * @see GNUNET_PSYCSTORE_counters_get_master()
712 *
713 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
714 */
715int
716libgnunet_plugin_psycstore_sqlite_counters_get_master
717 (void *cls,
718 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
719 uint64_t *fragment_id,
720 uint64_t *message_id,
721 uint64_t *group_generation)
722{
723
724}
725
726/**
727 * Retrieve latest values of counters for a channel slave.
728 *
729 * @see GNUNET_PSYCSTORE_counters_get_slave()
730 *
731 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
732 */
733int
734libgnunet_plugin_psycstore_sqlite_counters_get_slave
735 (void *cls,
736 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
737 uint64_t *max_state_msg_id) {
738
739}
740
741/**
742 * Set a state variable to the given value.
743 *
744 * @see GNUNET_PSYCSTORE_state_modify()
745 *
746 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
747 */
748int
749libgnunet_plugin_psycstore_sqlite_state_set
750 (struct GNUNET_PSYCSTORE_Handle *h,
751 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
752 const char *name,
753 size_t value_size,
754 const void *value) {
755
756}
757
758/**
759 * Retrieve a state variable by name.
760 *
761 * @param name Name of the variable to retrieve.
762 * @param[out] value_size Size of value.
763 * @param[out] value Returned value.
764 *
765 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
766 */
767int
768libgnunet_plugin_psycstore_sqlite_state_get
769 (struct GNUNET_PSYCSTORE_Handle *h,
770 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
771 const char *name,
772 GNUNET_PSYCSTORE_StateCallback cb,
773 void *cb_cls) {
774
775}
776
777/**
778 * Retrieve all state variables for a channel with the given prefix.
779 *
780 * @see GNUNET_PSYCSTORE_state_get_all()
781 *
782 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
783 */
784int
785libgnunet_plugin_psycstore_sqlite_state_get_all
786 (struct GNUNET_PSYCSTORE_Handle *h,
787 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
788 const char *name,
789 GNUNET_PSYCSTORE_StateCallback cb,
790 void *cb_cls) {
791
792}
793
794
795/**
796 * Entry point for the plugin.
797 *
798 * @param cls the "struct GNUNET_PSYCSTORE_PluginEnvironment*"
799 * @return NULL on error, otherwise the plugin context
800 */
801void *
802libgnunet_plugin_psycstore_sqlite_init (void *cls)
803{
804 static struct Plugin plugin;
805 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
806 struct GNUNET_PSYCSTORE_PluginFunctions *api;
807
808 if (NULL != plugin.cfg)
809 return NULL; /* can only initialize once! */
810 memset (&plugin, 0, sizeof (struct Plugin));
811 plugin.cfg = cfg;
812 if (GNUNET_OK != database_setup (&plugin))
813 {
814 database_shutdown (&plugin);
815 return NULL;
816 }
817 api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions);
818 api->cls = &plugin;
819 api->membership_store = &libgnunet_plugin_psycstore_sqlite_membership_store;
820 api->membership_test = &libgnunet_plugin_psycstore_sqlite_membership_test;
821 api->fragment_store = &libgnunet_plugin_psycstore_sqlite_fragment_store;
822 api->fragment_add_flags = &libgnunet_plugin_psycstore_sqlite_fragment_add_flags;
823 api->fragment_get = &libgnunet_plugin_psycstore_sqlite_fragment_get;
824 api->message_get = &libgnunet_plugin_psycstore_sqlite_message_get;
825 api->message_get_fragment = &libgnunet_plugin_psycstore_sqlite_message_get_fragment;
826 api->counters_get_master = &libgnunet_plugin_psycstore_sqlite_counters_get_master;
827 api->counters_get_slave = &libgnunet_plugin_psycstore_sqlite_counters_get_slave;
828 api->state_set = &libgnunet_plugin_psycstore_sqlite_state_set;
829 api->state_get = &libgnunet_plugin_psycstore_sqlite_state_get;
830 api->state_get_all = &libgnunet_plugin_psycstore_sqlite_state_get_all;
831
832 LOG (GNUNET_ERROR_TYPE_INFO,
833 _("Sqlite database running\n"));
834 return api;
835}
836
837
838/**
839 * Exit point from the plugin.
840 *
841 * @param cls the plugin context (as returned by "init")
842 * @return always NULL
843 */
844void *
845libgnunet_plugin_psycstore_sqlite_done (void *cls)
846{
847 struct GNUNET_PSYCSTORE_PluginFunctions *api = cls;
848 struct Plugin *plugin = api->cls;
849
850 database_shutdown (plugin);
851 plugin->cfg = NULL;
852 GNUNET_free (api);
853 LOG (GNUNET_ERROR_TYPE_DEBUG,
854 "sqlite plugin is finished\n");
855 return NULL;
856}
857
858/* end of plugin_psycstore_sqlite.c */