diff options
author | David Barksdale <amatus@amat.us> | 2017-04-16 12:39:43 -0500 |
---|---|---|
committer | David Barksdale <amatus@amat.us> | 2017-04-16 12:42:34 -0500 |
commit | 4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch) | |
tree | a2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore/plugin_datastore_sqlite.c | |
parent | cacd64d8635201459e59bf2cd8a2ea8fd0699b84 (diff) | |
download | gnunet-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.c | 149 |
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, | |||
554 | static void | 555 | static void |
555 | sqlite_plugin_put (void *cls, | 556 | sqlite_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 | */ | ||
667 | static void | ||
668 | sqlite_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; |