Skip to content

Commit

Permalink
Add support for keypaths crossing backlins
Browse files Browse the repository at this point in the history
  • Loading branch information
jedelbo committed Nov 17, 2023
1 parent ca8e1c5 commit be45032
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
21 changes: 10 additions & 11 deletions src/realm/object-store/c_api/notifications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,21 +88,20 @@ static KeyPathArray create_key_path_array(const ObjectSchema& object_schema, con
StringData property(path, p - path);
path = p;
if (!schema_at_index) {
auto found_schema = schema.find(prop->object_type);
if (found_schema != schema.end()) {
schema_at_index = &*found_schema;
}
else {
throw InvalidArgument(
util::format("Property '%1' in KeyPath '%2' is not a collection of objects or an object "
"reference, so it cannot be used as an intermediate keypath element.",
prop->public_name, *it));
}
throw InvalidArgument(
util::format("Property '%1' in KeyPath '%2' is not a collection of objects or an object "
"reference, so it cannot be used as an intermediate keypath element.",
prop->public_name, *it));
}
prop = schema_at_index->property_for_public_name(property);
if (prop) {
if (prop->type == PropertyType::Object || prop->type == PropertyType::LinkingObjects) {
auto found_schema = schema.find(prop->object_type);
if (found_schema != schema.end()) {
schema_at_index = &*found_schema;
}
}
resolved_key_path.emplace_back(schema_at_index->table_key, prop->column_key);
schema_at_index = nullptr;
}
else {
throw InvalidArgument(util::format("Property '%1' in KeyPath '%2' is not a valid property in %3.",
Expand Down
7 changes: 7 additions & 0 deletions src/realm/object-store/object_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,13 @@ void ObjectStore::set_schema_keys(Group const& group, Schema& schema)
for (auto& property : object_schema.persisted_properties) {
property.column_key = table->get_column_key(property.name);
}
for (auto& property : object_schema.computed_properties) {
if (property.type == PropertyType::LinkingObjects) {
auto origin_table = ObjectStore::table_for_object_type(group, property.object_type);
auto origin_column_key = origin_table->get_column_key(property.link_origin_property_name);
property.column_key = origin_table->get_opposite_column(origin_column_key);
}
}
}
}

Expand Down
17 changes: 17 additions & 0 deletions test/object-store/c_api/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2779,6 +2779,23 @@ TEST_CASE("C API - properties", "[c_api]") {
REQUIRE(key_path_array);
realm_release(key_path_array);
}
SECTION("using backlink") {
const char* bar_strings[1] = {"linking_objects.public_int"};
auto key_path_array = realm_create_key_path_array(realm, class_bar.key, 1, bar_strings);
REQUIRE(key_path_array);
auto token = cptr_checked(realm_list_add_notification_callback(bars.get(), &state, nullptr,
key_path_array, on_change));
realm_release(key_path_array);
checked(realm_refresh(realm, nullptr));

state.called = false;
write([&]() {
checked(realm_set_value(obj1.get(), foo_int_key, rlm_int_val(999), false));
});
REQUIRE(state.called);
CHECK(!state.error);
CHECK(state.changes);
}
SECTION("using invalid nesting") {
const char* bar_strings[1] = {"doubles.age"};
auto key_path_array = realm_create_key_path_array(realm, class_bar.key, 1, bar_strings);
Expand Down

0 comments on commit be45032

Please sign in to comment.