| Flutter Impeller |

archive_database.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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
5 #include "impeller/archivist/archive_database.h"
6
7 #include "third_party/sqlite/sqlite3.h"
8
9 #include <sstream>
10 #include <string>
11
12 #include "impeller/archivist/archive.h"
13 #include "impeller/archivist/archive_class_registration.h"
14 #include "impeller/archivist/archive_statement.h"
15 #include "impeller/base/validation.h"
16
17 namespace impeller {
18
19 struct ArchiveDatabase::Handle {
20 explicit Handle(const std::string& filename) {
21 if (::sqlite3_initialize() != SQLITE_OK) {
22 VALIDATION_LOG << "Could not initialize sqlite.";
23 return;
24 }
25
26 sqlite3* db = nullptr;
27 auto res = ::sqlite3_open(filename.c_str(), &db);
28
29 if (res != SQLITE_OK || db == nullptr) {
30 return;
31 }
32
33 handle_ = db;
34 }
35
36 ~Handle() {
37 if (handle_ == nullptr) {
38 return;
39 }
40 ::sqlite3_close(handle_);
41 }
42
43 ::sqlite3* Get() const { return handle_; }
44
45 bool IsValid() const { return handle_ != nullptr; }
46
47 private:
48 ::sqlite3* handle_ = nullptr;
49
50 Handle(const Handle&) = delete;
51
52 Handle& operator=(const Handle&) = delete;
53 };
54
55 ArchiveDatabase::ArchiveDatabase(const std::string& filename)
56 : handle_(std::make_unique<Handle>(filename)) {
57 if (!handle_->IsValid()) {
58 handle_.reset();
59 return;
60 }
61
62 begin_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
63 new ArchiveStatement(handle_->Get(), "BEGIN TRANSACTION;"));
64
65 if (!begin_transaction_stmt_->IsValid()) {
66 return;
67 }
68
69 end_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
70 new ArchiveStatement(handle_->Get(), "END TRANSACTION;"));
71
72 if (!end_transaction_stmt_->IsValid()) {
73 return;
74 }
75
76 rollback_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
77 new ArchiveStatement(handle_->Get(), "ROLLBACK TRANSACTION;"));
78
79 if (!rollback_transaction_stmt_->IsValid()) {
80 return;
81 }
82 }
83
84 ArchiveDatabase::~ArchiveDatabase() = default;
85
86 bool ArchiveDatabase::IsValid() const {
87 return handle_ != nullptr;
88 }
89
90 int64_t ArchiveDatabase::GetLastInsertRowID() {
91 if (!IsValid()) {
92 return 0u;
93 }
94 return ::sqlite3_last_insert_rowid(handle_->Get());
95 }
96
97 static inline const ArchiveClassRegistration* RegistrationIfReady(
98 const ArchiveClassRegistration* registration) {
99 if (registration == nullptr) {
100 return nullptr;
101 }
102 return registration->IsValid() ? registration : nullptr;
103 }
104
105 const ArchiveClassRegistration* ArchiveDatabase::GetRegistrationForDefinition(
106 const ArchiveDef& definition) {
107 auto found = registrations_.find(definition.table_name);
108 if (found != registrations_.end()) {
109 /*
110 * This class has already been registered.
111 */
112 return RegistrationIfReady(found->second.get());
113 }
114
115 /*
116 * Initialize a new class registration for the given class definition.
117 */
118 auto registration = std::unique_ptr<ArchiveClassRegistration>(
119 new ArchiveClassRegistration(*this, definition));
120 auto res =
121 registrations_.emplace(definition.table_name, std::move(registration));
122
123 /*
124 * If the new class registration is ready, return it to the caller.
125 */
126 return res.second ? RegistrationIfReady((*(res.first)).second.get())
127 : nullptr;
128 }
129
130 ArchiveStatement ArchiveDatabase::CreateStatement(
131 const std::string& statementString) const {
132 return ArchiveStatement{handle_ ? handle_->Get() : nullptr, statementString};
133 }
134
135 ArchiveTransaction ArchiveDatabase::CreateTransaction(
136 int64_t& transactionCount) {
137 return ArchiveTransaction{transactionCount, //
138 *begin_transaction_stmt_, //
139 *end_transaction_stmt_, //
140 *rollback_transaction_stmt_};
141 }
142
143 } // namespace impeller
impeller::ArchiveDatabase::GetLastInsertRowID
int64_t GetLastInsertRowID()
Definition: archive_database.cc:90
impeller::ArchiveClassRegistration::IsValid
bool IsValid() const
Definition: archive_class_registration.cc:35
impeller::ArchiveDatabase::ArchiveClassRegistration
friend class ArchiveClassRegistration
Definition: archive_database.h:47
impeller::ArchiveDatabase::Handle::Handle
Handle(const std::string &filename)
Definition: archive_database.cc:20
impeller::ArchiveDatabase::Handle::~Handle
~Handle()
Definition: archive_database.cc:36
impeller::ArchiveDef::table_name
const std::string table_name
Definition: archivable.h:16
impeller::ArchiveDef
Definition: archivable.h:15
impeller::ArchiveDatabase::Handle::Get
::sqlite3 * Get() const
Definition: archive_database.cc:43
validation.h
impeller::RegistrationIfReady
static const ArchiveClassRegistration * RegistrationIfReady(const ArchiveClassRegistration *registration)
Definition: archive_database.cc:97
impeller::ArchiveClassRegistration
Definition: archive_class_registration.h:17
archive_statement.h
impeller::ArchiveDatabase::ArchiveDatabase
ArchiveDatabase(const std::string &filename)
Definition: archive_database.cc:55
impeller::ArchiveDatabase::Handle
Definition: archive_database.cc:19
impeller::ArchiveStatement
Represents a read/write query to an archive database. Statements are expensive to create and must be ...
Definition: archive_statement.h:20
archive_class_registration.h
impeller::ArchiveDatabase::GetRegistrationForDefinition
const ArchiveClassRegistration * GetRegistrationForDefinition(const ArchiveDef &definition)
Definition: archive_database.cc:105
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
archive_database.h
archive.h
std
Definition: comparable.h:95
impeller::ArchiveTransaction
All writes made to the archive within a transaction that is not marked as ready for commit will be ro...
Definition: archive_transaction.h:22
impeller::ArchiveDatabase::IsValid
bool IsValid() const
Definition: archive_database.cc:86
impeller::ArchiveDatabase::~ArchiveDatabase
~ArchiveDatabase()
impeller::ArchiveDatabase::Handle::IsValid
bool IsValid() const
Definition: archive_database.cc:45
impeller
Definition: aiks_context.cc:10
impeller::ArchiveDatabase::CreateTransaction
ArchiveTransaction CreateTransaction(int64_t &transactionCount)
Definition: archive_database.cc:135