Commit 2dd65d39 authored by nhiroki@chromium.org's avatar nhiroki@chromium.org

SyncFS: Factor out DriveMetadataDB migration functions

This change factors out DriveMetadataDB V0-V1 migration functions into
metadata_db_migration_utils.{cc,h}, and also moves function to deprecate batch sync origins into the files.


BUG=none
TEST=unit_tests --gtest_filter=\*DriveMetadataDBMigrationUtilTest\*

Review URL: https://chromiumcodereview.appspot.com/15951007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203126 0039d316-1c4b-4281-b951-d872f2087c98
parent ec0c85be
......@@ -9,12 +9,16 @@
#include "base/string_util.h"
#include "googleurl/src/gurl.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/common/fileapi/file_system_types.h"
namespace sync_file_system {
namespace drive {
namespace {
const base::FilePath::CharType kV0FormatPathPrefix[] =
FILE_PATH_LITERAL("drive/");
const char kWapiFileIdPrefix[] = "file:";
const char kWapiFolderIdPrefix[] = "folder:";
......@@ -26,6 +30,28 @@ std::string RemovePrefix(const std::string& str, const std::string& prefix) {
} // namespace
bool ParseV0FormatFileSystemURL(const GURL& url,
GURL* origin,
base::FilePath* path) {
fileapi::FileSystemType mount_type;
base::FilePath virtual_path;
if (!fileapi::FileSystemURL::ParseFileSystemSchemeURL(
url, origin, &mount_type, &virtual_path) ||
mount_type != fileapi::kFileSystemTypeExternal) {
NOTREACHED() << "Failed to parse filesystem scheme URL";
return false;
}
base::FilePath::StringType prefix =
base::FilePath(kV0FormatPathPrefix).NormalizePathSeparators().value();
if (virtual_path.value().substr(0, prefix.size()) != prefix)
return false;
*path = base::FilePath(virtual_path.value().substr(prefix.size()));
return true;
}
std::string AddWapiFilePrefix(const std::string& resource_id) {
DCHECK(!StartsWithASCII(resource_id, kWapiFileIdPrefix, true));
DCHECK(!StartsWithASCII(resource_id, kWapiFolderIdPrefix, true));
......@@ -68,8 +94,78 @@ std::string RemoveWapiIdPrefix(const std::string& resource_id) {
return resource_id;
}
SyncStatusCode MigrateDatabaseFromV0ToV1(leveldb::DB* db) {
// Version 0 database format:
// key: "CHANGE_STAMP"
// value: <Largest Changestamp>
//
// key: "SYNC_ROOT_DIR"
// value: <Resource ID of the sync root directory>
//
// key: "METADATA: " +
// <FileSystemURL serialized by SerializeSyncableFileSystemURL>
// 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>
//
// Version 1 database format (changed keys/fields are marked with '*'):
// * key: "VERSION" (new)
// * 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)
// * 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>
const char kDatabaseVersionKey[] = "VERSION";
const char kDriveMetadataKeyPrefix[] = "METADATA: ";
const char kMetadataKeySeparator = ' ';
leveldb::WriteBatch write_batch;
write_batch.Put(kDatabaseVersionKey, "1");
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;
std::string serialized_url(RemovePrefix(key, kDriveMetadataKeyPrefix));
GURL origin;
base::FilePath path;
bool success = ParseV0FormatFileSystemURL(
GURL(serialized_url), &origin, &path);
DCHECK(success) << serialized_url;
std::string new_key = kDriveMetadataKeyPrefix + origin.spec() +
kMetadataKeySeparator + path.AsUTF8Unsafe();
write_batch.Put(new_key, itr->value());
write_batch.Delete(key);
}
return LevelDBStatusToSyncStatusCode(
db->Write(leveldb::WriteOptions(), &write_batch));
}
SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db) {
// Strips prefix of WAPI resource ID.
// Strips prefix of WAPI resource ID, and discards batch sync origins.
// (i.e. "file:xxxx" => "xxxx", "folder:yyyy" => "yyyy")
//
// Version 2 database format (changed keys/fields are marked with '*'):
......@@ -83,17 +179,21 @@ SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db) {
// * value: <Resource ID of the sync root directory> (striped)
//
// key: "METADATA: " + <Origin and URL>
// * value: <Serialized DriveMetadata> (striped)
// * value: <Serialized DriveMetadata> (stripped)
//
// * key: "BSYNC_ORIGIN: " + <URL string of a batch sync origin> (deleted)
// * value: <Resource ID of the drive directory for the origin> (deleted)
//
// key: "ISYNC_ORIGIN: " + <URL string of a incremental sync origin>
// * value: <Resource ID of the drive directory for the origin> (striped)
// * value: <Resource ID of the drive directory for the origin> (stripped)
//
// key: "DISABLED_ORIGIN: " + <URL string of a disabled origin>
// * value: <Resource ID of the drive directory for the origin> (striped)
// * value: <Resource ID of the drive directory for the origin> (stripped)
const char kDatabaseVersionKey[] = "VERSION";
const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR";
const char kDriveMetadataKeyPrefix[] = "METADATA: ";
const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: ";
const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: ";
......@@ -124,6 +224,12 @@ SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db) {
continue;
}
// Deprecate legacy batch sync origin entries that are no longer needed.
if (StartsWithASCII(key, kDriveBatchSyncOriginKeyPrefix, true)) {
write_batch.Delete(key);
continue;
}
// Strip resource ids of the incremental sync origins.
if (StartsWithASCII(key, kDriveIncrementalSyncOriginKeyPrefix, true)) {
write_batch.Put(key, RemoveWapiIdPrefix(itr->value().ToString()));
......
......@@ -11,9 +11,28 @@
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "webkit/browser/fileapi/syncable/sync_status_code.h"
class GURL;
namespace sync_file_system {
namespace drive {
// Parses a filesystem URL which contains 'drive' as a service name
// (a.k.a. V0-format filesystem URL).
//
// When you parse V0-format filesystem URL, you should use this function instead
// of DeserializeSyncableFileSystemURL() since 'drive' service name is no longer
// used and the deserializer cannot parse the unregistered service name.
//
// EXAMPLE:
// Assume following argument is given.
// url: 'filesystem:http://www.example.com/external/drive/foo/bar'
// returns
// origin: 'http://www.example.com/'
// path: 'foo/bar'
bool ParseV0FormatFileSystemURL(const GURL& url,
GURL* origin,
base::FilePath* path);
// Adds "file:" prefix to WAPI resource ID.
// EXAMPLE: "xxx" => "file:xxx"
std::string AddWapiFilePrefix(const std::string& resource_id);
......@@ -33,7 +52,10 @@ std::string AddWapiIdPrefix(const std::string& resource_id,
// "zzz" => "zzz"
std::string RemoveWapiIdPrefix(const std::string& resource_id);
// Migrate |db| scheme from version 1 to version 2.
// Migrate |db| schema from version 0 to version 1.
SyncStatusCode MigrateDatabaseFromV0ToV1(leveldb::DB* db);
// Migrate |db| schema from version 1 to version 2.
SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db);
} // namespace drive
......
......@@ -20,6 +20,31 @@
namespace sync_file_system {
namespace drive {
namespace {
const char kV0ServiceName[] = "drive";
}
TEST(DriveMetadataDBMigrationUtilTest, ParseV0FormatFileSystemURL) {
const GURL kOrigin("chrome-extension://example");
const base::FilePath kFile(FPL("foo bar"));
ASSERT_TRUE(RegisterSyncableFileSystem(kV0ServiceName));
fileapi::FileSystemURL url =
CreateSyncableFileSystemURL(kOrigin, kV0ServiceName, kFile);
std::string serialized_url;
SerializeSyncableFileSystemURL(url, &serialized_url);
GURL origin;
base::FilePath path;
EXPECT_TRUE(ParseV0FormatFileSystemURL(GURL(serialized_url), &origin, &path));
EXPECT_EQ(kOrigin, origin);
EXPECT_EQ(kFile, path);
EXPECT_TRUE(RevokeSyncableFileSystem(kV0ServiceName));
}
TEST(DriveMetadataDBMigrationUtilTest, AddWapiIdPrefix) {
DriveMetadata_ResourceType type_file =
DriveMetadata_ResourceType_RESOURCE_TYPE_FILE;
......@@ -46,26 +71,136 @@ TEST(DriveMetadataDBMigrationUtilTest, RemoveWapiIdPrefix) {
EXPECT_EQ("foo:xxx", RemoveWapiIdPrefix("foo:xxx"));
}
TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV0) {
const char kDatabaseVersionKey[] = "VERSION";
const char kChangeStampKey[] = "CHANGE_STAMP";
const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR";
const char kDriveMetadataKeyPrefix[] = "METADATA: ";
const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: ";
const GURL kOrigin1("chrome-extension://example1");
const GURL kOrigin2("chrome-extension://example2");
const std::string kSyncRootResourceId("folder:sync_root_resource_id");
const std::string kResourceId1("folder:hoge");
const std::string kResourceId2("folder:fuga");
const std::string kFileResourceId("file:piyo");
const base::FilePath kFile(FPL("foo bar"));
const std::string kFileMD5("file_md5");
ASSERT_TRUE(RegisterSyncableFileSystem(kV0ServiceName));
base::ScopedTempDir base_dir;
ASSERT_TRUE(base_dir.CreateUniqueTempDir());
leveldb::Options options;
options.create_if_missing = true;
leveldb::DB* db_ptr = NULL;
std::string db_dir = fileapi::FilePathToString(
base_dir.path().Append(DriveMetadataStore::kDatabaseName));
leveldb::Status status = leveldb::DB::Open(options, db_dir, &db_ptr);
scoped_ptr<leveldb::DB> db(db_ptr);
ASSERT_TRUE(status.ok());
// Setup the database with the schema version 0.
leveldb::WriteBatch batch;
batch.Put(kChangeStampKey, "1");
batch.Put(kSyncRootDirectoryKey, kSyncRootResourceId);
fileapi::FileSystemURL url =
CreateSyncableFileSystemURL(kOrigin1, kV0ServiceName, kFile);
// Setup drive metadata.
DriveMetadata drive_metadata;
drive_metadata.set_resource_id(kFileResourceId);
drive_metadata.set_md5_checksum(kFileMD5);
drive_metadata.set_conflicted(false);
drive_metadata.set_to_be_fetched(false);
std::string serialized_url;
SerializeSyncableFileSystemURL(url, &serialized_url);
std::string metadata_string;
drive_metadata.SerializeToString(&metadata_string);
batch.Put(kDriveMetadataKeyPrefix + serialized_url, metadata_string);
// Setup batch sync origin and incremental sync origin.
batch.Put(kDriveBatchSyncOriginKeyPrefix + kOrigin1.spec(), kResourceId1);
batch.Put(kDriveIncrementalSyncOriginKeyPrefix + kOrigin2.spec(),
kResourceId2);
status = db->Write(leveldb::WriteOptions(), &batch);
EXPECT_EQ(SYNC_STATUS_OK, LevelDBStatusToSyncStatusCode(status));
EXPECT_TRUE(RevokeSyncableFileSystem(kV0ServiceName));
// Migrate the database.
drive::MigrateDatabaseFromV0ToV1(db.get());
scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
// Verify DB schema version.
int64 database_version = 0;
itr->Seek(kDatabaseVersionKey);
EXPECT_TRUE(itr->Valid());
EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &database_version));
EXPECT_EQ(1, database_version);
// Verify the largest changestamp.
int64 changestamp = 0;
itr->Seek(kChangeStampKey);
EXPECT_TRUE(itr->Valid());
EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &changestamp));
EXPECT_EQ(1, changestamp);
// Verify the sync root directory.
itr->Seek(kSyncRootDirectoryKey);
EXPECT_TRUE(itr->Valid());
EXPECT_EQ(kSyncRootResourceId, itr->value().ToString());
// Verify the metadata.
itr->Seek(kDriveMetadataKeyPrefix);
EXPECT_TRUE(itr->Valid());
DriveMetadata metadata;
EXPECT_TRUE(metadata.ParseFromString(itr->value().ToString()));
EXPECT_EQ(kFileResourceId, metadata.resource_id());
EXPECT_EQ(kFileMD5, metadata.md5_checksum());
EXPECT_FALSE(metadata.conflicted());
EXPECT_FALSE(metadata.to_be_fetched());
// Verify the batch sync origin.
itr->Seek(kDriveBatchSyncOriginKeyPrefix);
EXPECT_TRUE(itr->Valid());
EXPECT_EQ(kResourceId1, itr->value().ToString());
// Verify the incremental sync origin.
itr->Seek(kDriveIncrementalSyncOriginKeyPrefix);
EXPECT_TRUE(itr->Valid());
EXPECT_EQ(kResourceId2, itr->value().ToString());
}
TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV1) {
const char kDatabaseVersionKey[] = "VERSION";
const char kChangeStampKey[] = "CHANGE_STAMP";
const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR";
const char kDriveMetadataKeyPrefix[] = "METADATA: ";
const char kMetadataKeySeparator = ' ';
const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: ";
const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: ";
const GURL kOrigin1("chrome-extension://example1");
const GURL kOrigin2("chrome-extension://example2");
const GURL kOrigin3("chrome-extension://example3");
const std::string kSyncRootResourceId("folder:sync_root_resource_id");
const std::string kResourceId1("folder:hoge");
const std::string kResourceId2("folder:fuga");
const std::string kResourceId3("folder:hogera");
const std::string kFileResourceId("file:piyo");
const base::FilePath kFile(FPL("foo bar"));
const std::string kFileMD5("file_md5");
const char kV1ServiceName[] = "drive";
const char kV1ServiceName[] = "syncfs";
ASSERT_TRUE(RegisterSyncableFileSystem(kV1ServiceName));
base::ScopedTempDir base_dir;
......@@ -81,7 +216,7 @@ TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV1) {
scoped_ptr<leveldb::DB> db(db_ptr);
ASSERT_TRUE(status.ok());
// Setup the database with the scheme version 1.
// Setup the database with the schema version 1.
leveldb::WriteBatch batch;
batch.Put(kDatabaseVersionKey, "1");
batch.Put(kChangeStampKey, "1");
......@@ -102,11 +237,11 @@ TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV1) {
kMetadataKeySeparator + url.path().AsUTF8Unsafe();
batch.Put(metadata_key, metadata_string);
// Setup incremental sync origin and disabled origin.
batch.Put(kDriveIncrementalSyncOriginKeyPrefix + kOrigin1.spec(),
kResourceId1);
batch.Put(kDriveDisabledOriginKeyPrefix + kOrigin2.spec(),
// Setup origins.
batch.Put(kDriveBatchSyncOriginKeyPrefix + kOrigin1.spec(), kResourceId1);
batch.Put(kDriveIncrementalSyncOriginKeyPrefix + kOrigin2.spec(),
kResourceId2);
batch.Put(kDriveDisabledOriginKeyPrefix + kOrigin3.spec(), kResourceId3);
status = db->Write(leveldb::WriteOptions(), &batch);
EXPECT_EQ(SYNC_STATUS_OK, LevelDBStatusToSyncStatusCode(status));
......@@ -117,13 +252,20 @@ TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV1) {
scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
// Verify DB scheme version.
// Verify DB schema version.
int64 database_version = 0;
itr->Seek(kDatabaseVersionKey);
EXPECT_TRUE(itr->Valid());
EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &database_version));
EXPECT_EQ(2, database_version);
// Verify the largest changestamp.
int64 changestamp = 0;
itr->Seek(kChangeStampKey);
EXPECT_TRUE(itr->Valid());
EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &changestamp));
EXPECT_EQ(1, changestamp);
// Verify the sync root directory.
itr->Seek(kSyncRootDirectoryKey);
EXPECT_TRUE(itr->Valid());
......@@ -139,15 +281,20 @@ TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV1) {
EXPECT_FALSE(metadata.conflicted());
EXPECT_FALSE(metadata.to_be_fetched());
// Verify the batch sync origin.
itr->Seek(kDriveBatchSyncOriginKeyPrefix);
EXPECT_FALSE(StartsWithASCII(kDriveBatchSyncOriginKeyPrefix,
itr->key().ToString(), true));
// Verify the incremental sync origin.
itr->Seek(kDriveIncrementalSyncOriginKeyPrefix);
EXPECT_TRUE(itr->Valid());
EXPECT_EQ(RemoveWapiIdPrefix(kResourceId1), itr->value().ToString());
EXPECT_EQ(RemoveWapiIdPrefix(kResourceId2), itr->value().ToString());
// Verify the disabled origin.
itr->Seek(kDriveDisabledOriginKeyPrefix);
EXPECT_TRUE(itr->Valid());
EXPECT_EQ(RemoveWapiIdPrefix(kResourceId2), itr->value().ToString());
EXPECT_EQ(RemoveWapiIdPrefix(kResourceId3), itr->value().ToString());
}
} // namespace drive
......
......@@ -48,34 +48,14 @@ const char kChangeStampKey[] = "CHANGE_STAMP";
const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR";
const char kDriveMetadataKeyPrefix[] = "METADATA: ";
const char kMetadataKeySeparator = ' ';
const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: ";
const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: ";
const size_t kDriveMetadataKeyPrefixLength = arraysize(kDriveMetadataKeyPrefix);
const base::FilePath::CharType kV0FormatPathPrefix[] =
FILE_PATH_LITERAL("drive/");
bool ParseV0FormatFileSystemURLString(const GURL& url,
GURL* origin,
base::FilePath* path) {
fileapi::FileSystemType mount_type;
base::FilePath virtual_path;
if (!fileapi::FileSystemURL::ParseFileSystemSchemeURL(
url, origin, &mount_type, &virtual_path) ||
mount_type != fileapi::kFileSystemTypeExternal) {
NOTREACHED() << "Failed to parse filesystem scheme URL";
return false;
}
base::FilePath::StringType prefix =
base::FilePath(kV0FormatPathPrefix).NormalizePathSeparators().value();
if (virtual_path.value().substr(0, prefix.size()) != prefix)
return false;
*path = base::FilePath(virtual_path.value().substr(prefix.size()));
return true;
std::string RemovePrefix(const std::string& str, const std::string& prefix) {
if (StartsWithASCII(str, prefix, true))
return str.substr(prefix.size());
return str;
}
std::string FileSystemURLToMetadataKey(const FileSystemURL& url) {
......@@ -86,8 +66,7 @@ std::string FileSystemURLToMetadataKey(const FileSystemURL& url) {
void MetadataKeyToOriginAndPath(const std::string& metadata_key,
GURL* origin,
base::FilePath* path) {
std::string key_body(metadata_key.begin() + kDriveMetadataKeyPrefixLength - 1,
metadata_key.end());
std::string key_body(RemovePrefix(metadata_key, kDriveMetadataKeyPrefix));
size_t separator_position = key_body.find(kMetadataKeySeparator);
*origin = GURL(key_body.substr(0, separator_position));
*path = base::FilePath::FromUTF8Unsafe(
......@@ -108,12 +87,6 @@ bool UpdateResourceIdMap(ResourceIdByOrigin* map,
return true;
}
std::string RemovePrefix(const std::string& str, const std::string& prefix) {
if (StartsWithASCII(str, prefix, true))
return str.substr(prefix.size());
return str;
}
} // namespace
class DriveMetadataDB {
......@@ -133,7 +106,6 @@ class DriveMetadataDB {
SyncStatusCode ReadContents(DriveMetadataDBContents* contents);
SyncStatusCode MigrateDatabaseIfNeeded();
SyncStatusCode MigrateFromVersion0To1Database();
SyncStatusCode SetLargestChangestamp(int64 largest_changestamp);
SyncStatusCode SetSyncRootDirectory(const std::string& resource_id);
......@@ -149,8 +121,6 @@ class DriveMetadataDB {
// origins like "UpdateOrigin(GURL, SyncStatusEnum)". And manage origins in
// just one map like "Map<SyncStatusEnum, ResourceIDMap>".
// http://crbug.com/211600
SyncStatusCode UpdateOriginAsBatchSync(const GURL& origin,
const std::string& resource_id);
SyncStatusCode UpdateOriginAsIncrementalSync(const GURL& origin,
const std::string& resource_id);
SyncStatusCode EnableOrigin(const GURL& origin,
......@@ -780,22 +750,6 @@ SyncStatusCode DriveMetadataDB::Initialize(bool* created) {
}
db_.reset(db);
// Deprecate legacy batch sync origin entries that are no longer needed.
leveldb::WriteBatch batch;
scoped_ptr<leveldb::Iterator> batch_origin_itr(
db_->NewIterator(leveldb::ReadOptions()));
for (batch_origin_itr->Seek(kDriveBatchSyncOriginKeyPrefix);
batch_origin_itr->Valid();
batch_origin_itr->Next()) {
std::string key = batch_origin_itr->key().ToString();
if (!StartsWithASCII(key, kDriveBatchSyncOriginKeyPrefix, true))
break;
batch.Delete(key);
}
status = db_->Write(leveldb::WriteOptions(), &batch);
return LevelDBStatusToSyncStatusCode(status);
}
......@@ -868,7 +822,7 @@ SyncStatusCode DriveMetadataDB::MigrateDatabaseIfNeeded() {
switch (database_version) {
case 0:
MigrateFromVersion0To1Database();
drive::MigrateDatabaseFromV0ToV1(db_.get());
// fall-through
case 1:
drive::MigrateDatabaseFromV1ToV2(db_.get());
......@@ -877,72 +831,6 @@ SyncStatusCode DriveMetadataDB::MigrateDatabaseIfNeeded() {
return SYNC_DATABASE_ERROR_FAILED;
}
SyncStatusCode DriveMetadataDB::MigrateFromVersion0To1Database() {
// Version 0 database format:
// key: "CHANGE_STAMP"
// value: <Largest Changestamp>
//
// key: "SYNC_ROOT_DIR"
// value: <Resource ID of the sync root directory>
//
// key: "METADATA: " +
// <FileSystemURL serialized by SerializeSyncableFileSystemURL>
// 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>
//
// Version 1 database format (changed keys/fields are marked with '*'):
// * key: "VERSION" (new)
// * 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)
// * 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>
leveldb::WriteBatch write_batch;
write_batch.Put(kDatabaseVersionKey, "1");
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;
std::string serialized_url(
key.begin() + kDriveMetadataKeyPrefixLength - 1, key.end());
GURL origin;
base::FilePath path;
bool success = ParseV0FormatFileSystemURLString(
GURL(serialized_url), &origin, &path);
DCHECK(success) << serialized_url;
std::string new_key = kDriveMetadataKeyPrefix + origin.spec() +
kMetadataKeySeparator + path.AsUTF8Unsafe();
write_batch.Put(new_key, itr->value());
write_batch.Delete(key);
}
return LevelDBStatusToSyncStatusCode(
db_->Write(leveldb::WriteOptions(), &write_batch));
}
SyncStatusCode DriveMetadataDB::SetLargestChangestamp(
int64 largest_changestamp) {
DCHECK(CalledOnValidThread());
......
......@@ -588,118 +588,6 @@ TEST_F(DriveMetadataStoreTest, GetResourceIdForOrigin) {
VerifyReverseMap();
}
TEST_F(DriveMetadataStoreTest, MigrationFromV0) {
const GURL kOrigin1("chrome-extension://example1");
const GURL kOrigin2("chrome-extension://example2");
const std::string kSyncRootResourceId("folder:sync_root_resource_id");
const std::string kResourceId1("folder:hoge");
const std::string kResourceId2("folder:fuga");
const std::string kFileResourceId("file:piyo");
const base::FilePath kFile(FPL("foo bar"));
const std::string kFileMD5("file_md5");
{
const char kChangeStampKey[] = "CHANGE_STAMP";
const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR";
const char kDriveMetadataKeyPrefix[] = "METADATA: ";
const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: ";
const char kV0ServiceName[] = "drive";
ASSERT_TRUE(RegisterSyncableFileSystem(kV0ServiceName));
leveldb::Options options;
options.create_if_missing = true;
leveldb::DB* db_ptr = NULL;
std::string db_dir = fileapi::FilePathToString(
base_dir().Append(DriveMetadataStore::kDatabaseName));
leveldb::Status status = leveldb::DB::Open(options, db_dir, &db_ptr);
scoped_ptr<leveldb::DB> db(db_ptr);
ASSERT_TRUE(status.ok());
leveldb::WriteOptions write_options;
db->Put(write_options, kChangeStampKey, "1");
db->Put(write_options, kSyncRootDirectoryKey, kSyncRootResourceId);
DriveMetadata drive_metadata;
drive_metadata.set_resource_id(kFileResourceId);
drive_metadata.set_md5_checksum(kFileMD5);
drive_metadata.set_conflicted(false);
drive_metadata.set_to_be_fetched(false);
fileapi::FileSystemURL url = CreateSyncableFileSystemURL(
kOrigin1, kV0ServiceName, kFile);
std::string serialized_url;
SerializeSyncableFileSystemURL(url, &serialized_url);
std::string metadata_string;
drive_metadata.SerializeToString(&metadata_string);
db->Put(write_options,
kDriveMetadataKeyPrefix + serialized_url, metadata_string);
db->Put(write_options,
kDriveBatchSyncOriginKeyPrefix + kOrigin1.spec(), kResourceId1);
db->Put(write_options,
kDriveIncrementalSyncOriginKeyPrefix + kOrigin2.spec(),
kResourceId2);
EXPECT_TRUE(RevokeSyncableFileSystem(kV0ServiceName));
MarkAsCreated();
}
InitializeDatabase();
EXPECT_EQ(1, metadata_store()->GetLargestChangeStamp());
EXPECT_EQ(kSyncRootResourceId, metadata_store()->sync_root_directory());
EXPECT_EQ(kResourceId2, metadata_store()->GetResourceIdForOrigin(kOrigin2));
DriveMetadata metadata;
EXPECT_EQ(SYNC_STATUS_OK,
metadata_store()->ReadEntry(
CreateSyncableFileSystemURL(kOrigin1, kServiceName, kFile),
&metadata));
EXPECT_EQ(kFileResourceId, metadata.resource_id());
EXPECT_EQ(kFileMD5, metadata.md5_checksum());
EXPECT_FALSE(metadata.conflicted());
EXPECT_FALSE(metadata.to_be_fetched());
VerifyReverseMap();
}
TEST_F(DriveMetadataStoreTest, DeprecateBatchSyncOrigins) {
// Make sure that previously saved batch sync origins were deleted from the DB
// as they are no longer used.
const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: ";
const GURL kOrigin1("chrome-extension://example1");
const std::string kResourceId1("hoge");
// Purposely add in an old batch sync origin (from previous DB version).
{
leveldb::Options options;
options.create_if_missing = true;
leveldb::DB* db_ptr = NULL;
std::string db_dir = fileapi::FilePathToString(
base_dir().Append(DriveMetadataStore::kDatabaseName));
leveldb::DB::Open(options, db_dir, &db_ptr);
scoped_ptr<leveldb::DB> db(db_ptr);
leveldb::WriteOptions write_options;
db->Put(write_options,
kDriveBatchSyncOriginKeyPrefix + kOrigin1.spec(), kResourceId1);
}
InitializeDatabase();
// Confirm no batch sync origins remain after InitializeDatabase.
scoped_ptr<leveldb::Iterator> itr(metadata_db()->NewIterator(
leveldb::ReadOptions()));
int batch_origins_found = 0;
for (itr->Seek(kDriveBatchSyncOriginKeyPrefix); itr->Valid(); itr->Next()) {
std::string key = itr->key().ToString();
if (!StartsWithASCII(key, kDriveBatchSyncOriginKeyPrefix, true))
break;
batch_origins_found++;
}
EXPECT_EQ(0, batch_origins_found);
}
TEST_F(DriveMetadataStoreTest, ResetOriginRootDirectory) {
const GURL kOrigin1("chrome-extension://example1");
const std::string kResourceId1("hoge");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment