Flutter Impeller
archive_class_registration.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 <sstream>
8 
12 
13 namespace impeller {
14 
15 static constexpr const char* kArchivePrimaryKeyColumnName = "primary_key";
16 
17 ArchiveClassRegistration::ArchiveClassRegistration(ArchiveDatabase& database,
18  ArchiveDef definition)
19  : database_(database), definition_(std::move(definition)) {
20  for (size_t i = 0; i < definition_.members.size(); i++) {
21  // The first index entry is the primary key. So add one to the index.
22  column_map_[definition_.members[i]] = i + 1;
23  }
24  is_valid_ = CreateTable();
25 }
26 
27 const std::string& ArchiveClassRegistration::GetClassName() const {
28  return definition_.table_name;
29 }
30 
31 size_t ArchiveClassRegistration::GetMemberCount() const {
32  return column_map_.size();
33 }
34 
35 bool ArchiveClassRegistration::IsValid() const {
36  return is_valid_;
37 }
38 
39 std::optional<size_t> ArchiveClassRegistration::FindColumnIndex(
40  const std::string& member) const {
41  auto found = column_map_.find(member);
42  if (found == column_map_.end()) {
43  VALIDATION_LOG << "No member named '" << member << "' in class '"
44  << definition_.table_name
45  << "'. Did you forget to register it?";
46  return std::nullopt;
47  }
48  return found->second;
49 }
50 
51 bool ArchiveClassRegistration::CreateTable() {
52  if (definition_.table_name.empty() || definition_.members.empty()) {
53  return false;
54  }
55 
56  std::stringstream stream;
57 
58  /*
59  * Table names cannot participate in parameter substitution, so we prepare
60  * a statement and check its validity before running.
61  */
62  stream << "CREATE TABLE IF NOT EXISTS " << definition_.table_name << " ("
63  << kArchivePrimaryKeyColumnName << " INTEGER PRIMARY KEY, ";
64 
65  for (size_t i = 0, columns = definition_.members.size(); i < columns; i++) {
66  stream << definition_.members[i];
67  if (i != columns - 1) {
68  stream << ", ";
69  }
70  }
71  stream << ");";
72 
73  auto statement = database_.CreateStatement(stream.str());
74 
75  if (!statement.IsValid()) {
76  return false;
77  }
78 
79  if (!statement.Reset()) {
80  return false;
81  }
82 
83  return statement.Execute() == ArchiveStatement::Result::kDone;
84 }
85 
86 ArchiveStatement ArchiveClassRegistration::CreateQueryStatement(
87  bool single) const {
88  std::stringstream stream;
89  stream << "SELECT " << kArchivePrimaryKeyColumnName << ", ";
90  for (size_t i = 0, columns = definition_.members.size(); i < columns; i++) {
91  stream << definition_.members[i];
92  if (i != columns - 1) {
93  stream << ",";
94  }
95  }
96  stream << " FROM " << definition_.table_name;
97 
98  if (single) {
99  stream << " WHERE " << kArchivePrimaryKeyColumnName << " = ?";
100  } else {
101  stream << " ORDER BY " << kArchivePrimaryKeyColumnName << " ASC";
102  }
103 
104  stream << ";";
105 
106  return database_.CreateStatement(stream.str());
107 }
108 
109 ArchiveStatement ArchiveClassRegistration::CreateInsertStatement() const {
110  std::stringstream stream;
111  stream << "INSERT OR REPLACE INTO " << definition_.table_name
112  << " VALUES ( ?, ";
113  for (size_t i = 0, columns = definition_.members.size(); i < columns; i++) {
114  stream << "?";
115  if (i != columns - 1) {
116  stream << ", ";
117  }
118  }
119  stream << ");";
120 
121  return database_.CreateStatement(stream.str());
122 }
123 
124 } // namespace impeller
impeller::ArchiveDef
Definition: archivable.h:14
validation.h
impeller::ArchiveDatabase
A handle to the underlying database connection for an archive.
Definition: archive_database.h:23
impeller::kArchivePrimaryKeyColumnName
static constexpr const char * kArchivePrimaryKeyColumnName
Definition: archive_class_registration.cc:15
archive_statement.h
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
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
archive_database.h
std
Definition: comparable.h:98
impeller
Definition: aiks_context.cc:10