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 
6 
7 #include "third_party/sqlite/sqlite3.h"
8 
9 #include <sstream>
10 #include <string>
11 
16 
17 namespace impeller {
18 
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 
85 
87  return handle_ != nullptr;
88 }
89 
91  if (!IsValid()) {
92  return 0u;
93  }
94  return ::sqlite3_last_insert_rowid(handle_->Get());
95 }
96 
98  const ArchiveClassRegistration* registration) {
99  if (registration == nullptr) {
100  return nullptr;
101  }
102  return registration->IsValid() ? registration : nullptr;
103 }
104 
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 
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