diff --git a/src/realm.h b/src/realm.h index f4b1449ded1..5b6a4d9f1c8 100644 --- a/src/realm.h +++ b/src/realm.h @@ -1946,6 +1946,13 @@ RLM_API bool realm_object_changes_is_deleted(const realm_object_changes_t*); */ RLM_API size_t realm_object_changes_get_num_modified_properties(const realm_object_changes_t*); +/** + * Get the number of paths to embedded collections that were modified. + * + * This function cannot fail. + */ +RLM_API size_t realm_object_changes_get_num_modified_paths(const realm_object_changes_t*); + /** * Get the column keys for the properties that were modified in an object * notification. @@ -1960,6 +1967,20 @@ RLM_API size_t realm_object_changes_get_num_modified_properties(const realm_obje RLM_API size_t realm_object_changes_get_modified_properties(const realm_object_changes_t*, realm_property_key_t* out_modified, size_t max); +/** + * Get the column keys for the properties that were modified in an object + * notification. + * + * This function cannot fail. + * + * @param out_modified Where the paths should be written. May be NULL. + * @param max The maximum number of paths to write. + * @return The number of paths written to @a out_modified, or the number + * of modified paths if @a out_modified is NULL. + */ +RLM_API size_t realm_object_changes_get_modified_paths(const realm_object_changes_t*, realm_string_t* out_modified, + size_t max); + /** * Get the number of various types of changes in a collection notification. * diff --git a/src/realm/collection.hpp b/src/realm/collection.hpp index 6dbcebc7eaf..0c2b1b071bf 100644 --- a/src/realm/collection.hpp +++ b/src/realm/collection.hpp @@ -39,6 +39,7 @@ class DummyParent : public CollectionParent { { return {}; } + void translate_path(const StablePath&, Path&) const final {} void add_index(Path&, const Index&) const noexcept final {} size_t find_index(const Index&) const noexcept final { diff --git a/src/realm/collection_parent.hpp b/src/realm/collection_parent.hpp index 53fe3ecb711..8fb95ff62ae 100644 --- a/src/realm/collection_parent.hpp +++ b/src/realm/collection_parent.hpp @@ -90,6 +90,7 @@ class CollectionParent : public std::enable_shared_from_this { // Return path from owning object virtual StablePath get_stable_path() const = 0; // Add a translation of Index to PathElement + virtual void translate_path(const StablePath&, Path&) const = 0; virtual void add_index(Path& path, const Index& ndx) const = 0; // Return position of Index held by child virtual size_t find_index(const Index& ndx) const = 0; @@ -110,9 +111,9 @@ class CollectionParent : public std::enable_shared_from_this { friend class CollectionList; #ifdef REALM_DEBUG - static constexpr size_t s_max_level = 4; + static constexpr int s_max_level = 4; #else - static constexpr size_t s_max_level = 100; + static constexpr int s_max_level = 100; #endif uint8_t m_level = 0; diff --git a/src/realm/dictionary.cpp b/src/realm/dictionary.cpp index dbc9da3aba9..aff9968f7c5 100644 --- a/src/realm/dictionary.cpp +++ b/src/realm/dictionary.cpp @@ -634,6 +634,28 @@ Dictionary::Iterator Dictionary::find(Mixed key) const noexcept return end(); } + +void Dictionary::translate_path(const StablePath& stable_path, Path& path) const +{ + auto& index = stable_path[m_level]; + auto ndx = find_index(index); + StringData key = do_get_key(ndx).get_string(); + path.emplace_back(key); + if (stable_path.size() > size_t(m_level) + 1) { + Mixed val = do_get(ndx); + if (val.is_type(type_Dictionary)) { + DummyParent parent(this->get_table(), val.get_ref()); + Dictionary dict(parent, 0); + dict.translate_path(stable_path, path); + } + else if (val.is_type(type_List)) { + DummyParent parent(this->get_table(), val.get_ref()); + Lst list(parent, 0); + list.translate_path(stable_path, path); + } + } +} + void Dictionary::add_index(Path& path, const Index& index) const { auto ndx = m_values->find_key(index.get_salt()); diff --git a/src/realm/dictionary.hpp b/src/realm/dictionary.hpp index ee313c9453a..29c52167cea 100644 --- a/src/realm/dictionary.hpp +++ b/src/realm/dictionary.hpp @@ -202,6 +202,7 @@ class Dictionary final : public CollectionBaseImpl, public Colle { return Base::get_stable_path(); } + void translate_path(const StablePath& stable_path, Path& path) const final; void add_index(Path& path, const Index& ndx) const final; size_t find_index(const Index&) const final; diff --git a/src/realm/list.cpp b/src/realm/list.cpp index 5a5482b70dc..14d52efa14a 100644 --- a/src/realm/list.cpp +++ b/src/realm/list.cpp @@ -763,6 +763,26 @@ void Lst::set_collection_ref(Index index, ref_type ref, CollectionType ty m_tree->set(ndx, Mixed(ref, type)); } +void Lst::translate_path(const StablePath& stable_path, Path& path) const +{ + auto& index = stable_path[m_level]; + auto ndx = find_index(index); + path.emplace_back(ndx); + if (stable_path.size() > size_t(m_level) + 1) { + Mixed val = get(ndx); + if (val.is_type(type_Dictionary)) { + DummyParent parent(this->get_table(), val.get_ref()); + Dictionary dict(parent, 0); + dict.translate_path(stable_path, path); + } + else if (val.is_type(type_List)) { + DummyParent parent(this->get_table(), val.get_ref()); + Lst list(parent, 0); + list.translate_path(stable_path, path); + } + } +} + void Lst::add_index(Path& path, const Index& index) const { auto ndx = m_tree->find_key(index.get_salt()); diff --git a/src/realm/list.hpp b/src/realm/list.hpp index fec6505c030..099d662a6d5 100644 --- a/src/realm/list.hpp +++ b/src/realm/list.hpp @@ -466,6 +466,7 @@ class Lst final : public CollectionBaseImpl, public CollectionPa { return Base::get_stable_path(); } + void translate_path(const StablePath& stable_path, Path& path) const final; ColKey get_col_key() const noexcept override { diff --git a/src/realm/obj.cpp b/src/realm/obj.cpp index d0e1c3c0bd2..eee4cb4929e 100644 --- a/src/realm/obj.cpp +++ b/src/realm/obj.cpp @@ -2090,6 +2090,16 @@ CollectionPtr Obj::get_collection_ptr(const Path& path) const return collection; } +void Obj::translate_path(const StablePath& stable_path, Path& path) const +{ + ColKey col_key = m_table->get_column_key(stable_path[0]); + path.emplace_back(m_table->get_column_name(col_key)); + if (stable_path.size() > 1) { + CollectionBasePtr collection = get_collection_ptr(col_key); + dynamic_cast(collection.get())->translate_path(stable_path, path); + } +} + CollectionPtr Obj::get_collection_by_stable_path(const StablePath& path) const { // First element in path is phony column key diff --git a/src/realm/obj.hpp b/src/realm/obj.hpp index c7c25399500..9b4ada7ebe4 100644 --- a/src/realm/obj.hpp +++ b/src/realm/obj.hpp @@ -72,6 +72,7 @@ class Obj { Path get_short_path() const noexcept; ColKey get_col_key() const noexcept; StablePath get_stable_path() const noexcept; + void translate_path(const StablePath&, Path&) const; void add_index(Path& path, const CollectionParent::Index& ndx) const; TableRef get_table() const noexcept @@ -441,6 +442,10 @@ class ObjCollectionParent final : public Obj, public CollectionParent { { return Obj::get_stable_path(); } + void translate_path(const StablePath& stable_path, Path& path) const override + { + Obj::translate_path(stable_path, path); + } void add_index(Path& path, const Index& ndx) const override { Obj::add_index(path, ndx); diff --git a/src/realm/object-store/binding_context.hpp b/src/realm/object-store/binding_context.hpp index 26a7cb62894..5a6e8c42c1e 100644 --- a/src/realm/object-store/binding_context.hpp +++ b/src/realm/object-store/binding_context.hpp @@ -165,7 +165,7 @@ class BindingContext { // Populated with information about which columns were changed // May be shorter than the actual number of columns if the later columns // are not modified - std::unordered_map changes; + std::unordered_map changes; // Simple lexographic ordering friend bool operator<(ObserverState const& lft, ObserverState const& rgt) diff --git a/src/realm/object-store/c_api/notifications.cpp b/src/realm/object-store/c_api/notifications.cpp index 666e3110fcf..3de35080ed7 100644 --- a/src/realm/object-store/c_api/notifications.cpp +++ b/src/realm/object-store/c_api/notifications.cpp @@ -113,6 +113,11 @@ RLM_API size_t realm_object_changes_get_num_modified_properties(const realm_obje return changes->columns.size(); } +RLM_API size_t realm_object_changes_get_num_modified_paths(const realm_object_changes_t* changes) +{ + return changes->modified_paths.size(); +} + RLM_API size_t realm_object_changes_get_modified_properties(const realm_object_changes_t* changes, realm_property_key_t* out_properties, size_t max) { @@ -130,6 +135,39 @@ RLM_API size_t realm_object_changes_get_modified_properties(const realm_object_c return i; } +RLM_API size_t realm_object_changes_get_modified_paths(const realm_object_changes_t* const_changes, + realm_string_t* out_paths, size_t max) +{ + if (!out_paths) + return const_changes->modified_paths.size(); + + realm_object_changes_t* changes = const_cast(const_changes); + changes->path_buffer.resize(changes->modified_paths.size()); + size_t i = 0; + for (const auto& p : changes->modified_paths) { + if (i >= max) { + break; + } + std::string& path = changes->path_buffer[i]; + path = p[0].get_key(); + for (auto path_elem = p.begin() + 1; path_elem != p.end(); ++path_elem) { + if (path_elem->is_key()) { + path += '.'; + path += path_elem->get_key(); + } + else { + char buffer[10]; + sprintf(buffer, "[%u]", unsigned(path_elem->get_ndx())); + path += buffer; + } + } + out_paths[i].data = path.data(); + out_paths[i].size = path.size(); + ++i; + } + return i; +} + RLM_API realm_notification_token_t* realm_list_add_notification_callback(realm_list_t* list, realm_userdata_t userdata, realm_free_userdata_func_t free, diff --git a/src/realm/object-store/c_api/types.hpp b/src/realm/object-store/c_api/types.hpp index 317fc09fec9..4c46cc60dd7 100644 --- a/src/realm/object-store/c_api/types.hpp +++ b/src/realm/object-store/c_api/types.hpp @@ -428,6 +428,7 @@ struct realm_object_changes : realm::c_api::WrapC, realm::CollectionChangeSet { { return new realm_object_changes{static_cast(*this)}; } + std::vector path_buffer; }; struct realm_collection_changes : realm::c_api::WrapC, realm::CollectionChangeSet { diff --git a/src/realm/object-store/collection_notifications.hpp b/src/realm/object-store/collection_notifications.hpp index d484e73cd02..af80e703fe1 100644 --- a/src/realm/object-store/collection_notifications.hpp +++ b/src/realm/object-store/collection_notifications.hpp @@ -105,8 +105,9 @@ struct CollectionChangeSet { // Per-column version of `modifications` std::unordered_map columns; + std::vector modified_paths; - std::set paths; + std::set stable_indexes; bool empty() const noexcept { diff --git a/src/realm/object-store/impl/collection_change_builder.cpp b/src/realm/object-store/impl/collection_change_builder.cpp index 66f9923bcae..5bbdb546b36 100644 --- a/src/realm/object-store/impl/collection_change_builder.cpp +++ b/src/realm/object-store/impl/collection_change_builder.cpp @@ -704,5 +704,5 @@ CollectionChangeSet CollectionChangeBuilder::finalize() && return {std::move(deletions), std::move(insertions), std::move(modifications_in_old), std::move(modifications), std::move(moves), collection_root_was_deleted, - collection_was_cleared, std::move(columns)}; + collection_was_cleared, std::move(columns), std::move(modified_paths)}; } diff --git a/src/realm/object-store/impl/list_notifier.cpp b/src/realm/object-store/impl/list_notifier.cpp index ebcfb797d77..9b22ad811c6 100644 --- a/src/realm/object-store/impl/list_notifier.cpp +++ b/src/realm/object-store/impl/list_notifier.cpp @@ -132,10 +132,10 @@ void ListNotifier::run() // Modifications to nested values in Mixed are recorded in replication as // StableIndex and we have to look up the actual index afterwards - if (m_change.paths.size()) { + if (m_change.stable_indexes.size()) { REALM_ASSERT(m_collection_parent); REALM_ASSERT(m_type == PropertyType::Mixed); - for (auto& p : m_change.paths) { + for (auto& p : m_change.stable_indexes) { if (auto ndx = m_collection_parent->find_index(p); ndx != realm::not_found) m_change.modifications.add(ndx); } diff --git a/src/realm/object-store/impl/object_notifier.cpp b/src/realm/object-store/impl/object_notifier.cpp index 676680017d8..078b0d4876e 100644 --- a/src/realm/object-store/impl/object_notifier.cpp +++ b/src/realm/object-store/impl/object_notifier.cpp @@ -100,13 +100,19 @@ void ObjectNotifier::run() const auto& change = it->second; - auto column_modifications = change.get_columns_modified(m_obj_key); - if (!column_modifications) + auto path_modifications = change.get_paths_modified(m_obj_key); + if (!path_modifications) return; // Finally we add all changes to `m_change` which is later used to notify about the changed columns. m_change.modifications.add(0); - for (auto col : *column_modifications) { - m_change.columns[col.value].add(0); + auto obj = m_table->get_object(m_obj_key); + for (const StablePath& stable_path : *path_modifications) { + m_change.columns[m_table->get_column_key(stable_path[0]).value].add(0); + if (stable_path.size() > 1) { + Path path; + obj.translate_path(stable_path, path); + m_change.modified_paths.emplace_back(std::move(path)); + } } } diff --git a/src/realm/object-store/impl/results_notifier.cpp b/src/realm/object-store/impl/results_notifier.cpp index b60029e58cd..8ebf8f53daa 100644 --- a/src/realm/object-store/impl/results_notifier.cpp +++ b/src/realm/object-store/impl/results_notifier.cpp @@ -375,9 +375,9 @@ void ListResultsNotifier::run() // Modifications to nested values in Mixed are recorded in replication as // StableIndex and we have to look up the actual index afterwards - if (m_change.paths.size()) { + if (m_change.stable_indexes.size()) { if (auto coll = dynamic_cast(m_list.get())) { - for (auto& p : m_change.paths) { + for (auto& p : m_change.stable_indexes) { if (auto ndx = coll->find_index(p); ndx != realm::not_found) m_change.modifications.add(ndx); } diff --git a/src/realm/object-store/impl/transact_log_handler.cpp b/src/realm/object-store/impl/transact_log_handler.cpp index 93377cfaa06..5ccda1bb933 100644 --- a/src/realm/object-store/impl/transact_log_handler.cpp +++ b/src/realm/object-store/impl/transact_log_handler.cpp @@ -110,10 +110,10 @@ void KVOAdapter::before(Transaction& sg) m_invalidated.push_back(observer.info); continue; } - auto column_modifications = table.get_columns_modified(key); - if (column_modifications) { - for (auto col : *column_modifications) { - observer.changes[col.value].kind = BindingContext::ColumnInfo::Kind::Set; + auto tbl = sg.get_table(observer.table_key); + if (auto path_modifications = table.get_paths_modified(key)) { + for (const StablePath& path : *path_modifications) { + observer.changes[tbl->get_column_key(path[0])].kind = BindingContext::ColumnInfo::Kind::Set; } } } @@ -123,7 +123,7 @@ void KVOAdapter::before(Transaction& sg) // We may have pre-emptively marked the column as modified if the // LinkList was selected but the actual changes made ended up being // a no-op - list.observer->changes.erase(list.col_key.value); + list.observer->changes.erase(list.col_key); continue; } // If the containing row was deleted then changes will be empty @@ -132,7 +132,7 @@ void KVOAdapter::before(Transaction& sg) continue; } // otherwise the column should have been marked as modified - auto it = list.observer->changes.find(list.col_key.value); + auto it = list.observer->changes.find(list.col_key); REALM_ASSERT(it != list.observer->changes.end()); auto& builder = list.builder; auto& changes = it->second; @@ -364,15 +364,17 @@ class TransactLogObserver : public TransactLogValidationMixin { return true; } - bool select_collection(ColKey col, ObjKey obj, const StablePath& path) + bool select_collection(ColKey, ObjKey obj, const StablePath& path) { - modify_object(col, obj); + if (m_active_table) { + m_active_table->modifications_add(obj, path); + } auto table = current_table(); m_active_collection = nullptr; for (auto& c : m_info.collections) { if (c.table_key == table && c.obj_key == obj && c.path.is_prefix_of(path)) { if (c.path.size() != path.size()) { - c.changes->paths.insert(path[c.path.size()]); + c.changes->stable_indexes.insert(path[c.path.size()]); } // If there are multiple exact matches for this collection we // use the first and then propagate the data to the others later @@ -463,8 +465,11 @@ class TransactLogObserver : public TransactLogValidationMixin { bool modify_object(ColKey col, ObjKey key) { - if (m_active_table) - m_active_table->modifications_add(key, col); + if (m_active_table) { + StablePath path; + path.push_back(StableIndex(col, 0)); + m_active_table->modifications_add(key, path); + } return true; } diff --git a/src/realm/object-store/object_changeset.cpp b/src/realm/object-store/object_changeset.cpp index 922a6a8ad28..6798240123d 100644 --- a/src/realm/object-store/object_changeset.cpp +++ b/src/realm/object-store/object_changeset.cpp @@ -25,11 +25,11 @@ void ObjectChangeSet::insertions_add(ObjKey obj) m_insertions.insert(obj); } -void ObjectChangeSet::modifications_add(ObjKey obj, ColKey col) +void ObjectChangeSet::modifications_add(ObjKey obj, const StablePath& path) { // don't report modifications on new objects if (m_insertions.find(obj) == m_insertions.end()) { - m_modifications[obj].insert(col); + m_modifications[obj].insert(path); } } @@ -82,9 +82,13 @@ bool ObjectChangeSet::modifications_contains(ObjKey obj, const std::vector& changed_columns_for_object = m_modifications.at(obj); + const std::set& changed_paths_for_object = m_modifications.at(obj); for (const auto& column_key_in_filter : filtered_column_keys) { - if (changed_columns_for_object.count(column_key_in_filter)) { + auto it = + std::find_if(changed_paths_for_object.begin(), changed_paths_for_object.end(), [&](const StablePath& p) { + return p[0].get_index().val == column_key_in_filter.get_index().val; + }); + if (it != changed_paths_for_object.end()) { return true; } } @@ -92,7 +96,7 @@ bool ObjectChangeSet::modifications_contains(ObjKey obj, const std::vector; using ColumnSet = std::unordered_set; - using ObjectMapToColumnSet = std::unordered_map; + using PathSet = std::set; + using ObjectMapToColumnSet = std::unordered_map; ObjectChangeSet() = default; ObjectChangeSet(ObjectChangeSet const&) = default; @@ -47,7 +48,7 @@ class ObjectChangeSet { ObjectChangeSet& operator=(ObjectChangeSet&&) = default; void insertions_add(ObjKey obj); - void modifications_add(ObjKey obj, ColKey col); + void modifications_add(ObjKey obj, const StablePath& path); void deletions_add(ObjKey obj); bool insertions_remove(ObjKey obj); @@ -69,7 +70,7 @@ class ObjectChangeSet { bool deletions_contains(ObjKey obj) const; // if the specified object has not been modified, returns nullptr // if the object has been modified, returns a pointer to the ObjectSet - const ColumnSet* get_columns_modified(ObjKey obj) const; + const PathSet* get_paths_modified(ObjKey obj) const; bool insertions_empty() const noexcept { diff --git a/test/object-store/c_api/c_api.cpp b/test/object-store/c_api/c_api.cpp index e04d5f3ff0e..60555cefcfb 100644 --- a/test/object-store/c_api/c_api.cpp +++ b/test/object-store/c_api/c_api.cpp @@ -4073,8 +4073,8 @@ TEST_CASE("C API - properties", "[c_api]") { realm_property_key_t modified_keys[2]; size_t n = realm_object_changes_get_modified_properties(state.changes.get(), modified_keys, 2); CHECK(n == 2); - CHECK(modified_keys[0] == foo_int_key); - CHECK(modified_keys[1] == foo_str_key); + CHECK(modified_keys[0] == foo_str_key); + CHECK(modified_keys[1] == foo_int_key); n = realm_object_changes_get_modified_properties(state.changes.get(), nullptr, 2); CHECK(n == 2); @@ -5264,6 +5264,7 @@ TEST_CASE("C API: nested collections", "[c_api]") { size_t modifications; bool was_deleted; realm_dictionary_t* dict; + std::vector paths; } user_data; auto parent_dict = cptr_checked(realm_set_dictionary(obj1.get(), foo_any_col_key)); @@ -5293,20 +5294,28 @@ TEST_CASE("C API: nested collections", "[c_api]") { CHECK(!realm_dictionary_is_valid(user_data->dict)); } }; - auto require_change = [&]() { - auto token = cptr_checked(realm_dictionary_add_notification_callback(dict2.get(), &user_data, nullptr, - nullptr, on_dictionary_change)); - checked(realm_refresh(realm, nullptr)); - return token; + auto on_obj_change = [](void* userdata, const realm_object_changes_t* changes) { + auto state = static_cast(userdata); + realm_string_t paths[10]; + auto num = realm_object_changes_get_modified_paths(changes, paths, 10); + for (size_t i = 0; i < num; i++) { + state->paths.emplace_back(paths[0].data, paths[0].size); + } }; - auto token = require_change(); + auto token_dict = cptr_checked(realm_dictionary_add_notification_callback(dict2.get(), &user_data, nullptr, + nullptr, on_dictionary_change)); + auto token = + cptr(realm_object_add_notification_callback(obj1.get(), &user_data, nullptr, nullptr, on_obj_change)); + checked(realm_refresh(realm, nullptr)); write([&] { checked(realm_dictionary_insert(dict2.get(), rlm_str_val("Nested-Godbye"), rlm_str_val("Nested-CruelWorld"), nullptr, nullptr)); }); CHECK(user_data.insertions == 1); + REQUIRE(user_data.paths.size() == 1); + CHECK(user_data.paths[0] == "any.Hi"); write([&] { realm_dictionary_insert(dict.get(), rlm_str_val("Hi"), rlm_str_val("Foo"), nullptr, nullptr); diff --git a/test/object-store/dictionary.cpp b/test/object-store/dictionary.cpp index 0ae18396843..21e2f216200 100644 --- a/test/object-store/dictionary.cpp +++ b/test/object-store/dictionary.cpp @@ -83,6 +83,13 @@ TEST_CASE("nested dictionary in mixed", "[dictionary]") { change_dictionary = c; }); + Object object(r, any_obj); + CollectionChangeSet change_obj; + auto token_obj = object.add_notification_callback([&](CollectionChangeSet c) { + change_obj = c; + }); + + auto write = [&](auto&& f) { r->begin_transaction(); f(); @@ -100,11 +107,11 @@ TEST_CASE("nested dictionary in mixed", "[dictionary]") { auto list = dict_mixed.get_list("list"); SECTION("notification on nested list") { - CollectionChangeSet change; + CollectionChangeSet change_list; auto require_change = [&] { auto token = list.add_notification_callback([&](CollectionChangeSet c) { - change = c; + change_list = c; }); advance_and_notify(*r); return token; @@ -116,7 +123,12 @@ TEST_CASE("nested dictionary in mixed", "[dictionary]") { list.add(Mixed{5}); list.add(Mixed{6}); }); - REQUIRE_INDICES(change.insertions, 0, 1); + Path modified_path; + modified_path.emplace_back("any"); + modified_path.emplace_back("list"); + REQUIRE(change_obj.modified_paths.size() == 1); + CHECK(change_obj.modified_paths[0] == modified_path); + REQUIRE_INDICES(change_list.insertions, 0, 1); REQUIRE_INDICES(change_dictionary.modifications, 1); } @@ -143,13 +155,13 @@ TEST_CASE("nested dictionary in mixed", "[dictionary]") { list.add(Mixed{5}); list.add(Mixed{6}); }); - REQUIRE_INDICES(change.insertions, 0, 1); + REQUIRE_INDICES(change_list.insertions, 0, 1); write([&] { dict_mixed.insert("list", 42); }); - REQUIRE_INDICES(change.deletions, 0, 1); + REQUIRE_INDICES(change_list.deletions, 0, 1); REQUIRE_INDICES(change_dictionary.modifications, 1); - REQUIRE(change.collection_root_was_deleted); + REQUIRE(change_list.collection_root_was_deleted); } SECTION("erase containing dictionary") { auto token = require_change(); @@ -157,12 +169,12 @@ TEST_CASE("nested dictionary in mixed", "[dictionary]") { list.add(Mixed{5}); list.add(Mixed{6}); }); - REQUIRE_INDICES(change.insertions, 0, 1); + REQUIRE_INDICES(change_list.insertions, 0, 1); write([&] { any_obj.set(col_any, Mixed(42)); }); - REQUIRE_INDICES(change.deletions, 0, 1); - REQUIRE(change.collection_root_was_deleted); + REQUIRE_INDICES(change_list.deletions, 0, 1); + REQUIRE(change_list.collection_root_was_deleted); } SECTION("erase containing object") { auto token = require_change(); @@ -170,12 +182,12 @@ TEST_CASE("nested dictionary in mixed", "[dictionary]") { list.add(Mixed{5}); list.add(Mixed{6}); }); - REQUIRE_INDICES(change.insertions, 0, 1); + REQUIRE_INDICES(change_list.insertions, 0, 1); write([&] { any_obj.remove(); }); - REQUIRE_INDICES(change.deletions, 0, 1); - REQUIRE(change.collection_root_was_deleted); + REQUIRE_INDICES(change_list.deletions, 0, 1); + REQUIRE(change_list.collection_root_was_deleted); } } SECTION("dictionary as Results") { diff --git a/test/object-store/realm.cpp b/test/object-store/realm.cpp index 93f10916b31..3eb3351b595 100644 --- a/test/object-store/realm.cpp +++ b/test/object-store/realm.cpp @@ -96,7 +96,7 @@ class Observer : public BindingContext { IndexSet array_change(size_t index, ColKey col_key) const noexcept { auto& changes = m_result[index].changes; - auto col = changes.find(col_key.value); + auto col = changes.find(col_key); return col == changes.end() ? IndexSet{} : col->second.indices; } diff --git a/test/object-store/transaction_log_parsing.cpp b/test/object-store/transaction_log_parsing.cpp index 316edc50c60..a9667188219 100644 --- a/test/object-store/transaction_log_parsing.cpp +++ b/test/object-store/transaction_log_parsing.cpp @@ -195,7 +195,7 @@ class KVOContext : public BindingContext { }); if (it == m_result.end()) return false; - auto col = it->changes.find(col_key.value); + auto col = it->changes.find(col_key); return col != it->changes.end() && col->second.kind != BindingContext::ColumnInfo::Kind::None; } @@ -207,7 +207,7 @@ class KVOContext : public BindingContext { ArrayChange array_change(size_t index, ColKey col_key) const noexcept { auto& changes = m_result[index].changes; - auto col = changes.find(col_key.value); + auto col = changes.find(col_key); return col == changes.end() ? ArrayChange{ColumnInfo::Kind::None, {}} : ArrayChange{col->second.kind, col->second.indices}; }