diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-02-21 20:41:31 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-02-21 20:41:31 +0000 |
commit | 6c1b5f3149788006601996ef10cd030fe3aa6f02 (patch) | |
tree | af8a9b075fa96354bb921f75b925b8f3658466c0 /src/namestore/plugin_namestore_sqlite.c | |
parent | 7590a212861cd5cafeceba3c20c1e6c9528b880d (diff) | |
download | gnunet-6c1b5f3149788006601996ef10cd030fe3aa6f02.tar.gz gnunet-6c1b5f3149788006601996ef10cd030fe3aa6f02.zip |
-finishing first pass at implementing sqlite statements for namestore
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r-- | src/namestore/plugin_namestore_sqlite.c | 285 |
1 files changed, 190 insertions, 95 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index ff0875ea6..10ee62403 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -676,107 +676,51 @@ namestore_sqlite_iterate_records (void *cls, | |||
676 | const GNUNET_HashCode *name_hash, | 676 | const GNUNET_HashCode *name_hash, |
677 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) | 677 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) |
678 | { | 678 | { |
679 | #if 0 | 679 | struct Plugin *plugin = cls; |
680 | int n; | 680 | unsigned int ret; |
681 | struct GNUNET_TIME_Absolute expiration; | 681 | struct GNUNET_TIME_Absolute expiration; |
682 | unsigned long long rowid; | 682 | uint32_t record_type; |
683 | unsigned int size; | 683 | enum GNUNET_NAMESTORE_RecordFlags flags; |
684 | int ret; | 684 | size_t data_size; |
685 | 685 | const void *data; | |
686 | n = sqlite3_step (stmt); | 686 | struct GNUNET_NAMESTORE_SignatureLocation loc; |
687 | switch (n) | 687 | const char *name; |
688 | |||
689 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->iterate_records, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
690 | (SQLITE_OK != sqlite3_bind_blob (plugin->iterate_records, 2, name_hash, sizeof (GNUNET_HashCode), SQLITE_STATIC)) ) | ||
688 | { | 691 | { |
689 | case SQLITE_ROW: | ||
690 | size = sqlite3_column_bytes (stmt, 5); | ||
691 | rowid = sqlite3_column_int64 (stmt, 6); | ||
692 | if (sqlite3_column_bytes (stmt, 4) != sizeof (GNUNET_HashCode)) | ||
693 | { | ||
694 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite", | ||
695 | _ | ||
696 | ("Invalid data in database. Trying to fix (by deletion).\n")); | ||
697 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
698 | LOG_SQLITE (plugin, | ||
699 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
700 | "sqlite3_reset"); | ||
701 | if (GNUNET_OK == delete_by_rowid (plugin, rowid)) | ||
702 | plugin->env->duc (plugin->env->cls, | ||
703 | -(size + GNUNET_NAMESTORE_ENTRY_OVERHEAD)); | ||
704 | break; | ||
705 | } | ||
706 | expiration.abs_value = sqlite3_column_int64 (stmt, 3); | ||
707 | #if DEBUG_SQLITE | ||
708 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", | ||
709 | "Found reply in database with expiration %llu\n", | ||
710 | (unsigned long long) expiration.abs_value); | ||
711 | #endif | ||
712 | ret = proc (proc_cls, sqlite3_column_blob (stmt, 4) /* key */ , | ||
713 | size, sqlite3_column_blob (stmt, 5) /* data */ , | ||
714 | sqlite3_column_int (stmt, 0) /* type */ , | ||
715 | sqlite3_column_int (stmt, 1) /* priority */ , | ||
716 | sqlite3_column_int (stmt, 2) /* anonymity */ , | ||
717 | expiration, rowid); | ||
718 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
719 | LOG_SQLITE (plugin, | ||
720 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
721 | "sqlite3_reset"); | ||
722 | if ((GNUNET_NO == ret) && (GNUNET_OK == delete_by_rowid (plugin, rowid))) | ||
723 | plugin->env->duc (plugin->env->cls, | ||
724 | -(size + GNUNET_NAMESTORE_ENTRY_OVERHEAD)); | ||
725 | return; | ||
726 | case SQLITE_DONE: | ||
727 | /* database must be empty */ | ||
728 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
729 | LOG_SQLITE (plugin, | ||
730 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
731 | "sqlite3_reset"); | ||
732 | break; | ||
733 | case SQLITE_BUSY: | ||
734 | case SQLITE_ERROR: | ||
735 | case SQLITE_MISUSE: | ||
736 | default: | ||
737 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 692 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
738 | "sqlite3_step"); | 693 | "sqlite3_bind_XXXX"); |
739 | if (SQLITE_OK != sqlite3_reset (stmt)) | 694 | if (SQLITE_OK != sqlite3_reset (plugin->iterate_records)) |
740 | LOG_SQLITE (plugin, | 695 | LOG_SQLITE (plugin, |
741 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 696 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
742 | "sqlite3_reset"); | 697 | "sqlite3_reset"); |
743 | GNUNET_break (0); | 698 | return GNUNET_SYSERR; |
744 | database_shutdown (plugin); | ||
745 | database_setup (plugin->env->cfg, plugin); | ||
746 | break; | ||
747 | } | ||
748 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
749 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
750 | "sqlite3_reset"); | ||
751 | proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); | ||
752 | |||
753 | |||
754 | |||
755 | |||
756 | |||
757 | const GNUNET_HashCode *key; | ||
758 | sqlite3_stmt *stmt; | ||
759 | int ret; | ||
760 | 699 | ||
761 | GNUNET_assert (proc != NULL); | ||
762 | if (sq_prepare (plugin->dbh, "SELECT hash FROM gn090", &stmt) != SQLITE_OK) | ||
763 | { | ||
764 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
765 | "sqlite_prepare"); | ||
766 | return; | ||
767 | } | 700 | } |
768 | while (SQLITE_ROW == (ret = sqlite3_step (stmt))) | 701 | ret = 0; |
702 | while (SQLITE_ROW == (ret = sqlite3_step (plugin->iterate_records))) | ||
769 | { | 703 | { |
770 | key = sqlite3_column_blob (stmt, 1); | 704 | ret++; |
771 | if (sizeof (GNUNET_HashCode) == sqlite3_column_bytes (stmt, 1)) | 705 | if (NULL == iter) |
772 | proc (proc_cls, key, 1); | 706 | continue; /* FIXME: just counting can be done more cheaply... */ |
707 | loc.revision = sqlite3_column_int (plugin->iterate_records, 1); | ||
708 | name = (const char*) sqlite3_column_text (plugin->iterate_records, 2); | ||
709 | record_type = sqlite3_column_int (plugin->iterate_records, 3); | ||
710 | loc.depth = sqlite3_column_int (plugin->iterate_records, 4); | ||
711 | loc.offset = sqlite3_column_int64 (plugin->iterate_records, 5); | ||
712 | expiration.abs_value = (uint64_t) sqlite3_column_int64 (plugin->iterate_records, 6); | ||
713 | flags = (enum GNUNET_NAMESTORE_RecordFlags) sqlite3_column_int (plugin->iterate_records, 7); | ||
714 | data = sqlite3_column_blob (plugin->iterate_records, 8); | ||
715 | data_size = sqlite3_column_bytes (plugin->iterate_records, 8); | ||
716 | iter (iter_cls, zone, | ||
717 | &loc, name, record_type, | ||
718 | expiration, flags, data_size, data); | ||
773 | } | 719 | } |
774 | if (SQLITE_DONE != ret) | 720 | if (SQLITE_DONE != ret) |
775 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | 721 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); |
776 | sqlite3_finalize (stmt); | 722 | sqlite3_finalize (plugin->iterate_records); |
777 | 723 | return ret; | |
778 | #endif | ||
779 | return 0; | ||
780 | } | 724 | } |
781 | 725 | ||
782 | 726 | ||
@@ -788,14 +732,63 @@ namestore_sqlite_iterate_records (void *cls, | |||
788 | * @param loc location of the node in the signature tree | 732 | * @param loc location of the node in the signature tree |
789 | * @param cb function to call with the result | 733 | * @param cb function to call with the result |
790 | * @param cb_cls closure for cont | 734 | * @param cb_cls closure for cont |
735 | * @return GNUNET_OK on success, GNUNET_NO if no node was found | ||
791 | */ | 736 | */ |
792 | static void | 737 | static int |
793 | namestore_sqlite_get_node (void *cls, | 738 | namestore_sqlite_get_node (void *cls, |
794 | const GNUNET_HashCode *zone, | 739 | const GNUNET_HashCode *zone, |
795 | const struct GNUNET_NAMESTORE_SignatureLocation *loc, | 740 | const struct GNUNET_NAMESTORE_SignatureLocation *loc, |
796 | GNUNET_NAMESTORE_NodeCallback cb, void *cb_cls) | 741 | GNUNET_NAMESTORE_NodeCallback cb, void *cb_cls) |
797 | { | 742 | { |
798 | // FIXME | 743 | struct Plugin *plugin = cls; |
744 | int ret; | ||
745 | size_t hashcodes_size; | ||
746 | const GNUNET_HashCode *hashcodes; | ||
747 | struct GNUNET_NAMESTORE_SignatureLocation ploc; | ||
748 | |||
749 | GNUNET_assert (NULL != cb); | ||
750 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->get_node, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
751 | (SQLITE_OK != sqlite3_bind_int (plugin->get_node, 2, loc->revision)) || | ||
752 | (SQLITE_OK != sqlite3_bind_int (plugin->get_node, 3, loc->depth)) || | ||
753 | (SQLITE_OK != sqlite3_bind_int64 (plugin->get_node, 4, loc->offset)) ) | ||
754 | { | ||
755 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
756 | "sqlite3_bind_XXXX"); | ||
757 | if (SQLITE_OK != sqlite3_reset (plugin->get_node)) | ||
758 | LOG_SQLITE (plugin, | ||
759 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
760 | "sqlite3_reset"); | ||
761 | return GNUNET_SYSERR; | ||
762 | |||
763 | } | ||
764 | ploc.revision = loc->revision; | ||
765 | ploc.depth = loc->depth + 1; | ||
766 | ret = GNUNET_NO; | ||
767 | if (SQLITE_ROW == (ret = sqlite3_step (plugin->get_node))) | ||
768 | { | ||
769 | ploc.offset = sqlite3_column_int64 (plugin->get_node, 1); | ||
770 | hashcodes = sqlite3_column_blob (plugin->get_node, 2); | ||
771 | hashcodes_size = sqlite3_column_bytes (plugin->get_node, 2); | ||
772 | if (0 != (hashcodes_size % sizeof (GNUNET_HashCode))) | ||
773 | { | ||
774 | GNUNET_break (0); | ||
775 | /* FIXME: delete bogus record? */ | ||
776 | } | ||
777 | else | ||
778 | { | ||
779 | ret = GNUNET_OK; | ||
780 | cb (cb_cls, | ||
781 | zone, | ||
782 | loc, | ||
783 | &ploc, | ||
784 | hashcodes_size / sizeof (GNUNET_HashCode), | ||
785 | hashcodes); | ||
786 | } | ||
787 | } | ||
788 | if (SQLITE_DONE != ret) | ||
789 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | ||
790 | sqlite3_finalize (plugin->get_node); | ||
791 | return ret; | ||
799 | } | 792 | } |
800 | 793 | ||
801 | 794 | ||
@@ -806,13 +799,111 @@ namestore_sqlite_get_node (void *cls, | |||
806 | * @param zone hash of public key of the zone | 799 | * @param zone hash of public key of the zone |
807 | * @param cb function to call with the result | 800 | * @param cb function to call with the result |
808 | * @param cb_cls closure for cont | 801 | * @param cb_cls closure for cont |
802 | * @return GNUNET_OK on success, GNUNET_NO if no node was found | ||
809 | */ | 803 | */ |
810 | static void | 804 | static int |
811 | namestore_sqlite_get_signature (void *cls, | 805 | namestore_sqlite_get_signature (void *cls, |
812 | const GNUNET_HashCode *zone, | 806 | const GNUNET_HashCode *zone, |
813 | GNUNET_NAMESTORE_SignatureCallback cb, void *cb_cls) | 807 | GNUNET_NAMESTORE_SignatureCallback cb, void *cb_cls) |
814 | { | 808 | { |
815 | // FIXME | 809 | struct Plugin *plugin = cls; |
810 | int ret; | ||
811 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; | ||
812 | struct GNUNET_NAMESTORE_SignatureLocation top_loc; | ||
813 | const struct GNUNET_CRYPTO_RsaSignature *zone_sig; | ||
814 | struct GNUNET_TIME_Absolute zone_time; | ||
815 | const GNUNET_HashCode *top_hash; | ||
816 | |||
817 | GNUNET_assert (NULL != cb); | ||
818 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->get_signature, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC))) | ||
819 | { | ||
820 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
821 | "sqlite3_bind_XXXX"); | ||
822 | if (SQLITE_OK != sqlite3_reset (plugin->get_signature)) | ||
823 | LOG_SQLITE (plugin, | ||
824 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
825 | "sqlite3_reset"); | ||
826 | return GNUNET_SYSERR; | ||
827 | } | ||
828 | ret = GNUNET_NO; | ||
829 | if (SQLITE_ROW == (ret = sqlite3_step (plugin->get_signature))) | ||
830 | { | ||
831 | top_loc.offset = 0; | ||
832 | top_loc.revision = sqlite3_column_int (plugin->get_signature, 1); | ||
833 | zone_time.abs_value = sqlite3_column_int64 (plugin->get_signature, 2); | ||
834 | top_hash = sqlite3_column_blob (plugin->get_signature, 3); | ||
835 | top_loc.depth = sqlite3_column_int (plugin->get_signature, 4); | ||
836 | zone_key = sqlite3_column_blob (plugin->get_signature, 5); | ||
837 | zone_sig = sqlite3_column_blob (plugin->get_signature, 6); | ||
838 | |||
839 | if ((sizeof (GNUNET_HashCode) != sqlite3_column_bytes (plugin->get_signature, 3)) || | ||
840 | (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != sqlite3_column_bytes (plugin->get_signature, 5)) || | ||
841 | (sizeof (struct GNUNET_CRYPTO_RsaSignature) != sqlite3_column_bytes (plugin->get_signature, 6))) | ||
842 | { | ||
843 | GNUNET_break (0); | ||
844 | /* FIXME: delete bogus record & full zone (!?) */ | ||
845 | } | ||
846 | else | ||
847 | { | ||
848 | ret = GNUNET_OK; | ||
849 | cb (cb_cls, | ||
850 | zone_key, | ||
851 | &top_loc, | ||
852 | zone_sig, | ||
853 | zone_time, | ||
854 | top_hash); | ||
855 | } | ||
856 | } | ||
857 | if (SQLITE_DONE != ret) | ||
858 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | ||
859 | sqlite3_finalize (plugin->get_signature); | ||
860 | return ret; | ||
861 | } | ||
862 | |||
863 | |||
864 | /** | ||
865 | * Run a SQL statement that takes only a 'zone' as the argument | ||
866 | * and returns nothing (deletes records). | ||
867 | * | ||
868 | * @param plugin our plugin | ||
869 | * @param zone zone argument to pass | ||
870 | * @param stmt prepared statement to run | ||
871 | */ | ||
872 | static void | ||
873 | run_delete_statement (struct Plugin *plugin, | ||
874 | const GNUNET_HashCode *zone, | ||
875 | sqlite3_stmt *stmt) | ||
876 | { | ||
877 | int n; | ||
878 | |||
879 | if (SQLITE_OK != sqlite3_bind_blob (plugin->delete_zone_records, 1, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) | ||
880 | { | ||
881 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
882 | "sqlite3_bind_XXXX"); | ||
883 | if (SQLITE_OK != sqlite3_reset (plugin->delete_zone_records)) | ||
884 | LOG_SQLITE (plugin, | ||
885 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
886 | "sqlite3_reset"); | ||
887 | return; | ||
888 | } | ||
889 | n = sqlite3_step (plugin->put_signature); | ||
890 | if (SQLITE_OK != sqlite3_reset (plugin->delete_zone_records)) | ||
891 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
892 | "sqlite3_reset"); | ||
893 | switch (n) | ||
894 | { | ||
895 | case SQLITE_DONE: | ||
896 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Zone records deleted\n"); | ||
897 | break; | ||
898 | case SQLITE_BUSY: | ||
899 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
900 | "sqlite3_step"); | ||
901 | break; | ||
902 | default: | ||
903 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
904 | "sqlite3_step"); | ||
905 | break; | ||
906 | } | ||
816 | } | 907 | } |
817 | 908 | ||
818 | 909 | ||
@@ -827,7 +918,11 @@ static void | |||
827 | namestore_sqlite_delete_zone (void *cls, | 918 | namestore_sqlite_delete_zone (void *cls, |
828 | const GNUNET_HashCode *zone) | 919 | const GNUNET_HashCode *zone) |
829 | { | 920 | { |
830 | // FIXME | 921 | struct Plugin *plugin = cls; |
922 | |||
923 | run_delete_statement (plugin, zone, plugin->delete_zone_records); | ||
924 | run_delete_statement (plugin, zone, plugin->delete_zone_nodes); | ||
925 | run_delete_statement (plugin, zone, plugin->delete_zone_signatures); | ||
831 | } | 926 | } |
832 | 927 | ||
833 | 928 | ||