blob: e23e49ead2e60f86fb2c4c0da3ac669f5389fede [file] [log] [blame]
alexilin6175b0a2017-04-28 17:34:401// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
David Van Clevea86bcb22020-01-21 17:25:445#ifndef COMPONENTS_SQLITE_PROTO_KEY_VALUE_TABLE_H_
6#define COMPONENTS_SQLITE_PROTO_KEY_VALUE_TABLE_H_
alexilin6175b0a2017-04-28 17:34:407
8#include <map>
9#include <string>
10#include <vector>
11
alexilin6175b0a2017-04-28 17:34:4012#include "sql/statement.h"
13
14namespace google {
15namespace protobuf {
16class MessageLite;
17}
Alex Ilindc577692019-05-29 09:27:2918} // namespace google
alexilin6175b0a2017-04-28 17:34:4019
David Van Clevea4e3ee12020-01-21 20:07:0120namespace sqlite_proto {
alexilin6175b0a2017-04-28 17:34:4021
22namespace internal {
23
24void BindDataToStatement(const std::string& key,
25 const google::protobuf::MessageLite& data,
26 sql::Statement* statement);
27
28std::string GetSelectAllSql(const std::string& table_name);
29std::string GetReplaceSql(const std::string& table_name);
30std::string GetDeleteSql(const std::string& table_name);
31std::string GetDeleteAllSql(const std::string& table_name);
32
33} // namespace internal
34
Alexandr Ilineb0f08a2017-05-30 10:55:3435// The backend class helps perform database operations on a single table. The
36// table name is passed as a constructor argument. The table schema is fixed: it
37// always consists of two columns, TEXT type "key" and BLOB type "proto". The
38// class doesn't manage the creation and the deletion of the table.
39//
Alexandr Ilin9a16ee72017-08-16 13:13:3440// All the functions except of the constructor must be called on a DB sequence
David Van Clevea4e3ee12020-01-21 20:07:0141// of the corresponding TableManager. The preferred way to call the methods of
42// this class is passing the method to TableManager::ScheduleDBTask().
Alexandr Ilineb0f08a2017-05-30 10:55:3443//
44// Example:
David Van Clevea4e3ee12020-01-21 20:07:0145// manager_->ScheduleDBTask(
Alexandr Ilineb0f08a2017-05-30 10:55:3446// FROM_HERE,
David Van Clevea4e3ee12020-01-21 20:07:0147// base::BindOnce(&KeyValueTable<PrefetchData>::UpdateData,
Alexandr Ilineb0f08a2017-05-30 10:55:3448// base::Unretained(table_), key, data));
alexilin6175b0a2017-04-28 17:34:4049template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:0150class KeyValueTable {
alexilin6175b0a2017-04-28 17:34:4051 public:
David Van Clevea4e3ee12020-01-21 20:07:0152 explicit KeyValueTable(const std::string& table_name);
alexilin6175b0a2017-04-28 17:34:4053 // Virtual for testing.
David Van Clevea4e3ee12020-01-21 20:07:0154 virtual ~KeyValueTable() = default;
55
56 KeyValueTable(const KeyValueTable&) = delete;
57 KeyValueTable& operator=(const KeyValueTable&) = delete;
58
Alexandr Ilineb0f08a2017-05-30 10:55:3459 virtual void GetAllData(std::map<std::string, T>* data_map,
Victor Costancfbfa602018-08-01 23:24:4660 sql::Database* db) const;
Alexandr Ilineb0f08a2017-05-30 10:55:3461 virtual void UpdateData(const std::string& key,
62 const T& data,
Victor Costancfbfa602018-08-01 23:24:4663 sql::Database* db);
Alexandr Ilineb0f08a2017-05-30 10:55:3464 virtual void DeleteData(const std::vector<std::string>& keys,
Victor Costancfbfa602018-08-01 23:24:4665 sql::Database* db);
66 virtual void DeleteAllData(sql::Database* db);
alexilin6175b0a2017-04-28 17:34:4067
68 private:
69 const std::string table_name_;
alexilin6175b0a2017-04-28 17:34:4070};
71
72template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:0173KeyValueTable<T>::KeyValueTable(const std::string& table_name)
Alexandr Ilineb0f08a2017-05-30 10:55:3474 : table_name_(table_name) {}
alexilin6175b0a2017-04-28 17:34:4075
76template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:0177void KeyValueTable<T>::GetAllData(std::map<std::string, T>* data_map,
78 sql::Database* db) const {
Alexandr Ilineb0f08a2017-05-30 10:55:3479 sql::Statement reader(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:0180 ::sqlite_proto::internal::GetSelectAllSql(table_name_).c_str()));
alexilin6175b0a2017-04-28 17:34:4081 while (reader.Step()) {
82 auto it = data_map->emplace(reader.ColumnString(0), T()).first;
83 int size = reader.ColumnByteLength(1);
84 const void* blob = reader.ColumnBlob(1);
85 DCHECK(blob);
86 it->second.ParseFromArray(blob, size);
87 }
88}
89
90template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:0191void KeyValueTable<T>::UpdateData(const std::string& key,
92 const T& data,
93 sql::Database* db) {
Alexandr Ilineb0f08a2017-05-30 10:55:3494 sql::Statement inserter(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:0195 ::sqlite_proto::internal::GetReplaceSql(table_name_).c_str()));
96 ::sqlite_proto::internal::BindDataToStatement(key, data, &inserter);
alexilin6175b0a2017-04-28 17:34:4097 inserter.Run();
98}
99
100template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:01101void KeyValueTable<T>::DeleteData(const std::vector<std::string>& keys,
102 sql::Database* db) {
Alexandr Ilineb0f08a2017-05-30 10:55:34103 sql::Statement deleter(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:01104 ::sqlite_proto::internal::GetDeleteSql(table_name_).c_str()));
alexilin6175b0a2017-04-28 17:34:40105 for (const auto& key : keys) {
alexilin6175b0a2017-04-28 17:34:40106 deleter.BindString(0, key);
107 deleter.Run();
Alexandr Ilineb0f08a2017-05-30 10:55:34108 deleter.Reset(true);
alexilin6175b0a2017-04-28 17:34:40109 }
110}
111
112template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:01113void KeyValueTable<T>::DeleteAllData(sql::Database* db) {
Alexandr Ilineb0f08a2017-05-30 10:55:34114 sql::Statement deleter(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:01115 ::sqlite_proto::internal::GetDeleteAllSql(table_name_).c_str()));
alexilin6175b0a2017-04-28 17:34:40116 deleter.Run();
117}
118
David Van Clevea4e3ee12020-01-21 20:07:01119} // namespace sqlite_proto
alexilin6175b0a2017-04-28 17:34:40120
David Van Clevea86bcb22020-01-21 17:25:44121#endif // COMPONENTS_SQLITE_PROTO_KEY_VALUE_TABLE_H_