aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/plugin_datastore_sqlite.c
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amat.us>2017-04-16 12:39:43 -0500
committerDavid Barksdale <amatus@amat.us>2017-04-16 12:42:34 -0500
commit4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch)
treea2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore/plugin_datastore_sqlite.c
parentcacd64d8635201459e59bf2cd8a2ea8fd0699b84 (diff)
downloadgnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.tar.gz
gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.zip
[datastore] Combine put and update plugin APIs
This resolves issue #4965.
Diffstat (limited to 'src/datastore/plugin_datastore_sqlite.c')
-rw-r--r--src/datastore/plugin_datastore_sqlite.c149
1 files changed, 64 insertions, 85 deletions
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index 1f874e190..469dd7717 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -95,7 +95,7 @@ struct Plugin
95 /** 95 /**
96 * Precompiled SQL for update. 96 * Precompiled SQL for update.
97 */ 97 */
98 sqlite3_stmt *updPrio; 98 sqlite3_stmt *update;
99 99
100 /** 100 /**
101 * Get maximum repl value in database. 101 * Get maximum repl value in database.
@@ -356,8 +356,8 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
356 "SET prio = prio + ?, " 356 "SET prio = prio + ?, "
357 "repl = repl + ?, " 357 "repl = repl + ?, "
358 "expire = MAX(expire, ?) " 358 "expire = MAX(expire, ?) "
359 "WHERE _ROWID_ = ?", 359 "WHERE hash = ? AND vhash = ?",
360 &plugin->updPrio)) || 360 &plugin->update)) ||
361 (SQLITE_OK != 361 (SQLITE_OK !=
362 sq_prepare (plugin->dbh, 362 sq_prepare (plugin->dbh,
363 "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?", 363 "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?",
@@ -450,8 +450,8 @@ database_shutdown (struct Plugin *plugin)
450 450
451 if (NULL != plugin->delRow) 451 if (NULL != plugin->delRow)
452 sqlite3_finalize (plugin->delRow); 452 sqlite3_finalize (plugin->delRow);
453 if (NULL != plugin->updPrio) 453 if (NULL != plugin->update)
454 sqlite3_finalize (plugin->updPrio); 454 sqlite3_finalize (plugin->update);
455 if (NULL != plugin->updRepl) 455 if (NULL != plugin->updRepl)
456 sqlite3_finalize (plugin->updRepl); 456 sqlite3_finalize (plugin->updRepl);
457 if (NULL != plugin->selRepl) 457 if (NULL != plugin->selRepl)
@@ -541,6 +541,7 @@ delete_by_rowid (struct Plugin *plugin,
541 * 541 *
542 * @param cls closure 542 * @param cls closure
543 * @param key key for the item 543 * @param key key for the item
544 * @param absent true if the key was not found in the bloom filter
544 * @param size number of bytes in @a data 545 * @param size number of bytes in @a data
545 * @param data content stored 546 * @param data content stored
546 * @param type type of the content 547 * @param type type of the content
@@ -554,6 +555,7 @@ delete_by_rowid (struct Plugin *plugin,
554static void 555static void
555sqlite_plugin_put (void *cls, 556sqlite_plugin_put (void *cls,
556 const struct GNUNET_HashCode *key, 557 const struct GNUNET_HashCode *key,
558 bool absent,
557 uint32_t size, 559 uint32_t size,
558 const void *data, 560 const void *data,
559 enum GNUNET_BLOCK_Type type, 561 enum GNUNET_BLOCK_Type type,
@@ -564,8 +566,63 @@ sqlite_plugin_put (void *cls,
564 PluginPutCont cont, 566 PluginPutCont cont,
565 void *cont_cls) 567 void *cont_cls)
566{ 568{
567 uint64_t rvalue; 569 struct Plugin *plugin = cls;
568 struct GNUNET_HashCode vhash; 570 struct GNUNET_HashCode vhash;
571 char *msg = NULL;
572
573 GNUNET_CRYPTO_hash (data,
574 size,
575 &vhash);
576
577 if (!absent)
578 {
579 struct GNUNET_SQ_QueryParam params[] = {
580 GNUNET_SQ_query_param_uint32 (&priority),
581 GNUNET_SQ_query_param_uint32 (&replication),
582 GNUNET_SQ_query_param_absolute_time (&expiration),
583 GNUNET_SQ_query_param_auto_from_type (key),
584 GNUNET_SQ_query_param_auto_from_type (&vhash),
585 GNUNET_SQ_query_param_end
586 };
587
588 if (GNUNET_OK !=
589 GNUNET_SQ_bind (plugin->update,
590 params))
591 {
592 cont (cont_cls,
593 key,
594 size,
595 GNUNET_SYSERR,
596 _("sqlite bind failure"));
597 return;
598 }
599 if (SQLITE_DONE != sqlite3_step (plugin->update))
600 {
601 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
602 "sqlite3_step");
603 cont (cont_cls,
604 key,
605 size,
606 GNUNET_SYSERR,
607 msg);
608 GNUNET_free_non_null (msg);
609 return;
610 }
611 int changes = sqlite3_changes (plugin->dbh);
612 GNUNET_SQ_reset (plugin->dbh,
613 plugin->update);
614 if (0 != changes)
615 {
616 cont (cont_cls,
617 key,
618 size,
619 GNUNET_NO,
620 NULL);
621 return;
622 }
623 }
624
625 uint64_t rvalue;
569 uint32_t type32 = (uint32_t) type; 626 uint32_t type32 = (uint32_t) type;
570 struct GNUNET_SQ_QueryParam params[] = { 627 struct GNUNET_SQ_QueryParam params[] = {
571 GNUNET_SQ_query_param_uint32 (&replication), 628 GNUNET_SQ_query_param_uint32 (&replication),
@@ -579,11 +636,9 @@ sqlite_plugin_put (void *cls,
579 GNUNET_SQ_query_param_fixed_size (data, size), 636 GNUNET_SQ_query_param_fixed_size (data, size),
580 GNUNET_SQ_query_param_end 637 GNUNET_SQ_query_param_end
581 }; 638 };
582 struct Plugin *plugin = cls;
583 int n; 639 int n;
584 int ret; 640 int ret;
585 sqlite3_stmt *stmt; 641 sqlite3_stmt *stmt;
586 char *msg = NULL;
587 642
588 if (size > MAX_ITEM_SIZE) 643 if (size > MAX_ITEM_SIZE)
589 { 644 {
@@ -598,15 +653,13 @@ sqlite_plugin_put (void *cls,
598 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration), 653 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration),
599 GNUNET_YES), 654 GNUNET_YES),
600 GNUNET_STRINGS_absolute_time_to_string (expiration)); 655 GNUNET_STRINGS_absolute_time_to_string (expiration));
601 GNUNET_CRYPTO_hash (data, size, &vhash);
602 stmt = plugin->insertContent; 656 stmt = plugin->insertContent;
603 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); 657 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
604 if (GNUNET_OK != 658 if (GNUNET_OK !=
605 GNUNET_SQ_bind (stmt, 659 GNUNET_SQ_bind (stmt,
606 params)) 660 params))
607 { 661 {
608 cont (cont_cls, key, size, GNUNET_SYSERR, msg); 662 cont (cont_cls, key, size, GNUNET_SYSERR, NULL);
609 GNUNET_free_non_null(msg);
610 return; 663 return;
611 } 664 }
612 n = sqlite3_step (stmt); 665 n = sqlite3_step (stmt);
@@ -646,79 +699,6 @@ sqlite_plugin_put (void *cls,
646 699
647 700
648/** 701/**
649 * Update the priority, replication and expiration for a particular
650 * unique ID in the datastore. If the expiration time in value is
651 * different than the time found in the datastore, the higher value
652 * should be kept. The specified priority and replication is added
653 * to the existing value.
654 *
655 * @param cls the plugin context (state for this module)
656 * @param uid unique identifier of the datum
657 * @param priority by how much should the priority
658 * change?
659 * @param replication by how much should the replication
660 * change?
661 * @param expire new expiration time should be the
662 * MAX of any existing expiration time and
663 * this value
664 * @param cont continuation called with success or failure status
665 * @param cons_cls closure for @a cont
666 */
667static void
668sqlite_plugin_update (void *cls,
669 uint64_t uid,
670 uint32_t priority,
671 uint32_t replication,
672 struct GNUNET_TIME_Absolute expire,
673 PluginUpdateCont cont,
674 void *cont_cls)
675{
676 struct Plugin *plugin = cls;
677 struct GNUNET_SQ_QueryParam params[] = {
678 GNUNET_SQ_query_param_uint32 (&priority),
679 GNUNET_SQ_query_param_uint32 (&replication),
680 GNUNET_SQ_query_param_absolute_time (&expire),
681 GNUNET_SQ_query_param_uint64 (&uid),
682 GNUNET_SQ_query_param_end
683 };
684 int n;
685 char *msg = NULL;
686
687 if (GNUNET_OK !=
688 GNUNET_SQ_bind (plugin->updPrio,
689 params))
690 {
691 cont (cont_cls, GNUNET_SYSERR, msg);
692 GNUNET_free_non_null(msg);
693 return;
694 }
695 n = sqlite3_step (plugin->updPrio);
696 GNUNET_SQ_reset (plugin->dbh,
697 plugin->updPrio);
698 switch (n)
699 {
700 case SQLITE_DONE:
701 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Block updated\n");
702 cont (cont_cls, GNUNET_OK, NULL);
703 return;
704 case SQLITE_BUSY:
705 LOG_SQLITE_MSG (plugin, &msg,
706 GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
707 "sqlite3_step");
708 cont (cont_cls, GNUNET_NO, msg);
709 GNUNET_free_non_null(msg);
710 return;
711 default:
712 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
713 "sqlite3_step");
714 cont (cont_cls, GNUNET_SYSERR, msg);
715 GNUNET_free_non_null(msg);
716 return;
717 }
718}
719
720
721/**
722 * Execute statement that gets a row and call the callback 702 * Execute statement that gets a row and call the callback
723 * with the result. Resets the statement afterwards. 703 * with the result. Resets the statement afterwards.
724 * 704 *
@@ -1300,7 +1280,6 @@ libgnunet_plugin_datastore_sqlite_init (void *cls)
1300 api->cls = &plugin; 1280 api->cls = &plugin;
1301 api->estimate_size = &sqlite_plugin_estimate_size; 1281 api->estimate_size = &sqlite_plugin_estimate_size;
1302 api->put = &sqlite_plugin_put; 1282 api->put = &sqlite_plugin_put;
1303 api->update = &sqlite_plugin_update;
1304 api->get_key = &sqlite_plugin_get_key; 1283 api->get_key = &sqlite_plugin_get_key;
1305 api->get_replication = &sqlite_plugin_get_replication; 1284 api->get_replication = &sqlite_plugin_get_replication;
1306 api->get_expiration = &sqlite_plugin_get_expiration; 1285 api->get_expiration = &sqlite_plugin_get_expiration;