Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / drive_backend / metadata_db_migration_util.cc
blobd7dda5396d931ee9e58f3034485e26881cd11391
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util.h"
7 #include "base/files/file_path.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_util.h"
10 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
11 #include "url/gurl.h"
12 #include "webkit/browser/fileapi/file_system_url.h"
13 #include "webkit/common/fileapi/file_system_types.h"
15 namespace sync_file_system {
16 namespace drive_backend {
18 namespace {
20 const base::FilePath::CharType kV0FormatPathPrefix[] =
21 FILE_PATH_LITERAL("drive/");
22 const char kWapiFileIdPrefix[] = "file:";
23 const char kWapiFolderIdPrefix[] = "folder:";
25 std::string RemovePrefix(const std::string& str, const std::string& prefix) {
26 if (StartsWithASCII(str, prefix, true))
27 return std::string(str.begin() + prefix.size(), str.end());
28 return str;
31 } // namespace
33 bool ParseV0FormatFileSystemURL(const GURL& url,
34 GURL* origin,
35 base::FilePath* path) {
36 fileapi::FileSystemType mount_type;
37 base::FilePath virtual_path;
39 if (!fileapi::FileSystemURL::ParseFileSystemSchemeURL(
40 url, origin, &mount_type, &virtual_path) ||
41 mount_type != fileapi::kFileSystemTypeExternal) {
42 NOTREACHED() << "Failed to parse filesystem scheme URL " << url.spec();
43 return false;
46 base::FilePath::StringType prefix =
47 base::FilePath(kV0FormatPathPrefix).NormalizePathSeparators().value();
48 if (virtual_path.value().substr(0, prefix.size()) != prefix)
49 return false;
51 *path = base::FilePath(virtual_path.value().substr(prefix.size()));
52 return true;
55 std::string AddWapiFilePrefix(const std::string& resource_id) {
56 DCHECK(!StartsWithASCII(resource_id, kWapiFileIdPrefix, true));
57 DCHECK(!StartsWithASCII(resource_id, kWapiFolderIdPrefix, true));
59 if (resource_id.empty() ||
60 StartsWithASCII(resource_id, kWapiFileIdPrefix, true) ||
61 StartsWithASCII(resource_id, kWapiFolderIdPrefix, true))
62 return resource_id;
63 return kWapiFileIdPrefix + resource_id;
66 std::string AddWapiFolderPrefix(const std::string& resource_id) {
67 DCHECK(!StartsWithASCII(resource_id, kWapiFileIdPrefix, true));
68 DCHECK(!StartsWithASCII(resource_id, kWapiFolderIdPrefix, true));
70 if (resource_id.empty() ||
71 StartsWithASCII(resource_id, kWapiFileIdPrefix, true) ||
72 StartsWithASCII(resource_id, kWapiFolderIdPrefix, true))
73 return resource_id;
74 return kWapiFolderIdPrefix + resource_id;
77 std::string AddWapiIdPrefix(const std::string& resource_id,
78 DriveMetadata_ResourceType type) {
79 switch (type) {
80 case DriveMetadata_ResourceType_RESOURCE_TYPE_FILE:
81 return AddWapiFilePrefix(resource_id);
82 case DriveMetadata_ResourceType_RESOURCE_TYPE_FOLDER:
83 return AddWapiFolderPrefix(resource_id);
85 NOTREACHED();
86 return resource_id;
89 std::string RemoveWapiIdPrefix(const std::string& resource_id) {
90 if (StartsWithASCII(resource_id, kWapiFileIdPrefix, true))
91 return RemovePrefix(resource_id, kWapiFileIdPrefix);
92 if (StartsWithASCII(resource_id, kWapiFolderIdPrefix, true))
93 return RemovePrefix(resource_id, kWapiFolderIdPrefix);
94 return resource_id;
97 SyncStatusCode MigrateDatabaseFromV0ToV1(leveldb::DB* db) {
98 // Version 0 database format:
99 // key: "CHANGE_STAMP"
100 // value: <Largest Changestamp>
102 // key: "SYNC_ROOT_DIR"
103 // value: <Resource ID of the sync root directory>
105 // key: "METADATA: " +
106 // <FileSystemURL serialized by SerializeSyncableFileSystemURL>
107 // value: <Serialized DriveMetadata>
109 // key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin>
110 // value: <Resource ID of the drive directory for the origin>
112 // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin>
113 // value: <Resource ID of the drive directory for the origin>
115 // Version 1 database format (changed keys/fields are marked with '*'):
116 // * key: "VERSION" (new)
117 // * value: 1
119 // key: "CHANGE_STAMP"
120 // value: <Largest Changestamp>
122 // key: "SYNC_ROOT_DIR"
123 // value: <Resource ID of the sync root directory>
125 // * key: "METADATA: " + <Origin and URL> (changed)
126 // * value: <Serialized DriveMetadata>
128 // key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin>
129 // value: <Resource ID of the drive directory for the origin>
131 // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin>
132 // value: <Resource ID of the drive directory for the origin>
134 // key: "DISABLED_ORIGIN: " + <URL string of a disabled origin>
135 // value: <Resource ID of the drive directory for the origin>
137 const char kDatabaseVersionKey[] = "VERSION";
138 const char kDriveMetadataKeyPrefix[] = "METADATA: ";
139 const char kMetadataKeySeparator = ' ';
141 leveldb::WriteBatch write_batch;
142 write_batch.Put(kDatabaseVersionKey, "1");
144 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
145 for (itr->Seek(kDriveMetadataKeyPrefix); itr->Valid(); itr->Next()) {
146 std::string key = itr->key().ToString();
147 if (!StartsWithASCII(key, kDriveMetadataKeyPrefix, true))
148 break;
149 std::string serialized_url(RemovePrefix(key, kDriveMetadataKeyPrefix));
151 GURL origin;
152 base::FilePath path;
153 bool success = ParseV0FormatFileSystemURL(
154 GURL(serialized_url), &origin, &path);
155 DCHECK(success) << serialized_url;
156 std::string new_key = kDriveMetadataKeyPrefix + origin.spec() +
157 kMetadataKeySeparator + path.AsUTF8Unsafe();
159 write_batch.Put(new_key, itr->value());
160 write_batch.Delete(key);
163 return LevelDBStatusToSyncStatusCode(
164 db->Write(leveldb::WriteOptions(), &write_batch));
167 SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db) {
168 // Strips prefix of WAPI resource ID, and discards batch sync origins.
169 // (i.e. "file:xxxx" => "xxxx", "folder:yyyy" => "yyyy")
171 // Version 2 database format (changed keys/fields are marked with '*'):
172 // key: "VERSION"
173 // * value: 2
175 // key: "CHANGE_STAMP"
176 // value: <Largest Changestamp>
178 // key: "SYNC_ROOT_DIR"
179 // * value: <Resource ID of the sync root directory> (striped)
181 // key: "METADATA: " + <Origin and URL>
182 // * value: <Serialized DriveMetadata> (stripped)
184 // * key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin> (deleted)
185 // * value: <Resource ID of the drive directory for the origin> (deleted)
187 // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin>
188 // * value: <Resource ID of the drive directory for the origin> (stripped)
190 // key: "DISABLED_ORIGIN: " + <URL string of a disabled origin>
191 // * value: <Resource ID of the drive directory for the origin> (stripped)
193 const char kDatabaseVersionKey[] = "VERSION";
194 const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR";
195 const char kDriveMetadataKeyPrefix[] = "METADATA: ";
196 const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
197 const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: ";
198 const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: ";
200 leveldb::WriteBatch write_batch;
201 write_batch.Put(kDatabaseVersionKey, "2");
203 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
204 for (itr->SeekToFirst(); itr->Valid(); itr->Next()) {
205 std::string key = itr->key().ToString();
207 // Strip resource id for the sync root directory.
208 if (StartsWithASCII(key, kSyncRootDirectoryKey, true)) {
209 write_batch.Put(key, RemoveWapiIdPrefix(itr->value().ToString()));
210 continue;
213 // Strip resource ids in the drive metadata.
214 if (StartsWithASCII(key, kDriveMetadataKeyPrefix, true)) {
215 DriveMetadata metadata;
216 bool success = metadata.ParseFromString(itr->value().ToString());
217 DCHECK(success);
219 metadata.set_resource_id(RemoveWapiIdPrefix(metadata.resource_id()));
220 std::string metadata_string;
221 metadata.SerializeToString(&metadata_string);
223 write_batch.Put(key, metadata_string);
224 continue;
227 // Deprecate legacy batch sync origin entries that are no longer needed.
228 if (StartsWithASCII(key, kDriveBatchSyncOriginKeyPrefix, true)) {
229 write_batch.Delete(key);
230 continue;
233 // Strip resource ids of the incremental sync origins.
234 if (StartsWithASCII(key, kDriveIncrementalSyncOriginKeyPrefix, true)) {
235 write_batch.Put(key, RemoveWapiIdPrefix(itr->value().ToString()));
236 continue;
239 // Strip resource ids of the disabled sync origins.
240 if (StartsWithASCII(key, kDriveDisabledOriginKeyPrefix, true)) {
241 write_batch.Put(key, RemoveWapiIdPrefix(itr->value().ToString()));
242 continue;
246 return LevelDBStatusToSyncStatusCode(
247 db->Write(leveldb::WriteOptions(), &write_batch));
250 } // namespace drive_backend
251 } // namespace sync_file_system