Chromium Code Reviews| 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..055e547183b3c925778fcaef42d3477e8b92d341 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 { |
| @@ -126,6 +167,7 @@ class DriveMetadataDB { |
| SyncStatusCode MigrateDatabaseIfNeeded(); |
| SyncStatusCode MigrateFromVersion0Database(); |
| + SyncStatusCode MigrateFromVersion1Database(); |
| 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,9 +942,13 @@ SyncStatusCode DriveMetadataDB::MigrateDatabaseIfNeeded() { |
| return SYNC_STATUS_OK; |
| } |
| - if (database_version == 0) { |
| - MigrateFromVersion0Database(); |
| - return SYNC_STATUS_OK; |
| + switch (database_version) { |
| + case 0: |
| + MigrateFromVersion0Database(); |
| + // fall-through |
| + case 1: |
| + MigrateFromVersion1Database(); |
| + return SYNC_STATUS_OK; |
| } |
| return SYNC_DATABASE_ERROR_FAILED; |
| } |
| @@ -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,73 @@ SyncStatusCode DriveMetadataDB::MigrateFromVersion0Database() { |
| db_->Write(leveldb::WriteOptions(), &write_batch)); |
| } |
| +SyncStatusCode DriveMetadataDB::MigrateFromVersion1Database() { |
|
kinuko
2013/05/27 08:25:16
Can we rename this: MigrateFromVersion1To2Database
nhiroki
2013/05/27 09:13:03
Done.
|
| + // Version 1 database format (changed keys/fields are marked with '*'): |
| + // key: "VERSION" (new) |
|
tzik
2013/05/27 08:04:42
drop (new)?
nhiroki
2013/05/27 09:13:03
Done.
|
| + // value: 1 |
| + // |
| + // key: "CHANGE_STAMP" |
| + // value: <Largest Changestamp> |
| + // |
| + // key: "SYNC_ROOT_DIR" |
| + // value: <Resource ID of the sync root directory> |
| + // |
| + // key: "METADATA: " + <Origin and URL> (changed) |
|
tzik
2013/05/27 08:04:42
drop (changed)?
nhiroki
2013/05/27 09:13:03
Done.
|
| + // value: <Serialized DriveMetadata> |
| + // |
| + // key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin> |
| + // value: <Resource ID of the drive directory for the origin> |
| + // |
| + // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin> |
| + // value: <Resource ID of the drive directory for the origin> |
| + // |
| + // key: "DISABLED_ORIGIN: " + <URL string of a disabled origin> |
| + // value: <Resource ID of the drive directory for the origin> |
| + // |
|
kinuko
2013/05/27 08:25:16
I think we could drop comments for Version 1 here?
kinuko
2013/05/27 08:26:57
I mean, because we have the same text right above
nhiroki
2013/05/27 09:13:03
Done.
|
| + // 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> |
| + // |
| + // key: "METADATA: " + <Origin and URL> |
| + // * value: <Serialized DriveMetadata> (Prefix of WAPI resource ID is striped) |
| + // (i.e. "file:xxxx" => "xxxx", "folder:yyyy" => "yyyy") |
| + // |
| + // key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin> |
| + // value: <Resource ID of the drive directory for the origin> |
| + // |
| + // key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin> |
| + // value: <Resource ID of the drive directory for the origin> |
| + // |
| + // key: "DISABLED_ORIGIN: " + <URL string of a disabled origin> |
| + // value: <Resource ID of the drive directory for the origin> |
| + |
| + leveldb::WriteBatch write_batch; |
| + write_batch.Put(kDatabaseVersionKey, "2"); |
| + |
| + 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()); |
| + } |
| + return LevelDBStatusToSyncStatusCode( |
| + db_->Write(leveldb::WriteOptions(), &write_batch)); |
| +} |
| + |
| SyncStatusCode DriveMetadataDB::SetLargestChangestamp( |
| int64 largest_changestamp) { |
| DCHECK(CalledOnValidThread()); |
| @@ -984,8 +1102,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 +1119,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 +1130,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 +1173,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 +1186,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 +1200,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 +1217,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 +1284,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 +1304,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 +1324,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); |
| } |