Skip to content

Commit

Permalink
Js/sectioned notification (#5926)
Browse files Browse the repository at this point in the history
* repro bug

* set sectioned results previous values on the initial run

* address review feedback
  • Loading branch information
ironage authored Oct 19, 2022
1 parent 7ff5f51 commit 8c07642
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 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 an assertion failure when observing change notifications on a sectioned result, if the first modification was to a linked property that did not cause the state of the sections to change. ([#5912](https://github.com/realm/realm-core/issues/5912), since the introduction of sectioned results in v12.3.0)
* CompensatingWriteErrorInfo reported string primary keys as boolean values instead ([PR #5938](https://github.com/realm/realm-core/pull/5938), since the introduction of CompensatingWriteErrorInfo in 12.1.0).
* Fix a use-after-free if the last external reference to an encrypted Realm was closed between when a client reset error was received and when the download of the new Realm began. ([PR #5949](https://github.com/realm/realm-core/pull/5949), since 12.4.0).

Expand Down
8 changes: 8 additions & 0 deletions src/realm/object-store/sectioned_results.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,14 @@ void SectionedResults::calculate_sections()
m_row_to_index_path[i] = {section.index, section.indices.size() - 1};
}
}
if (!has_performed_initial_evalutation) {
REALM_ASSERT_EX(m_previous_key_to_index_lookup.size() == 0, m_previous_key_to_index_lookup.size());
REALM_ASSERT_EX(m_prev_section_index_to_key.size() == 0, m_prev_section_index_to_key.size());
for (auto& [key, section] : m_sections) {
m_previous_key_to_index_lookup[key] = section.index;
m_prev_section_index_to_key[section.index] = section.key;
}
}
}

size_t SectionedResults::size()
Expand Down
69 changes: 69 additions & 0 deletions test/object-store/sectioned_results.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,75 @@ TEST_CASE("sectioned results", "[sectioned_results]") {
}
}

TEST_CASE("sectioned results link notification bug", "[sectioned_results]") {
_impl::RealmCoordinator::assert_no_open_realms();

InMemoryTestFile config;
config.automatic_change_notifications = false;

auto r = Realm::get_shared_realm(config);
r->update_schema(
{{"Transaction",
{{"_id", PropertyType::String, Property::IsPrimary{true}},
{"date", PropertyType::Date},
{"account", PropertyType::Object | PropertyType::Nullable, "Account"}}},
{"Account", {{"_id", PropertyType::String, Property::IsPrimary{true}}, {"name", PropertyType::String}}}});

auto coordinator = _impl::RealmCoordinator::get_coordinator(config.path);
auto transaction_table = r->read_group().get_table("class_Transaction");
transaction_table->get_column_key("date");
auto account_col = transaction_table->get_column_key("account");
auto account_table = r->read_group().get_table("class_Account");
auto account_name_col = account_table->get_column_key("name");

r->begin_transaction();
auto t1 = transaction_table->create_object_with_primary_key("t");
auto a1 = account_table->create_object_with_primary_key("a");
t1.set(account_col, a1.get_key());
r->commit_transaction();

Results results(r, transaction_table);
auto sorted = results.sort({{"date", false}});
auto sectioned_results = sorted.sectioned_results([](Mixed value, SharedRealm realm) {
auto obj = Object(realm, value.get_link());
auto ts = obj.get_column_value<Timestamp>("date");
auto tp = ts.get_time_point();
auto day = std::chrono::floor<std::chrono::hours>(tp);
return Timestamp{day};
});

REQUIRE(sectioned_results.size() == 1);
REQUIRE(sectioned_results[0].size() == 1);

SectionedResultsChangeSet changes;
size_t callback_count = 0;
auto token = sectioned_results.add_notification_callback([&](SectionedResultsChangeSet c) {
changes = c;
++callback_count;
});
coordinator->on_change();
advance_and_notify(*r);
REQUIRE(callback_count == 1);
REQUIRE(changes.sections_to_insert.empty());
REQUIRE(changes.sections_to_delete.empty());
REQUIRE(changes.insertions.size() == 0);
REQUIRE(changes.deletions.size() == 0);
REQUIRE(changes.modifications.size() == 0);

r->begin_transaction();
a1.set(account_name_col, "a2");
r->commit_transaction();
advance_and_notify(*r);

REQUIRE(callback_count == 2);
REQUIRE(changes.sections_to_insert.empty());
REQUIRE(changes.sections_to_delete.empty());
REQUIRE(changes.insertions.size() == 0);
REQUIRE(changes.deletions.size() == 0);
REQUIRE(changes.modifications.size() == 1);
REQUIRE_INDICES(changes.modifications[0], 0);
}

namespace cf = realm::sectioned_results_fixtures;

TEMPLATE_TEST_CASE("sectioned results primitive types", "[sectioned_results]", cf::MixedVal, cf::Int, cf::Bool,
Expand Down

0 comments on commit 8c07642

Please sign in to comment.