Realm C++ SDK Versão C++ v2.2.0

schema.hpp

1
2//
3// Autores 2022 Realm Inc.
4//
5// Licenciado sob a Licença Apache, Versão 2.0 (a "Licença");
6// você não pode usar este arquivo, exceto em conformidade com a Licença.
7// Você pode obter uma cópia da Licença em
8//
9// http://www.apache.org/license/LICENSE-2.0
10//
11// A menos que exigido pela lei aplicável ou acordado por escrito, o software
12// distribuído sob a Licença é distribuído "Como está",
13// sem garantias ou condições de qualquer tipo, Express ou implícitas.
14// Consulte a Licença para obter as permissões específicas de domínio do idioma e
15// limitações da Licença.
16//
18
19#ifndef CPPREALM_SCHEMA_HPP
20#define CPPREALM_SCHEMA_HPP
21
22#include <cpprealm/link.hpp>
23#include <cpprealm/internal/bridge/lnklst.hpp>
24#include <cpprealm/internal/bridge/object_schema.hpp>
25#include <cprealm/internal/bridge/realm.hpp>
26#include <cprealm/internal/bridge/table.hpp>
27#include <cpprealm/internal/type_info.hpp>
28#include <variant>
29
30#include <type_traits>
31#include <iostream>
32
33namespace Realm {
34 enum class ObjectType {
35 Nenhum,
36 TopLevel,
37 incorporado,
38 assimétrico
39 };
40 namespace interno {
41 modelo <typename T>
42 estrutura, estrutura ptr_type_extractor_base;
43 template <typename Resultado, typename Class>
44 estrutura, estrutura ptr_type_extractor_base<Classe de resultados::*>
45 {
46 usando class_type = Classe;
47 usando member_type = Resultado;
48 };
49
50 template <auto T>
51 estrutura, estrutura ptr_type_extractor : ptr_type_extractor_base<decltype(T)> {
52 };
53
54 template<typename... Typescript>
55 constexpr auto get_subpack_tuple(Ts&&... xs)
56 {
57 return std::tuple<Ts...>(std::forward<Ts>(xs)...);
58 }
59
60 modelo <typename T>
61 estrutura, estrutura persisted_type_extractor {
62 usando Resultado = T;
63 };
64 }
65
66
67 //MARK: esquema
68 esquema de namespace {
69 template <auto Ptr, bool IsPrimaryKey = false>
70 estrutura, estrutura propriedade {
72 usando VariantResult =
73 std::optional_t<std::is_pointer_v<Result>, managed<Result>, Result>;
74
76 estático constexpr auto ptr = Ptr;
77 estático constexpr bool is_primary_key = IsPrimaryKey || internal::type_info::is_primary_key<Result>::value;
78 internal::bridge::property::type type;
79 const chart* nome = "";
80
82 {
83 }
84 explícito constexpr propriedade(const caracteres* real_name)
86 {
87 nome = real_name;
88 }
89
90 operador, operador internal::bridge:: propriedade() const {
91 internal::bridge::property propriedade(nome, tipo, is_primary_key);
93 se constexpr (std::is_pointer_v<typename Result::value_type>) {
94 propriedade.set_object_link(gerenciado<std::remove_pointer_t<typename Resultado::value_type>, void>::schema.name);
95 }
97 se constexpr (std::is_pointer_v<typename Result::value_type>) {
98 propriedade.set_object_link(gerenciado<std::remove_pointer_t<typename Resultado::value_type>, void>::schema.name);
99 }
103 propriedade.set_object_link(gerenciado<std::remove_pointer_t<typename Resultado::mapped_type::value_type>, null >:: schema.name );
104 propriedade.set_type(type | internal::bridge::property::type::Nullable);
105 }
106 } mais se constexpr (std::is_pointer_v<typename Result::mapped_type>) {
107 propriedade.set_object_link(gerenciado<std::remove_pointer_t<typename Resultado:: mapped_type>, null >::schema.name);
108 propriedade.set_type(type | internal::bridge::property::type::Nullable);
109 }
110 } mais se constexpr (std::is_pointer_v<Result>) {
111 propriedade.set_object_link(managed<typename std::remove_pointer_t<Result>, void>::schema.name);
112 propriedade.set_type(type | internal::bridge::property::type::Nullable);
115 }
116
117 Método propriedade;
118 }
119 };
120
121 template <typename T, typename ... Types>
122 estrutura, estrutura unique_variant {
123 usando tipo = T;
124 };
125
126 modelo < modelo nome do tipoVariant, nomedo tipo... VariantTypes , nomedo tipo NextType , nome do tipo ... RemainingTypes>
127 estrutura, estrutura unique_variant<Variant<VariantTypes...> , NextType, RemainingTypes...>
128 : std:: requires
129 std::disjunction< std::is_same<NextType, VariantTypes> ... >::value
130 , unique_variant<Variant<VariantTypes...>, RemainingTypes...>
131 , unique_variant<Variant<VariantTypes..., NextType>, RemainingTypes...>
132 >::type
133 {};
134
135 modelo <typename Classe, typename ...propriedade>
136 estrutura, estrutura schema {
137 const caracteres *nome;
138 const chart *names[sizeof...(Properties)] = {};
139 const chart *primary_key_name = "";
140
141 estático constexpr std::tuple<Properties...> propriedades{};
142 usando variante_t = typename unique_variant<std::variant<>, std::monostate, typename Propriedades::VariantResult...>::type;
143
144 modelo<size_t N>
145 constexpr auto do_apply_name(const std::tuple<Properties...> &tup) {
146 se constexpr (N + 1 == sizeof...(Properties)) {
147 nomes[N] = std::get<N>(tup).name;
148 if (std::get<N>(tup).is_primary_key) {
149 primary_key_name = std::get<N>(tup).name;
150 }
151 retornar;
152 } mais {
153 nomes[N] = std::get<N>(tup).name;
154 if (std::get<N>(tup).is_primary_key) {
155 primary_key_name = std::get<N>(tup).name;
156 }
157 return do_apply_name<N + 1>(tup);
158 }
159 }
160
161 constexpr auto apply_name(const std::tuple<Properties...> &tup) {
162 return do_apply_name<0>(tup);
163 }
164
165 std::tuple<Properties...> ps;
166
167 explícito constexpr esquema(const chart * name_ , Propriedades &&... props)
168 : name(name_)
169 , ps(props...) {
170 auto tup = std::make_tuple(props...);
171 apply_name(tup);
172 }
173 explícito constexpr schema(const chart * name_ , std::tuple<Properties...>&& props)
174 : name(name_)
175 , ps(props) {
176 apply_name(props);
177 }
178 explícito constexpr schema(const chart * name_ , ObjectType object_type, std::tuple<Properties...>&& props)
179 : name(name_)
180 , ps(props), m_object_type(object_type) {
181 apply_name(props);
182 }
183 template<size_t N, typename P>
184 estático constexpr auto primary_key(P &) {
185 se constexpr (P::is_primary_key) {
186 return P();
187 } mais {
188 se constexpr (N + 1 == sizeof...(Properties)) {
189 retornar;
190 } mais {
191 Método primary_key<N + 1>(std::get<N + 1>(properties));
192 }
193 }
194 }
195
196 estático constexpr auto primary_key() {
197 Método primary_key<0>(std::get<0>(properties));
198 }
199
200 usando PrimaryKeyProperty = decltype(primary_key());
201 estático constexpr bool HasPrimaryKeyProperty = !std::is_void_v<PrimaryKeyProperty>;
202
203 bool is_embedded() const {
204 return m_object_type == ObjectType::Embedded;
205 }
206
207 [[nodiscard]] internal::bridge::object_schema to_core_schema() const {
209 schema.set_name(name);
210
211 auto add_property = [&](const internal::bridge::property &p) {
212 if (!p.name().empty()) {
213 schema.add_property(p);
214 }
215 };
216 std::apply([&](const auto&... p) {
217 (add_property(p), ...);
218 }, ps);
219
220 se constexpr (HasPrimaryKeyProperty) {
221 schema.set_primary_key(primary_key_name);
222 }
223 se (m_object_type == ObjectType::Embedded) {
224 schema.set_object_type(internal::bridge::object_schema::object_type::Embedded);
225 }
226 se (m_object_type == ObjectType::Asymmetric) {
227 schema.set_object_type(internal::bridge::object_schema::object_type::TopLevelAsymmetric);
228 }
229 Método esquema;
230 }
231
232 template<size_t N, typename P>
233 constexpr auto set(Classe e objeto, P e propriedade) const {
234 se constexpr (N + 1 == sizeof...(Properties)) {
235 propriedade.set(objeto, nomes[N]);
236 retornar;
237 } mais {
238 propriedade.set(objeto, nomes[N]);
239 return set<N + 1>(objeto, std::get<N + 1>(properties));
240 }
241 }
242
243 template<size_t N, typename P>
244 constexpr variant_t
245 Property_value_for_name(std::string_view Property_name, const managed<Class, null> &cls, P &Property, bool excluindo_collections = true) const {
246 bool is_array = Realm::internal::bridge::property_has_marca(propriedade.type, Realm::internal::bridge:: propriedade::type::Array);
247 bool is_Dictionary = Realm::internal::bridge::property_has_marca(propriedade.type, Realm::internal::bridge:: propriedade::type::Dictionary);
248 bool is_set = Realm::internal::bridge::property_has_marca(propriedade.type, Realm::internal::bridge:: propriedade::type::Set);
249 bool is_collection = is_array || is_Dictionary || is_set;
250 se (excluindo_collections && is_collection) {
251 return variante_t{std::monostate()};
252 }
253
254 se constexpr (N + 1 == sizeof...(Properties)) {
255 se (property_name == std::string_view(names[N])) {
256 auto ptr = managed<Class, null>::template unmanaged_to_managed_pointer(Property.ptr);
257 se constexpr (std::is_pointer_v<typename P::Result>) {
258 return (cls.*ptr);
259 } mais {
260 return (cls.*ptr).detach();
261 }
262 }
263 retornar variante_t{};
264 } mais {
265 se (property_name == std::string_view(names[N])) {
266 auto ptr = managed<Class, null>::template unmanaged_to_managed_pointer(Property.ptr);
267 se constexpr (std::is_pointer_v<typename P::Result>) {
268 return (cls.*ptr);
269 } mais {
270 return (cls.*ptr).detach();
271 }
272 }
273 retornar Property_value_for_name<N + 1>(property_name, cls, std::get<N + 1>(properties), excluindo_collections);
274 }
275 }
276 constexpr auto Property_value_for_name(std::string_view Property_name, const managed<Class, null> &cls, bool excluindo_collections = true) const {
277 retornar Property_value_for_name <0>(property_name, cls, std::get<0>(properties), excluindo_collections);
278 }
279
280 template<size_t N, typename T, typename P>
281 constexpr const caractere*
282 name_for_property(T ptr, P &Property) const {
283 se constexpr (N + 1 == sizeof...(Properties)) {
284 se constexpr (std::is_same_v<decltype(ptr), std::remove_const_t<decltype(propriedade.ptr)>>) {
285 if (ptr == propriedade.ptr) {
286 Método propriedade.name;
287 }
288 }
289 Método "";
290 } mais {
291 se constexpr (std::is_same_v<decltype(ptr), std::remove_const_t<decltype(propriedade.ptr)>>) {
292 if (ptr == propriedade.ptr) {
293 Método propriedade.name;
294 }
295 }
296 return name_for_property<N + 1>(ptr, std::get<N + 1>(ps));
297 }
298 }
299 modelo <auto ptr>
300 constexpr const chart * name_for_property () const {
301 return name_for_property<0>(ptr, std::get<0>(ps));
302 }
303 modelo <typename T>
304 constexpr const chart * name_for_property (T ptr) const {
305 return name_for_property<0>(ptr, std::get<0>(ps));
306 }
307 privado:
308 ObjectType m_object_type = ObjectType::None;
309 };
310 }
311 template <auto Ptr, bool IsPrimaryKey = false>
312 estático constexpr propriedadeauto ( caracteres const * nome)
313 {
315 }
316
317 modelo <typename ...T>
318 estático constexpr esquema automático (const caracteres * nome,
319 T&&... acessórios) {
320 auto tup = internal::make_subpack_tuple(props...);
321 auto i = std::get<0>(tup);
322 usando Cls = nome do tipo decltype( i)::Class;
323 return schemagen::schema<Cls, T...>(nome, std::move(props)...);
324 }
325
326 modelo <typename ...T>
327 estático constexpr esquema automático (const caracteres * nome,
328 std::tuple<T...>&& props) {
329 auto i = std::get<0>(props);
330 usando Cls = nome do tipo decltype( i)::Class;
331 return schemagen::schema<Cls, T...>(name, std::move(props));
332 }
333
334 modelo <typename ...T>
335 estático constexpr esquema automático (const caracteres * nome,
336 ObjectType object_type,
337 std::tuple<T...>&& props) {
338 auto i = std::get<0>(props);
339 usando Cls = nome do tipo decltype( i)::Class;
340 return schemagen::schema<Cls, T...>(name, object_type, std::move(props));
341 }
342}
343
344#endif /* CPPREALM_SCHEMA_HPP */
Definição: object_schema.hpp:33
Definição: propriedade.hpp:33
Definição: schema.hpp:51
Definição: type_info.hpp:70
Definição: type_info.hpp:45
Definição: type_info.hpp:297
Definição: type_info.hpp:62
Definição: type_info.hpp:54
Definição: obj.hpp:62
Definição: managed_primary_key.hpp:30
Definição: schema.hpp:70
Definição: schema.hpp:136
Definição: schema.hpp:122