Skip to content

Commit

Permalink
fix remove recursive to follow mixed links
Browse files Browse the repository at this point in the history
  • Loading branch information
ironage committed Jun 20, 2024
1 parent 722eccd commit 71f78e9
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
* Fixed a change of mode from Strong to All when removing links from an embedded object that links to a tombstone. This affects sync apps that use embedded objects which have a `Lst<Mixed>` that contains a link to another top level object which has been deleted by another sync client (creating a tombstone locally). In this particular case, the switch would cause any remaining link removals to recursively delete the destination object if there were no other links to it. ([#7828](https://github.com/realm/realm-core/issues/7828), since 14.0.0-beta.0)
* Fixed `Table::remove_object_recursive` which wouldn't recursively follow links through a single `Mixed` property. ([#7829](https://github.com/realm/realm-core/issues/7829), likely since the introduction of Mixed)

### Breaking changes
* None.
Expand Down
9 changes: 3 additions & 6 deletions src/realm/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -788,11 +788,8 @@ inline void Cluster::do_erase_mixed(size_t ndx, ColKey col_key, ObjKey key, Casc
Mixed value = values.get(ndx);
if (value.is_type(type_TypedLink)) {
ObjLink link = value.get<ObjLink>();
auto target_obj = origin_table->get_parent_group()->get_object(link);

ColKey backlink_col_key = target_obj.get_table()->find_backlink_column(col_key, origin_table->get_key());
REALM_ASSERT(backlink_col_key);
target_obj.remove_one_backlink(backlink_col_key, get_real_key(ndx)); // Throws
Obj obj(origin_table->m_own_ref, get_mem(), key, ndx);
obj.remove_backlink(col_key, link, state);
}
if (value.is_type(type_List)) {
Obj obj(origin_table->m_own_ref, get_mem(), key, ndx);
Expand Down Expand Up @@ -1541,7 +1538,7 @@ void Cluster::remove_backlinks(const Table* origin_table, ObjKey origin_key, Col
bool last_removed = target_obj.remove_one_backlink(backlink_col_key, origin_key); // Throws
if (is_unres) {
if (last_removed) {
// Check is there are more backlinks
// Check if there are more backlinks
if (!target_obj.has_backlinks(false)) {
// Tombstones can be erased right away - there is no cascading effect
target_table->m_tombstones->erase(link.get_obj_key(), state);
Expand Down
21 changes: 21 additions & 0 deletions test/test_mixed_null_assertions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,24 @@ TEST(Mixed_EmbeddedLstMixedRecursiveDelete)
CHECK_EQUAL(top3_obj4.get_backlink_count(), 0);
}

TEST(Mixed_SingleLinkRecursiveDelete)
{
Group g;
auto top1 = g.add_table_with_primary_key("source", type_String, "_id");
auto top2 = g.add_table_with_primary_key("top2", type_String, "_id");

ColKey top1_mixed_col = top1->add_column(type_Mixed, "mixed");
auto top1_obj1 = top1->create_object_with_primary_key("top1_obj1");
auto top2_obj1 = top2->create_object_with_primary_key("top2_obj1");

top1_obj1.set<Mixed>(top1_mixed_col, ObjLink{top2->get_key(), top2_obj1.get_key()});

CHECK_EQUAL(top2_obj1.get_backlink_count(), 1);

top1->remove_object_recursive(top1_obj1.get_key());

CHECK_NOT(top1_obj1.is_valid());
CHECK_EQUAL(top1->size(), 0);
CHECK_NOT(top2_obj1.is_valid());
CHECK_EQUAL(top2->size(), 0);
}

0 comments on commit 71f78e9

Please sign in to comment.