Index: chrome/browser/sync_file_system/drive/metadata_db_migration_util.cc |
diff --git a/chrome/browser/sync_file_system/drive/metadata_db_migration_util.cc b/chrome/browser/sync_file_system/drive/metadata_db_migration_util.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f89246baf00bcea5f39bf8e873441a8131695e8a |
--- /dev/null |
+++ b/chrome/browser/sync_file_system/drive/metadata_db_migration_util.cc |
@@ -0,0 +1,154 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/sync_file_system/drive/metadata_db_migration_util.h" |
+ |
+#include "base/files/file_path.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/string_util.h" |
+#include "googleurl/src/gurl.h" |
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
+ |
+namespace sync_file_system { |
+namespace drive { |
+ |
+namespace { |
+const char kWapiFileIdPrefix[] = "file:"; |
+const char kWapiFolderIdPrefix[] = "folder:"; |
+} |
+ |
+std::string AddWapiFilePrefix(const std::string& resource_id) { |
+ if (resource_id.empty() || |
+ StartsWithASCII(resource_id, kWapiFileIdPrefix, true) || |
+ StartsWithASCII(resource_id, kWapiFolderIdPrefix, true)) |
kinuko
2013/05/28 15:09:20
Is this ok? Does this mean we get 'folder:xxxx' r
nhiroki
2013/05/29 04:10:18
Yes, I mean it. Do you prefer to return empty stri
kinuko
2013/05/29 04:44:36
When does this happen? If your answer to my first
nhiroki
2013/05/29 06:31:03
For example:
a) metadata.type() == TYPE_FILE, but
kinuko
2013/05/29 06:41:13
Thanks for the details.
If it never happens or it'
nhiroki
2013/05/29 07:49:16
Sorry, empty resource id is valid here since to-be
|
+ return resource_id; |
+ return kWapiFileIdPrefix + resource_id; |
+} |
+ |
+std::string AddWapiFolderPrefix(const std::string& resource_id) { |
+ if (resource_id.empty() || |
+ StartsWithASCII(resource_id, kWapiFileIdPrefix, true) || |
+ StartsWithASCII(resource_id, kWapiFolderIdPrefix, true)) |
+ return resource_id; |
+ return kWapiFolderIdPrefix + resource_id; |
+} |
+ |
+std::string AddWapiIdPrefix(const std::string& resource_id, |
+ DriveMetadata_ResourceType type) { |
+ switch (type) { |
+ case DriveMetadata_ResourceType_RESOURCE_TYPE_FILE: |
+ return AddWapiFilePrefix(resource_id); |
+ case DriveMetadata_ResourceType_RESOURCE_TYPE_FOLDER: |
+ return AddWapiFolderPrefix(resource_id); |
+ default: |
+ NOTREACHED(); |
+ return resource_id; |
+ } |
+} |
+ |
+std::string RemoveWapiIdPrefix(const std::string& resource_id) { |
+ if (StartsWithASCII(resource_id, kWapiFileIdPrefix, true)) |
+ return std::string(resource_id.begin() + arraysize(kWapiFileIdPrefix) - 1, |
+ resource_id.end()); |
+ if (StartsWithASCII(resource_id, kWapiFolderIdPrefix, true)) |
+ return std::string(resource_id.begin() + arraysize(kWapiFolderIdPrefix) - 1, |
+ resource_id.end()); |
kinuko
2013/05/28 15:09:20
nit: please put { } if body spans multiple line (f
nhiroki
2013/05/29 04:10:18
Done.
|
+ return resource_id; |
+} |
+ |
+SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db) { |
+ // Strips prefix of WAPI resource ID. |
+ // (i.e. "file:xxxx" => "xxxx", "folder:yyyy" => "yyyy") |
+ // |
+ // Version 2 database format (changed keys/fields are marked with '*'): |
+ // key: "VERSION" |
+ // * value: 2 |
+ // |
+ // key: "CHANGE_STAMP" |
+ // value: <Largest Changestamp> |
+ // |
+ // key: "SYNC_ROOT_DIR" |
+ // * value: <Resource ID of the sync root directory> (striped) |
+ // |
+ // key: "METADATA: " + <Origin and URL> |
+ // * value: <Serialized DriveMetadata> (striped) |
+ // |
+ // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin> |
+ // * value: <Resource ID of the drive directory for the origin> (striped) |
+ // |
+ // key: "DISABLED_ORIGIN: " + <URL string of a disabled origin> |
+ // * value: <Resource ID of the drive directory for the origin> (striped) |
+ |
+ const char kDatabaseVersionKey[] = "VERSION"; |
+ const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR"; |
+ const char kDriveMetadataKeyPrefix[] = "METADATA: "; |
+ const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: "; |
+ const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: "; |
+ |
+ leveldb::WriteBatch write_batch; |
+ write_batch.Put(kDatabaseVersionKey, "2"); |
+ |
+ // Strip resource id for the sync root directory. |
+ std::string sync_root_resource_id; |
+ leveldb::Status status = db->Get( |
+ leveldb::ReadOptions(), kSyncRootDirectoryKey, &sync_root_resource_id); |
+ write_batch.Put(kSyncRootDirectoryKey, |
+ RemoveWapiIdPrefix(sync_root_resource_id)); |
+ |
+ // Strip resource ids in the drive metadata. |
+ scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); |
+ for (itr->Seek(kDriveMetadataKeyPrefix); itr->Valid(); itr->Next()) { |
+ std::string key = itr->key().ToString(); |
+ if (!StartsWithASCII(key, kDriveMetadataKeyPrefix, true)) |
+ break; |
+ |
+ DriveMetadata metadata; |
+ bool success = metadata.ParseFromString(itr->value().ToString()); |
+ DCHECK(success); |
+ |
+ metadata.set_resource_id(RemoveWapiIdPrefix(metadata.resource_id())); |
+ std::string metadata_string; |
+ metadata.SerializeToString(&metadata_string); |
+ |
+ write_batch.Put(key, metadata_string); |
+ } |
+ |
+ // Strip resource ids of the incremental sync origins. |
+ for (itr->Seek(kDriveIncrementalSyncOriginKeyPrefix); |
+ itr->Valid(); itr->Next()) { |
+ std::string key = itr->key().ToString(); |
+ if (!StartsWithASCII(key, kDriveIncrementalSyncOriginKeyPrefix, true)) |
+ break; |
+ |
+ GURL origin(std::string( |
+ key.begin() + arraysize(kDriveIncrementalSyncOriginKeyPrefix) - 1, |
+ key.end())); |
+ DCHECK(origin.is_valid()); |
+ |
+ write_batch.Put(kDriveIncrementalSyncOriginKeyPrefix + origin.spec(), |
+ RemoveWapiIdPrefix(itr->value().ToString())); |
+ } |
+ |
+ // Strip resource ids of the disabled sync origins. |
+ for (itr->Seek(kDriveDisabledOriginKeyPrefix); |
+ itr->Valid(); itr->Next()) { |
+ std::string key = itr->key().ToString(); |
+ if (!StartsWithASCII(key, kDriveDisabledOriginKeyPrefix, true)) |
+ break; |
+ |
+ GURL origin(std::string( |
+ key.begin() + arraysize(kDriveDisabledOriginKeyPrefix) - 1, |
+ key.end())); |
+ DCHECK(origin.is_valid()); |
+ |
+ write_batch.Put(kDriveDisabledOriginKeyPrefix + origin.spec(), |
+ RemoveWapiIdPrefix(itr->value().ToString())); |
+ } |
+ |
+ return LevelDBStatusToSyncStatusCode( |
+ db->Write(leveldb::WriteOptions(), &write_batch)); |
+} |
+ |
+} // namespace drive |
+} // namespace sync_file_system |