blob: ff134e7349ba574c1f8cfbfbb3943375e02f62a9 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_LEVELDB_PROTO_MIGRATION_DELEGATE_H_
#define COMPONENTS_LEVELDB_PROTO_MIGRATION_DELEGATE_H_
#include "base/bind.h"
#include "base/callback.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/leveldb_proto/proto_database.h"
namespace leveldb_proto {
// Small class that strictly performs the migration functionality of
// SharedProtoDatabase.
template <typename T>
class MigrationDelegate {
public:
using MigrationCallback = base::OnceCallback<void(bool)>;
MigrationDelegate();
// Copies the keys/entries of |from| to |to|, and returns a boolean success
// in |callback|.
void DoMigration(ProtoDatabase<T>* from,
ProtoDatabase<T>* to,
MigrationCallback callback);
private:
void OnLoadKeysAndEntries(
MigrationCallback callback,
ProtoDatabase<T>* to,
bool success,
std::unique_ptr<std::map<std::string, T>> keys_entries);
void OnUpdateEntries(MigrationCallback callback, bool success);
base::WeakPtrFactory<MigrationDelegate<T>> weak_ptr_factory_;
};
template <typename T>
MigrationDelegate<T>::MigrationDelegate() : weak_ptr_factory_(this) {}
template <typename T>
void MigrationDelegate<T>::DoMigration(ProtoDatabase<T>* from,
ProtoDatabase<T>* to,
MigrationCallback callback) {
from->LoadKeysAndEntries(
base::BindOnce(&MigrationDelegate<T>::OnLoadKeysAndEntries,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
base::Unretained(to)));
}
template <typename T>
void MigrationDelegate<T>::OnLoadKeysAndEntries(
MigrationCallback callback,
ProtoDatabase<T>* to,
bool success,
std::unique_ptr<std::map<std::string, T>> keys_entries) {
if (!success) {
DCHECK(base::SequencedTaskRunnerHandle::IsSet());
auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
current_task_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), false));
return;
}
// Convert the std::map we got back into a vector of std::pairs to be used
// with UpdateEntries.
auto kev = std::make_unique<typename ProtoDatabase<T>::KeyEntryVector>();
for (auto const& key_entry : *keys_entries)
kev->push_back(key_entry);
// Save the entries in |to|.
to->UpdateEntries(
std::move(kev), std::make_unique<std::vector<std::string>>(),
base::BindOnce(&MigrationDelegate<T>::OnUpdateEntries,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
template <typename T>
void MigrationDelegate<T>::OnUpdateEntries(MigrationCallback callback,
bool success) {
DCHECK(base::SequencedTaskRunnerHandle::IsSet());
auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
current_task_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), success));
// TODO (thildebr): For additional insurance, verify the entries match,
// although they should if we got a success from UpdateEntries.
}
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_MIGRATION_DELEGATE_H_