Commit 30702684 authored by Yue Zhang's avatar Yue Zhang Committed by Chromium LUCI CQ

Add more functions to ProfileProtoDB

This CL extends the functionality of ProfileProtoDB by adding functions
to load one entry, load all entries and delete one entry in the DB.
These will be used by database for ChromeCart.

Bug: 1157892
Change-Id: Ifaf2dd049ba1a434da7e52c65987050126e30ebe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2594440Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839142}
parent 8e2f8002
......@@ -60,6 +60,12 @@ class ProfileProtoDB : public KeyedService {
ProfileProtoDB& operator=(const ProfileProtoDB&) = delete;
~ProfileProtoDB() override;
// Loads the entry for the key and passes it to the callback.
void LoadOneEntry(const std::string& key, LoadCallback callback);
// Loads all entries within the databse and passes them to the callback.
void LoadAllEntries(LoadCallback callback);
// Loads the content data matching a prefix for the key and passes them to the
// callback.
void LoadContentWithPrefix(const std::string& key_prefix,
......@@ -71,6 +77,9 @@ class ProfileProtoDB : public KeyedService {
const T& value,
OperationCallback callback);
// Deletes the entry with certain key in the database.
void DeleteOneEntry(const std::string& key, OperationCallback callback);
// Deletes content in the database, matching all keys which have a prefix
// that matches the key.
void DeleteContentWithPrefix(const std::string& key_prefix,
......@@ -102,6 +111,11 @@ class ProfileProtoDB : public KeyedService {
// Passes back database status following database initialization.
void OnDatabaseInitialized(leveldb_proto::Enums::InitStatus status);
// Callback when one entry is loaded.
void OnLoadOneEntry(LoadCallback callback,
bool success,
std::unique_ptr<T> entry);
// Callback when content is loaded.
void OnLoadContent(LoadCallback callback,
bool success,
......@@ -151,13 +165,49 @@ bool DatabasePrefixFilter(const std::string& key_prefix,
template <typename T>
ProfileProtoDB<T>::~ProfileProtoDB() = default;
template <typename T>
void ProfileProtoDB<T>::LoadOneEntry(const std::string& key,
LoadCallback callback) {
if (InitStatusUnknown()) {
deferred_operations_.push_back(base::BindOnce(
&ProfileProtoDB::LoadOneEntry, weak_ptr_factory_.GetWeakPtr(), key,
std::move(callback)));
} else if (FailedToInit()) {
base::ThreadPool::PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), false, std::vector<KeyAndValue>()));
} else {
storage_database_->GetEntry(
key,
base::BindOnce(&ProfileProtoDB::OnLoadOneEntry,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
}
template <typename T>
void ProfileProtoDB<T>::LoadAllEntries(LoadCallback callback) {
if (InitStatusUnknown()) {
deferred_operations_.push_back(
base::BindOnce(&ProfileProtoDB::LoadAllEntries,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
} else if (FailedToInit()) {
base::ThreadPool::PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), false, std::vector<KeyAndValue>()));
} else {
storage_database_->LoadEntries(
base::BindOnce(&ProfileProtoDB::OnLoadContent,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
}
template <typename T>
void ProfileProtoDB<T>::LoadContentWithPrefix(const std::string& key_prefix,
LoadCallback callback) {
if (InitStatusUnknown()) {
deferred_operations_.push_back(base::BindOnce(
&ProfileProtoDB::LoadContentWithPrefix, weak_ptr_factory_.GetWeakPtr(),
std::move(key_prefix), std::move(callback)));
key_prefix, std::move(callback)));
} else if (FailedToInit()) {
base::ThreadPool::PostTask(
FROM_HERE,
......@@ -180,8 +230,8 @@ void ProfileProtoDB<T>::InsertContent(const std::string& key,
OperationCallback callback) {
if (InitStatusUnknown()) {
deferred_operations_.push_back(base::BindOnce(
&ProfileProtoDB::InsertContent, weak_ptr_factory_.GetWeakPtr(),
std::move(key), std::move(value), std::move(callback)));
&ProfileProtoDB::InsertContent, weak_ptr_factory_.GetWeakPtr(), key,
std::move(value), std::move(callback)));
} else if (FailedToInit()) {
base::ThreadPool::PostTask(FROM_HERE,
base::BindOnce(std::move(callback), false));
......@@ -196,24 +246,42 @@ void ProfileProtoDB<T>::InsertContent(const std::string& key,
}
}
template <typename T>
void ProfileProtoDB<T>::DeleteOneEntry(const std::string& key,
OperationCallback callback) {
if (InitStatusUnknown()) {
deferred_operations_.push_back(base::BindOnce(
&ProfileProtoDB::DeleteOneEntry, weak_ptr_factory_.GetWeakPtr(), key,
std::move(callback)));
} else if (FailedToInit()) {
base::ThreadPool::PostTask(FROM_HERE,
base::BindOnce(std::move(callback), false));
} else {
auto keys = std::make_unique<std::vector<std::string>>();
keys->push_back(key);
storage_database_->UpdateEntries(
std::make_unique<ContentEntry>(), std::move(keys),
base::BindOnce(&ProfileProtoDB::OnOperationCommitted,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
}
// Deletes content in the database, matching all keys which have a prefix
// that matches the key.
template <typename T>
void ProfileProtoDB<T>::DeleteContentWithPrefix(const std::string& key_prefix,
OperationCallback callback) {
if (InitStatusUnknown()) {
deferred_operations_.push_back(
base::BindOnce(&ProfileProtoDB::DeleteContentWithPrefix,
weak_ptr_factory_.GetWeakPtr(), std::move(key_prefix),
std::move(callback)));
deferred_operations_.push_back(base::BindOnce(
&ProfileProtoDB::DeleteContentWithPrefix,
weak_ptr_factory_.GetWeakPtr(), key_prefix, std::move(callback)));
} else if (FailedToInit()) {
base::ThreadPool::PostTask(FROM_HERE,
base::BindOnce(std::move(callback), false));
} else {
storage_database_->UpdateEntriesWithRemoveFilter(
std::make_unique<ContentEntry>(),
std::move(
base::BindRepeating(&DatabasePrefixFilter, std::move(key_prefix))),
std::move(base::BindRepeating(&DatabasePrefixFilter, key_prefix)),
base::BindOnce(&ProfileProtoDB::OnOperationCommitted,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
......@@ -283,6 +351,18 @@ void ProfileProtoDB<T>::OnDatabaseInitialized(
deferred_operations_.clear();
}
// Callback when one entry is loaded.
template <typename T>
void ProfileProtoDB<T>::OnLoadOneEntry(LoadCallback callback,
bool success,
std::unique_ptr<T> entry) {
std::vector<KeyAndValue> results;
if (success && entry) {
results.emplace_back(entry->key(), *entry);
}
std::move(callback).Run(success, std::move(results));
}
// Callback when content is loaded.
template <typename T>
void ProfileProtoDB<T>::OnLoadContent(LoadCallback callback,
......
......@@ -36,22 +36,32 @@ profile_proto_db::ProfileProtoDBTestProto BuildTestProto(const char* key,
return proto;
}
const char kMockKey[] = "key";
const char kMockKeyPrefix[] = "k";
const std::vector<uint8_t> kMockValueArray = {0xfa, 0x5b, 0x4c, 0x12};
const persisted_state_db::PersistedStateContentProto kMockValue =
BuildProto(kMockKey, kMockValueArray);
const char kMockKeyA[] = "A_key";
const char kMockKeyPrefixA[] = "A";
const std::vector<uint8_t> kMockValueArrayA = {0xfa, 0x5b, 0x4c, 0x12};
const persisted_state_db::PersistedStateContentProto kMockValueA =
BuildProto(kMockKeyA, kMockValueArrayA);
const std::vector<
ProfileProtoDB<persisted_state_db::PersistedStateContentProto>::KeyAndValue>
kExpected = {{kMockKey, kMockValue}};
kExpectedA = {{kMockKeyA, kMockValueA}};
const char kMockKeyB[] = "B_key";
const std::vector<uint8_t> kMockValueArrayB = {0x3c, 0x9f, 0x5e, 0x69};
const persisted_state_db::PersistedStateContentProto kMockValueB =
BuildProto(kMockKeyB, kMockValueArrayB);
const std::vector<
ProfileProtoDB<persisted_state_db::PersistedStateContentProto>::KeyAndValue>
kExpectedB = {{kMockKeyB, kMockValueB}};
const std::vector<
ProfileProtoDB<persisted_state_db::PersistedStateContentProto>::KeyAndValue>
kExpectedAB = {{kMockKeyA, kMockValueA}, {kMockKeyB, kMockValueB}};
const std::vector<
ProfileProtoDB<persisted_state_db::PersistedStateContentProto>::KeyAndValue>
kEmptyExpected = {};
const profile_proto_db::ProfileProtoDBTestProto kTestProto =
BuildTestProto(kMockKey, 42);
BuildTestProto(kMockKeyA, 42);
const std::vector<
ProfileProtoDB<profile_proto_db::ProfileProtoDBTestProto>::KeyAndValue>
kTestProtoExpected = {{kMockKey, kTestProto}};
kTestProtoExpected = {{kMockKeyA, kTestProto}};
} // namespace
......@@ -229,14 +239,14 @@ TEST_F(ProfileProtoDBTest, TestArbitraryProto) {
RunUntilIdle();
base::RunLoop run_loop[2];
test_proto_db()->InsertContent(
kMockKey, kTestProto,
kMockKeyA, kTestProto,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
test_content_db()->UpdateCallback(true);
RunUntilIdle();
run_loop[0].Run();
test_proto_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetTestEvaluationTestProtoDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kTestProtoExpected));
......@@ -254,16 +264,16 @@ TEST_F(ProfileProtoDBTest, TestKeyInsertionSucceeded) {
InitPersistedStateDB();
base::RunLoop run_loop[2];
persisted_state_db()->InsertContent(
kMockKey, kMockValue,
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[0].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kExpected));
kExpectedA));
MockLoadCallbackPersistedStateDB(content_db(), true);
run_loop[1].Run();
}
......@@ -272,13 +282,13 @@ TEST_F(ProfileProtoDBTest, TestKeyInsertionFailed) {
InitPersistedStateDB();
base::RunLoop run_loop[2];
persisted_state_db()->InsertContent(
kMockKey, kMockValue,
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), false));
MockInsertCallbackPersistedStateDB(content_db(), false);
run_loop[0].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kEmptyExpected));
......@@ -290,46 +300,99 @@ TEST_F(ProfileProtoDBTest, TestKeyInsertionPrefix) {
InitPersistedStateDB();
base::RunLoop run_loop[2];
persisted_state_db()->InsertContent(
kMockKey, kMockValue,
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[0].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKeyPrefix,
kMockKeyPrefixA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kExpected));
kExpectedA));
MockLoadCallbackPersistedStateDB(content_db(), true);
run_loop[1].Run();
}
TEST_F(ProfileProtoDBTest, TestDelete) {
TEST_F(ProfileProtoDBTest, TestLoadOneEntry) {
InitPersistedStateDB();
base::RunLoop run_loop[4];
persisted_state_db()->InsertContent(
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[0].Run();
persisted_state_db()->InsertContent(
kMockKeyB, kMockValueB,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[1].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[1].Run();
persisted_state_db()->LoadOneEntry(
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[2].QuitClosure(),
kExpectedA));
content_db()->GetCallback(true);
run_loop[2].Run();
persisted_state_db()->LoadOneEntry(
kMockKeyB,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[3].QuitClosure(),
kExpectedB));
content_db()->GetCallback(true);
run_loop[3].Run();
}
TEST_F(ProfileProtoDBTest, TestLoadAllEntries) {
InitPersistedStateDB();
base::RunLoop run_loop[3];
persisted_state_db()->InsertContent(
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[0].Run();
persisted_state_db()->InsertContent(
kMockKeyB, kMockValueB,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[1].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[1].Run();
persisted_state_db()->LoadAllEntries(base::BindOnce(
&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[2].QuitClosure(), kExpectedAB));
MockLoadCallbackPersistedStateDB(content_db(), true);
run_loop[2].Run();
}
TEST_F(ProfileProtoDBTest, TestDeleteWithPrefix) {
InitPersistedStateDB();
base::RunLoop run_loop[4];
persisted_state_db()->InsertContent(
kMockKey, kMockValue,
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[0].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kExpected));
kExpectedA));
MockLoadCallbackPersistedStateDB(content_db(), true);
run_loop[1].Run();
persisted_state_db()->DeleteContentWithPrefix(
kMockKey,
kMockKeyPrefixA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[2].QuitClosure(), true));
MockDeleteCallbackPersistedStateDB(content_db(), true);
run_loop[2].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[3].QuitClosure(),
kEmptyExpected));
......@@ -337,6 +400,50 @@ TEST_F(ProfileProtoDBTest, TestDelete) {
run_loop[3].Run();
}
TEST_F(ProfileProtoDBTest, TestDeleteOneEntry) {
InitPersistedStateDB();
base::RunLoop run_loop[6];
persisted_state_db()->InsertContent(
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
MockInsertCallbackPersistedStateDB(content_db(), true);
run_loop[0].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kExpectedA));
MockLoadCallbackPersistedStateDB(content_db(), true);
run_loop[1].Run();
persisted_state_db()->DeleteOneEntry(
kMockKeyPrefixA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[2].QuitClosure(), false));
MockDeleteCallbackPersistedStateDB(content_db(), false);
run_loop[2].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[3].QuitClosure(),
kExpectedA));
MockLoadCallbackPersistedStateDB(content_db(), true);
run_loop[3].Run();
persisted_state_db()->DeleteOneEntry(
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[4].QuitClosure(), true));
MockDeleteCallbackPersistedStateDB(content_db(), true);
run_loop[4].Run();
persisted_state_db()->LoadContentWithPrefix(
kMockKeyPrefixA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[5].QuitClosure(),
kEmptyExpected));
MockLoadCallbackPersistedStateDB(content_db(), true);
run_loop[5].Run();
}
TEST_F(ProfileProtoDBTest, TestDeferredOperations) {
InitPersistedStateDBWithoutCallback();
RunUntilIdle();
......@@ -344,14 +451,14 @@ TEST_F(ProfileProtoDBTest, TestDeferredOperations) {
base::RunLoop run_loop[4];
persisted_state_db()->InsertContent(
kMockKey, kMockValue,
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kExpected));
kExpectedA));
EXPECT_EQ(2u, deferred_operations().size());
content_db()->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
......@@ -364,14 +471,14 @@ TEST_F(ProfileProtoDBTest, TestDeferredOperations) {
EXPECT_EQ(0u, deferred_operations().size());
persisted_state_db()->DeleteContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[2].QuitClosure(), true));
EXPECT_EQ(0u, deferred_operations().size());
MockDeleteCallbackPersistedStateDB(content_db(), true);
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[3].QuitClosure(),
kEmptyExpected));
......@@ -388,16 +495,16 @@ TEST_F(ProfileProtoDBTest, TestInitializationFailure) {
// Do some operations before database status is known
persisted_state_db()->InsertContent(
kMockKey, kMockValue,
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), false));
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[1].QuitClosure(),
kEmptyExpected));
persisted_state_db()->DeleteContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[2].QuitClosure(), false));
EXPECT_EQ(3u, deferred_operations().size());
......@@ -415,16 +522,16 @@ TEST_F(ProfileProtoDBTest, TestInitializationFailure) {
// More operations should just return false/null as the database
// failed to initialize
persisted_state_db()->InsertContent(
kMockKey, kMockValue,
kMockKeyA, kMockValueA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[3].QuitClosure(), false));
persisted_state_db()->LoadContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::GetEvaluationPersistedStateDB,
base::Unretained(this), run_loop[4].QuitClosure(),
kEmptyExpected));
persisted_state_db()->DeleteContentWithPrefix(
kMockKey,
kMockKeyA,
base::BindOnce(&ProfileProtoDBTest::OperationEvaluation,
base::Unretained(this), run_loop[5].QuitClosure(), false));
......
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