aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_namestore_sqlite.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-16 21:52:04 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-16 21:52:04 +0000
commitdbc823a07a03e1085172038125b0edf15b0dc6fe (patch)
tree4e7c3bf60ce83e801c69a6566ea36d514b571cba /src/namestore/plugin_namestore_sqlite.c
parenteec0e5088ec9437f5c0cf9d3ffef87603ad2777a (diff)
downloadgnunet-dbc823a07a03e1085172038125b0edf15b0dc6fe.tar.gz
gnunet-dbc823a07a03e1085172038125b0edf15b0dc6fe.zip
-finishing split of namestore into namestore and namecache (#3065) -- in theory; in practice, somehow something broke badly, so the tests are now failing
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r--src/namestore/plugin_namestore_sqlite.c314
1 files changed, 1 insertions, 313 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index ce7be2a20..2cf604dbd 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -73,26 +73,6 @@ struct Plugin
73 sqlite3 *dbh; 73 sqlite3 *dbh;
74 74
75 /** 75 /**
76 * Precompiled SQL for caching a block
77 */
78 sqlite3_stmt *cache_block;
79
80 /**
81 * Precompiled SQL for deleting an older block
82 */
83 sqlite3_stmt *delete_block;
84
85 /**
86 * Precompiled SQL for looking up a block
87 */
88 sqlite3_stmt *lookup_block;
89
90 /**
91 * Precompiled SQL for removing expired blocks
92 */
93 sqlite3_stmt *expire_blocks;
94
95 /**
96 * Precompiled SQL to store records. 76 * Precompiled SQL to store records.
97 */ 77 */
98 sqlite3_stmt *store_records; 78 sqlite3_stmt *store_records;
@@ -153,12 +133,6 @@ create_indices (sqlite3 * dbh)
153{ 133{
154 /* create indices */ 134 /* create indices */
155 if ( (SQLITE_OK != 135 if ( (SQLITE_OK !=
156 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_query_hash ON ns096blocks (query,expiration_time)",
157 NULL, NULL, NULL)) ||
158 (SQLITE_OK !=
159 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_block_expiration ON ns096blocks (expiration_time)",
160 NULL, NULL, NULL)) ||
161 (SQLITE_OK !=
162 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_reverse ON ns097records (zone_private_key,pkey)", 136 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_reverse ON ns097records (zone_private_key,pkey)",
163 NULL, NULL, NULL)) || 137 NULL, NULL, NULL)) ||
164 (SQLITE_OK != 138 (SQLITE_OK !=
@@ -255,27 +229,7 @@ database_setup (struct Plugin *plugin)
255 CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS)); 229 CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));
256 230
257 231
258 /* Create tables */ 232 /* Create table */
259 CHECK (SQLITE_OK ==
260 sq_prepare (plugin->dbh,
261 "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096blocks'",
262 &stmt));
263 if ((sqlite3_step (stmt) == SQLITE_DONE) &&
264 (sqlite3_exec
265 (plugin->dbh,
266 "CREATE TABLE ns096blocks ("
267 " query BLOB NOT NULL DEFAULT '',"
268 " block BLOB NOT NULL DEFAULT '',"
269 " expiration_time INT8 NOT NULL DEFAULT 0"
270 ")",
271 NULL, NULL, NULL) != SQLITE_OK))
272 {
273 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
274 sqlite3_finalize (stmt);
275 return GNUNET_SYSERR;
276 }
277 sqlite3_finalize (stmt);
278
279 CHECK (SQLITE_OK == 233 CHECK (SQLITE_OK ==
280 sq_prepare (plugin->dbh, 234 sq_prepare (plugin->dbh,
281 "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns097records'", 235 "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns097records'",
@@ -303,22 +257,6 @@ database_setup (struct Plugin *plugin)
303 257
304 if ((sq_prepare 258 if ((sq_prepare
305 (plugin->dbh, 259 (plugin->dbh,
306 "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, ?)",
307 &plugin->cache_block) != SQLITE_OK) ||
308 (sq_prepare
309 (plugin->dbh,
310 "DELETE FROM ns096blocks WHERE expiration_time<?",
311 &plugin->expire_blocks) != SQLITE_OK) ||
312 (sq_prepare
313 (plugin->dbh,
314 "DELETE FROM ns096blocks WHERE query=? AND expiration_time<=?",
315 &plugin->delete_block) != SQLITE_OK) ||
316 (sq_prepare
317 (plugin->dbh,
318 "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time DESC LIMIT 1",
319 &plugin->lookup_block) != SQLITE_OK) ||
320 (sq_prepare
321 (plugin->dbh,
322 "INSERT INTO ns097records (zone_private_key, pkey, rvalue, record_count, record_data, label)" 260 "INSERT INTO ns097records (zone_private_key, pkey, rvalue, record_count, record_data, label)"
323 " VALUES (?, ?, ?, ?, ?, ?)", 261 " VALUES (?, ?, ?, ?, ?, ?)",
324 &plugin->store_records) != SQLITE_OK) || 262 &plugin->store_records) != SQLITE_OK) ||
@@ -361,14 +299,6 @@ database_shutdown (struct Plugin *plugin)
361 int result; 299 int result;
362 sqlite3_stmt *stmt; 300 sqlite3_stmt *stmt;
363 301
364 if (NULL != plugin->cache_block)
365 sqlite3_finalize (plugin->cache_block);
366 if (NULL != plugin->lookup_block)
367 sqlite3_finalize (plugin->lookup_block);
368 if (NULL != plugin->expire_blocks)
369 sqlite3_finalize (plugin->expire_blocks);
370 if (NULL != plugin->delete_block)
371 sqlite3_finalize (plugin->delete_block);
372 if (NULL != plugin->store_records) 302 if (NULL != plugin->store_records)
373 sqlite3_finalize (plugin->store_records); 303 sqlite3_finalize (plugin->store_records);
374 if (NULL != plugin->delete_records) 304 if (NULL != plugin->delete_records)
@@ -405,246 +335,6 @@ database_shutdown (struct Plugin *plugin)
405 335
406 336
407/** 337/**
408 * Removes any expired block.
409 *
410 * @param plugin the plugin
411 */
412static void
413namestore_sqlite_expire_blocks (struct Plugin *plugin)
414{
415 struct GNUNET_TIME_Absolute now;
416 int n;
417
418 now = GNUNET_TIME_absolute_get ();
419 if (SQLITE_OK != sqlite3_bind_int64 (plugin->expire_blocks,
420 1, now.abs_value_us))
421 {
422 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
423 "sqlite3_bind_XXXX");
424 if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
425 LOG_SQLITE (plugin,
426 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
427 "sqlite3_reset");
428 return;
429 }
430 n = sqlite3_step (plugin->expire_blocks);
431 if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
432 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
433 "sqlite3_reset");
434 switch (n)
435 {
436 case SQLITE_DONE:
437 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Records expired\n");
438 return;
439 case SQLITE_BUSY:
440 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
441 "sqlite3_step");
442 return;
443 default:
444 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
445 "sqlite3_step");
446 return;
447 }
448}
449
450
451/**
452 * Cache a block in the datastore.
453 *
454 * @param cls closure (internal context for the plugin)
455 * @param block block to cache
456 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
457 */
458static int
459namestore_sqlite_cache_block (void *cls,
460 const struct GNUNET_GNSRECORD_Block *block)
461{
462 struct Plugin *plugin = cls;
463 struct GNUNET_HashCode query;
464 struct GNUNET_TIME_Absolute expiration;
465 int64_t dval;
466 size_t block_size;
467 int n;
468
469 namestore_sqlite_expire_blocks (plugin);
470 GNUNET_CRYPTO_hash (&block->derived_key,
471 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
472 &query);
473 expiration = GNUNET_TIME_absolute_ntoh (block->expiration_time);
474 dval = (int64_t) expiration.abs_value_us;
475 if (dval < 0)
476 dval = INT64_MAX;
477 block_size = ntohl (block->purpose.size) +
478 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
479 sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
480 if (block_size > 64 * 65536)
481 {
482 GNUNET_break (0);
483 return GNUNET_SYSERR;
484 }
485
486 /* delete old version of the block */
487 if ( (SQLITE_OK !=
488 sqlite3_bind_blob (plugin->delete_block, 1,
489 &query, sizeof (struct GNUNET_HashCode),
490 SQLITE_STATIC)) ||
491 (SQLITE_OK !=
492 sqlite3_bind_int64 (plugin->delete_block,
493 2, dval)) )
494 {
495 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
496 "sqlite3_bind_XXXX");
497 if (SQLITE_OK != sqlite3_reset (plugin->delete_block))
498 LOG_SQLITE (plugin,
499 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
500 "sqlite3_reset");
501 return GNUNET_SYSERR;
502 }
503 n = sqlite3_step (plugin->delete_block);
504 switch (n)
505 {
506 case SQLITE_DONE:
507 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Old block deleted\n");
508 break;
509 case SQLITE_BUSY:
510 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
511 "sqlite3_step");
512 break;
513 default:
514 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
515 "sqlite3_step");
516 break;
517 }
518 if (SQLITE_OK != sqlite3_reset (plugin->delete_block))
519 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
520 "sqlite3_reset");
521
522 /* insert new version of the block */
523 if ((SQLITE_OK !=
524 sqlite3_bind_blob (plugin->cache_block, 1,
525 &query, sizeof (struct GNUNET_HashCode),
526 SQLITE_STATIC)) ||
527 (SQLITE_OK !=
528 sqlite3_bind_blob (plugin->cache_block, 2,
529 block, block_size,
530 SQLITE_STATIC)) ||
531 (SQLITE_OK !=
532 sqlite3_bind_int64 (plugin->cache_block, 3,
533 dval)))
534 {
535 LOG_SQLITE (plugin,
536 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
537 "sqlite3_bind_XXXX");
538 if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
539 LOG_SQLITE (plugin,
540 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
541 "sqlite3_reset");
542 return GNUNET_SYSERR;
543
544 }
545 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
546 "Caching block under derived key `%s'\n",
547 GNUNET_h2s_full (&query));
548 n = sqlite3_step (plugin->cache_block);
549 if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
550 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
551 "sqlite3_reset");
552 switch (n)
553 {
554 case SQLITE_DONE:
555 LOG (GNUNET_ERROR_TYPE_DEBUG,
556 "Record stored\n");
557 return GNUNET_OK;
558 case SQLITE_BUSY:
559 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
560 "sqlite3_step");
561 return GNUNET_NO;
562 default:
563 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
564 "sqlite3_step");
565 return GNUNET_SYSERR;
566 }
567}
568
569
570/**
571 * Get the block for a particular zone and label in the
572 * datastore. Will return at most one result to the iterator.
573 *
574 * @param cls closure (internal context for the plugin)
575 * @param query hash of public key derived from the zone and the label
576 * @param iter function to call with the result
577 * @param iter_cls closure for @a iter
578 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
579 */
580static int
581namestore_sqlite_lookup_block (void *cls,
582 const struct GNUNET_HashCode *query,
583 GNUNET_GNSRECORD_BlockCallback iter, void *iter_cls)
584{
585 struct Plugin *plugin = cls;
586 int ret;
587 int sret;
588 size_t block_size;
589 const struct GNUNET_GNSRECORD_Block *block;
590
591 if (SQLITE_OK != sqlite3_bind_blob (plugin->lookup_block, 1,
592 query, sizeof (struct GNUNET_HashCode),
593 SQLITE_STATIC))
594 {
595 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
596 "sqlite3_bind_XXXX");
597 if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
598 LOG_SQLITE (plugin,
599 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
600 "sqlite3_reset");
601 return GNUNET_SYSERR;
602 }
603 ret = GNUNET_NO;
604 if (SQLITE_ROW == (sret = sqlite3_step (plugin->lookup_block)))
605 {
606 block = sqlite3_column_blob (plugin->lookup_block, 0);
607 block_size = sqlite3_column_bytes (plugin->lookup_block, 0);
608 if ( (block_size < sizeof (struct GNUNET_GNSRECORD_Block)) ||
609 (ntohl (block->purpose.size) +
610 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
611 sizeof (struct GNUNET_CRYPTO_EcdsaSignature) != block_size) )
612 {
613 GNUNET_break (0);
614 ret = GNUNET_SYSERR;
615 }
616 else
617 {
618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
619 "Found block under derived key `%s'\n",
620 GNUNET_h2s_full (query));
621 iter (iter_cls, block);
622 ret = GNUNET_YES;
623 }
624 }
625 else
626 {
627 if (SQLITE_DONE != sret)
628 {
629 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
630 ret = GNUNET_SYSERR;
631 }
632 else
633 {
634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
635 "No block found under derived key `%s'\n",
636 GNUNET_h2s_full (query));
637 }
638 }
639 if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
640 LOG_SQLITE (plugin,
641 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
642 "sqlite3_reset");
643 return ret;
644}
645
646
647/**
648 * Store a record in the datastore. Removes any existing record in the 338 * Store a record in the datastore. Removes any existing record in the
649 * same zone with the same name. 339 * same zone with the same name.
650 * 340 *
@@ -965,8 +655,6 @@ libgnunet_plugin_namestore_sqlite_init (void *cls)
965 } 655 }
966 api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions); 656 api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
967 api->cls = &plugin; 657 api->cls = &plugin;
968 api->cache_block = &namestore_sqlite_cache_block;
969 api->lookup_block = &namestore_sqlite_lookup_block;
970 api->store_records = &namestore_sqlite_store_records; 658 api->store_records = &namestore_sqlite_store_records;
971 api->iterate_records = &namestore_sqlite_iterate_records; 659 api->iterate_records = &namestore_sqlite_iterate_records;
972 api->zone_to_name = &namestore_sqlite_zone_to_name; 660 api->zone_to_name = &namestore_sqlite_zone_to_name;