Flutter Impeller
archive_location.h
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 #pragma once
6 
7 #include <optional>
8 #include <type_traits>
9 
10 #include "flutter/fml/macros.h"
14 
15 namespace impeller {
16 
17 class Archive;
18 class ArchiveClassRegistration;
19 class ArchiveStatement;
20 
22  public:
23  PrimaryKey GetPrimaryKey() const;
24 
25  template <class T, class = std::enable_if_t<std::is_integral<T>::value>>
26  bool Write(const std::string& member, T item) {
27  return WriteIntegral(member, static_cast<int64_t>(item));
28  }
29 
30  bool Write(const std::string& member, double item);
31 
32  bool Write(const std::string& member, const std::string& item);
33 
34  bool Write(const std::string& member, const Allocation& allocation);
35 
36  template <class T,
37  class = std::enable_if_t<std::is_base_of<Archivable, T>::value>>
38  bool WriteArchivable(const std::string& member, const T& other) {
39  const ArchiveDef& otherDef = T::ArchiveDefinition;
40  return Write(member, otherDef, other);
41  }
42 
43  template <class T, class = std::enable_if_t<std::is_enum<T>::value>>
44  bool WriteEnum(const std::string& member, const T& item) {
45  return WriteIntegral(member, static_cast<int64_t>(item));
46  }
47 
48  template <class T,
49  class = std::enable_if_t<std::is_base_of<Archivable, T>::value>>
50  bool Write(const std::string& member, const std::vector<T>& items) {
51  /*
52  * All items in the vector are individually encoded and their keys noted
53  */
54  std::vector<int64_t> members;
55  members.reserve(items.size());
56 
57  const ArchiveDef& itemDefinition = T::kArchiveDefinition;
58  for (const auto& item : items) {
59  auto row_id = context_.ArchiveInstance(itemDefinition, item);
60  if (!row_id.has_value()) {
61  return false;
62  }
63  members.emplace_back(row_id.value());
64  }
65 
66  /*
67  * The keys are flattened into the vectors table. Write to that table
68  */
69  auto vectorInsert = WriteVectorKeys(std::move(members));
70 
71  if (!vectorInsert.has_value()) {
72  return false;
73  }
74 
75  return WriteIntegral(member, vectorInsert.value());
76  }
77 
78  template <class T, class = std::enable_if_t<std::is_integral<T>::value>>
79  bool Read(const std::string& member, T& item) {
80  int64_t decoded = 0;
81  auto result = ReadIntegral(member, decoded);
82  item = static_cast<T>(decoded);
83  return result;
84  }
85 
86  bool Read(const std::string& member, double& item);
87 
88  bool Read(const std::string& member, std::string& item);
89 
90  bool Read(const std::string& member, Allocation& allocation);
91 
92  template <class T,
93  class = std::enable_if_t<std::is_base_of<Archivable, T>::value>>
94  bool ReadArchivable(const std::string& member, T& other) {
95  const ArchiveDef& otherDef = T::ArchiveDefinition;
96  return decode(member, otherDef, other);
97  }
98 
99  template <class T, class = std::enable_if_t<std::is_enum<T>::value>>
100  bool ReadEnum(const std::string& member, T& item) {
101  int64_t desugared = 0;
102  if (ReadIntegral(member, desugared)) {
103  item = static_cast<T>(desugared);
104  return true;
105  }
106  return false;
107  }
108 
109  template <class T,
110  class = std::enable_if_t<std::is_base_of<Archivable, T>::value>>
111  bool Read(const std::string& member, std::vector<T>& items) {
112  /*
113  * From the member, find the foreign key of the vector
114  */
115  int64_t vectorForeignKey = 0;
116  if (!ReadIntegral(member, vectorForeignKey)) {
117  return false;
118  }
119 
120  /*
121  * Get vector keys
122  */
123  std::vector<int64_t> keys;
124  if (!ReadVectorKeys(vectorForeignKey, keys)) {
125  return false;
126  }
127 
128  const ArchiveDef& otherDef = T::kArchiveDefinition;
129  for (const auto& key : keys) {
130  items.emplace_back();
131 
132  if (!context_.UnarchiveInstance(otherDef, key, items.back())) {
133  return false;
134  }
135  }
136 
137  return true;
138  }
139 
140  private:
141  Archive& context_;
142  ArchiveStatement& statement_;
143  const ArchiveClassRegistration& registration_;
144  PrimaryKey primary_key_;
145 
146  friend class Archive;
147 
148  ArchiveLocation(Archive& context,
149  ArchiveStatement& statement,
150  const ArchiveClassRegistration& registration,
151  PrimaryKey name);
152 
153  bool WriteIntegral(const std::string& member, int64_t item);
154 
155  bool ReadIntegral(const std::string& member, int64_t& item);
156 
157  std::optional<int64_t> WriteVectorKeys(std::vector<int64_t>&& members);
158 
159  bool ReadVectorKeys(PrimaryKey name, std::vector<int64_t>& members);
160 
161  bool Write(const std::string& member,
162  const ArchiveDef& otherDef,
163  const Archivable& other);
164 
165  bool Read(const std::string& member,
166  const ArchiveDef& otherDef,
167  Archivable& other);
168 
169  FML_DISALLOW_COPY_AND_ASSIGN(ArchiveLocation);
170 };
171 
172 } // namespace impeller
impeller::ArchiveLocation::GetPrimaryKey
PrimaryKey GetPrimaryKey() const
Definition: archive_location.cc:21
impeller::ArchiveLocation::ReadEnum
bool ReadEnum(const std::string &member, T &item)
Definition: archive_location.h:100
impeller::Archive
Definition: archive.h:22
allocation.h
impeller::Archivable
Instances of Archivables can be read from and written to a persistent archive.
Definition: archivable.h:27
impeller::ArchiveDef
Definition: archivable.h:14
impeller::ArchiveLocation::WriteEnum
bool WriteEnum(const std::string &member, const T &item)
Definition: archive_location.h:44
archivable.h
impeller::PrimaryKey
std::optional< int64_t > PrimaryKey
Definition: archivable.h:21
impeller::ArchiveLocation::Read
bool Read(const std::string &member, std::vector< T > &items)
Definition: archive_location.h:111
impeller::ArchiveLocation::Write
bool Write(const std::string &member, const std::vector< T > &items)
Definition: archive_location.h:50
impeller::ArchiveLocation::WriteArchivable
bool WriteArchivable(const std::string &member, const T &other)
Definition: archive_location.h:38
impeller::ArchiveClassRegistration
Definition: archive_class_registration.h:16
impeller::ArchiveLocation::ReadArchivable
bool ReadArchivable(const std::string &member, T &other)
Definition: archive_location.h:94
impeller::ArchiveLocation::Read
bool Read(const std::string &member, T &item)
Definition: archive_location.h:79
impeller::ArchiveStatement
Represents a read/write query to an archive database. Statements are expensive to create and must be ...
Definition: archive_statement.h:20
impeller::Allocation
Definition: allocation.h:15
impeller::ArchiveLocation
Definition: archive_location.h:21
archive.h
impeller::ArchiveLocation::Write
bool Write(const std::string &member, T item)
Definition: archive_location.h:26
impeller
Definition: aiks_context.cc:10