Index: components/sync/model_impl/model_type_store_backend.cc |
diff --git a/components/sync/model_impl/model_type_store_backend.cc b/components/sync/model_impl/model_type_store_backend.cc |
index 564bbd3dbe6f038513657d10f539e2cec2b12be4..37ee1c8eb9a5c8507d5584d26f91b39644285b63 100644 |
--- a/components/sync/model_impl/model_type_store_backend.cc |
+++ b/components/sync/model_impl/model_type_store_backend.cc |
@@ -8,6 +8,7 @@ |
#include "base/files/file_path.h" |
#include "base/memory/ptr_util.h" |
+#include "components/sync/protocol/model_type_store_schema_descriptor.pb.h" |
#include "third_party/leveldatabase/env_chromium.h" |
#include "third_party/leveldatabase/src/helpers/memenv/memenv.h" |
#include "third_party/leveldatabase/src/include/leveldb/db.h" |
@@ -18,8 +19,15 @@ |
#include "third_party/leveldatabase/src/include/leveldb/status.h" |
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
+using sync_pb::ModelTypeStoreSchemaDescriptor; |
+ |
namespace syncer { |
+const int64_t kInvalidSchemaVersion = -1; |
+const int64_t ModelTypeStoreBackend::kLatestSchemaVersion = 1; |
+const char ModelTypeStoreBackend::kDBSchemaDescriptorRecordId[] = |
+ "_mts_schema_descriptor"; |
+ |
// static |
base::LazyInstance<ModelTypeStoreBackend::BackendMap> |
ModelTypeStoreBackend::backend_map_ = LAZY_INSTANCE_INITIALIZER; |
@@ -80,6 +88,19 @@ ModelTypeStore::Result ModelTypeStoreBackend::Init( |
return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
} |
db_.reset(db_raw); |
+ |
+ int64_t current_version = GetStoreVersion(); |
+ if (current_version == kInvalidSchemaVersion) { |
+ return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+ } |
+ |
+ if (current_version != kLatestSchemaVersion) { |
+ ModelTypeStore::Result result = |
+ Migrate(current_version, kLatestSchemaVersion); |
+ if (result != ModelTypeStore::Result::SUCCESS) { |
+ return result; |
+ } |
+ } |
return ModelTypeStore::Result::SUCCESS; |
} |
@@ -99,8 +120,7 @@ ModelTypeStore::Result ModelTypeStoreBackend::ReadRecordsWithPrefix( |
key = prefix + id; |
leveldb::Status status = db_->Get(read_options, key, &value); |
if (status.ok()) { |
- // TODO(pavely): Use emplace_back instead of push_back once it is allowed. |
- record_list->push_back(ModelTypeStore::Record(id, value)); |
+ record_list->emplace_back(id, value); |
} else if (status.IsNotFound()) { |
missing_id_list->push_back(id); |
} else { |
@@ -124,9 +144,7 @@ ModelTypeStore::Result ModelTypeStoreBackend::ReadAllRecordsWithPrefix( |
if (!key.starts_with(prefix_slice)) |
break; |
key.remove_prefix(prefix_slice.size()); |
- // TODO(pavely): Use emplace_back instead of push_back once it is allowed. |
- record_list->push_back( |
- ModelTypeStore::Record(key.ToString(), iter->value().ToString())); |
+ record_list->emplace_back(key.ToString(), iter->value().ToString()); |
} |
return iter->status().ok() ? ModelTypeStore::Result::SUCCESS |
: ModelTypeStore::Result::UNSPECIFIED_ERROR; |
@@ -142,4 +160,47 @@ ModelTypeStore::Result ModelTypeStoreBackend::WriteModifications( |
: ModelTypeStore::Result::UNSPECIFIED_ERROR; |
} |
+int64_t ModelTypeStoreBackend::GetStoreVersion() { |
+ DCHECK(db_); |
+ leveldb::ReadOptions read_options; |
+ read_options.verify_checksums = true; |
+ std::string value; |
+ ModelTypeStoreSchemaDescriptor schema_descriptor; |
+ leveldb::Status status = |
+ db_->Get(read_options, kDBSchemaDescriptorRecordId, &value); |
+ if (status.IsNotFound()) { |
+ return 0; |
+ } else if (!status.ok() || !schema_descriptor.ParseFromString(value)) { |
+ return kInvalidSchemaVersion; |
+ } |
+ return schema_descriptor.version_number(); |
+} |
+ |
+ModelTypeStore::Result ModelTypeStoreBackend::Migrate(int64_t current_version, |
+ int64_t desired_version) { |
+ DCHECK(db_); |
+ if (current_version == 0) { |
+ if (Migrate0To1()) { |
+ current_version = 1; |
+ } |
+ } |
+ if (current_version == desired_version) { |
+ return ModelTypeStore::Result::SUCCESS; |
+ } else if (current_version > desired_version) { |
+ return ModelTypeStore::Result::SCHEMA_VERSION_TOO_HIGH; |
+ } else { |
+ return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+ } |
+} |
+ |
+bool ModelTypeStoreBackend::Migrate0To1() { |
+ DCHECK(db_); |
+ ModelTypeStoreSchemaDescriptor schema_descriptor; |
+ schema_descriptor.set_version_number(1); |
+ leveldb::Status status = |
+ db_->Put(leveldb::WriteOptions(), kDBSchemaDescriptorRecordId, |
+ schema_descriptor.SerializeAsString()); |
+ return status.ok(); |
+} |
+ |
} // namespace syncer |