Skip to content

Commit

Permalink
update set_collection for list and have an explicit function for each…
Browse files Browse the repository at this point in the history
… collection
  • Loading branch information
nicola-cab committed Aug 16, 2023
1 parent 23dcc34 commit fefd3ce
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 19 deletions.
12 changes: 8 additions & 4 deletions src/realm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1642,7 +1642,9 @@ RLM_API realm_object_t* realm_set_embedded(realm_object_t*, realm_property_key_t
* Create a collection in a given Mixed property.
*
*/
RLM_API bool realm_set_collection(realm_object_t*, realm_property_key_t, realm_collection_type_e);
RLM_API bool realm_set_list(realm_object_t*, realm_property_key_t);
RLM_API bool realm_set_set(realm_object_t*, realm_property_key_t);
RLM_API bool realm_set_dictionary(realm_object_t*, realm_property_key_t);

/** Return the object linked by the given property
*
Expand Down Expand Up @@ -1797,15 +1799,17 @@ RLM_API realm_set_t* realm_list_insert_set(realm_list_t* list, size_t index);
RLM_API realm_dictionary_t* realm_list_insert_dictionary(realm_list_t* list, size_t index);

/**
* Set a collection inside a list (only available for mixed properities).
* Set a collection inside a list (only available for mixed types).
* If the list already contains a collection of the requested type, the
* operation is idempotent.
*
* @param list valid ptr to a list where a nested collection needs to be set
* @param index position in the list where to set the collection
* @return RLM_API
* @return a valid ptr representing the collection just set
*/
RLM_API bool realm_list_set_collection(realm_list_t* list, size_t index, realm_collection_type_e);
RLM_API realm_list_t* realm_list_set_list(realm_list_t* list, size_t index);
RLM_API realm_set_t* realm_list_set_set(realm_list_t* list, size_t index);
RLM_API realm_dictionary_t* realm_list_set_dictionary(realm_list_t* list, size_t index);

/**
* Returns a nested list if such collection exists, NULL otherwise.
Expand Down
23 changes: 20 additions & 3 deletions src/realm/object-store/c_api/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,28 @@ RLM_API realm_dictionary_t* realm_list_insert_dictionary(realm_list_t* list, siz
});
}

RLM_API bool realm_list_set_collection(realm_list_t* list, size_t index, realm_collection_type_e type)
RLM_API realm_list_t* realm_list_set_list(realm_list_t* list, size_t index)
{
return wrap_err([&]() {
list->set_collection(index, *from_capi(type));
return true;
list->set_collection(index, CollectionType::List);
return new realm_list_t{list->get_list(index)};
});
}

RLM_API realm_set_t* realm_list_set_set(realm_list_t* list, size_t index)
{
return wrap_err([&]() {
list->set_collection(index, CollectionType::Set);
return new realm_set_t{list->get_set(index)};
});
}

RLM_API realm_dictionary_t* realm_list_set_dictionary(realm_list_t* list, size_t index)
{
return wrap_err([&]() {
list->set_collection(index, CollectionType::Dictionary);
return new realm_dictionary_t{list->get_dictionary(index)};
;
});
}

Expand Down
22 changes: 20 additions & 2 deletions src/realm/object-store/c_api/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,11 +337,29 @@ RLM_API realm_object_t* realm_set_embedded(realm_object_t* obj, realm_property_k
});
}

RLM_API bool realm_set_collection(realm_object_t* obj, realm_property_key_t col, realm_collection_type_e type)
RLM_API bool realm_set_list(realm_object_t* obj, realm_property_key_t col)
{
return wrap_err([&]() {
obj->verify_attached();
obj->get_obj().set_collection(ColKey(col), *from_capi(type));
obj->get_obj().set_collection(ColKey(col), CollectionType::List);
return true;
});
}

RLM_API bool realm_set_set(realm_object_t* obj, realm_property_key_t col)
{
return wrap_err([&]() {
obj->verify_attached();
obj->get_obj().set_collection(ColKey(col), CollectionType::Set);
return true;
});
}

RLM_API bool realm_set_dictionary(realm_object_t* obj, realm_property_key_t col)
{
return wrap_err([&]() {
obj->verify_attached();
obj->get_obj().set_collection(ColKey(col), CollectionType::Dictionary);
return true;
});
}
Expand Down
20 changes: 10 additions & 10 deletions test/object-store/c_api/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5071,7 +5071,7 @@ TEST_CASE("C API: nested collections", "[c_api]") {
realm_dictionary_t* dict;
} user_data;

REQUIRE(realm_set_collection(obj1.get(), foo_any_col_key, RLM_COLLECTION_TYPE_DICTIONARY));
REQUIRE(realm_set_dictionary(obj1.get(), foo_any_col_key));
realm_value_t value;
realm_get_value(obj1.get(), foo_any_col_key, &value);
REQUIRE(value.type == RLM_TYPE_DICTIONARY);
Expand Down Expand Up @@ -5140,7 +5140,7 @@ TEST_CASE("C API: nested collections", "[c_api]") {
realm_list_t* list;
} user_data;

REQUIRE(realm_set_collection(obj1.get(), foo_any_col_key, RLM_COLLECTION_TYPE_LIST));
REQUIRE(realm_set_list(obj1.get(), foo_any_col_key));
realm_value_t value;
realm_get_value(obj1.get(), foo_any_col_key, &value);
REQUIRE(value.type == RLM_TYPE_LIST);
Expand Down Expand Up @@ -5200,7 +5200,7 @@ TEST_CASE("C API: nested collections", "[c_api]") {
}

SECTION("set list for collection in mixed, verify that previous reference is invalid") {
REQUIRE(realm_set_collection(obj1.get(), foo_any_col_key, RLM_COLLECTION_TYPE_LIST));
REQUIRE(realm_set_list(obj1.get(), foo_any_col_key));
realm_value_t value;
realm_get_value(obj1.get(), foo_any_col_key, &value);
REQUIRE(value.type == RLM_TYPE_LIST);
Expand All @@ -5210,44 +5210,44 @@ TEST_CASE("C API: nested collections", "[c_api]") {
checked(realm_list_size(list.get(), &size));
REQUIRE(size == 1);
realm_list_insert(n_list.get(), 0, rlm_str_val("Test1"));
realm_list_set_collection(list.get(), 0, RLM_COLLECTION_TYPE_DICTIONARY);
auto n_dict = cptr_checked(realm_list_set_dictionary(list.get(), 0));
// accessor has become invalid
REQUIRE(!realm_list_insert(n_list.get(), 1, rlm_str_val("Test2")));
CHECK_ERR(RLM_ERR_INVALIDATED_OBJECT);
// try to get a dictionary should work
auto n_dict = cptr_checked(realm_list_get_dictionary(list.get(), 0));
n_dict = cptr_checked(realm_list_get_dictionary(list.get(), 0));
bool inserted = false;
size_t ndx;
realm_value_t key = rlm_str_val("key");
realm_value_t val = rlm_str_val("value");
REQUIRE(realm_dictionary_insert(n_dict.get(), key, val, &ndx, &inserted));
REQUIRE(ndx == 0);
REQUIRE(inserted);
realm_list_set_collection(list.get(), 0, RLM_COLLECTION_TYPE_SET);
auto n_set = cptr_checked(realm_list_set_set(list.get(), 0));
// accessor invalid
REQUIRE(!realm_dictionary_insert(n_dict.get(), key, val, &ndx, &inserted));
CHECK_ERR(RLM_ERR_INVALIDATED_OBJECT);
auto n_set = cptr_checked(realm_list_get_set(list.get(), 0));
n_set = cptr_checked(realm_list_get_set(list.get(), 0));
REQUIRE(realm_set_insert(n_set.get(), val, &ndx, &inserted));
REQUIRE(ndx == 0);
REQUIRE(inserted);
realm_list_set_collection(list.get(), 0, RLM_COLLECTION_TYPE_LIST);
n_list = cptr_checked(realm_list_set_list(list.get(), 0));
// accessor invalid
REQUIRE(!realm_set_insert(n_set.get(), val, &ndx, &inserted));
CHECK_ERR(RLM_ERR_INVALIDATED_OBJECT);
// get a list should work
n_list = cptr_checked(realm_list_get_list(list.get(), 0));
REQUIRE(realm_list_insert(n_list.get(), 0, rlm_str_val("Test1")));
// reset the collection type to the same type (nop)
realm_list_set_collection(list.get(), 0, RLM_COLLECTION_TYPE_LIST);
n_list = cptr_checked(realm_list_set_list(list.get(), 0));
// accessor is still valid
REQUIRE(realm_list_insert(n_list.get(), 0, rlm_str_val("Test2")));
checked(realm_list_size(n_list.get(), &size));
REQUIRE(size == 2);
}

SECTION("set") {
REQUIRE(realm_set_collection(obj1.get(), foo_any_col_key, RLM_COLLECTION_TYPE_SET));
REQUIRE(realm_set_set(obj1.get(), foo_any_col_key));
realm_value_t value;
realm_get_value(obj1.get(), foo_any_col_key, &value);
REQUIRE(value.type == RLM_TYPE_SET);
Expand Down

0 comments on commit fefd3ce

Please sign in to comment.