Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: chrome/browser/sync_file_system/drive_metadata_store.cc

Issue 15951007: SyncFS: Factor out DriveMetadataDB migration functions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win test Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync_file_system/drive_metadata_store.h" 5 #include "chrome/browser/sync_file_system/drive_metadata_store.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 30 matching lines...) Expand all
41 41
42 namespace { 42 namespace {
43 43
44 const char* const kServiceName = DriveFileSyncService::kServiceName; 44 const char* const kServiceName = DriveFileSyncService::kServiceName;
45 const char kDatabaseVersionKey[] = "VERSION"; 45 const char kDatabaseVersionKey[] = "VERSION";
46 const int64 kCurrentDatabaseVersion = 2; 46 const int64 kCurrentDatabaseVersion = 2;
47 const char kChangeStampKey[] = "CHANGE_STAMP"; 47 const char kChangeStampKey[] = "CHANGE_STAMP";
48 const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR"; 48 const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR";
49 const char kDriveMetadataKeyPrefix[] = "METADATA: "; 49 const char kDriveMetadataKeyPrefix[] = "METADATA: ";
50 const char kMetadataKeySeparator = ' '; 50 const char kMetadataKeySeparator = ' ';
51 const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
52 const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: "; 51 const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: ";
53 const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: "; 52 const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: ";
54 const size_t kDriveMetadataKeyPrefixLength = arraysize(kDriveMetadataKeyPrefix); 53 const size_t kDriveMetadataKeyPrefixLength = arraysize(kDriveMetadataKeyPrefix);
55 54
56 const base::FilePath::CharType kV0FormatPathPrefix[] = 55 std::string RemovePrefix(const std::string& str, const std::string& prefix) {
57 FILE_PATH_LITERAL("drive/"); 56 if (StartsWithASCII(str, prefix, true))
58 57 return str.substr(prefix.size());
59 bool ParseV0FormatFileSystemURLString(const GURL& url, 58 return str;
60 GURL* origin,
61 base::FilePath* path) {
62 fileapi::FileSystemType mount_type;
63 base::FilePath virtual_path;
64
65 if (!fileapi::FileSystemURL::ParseFileSystemSchemeURL(
66 url, origin, &mount_type, &virtual_path) ||
67 mount_type != fileapi::kFileSystemTypeExternal) {
68 NOTREACHED() << "Failed to parse filesystem scheme URL";
69 return false;
70 }
71
72 base::FilePath::StringType prefix =
73 base::FilePath(kV0FormatPathPrefix).NormalizePathSeparators().value();
74 if (virtual_path.value().substr(0, prefix.size()) != prefix)
75 return false;
76
77 *path = base::FilePath(virtual_path.value().substr(prefix.size()));
78 return true;
79 } 59 }
80 60
81 std::string FileSystemURLToMetadataKey(const FileSystemURL& url) { 61 std::string FileSystemURLToMetadataKey(const FileSystemURL& url) {
82 return kDriveMetadataKeyPrefix + url.origin().spec() + 62 return kDriveMetadataKeyPrefix + url.origin().spec() +
83 kMetadataKeySeparator + url.path().AsUTF8Unsafe(); 63 kMetadataKeySeparator + url.path().AsUTF8Unsafe();
84 } 64 }
85 65
86 void MetadataKeyToOriginAndPath(const std::string& metadata_key, 66 void MetadataKeyToOriginAndPath(const std::string& metadata_key,
87 GURL* origin, 67 GURL* origin,
88 base::FilePath* path) { 68 base::FilePath* path) {
89 std::string key_body(metadata_key.begin() + kDriveMetadataKeyPrefixLength - 1, 69 std::string key_body(RemovePrefix(metadata_key, kDriveMetadataKeyPrefix));
90 metadata_key.end());
91 size_t separator_position = key_body.find(kMetadataKeySeparator); 70 size_t separator_position = key_body.find(kMetadataKeySeparator);
92 *origin = GURL(key_body.substr(0, separator_position)); 71 *origin = GURL(key_body.substr(0, separator_position));
93 *path = base::FilePath::FromUTF8Unsafe( 72 *path = base::FilePath::FromUTF8Unsafe(
94 key_body.substr(separator_position + 1)); 73 key_body.substr(separator_position + 1));
95 } 74 }
96 75
97 bool UpdateResourceIdMap(ResourceIdByOrigin* map, 76 bool UpdateResourceIdMap(ResourceIdByOrigin* map,
98 OriginByResourceId* reverse_map, 77 OriginByResourceId* reverse_map,
99 const GURL& origin, 78 const GURL& origin,
100 const std::string& resource_id) { 79 const std::string& resource_id) {
101 ResourceIdByOrigin::iterator found = map->find(origin); 80 ResourceIdByOrigin::iterator found = map->find(origin);
102 if (found == map->end()) 81 if (found == map->end())
103 return false; 82 return false;
104 reverse_map->erase(found->second); 83 reverse_map->erase(found->second);
105 reverse_map->insert(std::make_pair(resource_id, origin)); 84 reverse_map->insert(std::make_pair(resource_id, origin));
106 85
107 found->second = resource_id; 86 found->second = resource_id;
108 return true; 87 return true;
109 } 88 }
110 89
111 std::string RemovePrefix(const std::string& str, const std::string& prefix) {
112 if (StartsWithASCII(str, prefix, true))
113 return str.substr(prefix.size());
114 return str;
115 }
116
117 } // namespace 90 } // namespace
118 91
119 class DriveMetadataDB { 92 class DriveMetadataDB {
120 public: 93 public:
121 enum OriginSyncType { 94 enum OriginSyncType {
122 INCREMENTAL_SYNC_ORIGIN, 95 INCREMENTAL_SYNC_ORIGIN,
123 DISABLED_ORIGIN 96 DISABLED_ORIGIN
124 }; 97 };
125 98
126 typedef DriveMetadataStore::MetadataMap MetadataMap; 99 typedef DriveMetadataStore::MetadataMap MetadataMap;
127 100
128 DriveMetadataDB(const base::FilePath& base_dir, 101 DriveMetadataDB(const base::FilePath& base_dir,
129 base::SequencedTaskRunner* task_runner); 102 base::SequencedTaskRunner* task_runner);
130 ~DriveMetadataDB(); 103 ~DriveMetadataDB();
131 104
132 SyncStatusCode Initialize(bool* created); 105 SyncStatusCode Initialize(bool* created);
133 SyncStatusCode ReadContents(DriveMetadataDBContents* contents); 106 SyncStatusCode ReadContents(DriveMetadataDBContents* contents);
134 107
135 SyncStatusCode MigrateDatabaseIfNeeded(); 108 SyncStatusCode MigrateDatabaseIfNeeded();
136 SyncStatusCode MigrateFromVersion0To1Database();
137 109
138 SyncStatusCode SetLargestChangestamp(int64 largest_changestamp); 110 SyncStatusCode SetLargestChangestamp(int64 largest_changestamp);
139 SyncStatusCode SetSyncRootDirectory(const std::string& resource_id); 111 SyncStatusCode SetSyncRootDirectory(const std::string& resource_id);
140 SyncStatusCode GetSyncRootDirectory(std::string* resource_id); 112 SyncStatusCode GetSyncRootDirectory(std::string* resource_id);
141 SyncStatusCode SetOriginRootDirectory(const GURL& origin, 113 SyncStatusCode SetOriginRootDirectory(const GURL& origin,
142 OriginSyncType sync_type, 114 OriginSyncType sync_type,
143 const std::string& resource_id); 115 const std::string& resource_id);
144 SyncStatusCode UpdateEntry(const FileSystemURL& url, 116 SyncStatusCode UpdateEntry(const FileSystemURL& url,
145 DriveMetadata metadata); 117 DriveMetadata metadata);
146 SyncStatusCode DeleteEntry(const FileSystemURL& url); 118 SyncStatusCode DeleteEntry(const FileSystemURL& url);
147 119
148 // TODO(calvinlo): consolidate these state transition functions for sync 120 // TODO(calvinlo): consolidate these state transition functions for sync
149 // origins like "UpdateOrigin(GURL, SyncStatusEnum)". And manage origins in 121 // origins like "UpdateOrigin(GURL, SyncStatusEnum)". And manage origins in
150 // just one map like "Map<SyncStatusEnum, ResourceIDMap>". 122 // just one map like "Map<SyncStatusEnum, ResourceIDMap>".
151 // http://crbug.com/211600 123 // http://crbug.com/211600
152 SyncStatusCode UpdateOriginAsBatchSync(const GURL& origin,
153 const std::string& resource_id);
154 SyncStatusCode UpdateOriginAsIncrementalSync(const GURL& origin, 124 SyncStatusCode UpdateOriginAsIncrementalSync(const GURL& origin,
155 const std::string& resource_id); 125 const std::string& resource_id);
156 SyncStatusCode EnableOrigin(const GURL& origin, 126 SyncStatusCode EnableOrigin(const GURL& origin,
157 const std::string& resource_id); 127 const std::string& resource_id);
158 SyncStatusCode DisableOrigin(const GURL& origin, 128 SyncStatusCode DisableOrigin(const GURL& origin,
159 const std::string& resource_id); 129 const std::string& resource_id);
160 SyncStatusCode RemoveOrigin(const GURL& origin); 130 SyncStatusCode RemoveOrigin(const GURL& origin);
161 131
162 SyncStatusCode GetOrigins(ResourceIdByOrigin* incremental_sync_origins, 132 SyncStatusCode GetOrigins(ResourceIdByOrigin* incremental_sync_origins,
163 ResourceIdByOrigin* disabled_origins); 133 ResourceIdByOrigin* disabled_origins);
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 status = db->Put(leveldb::WriteOptions(), 743 status = db->Put(leveldb::WriteOptions(),
774 kDatabaseVersionKey, 744 kDatabaseVersionKey,
775 base::Int64ToString(kCurrentDatabaseVersion)); 745 base::Int64ToString(kCurrentDatabaseVersion));
776 if (!status.ok()) { 746 if (!status.ok()) {
777 delete db; 747 delete db;
778 return LevelDBStatusToSyncStatusCode(status); 748 return LevelDBStatusToSyncStatusCode(status);
779 } 749 }
780 } 750 }
781 751
782 db_.reset(db); 752 db_.reset(db);
783
784
785 // Deprecate legacy batch sync origin entries that are no longer needed.
786 leveldb::WriteBatch batch;
787 scoped_ptr<leveldb::Iterator> batch_origin_itr(
788 db_->NewIterator(leveldb::ReadOptions()));
789 for (batch_origin_itr->Seek(kDriveBatchSyncOriginKeyPrefix);
790 batch_origin_itr->Valid();
791 batch_origin_itr->Next()) {
792 std::string key = batch_origin_itr->key().ToString();
793 if (!StartsWithASCII(key, kDriveBatchSyncOriginKeyPrefix, true))
794 break;
795
796 batch.Delete(key);
797 }
798 status = db_->Write(leveldb::WriteOptions(), &batch);
799 return LevelDBStatusToSyncStatusCode(status); 753 return LevelDBStatusToSyncStatusCode(status);
800 } 754 }
801 755
802 SyncStatusCode DriveMetadataDB::ReadContents( 756 SyncStatusCode DriveMetadataDB::ReadContents(
803 DriveMetadataDBContents* contents) { 757 DriveMetadataDBContents* contents) {
804 DCHECK(CalledOnValidThread()); 758 DCHECK(CalledOnValidThread());
805 DCHECK(db_.get()); 759 DCHECK(db_.get());
806 DCHECK(contents); 760 DCHECK(contents);
807 761
808 contents->largest_changestamp = 0; 762 contents->largest_changestamp = 0;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 if (!success) 815 if (!success)
862 return SYNC_DATABASE_ERROR_FAILED; 816 return SYNC_DATABASE_ERROR_FAILED;
863 if (database_version > kCurrentDatabaseVersion) 817 if (database_version > kCurrentDatabaseVersion)
864 return SYNC_DATABASE_ERROR_FAILED; 818 return SYNC_DATABASE_ERROR_FAILED;
865 if (database_version == kCurrentDatabaseVersion) 819 if (database_version == kCurrentDatabaseVersion)
866 return SYNC_STATUS_OK; 820 return SYNC_STATUS_OK;
867 } 821 }
868 822
869 switch (database_version) { 823 switch (database_version) {
870 case 0: 824 case 0:
871 MigrateFromVersion0To1Database(); 825 drive::MigrateDatabaseFromV0ToV1(db_.get());
872 // fall-through 826 // fall-through
873 case 1: 827 case 1:
874 drive::MigrateDatabaseFromV1ToV2(db_.get()); 828 drive::MigrateDatabaseFromV1ToV2(db_.get());
875 return SYNC_STATUS_OK; 829 return SYNC_STATUS_OK;
876 } 830 }
877 return SYNC_DATABASE_ERROR_FAILED; 831 return SYNC_DATABASE_ERROR_FAILED;
878 } 832 }
879 833
880 SyncStatusCode DriveMetadataDB::MigrateFromVersion0To1Database() {
881 // Version 0 database format:
882 // key: "CHANGE_STAMP"
883 // value: <Largest Changestamp>
884 //
885 // key: "SYNC_ROOT_DIR"
886 // value: <Resource ID of the sync root directory>
887 //
888 // key: "METADATA: " +
889 // <FileSystemURL serialized by SerializeSyncableFileSystemURL>
890 // value: <Serialized DriveMetadata>
891 //
892 // key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin>
893 // value: <Resource ID of the drive directory for the origin>
894 //
895 // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin>
896 // value: <Resource ID of the drive directory for the origin>
897 //
898 // Version 1 database format (changed keys/fields are marked with '*'):
899 // * key: "VERSION" (new)
900 // * value: 1
901 //
902 // key: "CHANGE_STAMP"
903 // value: <Largest Changestamp>
904 //
905 // key: "SYNC_ROOT_DIR"
906 // value: <Resource ID of the sync root directory>
907 //
908 // * key: "METADATA: " + <Origin and URL> (changed)
909 // * value: <Serialized DriveMetadata>
910 //
911 // key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin>
912 // value: <Resource ID of the drive directory for the origin>
913 //
914 // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin>
915 // value: <Resource ID of the drive directory for the origin>
916 //
917 // key: "DISABLED_ORIGIN: " + <URL string of a disabled origin>
918 // value: <Resource ID of the drive directory for the origin>
919
920 leveldb::WriteBatch write_batch;
921 write_batch.Put(kDatabaseVersionKey, "1");
922
923 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
924 for (itr->Seek(kDriveMetadataKeyPrefix); itr->Valid(); itr->Next()) {
925 std::string key = itr->key().ToString();
926 if (!StartsWithASCII(key, kDriveMetadataKeyPrefix, true))
927 break;
928 std::string serialized_url(
929 key.begin() + kDriveMetadataKeyPrefixLength - 1, key.end());
930
931 GURL origin;
932 base::FilePath path;
933 bool success = ParseV0FormatFileSystemURLString(
934 GURL(serialized_url), &origin, &path);
935 DCHECK(success) << serialized_url;
936 std::string new_key = kDriveMetadataKeyPrefix + origin.spec() +
937 kMetadataKeySeparator + path.AsUTF8Unsafe();
938
939 write_batch.Put(new_key, itr->value());
940 write_batch.Delete(key);
941 }
942 return LevelDBStatusToSyncStatusCode(
943 db_->Write(leveldb::WriteOptions(), &write_batch));
944 }
945
946 SyncStatusCode DriveMetadataDB::SetLargestChangestamp( 834 SyncStatusCode DriveMetadataDB::SetLargestChangestamp(
947 int64 largest_changestamp) { 835 int64 largest_changestamp) {
948 DCHECK(CalledOnValidThread()); 836 DCHECK(CalledOnValidThread());
949 DCHECK(db_.get()); 837 DCHECK(db_.get());
950 838
951 leveldb::Status status = db_->Put( 839 leveldb::Status status = db_->Put(
952 leveldb::WriteOptions(), 840 leveldb::WriteOptions(),
953 kChangeStampKey, base::Int64ToString(largest_changestamp)); 841 kChangeStampKey, base::Int64ToString(largest_changestamp));
954 return LevelDBStatusToSyncStatusCode(status); 842 return LevelDBStatusToSyncStatusCode(status);
955 } 843 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 1038
1151 bool result = disabled_origins->insert( 1039 bool result = disabled_origins->insert(
1152 std::make_pair(origin, origin_resource_id)).second; 1040 std::make_pair(origin, origin_resource_id)).second;
1153 DCHECK(result); 1041 DCHECK(result);
1154 } 1042 }
1155 1043
1156 return SYNC_STATUS_OK; 1044 return SYNC_STATUS_OK;
1157 } 1045 }
1158 1046
1159 } // namespace sync_file_system 1047 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698