19#ifndef CPPREALM_RESULTS_HPP
20#define CPPREALM_RESULTS_HPP
22#include <cpprealm/internal/bridge/mixed.hpp>
23#include <cpprealm/internal/bridge/query.hpp>
24#include <cpprealm/internal/bridge/results.hpp>
25#include <cpprealm/internal/bridge/table.hpp>
26#include <cpprealm/macros.hpp>
27#include <cpprealm/notifications.hpp>
28#include <cpprealm/schema.hpp>
29#include <cpprealm/rbool.hpp>
32 struct mutable_sync_subscription_set;
37 using sort_descriptor = internal::bridge::sort_descriptor;
41 template<
typename T,
typename Derived,
typename ShouldEnable =
void>
43 template<
typename T,
typename Derived>
46 template<
typename T,
typename Derived>
53 std::vector<uint64_t> deletions;
54 std::vector<uint64_t> insertions;
55 std::vector<uint64_t> modifications;
60 bool collection_root_was_deleted =
false;
62 [[nodiscard]]
bool empty()
const noexcept {
63 return deletions.empty() && insertions.empty() && modifications.empty() &&
64 !collection_root_was_deleted;
69 return m_parent.size();
73 Derived where(
const std::string &query,
const std::vector<realm::mixed>& arguments) {
74 std::vector<internal::bridge::mixed> mixed_args;
75 for(
auto& a : arguments)
76 mixed_args.push_back(serialize(a));
78 m_parent.get_table().query(query, std::move(mixed_args))));
81 Derived where(std::function<rbool(managed<T>&)>&& fn) {
82 static_assert(
sizeof(managed<T>),
"Must declare schema for 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));
96 bool ignore_initial_notification =
true)
97 : m_handler(std::move(fn)),
99 m_ignore_changes_in_initial_notification(ignore_initial_notification) {}
104 if (m_ignore_changes_in_initial_notification) {
105 m_ignore_changes_in_initial_notification =
false;
106 m_handler({collection, {}, {}, {}});
107 }
else if (changes.empty()) {
108 m_handler({collection, {}, {}, {}});
109 }
else if (!changes.collection_root_was_deleted() || !changes.deletions().empty()) {
112 to_vector(changes.deletions()),
113 to_vector(changes.insertions()),
114 to_vector(changes.modifications()),
123 bool m_ignore_changes_in_initial_notification;
125 auto vector = std::vector<uint64_t>();
126 for (
auto index: index_set.as_indexes()) {
127 vector.push_back(index);
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();
142 auto frozen_realm = m_parent.get_realm().freeze();
147 auto thawed_realm = m_parent.get_realm().thaw();
148 return Derived(internal::bridge::results(thawed_realm, thawed_realm.table_for_object_type(managed<T>::schema.name)));
152 return m_parent.get_realm().is_frozen();
155 Derived sort(
const std::string& key_path,
bool ascending) {
156 return Derived(m_parent.sort({{key_path, ascending}}));
159 Derived sort(
const std::vector<sort_descriptor>& sort_descriptors) {
160 return Derived(m_parent.sort(sort_descriptors));
164 internal::bridge::results m_parent;
165 template <auto>
friend struct linking_objects;
169 using results_is_primitive = std::enable_if_t<!managed<T>::is_object && !std::is_enum_v<T> && !internal::type_info::is_variant_t<T>::value>;
171 using results_is_enum = std::enable_if_t<!managed<T>::is_object && std::is_enum_v<T> && !internal::type_info::is_variant_t<T>::value>;
173 using results_is_mixed = std::enable_if_t<!managed<T>::is_object && !std::is_enum_v<T> && internal::type_info::is_variant_t<T>::value>;
175 template<
typename T,
typename Derived>
181 T operator[](
size_t index) {
182 if (index >= this->m_parent.size())
183 throw std::out_of_range(
"Index out of range.");
184 return internal::bridge::get<T>(this->m_parent, index);
189 using difference_type = size_t;
190 using value_type = T;
191 using iterator_category = std::input_iterator_tag;
193 bool operator!=(
const iterator &other)
const {
194 return !(*
this == other);
197 bool operator==(
const iterator &other)
const {
198 return (m_parent == other.m_parent) && (m_idx == other.m_idx);
201 value_type operator*()
noexcept {
202 return m_parent->operator[](m_idx);
205 iterator &operator++() {
210 iterator operator++(
int i) {
215 explicit iterator(
size_t idx, Derived *parent)
216 : m_idx(idx), m_parent(parent) {
224 return iterator(0,
static_cast<Derived*
>(
this));
228 return iterator(this->m_parent.size(),
static_cast<Derived*
>(
this));
232 template<
typename T,
typename Derived>
238 T operator[](
size_t index) {
239 if (index >= this->m_parent.size())
240 throw std::out_of_range(
"Index out of range.");
241 return deserialize<T>(internal::bridge::get<internal::bridge::mixed>(this->m_parent, index));
252 using difference_type = size_t;
253 using value_type = T;
254 using iterator_category = std::input_iterator_tag;
256 bool operator!=(
const iterator &other)
const {
257 return !(*
this == other);
260 bool operator==(
const iterator &other)
const {
261 return (m_parent == other.m_parent) && (m_idx == other.m_idx);
264 value_type operator*()
noexcept {
265 return m_parent->operator[](m_idx);
268 iterator &operator++() {
273 iterator operator++(
int i) {
278 explicit iterator(
size_t idx, Derived *parent)
279 : m_idx(idx), m_parent(parent) {
287 return iterator(0,
static_cast<Derived*
>(
this));
291 return iterator(this->m_parent.size(),
static_cast<Derived*
>(
this));
295 template<
typename T,
typename Derived>
301 T operator[](
size_t index) {
302 if (index >= this->m_parent.size())
303 throw std::out_of_range(
"Index out of range.");
304 return static_cast<T
>(internal::bridge::get<int64_t>(this->m_parent, index));
309 using difference_type = size_t;
310 using value_type = T;
311 using iterator_category = std::input_iterator_tag;
313 bool operator!=(
const iterator &other)
const {
314 return !(*
this == other);
317 bool operator==(
const iterator &other)
const {
318 return (m_parent == other.m_parent) && (m_idx == other.m_idx);
321 value_type operator*()
noexcept {
322 return m_parent->operator[](m_idx);
325 iterator &operator++() {
330 iterator operator++(
int i) {
335 explicit iterator(
size_t idx, Derived *parent)
336 : m_idx(idx), m_parent(parent) {
344 return iterator(0,
static_cast<Derived*
>(
this));
348 return iterator(this->m_parent.size(),
static_cast<Derived*
>(
this));
352 template<
typename T,
typename Derived>
359 if (index >= this->m_parent.size())
360 throw std::out_of_range(
"Index out of range.");
361 return managed<T, void>(internal::bridge::get<internal::bridge::obj>(this->m_parent, index), this->m_parent.get_realm());
366 using difference_type = size_t;
368 using iterator_category = std::input_iterator_tag;
370 bool operator!=(
const iterator &other)
const {
371 return !(*
this == other);
374 bool operator==(
const iterator &other)
const {
375 return (m_parent == other.m_parent) && (m_idx == other.m_idx);
380 return managed<T, void>(std::move(obj), this->m_parent->m_parent.get_realm());
383 iterator &operator++() {
388 iterator operator++(
int i) {
393 explicit iterator(
size_t idx, Derived *parent)
394 : m_idx(idx), m_parent(parent) {
402 return iterator(0,
static_cast<Derived*
>(
this));
406 return iterator(this->m_parent.size(),
static_cast<Derived*
>(
this));
412 using value_type = T;
420 static inline auto Ptr = ptr;
435 return iterator(0, get_results());
439 auto r = get_results();
440 return iterator(r.size(), r);
444 return get_results().size();
447 return get_results()[idx];
452 auto table = m_obj->get_table();
453 if (!table.is_valid(m_obj->get_key())) {
454 throw std::logic_error(
"Object has been deleted or invalidated.");
459 auto linking_property = schema.property_for_name(
managed<Class>::schema.
template name_for_property<ptr>());
460 if (!linking_property.column_key()) {
461 throw std::logic_error(
"Invalid column key for origin property.");
465 return ::realm::results<Class>(std::move(
results));
Definition: object.hpp:148
Definition: object.hpp:126
Definition: object.hpp:63
Definition: results.hpp:46
Definition: results.hpp:419
Definition: macros.hpp:286
Definition: notifications.hpp:38
Definition: results.hpp:42
Definition: results.hpp:93
Definition: results.hpp:51
Definition: results.hpp:47
Definition: results.hpp:411