blob: b84bb7db1b67407f0daa698a2e0a6e4324fd3e8a [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,
David Van Cleve1b47a512020-08-13 22:13:3948// table_->AsWeakPtr(), key, data));
49//
50// TODO(crbug.com/1115398): Supporting weak pointers is a temporary measure
51// mitigating a crash caused by complex lifetime requirements for KeyValueTable
52// relative to the related classes. Making KeyValueTable<T> stateless instead
53// could be a better way to resolve these lifetime issues in the long run.
alexilin6175b0a2017-04-28 17:34:4054template <typename T>
David Van Cleve1b47a512020-08-13 22:13:3955class KeyValueTable : public base::SupportsWeakPtr<KeyValueTable<T>> {
alexilin6175b0a2017-04-28 17:34:4056 public:
David Van Clevea4e3ee12020-01-21 20:07:0157 explicit KeyValueTable(const std::string& table_name);
alexilin6175b0a2017-04-28 17:34:4058 // Virtual for testing.
David Van Clevea4e3ee12020-01-21 20:07:0159 virtual ~KeyValueTable() = default;
60
61 KeyValueTable(const KeyValueTable&) = delete;
62 KeyValueTable& operator=(const KeyValueTable&) = delete;
63
Alexandr Ilineb0f08a2017-05-30 10:55:3464 virtual void GetAllData(std::map<std::string, T>* data_map,
Victor Costancfbfa602018-08-01 23:24:4665 sql::Database* db) const;
Alexandr Ilineb0f08a2017-05-30 10:55:3466 virtual void UpdateData(const std::string& key,
67 const T& data,
Victor Costancfbfa602018-08-01 23:24:4668 sql::Database* db);
Alexandr Ilineb0f08a2017-05-30 10:55:3469 virtual void DeleteData(const std::vector<std::string>& keys,
Victor Costancfbfa602018-08-01 23:24:4670 sql::Database* db);
71 virtual void DeleteAllData(sql::Database* db);
alexilin6175b0a2017-04-28 17:34:4072
73 private:
74 const std::string table_name_;
alexilin6175b0a2017-04-28 17:34:4075};
76
77template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:0178KeyValueTable<T>::KeyValueTable(const std::string& table_name)
Alexandr Ilineb0f08a2017-05-30 10:55:3479 : table_name_(table_name) {}
alexilin6175b0a2017-04-28 17:34:4080
81template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:0182void KeyValueTable<T>::GetAllData(std::map<std::string, T>* data_map,
83 sql::Database* db) const {
Alexandr Ilineb0f08a2017-05-30 10:55:3484 sql::Statement reader(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:0185 ::sqlite_proto::internal::GetSelectAllSql(table_name_).c_str()));
alexilin6175b0a2017-04-28 17:34:4086 while (reader.Step()) {
87 auto it = data_map->emplace(reader.ColumnString(0), T()).first;
Victor Costan1268a9992021-07-16 17:16:3988 base::span<const uint8_t> blob = reader.ColumnBlob(1);
89 it->second.ParseFromArray(blob.data(), blob.size());
alexilin6175b0a2017-04-28 17:34:4090 }
91}
92
93template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:0194void KeyValueTable<T>::UpdateData(const std::string& key,
95 const T& data,
96 sql::Database* db) {
Alexandr Ilineb0f08a2017-05-30 10:55:3497 sql::Statement inserter(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:0198 ::sqlite_proto::internal::GetReplaceSql(table_name_).c_str()));
99 ::sqlite_proto::internal::BindDataToStatement(key, data, &inserter);
alexilin6175b0a2017-04-28 17:34:40100 inserter.Run();
101}
102
103template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:01104void KeyValueTable<T>::DeleteData(const std::vector<std::string>& keys,
105 sql::Database* db) {
Alexandr Ilineb0f08a2017-05-30 10:55:34106 sql::Statement deleter(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:01107 ::sqlite_proto::internal::GetDeleteSql(table_name_).c_str()));
alexilin6175b0a2017-04-28 17:34:40108 for (const auto& key : keys) {
alexilin6175b0a2017-04-28 17:34:40109 deleter.BindString(0, key);
110 deleter.Run();
Alexandr Ilineb0f08a2017-05-30 10:55:34111 deleter.Reset(true);
alexilin6175b0a2017-04-28 17:34:40112 }
113}
114
115template <typename T>
David Van Clevea4e3ee12020-01-21 20:07:01116void KeyValueTable<T>::DeleteAllData(sql::Database* db) {
Alexandr Ilineb0f08a2017-05-30 10:55:34117 sql::Statement deleter(db->GetUniqueStatement(
David Van Clevea4e3ee12020-01-21 20:07:01118 ::sqlite_proto::internal::GetDeleteAllSql(table_name_).c_str()));
alexilin6175b0a2017-04-28 17:34:40119 deleter.Run();
120}
121
David Van Clevea4e3ee12020-01-21 20:07:01122} // namespace sqlite_proto
alexilin6175b0a2017-04-28 17:34:40123
David Van Clevea86bcb22020-01-21 17:25:44124#endif // COMPONENTS_SQLITE_PROTO_KEY_VALUE_TABLE_H_