summaryrefslogtreecommitdiff
path: root/src/namestore/plugin_namestore_sqlite.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-02-21 20:41:31 +0000
committerChristian Grothoff <christian@grothoff.org>2012-02-21 20:41:31 +0000
commit6c1b5f3149788006601996ef10cd030fe3aa6f02 (patch)
treeaf8a9b075fa96354bb921f75b925b8f3658466c0 /src/namestore/plugin_namestore_sqlite.c
parent7590a212861cd5cafeceba3c20c1e6c9528b880d (diff)
downloadgnunet-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.c285
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 */
792static void 737static int
793namestore_sqlite_get_node (void *cls, 738namestore_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 */
810static void 804static int
811namestore_sqlite_get_signature (void *cls, 805namestore_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 */
872static void
873run_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
827namestore_sqlite_delete_zone (void *cls, 918namestore_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