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  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 
83 
85  return handle_ != nullptr;
86 }
87 
89  if (!IsValid()) {
90  return 0u;
91  }
92  return ::sqlite3_last_insert_rowid(handle_->Get());
93 }
94 
96  const ArchiveClassRegistration* registration) {
97  if (registration == nullptr) {
98  return nullptr;
99  }
100  return registration->IsValid() ? registration : nullptr;
101 }
102 
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 
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