Index: chrome/browser/sync_file_system/drive_metadata_store.cc |
diff --git a/chrome/browser/sync_file_system/drive_metadata_store.cc b/chrome/browser/sync_file_system/drive_metadata_store.cc |
index 9c3519abf83b69c409e72c61dab586edc0a1a46b..978a23e74dfa6b17102885c7621d2cc447a540bd 100644 |
--- a/chrome/browser/sync_file_system/drive_metadata_store.cc |
+++ b/chrome/browser/sync_file_system/drive_metadata_store.cc |
@@ -18,6 +18,7 @@ |
#include "base/strings/string_number_conversions.h" |
#include "base/task_runner_util.h" |
#include "chrome/browser/sync_file_system/drive_file_sync_service.h" |
+#include "chrome/browser/sync_file_system/drive_file_sync_util.h" |
#include "chrome/browser/sync_file_system/sync_file_system.pb.h" |
#include "googleurl/src/gurl.h" |
#include "third_party/leveldatabase/src/include/leveldb/db.h" |
@@ -40,7 +41,7 @@ namespace { |
const char* const kServiceName = DriveFileSyncService::kServiceName; |
const char kDatabaseVersionKey[] = "VERSION"; |
-const int64 kCurrentDatabaseVersion = 1; |
+const int64 kCurrentDatabaseVersion = 2; |
const char kChangeStampKey[] = "CHANGE_STAMP"; |
const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR"; |
const char kDriveMetadataKeyPrefix[] = "METADATA: "; |
@@ -50,6 +51,9 @@ const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: "; |
const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: "; |
const size_t kDriveMetadataKeyPrefixLength = arraysize(kDriveMetadataKeyPrefix); |
+const char kWapiFileIdPrefix[] = "file:"; |
+const char kWapiFolderIdPrefix[] = "folder:"; |
+ |
const base::FilePath::CharType kV0FormatPathPrefix[] = |
FILE_PATH_LITERAL("drive/"); |
@@ -105,6 +109,43 @@ bool UpdateResourceIdMap(ResourceIdByOrigin* map, |
return true; |
} |
+std::string AddWapiFilePrefix(const std::string& resource_id) { |
+ if (resource_id.empty() || |
+ StartsWithASCII(resource_id, kWapiFileIdPrefix, true)) |
+ return resource_id; |
+ return kWapiFileIdPrefix + resource_id; |
+} |
+ |
+std::string AddWapiFolderPrefix(const std::string& resource_id) { |
+ if (resource_id.empty() || |
+ 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()); |
+ return resource_id; |
+} |
+ |
} // namespace |
class DriveMetadataDB { |
@@ -125,7 +166,8 @@ class DriveMetadataDB { |
SyncStatusCode ReadContents(DriveMetadataDBContents* contents); |
SyncStatusCode MigrateDatabaseIfNeeded(); |
- SyncStatusCode MigrateFromVersion0Database(); |
+ SyncStatusCode MigrateFromVersion0To1Database(); |
+ SyncStatusCode MigrateFromVersion1To2Database(); |
SyncStatusCode SetLargestChangestamp(int64 largest_changestamp); |
SyncStatusCode SetSyncRootDirectory(const std::string& resource_id); |
@@ -134,7 +176,7 @@ class DriveMetadataDB { |
OriginSyncType sync_type, |
const std::string& resource_id); |
SyncStatusCode UpdateEntry(const FileSystemURL& url, |
- const DriveMetadata& metadata); |
+ DriveMetadata metadata); |
SyncStatusCode DeleteEntry(const FileSystemURL& url); |
// TODO(calvinlo): consolidate these state transition functions for sync |
@@ -449,6 +491,7 @@ void DriveMetadataStore::DeleteEntry( |
AsWeakPtr(), callback)); |
return; |
} |
+ |
base::MessageLoopProxy::current()->PostTask( |
FROM_HERE, |
base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND)); |
@@ -857,6 +900,11 @@ SyncStatusCode DriveMetadataDB::ReadContents( |
bool success = metadata.ParseFromString(itr->value().ToString()); |
DCHECK(success); |
+ if (!IsDriveAPIEnabled()) { |
+ metadata.set_resource_id( |
+ AddWapiIdPrefix(metadata.resource_id(), metadata.type())); |
+ } |
+ |
success = contents->metadata_map[origin].insert( |
std::make_pair(path, metadata)).second; |
DCHECK(success); |
@@ -894,14 +942,18 @@ SyncStatusCode DriveMetadataDB::MigrateDatabaseIfNeeded() { |
return SYNC_STATUS_OK; |
} |
- if (database_version == 0) { |
- MigrateFromVersion0Database(); |
- return SYNC_STATUS_OK; |
+ switch (database_version) { |
+ case 0: |
+ MigrateFromVersion0To1Database(); |
+ // fall-through |
+ case 1: |
+ MigrateFromVersion1To2Database(); |
+ return SYNC_STATUS_OK; |
} |
return SYNC_DATABASE_ERROR_FAILED; |
} |
-SyncStatusCode DriveMetadataDB::MigrateFromVersion0Database() { |
+SyncStatusCode DriveMetadataDB::MigrateFromVersion0To1Database() { |
// Version 0 database format: |
// key: "CHANGE_STAMP" |
// value: <Largest Changestamp> |
@@ -942,8 +994,7 @@ SyncStatusCode DriveMetadataDB::MigrateFromVersion0Database() { |
// value: <Resource ID of the drive directory for the origin> |
leveldb::WriteBatch write_batch; |
- write_batch.Put(kDatabaseVersionKey, |
- base::Int64ToString(kCurrentDatabaseVersion)); |
+ write_batch.Put(kDatabaseVersionKey, "1"); |
scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
for (itr->Seek(kDriveMetadataKeyPrefix); itr->Valid(); itr->Next()) { |
@@ -968,6 +1019,110 @@ SyncStatusCode DriveMetadataDB::MigrateFromVersion0Database() { |
db_->Write(leveldb::WriteOptions(), &write_batch)); |
} |
+SyncStatusCode DriveMetadataDB::MigrateFromVersion1To2Database() { |
+ // 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: "BSYNC_ORIGIN: " + <URL string of a batch sync origin> |
+ // * value: <Resource ID of the drive directory for the origin> (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) |
+ |
+ 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())); |
+ |
+ write_batch.Put(key, itr->value()); |
+ } |
+ |
+ // Strip resource ids of the batch sync origins. |
+ for (itr->Seek(kDriveBatchSyncOriginKeyPrefix); |
+ itr->Valid(); itr->Next()) { |
+ std::string key = itr->key().ToString(); |
+ if (!StartsWithASCII(key, kDriveBatchSyncOriginKeyPrefix, true)) |
+ break; |
+ |
+ GURL origin(std::string( |
+ key.begin() + arraysize(kDriveBatchSyncOriginKeyPrefix) - 1, |
+ key.end())); |
+ DCHECK(origin.is_valid()); |
+ |
+ write_batch.Put(CreateKeyForOriginRoot(origin, BATCH_SYNC_ORIGIN), |
+ RemoveWapiIdPrefix(itr->value().ToString())); |
+ } |
+ |
+ // 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(CreateKeyForOriginRoot(origin, INCREMENTAL_SYNC_ORIGIN), |
+ 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(CreateKeyForOriginRoot(origin, DISABLED_ORIGIN), |
+ RemoveWapiIdPrefix(itr->value().ToString())); |
+ } |
+ |
+ return LevelDBStatusToSyncStatusCode( |
+ db_->Write(leveldb::WriteOptions(), &write_batch)); |
+} |
+ |
SyncStatusCode DriveMetadataDB::SetLargestChangestamp( |
int64 largest_changestamp) { |
DCHECK(CalledOnValidThread()); |
@@ -984,8 +1139,9 @@ SyncStatusCode DriveMetadataDB::SetSyncRootDirectory( |
DCHECK(CalledOnValidThread()); |
DCHECK(db_.get()); |
- leveldb::Status status = db_->Put( |
- leveldb::WriteOptions(), kSyncRootDirectoryKey, resource_id); |
+ leveldb::Status status = db_->Put(leveldb::WriteOptions(), |
+ kSyncRootDirectoryKey, |
+ RemoveWapiIdPrefix(resource_id)); |
return LevelDBStatusToSyncStatusCode(status); |
} |
@@ -1000,7 +1156,8 @@ SyncStatusCode DriveMetadataDB::SetOriginRootDirectory( |
if (key.empty()) |
return SYNC_DATABASE_ERROR_FAILED; |
- leveldb::Status status = db_->Put(leveldb::WriteOptions(), key, resource_id); |
+ leveldb::Status status = db_->Put( |
+ leveldb::WriteOptions(), key, RemoveWapiIdPrefix(resource_id)); |
return LevelDBStatusToSyncStatusCode(status); |
} |
@@ -1010,14 +1167,21 @@ SyncStatusCode DriveMetadataDB::GetSyncRootDirectory(std::string* resource_id) { |
leveldb::Status status = db_->Get( |
leveldb::ReadOptions(), kSyncRootDirectoryKey, resource_id); |
+ |
+ if (!IsDriveAPIEnabled() && status.ok()) |
+ *resource_id = AddWapiFolderPrefix(*resource_id); |
+ |
return LevelDBStatusToSyncStatusCode(status); |
} |
SyncStatusCode DriveMetadataDB::UpdateEntry(const FileSystemURL& url, |
- const DriveMetadata& metadata) { |
+ DriveMetadata metadata) { |
DCHECK(CalledOnValidThread()); |
DCHECK(db_.get()); |
+ if (!IsDriveAPIEnabled()) |
+ metadata.set_resource_id(RemoveWapiIdPrefix(metadata.resource_id())); |
+ |
std::string metadata_key = FileSystemURLToMetadataKey(url); |
std::string value; |
bool success = metadata.SerializeToString(&value); |
@@ -1046,7 +1210,7 @@ SyncStatusCode DriveMetadataDB::UpdateOriginAsBatchSync( |
leveldb::Status status = db_->Put( |
leveldb::WriteOptions(), |
CreateKeyForOriginRoot(origin, BATCH_SYNC_ORIGIN), |
- resource_id); |
+ RemoveWapiIdPrefix(resource_id)); |
return LevelDBStatusToSyncStatusCode(status); |
} |
@@ -1059,7 +1223,7 @@ SyncStatusCode DriveMetadataDB::UpdateOriginAsIncrementalSync( |
batch.Delete(CreateKeyForOriginRoot(origin, BATCH_SYNC_ORIGIN)); |
batch.Delete(CreateKeyForOriginRoot(origin, DISABLED_ORIGIN)); |
batch.Put(CreateKeyForOriginRoot(origin, INCREMENTAL_SYNC_ORIGIN), |
- resource_id); |
+ RemoveWapiIdPrefix(resource_id)); |
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); |
return LevelDBStatusToSyncStatusCode(status); |
@@ -1073,7 +1237,8 @@ SyncStatusCode DriveMetadataDB::EnableOrigin( |
leveldb::WriteBatch batch; |
batch.Delete(CreateKeyForOriginRoot(origin, INCREMENTAL_SYNC_ORIGIN)); |
batch.Delete(CreateKeyForOriginRoot(origin, DISABLED_ORIGIN)); |
- batch.Put(CreateKeyForOriginRoot(origin, BATCH_SYNC_ORIGIN), resource_id); |
+ batch.Put(CreateKeyForOriginRoot(origin, BATCH_SYNC_ORIGIN), |
+ RemoveWapiIdPrefix(resource_id)); |
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); |
return LevelDBStatusToSyncStatusCode(status); |
@@ -1089,7 +1254,7 @@ SyncStatusCode DriveMetadataDB::DisableOrigin( |
batch.Delete(CreateKeyForOriginRoot(origin_to_disable, |
INCREMENTAL_SYNC_ORIGIN)); |
batch.Put(CreateKeyForOriginRoot(origin_to_disable, DISABLED_ORIGIN), |
- resource_id); |
+ RemoveWapiIdPrefix(resource_id)); |
// Remove entries specified by |origin_to_disable|. |
scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
@@ -1156,8 +1321,13 @@ SyncStatusCode DriveMetadataDB::GetOrigins( |
key.begin() + arraysize(kDriveBatchSyncOriginKeyPrefix) - 1, |
key.end())); |
DCHECK(origin.is_valid()); |
+ |
+ std::string origin_resource_id = |
+ IsDriveAPIEnabled() ? itr->value().ToString() |
+ : AddWapiFolderPrefix(itr->value().ToString()); |
+ |
bool result = batch_sync_origins->insert( |
- std::make_pair(origin, itr->value().ToString())).second; |
+ std::make_pair(origin, origin_resource_id)).second; |
DCHECK(result); |
} |
@@ -1171,8 +1341,13 @@ SyncStatusCode DriveMetadataDB::GetOrigins( |
key.begin() + arraysize(kDriveIncrementalSyncOriginKeyPrefix) - 1, |
key.end())); |
DCHECK(origin.is_valid()); |
+ |
+ std::string origin_resource_id = |
+ IsDriveAPIEnabled() ? itr->value().ToString() |
+ : AddWapiFolderPrefix(itr->value().ToString()); |
+ |
bool result = incremental_sync_origins->insert( |
- std::make_pair(origin, itr->value().ToString())).second; |
+ std::make_pair(origin, origin_resource_id)).second; |
DCHECK(result); |
} |
@@ -1186,8 +1361,13 @@ SyncStatusCode DriveMetadataDB::GetOrigins( |
key.begin() + arraysize(kDriveDisabledOriginKeyPrefix) - 1, |
key.end())); |
DCHECK(origin.is_valid()); |
+ |
+ std::string origin_resource_id = |
+ IsDriveAPIEnabled() ? itr->value().ToString() |
+ : AddWapiFolderPrefix(itr->value().ToString()); |
+ |
bool result = disabled_origins->insert( |
- std::make_pair(origin, itr->value().ToString())).second; |
+ std::make_pair(origin, origin_resource_id)).second; |
DCHECK(result); |
} |