diff options
author | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
commit | eb9556bf2983ca19a5cbcf7cf460a0b2509b290a (patch) | |
tree | 285d31e951f7ecf9308b22257adcadd5b07d80ea /src/psycstore/plugin_psycstore_sqlite.c | |
parent | 37bafa60a6f0e447cb5b61547404f0902fa7ad41 (diff) | |
download | gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.tar.gz gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.zip |
PSYCstore SQLite backend; API fixes/enhancements
Diffstat (limited to 'src/psycstore/plugin_psycstore_sqlite.c')
-rw-r--r-- | src/psycstore/plugin_psycstore_sqlite.c | 1172 |
1 files changed, 936 insertions, 236 deletions
diff --git a/src/psycstore/plugin_psycstore_sqlite.c b/src/psycstore/plugin_psycstore_sqlite.c index 8bec31f12..f214e1c60 100644 --- a/src/psycstore/plugin_psycstore_sqlite.c +++ b/src/psycstore/plugin_psycstore_sqlite.c | |||
@@ -25,9 +25,16 @@ t * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
25 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* | ||
29 | * FIXME: SQLite3 only supports signed 64-bit integers natively, | ||
30 | * thus it can only store 63 bits of the uint64_t's. | ||
31 | */ | ||
32 | |||
28 | #include "platform.h" | 33 | #include "platform.h" |
29 | #include "gnunet_psycstore_plugin.h" | 34 | #include "gnunet_psycstore_plugin.h" |
30 | #include "gnunet_psycstore_service.h" | 35 | #include "gnunet_psycstore_service.h" |
36 | #include "gnunet_multicast_service.h" | ||
37 | #include "gnunet_crypto_lib.h" | ||
31 | #include "psycstore.h" | 38 | #include "psycstore.h" |
32 | #include <sqlite3.h> | 39 | #include <sqlite3.h> |
33 | 40 | ||
@@ -43,13 +50,14 @@ t * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
43 | */ | 50 | */ |
44 | #define BUSY_TIMEOUT_MS 1000 | 51 | #define BUSY_TIMEOUT_MS 1000 |
45 | 52 | ||
53 | #define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING | ||
46 | 54 | ||
47 | /** | 55 | /** |
48 | * Log an error message at log-level 'level' that indicates | 56 | * Log an error message at log-level 'level' that indicates |
49 | * a failure of the command 'cmd' on file 'filename' | 57 | * a failure of the command 'cmd' on file 'filename' |
50 | * with the message given by strerror(errno). | 58 | * with the message given by strerror(errno). |
51 | */ | 59 | */ |
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) | 60 | #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "psycstore-sqlite", _("`%s' failed at %s:%d with error: %s (%d)\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh), sqlite3_errcode(db->dbh)); } while(0) |
53 | 61 | ||
54 | #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__) | 62 | #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__) |
55 | 63 | ||
@@ -100,9 +108,9 @@ struct Plugin | |||
100 | sqlite3_stmt *insert_fragment; | 108 | sqlite3_stmt *insert_fragment; |
101 | 109 | ||
102 | /** | 110 | /** |
103 | * Precompiled SQL for fragment_add_flags() | 111 | * Precompiled SQL for message_add_flags() |
104 | */ | 112 | */ |
105 | sqlite3_stmt *update_fragment_flags; | 113 | sqlite3_stmt *update_message_flags; |
106 | 114 | ||
107 | /** | 115 | /** |
108 | * Precompiled SQL for fragment_get() | 116 | * Precompiled SQL for fragment_get() |
@@ -122,12 +130,12 @@ struct Plugin | |||
122 | /** | 130 | /** |
123 | * Precompiled SQL for counters_get_master() | 131 | * Precompiled SQL for counters_get_master() |
124 | */ | 132 | */ |
125 | sqlite3_stmt *select_master_counters; | 133 | sqlite3_stmt *select_counters_master; |
126 | 134 | ||
127 | /** | 135 | /** |
128 | * Precompiled SQL for counters_get_slave() | 136 | * Precompiled SQL for counters_get_slave() |
129 | */ | 137 | */ |
130 | sqlite3_stmt *select_slave_counters; | 138 | sqlite3_stmt *select_counters_slave; |
131 | 139 | ||
132 | 140 | ||
133 | /** | 141 | /** |
@@ -136,11 +144,6 @@ struct Plugin | |||
136 | sqlite3_stmt *insert_state_current; | 144 | sqlite3_stmt *insert_state_current; |
137 | 145 | ||
138 | /** | 146 | /** |
139 | * Precompiled SQL for state_set() | ||
140 | */ | ||
141 | sqlite3_stmt *update_state_current; | ||
142 | |||
143 | /** | ||
144 | * Precompiled SQL for state_set_signed() | 147 | * Precompiled SQL for state_set_signed() |
145 | */ | 148 | */ |
146 | sqlite3_stmt *update_state_signed; | 149 | sqlite3_stmt *update_state_signed; |
@@ -166,6 +169,11 @@ struct Plugin | |||
166 | sqlite3_stmt *delete_state_sync; | 169 | sqlite3_stmt *delete_state_sync; |
167 | 170 | ||
168 | /** | 171 | /** |
172 | * Precompiled SQL for state_get_signed() | ||
173 | */ | ||
174 | sqlite3_stmt *select_state_signed; | ||
175 | |||
176 | /** | ||
169 | * Precompiled SQL for state_get() | 177 | * Precompiled SQL for state_get() |
170 | */ | 178 | */ |
171 | sqlite3_stmt *select_state_one; | 179 | sqlite3_stmt *select_state_one; |
@@ -177,6 +185,15 @@ struct Plugin | |||
177 | 185 | ||
178 | }; | 186 | }; |
179 | 187 | ||
188 | #if DEBUG_PSYCSTORE | ||
189 | |||
190 | static void | ||
191 | sql_trace (void *cls, const char *sql) | ||
192 | { | ||
193 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SQL query:\n%s\n", sql); | ||
194 | } | ||
195 | |||
196 | #endif | ||
180 | 197 | ||
181 | /** | 198 | /** |
182 | * @brief Prepare a SQL statement | 199 | * @brief Prepare a SQL statement |
@@ -208,8 +225,7 @@ sql_prepare (sqlite3 *dbh, const char *sql, sqlite3_stmt **stmt) | |||
208 | * @brief Prepare a SQL statement | 225 | * @brief Prepare a SQL statement |
209 | * | 226 | * |
210 | * @param dbh handle to the database | 227 | * @param dbh handle to the database |
211 | * @param zSql SQL statement, UTF-8 encoded | 228 | * @param sql SQL statement, UTF-8 encoded |
212 | * @param ppStmt set to the prepared statement | ||
213 | * @return 0 on success | 229 | * @return 0 on success |
214 | */ | 230 | */ |
215 | static int | 231 | static int |
@@ -262,7 +278,7 @@ database_setup (struct Plugin *plugin) | |||
262 | plugin->fn = filename; | 278 | plugin->fn = filename; |
263 | 279 | ||
264 | /* Open database and precompile statements */ | 280 | /* Open database and precompile statements */ |
265 | if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) | 281 | if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh)) |
266 | { | 282 | { |
267 | LOG (GNUNET_ERROR_TYPE_ERROR, | 283 | LOG (GNUNET_ERROR_TYPE_ERROR, |
268 | _("Unable to initialize SQLite: %s.\n"), | 284 | _("Unable to initialize SQLite: %s.\n"), |
@@ -270,6 +286,10 @@ database_setup (struct Plugin *plugin) | |||
270 | return GNUNET_SYSERR; | 286 | return GNUNET_SYSERR; |
271 | } | 287 | } |
272 | 288 | ||
289 | #if DEBUG_PSYCSTORE | ||
290 | sqlite3_trace (plugin->dbh, &sql_trace, NULL); | ||
291 | #endif | ||
292 | |||
273 | sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); | 293 | sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); |
274 | sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL"); | 294 | sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL"); |
275 | sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); | 295 | sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); |
@@ -284,62 +304,62 @@ database_setup (struct Plugin *plugin) | |||
284 | /* Create tables */ | 304 | /* Create tables */ |
285 | 305 | ||
286 | sql_exec (plugin->dbh, | 306 | sql_exec (plugin->dbh, |
287 | "CREATE TABLE IF NOT EXISTS channels (" | 307 | "CREATE TABLE IF NOT EXISTS channels (\n" |
288 | " id INTEGER PRIMARY KEY," | 308 | " id INTEGER PRIMARY KEY,\n" |
289 | " pub_key BLOB UNIQUE" | 309 | " pub_key BLOB UNIQUE\n" |
290 | ");"); | 310 | ");"); |
291 | 311 | ||
292 | sql_exec (plugin->dbh, | 312 | sql_exec (plugin->dbh, |
293 | "CREATE TABLE IF NOT EXISTS slaves (" | 313 | "CREATE TABLE IF NOT EXISTS slaves (\n" |
294 | " id INTEGER PRIMARY KEY," | 314 | " id INTEGER PRIMARY KEY,\n" |
295 | " pub_key BLOB UNIQUE" | 315 | " pub_key BLOB UNIQUE\n" |
296 | ");"); | 316 | ");"); |
297 | 317 | ||
298 | sql_exec (plugin->dbh, | 318 | sql_exec (plugin->dbh, |
299 | "CREATE TABLE IF NOT EXISTS membership (" | 319 | "CREATE TABLE IF NOT EXISTS membership (\n" |
300 | " channel_id INTEGER NOT NULL REFERENCES channels(id)," | 320 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
301 | " slave_id INTEGER NOT NULL REFERENCES slaves(id)," | 321 | " slave_id INTEGER NOT NULL REFERENCES slaves(id),\n" |
302 | " did_join INTEGER NOT NULL," | 322 | " did_join INTEGER NOT NULL,\n" |
303 | " announced_at INTEGER NOT NULL," | 323 | " announced_at INTEGER NOT NULL,\n" |
304 | " effective_since INTEGER NOT NULL," | 324 | " effective_since INTEGER NOT NULL,\n" |
305 | " group_generation INTEGER NOT NULL" | 325 | " group_generation INTEGER NOT NULL\n" |
306 | ");"); | 326 | ");"); |
307 | sql_exec (plugin->dbh, | 327 | sql_exec (plugin->dbh, |
308 | "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id " | 328 | "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id " |
309 | "ON membership (channel_id, slave_id);"); | 329 | "ON membership (channel_id, slave_id);"); |
310 | 330 | ||
311 | sql_exec (plugin->dbh, | 331 | sql_exec (plugin->dbh, |
312 | "CREATE TABLE IF NOT EXISTS messages (" | 332 | "CREATE TABLE IF NOT EXISTS messages (\n" |
313 | " channel_id INTEGER NOT NULL," | 333 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
314 | " hop_counter INTEGER NOT NULL," | 334 | " hop_counter INTEGER NOT NULL,\n" |
315 | " signature BLOB," | 335 | " signature BLOB,\n" |
316 | " purpose BLOB," | 336 | " purpose BLOB,\n" |
317 | " fragment_id INTEGER NOT NULL," | 337 | " fragment_id INTEGER NOT NULL,\n" |
318 | " fragment_offset INTEGER NOT NULL," | 338 | " fragment_offset INTEGER NOT NULL,\n" |
319 | " message_id INTEGER NOT NULL," | 339 | " message_id INTEGER NOT NULL,\n" |
320 | " group_generation INTEGER NOT NULL," | 340 | " group_generation INTEGER NOT NULL,\n" |
321 | " multicast_flags INTEGER NOT NULL," | 341 | " multicast_flags INTEGER NOT NULL,\n" |
322 | " psyc_flags INTEGER NOT NULL," | 342 | " psycstore_flags INTEGER NOT NULL,\n" |
323 | " data BLOB," | 343 | " data BLOB,\n" |
324 | " PRIMARY KEY (channel_id, fragment_id)," | 344 | " PRIMARY KEY (channel_id, fragment_id),\n" |
325 | " UNIQUE (channel_id, message_id, fragment_offset)" | 345 | " UNIQUE (channel_id, message_id, fragment_offset)\n" |
326 | ");"); | 346 | ");"); |
327 | 347 | ||
328 | sql_exec (plugin->dbh, | 348 | sql_exec (plugin->dbh, |
329 | "CREATE TABLE IF NOT EXISTS state (" | 349 | "CREATE TABLE IF NOT EXISTS state (\n" |
330 | " channel_id INTEGER NOT NULL," | 350 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
331 | " name TEXT NOT NULL," | 351 | " name TEXT NOT NULL,\n" |
332 | " value_current BLOB, " | 352 | " value_current BLOB,\n" |
333 | " value_signed BLOB, " | 353 | " value_signed BLOB,\n" |
334 | " PRIMARY KEY (channel_id, name)" | 354 | " PRIMARY KEY (channel_id, name)\n" |
335 | ");"); | 355 | ");"); |
336 | 356 | ||
337 | sql_exec (plugin->dbh, | 357 | sql_exec (plugin->dbh, |
338 | "CREATE TABLE IF NOT EXISTS state_sync (" | 358 | "CREATE TABLE IF NOT EXISTS state_sync (\n" |
339 | " channel_id INTEGER NOT NULL," | 359 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
340 | " name TEXT NOT NULL," | 360 | " name TEXT NOT NULL,\n" |
341 | " value BLOB, " | 361 | " value BLOB,\n" |
342 | " PRIMARY KEY (channel_id, name)" | 362 | " PRIMARY KEY (channel_id, name)\n" |
343 | ");"); | 363 | ");"); |
344 | 364 | ||
345 | /* Prepare statements */ | 365 | /* Prepare statements */ |
@@ -353,132 +373,143 @@ database_setup (struct Plugin *plugin) | |||
353 | &plugin->insert_slave_key); | 373 | &plugin->insert_slave_key); |
354 | 374 | ||
355 | sql_prepare (plugin->dbh, | 375 | sql_prepare (plugin->dbh, |
356 | "INSERT INTO membership " | 376 | "INSERT INTO membership\n" |
357 | " (channel_id, slave_id, did_join, announced_at, " | 377 | " (channel_id, slave_id, did_join, announced_at,\n" |
358 | " effective_since, group_generation) " | 378 | " effective_since, group_generation)\n" |
359 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), " | 379 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n" |
360 | " (SELECT id FROM slaves WHERE pub_key = ?), " | 380 | " (SELECT id FROM slaves WHERE pub_key = ?),\n" |
361 | " ?, ?, ?, ?);", | 381 | " ?, ?, ?, ?);", |
362 | &plugin->insert_membership); | 382 | &plugin->insert_membership); |
363 | 383 | ||
364 | sql_prepare (plugin->dbh, | 384 | sql_prepare (plugin->dbh, |
365 | "SELECT did_join FROM membership " | 385 | "SELECT did_join FROM membership\n" |
366 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 386 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
367 | " AND slave_id = ? AND effective_since <= ? " | 387 | " AND slave_id = (SELECT id FROM slaves WHERE pub_key = ?)\n" |
388 | " AND effective_since <= ? AND did_join = 1\n" | ||
368 | "ORDER BY announced_at DESC LIMIT 1;", | 389 | "ORDER BY announced_at DESC LIMIT 1;", |
369 | &plugin->select_membership); | 390 | &plugin->select_membership); |
370 | 391 | ||
371 | sql_prepare (plugin->dbh, | 392 | sql_prepare (plugin->dbh, |
372 | "INSERT INTO messages " | 393 | "INSERT INTO messages\n" |
373 | " (channel_id, hop_counter, signature, purpose, " | 394 | " (channel_id, hop_counter, signature, purpose,\n" |
374 | " fragment_id, fragment_offset, message_id, " | 395 | " fragment_id, fragment_offset, message_id,\n" |
375 | " group_generation, multicast_flags, psyc_flags, data) " | 396 | " group_generation, multicast_flags, psycstore_flags, data)\n" |
376 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), " | 397 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n" |
377 | " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", | 398 | " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", |
378 | &plugin->insert_fragment); | 399 | &plugin->insert_fragment); |
379 | 400 | ||
380 | sql_prepare (plugin->dbh, | 401 | sql_prepare (plugin->dbh, |
381 | "UPDATE messages " | 402 | "UPDATE messages\n" |
382 | "SET multicast_flags = multicast_flags | ?, " | 403 | "SET psycstore_flags = psycstore_flags | ?\n" |
383 | " psyc_flags = psyc_flags | ? " | 404 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
384 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 405 | " AND message_id = ? AND fragment_offset = 0;", |
385 | " AND message_id = ?;", | 406 | &plugin->update_message_flags); |
386 | &plugin->update_fragment_flags); | ||
387 | 407 | ||
388 | sql_prepare (plugin->dbh, | 408 | sql_prepare (plugin->dbh, |
389 | "SELECT hop_counter, signature, purpose, " | 409 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
390 | " fragment_offset, message_id, group_generation, " | 410 | " fragment_offset, message_id, group_generation,\n" |
391 | " multicast_flags, psyc_flags, data " | 411 | " multicast_flags, psycstore_flags, data\n" |
392 | "FROM messages " | 412 | "FROM messages\n" |
393 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 413 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
394 | " AND fragment_id = ?;", | 414 | " AND fragment_id = ?;", |
395 | &plugin->select_fragment); | 415 | &plugin->select_fragment); |
396 | 416 | ||
397 | sql_prepare (plugin->dbh, | 417 | sql_prepare (plugin->dbh, |
398 | "SELECT hop_counter, signature, purpose, " | 418 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
399 | " fragment_id, fragment_offset, group_generation, " | 419 | " fragment_offset, message_id, group_generation,\n" |
400 | " multicast_flags, psyc_flags, data " | 420 | " multicast_flags, psycstore_flags, data\n" |
401 | "FROM messages " | 421 | "FROM messages\n" |
402 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 422 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
403 | " AND message_id = ?;", | 423 | " AND message_id = ?;", |
404 | &plugin->select_message); | 424 | &plugin->select_message); |
405 | 425 | ||
406 | sql_prepare (plugin->dbh, | 426 | sql_prepare (plugin->dbh, |
407 | "SELECT hop_counter, signature, purpose, " | 427 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
408 | " fragment_id, message_id, group_generation, " | 428 | " fragment_offset, message_id, group_generation,\n" |
409 | " multicast_flags, psyc_flags, data " | 429 | " multicast_flags, psycstore_flags, data\n" |
410 | "FROM messages " | 430 | "FROM messages\n" |
411 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 431 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
412 | " AND message_id = ? AND fragment_offset = ?;", | 432 | " AND message_id = ? AND fragment_offset = ?;", |
413 | &plugin->select_message_fragment); | 433 | &plugin->select_message_fragment); |
414 | 434 | ||
415 | sql_prepare (plugin->dbh, | 435 | sql_prepare (plugin->dbh, |
416 | "SELECT max(fragment_id), max(message_id), max(group_generation) " | 436 | "SELECT fragment_id, message_id, group_generation\n" |
417 | "FROM messages " | 437 | "FROM messages\n" |
418 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 438 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
419 | &plugin->select_master_counters); | 439 | "ORDER BY fragment_id DESC LIMIT 1;", |
440 | &plugin->select_counters_master); | ||
420 | 441 | ||
421 | sql_prepare (plugin->dbh, | 442 | sql_prepare (plugin->dbh, |
422 | "SELECT max(message_id) " | 443 | "SELECT message_id\n" |
423 | "FROM messages " | 444 | "FROM messages\n" |
424 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 445 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
425 | " AND psyc_flags & ?;", | 446 | " AND psycstore_flags & ?\n" |
426 | &plugin->select_slave_counters); | 447 | "ORDER BY message_id DESC LIMIT 1", |
448 | &plugin->select_counters_slave); | ||
427 | 449 | ||
428 | sql_prepare (plugin->dbh, | 450 | sql_prepare (plugin->dbh, |
429 | "INSERT OR REPLACE INTO state (channel_id, name, value_current) " | 451 | "INSERT OR REPLACE INTO state\n" |
430 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", | 452 | " (channel_id, name, value_current, value_signed)\n" |
453 | "SELECT new.channel_id, new.name,\n" | ||
454 | " new.value_current, old.value_signed\n" | ||
455 | "FROM (SELECT (SELECT id FROM channels WHERE pub_key = ?)\n" | ||
456 | " AS channel_id,\n" | ||
457 | " ? AS name, ? AS value_current) AS new\n" | ||
458 | "LEFT JOIN (SELECT channel_id, name, value_signed\n" | ||
459 | " FROM state) AS old\n" | ||
460 | "ON new.channel_id = old.channel_id AND new.name = old.name;", | ||
431 | &plugin->insert_state_current); | 461 | &plugin->insert_state_current); |
432 | 462 | ||
433 | sql_prepare (plugin->dbh, | 463 | sql_prepare (plugin->dbh, |
434 | "UPDATE state " | 464 | "UPDATE state\n" |
435 | "SET value_current = ? " | 465 | "SET value_signed = value_current\n" |
436 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 466 | "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); | 467 | &plugin->update_state_signed); |
445 | 468 | ||
446 | sql_prepare (plugin->dbh, | 469 | sql_prepare (plugin->dbh, |
447 | "INSERT INTO state_sync (channel_id, name, value) " | 470 | "INSERT INTO state_sync (channel_id, name, value)\n" |
448 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", | 471 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", |
449 | &plugin->insert_state_sync); | 472 | &plugin->insert_state_sync); |
450 | 473 | ||
451 | sql_prepare (plugin->dbh, | 474 | sql_prepare (plugin->dbh, |
452 | "DELETE FROM state " | 475 | "DELETE FROM state\n" |
453 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 476 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
454 | &plugin->delete_state); | 477 | &plugin->delete_state); |
455 | 478 | ||
456 | sql_prepare (plugin->dbh, | 479 | sql_prepare (plugin->dbh, |
457 | "INSERT INTO state " | 480 | "INSERT INTO state\n" |
458 | " (channel_id, name, value_current, value_signed) " | 481 | " (channel_id, name, value_current, value_signed)\n" |
459 | "SELECT channel_id, name, value, value " | 482 | "SELECT channel_id, name, value, value\n" |
460 | "FROM state_sync " | 483 | "FROM state_sync\n" |
461 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 484 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
462 | &plugin->insert_state_from_sync); | 485 | &plugin->insert_state_from_sync); |
463 | 486 | ||
464 | sql_prepare (plugin->dbh, | 487 | sql_prepare (plugin->dbh, |
465 | "DELETE FROM state_sync " | 488 | "DELETE FROM state_sync\n" |
466 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 489 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
467 | &plugin->delete_state_sync); | 490 | &plugin->delete_state_sync); |
468 | 491 | ||
469 | sql_prepare (plugin->dbh, | 492 | sql_prepare (plugin->dbh, |
470 | "SELECT value_current " | 493 | "SELECT value_current\n" |
471 | "FROM state " | 494 | "FROM state\n" |
472 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 495 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
473 | " AND name = ?;", | 496 | " AND name = ?;", |
474 | &plugin->select_state_one); | 497 | &plugin->select_state_one); |
475 | 498 | ||
476 | sql_prepare (plugin->dbh, | 499 | sql_prepare (plugin->dbh, |
477 | "SELECT value_current " | 500 | "SELECT name, value_current\n" |
478 | "FROM state " | 501 | "FROM state\n" |
479 | "WHERE name LIKE ? OR name LIKE ?;", | 502 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
503 | " AND name = ? OR name LIKE ?;", | ||
480 | &plugin->select_state_prefix); | 504 | &plugin->select_state_prefix); |
481 | 505 | ||
506 | sql_prepare (plugin->dbh, | ||
507 | "SELECT name, value_signed\n" | ||
508 | "FROM state\n" | ||
509 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)" | ||
510 | " AND value_signed IS NOT NULL;", | ||
511 | &plugin->select_state_signed); | ||
512 | |||
482 | return GNUNET_OK; | 513 | return GNUNET_OK; |
483 | } | 514 | } |
484 | 515 | ||
@@ -509,8 +540,8 @@ database_shutdown (struct Plugin *plugin) | |||
509 | if (NULL != plugin->insert_fragment) | 540 | if (NULL != plugin->insert_fragment) |
510 | sqlite3_finalize (plugin->insert_fragment); | 541 | sqlite3_finalize (plugin->insert_fragment); |
511 | 542 | ||
512 | if (NULL != plugin->update_fragment_flags) | 543 | if (NULL != plugin->update_message_flags) |
513 | sqlite3_finalize (plugin->update_fragment_flags); | 544 | sqlite3_finalize (plugin->update_message_flags); |
514 | 545 | ||
515 | if (NULL != plugin->select_fragment) | 546 | if (NULL != plugin->select_fragment) |
516 | sqlite3_finalize (plugin->select_fragment); | 547 | sqlite3_finalize (plugin->select_fragment); |
@@ -521,18 +552,15 @@ database_shutdown (struct Plugin *plugin) | |||
521 | if (NULL != plugin->select_message_fragment) | 552 | if (NULL != plugin->select_message_fragment) |
522 | sqlite3_finalize (plugin->select_message_fragment); | 553 | sqlite3_finalize (plugin->select_message_fragment); |
523 | 554 | ||
524 | if (NULL != plugin->select_master_counters) | 555 | if (NULL != plugin->select_counters_master) |
525 | sqlite3_finalize (plugin->select_master_counters); | 556 | sqlite3_finalize (plugin->select_counters_master); |
526 | 557 | ||
527 | if (NULL != plugin->select_slave_counters) | 558 | if (NULL != plugin->select_counters_slave) |
528 | sqlite3_finalize (plugin->select_slave_counters); | 559 | sqlite3_finalize (plugin->select_counters_slave); |
529 | 560 | ||
530 | if (NULL != plugin->insert_state_current) | 561 | if (NULL != plugin->insert_state_current) |
531 | sqlite3_finalize (plugin->insert_state_current); | 562 | sqlite3_finalize (plugin->insert_state_current); |
532 | 563 | ||
533 | if (NULL != plugin->update_state_current) | ||
534 | sqlite3_finalize (plugin->update_state_current); | ||
535 | |||
536 | if (NULL != plugin->update_state_signed) | 564 | if (NULL != plugin->update_state_signed) |
537 | sqlite3_finalize (plugin->update_state_signed); | 565 | sqlite3_finalize (plugin->update_state_signed); |
538 | 566 | ||
@@ -579,6 +607,65 @@ database_shutdown (struct Plugin *plugin) | |||
579 | } | 607 | } |
580 | 608 | ||
581 | 609 | ||
610 | static int | ||
611 | channel_key_store (struct Plugin *plugin, | ||
612 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
613 | { | ||
614 | sqlite3_stmt *stmt = plugin->insert_channel_key; | ||
615 | |||
616 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
617 | sizeof (*channel_key), SQLITE_STATIC)) | ||
618 | { | ||
619 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
620 | "insert_channel_key (bind)"); | ||
621 | } | ||
622 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
623 | { | ||
624 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
625 | "insert_channel_key (step)"); | ||
626 | } | ||
627 | |||
628 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
629 | { | ||
630 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
631 | "insert_channel_key (reset)"); | ||
632 | return GNUNET_SYSERR; | ||
633 | } | ||
634 | |||
635 | return GNUNET_OK; | ||
636 | } | ||
637 | |||
638 | |||
639 | static int | ||
640 | slave_key_store (struct Plugin *plugin, | ||
641 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key) | ||
642 | { | ||
643 | sqlite3_stmt *stmt = plugin->insert_slave_key; | ||
644 | |||
645 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, slave_key, | ||
646 | sizeof (*slave_key), SQLITE_STATIC)) | ||
647 | { | ||
648 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
649 | "insert_slave_key (bind)"); | ||
650 | } | ||
651 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
652 | { | ||
653 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
654 | "insert_slave_key (step)"); | ||
655 | } | ||
656 | |||
657 | |||
658 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
659 | { | ||
660 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
661 | "insert_slave_key (reset)"); | ||
662 | return GNUNET_SYSERR; | ||
663 | } | ||
664 | |||
665 | return GNUNET_OK; | ||
666 | } | ||
667 | |||
668 | |||
582 | /** | 669 | /** |
583 | * Store join/leave events for a PSYC channel in order to be able to answer | 670 | * Store join/leave events for a PSYC channel in order to be able to answer |
584 | * membership test queries later. | 671 | * membership test queries later. |
@@ -587,17 +674,56 @@ database_shutdown (struct Plugin *plugin) | |||
587 | * | 674 | * |
588 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 675 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
589 | */ | 676 | */ |
590 | int | 677 | static int |
591 | libgnunet_plugin_psycstore_sqlite_membership_store | 678 | membership_store (void *cls, |
592 | (void *cls, | 679 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
593 | const struct GNUNET_HashCode *channel_key, | 680 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
594 | const struct GNUNET_HashCode *slave_key, | 681 | int did_join, |
595 | int did_join, | 682 | uint64_t announced_at, |
596 | uint64_t announced_at, | 683 | uint64_t effective_since, |
597 | uint64_t effective_since, | 684 | uint64_t group_generation) |
598 | uint64_t group_generation) { | 685 | { |
686 | if (announced_at > INT64_MAX || | ||
687 | effective_since > INT64_MAX || | ||
688 | group_generation > INT64_MAX) | ||
689 | { | ||
690 | GNUNET_break (0); | ||
691 | return GNUNET_SYSERR; | ||
692 | } | ||
693 | |||
694 | struct Plugin *plugin = cls; | ||
695 | sqlite3_stmt *stmt = plugin->insert_membership; | ||
599 | 696 | ||
697 | if (GNUNET_OK != channel_key_store (plugin, channel_key) || | ||
698 | GNUNET_OK != slave_key_store (plugin, slave_key)) | ||
699 | return GNUNET_SYSERR; | ||
600 | 700 | ||
701 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
702 | sizeof (*channel_key), SQLITE_STATIC) || | ||
703 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key, | ||
704 | sizeof (*slave_key), SQLITE_STATIC) || | ||
705 | SQLITE_OK != sqlite3_bind_int (stmt, 3, did_join) || | ||
706 | SQLITE_OK != sqlite3_bind_int64 (stmt, 4, announced_at) || | ||
707 | SQLITE_OK != sqlite3_bind_int64 (stmt, 5, effective_since) || | ||
708 | SQLITE_OK != sqlite3_bind_int64 (stmt, 6, group_generation)) | ||
709 | { | ||
710 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
711 | "insert_membership (bind)"); | ||
712 | } | ||
713 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
714 | { | ||
715 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
716 | "insert_membership (step)"); | ||
717 | } | ||
718 | |||
719 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
720 | { | ||
721 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
722 | "insert_membership (reset)"); | ||
723 | return GNUNET_SYSERR; | ||
724 | } | ||
725 | |||
726 | return GNUNET_OK; | ||
601 | } | 727 | } |
602 | 728 | ||
603 | /** | 729 | /** |
@@ -608,14 +734,44 @@ libgnunet_plugin_psycstore_sqlite_membership_store | |||
608 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, | 734 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, |
609 | * #GNUNET_SYSERR if there was en error. | 735 | * #GNUNET_SYSERR if there was en error. |
610 | */ | 736 | */ |
611 | int | 737 | static int |
612 | libgnunet_plugin_psycstore_sqlite_membership_test | 738 | membership_test (void *cls, |
613 | (void *cls, | 739 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
614 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 740 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
615 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | 741 | uint64_t message_id) |
616 | uint64_t message_id, | 742 | { |
617 | uint64_t group_generation) { | 743 | struct Plugin *plugin = cls; |
744 | sqlite3_stmt *stmt = plugin->select_membership; | ||
745 | int ret = GNUNET_SYSERR; | ||
746 | |||
747 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
748 | sizeof (*channel_key), SQLITE_STATIC) || | ||
749 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key, | ||
750 | sizeof (*slave_key), SQLITE_STATIC) || | ||
751 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id)) | ||
752 | { | ||
753 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
754 | "select_membership (bind)"); | ||
755 | } | ||
756 | else | ||
757 | { | ||
758 | switch (sqlite3_step (stmt)) | ||
759 | { | ||
760 | case SQLITE_DONE: | ||
761 | ret = GNUNET_NO; | ||
762 | break; | ||
763 | case SQLITE_ROW: | ||
764 | ret = GNUNET_YES; | ||
765 | } | ||
766 | } | ||
618 | 767 | ||
768 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
769 | { | ||
770 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
771 | "select_membership (reset)"); | ||
772 | } | ||
773 | |||
774 | return ret; | ||
619 | } | 775 | } |
620 | 776 | ||
621 | /** | 777 | /** |
@@ -625,30 +781,141 @@ libgnunet_plugin_psycstore_sqlite_membership_test | |||
625 | * | 781 | * |
626 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 782 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
627 | */ | 783 | */ |
628 | int | 784 | static int |
629 | libgnunet_plugin_psycstore_sqlite_fragment_store | 785 | fragment_store (void *cls, |
630 | (void *cls, | 786 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
631 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 787 | const struct GNUNET_MULTICAST_MessageHeader *msg, |
632 | const struct GNUNET_MULTICAST_MessageHeader *message) { | 788 | uint32_t psycstore_flags) |
789 | { | ||
790 | if (msg->fragment_id > INT64_MAX || | ||
791 | msg->fragment_offset > INT64_MAX || | ||
792 | msg->message_id > INT64_MAX || | ||
793 | msg->group_generation > INT64_MAX) | ||
794 | { | ||
795 | GNUNET_break (0); | ||
796 | return GNUNET_SYSERR; | ||
797 | } | ||
798 | |||
799 | struct Plugin *plugin = cls; | ||
800 | sqlite3_stmt *stmt = plugin->insert_fragment; | ||
801 | |||
802 | if (GNUNET_OK != channel_key_store (plugin, channel_key)) | ||
803 | return GNUNET_SYSERR; | ||
804 | |||
805 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
806 | sizeof (*channel_key), SQLITE_STATIC) || | ||
807 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, msg->hop_counter ) || | ||
808 | SQLITE_OK != sqlite3_bind_blob (stmt, 3, (const void *) &msg->signature, | ||
809 | sizeof (msg->signature), SQLITE_STATIC) || | ||
810 | SQLITE_OK != sqlite3_bind_blob (stmt, 4, (const void *) &msg->purpose, | ||
811 | sizeof (msg->purpose), SQLITE_STATIC) || | ||
812 | SQLITE_OK != sqlite3_bind_int64 (stmt, 5, msg->fragment_id) || | ||
813 | SQLITE_OK != sqlite3_bind_int64 (stmt, 6, msg->fragment_offset) || | ||
814 | SQLITE_OK != sqlite3_bind_int64 (stmt, 7, msg->message_id) || | ||
815 | SQLITE_OK != sqlite3_bind_int64 (stmt, 8, msg->group_generation) || | ||
816 | SQLITE_OK != sqlite3_bind_int64 (stmt, 9, msg->flags) || | ||
817 | SQLITE_OK != sqlite3_bind_int64 (stmt, 10, psycstore_flags) || | ||
818 | SQLITE_OK != sqlite3_bind_blob (stmt, 11, (const void *) &msg[1], | ||
819 | ntohs (msg->header.size) - sizeof (*msg), | ||
820 | SQLITE_STATIC)) | ||
821 | { | ||
822 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
823 | "insert_fragment (bind)"); | ||
824 | } | ||
825 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
826 | { | ||
827 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
828 | "insert_fragment (step)"); | ||
829 | } | ||
830 | |||
831 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
832 | { | ||
833 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
834 | "insert_fragment (reset)"); | ||
835 | return GNUNET_SYSERR; | ||
836 | } | ||
633 | 837 | ||
838 | return GNUNET_OK; | ||
634 | } | 839 | } |
635 | 840 | ||
636 | /** | 841 | /** |
637 | * Set additional flags for a given message. | 842 | * Set additional flags for a given message. |
638 | * | 843 | * |
844 | * They are OR'd with any existing flags set. | ||
845 | * | ||
846 | * @param plugin Plugin handle. | ||
847 | * @param channel_key Public key of the channel. | ||
639 | * @param message_id ID of the message. | 848 | * @param message_id ID of the message. |
640 | * @param flags Flags to add. | 849 | * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags. |
641 | * | 850 | * |
642 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 851 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
643 | */ | 852 | */ |
644 | int | 853 | static int |
645 | libgnunet_plugin_psycstore_sqlite_fragment_add_flags | 854 | message_add_flags (void *cls, |
646 | (void *cls, | 855 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
647 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 856 | uint64_t message_id, |
648 | uint64_t message_id, | 857 | uint64_t psycstore_flags) |
649 | uint64_t multicast_flags, | 858 | { |
650 | uint64_t psyc_flags) { | 859 | struct Plugin *plugin = cls; |
860 | sqlite3_stmt *stmt = plugin->update_message_flags; | ||
861 | int ret = GNUNET_SYSERR; | ||
862 | |||
863 | if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, psycstore_flags) || | ||
864 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key, | ||
865 | sizeof (*channel_key), SQLITE_STATIC) || | ||
866 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id)) | ||
867 | { | ||
868 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
869 | "update_message_flags (bind)"); | ||
870 | } | ||
871 | else | ||
872 | { | ||
873 | switch (sqlite3_step (stmt)) | ||
874 | { | ||
875 | case SQLITE_DONE: | ||
876 | ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO; | ||
877 | break; | ||
878 | default: | ||
879 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
880 | "update_message_flags (step)"); | ||
881 | } | ||
882 | } | ||
883 | |||
884 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
885 | { | ||
886 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
887 | "update_message_flags (reset)"); | ||
888 | return GNUNET_SYSERR; | ||
889 | } | ||
890 | |||
891 | return ret; | ||
892 | } | ||
651 | 893 | ||
894 | static int | ||
895 | fragment_row (sqlite3_stmt *stmt, GNUNET_PSYCSTORE_FragmentCallback cb, | ||
896 | void *cb_cls) | ||
897 | { | ||
898 | int data_size = sqlite3_column_bytes (stmt, 9); | ||
899 | struct GNUNET_MULTICAST_MessageHeader *msg | ||
900 | = GNUNET_malloc (sizeof (*msg) + data_size); | ||
901 | |||
902 | msg->header.size = htons (sizeof (*msg) + data_size); | ||
903 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE); | ||
904 | msg->hop_counter = (uint32_t) sqlite3_column_int64 (stmt, 0); | ||
905 | memcpy (&msg->signature, | ||
906 | sqlite3_column_blob (stmt, 1), | ||
907 | sqlite3_column_bytes (stmt, 1)); | ||
908 | memcpy (&msg->purpose, | ||
909 | sqlite3_column_blob (stmt, 2), | ||
910 | sqlite3_column_bytes (stmt, 2)); | ||
911 | msg->fragment_id = sqlite3_column_int64 (stmt, 3); | ||
912 | msg->fragment_offset = sqlite3_column_int64 (stmt, 4); | ||
913 | msg->message_id = sqlite3_column_int64 (stmt, 5); | ||
914 | msg->group_generation = sqlite3_column_int64 (stmt, 6); | ||
915 | msg->flags = sqlite3_column_int64 (stmt, 7); | ||
916 | memcpy (&msg[1], sqlite3_column_blob (stmt, 9), data_size); | ||
917 | |||
918 | return cb (cb_cls, (void *) msg, sqlite3_column_int64 (stmt, 8)); | ||
652 | } | 919 | } |
653 | 920 | ||
654 | /** | 921 | /** |
@@ -658,14 +925,49 @@ libgnunet_plugin_psycstore_sqlite_fragment_add_flags | |||
658 | * | 925 | * |
659 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 926 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
660 | */ | 927 | */ |
661 | int | 928 | static int |
662 | libgnunet_plugin_psycstore_sqlite_fragment_get | 929 | fragment_get (void *cls, |
663 | (void *cls, | 930 | const struct |
664 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 931 | GNUNET_CRYPTO_EccPublicKey *channel_key, |
665 | uint64_t fragment_id, | 932 | uint64_t fragment_id, |
666 | GNUNET_PSYCSTORE_FragmentCallback cb, | 933 | GNUNET_PSYCSTORE_FragmentCallback cb, |
667 | void *cb_cls) { | 934 | void *cb_cls) |
935 | { | ||
936 | struct Plugin *plugin = cls; | ||
937 | sqlite3_stmt *stmt = plugin->select_fragment; | ||
938 | int ret = GNUNET_SYSERR; | ||
939 | |||
940 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
941 | sizeof (*channel_key), | ||
942 | SQLITE_STATIC) || | ||
943 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, fragment_id)) | ||
944 | { | ||
945 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
946 | "select_fragment (bind)"); | ||
947 | } | ||
948 | else | ||
949 | { | ||
950 | switch (sqlite3_step (stmt)) | ||
951 | { | ||
952 | case SQLITE_DONE: | ||
953 | ret = GNUNET_NO; | ||
954 | break; | ||
955 | case SQLITE_ROW: | ||
956 | ret = fragment_row (stmt, cb, cb_cls); | ||
957 | break; | ||
958 | default: | ||
959 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
960 | "select_fragment (step)"); | ||
961 | } | ||
962 | } | ||
668 | 963 | ||
964 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
965 | { | ||
966 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
967 | "select_fragment (reset)"); | ||
968 | } | ||
969 | |||
970 | return ret; | ||
669 | } | 971 | } |
670 | 972 | ||
671 | /** | 973 | /** |
@@ -675,14 +977,57 @@ libgnunet_plugin_psycstore_sqlite_fragment_get | |||
675 | * | 977 | * |
676 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 978 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
677 | */ | 979 | */ |
678 | int | 980 | static int |
679 | libgnunet_plugin_psycstore_sqlite_message_get | 981 | message_get (void *cls, |
680 | (void *cls, | 982 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
681 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 983 | uint64_t message_id, |
682 | uint64_t message_id, | 984 | GNUNET_PSYCSTORE_FragmentCallback cb, |
683 | GNUNET_PSYCSTORE_FragmentCallback cb, | 985 | void *cb_cls) |
684 | void *cb_cls) { | 986 | { |
987 | struct Plugin *plugin = cls; | ||
988 | sqlite3_stmt *stmt = plugin->select_message; | ||
989 | int ret = GNUNET_SYSERR; | ||
990 | |||
991 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
992 | sizeof (*channel_key), | ||
993 | SQLITE_STATIC) || | ||
994 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id)) | ||
995 | { | ||
996 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
997 | "select_message (bind)"); | ||
998 | } | ||
999 | else | ||
1000 | { | ||
1001 | int sql_ret; | ||
1002 | do | ||
1003 | { | ||
1004 | sql_ret = sqlite3_step (stmt); | ||
1005 | switch (sql_ret) | ||
1006 | { | ||
1007 | case SQLITE_DONE: | ||
1008 | if (ret != GNUNET_OK) | ||
1009 | ret = GNUNET_NO; | ||
1010 | break; | ||
1011 | case SQLITE_ROW: | ||
1012 | ret = fragment_row (stmt, cb, cb_cls); | ||
1013 | if (ret != GNUNET_YES) | ||
1014 | sql_ret = SQLITE_DONE; | ||
1015 | break; | ||
1016 | default: | ||
1017 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1018 | "select_message (step)"); | ||
1019 | } | ||
1020 | } | ||
1021 | while (sql_ret == SQLITE_ROW); | ||
1022 | } | ||
685 | 1023 | ||
1024 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1025 | { | ||
1026 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1027 | "select_message (reset)"); | ||
1028 | } | ||
1029 | |||
1030 | return ret; | ||
686 | } | 1031 | } |
687 | 1032 | ||
688 | /** | 1033 | /** |
@@ -693,16 +1038,51 @@ libgnunet_plugin_psycstore_sqlite_message_get | |||
693 | * | 1038 | * |
694 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1039 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
695 | */ | 1040 | */ |
696 | int | 1041 | static int |
697 | libgnunet_plugin_psycstore_sqlite_message_get_fragment | 1042 | message_get_fragment (void *cls, |
698 | (void *cls, | 1043 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
699 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1044 | uint64_t message_id, |
700 | uint64_t message_id, | 1045 | uint64_t fragment_offset, |
701 | uint64_t fragment_offset, | 1046 | GNUNET_PSYCSTORE_FragmentCallback cb, |
702 | GNUNET_PSYCSTORE_FragmentCallback cb, | 1047 | void *cb_cls) |
703 | void *cb_cls) | ||
704 | { | 1048 | { |
1049 | struct Plugin *plugin = cls; | ||
1050 | int ret = GNUNET_SYSERR; | ||
1051 | |||
1052 | sqlite3_stmt *stmt = plugin->select_message_fragment; | ||
1053 | |||
1054 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1055 | sizeof (*channel_key), | ||
1056 | SQLITE_STATIC) || | ||
1057 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id) || | ||
1058 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, fragment_offset)) | ||
1059 | { | ||
1060 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1061 | "select_message_fragment (bind)"); | ||
1062 | } | ||
1063 | else | ||
1064 | { | ||
1065 | switch (sqlite3_step (stmt)) | ||
1066 | { | ||
1067 | case SQLITE_DONE: | ||
1068 | ret = GNUNET_NO; | ||
1069 | break; | ||
1070 | case SQLITE_ROW: | ||
1071 | ret = fragment_row (stmt, cb, cb_cls); | ||
1072 | break; | ||
1073 | default: | ||
1074 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1075 | "select_message_fragment (step)"); | ||
1076 | } | ||
1077 | } | ||
705 | 1078 | ||
1079 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1080 | { | ||
1081 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1082 | "select_message_fragment (reset)"); | ||
1083 | } | ||
1084 | |||
1085 | return ret; | ||
706 | } | 1086 | } |
707 | 1087 | ||
708 | /** | 1088 | /** |
@@ -712,15 +1092,50 @@ libgnunet_plugin_psycstore_sqlite_message_get_fragment | |||
712 | * | 1092 | * |
713 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1093 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
714 | */ | 1094 | */ |
715 | int | 1095 | static int |
716 | libgnunet_plugin_psycstore_sqlite_counters_get_master | 1096 | counters_get_master (void *cls, |
717 | (void *cls, | 1097 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
718 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1098 | uint64_t *fragment_id, |
719 | uint64_t *fragment_id, | 1099 | uint64_t *message_id, |
720 | uint64_t *message_id, | 1100 | uint64_t *group_generation) |
721 | uint64_t *group_generation) | ||
722 | { | 1101 | { |
1102 | struct Plugin *plugin = cls; | ||
1103 | sqlite3_stmt *stmt = plugin->select_counters_master; | ||
1104 | int ret = GNUNET_SYSERR; | ||
1105 | |||
1106 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1107 | sizeof (*channel_key), | ||
1108 | SQLITE_STATIC)) | ||
1109 | { | ||
1110 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1111 | "select_counters_master (bind)"); | ||
1112 | } | ||
1113 | else | ||
1114 | { | ||
1115 | switch (sqlite3_step (stmt)) | ||
1116 | { | ||
1117 | case SQLITE_DONE: | ||
1118 | ret = GNUNET_NO; | ||
1119 | break; | ||
1120 | case SQLITE_ROW: | ||
1121 | *fragment_id = sqlite3_column_int64 (stmt, 0); | ||
1122 | *message_id = sqlite3_column_int64 (stmt, 1); | ||
1123 | *group_generation = sqlite3_column_int64 (stmt, 2); | ||
1124 | ret = GNUNET_OK; | ||
1125 | break; | ||
1126 | default: | ||
1127 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1128 | "select_counters_master (step)"); | ||
1129 | } | ||
1130 | } | ||
723 | 1131 | ||
1132 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1133 | { | ||
1134 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1135 | "select_counters_master (reset)"); | ||
1136 | } | ||
1137 | |||
1138 | return ret; | ||
724 | } | 1139 | } |
725 | 1140 | ||
726 | /** | 1141 | /** |
@@ -730,12 +1145,48 @@ libgnunet_plugin_psycstore_sqlite_counters_get_master | |||
730 | * | 1145 | * |
731 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1146 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
732 | */ | 1147 | */ |
733 | int | 1148 | static int |
734 | libgnunet_plugin_psycstore_sqlite_counters_get_slave | 1149 | counters_get_slave (void *cls, |
735 | (void *cls, | 1150 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
736 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1151 | uint64_t *max_state_msg_id) |
737 | uint64_t *max_state_msg_id) { | 1152 | { |
1153 | struct Plugin *plugin = cls; | ||
1154 | sqlite3_stmt *stmt = plugin->select_counters_slave; | ||
1155 | int ret = GNUNET_SYSERR; | ||
1156 | |||
1157 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1158 | sizeof (*channel_key), | ||
1159 | SQLITE_STATIC) || | ||
1160 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, | ||
1161 | GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED)) | ||
1162 | { | ||
1163 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1164 | "select_counters_slave (bind)"); | ||
1165 | } | ||
1166 | else | ||
1167 | { | ||
1168 | switch (sqlite3_step (stmt)) | ||
1169 | { | ||
1170 | case SQLITE_DONE: | ||
1171 | ret = GNUNET_NO; | ||
1172 | break; | ||
1173 | case SQLITE_ROW: | ||
1174 | *max_state_msg_id = sqlite3_column_int64 (stmt, 0); | ||
1175 | ret = GNUNET_OK; | ||
1176 | break; | ||
1177 | default: | ||
1178 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1179 | "select_counters_slave (step)"); | ||
1180 | } | ||
1181 | } | ||
738 | 1182 | ||
1183 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1184 | { | ||
1185 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1186 | "select_counters_slave (reset)"); | ||
1187 | } | ||
1188 | |||
1189 | return ret; | ||
739 | } | 1190 | } |
740 | 1191 | ||
741 | /** | 1192 | /** |
@@ -745,35 +1196,174 @@ libgnunet_plugin_psycstore_sqlite_counters_get_slave | |||
745 | * | 1196 | * |
746 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1197 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
747 | */ | 1198 | */ |
748 | int | 1199 | static int |
749 | libgnunet_plugin_psycstore_sqlite_state_set | 1200 | state_set (void *cls, |
750 | (struct GNUNET_PSYCSTORE_Handle *h, | 1201 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
751 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1202 | const char *name, const void *value, size_t value_size) |
752 | const char *name, | 1203 | { |
753 | size_t value_size, | 1204 | struct Plugin *plugin = cls; |
754 | const void *value) { | 1205 | int ret = GNUNET_SYSERR; |
1206 | |||
1207 | sqlite3_stmt *stmt = plugin->insert_state_current; | ||
1208 | |||
1209 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1210 | sizeof (*channel_key), SQLITE_STATIC) || | ||
1211 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC) || | ||
1212 | SQLITE_OK != sqlite3_bind_blob (stmt, 3, value, value_size, | ||
1213 | SQLITE_STATIC)) | ||
1214 | { | ||
1215 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1216 | "insert_state_current (bind)"); | ||
1217 | } | ||
1218 | else | ||
1219 | { | ||
1220 | switch (sqlite3_step (stmt)) | ||
1221 | { | ||
1222 | case SQLITE_DONE: | ||
1223 | ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO; | ||
1224 | break; | ||
1225 | default: | ||
1226 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1227 | "insert_state_current (step)"); | ||
1228 | } | ||
1229 | } | ||
1230 | |||
1231 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1232 | { | ||
1233 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1234 | "insert_state_current (reset)"); | ||
1235 | return GNUNET_SYSERR; | ||
1236 | } | ||
1237 | |||
1238 | return ret; | ||
1239 | } | ||
1240 | |||
1241 | |||
1242 | /** | ||
1243 | * Reset the state of a channel. | ||
1244 | * | ||
1245 | * @see GNUNET_PSYCSTORE_state_reset() | ||
1246 | * | ||
1247 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1248 | */ | ||
1249 | static int | ||
1250 | state_reset (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
1251 | { | ||
1252 | struct Plugin *plugin = cls; | ||
1253 | sqlite3_stmt *stmt = plugin->delete_state; | ||
1254 | |||
1255 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1256 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1257 | { | ||
1258 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1259 | "delete_state (bind)"); | ||
1260 | } | ||
1261 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
1262 | { | ||
1263 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1264 | "delete_state (step)"); | ||
1265 | } | ||
1266 | |||
1267 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1268 | { | ||
1269 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1270 | "delete_state (reset)"); | ||
1271 | return GNUNET_SYSERR; | ||
1272 | } | ||
1273 | |||
1274 | return GNUNET_OK; | ||
1275 | } | ||
1276 | |||
1277 | |||
1278 | /** | ||
1279 | * Update signed values of state variables in the state store. | ||
1280 | * | ||
1281 | * @see GNUNET_PSYCSTORE_state_hash_update() | ||
1282 | * | ||
1283 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1284 | */ | ||
1285 | static int | ||
1286 | state_update_signed (void *cls, | ||
1287 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
1288 | { | ||
1289 | struct Plugin *plugin = cls; | ||
1290 | sqlite3_stmt *stmt = plugin->update_state_signed; | ||
1291 | |||
1292 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1293 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1294 | { | ||
1295 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1296 | "update_state_signed (bind)"); | ||
1297 | } | ||
1298 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
1299 | { | ||
1300 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1301 | "update_state_signed (step)"); | ||
1302 | } | ||
1303 | |||
1304 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1305 | { | ||
1306 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1307 | "update_state_signed (reset)"); | ||
1308 | return GNUNET_SYSERR; | ||
1309 | } | ||
755 | 1310 | ||
1311 | return GNUNET_OK; | ||
756 | } | 1312 | } |
757 | 1313 | ||
1314 | |||
758 | /** | 1315 | /** |
759 | * Retrieve a state variable by name. | 1316 | * Retrieve a state variable by name. |
760 | * | 1317 | * |
761 | * @param name Name of the variable to retrieve. | 1318 | * @see GNUNET_PSYCSTORE_state_get() |
762 | * @param[out] value_size Size of value. | ||
763 | * @param[out] value Returned value. | ||
764 | * | 1319 | * |
765 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1320 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
766 | */ | 1321 | */ |
767 | int | 1322 | static int |
768 | libgnunet_plugin_psycstore_sqlite_state_get | 1323 | state_get (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
769 | (struct GNUNET_PSYCSTORE_Handle *h, | 1324 | const char *name, GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls) |
770 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1325 | { |
771 | const char *name, | 1326 | struct Plugin *plugin = cls; |
772 | GNUNET_PSYCSTORE_StateCallback cb, | 1327 | int ret = GNUNET_SYSERR; |
773 | void *cb_cls) { | 1328 | |
1329 | sqlite3_stmt *stmt = plugin->select_state_one; | ||
1330 | |||
1331 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1332 | sizeof (*channel_key), | ||
1333 | SQLITE_STATIC) || | ||
1334 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC)) | ||
1335 | { | ||
1336 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1337 | "select_state_one (bind)"); | ||
1338 | } | ||
1339 | else | ||
1340 | { | ||
1341 | switch (sqlite3_step (stmt)) | ||
1342 | { | ||
1343 | case SQLITE_DONE: | ||
1344 | ret = GNUNET_NO; | ||
1345 | break; | ||
1346 | case SQLITE_ROW: | ||
1347 | ret = cb (cb_cls, name, sqlite3_column_blob (stmt, 0), | ||
1348 | sqlite3_column_bytes (stmt, 0)); | ||
1349 | break; | ||
1350 | default: | ||
1351 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1352 | "select_state_one (step)"); | ||
1353 | } | ||
1354 | } | ||
774 | 1355 | ||
1356 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1357 | { | ||
1358 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1359 | "select_state_one (reset)"); | ||
1360 | } | ||
1361 | |||
1362 | |||
1363 | return ret; | ||
775 | } | 1364 | } |
776 | 1365 | ||
1366 | |||
777 | /** | 1367 | /** |
778 | * Retrieve all state variables for a channel with the given prefix. | 1368 | * Retrieve all state variables for a channel with the given prefix. |
779 | * | 1369 | * |
@@ -781,21 +1371,130 @@ libgnunet_plugin_psycstore_sqlite_state_get | |||
781 | * | 1371 | * |
782 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1372 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
783 | */ | 1373 | */ |
784 | int | 1374 | static int |
785 | libgnunet_plugin_psycstore_sqlite_state_get_all | 1375 | state_get_all (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
786 | (struct GNUNET_PSYCSTORE_Handle *h, | 1376 | const char *name, GNUNET_PSYCSTORE_StateCallback cb, |
787 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1377 | void *cb_cls) |
788 | const char *name, | 1378 | { |
789 | GNUNET_PSYCSTORE_StateCallback cb, | 1379 | struct Plugin *plugin = cls; |
790 | void *cb_cls) { | 1380 | int ret = GNUNET_SYSERR; |
1381 | |||
1382 | sqlite3_stmt *stmt = plugin->select_state_prefix; | ||
1383 | size_t name_len = strlen (name); | ||
1384 | char *name_prefix = GNUNET_malloc (name_len + 2); | ||
1385 | memcpy (name_prefix, name, name_len); | ||
1386 | memcpy (name_prefix + name_len, "_%", 2); | ||
1387 | |||
1388 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1389 | sizeof (*channel_key), SQLITE_STATIC) || | ||
1390 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, name_len, SQLITE_STATIC) || | ||
1391 | SQLITE_OK != sqlite3_bind_text (stmt, 3, name_prefix, name_len + 2, | ||
1392 | SQLITE_STATIC)) | ||
1393 | { | ||
1394 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1395 | "select_state_prefix (bind)"); | ||
1396 | } | ||
1397 | else | ||
1398 | { | ||
1399 | int sql_ret; | ||
1400 | do | ||
1401 | { | ||
1402 | sql_ret = sqlite3_step (stmt); | ||
1403 | switch (sql_ret) | ||
1404 | { | ||
1405 | case SQLITE_DONE: | ||
1406 | if (ret != GNUNET_OK) | ||
1407 | ret = GNUNET_NO; | ||
1408 | break; | ||
1409 | case SQLITE_ROW: | ||
1410 | ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0), | ||
1411 | sqlite3_column_blob (stmt, 1), | ||
1412 | sqlite3_column_bytes (stmt, 1)); | ||
1413 | if (ret != GNUNET_YES) | ||
1414 | sql_ret = SQLITE_DONE; | ||
1415 | break; | ||
1416 | default: | ||
1417 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1418 | "select_state_prefix (step)"); | ||
1419 | } | ||
1420 | } | ||
1421 | while (sql_ret == SQLITE_ROW); | ||
1422 | } | ||
1423 | |||
1424 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1425 | { | ||
1426 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1427 | "select_state_prefix (reset)"); | ||
1428 | } | ||
791 | 1429 | ||
1430 | return ret; | ||
792 | } | 1431 | } |
793 | 1432 | ||
794 | 1433 | ||
795 | /** | 1434 | /** |
1435 | * Retrieve all signed state variables for a channel. | ||
1436 | * | ||
1437 | * @see GNUNET_PSYCSTORE_state_get_signed() | ||
1438 | * | ||
1439 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1440 | */ | ||
1441 | static int | ||
1442 | state_get_signed (void *cls, | ||
1443 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
1444 | GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls) | ||
1445 | { | ||
1446 | struct Plugin *plugin = cls; | ||
1447 | int ret = GNUNET_SYSERR; | ||
1448 | |||
1449 | sqlite3_stmt *stmt = plugin->select_state_signed; | ||
1450 | |||
1451 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1452 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1453 | { | ||
1454 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1455 | "select_state_signed (bind)"); | ||
1456 | } | ||
1457 | else | ||
1458 | { | ||
1459 | int sql_ret; | ||
1460 | do | ||
1461 | { | ||
1462 | sql_ret = sqlite3_step (stmt); | ||
1463 | switch (sql_ret) | ||
1464 | { | ||
1465 | case SQLITE_DONE: | ||
1466 | if (ret != GNUNET_OK) | ||
1467 | ret = GNUNET_NO; | ||
1468 | break; | ||
1469 | case SQLITE_ROW: | ||
1470 | ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0), | ||
1471 | sqlite3_column_blob (stmt, 1), | ||
1472 | sqlite3_column_bytes (stmt, 1)); | ||
1473 | if (ret != GNUNET_YES) | ||
1474 | sql_ret = SQLITE_DONE; | ||
1475 | break; | ||
1476 | default: | ||
1477 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1478 | "select_state_signed (step)"); | ||
1479 | } | ||
1480 | } | ||
1481 | while (sql_ret == SQLITE_ROW); | ||
1482 | } | ||
1483 | |||
1484 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1485 | { | ||
1486 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1487 | "select_state_signed (reset)"); | ||
1488 | } | ||
1489 | |||
1490 | return ret; | ||
1491 | } | ||
1492 | |||
1493 | |||
1494 | /** | ||
796 | * Entry point for the plugin. | 1495 | * Entry point for the plugin. |
797 | * | 1496 | * |
798 | * @param cls the "struct GNUNET_PSYCSTORE_PluginEnvironment*" | 1497 | * @param cls The struct GNUNET_CONFIGURATION_Handle. |
799 | * @return NULL on error, otherwise the plugin context | 1498 | * @return NULL on error, otherwise the plugin context |
800 | */ | 1499 | */ |
801 | void * | 1500 | void * |
@@ -816,21 +1515,23 @@ libgnunet_plugin_psycstore_sqlite_init (void *cls) | |||
816 | } | 1515 | } |
817 | api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions); | 1516 | api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions); |
818 | api->cls = &plugin; | 1517 | api->cls = &plugin; |
819 | api->membership_store = &libgnunet_plugin_psycstore_sqlite_membership_store; | 1518 | api->membership_store = &membership_store; |
820 | api->membership_test = &libgnunet_plugin_psycstore_sqlite_membership_test; | 1519 | api->membership_test = &membership_test; |
821 | api->fragment_store = &libgnunet_plugin_psycstore_sqlite_fragment_store; | 1520 | api->fragment_store = &fragment_store; |
822 | api->fragment_add_flags = &libgnunet_plugin_psycstore_sqlite_fragment_add_flags; | 1521 | api->message_add_flags = &message_add_flags; |
823 | api->fragment_get = &libgnunet_plugin_psycstore_sqlite_fragment_get; | 1522 | api->fragment_get = &fragment_get; |
824 | api->message_get = &libgnunet_plugin_psycstore_sqlite_message_get; | 1523 | api->message_get = &message_get; |
825 | api->message_get_fragment = &libgnunet_plugin_psycstore_sqlite_message_get_fragment; | 1524 | api->message_get_fragment = &message_get_fragment; |
826 | api->counters_get_master = &libgnunet_plugin_psycstore_sqlite_counters_get_master; | 1525 | api->counters_get_master = &counters_get_master; |
827 | api->counters_get_slave = &libgnunet_plugin_psycstore_sqlite_counters_get_slave; | 1526 | api->counters_get_slave = &counters_get_slave; |
828 | api->state_set = &libgnunet_plugin_psycstore_sqlite_state_set; | 1527 | api->state_set = &state_set; |
829 | api->state_get = &libgnunet_plugin_psycstore_sqlite_state_get; | 1528 | api->state_reset = &state_reset; |
830 | api->state_get_all = &libgnunet_plugin_psycstore_sqlite_state_get_all; | 1529 | api->state_update_signed = &state_update_signed; |
831 | 1530 | api->state_get = &state_get; | |
832 | LOG (GNUNET_ERROR_TYPE_INFO, | 1531 | api->state_get_all = &state_get_all; |
833 | _("Sqlite database running\n")); | 1532 | api->state_get_signed = &state_get_signed; |
1533 | |||
1534 | LOG (GNUNET_ERROR_TYPE_INFO, _("SQLite database running\n")); | ||
834 | return api; | 1535 | return api; |
835 | } | 1536 | } |
836 | 1537 | ||
@@ -838,8 +1539,8 @@ libgnunet_plugin_psycstore_sqlite_init (void *cls) | |||
838 | /** | 1539 | /** |
839 | * Exit point from the plugin. | 1540 | * Exit point from the plugin. |
840 | * | 1541 | * |
841 | * @param cls the plugin context (as returned by "init") | 1542 | * @param cls The plugin context (as returned by "init") |
842 | * @return always NULL | 1543 | * @return Always NULL |
843 | */ | 1544 | */ |
844 | void * | 1545 | void * |
845 | libgnunet_plugin_psycstore_sqlite_done (void *cls) | 1546 | libgnunet_plugin_psycstore_sqlite_done (void *cls) |
@@ -850,8 +1551,7 @@ libgnunet_plugin_psycstore_sqlite_done (void *cls) | |||
850 | database_shutdown (plugin); | 1551 | database_shutdown (plugin); |
851 | plugin->cfg = NULL; | 1552 | plugin->cfg = NULL; |
852 | GNUNET_free (api); | 1553 | GNUNET_free (api); |
853 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1554 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SQLite plugin is finished\n"); |
854 | "sqlite plugin is finished\n"); | ||
855 | return NULL; | 1555 | return NULL; |
856 | } | 1556 | } |
857 | 1557 | ||