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..d3bc8ecacf4568c43e036b9c6cddd6286ba83c83 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,13 @@ |
#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 kLatestSchemaVersion = 1; |
+const char kDBSchemaDescriptorRecordId[] = "_mts_schema_descriptor"; |
+ |
// static |
base::LazyInstance<ModelTypeStoreBackend::BackendMap> |
ModelTypeStoreBackend::backend_map_ = LAZY_INSTANCE_INITIALIZER; |
@@ -80,6 +86,19 @@ ModelTypeStore::Result ModelTypeStoreBackend::Init( |
return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
} |
db_.reset(db_raw); |
+ |
+ ModelTypeStoreSchemaDescriptor current_descriptor; |
+ if (!GetStoreDescriptor(¤t_descriptor)) { |
+ return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+ } |
+ |
+ if (current_descriptor.version_number() < kLatestSchemaVersion) { |
+ ModelTypeStoreSchemaDescriptor desired_descriptor; |
+ desired_descriptor.set_version_number(kLatestSchemaVersion); |
+ if (!Migrate(current_descriptor, desired_descriptor)) { |
+ return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+ } |
+ } |
return ModelTypeStore::Result::SUCCESS; |
} |
@@ -99,8 +118,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 +142,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 +158,44 @@ ModelTypeStore::Result ModelTypeStoreBackend::WriteModifications( |
: ModelTypeStore::Result::UNSPECIFIED_ERROR; |
} |
+bool ModelTypeStoreBackend::GetStoreDescriptor( |
+ ModelTypeStoreSchemaDescriptor* schema_descriptor) { |
+ DCHECK(db_); |
+ leveldb::ReadOptions read_options; |
+ read_options.verify_checksums = true; |
+ std::string value; |
+ leveldb::Status status = |
+ db_->Get(read_options, kDBSchemaDescriptorRecordId, &value); |
+ if (status.IsNotFound()) { |
+ schema_descriptor->set_version_number(0); |
+ return true; |
+ } else if (!status.ok()) { |
+ return false; |
+ } |
+ return schema_descriptor->ParseFromString(value); |
+} |
+ |
+bool ModelTypeStoreBackend::Migrate( |
+ const ModelTypeStoreSchemaDescriptor& current_descriptor, |
+ const ModelTypeStoreSchemaDescriptor& desired_descriptor) { |
+ DCHECK(db_); |
+ int64_t current_version = current_descriptor.version_number(); |
+ if (current_version == 0) { |
+ if (Migrate0To1()) { |
+ current_version = 1; |
+ } |
+ } |
+ return current_version == desired_descriptor.version_number(); |
+} |
+ |
+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 |