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

results.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_RESULTS_HPP
20#define CPPREALM_RESULTS_HPP
21
22#include <cpprealm/internal/bridge/mixed.hpp>
23#include <cpprealm/internal/bridge/query.hpp>
24#include <cpprealm/internal/bridge/results.hpp>
25#include <cprealm/internal/bridge/table.hpp>
26#include <cprealm/macros.hpp>
27#include <cprealm/notifications.hpp>
28#include <cprealm/schema.hpp>
29#include <cprealm/rbool.hpp>
30
31namespace Realm {
32 struct mutable_sync_subscription_set;
33}
34
35namespace Realm {
36
37 usando sort_descriptor = internal::bridge::sort_descriptor;
38
39 modelo<nome do tipo>
40 estrutura de resultados;
41 template<typename T, typename Derivado, typename ShouldEnable= null >
42 estrutura, estrutura results_base;
43 template<typename T, typename Derivado>
44 estrutura, estrutura results_common_base;
45
46 template<typename T, typename Derivado>
47 estrutura, estrutura results_common_base {
49 : m_parent(parent) {
50 }
51 estrutura, estrutura results_change {
52 *coleção derivada;
53 std::vector<uint64_t> exclusões;
54 std::vector<uint64_t> inserções;
55 std::vector<uint64_t> modificações;
56
57 // Este sinalizador indica se o objeto subjacente que é a origem desta
58 // a collection foi excluída. Isso se aplica a listas, dicionários e conjuntos.
59 // Isso permite que os notificadores relatem uma alteração nas coleções vazias que foram excluídas.
60 bool collection_root_was_deleted = false;
61
62 [[nodiscard]] bool empty() const noexceto {
63 return deleteries.empty() && inserts.empty() && modified.empty() &&
64 !collection_root_was_deleted;
65 }
66 };
67
68 tamanho_t tamanho() {
69 return m_parent.size();
70 }
71
72 virtual ~results_common_base() = padrão;
73 Derivado de onde(const std::string &query, const std::vector<realm::mixed>& argumentos) {
74 std::vector<internal::bridge::mixed> mixed_args;
75 para(auto& a : argumentos)
76 mixed_args.push_back(serialize(a));
77 return Derivado(interno::bridge::results(m_parent.get_realm(),
78 m_parent.get_table().query(query, std::move(mixed_args))));
79 }
80
81 Derivado de onde(std::function<rbool(managed<T>&)>&& fn) {
82 estático_assert(sizeof(managed<T>), "Deve declarar esquema para T");
83 auto realm = m_parent.get_realm();
84 auto schema = realm.schema().find(managed<T>::schema.name);
85 auto group = Realm.read_group();
86 auto table_ref = group.get_table(schema.table_key());
87 rbool query = rbool(internal::bridge::query(table_ref));
88 auto query_object = managed<T>::prepare_for_query(realm, &query);
89 auto full_query = fn(query_object).q;
90 return Derived(internal::bridge::results(m_parent.get_realm(), full_query));
91 }
92
94 explícito results_callback_wrapper(std::function <null(results_change) >&& fn,
95 Derivado *c,
96 bool ignore_initial_notification = true)
97 : m_handler(std::move(fn)),
98 collection(c),
99 m_ignore_changes_in_initial_notification(ignore_initial_notification) {}
100
101 null before(const realm::internal::bridge::collection_change_set&) override {}
102
103 null after(internal::bridge::collection_change_set const &changes) final {
104 se (m_ignore_changes_in_initial_notification) {
105 m_ignore_changes_in_initial_notification = false;
106 m_handler({collection, {}, {} , {}});
107 } mais se (changes.empty()) {
108 m_handler({collection, {}, {} , {}});
109 } mais se (!changes.collection_root_was_deleted() || !changes.deletions().empty() {
110 m_handler({
111 coleção,
112 to_vector(changes.deletions()),
113 to_vector(changes.insertions()),
114 to_vector(changes.modifications()),
115 });
116 }
117 }
118
119 *coleção derivada;
120
121 privado:
122 std::function <void(results_change)> m_handler;
123 bool m_ignore_changes_in_initial_notification;
124 std::vector<uint64_t> to_vector(const internal::bridge::index_set &index_set) {
125 auto vector = std::vector<uint64_t>();
126 para ( índice automático : index_set.as_indexes()) {
127 vector.push_back(index);
128 }
129 vetor de retorno ;
130 };
131 };
132
133 Realm::notification_token observe(std::function <null(results_change) >&& handler) {
134 auto r = std::make_shared<internal::bridge::results>(m_parent.get_realm(), m_parent.get_realm().table_for_object_type(managed<T>::schema.name));
135 Realm::notification_token token = r->add_notification_callback(std::make_shared<results_callback_wrapper>(std::move(handler), static_cast<Derived*>(this)));
136 token.m_realm = r->get_realm();
137 token.m_results = r;
138 token de devolução ;
139 }
140
141 Congelamento derivado () {
142 auto ice_realm = m_parent.get_realm().freeze();
143 return Derived(internal::bridge::results(frozen_realm, chunky_realm.table_for_object_type(managed<T>::schema.name)));
144 }
145
146 Descongelamento derivado() {
147 auto tailed_realm = m_parent.get_realm().thaw();
148 return Derived(internal::bridge::results(thubed_realm, thawed_realm.table_for_object_type(managed<T>::schema.name)));
149 }
150
151 bool is_frozen() {
152 return m_parent.get_realm().is_frozen();
153 }
154
155 Classificação derivada(const std::string& key_path, bool ascendente) {
156 return Derivado(m_parent.sort({{key_path, ascendente}}));
157 }
158
159 Classificação derivada(const std::vector<sort_descriptor>& sort_descriptors) {
160 return Derivado(m_parent.sort(sort_descriptors));
161 }
162
163 protegido:
164 internal::bridge::results m_parent;
165 <auto> modelo estrutura de amigo linking_objects;
166 };
167
168 modelo<typename T>
169 usando results_is_primitive = std::enable_if_t<!managed<T>::is_object && !std::is_enum_v<T> && !internal::type_info::is_variant_t<T>::value>;
170 modelo<typename T>
171 usando results_is_enum = std::enable_if_t<!managed<T>::is_object && std::is_enum_v<T> && !internal::type_info::is_variant_t<T>::value>;
172 modelo<typename T>
173 usando results_is_mixed = std::enable_if_t<!managed<T>::is_object && !std::is_enum_v<T> && internal::type_info::is_variant_t<T>::value>;
174
175 template<typename T, typename Derivado>
176 estrutura, estrutura results_base<T, Derived, results_is_primitive<T>> : public results_common_base<T, Derived> {
177 explícito results_base(internal::bridge::results &&parent)
178 : results_common_base<T, Derived>(std::move(parent)) {
179 }
180
181 Operador T[](índice size_t ) {
182 se (index >= this->m_parent.size())
183 lance std::out_of_range("Índice fora do intervalo.");
184 return internal::bridge::get<T>(This->m_parent, index);
185 }
186
187 iterador de classe {
188 público:
189 usando change_type = tamanho_t;
190 usando value_type = T;
191 usando iterator_category = std::input_iterator_tag;
192
193 operador de bool !=(const iterador e outros) const {
194 return !(*isto == outro);
195 }
196
197 operador bool ==( iterador const e outros) const {
198 return (m_parent == other.m_parent) && (m_idx == outro.m_idx);
199 }
200
201 operador value_type*() noexceto {
202 return m_parent->operator[](m_idx);
203 }
204
205 iterador e operador++() {
206 m_idx++;
207 devolva *isto;
208 }
209
210 operador do iterador++(int i) {
211 m_idx += i;
212 devolva *isto;
213 }
214
215 iterador explícito (size_t idx, derivado *principal)
216 : m_idx(idx), m_parent(parent) {
217 }
218 privado:
219 size_t m_idx;
220 Derivado de *m_parent;
221 };
222
223 iterador begin() {
224 return iterador(0, estático_cast<Derivado*>(isto));
225 }
226
227 end() do iterador {
228 return iterador(isto->m_parent.size(), estático_cast <Derivado *>(isto));
229 }
230 };
231
232 template<typename T, typename Derivado>
233 estrutura, estrutura results_base<T, Derived, results_is_mixed<T>> : public results_common_base<T, Derived> {
234 explícito results_base(internal::bridge::results &&parent)
235 : results_common_base<T, Derived>(std::move(parent)) {
236 }
237
238 Operador T[](índice size_t ) {
239 se (index >= this->m_parent.size())
240 lance std::out_of_range("Índice fora do intervalo.");
241 return deserialize<T>(internal::bridge::get<internal::bridge::mixed>(This->m_parent, index));
242 }
243
244 // TODO: A implementação atual do realm::mixed não permite tipos de objetos gerenciados,
245 // para ser acessado a partir do iterador, pois seria necessário estar envolto em um
246 // modelo de <> gerenciado. Como esses modelos exigem uma chave col & obj, pois atuam como gerenciados
247 // propriedades em um objeto que este caso de uso está quebrado. Idealmente, devemos substituir realm::mixed para
248 // não ser uma std::variant, mas ser uma união segura por tipo que definimos no SDK para que
249 // realm::mixed pode ter um contexto gerenciado por si só.
250 iterador de classe {
251 público:
252 usando change_type = tamanho_t;
253 usando value_type = T;
254 usando iterator_category = std::input_iterator_tag;
255
256 operador de bool !=(const iterador e outros) const {
257 return !(*isto == outro);
258 }
259
260 operador bool ==( iterador const e outros) const {
261 return (m_parent == other.m_parent) && (m_idx == outro.m_idx);
262 }
263
264 operador value_type*() noexceto {
265 return m_parent->operator[](m_idx);
266 }
267
268 iterador e operador++() {
269 m_idx++;
270 devolva *isto;
271 }
272
273 operador do iterador++(int i) {
274 m_idx += i;
275 devolva *isto;
276 }
277
278 iterador explícito (size_t idx, derivado *principal)
279 : m_idx(idx), m_parent(parent) {
280 }
281 privado:
282 size_t m_idx;
283 Derivado de *m_parent;
284 };
285
286 iterador begin() {
287 return iterador(0, estático_cast<Derivado*>(isto));
288 }
289
290 end() do iterador {
291 return iterador(isto->m_parent.size(), estático_cast <Derivado *>(isto));
292 }
293 };
294
295 template<typename T, typename Derivado>
296 estrutura, estrutura results_base<T, Derived, results_is_enum<T>> : public results_common_base<T, Derived> {
297 explícito results_base(internal::bridge::results &&parent)
298 : results_common_base<T, Derived>(std::move(parent)) {
299 }
300
301 Operador T[](índice size_t ) {
302 se (index >= this->m_parent.size())
303 lance std::out_of_range("Índice fora do intervalo.");
304 Método estático_cast<T>(internal::bridge::get<int64_t>(This->m_parent, index));
305 }
306
307 iterador de classe {
308 público:
309 usando change_type = tamanho_t;
310 usando value_type = T;
311 usando iterator_category = std::input_iterator_tag;
312
313 operador de bool !=(const iterador e outros) const {
314 return !(*isto == outro);
315 }
316
317 operador bool ==( iterador const e outros) const {
318 return (m_parent == other.m_parent) && (m_idx == outro.m_idx);
319 }
320
321 operador value_type*() noexceto {
322 return m_parent->operator[](m_idx);
323 }
324
325 iterador e operador++() {
326 m_idx++;
327 devolva *isto;
328 }
329
330 operador do iterador++(int i) {
331 m_idx += i;
332 devolva *isto;
333 }
334
335 iterador explícito (size_t idx, derivado *principal)
336 : m_idx(idx), m_parent(parent) {
337 }
338 privado:
339 size_t m_idx;
340 Derivado de *m_parent;
341 };
342
343 iterador begin() {
344 return iterador(0, estático_cast<Derivado*>(isto));
345 }
346
347 end() do iterador {
348 return iterador(isto->m_parent.size(), estático_cast <Derivado *>(isto));
349 }
350 };
351
352 template<typename T, typename Derivado>
353 estrutura, estrutura results_base<T, Derived, std::enable_if_t<managed<T>::is_object>> : public results_common_base<T, Derived> {
354 explícito results_base(internal::bridge::results &&parent)
355 : results_common_base<T, Derived>(std::move(parent)) {
356 }
357
358 managed <T, null> operator[](size_t index) {
359 se (index >= this->m_parent.size())
360 lance std::out_of_range("Índice fora do intervalo.");
361 Método managed<T, null>(internal::bridge::get<internal::bridge::obj>(This->m_parent, index), this->m_parent.get_realm());
362 }
363
364 iterador de classe {
365 público:
366 usando change_type = tamanho_t;
368 usando iterator_category = std::input_iterator_tag;
369
370 operador de bool !=(const iterador e outros) const {
371 return !(*isto == outro);
372 }
373
374 operador bool ==( iterador const e outros) const {
375 return (m_parent == other.m_parent) && (m_idx == outro.m_idx);
376 }
377
378 operador value_type *() noexceto {
379 internal::bridge::obj obj = internal::bridge::get<internal::bridge::obj>(m_parent->m_parent, m_idx);
380 Método managed<T, null>(std::move(obj), this->m_parent->m_parent.get_realm());
381 }
382
383 iterador e operador++() {
384 m_idx++;
385 devolva *isto;
386 }
387
388 operador do iterador++(int i) {
389 m_idx += i;
390 devolva *isto;
391 }
392
393 iterador explícito (size_t idx, derivado *principal)
394 : m_idx(idx), m_parent(parent) {
395 }
396 privado:
397 size_t m_idx;
398 Derivado de *m_parent;
399 };
400
401 iterador begin() {
402 return iterador(0, estático_cast<Derivado*>(isto));
403 }
404
405 end() do iterador {
406 return iterador(isto->m_parent.size(), estático_cast <Derivado *>(isto));
407 }
408 };
409
410 modelo<typename T>
411 estrutura, estrutura resultados : public results_base<T, results<T>> {
412 usando value_type = T;
413 explícito resultados(internal::bridge::results &&parent)
414 : results_base<T, results<T>>(std::move(parent)) {
415 }
416 };
417
418 modelo <auto ptr>
419 estrutura, estrutura linking_objects {
420 estático in-line auto Ptr = ptr;
421 usando Class = typename internal::ptr_type_extractor<ptr>::class_type;
422
423 estático_assert(sizeof(managed <typename internal::ptr_type_extractor<ptr>::class_type>), "O tipo não é gerenciado pelo Realm");
424 };
425
426 modelo <auto ptr> estrutura gerenciada<linking_objects<ptr>> : managed_base {
427 usando iterador = resultados do tipo5nome do tipo interno::ptr_type_extractor<ptr>::class_type>::iterator;
428 usando Class = typename internal::ptr_type_extractor<ptr>::class_type;
429
430 linking_objects<ptr> detach() const {
431 return {};
432 }
433
434 iterador begin() {
435 return iterador(0, get_results());
436 }
437
438 end() do iterador {
439 auto r = get_results();
440 return iterador(r.size(), r);
441 }
442
443 tamanho_t tamanho() {
444 return get_results().size();
445 }
446 managed<Class> operator[](size_t idx) {
447 return get_results()[idx];
448 }
449
450 privado:
451 results<Class> get_results() {
452 auto table = m_obj->get_table();
453 se (!table.is_valid(m_obj->get_key())) {
454 lance std::logical_error("O objeto foi excluído ou invalidado.");
455 }
456
457 internal::bridge::obj* obj = m_obj;
458 auto schema = m_realm->schema().find(managed<Class>::schema.name);
459 auto linking_property = schema.property_for_name(managed<Class>::schema.template name_for_property<ptr>());
460 se (!linking_property.column_key()) {
461 lance std::logical_error("Chave de coluna inválida para propriedade de origem.");
462 }
463
464 internal::bridge::resultados resultados(*m_realm, obj->get_backlink_view(m_realm->get_table(schema.table_key()), linking_property.column_key()));
465 return ::realm::results<Class>(std::move(results));
466 }
467 };
468}
469
470
471#endif //CPPrealm_RESULTS_HPP
Definição: object.hpp:63
Definição: obj.hpp:123
Definição: results.hpp:46
Definição: schema.hpp:51
Definição: results.hpp:419
Definição: macros.hpp:286
Definição: obj.hpp:62
Definição: notificações.hpp:38
Definição: results.hpp:42
Definição: results.hpp:47
Definição: results.hpp:411