| 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
5 #include "impeller/archivist/archive_class_registration.h"
6
7 #include <sstream>
8
9 #include "impeller/archivist/archive_database.h"
10 #include "impeller/archivist/archive_statement.h"
11 #include "impeller/base/validation.h"
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