aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/plugin_datastore_sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datastore/plugin_datastore_sqlite.c')
-rw-r--r--src/datastore/plugin_datastore_sqlite.c792
1 files changed, 413 insertions, 379 deletions
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index 9ab50714f..76f791ad4 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -1,6 +1,6 @@
1 /* 1 /*
2 * This file is part of GNUnet 2 * This file is part of GNUnet
3 * Copyright (C) 2009, 2011 GNUnet e.V. 3 * Copyright (C) 2009, 2011, 2017 GNUnet e.V.
4 * 4 *
5 * GNUnet is free software; you can redistribute it and/or modify 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 6 * it under the terms of the GNU General Public License as published
@@ -26,6 +26,7 @@
26 26
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_datastore_plugin.h" 28#include "gnunet_datastore_plugin.h"
29#include "gnunet_sq_lib.h"
29#include <sqlite3.h> 30#include <sqlite3.h>
30 31
31 32
@@ -127,6 +128,11 @@ struct Plugin
127 sqlite3_stmt *insertContent; 128 sqlite3_stmt *insertContent;
128 129
129 /** 130 /**
131 * Precompiled SQL for selection
132 */
133 sqlite3_stmt *get;
134
135 /**
130 * Should the database be dropped on shutdown? 136 * Should the database be dropped on shutdown?
131 */ 137 */
132 int drop_on_shutdown; 138 int drop_on_shutdown;
@@ -150,11 +156,17 @@ sq_prepare (sqlite3 *dbh,
150 char *dummy; 156 char *dummy;
151 int result; 157 int result;
152 158
153 result = 159 result = sqlite3_prepare_v2 (dbh,
154 sqlite3_prepare_v2 (dbh, zSql, strlen (zSql), ppStmt, 160 zSql,
155 (const char **) &dummy); 161 strlen (zSql),
156 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", 162 ppStmt,
157 "Prepared `%s' / %p: %d\n", zSql, *ppStmt, result); 163 (const char **) &dummy);
164 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
165 "sqlite",
166 "Prepared `%s' / %p: %d\n",
167 zSql,
168 *ppStmt,
169 result);
158 return result; 170 return result;
159} 171}
160 172
@@ -310,80 +322,110 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
310 * we do math or inequality tests, so we can't handle the entire range of uint32_t. 322 * we do math or inequality tests, so we can't handle the entire range of uint32_t.
311 * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC. 323 * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC.
312 */ 324 */
313 if ((sqlite3_step (stmt) == SQLITE_DONE) && 325 if ( (SQLITE_DONE ==
314 (sqlite3_exec 326 sqlite3_step (stmt)) &&
315 (plugin->dbh, 327 (SQLITE_OK !=
316 "CREATE TABLE gn090 (" " repl INT4 NOT NULL DEFAULT 0," 328 sqlite3_exec (plugin->dbh,
317 " type INT4 NOT NULL DEFAULT 0," " prio INT4 NOT NULL DEFAULT 0," 329 "CREATE TABLE gn090 ("
318 " anonLevel INT4 NOT NULL DEFAULT 0," 330 " repl INT4 NOT NULL DEFAULT 0,"
319 " expire INT8 NOT NULL DEFAULT 0," " rvalue INT8 NOT NULL," 331 " type INT4 NOT NULL DEFAULT 0,"
320 " hash TEXT NOT NULL DEFAULT ''," " vhash TEXT NOT NULL DEFAULT ''," 332 " prio INT4 NOT NULL DEFAULT 0,"
321 " value BLOB NOT NULL DEFAULT '')", NULL, NULL, NULL) != SQLITE_OK)) 333 " anonLevel INT4 NOT NULL DEFAULT 0,"
334 " expire INT8 NOT NULL DEFAULT 0,"
335 " rvalue INT8 NOT NULL,"
336 " hash TEXT NOT NULL DEFAULT '',"
337 " vhash TEXT NOT NULL DEFAULT '',"
338 " value BLOB NOT NULL DEFAULT '')",
339 NULL,
340 NULL,
341 NULL)) )
322 { 342 {
323 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec"); 343 LOG_SQLITE (plugin,
344 GNUNET_ERROR_TYPE_ERROR,
345 "sqlite3_exec");
324 sqlite3_finalize (stmt); 346 sqlite3_finalize (stmt);
325 return GNUNET_SYSERR; 347 return GNUNET_SYSERR;
326 } 348 }
327 sqlite3_finalize (stmt); 349 sqlite3_finalize (stmt);
328 create_indices (plugin->dbh); 350 create_indices (plugin->dbh);
329 351
330 if ((sq_prepare 352 if ( (SQLITE_OK !=
331 (plugin->dbh, 353 sq_prepare (plugin->dbh,
332 "UPDATE gn090 " 354 "UPDATE gn090 "
333 "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?", 355 "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?",
334 &plugin->updPrio) != SQLITE_OK) || 356 &plugin->updPrio)) ||
335 (sq_prepare 357 (SQLITE_OK !=
336 (plugin->dbh, 358 sq_prepare (plugin->dbh,
337 "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?", 359 "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?",
338 &plugin->updRepl) != SQLITE_OK) || 360 &plugin->updRepl)) ||
339 (sq_prepare 361 (SQLITE_OK !=
340 (plugin->dbh, 362 sq_prepare (plugin->dbh,
341 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 363 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
342#if SQLITE_VERSION_NUMBER >= 3007000 364#if SQLITE_VERSION_NUMBER >= 3007000
343 "INDEXED BY idx_repl_rvalue " 365 "INDEXED BY idx_repl_rvalue "
344#endif 366#endif
345 "WHERE repl=?2 AND " " (rvalue>=?1 OR " 367 "WHERE repl=?2 AND " " (rvalue>=?1 OR "
346 " NOT EXISTS (SELECT 1 FROM gn090 " 368 " NOT EXISTS (SELECT 1 FROM gn090 "
347#if SQLITE_VERSION_NUMBER >= 3007000 369#if SQLITE_VERSION_NUMBER >= 3007000
348 "INDEXED BY idx_repl_rvalue " 370 "INDEXED BY idx_repl_rvalue "
349#endif 371#endif
350 "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) " 372 "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) "
351 "ORDER BY rvalue ASC LIMIT 1", &plugin->selRepl) != SQLITE_OK) || 373 "ORDER BY rvalue ASC LIMIT 1",
352 (sq_prepare (plugin->dbh, "SELECT MAX(repl) FROM gn090" 374 &plugin->selRepl)) ||
375 (SQLITE_OK !=
376 sq_prepare (plugin->dbh,
377 "SELECT MAX(repl) FROM gn090"
353#if SQLITE_VERSION_NUMBER >= 3007000 378#if SQLITE_VERSION_NUMBER >= 3007000
354 " INDEXED BY idx_repl_rvalue" 379 " INDEXED BY idx_repl_rvalue"
355#endif 380#endif
356 "", &plugin->maxRepl) != SQLITE_OK) || 381 "",
357 (sq_prepare 382 &plugin->maxRepl)) ||
358 (plugin->dbh, 383 (SQLITE_OK !=
359 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 384 sq_prepare (plugin->dbh,
385 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
360#if SQLITE_VERSION_NUMBER >= 3007000 386#if SQLITE_VERSION_NUMBER >= 3007000
361 "INDEXED BY idx_expire " 387 "INDEXED BY idx_expire "
362#endif 388#endif
363 "WHERE NOT EXISTS (SELECT 1 FROM gn090 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) " 389 "WHERE NOT EXISTS (SELECT 1 FROM gn090 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) "
364 "ORDER BY expire ASC LIMIT 1", &plugin->selExpi) != SQLITE_OK) || 390 "ORDER BY expire ASC LIMIT 1",
365 (sq_prepare 391 &plugin->selExpi)) ||
366 (plugin->dbh, 392 (SQLITE_OK !=
367 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 393 sq_prepare (plugin->dbh,
394 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
368#if SQLITE_VERSION_NUMBER >= 3007000 395#if SQLITE_VERSION_NUMBER >= 3007000
369 "INDEXED BY idx_anon_type_hash " 396 "INDEXED BY idx_anon_type_hash "
370#endif 397#endif
371 "WHERE (anonLevel = 0 AND type=?1) " 398 "WHERE _ROWID_ >= ? AND "
372 "ORDER BY hash DESC LIMIT 1 OFFSET ?2", 399 "anonLevel = 0 AND "
373 &plugin->selZeroAnon) != SQLITE_OK) || 400 "type = ? "
374 (sq_prepare 401 "ORDER BY _ROWID_ ASC LIMIT 1",
375 (plugin->dbh, 402 &plugin->selZeroAnon)) ||
376 "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) " 403 (SQLITE_OK !=
377 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", 404 sq_prepare (plugin->dbh,
378 &plugin->insertContent) != SQLITE_OK) || 405 "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
379 (sq_prepare 406 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
380 (plugin->dbh, "DELETE FROM gn090 WHERE _ROWID_ = ?", 407 &plugin->insertContent)) ||
381 &plugin->delRow) != SQLITE_OK)) 408 (SQLITE_OK !=
409 sq_prepare (plugin->dbh,
410 "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ FROM gn090 "
411 "WHERE _ROWID_ >= ? AND "
412 "(rvalue >= ? OR 0 = ?) AND "
413 "(hash = ? OR 0 = ?) AND "
414 "(vhash = ? OR 0 = ?) AND "
415 "(type = ? OR 0 = ?) "
416 "ORDER BY _ROWID_ ASC LIMIT 1",
417 &plugin->get)) ||
418 (SQLITE_OK !=
419 sq_prepare (plugin->dbh,
420 "DELETE FROM gn090 WHERE _ROWID_ = ?",
421 &plugin->delRow))
422 )
382 { 423 {
383 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "precompiling"); 424 LOG_SQLITE (plugin,
425 GNUNET_ERROR_TYPE_ERROR,
426 "precompiling");
384 return GNUNET_SYSERR; 427 return GNUNET_SYSERR;
385 } 428 }
386
387 return GNUNET_OK; 429 return GNUNET_OK;
388} 430}
389 431
@@ -398,51 +440,60 @@ static void
398database_shutdown (struct Plugin *plugin) 440database_shutdown (struct Plugin *plugin)
399{ 441{
400 int result; 442 int result;
401
402#if SQLITE_VERSION_NUMBER >= 3007000 443#if SQLITE_VERSION_NUMBER >= 3007000
403 sqlite3_stmt *stmt; 444 sqlite3_stmt *stmt;
404#endif 445#endif
405 446
406 if (plugin->delRow != NULL) 447 if (NULL != plugin->delRow)
407 sqlite3_finalize (plugin->delRow); 448 sqlite3_finalize (plugin->delRow);
408 if (plugin->updPrio != NULL) 449 if (NULL != plugin->updPrio)
409 sqlite3_finalize (plugin->updPrio); 450 sqlite3_finalize (plugin->updPrio);
410 if (plugin->updRepl != NULL) 451 if (NULL != plugin->updRepl)
411 sqlite3_finalize (plugin->updRepl); 452 sqlite3_finalize (plugin->updRepl);
412 if (plugin->selRepl != NULL) 453 if (NULL != plugin->selRepl)
413 sqlite3_finalize (plugin->selRepl); 454 sqlite3_finalize (plugin->selRepl);
414 if (plugin->maxRepl != NULL) 455 if (NULL != plugin->maxRepl)
415 sqlite3_finalize (plugin->maxRepl); 456 sqlite3_finalize (plugin->maxRepl);
416 if (plugin->selExpi != NULL) 457 if (NULL != plugin->selExpi)
417 sqlite3_finalize (plugin->selExpi); 458 sqlite3_finalize (plugin->selExpi);
418 if (plugin->selZeroAnon != NULL) 459 if (NULL != plugin->selZeroAnon)
419 sqlite3_finalize (plugin->selZeroAnon); 460 sqlite3_finalize (plugin->selZeroAnon);
420 if (plugin->insertContent != NULL) 461 if (NULL != plugin->insertContent)
421 sqlite3_finalize (plugin->insertContent); 462 sqlite3_finalize (plugin->insertContent);
463 if (NULL != plugin->get)
464 sqlite3_finalize (plugin->get);
422 result = sqlite3_close (plugin->dbh); 465 result = sqlite3_close (plugin->dbh);
423#if SQLITE_VERSION_NUMBER >= 3007000 466#if SQLITE_VERSION_NUMBER >= 3007000
424 if (result == SQLITE_BUSY) 467 if (result == SQLITE_BUSY)
425 { 468 {
426 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite", 469 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
427 _ 470 "sqlite",
428 ("Tried to close sqlite without finalizing all prepared statements.\n")); 471 _("Tried to close sqlite without finalizing all prepared statements.\n"));
429 stmt = sqlite3_next_stmt (plugin->dbh, NULL); 472 stmt = sqlite3_next_stmt (plugin->dbh,
430 while (stmt != NULL) 473 NULL);
474 while (NULL != stmt)
431 { 475 {
432 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", 476 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
433 "Closing statement %p\n", stmt); 477 "sqlite",
478 "Closing statement %p\n",
479 stmt);
434 result = sqlite3_finalize (stmt); 480 result = sqlite3_finalize (stmt);
435 if (result != SQLITE_OK) 481 if (result != SQLITE_OK)
436 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite", 482 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
437 "Failed to close statement %p: %d\n", stmt, result); 483 "sqlite",
438 stmt = sqlite3_next_stmt (plugin->dbh, NULL); 484 "Failed to close statement %p: %d\n",
485 stmt,
486 result);
487 stmt = sqlite3_next_stmt (plugin->dbh,
488 NULL);
439 } 489 }
440 result = sqlite3_close (plugin->dbh); 490 result = sqlite3_close (plugin->dbh);
441 } 491 }
442#endif 492#endif
443 if (SQLITE_OK != result) 493 if (SQLITE_OK != result)
444 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close"); 494 LOG_SQLITE (plugin,
445 495 GNUNET_ERROR_TYPE_ERROR,
496 "sqlite3_close");
446 GNUNET_free_non_null (plugin->fn); 497 GNUNET_free_non_null (plugin->fn);
447} 498}
448 499
@@ -456,31 +507,27 @@ database_shutdown (struct Plugin *plugin)
456 */ 507 */
457static int 508static int
458delete_by_rowid (struct Plugin *plugin, 509delete_by_rowid (struct Plugin *plugin,
459 unsigned long long rid) 510 uint64_t rid)
460{ 511{
461 if (SQLITE_OK != sqlite3_bind_int64 (plugin->delRow, 1, rid)) 512 struct GNUNET_SQ_QueryParam params[] = {
462 { 513 GNUNET_SQ_query_param_uint64 (&rid),
463 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 514 GNUNET_SQ_query_param_end
464 "sqlite3_bind_XXXX"); 515 };
465 if (SQLITE_OK != sqlite3_reset (plugin->delRow)) 516
466 LOG_SQLITE (plugin, 517 if (GNUNET_OK !=
467 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 518 GNUNET_SQ_bind (plugin->delRow,
468 "sqlite3_reset"); 519 params))
469 return GNUNET_SYSERR; 520 return GNUNET_SYSERR;
470 }
471 if (SQLITE_DONE != sqlite3_step (plugin->delRow)) 521 if (SQLITE_DONE != sqlite3_step (plugin->delRow))
472 { 522 {
473 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 523 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
474 "sqlite3_step"); 524 "sqlite3_step");
475 if (SQLITE_OK != sqlite3_reset (plugin->delRow)) 525 GNUNET_SQ_reset (plugin->dbh,
476 LOG_SQLITE (plugin, 526 plugin->delRow);
477 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
478 "sqlite3_reset");
479 return GNUNET_SYSERR; 527 return GNUNET_SYSERR;
480 } 528 }
481 if (SQLITE_OK != sqlite3_reset (plugin->delRow)) 529 GNUNET_SQ_reset (plugin->dbh,
482 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 530 plugin->delRow);
483 "sqlite3_reset");
484 return GNUNET_OK; 531 return GNUNET_OK;
485} 532}
486 533
@@ -513,12 +560,25 @@ sqlite_plugin_put (void *cls,
513 PluginPutCont cont, 560 PluginPutCont cont,
514 void *cont_cls) 561 void *cont_cls)
515{ 562{
563 uint64_t rvalue;
564 struct GNUNET_HashCode vhash;
565 uint32_t type32 = (uint32_t) type;
566 struct GNUNET_SQ_QueryParam params[] = {
567 GNUNET_SQ_query_param_uint32 (&replication),
568 GNUNET_SQ_query_param_uint32 (&type32),
569 GNUNET_SQ_query_param_uint32 (&priority),
570 GNUNET_SQ_query_param_uint32 (&anonymity),
571 GNUNET_SQ_query_param_absolute_time (&expiration),
572 GNUNET_SQ_query_param_uint64 (&rvalue),
573 GNUNET_SQ_query_param_auto_from_type (key),
574 GNUNET_SQ_query_param_auto_from_type (&vhash),
575 GNUNET_SQ_query_param_fixed_size (data, size),
576 GNUNET_SQ_query_param_end
577 };
516 struct Plugin *plugin = cls; 578 struct Plugin *plugin = cls;
517 int n; 579 int n;
518 int ret; 580 int ret;
519 sqlite3_stmt *stmt; 581 sqlite3_stmt *stmt;
520 struct GNUNET_HashCode vhash;
521 uint64_t rvalue;
522 char *msg = NULL; 582 char *msg = NULL;
523 583
524 if (size > MAX_ITEM_SIZE) 584 if (size > MAX_ITEM_SIZE)
@@ -537,26 +597,10 @@ sqlite_plugin_put (void *cls,
537 GNUNET_CRYPTO_hash (data, size, &vhash); 597 GNUNET_CRYPTO_hash (data, size, &vhash);
538 stmt = plugin->insertContent; 598 stmt = plugin->insertContent;
539 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); 599 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
540 if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, replication)) || 600 if (GNUNET_OK !=
541 (SQLITE_OK != sqlite3_bind_int (stmt, 2, type)) || 601 GNUNET_SQ_bind (stmt,
542 (SQLITE_OK != sqlite3_bind_int (stmt, 3, priority)) || 602 params))
543 (SQLITE_OK != sqlite3_bind_int (stmt, 4, anonymity)) ||
544 (SQLITE_OK != sqlite3_bind_int64 (stmt, 5, expiration.abs_value_us)) ||
545 (SQLITE_OK != sqlite3_bind_int64 (stmt, 6, rvalue)) ||
546 (SQLITE_OK !=
547 sqlite3_bind_blob (stmt, 7, key, sizeof (struct GNUNET_HashCode),
548 SQLITE_TRANSIENT)) ||
549 (SQLITE_OK !=
550 sqlite3_bind_blob (stmt, 8, &vhash, sizeof (struct GNUNET_HashCode),
551 SQLITE_TRANSIENT)) ||
552 (SQLITE_OK != sqlite3_bind_blob (stmt, 9, data, size, SQLITE_TRANSIENT)))
553 { 603 {
554 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
555 "sqlite3_bind_XXXX");
556 if (SQLITE_OK != sqlite3_reset (stmt))
557 LOG_SQLITE (plugin,
558 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
559 "sqlite3_reset");
560 cont (cont_cls, key, size, GNUNET_SYSERR, msg); 604 cont (cont_cls, key, size, GNUNET_SYSERR, msg);
561 GNUNET_free_non_null(msg); 605 GNUNET_free_non_null(msg);
562 return; 606 return;
@@ -582,19 +626,16 @@ sqlite_plugin_put (void *cls,
582 default: 626 default:
583 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 627 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
584 "sqlite3_step"); 628 "sqlite3_step");
585 if (SQLITE_OK != sqlite3_reset (stmt)) 629 GNUNET_SQ_reset (plugin->dbh,
586 LOG_SQLITE (plugin, 630 stmt);
587 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
588 "sqlite3_reset");
589 database_shutdown (plugin); 631 database_shutdown (plugin);
590 database_setup (plugin->env->cfg, plugin); 632 database_setup (plugin->env->cfg, plugin);
591 cont (cont_cls, key, size, GNUNET_SYSERR, msg); 633 cont (cont_cls, key, size, GNUNET_SYSERR, msg);
592 GNUNET_free_non_null(msg); 634 GNUNET_free_non_null(msg);
593 return; 635 return;
594 } 636 }
595 if (SQLITE_OK != sqlite3_reset (stmt)) 637 GNUNET_SQ_reset (plugin->dbh,
596 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 638 stmt);
597 "sqlite3_reset");
598 cont (cont_cls, key, size, ret, msg); 639 cont (cont_cls, key, size, ret, msg);
599 GNUNET_free_non_null(msg); 640 GNUNET_free_non_null(msg);
600} 641}
@@ -619,7 +660,7 @@ sqlite_plugin_put (void *cls,
619 * MAX of any existing expiration time and 660 * MAX of any existing expiration time and
620 * this value 661 * this value
621 * @param cont continuation called with success or failure status 662 * @param cont continuation called with success or failure status
622 * @param cons_cls continuation closure 663 * @param cons_cls closure for @a cont
623 */ 664 */
624static void 665static void
625sqlite_plugin_update (void *cls, 666sqlite_plugin_update (void *cls,
@@ -630,27 +671,26 @@ sqlite_plugin_update (void *cls,
630 void *cont_cls) 671 void *cont_cls)
631{ 672{
632 struct Plugin *plugin = cls; 673 struct Plugin *plugin = cls;
674 struct GNUNET_SQ_QueryParam params[] = {
675 GNUNET_SQ_query_param_uint32 (&delta),
676 GNUNET_SQ_query_param_absolute_time (&expire),
677 GNUNET_SQ_query_param_uint64 (&uid),
678 GNUNET_SQ_query_param_end
679 };
633 int n; 680 int n;
634 char *msg = NULL; 681 char *msg = NULL;
635 682
636 if ((SQLITE_OK != sqlite3_bind_int (plugin->updPrio, 1, delta)) || 683 if (GNUNET_OK !=
637 (SQLITE_OK != sqlite3_bind_int64 (plugin->updPrio, 2, expire.abs_value_us)) 684 GNUNET_SQ_bind (plugin->updPrio,
638 || (SQLITE_OK != sqlite3_bind_int64 (plugin->updPrio, 3, uid))) 685 params))
639 { 686 {
640 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
641 "sqlite3_bind_XXXX");
642 if (SQLITE_OK != sqlite3_reset (plugin->updPrio))
643 LOG_SQLITE (plugin,
644 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
645 "sqlite3_reset");
646 cont (cont_cls, GNUNET_SYSERR, msg); 687 cont (cont_cls, GNUNET_SYSERR, msg);
647 GNUNET_free_non_null(msg); 688 GNUNET_free_non_null(msg);
648 return; 689 return;
649 } 690 }
650 n = sqlite3_step (plugin->updPrio); 691 n = sqlite3_step (plugin->updPrio);
651 if (SQLITE_OK != sqlite3_reset (plugin->updPrio)) 692 GNUNET_SQ_reset (plugin->dbh,
652 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 693 plugin->updPrio);
653 "sqlite3_reset");
654 switch (n) 694 switch (n)
655 { 695 {
656 case SQLITE_DONE: 696 case SQLITE_DONE:
@@ -691,75 +731,84 @@ execute_get (struct Plugin *plugin,
691{ 731{
692 int n; 732 int n;
693 struct GNUNET_TIME_Absolute expiration; 733 struct GNUNET_TIME_Absolute expiration;
694 unsigned long long rowid; 734 uint32_t type;
695 unsigned int size; 735 uint32_t priority;
736 uint32_t anonymity;
737 uint64_t rowid;
738 void *value;
739 size_t value_size;
740 struct GNUNET_HashCode key;
696 int ret; 741 int ret;
742 struct GNUNET_SQ_ResultSpec rs[] = {
743 GNUNET_SQ_result_spec_uint32 (&type),
744 GNUNET_SQ_result_spec_uint32 (&priority),
745 GNUNET_SQ_result_spec_uint32 (&anonymity),
746 GNUNET_SQ_result_spec_absolute_time (&expiration),
747 GNUNET_SQ_result_spec_auto_from_type (&key),
748 GNUNET_SQ_result_spec_variable_size (&value,
749 &value_size),
750 GNUNET_SQ_result_spec_uint64 (&rowid),
751 GNUNET_SQ_result_spec_end
752 };
697 753
698 n = sqlite3_step (stmt); 754 n = sqlite3_step (stmt);
699 switch (n) 755 switch (n)
700 { 756 {
701 case SQLITE_ROW: 757 case SQLITE_ROW:
702 size = sqlite3_column_bytes (stmt, 5); 758 if (GNUNET_OK !=
703 rowid = sqlite3_column_int64 (stmt, 6); 759 GNUNET_SQ_extract_result (stmt,
704 if (sqlite3_column_bytes (stmt, 4) != sizeof (struct GNUNET_HashCode)) 760 rs))
705 { 761 {
706 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite", 762 GNUNET_break (0);
707 _("Invalid data in database. Trying to fix (by deletion).\n"));
708 if (SQLITE_OK != sqlite3_reset (stmt))
709 LOG_SQLITE (plugin,
710 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
711 "sqlite3_reset");
712 if ( (GNUNET_OK == delete_by_rowid (plugin, rowid)) &&
713 (NULL != plugin->env->duc) )
714 plugin->env->duc (plugin->env->cls,
715 -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
716 break; 763 break;
717 } 764 }
718 expiration.abs_value_us = sqlite3_column_int64 (stmt, 3); 765 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
719 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", 766 "sqlite",
720 "Found reply in database with expiration %s\n", 767 "Found reply in database with expiration %s\n",
721 GNUNET_STRINGS_absolute_time_to_string (expiration)); 768 GNUNET_STRINGS_absolute_time_to_string (expiration));
722 ret = proc (proc_cls, sqlite3_column_blob (stmt, 4) /* key */ , 769 ret = proc (proc_cls,
723 size, sqlite3_column_blob (stmt, 5) /* data */ , 770 &key,
724 sqlite3_column_int (stmt, 0) /* type */ , 771 value_size,
725 sqlite3_column_int (stmt, 1) /* priority */ , 772 value,
726 sqlite3_column_int (stmt, 2) /* anonymity */ , 773 type,
727 expiration, rowid); 774 priority,
728 if (SQLITE_OK != sqlite3_reset (stmt)) 775 anonymity,
729 LOG_SQLITE (plugin, 776 expiration,
730 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 777 rowid);
731 "sqlite3_reset"); 778 GNUNET_SQ_cleanup_result (rs);
779 GNUNET_SQ_reset (plugin->dbh,
780 stmt);
732 if ( (GNUNET_NO == ret) && 781 if ( (GNUNET_NO == ret) &&
733 (GNUNET_OK == delete_by_rowid (plugin, rowid)) && 782 (GNUNET_OK == delete_by_rowid (plugin,
783 rowid)) &&
734 (NULL != plugin->env->duc) ) 784 (NULL != plugin->env->duc) )
735 plugin->env->duc (plugin->env->cls, 785 plugin->env->duc (plugin->env->cls,
736 -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); 786 -(value_size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
737 return; 787 return;
738 case SQLITE_DONE: 788 case SQLITE_DONE:
739 /* database must be empty */ 789 /* database must be empty */
740 if (SQLITE_OK != sqlite3_reset (stmt))
741 LOG_SQLITE (plugin,
742 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
743 "sqlite3_reset");
744 break; 790 break;
745 case SQLITE_BUSY: 791 case SQLITE_BUSY:
746 case SQLITE_ERROR: 792 case SQLITE_ERROR:
747 case SQLITE_MISUSE: 793 case SQLITE_MISUSE:
748 default: 794 default:
749 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 795 LOG_SQLITE (plugin,
796 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
750 "sqlite3_step"); 797 "sqlite3_step");
751 if (SQLITE_OK != sqlite3_reset (stmt)) 798 if (SQLITE_OK !=
799 sqlite3_reset (stmt))
752 LOG_SQLITE (plugin, 800 LOG_SQLITE (plugin,
753 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 801 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
754 "sqlite3_reset"); 802 "sqlite3_reset");
755 GNUNET_break (0); 803 GNUNET_break (0);
804 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
756 database_shutdown (plugin); 805 database_shutdown (plugin);
757 database_setup (plugin->env->cfg, plugin); 806 database_setup (plugin->env->cfg,
758 break; 807 plugin);
808 return;
759 } 809 }
760 if (SQLITE_OK != sqlite3_reset (stmt)) 810 GNUNET_SQ_reset (plugin->dbh,
761 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 811 stmt);
762 "sqlite3_reset");
763 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 812 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
764} 813}
765 814
@@ -769,37 +818,36 @@ execute_get (struct Plugin *plugin,
769 * the given processor for the item. 818 * the given processor for the item.
770 * 819 *
771 * @param cls our plugin context 820 * @param cls our plugin context
772 * @param offset offset of the result (modulo num-results); 821 * @param next_uid return the result with lowest uid >= next_uid
773 * specific ordering does not matter for the offset
774 * @param type entries of which type should be considered? 822 * @param type entries of which type should be considered?
775 * Use 0 for any type. 823 * Must not be zero (ANY).
776 * @param proc function to call on each matching value; 824 * @param proc function to call on the matching value;
777 * will be called once with a NULL value at the end 825 * will be called with NULL if no value matches
778 * @param proc_cls closure for @a proc 826 * @param proc_cls closure for @a proc
779 */ 827 */
780static void 828static void
781sqlite_plugin_get_zero_anonymity (void *cls, uint64_t offset, 829sqlite_plugin_get_zero_anonymity (void *cls,
830 uint64_t next_uid,
782 enum GNUNET_BLOCK_Type type, 831 enum GNUNET_BLOCK_Type type,
783 PluginDatumProcessor proc, void *proc_cls) 832 PluginDatumProcessor proc,
833 void *proc_cls)
784{ 834{
785 struct Plugin *plugin = cls; 835 struct Plugin *plugin = cls;
786 sqlite3_stmt *stmt; 836 struct GNUNET_SQ_QueryParam params[] = {
837 GNUNET_SQ_query_param_uint64 (&next_uid),
838 GNUNET_SQ_query_param_uint32 (&type),
839 GNUNET_SQ_query_param_end
840 };
787 841
788 GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY); 842 GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY);
789 stmt = plugin->selZeroAnon; 843 if (GNUNET_OK !=
790 if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) || 844 GNUNET_SQ_bind (plugin->selZeroAnon,
791 (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, offset))) 845 params))
792 { 846 {
793 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
794 "sqlite3_bind_XXXX");
795 if (SQLITE_OK != sqlite3_reset (stmt))
796 LOG_SQLITE (plugin,
797 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
798 "sqlite3_reset");
799 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 847 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
800 return; 848 return;
801 } 849 }
802 execute_get (plugin, stmt, proc, proc_cls); 850 execute_get (plugin, plugin->selZeroAnon, proc, proc_cls);
803} 851}
804 852
805 853
@@ -807,8 +855,9 @@ sqlite_plugin_get_zero_anonymity (void *cls, uint64_t offset,
807 * Get results for a particular key in the datastore. 855 * Get results for a particular key in the datastore.
808 * 856 *
809 * @param cls closure 857 * @param cls closure
810 * @param offset offset (mod count). 858 * @param next_uid return the result with lowest uid >= next_uid
811 * @param key key to match, never NULL 859 * @param random if true, return a random result instead of using next_uid
860 * @param key maybe NULL (to match all entries)
812 * @param vhash hash of the value, maybe NULL (to 861 * @param vhash hash of the value, maybe NULL (to
813 * match all values that have the right key). 862 * match all values that have the right key).
814 * Note that for DBlocks there is no difference 863 * Note that for DBlocks there is no difference
@@ -822,7 +871,8 @@ sqlite_plugin_get_zero_anonymity (void *cls, uint64_t offset,
822 */ 871 */
823static void 872static void
824sqlite_plugin_get_key (void *cls, 873sqlite_plugin_get_key (void *cls,
825 uint64_t offset, 874 uint64_t next_uid,
875 bool random,
826 const struct GNUNET_HashCode *key, 876 const struct GNUNET_HashCode *key,
827 const struct GNUNET_HashCode *vhash, 877 const struct GNUNET_HashCode *vhash,
828 enum GNUNET_BLOCK_Type type, 878 enum GNUNET_BLOCK_Type type,
@@ -830,97 +880,45 @@ sqlite_plugin_get_key (void *cls,
830 void *proc_cls) 880 void *proc_cls)
831{ 881{
832 struct Plugin *plugin = cls; 882 struct Plugin *plugin = cls;
833 int ret; 883 uint64_t rvalue;
834 int total; 884 uint16_t use_rvalue = random;
835 int limit_off; 885 uint32_t type32 = (uint32_t) type;
836 unsigned int sqoff; 886 uint16_t use_type = GNUNET_BLOCK_TYPE_ANY != type;
837 sqlite3_stmt *stmt; 887 uint16_t use_key = NULL != key;
838 char scratch[256]; 888 uint16_t use_vhash = NULL != vhash;
839 889 struct GNUNET_SQ_QueryParam params[] = {
840 GNUNET_assert (proc != NULL); 890 GNUNET_SQ_query_param_uint64 (&next_uid),
841 GNUNET_assert (key != NULL); 891 GNUNET_SQ_query_param_uint64 (&rvalue),
842 GNUNET_snprintf (scratch, sizeof (scratch), 892 GNUNET_SQ_query_param_uint16 (&use_rvalue),
843 "SELECT count(*) FROM gn090 WHERE hash=?%s%s", 893 GNUNET_SQ_query_param_auto_from_type (key),
844 vhash == NULL ? "" : " AND vhash=?", 894 GNUNET_SQ_query_param_uint16 (&use_key),
845 type == 0 ? "" : " AND type=?"); 895 GNUNET_SQ_query_param_auto_from_type (vhash),
846 if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK) 896 GNUNET_SQ_query_param_uint16 (&use_vhash),
847 { 897 GNUNET_SQ_query_param_uint32 (&type32),
848 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 898 GNUNET_SQ_query_param_uint16 (&use_type),
849 "sqlite_prepare"); 899 GNUNET_SQ_query_param_end
850 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 900 };
851 return; 901
852 } 902 if (random)
853 sqoff = 1;
854 ret =
855 sqlite3_bind_blob (stmt, sqoff++, key, sizeof (struct GNUNET_HashCode),
856 SQLITE_TRANSIENT);
857 if ((vhash != NULL) && (ret == SQLITE_OK))
858 ret =
859 sqlite3_bind_blob (stmt, sqoff++, vhash, sizeof (struct GNUNET_HashCode),
860 SQLITE_TRANSIENT);
861 if ((type != 0) && (ret == SQLITE_OK))
862 ret = sqlite3_bind_int (stmt, sqoff++, type);
863 if (SQLITE_OK != ret)
864 {
865 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_bind");
866 sqlite3_finalize (stmt);
867 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
868 return;
869 }
870 ret = sqlite3_step (stmt);
871 if (ret != SQLITE_ROW)
872 {
873 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
874 "sqlite_step");
875 sqlite3_finalize (stmt);
876 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
877 return;
878 }
879 total = sqlite3_column_int (stmt, 0);
880 sqlite3_finalize (stmt);
881 if (0 == total)
882 {
883 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
884 return;
885 }
886 limit_off = (int) (offset % total);
887 if (limit_off < 0)
888 limit_off += total;
889 GNUNET_snprintf (scratch, sizeof (scratch),
890 "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ "
891 "FROM gn090 WHERE hash=?%s%s "
892 "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET ?",
893 vhash == NULL ? "" : " AND vhash=?",
894 type == 0 ? "" : " AND type=?");
895 if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
896 { 903 {
897 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 904 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
898 "sqlite_prepare"); 905 UINT64_MAX);
899 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 906 next_uid = 0;
900 return;
901 } 907 }
902 sqoff = 1; 908 else
903 ret = sqlite3_bind_blob (stmt, sqoff++, key, 909 rvalue = 0;
904 sizeof (struct GNUNET_HashCode), 910
905 SQLITE_TRANSIENT); 911 if (GNUNET_OK !=
906 if ((vhash != NULL) && (ret == SQLITE_OK)) 912 GNUNET_SQ_bind (plugin->get,
907 ret = sqlite3_bind_blob (stmt, sqoff++, vhash, 913 params))
908 sizeof (struct GNUNET_HashCode),
909 SQLITE_TRANSIENT);
910 if ((type != 0) && (ret == SQLITE_OK))
911 ret = sqlite3_bind_int (stmt, sqoff++, type);
912 if (ret == SQLITE_OK)
913 ret = sqlite3_bind_int64 (stmt, sqoff++, limit_off);
914 if (ret != SQLITE_OK)
915 { 914 {
916 LOG_SQLITE (plugin,
917 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
918 "sqlite_bind");
919 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 915 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
920 return; 916 return;
921 } 917 }
922 execute_get (plugin, stmt, proc, proc_cls); 918 execute_get (plugin,
923 sqlite3_finalize (stmt); 919 plugin->get,
920 proc,
921 proc_cls);
924} 922}
925 923
926 924
@@ -984,13 +982,17 @@ repl_proc (void *cls,
984 struct ReplCtx *rc = cls; 982 struct ReplCtx *rc = cls;
985 int ret; 983 int ret;
986 984
985 if (GNUNET_SYSERR == rc->have_uid)
986 rc->have_uid = GNUNET_NO;
987 ret = rc->proc (rc->proc_cls, 987 ret = rc->proc (rc->proc_cls,
988 key, 988 key,
989 size, data, 989 size,
990 data,
990 type, 991 type,
991 priority, 992 priority,
992 anonymity, 993 anonymity,
993 expiration, uid); 994 expiration,
995 uid);
994 if (NULL != key) 996 if (NULL != key)
995 { 997 {
996 rc->uid = uid; 998 rc->uid = uid;
@@ -1011,81 +1013,77 @@ repl_proc (void *cls,
1011 * @param proc_cls closure for @a proc 1013 * @param proc_cls closure for @a proc
1012 */ 1014 */
1013static void 1015static void
1014sqlite_plugin_get_replication (void *cls, PluginDatumProcessor proc, 1016sqlite_plugin_get_replication (void *cls,
1017 PluginDatumProcessor proc,
1015 void *proc_cls) 1018 void *proc_cls)
1016{ 1019{
1017 struct Plugin *plugin = cls; 1020 struct Plugin *plugin = cls;
1018 struct ReplCtx rc; 1021 struct ReplCtx rc;
1019 uint64_t rvalue; 1022 uint64_t rvalue;
1020 uint32_t repl; 1023 uint32_t repl;
1021 sqlite3_stmt *stmt; 1024 struct GNUNET_SQ_QueryParam params_sel_repl[] = {
1022 1025 GNUNET_SQ_query_param_uint64 (&rvalue),
1023 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", 1026 GNUNET_SQ_query_param_uint32 (&repl),
1027 GNUNET_SQ_query_param_end
1028 };
1029 struct GNUNET_SQ_QueryParam params_upd_repl[] = {
1030 GNUNET_SQ_query_param_uint64 (&rc.uid),
1031 GNUNET_SQ_query_param_end
1032 };
1033
1034 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1035 "datastore-sqlite",
1024 "Getting random block based on replication order.\n"); 1036 "Getting random block based on replication order.\n");
1025 rc.have_uid = GNUNET_NO; 1037 if (SQLITE_ROW !=
1026 rc.proc = proc; 1038 sqlite3_step (plugin->maxRepl))
1027 rc.proc_cls = proc_cls;
1028 stmt = plugin->maxRepl;
1029 if (SQLITE_ROW != sqlite3_step (stmt))
1030 { 1039 {
1031 if (SQLITE_OK != sqlite3_reset (stmt)) 1040 GNUNET_SQ_reset (plugin->dbh,
1032 LOG_SQLITE (plugin, 1041 plugin->maxRepl);
1033 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1034 "sqlite3_reset");
1035 /* DB empty */ 1042 /* DB empty */
1036 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1043 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1037 return; 1044 return;
1038 } 1045 }
1039 repl = sqlite3_column_int (stmt, 0); 1046 repl = sqlite3_column_int (plugin->maxRepl,
1040 if (SQLITE_OK != sqlite3_reset (stmt)) 1047 0);
1041 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1048 GNUNET_SQ_reset (plugin->dbh,
1042 "sqlite3_reset"); 1049 plugin->maxRepl);
1043 stmt = plugin->selRepl; 1050 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1044 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); 1051 UINT64_MAX);
1045 if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, rvalue)) 1052 if (GNUNET_OK !=
1053 GNUNET_SQ_bind (plugin->selRepl,
1054 params_sel_repl))
1046 { 1055 {
1047 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1048 "sqlite3_bind_XXXX");
1049 if (SQLITE_OK != sqlite3_reset (stmt))
1050 LOG_SQLITE (plugin,
1051 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1052 "sqlite3_reset");
1053 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1056 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1054 return; 1057 return;
1055 } 1058 }
1056 if (SQLITE_OK != sqlite3_bind_int (stmt, 2, repl)) 1059 rc.have_uid = GNUNET_SYSERR;
1057 { 1060 rc.proc = proc;
1058 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1061 rc.proc_cls = proc_cls;
1059 "sqlite3_bind_XXXX"); 1062 execute_get (plugin,
1060 if (SQLITE_OK != sqlite3_reset (stmt)) 1063 plugin->selRepl,
1061 LOG_SQLITE (plugin, 1064 &repl_proc,
1062 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1065 &rc);
1063 "sqlite3_reset");
1064 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1065 return;
1066 }
1067 execute_get (plugin, stmt, &repl_proc, &rc);
1068 if (GNUNET_YES == rc.have_uid) 1066 if (GNUNET_YES == rc.have_uid)
1069 { 1067 {
1070 if (SQLITE_OK != sqlite3_bind_int64 (plugin->updRepl, 1, rc.uid)) 1068 if (GNUNET_OK !=
1069 GNUNET_SQ_bind (plugin->updRepl,
1070 params_upd_repl))
1071 { 1071 {
1072 LOG_SQLITE (plugin, 1072 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1073 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1074 "sqlite3_bind_XXXX");
1075 if (SQLITE_OK != sqlite3_reset (plugin->updRepl))
1076 LOG_SQLITE (plugin,
1077 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1078 "sqlite3_reset");
1079 return; 1073 return;
1080 } 1074 }
1081 if (SQLITE_DONE != sqlite3_step (plugin->updRepl)) 1075 if (SQLITE_DONE !=
1076 sqlite3_step (plugin->updRepl))
1082 LOG_SQLITE (plugin, 1077 LOG_SQLITE (plugin,
1083 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1078 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1084 "sqlite3_step"); 1079 "sqlite3_step");
1085 if (SQLITE_OK != sqlite3_reset (plugin->updRepl)) 1080 GNUNET_SQ_reset (plugin->dbh,
1086 LOG_SQLITE (plugin, 1081 plugin->updRepl);
1087 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1082 }
1088 "sqlite3_reset"); 1083 if (GNUNET_SYSERR == rc.have_uid)
1084 {
1085 /* proc was not called at all so far, do it now. */
1086 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1089 } 1087 }
1090} 1088}
1091 1089
@@ -1105,19 +1103,20 @@ sqlite_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
1105 struct Plugin *plugin = cls; 1103 struct Plugin *plugin = cls;
1106 sqlite3_stmt *stmt; 1104 sqlite3_stmt *stmt;
1107 struct GNUNET_TIME_Absolute now; 1105 struct GNUNET_TIME_Absolute now;
1106 struct GNUNET_SQ_QueryParam params[] = {
1107 GNUNET_SQ_query_param_absolute_time (&now),
1108 GNUNET_SQ_query_param_end
1109 };
1108 1110
1109 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", 1111 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1112 "sqlite",
1110 "Getting random block based on expiration and priority order.\n"); 1113 "Getting random block based on expiration and priority order.\n");
1111 now = GNUNET_TIME_absolute_get (); 1114 now = GNUNET_TIME_absolute_get ();
1112 stmt = plugin->selExpi; 1115 stmt = plugin->selExpi;
1113 if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, now.abs_value_us)) 1116 if (GNUNET_OK !=
1117 GNUNET_SQ_bind (stmt,
1118 params))
1114 { 1119 {
1115 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1116 "sqlite3_bind_XXXX");
1117 if (SQLITE_OK != sqlite3_reset (stmt))
1118 LOG_SQLITE (plugin,
1119 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1120 "sqlite3_reset");
1121 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1120 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1122 return; 1121 return;
1123 } 1122 }
@@ -1138,30 +1137,47 @@ sqlite_plugin_get_keys (void *cls,
1138 void *proc_cls) 1137 void *proc_cls)
1139{ 1138{
1140 struct Plugin *plugin = cls; 1139 struct Plugin *plugin = cls;
1141 const struct GNUNET_HashCode *key; 1140 struct GNUNET_HashCode key;
1141 struct GNUNET_SQ_ResultSpec results[] = {
1142 GNUNET_SQ_result_spec_auto_from_type (&key),
1143 GNUNET_SQ_result_spec_end
1144 };
1142 sqlite3_stmt *stmt; 1145 sqlite3_stmt *stmt;
1143 int ret; 1146 int ret;
1144 1147
1145 GNUNET_assert (proc != NULL); 1148 GNUNET_assert (NULL != proc);
1146 if (sq_prepare (plugin->dbh, "SELECT hash FROM gn090", &stmt) != SQLITE_OK) 1149 if (SQLITE_OK !=
1150 sq_prepare (plugin->dbh,
1151 "SELECT hash FROM gn090",
1152 &stmt))
1147 { 1153 {
1148 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1154 LOG_SQLITE (plugin,
1155 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1149 "sqlite_prepare"); 1156 "sqlite_prepare");
1150 proc (proc_cls, NULL, 0); 1157 proc (proc_cls,
1158 NULL,
1159 0);
1151 return; 1160 return;
1152 } 1161 }
1153 while (SQLITE_ROW == (ret = sqlite3_step (stmt))) 1162 while (SQLITE_ROW == (ret = sqlite3_step (stmt)))
1154 { 1163 {
1155 key = sqlite3_column_blob (stmt, 0); 1164 if (GNUNET_OK ==
1156 if (sizeof (struct GNUNET_HashCode) == sqlite3_column_bytes (stmt, 0)) 1165 GNUNET_SQ_extract_result (stmt,
1157 proc (proc_cls, key, 1); 1166 results))
1167 proc (proc_cls,
1168 &key,
1169 1);
1158 else 1170 else
1159 GNUNET_break (0); 1171 GNUNET_break (0);
1160 } 1172 }
1161 if (SQLITE_DONE != ret) 1173 if (SQLITE_DONE != ret)
1162 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); 1174 LOG_SQLITE (plugin,
1175 GNUNET_ERROR_TYPE_ERROR,
1176 "sqlite_step");
1163 sqlite3_finalize (stmt); 1177 sqlite3_finalize (stmt);
1164 proc (proc_cls, NULL, 0); 1178 proc (proc_cls,
1179 NULL,
1180 0);
1165} 1181}
1166 1182
1167 1183
@@ -1187,7 +1203,8 @@ sqlite_plugin_drop (void *cls)
1187 * @return the size of the database on disk (estimate) 1203 * @return the size of the database on disk (estimate)
1188 */ 1204 */
1189static void 1205static void
1190sqlite_plugin_estimate_size (void *cls, unsigned long long *estimate) 1206sqlite_plugin_estimate_size (void *cls,
1207 unsigned long long *estimate)
1191{ 1208{
1192 struct Plugin *plugin = cls; 1209 struct Plugin *plugin = cls;
1193 sqlite3_stmt *stmt; 1210 sqlite3_stmt *stmt;
@@ -1202,30 +1219,45 @@ sqlite_plugin_estimate_size (void *cls, unsigned long long *estimate)
1202 return; 1219 return;
1203 if (SQLITE_VERSION_NUMBER < 3006000) 1220 if (SQLITE_VERSION_NUMBER < 3006000)
1204 { 1221 {
1205 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "datastore-sqlite", 1222 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1206 _ 1223 "datastore-sqlite",
1207 ("sqlite version to old to determine size, assuming zero\n")); 1224 _("sqlite version to old to determine size, assuming zero\n"));
1208 *estimate = 0; 1225 *estimate = 0;
1209 return; 1226 return;
1210 } 1227 }
1211 CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "VACUUM", NULL, NULL, ENULL));
1212 CHECK (SQLITE_OK == 1228 CHECK (SQLITE_OK ==
1213 sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL, 1229 sqlite3_exec (plugin->dbh,
1230 "VACUUM",
1231 NULL,
1232 NULL,
1233 ENULL));
1234 CHECK (SQLITE_OK ==
1235 sqlite3_exec (plugin->dbh,
1236 "PRAGMA auto_vacuum=INCREMENTAL",
1237 NULL,
1214 NULL, ENULL)); 1238 NULL, ENULL));
1215 CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_count", &stmt)); 1239 CHECK (SQLITE_OK ==
1240 sq_prepare (plugin->dbh,
1241 "PRAGMA page_count",
1242 &stmt));
1216 if (SQLITE_ROW == sqlite3_step (stmt)) 1243 if (SQLITE_ROW == sqlite3_step (stmt))
1217 pages = sqlite3_column_int64 (stmt, 0); 1244 pages = sqlite3_column_int64 (stmt,
1245 0);
1218 else 1246 else
1219 pages = 0; 1247 pages = 0;
1220 sqlite3_finalize (stmt); 1248 sqlite3_finalize (stmt);
1221 CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_size", &stmt)); 1249 CHECK (SQLITE_OK ==
1222 CHECK (SQLITE_ROW == sqlite3_step (stmt)); 1250 sq_prepare (plugin->dbh,
1251 "PRAGMA page_size",
1252 &stmt));
1253 CHECK (SQLITE_ROW ==
1254 sqlite3_step (stmt));
1223 page_size = sqlite3_column_int64 (stmt, 0); 1255 page_size = sqlite3_column_int64 (stmt, 0);
1224 sqlite3_finalize (stmt); 1256 sqlite3_finalize (stmt);
1225 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1257 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1226 _ 1258 _("Using sqlite page utilization to estimate payload (%llu pages of size %llu bytes)\n"),
1227 ("Using sqlite page utilization to estimate payload (%llu pages of size %llu bytes)\n"), 1259 (unsigned long long) pages,
1228 (unsigned long long) pages, (unsigned long long) page_size); 1260 (unsigned long long) page_size);
1229 *estimate = pages * page_size; 1261 *estimate = pages * page_size;
1230} 1262}
1231 1263
@@ -1243,9 +1275,11 @@ libgnunet_plugin_datastore_sqlite_init (void *cls)
1243 struct GNUNET_DATASTORE_PluginEnvironment *env = cls; 1275 struct GNUNET_DATASTORE_PluginEnvironment *env = cls;
1244 struct GNUNET_DATASTORE_PluginFunctions *api; 1276 struct GNUNET_DATASTORE_PluginFunctions *api;
1245 1277
1246 if (plugin.env != NULL) 1278 if (NULL != plugin.env)
1247 return NULL; /* can only initialize once! */ 1279 return NULL; /* can only initialize once! */
1248 memset (&plugin, 0, sizeof (struct Plugin)); 1280 memset (&plugin,
1281 0,
1282 sizeof (struct Plugin));
1249 plugin.env = env; 1283 plugin.env = env;
1250 if (GNUNET_OK != database_setup (env->cfg, &plugin)) 1284 if (GNUNET_OK != database_setup (env->cfg, &plugin))
1251 { 1285 {
@@ -1263,7 +1297,8 @@ libgnunet_plugin_datastore_sqlite_init (void *cls)
1263 api->get_zero_anonymity = &sqlite_plugin_get_zero_anonymity; 1297 api->get_zero_anonymity = &sqlite_plugin_get_zero_anonymity;
1264 api->get_keys = &sqlite_plugin_get_keys; 1298 api->get_keys = &sqlite_plugin_get_keys;
1265 api->drop = &sqlite_plugin_drop; 1299 api->drop = &sqlite_plugin_drop;
1266 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "sqlite", 1300 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
1301 "sqlite",
1267 _("Sqlite database running\n")); 1302 _("Sqlite database running\n"));
1268 return api; 1303 return api;
1269} 1304}
@@ -1282,24 +1317,23 @@ libgnunet_plugin_datastore_sqlite_done (void *cls)
1282 struct GNUNET_DATASTORE_PluginFunctions *api = cls; 1317 struct GNUNET_DATASTORE_PluginFunctions *api = cls;
1283 struct Plugin *plugin = api->cls; 1318 struct Plugin *plugin = api->cls;
1284 1319
1285 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", 1320 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1321 "sqlite",
1286 "sqlite plugin is done\n"); 1322 "sqlite plugin is done\n");
1287 fn = NULL; 1323 fn = NULL;
1288 if (plugin->drop_on_shutdown) 1324 if (plugin->drop_on_shutdown)
1289 fn = GNUNET_strdup (plugin->fn); 1325 fn = GNUNET_strdup (plugin->fn);
1290 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1291 "Shutting down database\n");
1292 database_shutdown (plugin); 1326 database_shutdown (plugin);
1293 plugin->env = NULL; 1327 plugin->env = NULL;
1294 GNUNET_free (api); 1328 GNUNET_free (api);
1295 if (fn != NULL) 1329 if (NULL != fn)
1296 { 1330 {
1297 if (0 != UNLINK (fn)) 1331 if (0 != UNLINK (fn))
1298 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); 1332 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
1333 "unlink",
1334 fn);
1299 GNUNET_free (fn); 1335 GNUNET_free (fn);
1300 } 1336 }
1301 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1302 "sqlite plugin is finished\n");
1303 return NULL; 1337 return NULL;
1304} 1338}
1305 1339