8000 Make information on the deletion of a collection available in C API by jedelbo · Pull Request #6896 · realm/realm-core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Make information on the deletion of a collection available in C API #6896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* Support for upgrading from Realm files produced by RealmCore v5.23.9 or earlier is no longer supported.
* Remove `set_string_compare_method`, only one sort method is now supported which was previously called `STRING_COMPARE_CORE`.
* BinaryData and StringData are now strongly typed for comparisons and queries. This change is especially relevant when querying for a string constant on a Mixed property, as now only strings will be returned. If searching for BinaryData is desired, then that type must be specified by the constant. In RQL the new way to specify a binary constant is to use `mixed = bin('xyz')` or `mixed = binary('xyz')`. ([6407](https://github.com/realm/realm-core/issues/6407)).
* In the C API, `realm_collection_changes_get_num_changes` and `realm_dictionary_get_changes` have got an extra parameter to receive information on the deletion of the entire collection.

### Compatibility
* Fileformat: Generates files with format v24. Reads and automatically upgrade from fileformat v10. If you want to upgrade from an earlier file format version you will have to use RealmCore v13.x.y or earlier.
Expand Down
8 changes: 6 additions & 2 deletions src/realm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1939,10 +1939,12 @@ RLM_API size_t realm_object_changes_get_modified_properties(const realm_object_c
* @param out_num_modifications The number of modifications. May be NULL.
* @param out_num_moves The number of moved elements. May be NULL.
* @param out_collection_was_cleared a flag to signal if the collection has been cleared. May be NULL
* @param out_collection_was_deleted a flag to signal if the collection has been deleted. May be NULL
*/
RLM_API void realm_collection_changes_get_num_changes(const realm_collection_changes_t*, size_t* out_num_deletions,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to update the documentation as well. Can you add the argument above in the comment pls?

8000 size_t* out_num_insertions, size_t* out_num_modifications,
size_t* out_num_moves, bool* out_collection_was_cleared);
size_t* out_num_moves, bool* out_collection_was_cleared,
bool* out_collection_was_deleted);

/**
* Get the number of various types of changes in a collection notification,
Expand Down Expand Up @@ -2023,9 +2025,11 @@ RLM_API void realm_collection_changes_get_ranges(
* @param out_deletions_size number of deletions
* @param out_insertion_size number of insertions
* @param out_modification_size number of modifications
* @param out_was_deleted a flag to signal if the dictionary has been deleted.
*/
RLM_API void realm_dictionary_get_changes(const realm_dictionary_changes_t* changes, size_t* out_deletions_size,
size_t* out_insertion_size, size_t* out_modification_size);
size_t* out_insertion_size, size_t* out_modification_size,
bool* out_was_deleted);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to update the documentation as well. Can you add the argument above in the comment pls?


/**
* Returns the list of keys changed for the dictionary passed as argument.
Expand Down
8000
10 changes: 8 additions & 2 deletions src/realm/object-store/c_api/notifications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ RLM_API void realm_collection_changes_get_num_ranges(const realm_collection_chan
RLM_API void realm_collection_changes_get_num_changes(const realm_collection_changes_t* changes,
size_t* out_num_deletions, size_t* out_num_insertions,
size_t* out_num_modifications, size_t* out_num_moves,
bool* out_collection_was_cleared)
bool* out_collection_was_cleared,
bool* out_collection_was_deleted)
{
// FIXME: This has O(n) performance, which seems ridiculous.

Expand All @@ -216,6 +217,8 @@ RLM_API void realm_collection_changes_get_num_changes(const realm_collection_cha
*out_num_moves = changes->moves.size();
if (out_collection_was_cleared)
*out_collection_was_cleared = changes->collection_was_cleared;
if (out_collection_was_deleted)
*out_collection_was_deleted = changes->collection_root_was_deleted;
}

static inline void copy_index_ranges(const IndexSet& index_set, realm_index_range_t* out_ranges, size_t max)
Expand Down Expand Up @@ -259,14 +262,17 @@ RLM_API void realm_collection_changes_get_ranges(
}

RLM_API void realm_dictionary_get_changes(const realm_dictionary_changes_t* changes, size_t* out_deletions_size,
size_t* out_insertion_size, size_t* out_modification_size)
size_t* out_insertion_size, size_t* out_modification_size,
bool* out_was_deleted)
{
if (out_deletions_size)
*out_deletions_size = changes->deletions.size();
if (out_insertion_size)
*out_insertion_size = changes->insertions.size();
if (out_modification_size)
*out_modification_size = changes->modifications.size();
if (out_was_deleted)
*out_was_deleted = changes->collection_root_was_deleted;
}

RLM_API void realm_dictionary_get_changed_keys(const realm_dictionary_changes_t* changes,
Expand Down
104 changes: 98 additions & 6 deletions test/object-store/c_api/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3562,7 +3562,8 @@ TEST_CASE("C API", "[c_api]") {
size_t num_deletions, num_insertions, num_modifications;
bool collection_cleared = false;
realm_collection_changes_get_num_changes(state.changes.get(), &num_deletions, &num_insertions,
&num_modifications, &num_moves, &collection_cleared);
&num_modifications, &num_moves, &collection_cleared,
nullptr);
CHECK(num_deletions == 1);
CHECK(num_insertions == 2);
CHECK(num_modifications == 1);
Expand Down Expand Up @@ -3609,7 +3610,8 @@ TEST_CASE("C API", "[c_api]") {
});

realm_collection_changes_get_num_changes(state.changes.get(), &num_deletions, &num_insertions,
&num_modifications, &num_moves, &collection_cleared);
&num_modifications, &num_moves, &collection_cleared,
nullptr);
CHECK(collection_cleared == true);
}
}
Expand Down Expand Up @@ -4037,7 +4039,8 @@ TEST_CASE("C API", "[c_api]") {
size_t num_deletions, num_insertions, num_modifications;
bool collection_cleared = false;
realm_collection_changes_get_num_changes(state.changes.get(), &num_deletions, &num_insertions,
&num_modifications, &num_moves, &collection_cleared);
&num_modifications, &num_moves, &collection_cleared,
nullptr);
CHECK(collection_cleared == true);
}
}
Expand Down Expand Up @@ -4542,7 +4545,7 @@ TEST_CASE("C API", "[c_api]") {

size_t num_deletions, num_insertions, num_modifications;
realm_dictionary_get_changes(state.dictionary_changes.get(), &num_deletions, &num_insertions,
&num_modifications);
&num_modifications, nullptr);
CHECK(num_deletions == 1);
CHECK(num_insertions == 2);
CHECK(num_modifications == 0);
Expand Down Expand Up @@ -5052,7 +5055,22 @@ TEST_CASE("C API: nested collections", "[c_api]") {
realm_value_t pk = rlm_int_val(42);
obj1 = cptr_checked(realm_object_create_with_primary_key(realm, class_foo.key, pk));

auto write = [&](auto&& f) {
checked(realm_begin_write(realm));
f();
checked(realm_commit(realm));
checked(realm_refresh(realm, nullptr));
};

SECTION("dictionary") {
struct UserData {
size_t deletions;
size_t insertions;
size_t modifications;
bool was_deleted;
realm_dictionary_t* dict;
} user_data;

REQUIRE(realm_set_collection(obj1.get(), foo_any_col_key, RLM_COLLECTION_TYPE_DICTIONARY));
realm_value_t value;
realm_get_value(obj1.get(), foo_any_col_key, &value);
Expand All @@ -5066,8 +5084,41 @@ TEST_CASE("C API: nested collections", "[c_api]") {
realm_list_insert(list.get(), 0, rlm_int_val(42));
// dict -> dict
auto dict2 = cptr_checked(realm_dictionary_insert_dictionary(dict.get(), rlm_str_val("Hi")));
user_data.dict = dict2.get();
checked(realm_dictionary_insert(dict2.get(), rlm_str_val("Nested-Hello"), rlm_str_val("Nested-World"),
nullptr, nullptr));
checked(realm_commit(realm));

auto on_dictionary_change = [](void* data, const realm_dictionary_changes_t* changes) {
auto* user_data = static_cast<UserData*>(data);
realm_dictionary_get_changes(changes, &user_data->deletions, &user_data->insertions,
&user_data->modifications, &user_data->was_deleted);
if (user_data->was_deleted) {
CHECK(!realm_dictionary_is_valid(user_data->dict));
}
};
auto require_change = [& AE96 amp;]() {
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 token = require_change();

write([&] {
checked(realm_dictionary_insert(dict2.get(), rlm_str_val("Nested-Godbye"),
rlm_str_val("Nested-CruelWorld"), nullptr, nullptr));
});
CHECK(user_data.insertions == 1);

write([&] {
realm_dictionary_insert(dict.get(), rlm_str_val("Hi"), rlm_str_val("Foo"), nullptr, nullptr);
});
CHECK(user_data.deletions == 2);
CHECK(user_data.was_deleted);

checked(realm_begin_write(realm));
// dict -> set
auto set = cptr_checked(realm_dictionary_insert_set(dict.get(), rlm_str_val("Leaf-Set")));
bool inserted;
Expand All @@ -5081,6 +5132,14 @@ TEST_CASE("C API: nested collections", "[c_api]") {
}

SECTION("list") {
struct UserData {
size_t deletions;
size_t insertions;
size_t modifications;
bool was_deleted;
realm_list_t* list;
} user_data;

REQUIRE(realm_set_collection(obj1.get(), foo_any_col_key, RLM_COLLECTION_TYPE_LIST));
realm_value_t value;
realm_get_value(obj1.get(), foo_any_col_key, &value);
Expand All @@ -5093,9 +5152,42 @@ TEST_CASE("C API: nested collections", "[c_api]") {
checked(realm_dictionary_insert(dict.get(), rlm_str_val("Hello"), rlm_str_val("world"), nullptr, nullptr));
// list -> list
auto list2 = cptr_checked(realm_list_insert_list(list.get(), 2));
realm_list_insert(list2.get(), 0, rlm_str_val("Nested-Hello"));
realm_list_insert(list2.get(), 1, rlm_str_val("Nested-World"));
user_data.list = list2.get();

checked(realm_commit(realm));

auto on_list_change = [](void* data, const realm_collection_changes_t* changes) {
auto* user_data = static_cast<UserData*>(data);
realm_collection_changes_get_num_changes(changes, &user_data->deletions, &user_data->insertions,
&user_data->modifications, nullptr, nullptr,
&user_data->was_deleted);
if (user_data->was_deleted) {
CHECK(!realm_list_is_valid(user_data->list));
}
};
auto require_change = [&]() {
auto token = cptr_checked(
realm_list_add_notification_callback(list2.get(), &user_data, nullptr, nullptr, on_list_change));
checked(realm_refresh(realm, nullptr));
return token;
};

auto token = require_change();

write([&] {
realm_list_insert(list2.get(), 0, rlm_str_val("Nested-Hello"));
realm_list_insert(list2.get(), 1, rlm_str_val("Nested-World"));
});
CHECK(user_data.insertions == 2);

write([&] {
realm_list_set(list.get(), 2, rlm_str_val("Foo"));
});
CHECK(user_data.deletions == 2);
CHECK(user_data.was_deleted);

// list -> set
checked(realm_begin_write(realm));
auto set = cptr_checked(realm_list_insert_set(list.get(), 3));
bool inserted;
size_t index;
Expand Down
0