| 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 FML_DISALLOW_COPY_AND_ASSIGN(Handle);
51 };
52
53 ArchiveDatabase::ArchiveDatabase(const std::string& filename)
54 : handle_(std::make_unique<Handle>(filename)) {
55 if (!handle_->IsValid()) {
56 handle_.reset();
57 return;
58 }
59
60 begin_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
61 new ArchiveStatement(handle_->Get(), "BEGIN TRANSACTION;"));
62
63 if (!begin_transaction_stmt_->IsValid()) {
64 return;
65 }
66
67 end_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
68 new ArchiveStatement(handle_->Get(), "END TRANSACTION;"));
69
70 if (!end_transaction_stmt_->IsValid()) {
71 return;
72 }
73
74 rollback_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
75 new ArchiveStatement(handle_->Get(), "ROLLBACK TRANSACTION;"));
76
77 if (!rollback_transaction_stmt_->IsValid()) {
78 return;
79 }
80 }
81
82 ArchiveDatabase::~ArchiveDatabase() = default;
83
84 bool ArchiveDatabase::IsValid() const {
85 return handle_ != nullptr;
86 }
87
88 int64_t ArchiveDatabase::GetLastInsertRowID() {
89 if (!IsValid()) {
90 return 0u;
91 }
92 return ::sqlite3_last_insert_rowid(handle_->Get());
93 }
94
95 static inline const ArchiveClassRegistration* RegistrationIfReady(
96 const ArchiveClassRegistration* registration) {
97 if (registration == nullptr) {
98 return nullptr;
99 }
100 return registration->IsValid() ? registration : nullptr;
101 }
102
103 const ArchiveClassRegistration* ArchiveDatabase::GetRegistrationForDefinition(
104 const ArchiveDef& definition) {
105 auto found = registrations_.find(definition.table_name);
106 if (found != registrations_.end()) {
107 /*
108 * This class has already been registered.
109 */
110 return RegistrationIfReady(found->second.get());
111 }
112
113 /*
114 * Initialize a new class registration for the given class definition.
115 */
116 auto registration = std::unique_ptr<ArchiveClassRegistration>(
117 new ArchiveClassRegistration(*this, definition));
118 auto res =
119 registrations_.emplace(definition.table_name, std::move(registration));
120
121 /*
122 * If the new class registration is ready, return it to the caller.
123 */
124 return res.second ? RegistrationIfReady((*(res.first)).second.get())
125 : nullptr;
126 }
127
128 ArchiveStatement ArchiveDatabase::CreateStatement(
129 const std::string& statementString) const {
130 return ArchiveStatement{handle_ ? handle_->Get() : nullptr, statementString};
131 }
132
133 ArchiveTransaction ArchiveDatabase::CreateTransaction(
134 int64_t& transactionCount) {
135 return ArchiveTransaction{transactionCount, //
136 *begin_transaction_stmt_, //
137 *end_transaction_stmt_, //
138 *rollback_transaction_stmt_};
139 }
140
141 } // namespace impeller
impeller::ArchiveDatabase::GetLastInsertRowID
int64_t GetLastInsertRowID()
Definition: archive_database.cc:88
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:15
impeller::ArchiveDef
Definition: archivable.h:14
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:95
impeller::ArchiveClassRegistration
Definition: archive_class_registration.h:16
archive_statement.h
impeller::ArchiveDatabase::ArchiveDatabase
ArchiveDatabase(const std::string &filename)
Definition: archive_database.cc:53
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:103
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
archive_database.h
archive.h
std
Definition: comparable.h:98
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:23
impeller::ArchiveDatabase::IsValid
bool IsValid() const
Definition: archive_database.cc:84
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:133