Skip to content

Commit

Permalink
RCPP-80 RCPP-81 Add to_json, truepredicate & falsepredicate (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
leemaguire authored Jun 21, 2024
1 parent 9f0dc47 commit bc0e1a6
Show file tree
Hide file tree
Showing 19 changed files with 160 additions and 103 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Package.resolved
examples/*.pro.user
docs/html
docs/latex
.idea
realm-core/src/realm/parser/generated
.idea/
realm-core/src/realm/parser/generated/
8 changes: 0 additions & 8 deletions .idea/.gitignore

This file was deleted.

1 change: 0 additions & 1 deletion .idea/.name

This file was deleted.

19 changes: 0 additions & 19 deletions .idea/codeStyles/Project.xml

This file was deleted.

5 changes: 0 additions & 5 deletions .idea/codeStyles/codeStyleConfig.xml

This file was deleted.

25 changes: 0 additions & 25 deletions .idea/deployment.xml

This file was deleted.

4 changes: 0 additions & 4 deletions .idea/misc.xml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

2 changes: 0 additions & 2 deletions .idea/realm-cpp-sdk.iml

This file was deleted.

16 changes: 0 additions & 16 deletions .idea/vcs.xml

This file was deleted.

4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
X.Y.Z Release notes (YYYY-MM-DD)
NEXT RELEASE Release notes (YYYY-MM-DD)
=============================================================

### Fixed
Expand All @@ -8,6 +8,8 @@ X.Y.Z Release notes (YYYY-MM-DD)
* Add `realm::default_scheduler::set_default_factory(std::function<std::shared_ptr<realm::scheduler>()>&& factory_fn)` for generating a default scheduler.
Set your scheduler factory before instantiating a `realm::db_config`.
* Add `realm::default_scheduler::make_default()` which generates a platform default scheduler if `realm::default_scheduler::set_default_factory` is not set.
* Add `managed<T>::to_json(std::ostream&)` which allows managed objects to be printed as json.
* Add `rbool::truepredicate()` and `rbool::falsepredicate()` expressions for type safe queries.

### Compatibility
* Fileformat: Generates files with format v24. Reads and automatically upgrade from fileformat v10.
Expand Down
2 changes: 1 addition & 1 deletion include/cpprealm/internal/bridge/obj.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ namespace realm::internal::bridge {
void set_null(const col_key&);
obj create_and_set_linked_object(const col_key&);
table_view get_backlink_view(table, col_key);

void to_json(std::ostream& out) const noexcept;
private:
inline const Obj* get_obj() const;
inline Obj* get_obj();
Expand Down
8 changes: 3 additions & 5 deletions include/cpprealm/internal/bridge/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ namespace realm::internal::bridge {
query& links_to(col_key column_key, const internal::bridge::obj& o);
query& not_links_to(col_key column_key, const internal::bridge::obj& o);

// Expressions
static query falsepredicate();

std::string description() const;
private:
inline Query* get_query();
Expand All @@ -243,11 +246,6 @@ namespace realm::internal::bridge {

};

template <typename T>
using QFn = query& (query::*)(col_key, T);
template <typename T>
using QFnCS = query& (query::*)(col_key, T, bool);

query operator || (const query& lhs, const query& rhs);
}

Expand Down
22 changes: 21 additions & 1 deletion include/cpprealm/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,9 @@ rbool managed<std::optional<type>>::operator op(const std::optional<type>& rhs)
db get_realm() { \
return db(m_realm); \
} \
bool operator ==(const managed<cls>& other) const { \
bool operator ==(const managed<cls>& other) const { \
if (m_rbool_query != nullptr) \
throw std::runtime_error("This comparison operator is not valid inside of `where`"); \
auto& a = m_obj; \
auto& b = other.m_obj; \
if (m_realm != other.m_realm) { \
Expand All @@ -554,6 +556,8 @@ rbool managed<std::optional<type>>::operator op(const std::optional<type>& rhs)
&& a.get_key() == b.get_key(); \
} \
bool operator ==(const managed<cls*>& other) const { \
if (m_rbool_query != nullptr) \
throw std::runtime_error("This comparison operator is not valid inside of `where`"); \
auto& a = m_obj; \
auto& b = other.m_obj; \
if (m_realm != other->m_realm) { \
Expand All @@ -571,6 +575,9 @@ rbool managed<std::optional<type>>::operator op(const std::optional<type>& rhs)
bool operator < (const managed<cls>& rhs) const { \
return m_obj.get_key() < rhs.m_obj.get_key(); \
} \
void to_json(std::ostream& out) const noexcept { \
m_obj.to_json(out); \
} \
private: \
internal::bridge::obj m_obj; \
internal::bridge::realm m_realm; \
Expand All @@ -579,6 +586,8 @@ rbool managed<std::optional<type>>::operator op(const std::optional<type>& rhs)
template <typename, typename> friend struct managed; \
template <typename, typename> friend struct box; \
template <typename> friend struct ::realm::thread_safe_reference; \
template <typename T> friend rbool* ::realm::internal::get_rbool(const T&); \
\
}; \
struct meta_schema_##cls { \
meta_schema_##cls() { \
Expand All @@ -590,4 +599,15 @@ rbool managed<std::optional<type>>::operator op(const std::optional<type>& rhs)
}; \
static inline meta_schema_##cls _meta_schema_##cls{};

namespace realm::internal {
/*
* Helper method for extracting the private `m_rbool_query`
* property on a managed<T> object.
*/
template<typename T>
rbool* get_rbool(const T& o) {
return o.m_rbool_query;
}
}

#endif //CPPREALM_MACROS_HPP
28 changes: 24 additions & 4 deletions include/cpprealm/rbool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,11 @@ namespace realm {
std::optional<internal::bridge::link_chain> m_link_chain;
internal::bridge::table m_table;

friend rbool operator&&(const rbool &lhs, const rbool &rhs);

template<typename T>
friend struct results;

friend rbool operator&&(const rbool &lhs, const rbool &rhs);
friend rbool operator||(const rbool &lhs, const rbool &rhs);
public:

rbool& add_link_chain(const internal::bridge::col_key& col_key) {
if (m_link_chain) {
m_link_chain->link(col_key);
Expand Down Expand Up @@ -237,6 +234,29 @@ namespace realm {
}
return lhs.b && rhs.b;
}

/// Return all objects from a collection.
template<typename T>
inline rbool truepredicate(const T& o) {
// An empty query returns all results and one way to indicate this
// is to serialise TRUEPREDICATE which is functionally equivalent
rbool* rb = internal::get_rbool(o);
if (rb == nullptr)
throw std::runtime_error("Managed object is not used in a query context");
auto table = rb->q.get_table();
return rbool(table);
}

/// Return no objects from a collection.
template<typename T>
inline rbool falsepredicate(const T& o) {
rbool* rb = internal::get_rbool(o);
if (rb == nullptr)
throw std::runtime_error("Managed object is not used in a query context");
auto table = rb->q.get_table();
auto q = internal::bridge::query(table).and_query(internal::bridge::query(table).falsepredicate());
return rbool(std::move(q));
}
}

#endif //CPPREALM_RBOOL_HPP
4 changes: 4 additions & 0 deletions src/cpprealm/internal/bridge/obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,10 @@ namespace realm::internal::bridge {
table_view obj::get_backlink_view(table table, col_key col_key) {
return get_obj()->get_backlink_view(table, col_key);
}

void obj::to_json(std::ostream& out) const noexcept {
return get_obj()->to_json(out);
}
}

std::string realm::internal::bridge::table_name_for_object_type(const std::string &v) {
Expand Down
4 changes: 4 additions & 0 deletions src/cpprealm/internal/bridge/query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,10 @@ namespace realm::internal::bridge {
return *this;
}

query query::falsepredicate() {
return query(Query(std::make_unique<FalseExpression>()));
}

std::string query::description() const {
#ifdef CPPREALM_HAVE_GENERATED_BRIDGE_TYPES
return reinterpret_cast<const Query *>(&m_query)->get_description();
Expand Down
18 changes: 18 additions & 0 deletions tests/db/object_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "../main.hpp"
#include "test_objects.hpp"

#include <iostream>

namespace realm {

enum class PrimaryKeyEnum {
Expand Down Expand Up @@ -1035,6 +1037,22 @@ namespace realm {
CHECK(realm.objects<AllTypesObjectLink>().size() == 1);
}

SECTION("to_json") {
StringObject str_obj;
str_obj.str_col = "test";
str_obj._id = 123;
auto realm = db(std::move(config));

auto managed_obj = realm.write([&](){
return realm.add(std::move(str_obj));
});

std::stringstream ss;
managed_obj.to_json(ss);
auto json_str = ss.str();
CHECK(json_str == "{\"_id\":123,\"str_col\":\"test\"}");
}

static_assert(!std::is_constructible_v<typename managed<AllTypesObjectLink *>::ref_type>, "Default constructor is private.");
static_assert(!std::is_constructible_v<managed<int64_t>>, "Default constructor is private.");
static_assert(!std::is_constructible_v<managed<double>>, "Default constructor is private.");
Expand Down
Loading

0 comments on commit bc0e1a6

Please sign in to comment.