Skip to content

Commit

Permalink
small changes to the c api for collections in mixed (#6881)
Browse files Browse the repository at this point in the history
* explicit insertion for collections in mixed and return the collection just inserted
  • Loading branch information
nicola-cab committed Aug 15, 2023
1 parent e5796df commit cc3c496
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 27 deletions.
22 changes: 16 additions & 6 deletions src/realm.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ typedef bool (*realm_on_object_store_error_callback_t)(realm_userdata_t userdata

/* Accessor types */
typedef struct realm_object realm_object_t;

typedef struct realm_list realm_list_t;
typedef struct realm_set realm_set_t;
typedef struct realm_dictionary realm_dictionary_t;
Expand Down Expand Up @@ -1785,13 +1786,15 @@ RLM_API bool realm_list_set(realm_list_t*, size_t index, realm_value_t value);
RLM_API bool realm_list_insert(realm_list_t*, size_t index, realm_value_t value);

/**
* Insert a collection inside a list (only available for mixed properities)
* Insert a collection inside a list (only available for mixed types)
*
* @param list valid ptr to a list where a nested collection needs to be added
* @param list valid ptr to a list of mixed
* @param index position in the list where to add the collection
* @return RLM_API
* @return pointer to a valid collection that has been just inserted at the index passed as argument
*/
RLM_API bool realm_list_insert_collection(realm_list_t* list, size_t index, realm_collection_type_e);
RLM_API realm_list_t* realm_list_insert_list(realm_list_t* list, size_t index);
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).
Expand Down Expand Up @@ -2309,9 +2312,16 @@ RLM_API bool realm_dictionary_insert(realm_dictionary_t*, realm_value_t key, rea
RLM_API realm_object_t* realm_dictionary_insert_embedded(realm_dictionary_t*, realm_value_t key);

/**
* Insert a nested collection
* Insert a collection inside a dictionary (only available for mixed types)
*
* @param dictionary valid ptr to a dictionary of mixed
* @param key the mixed representing a key for a dictionary (only string)
* @return pointer to a valid collection that has been just inserted at the key passed as argument
*/
RLM_API bool realm_dictionary_insert_collection(realm_dictionary_t*, realm_value_t key, realm_collection_type_e);
RLM_API realm_list_t* realm_dictionary_insert_list(realm_dictionary_t* dictionary, realm_value_t key);
RLM_API realm_set_t* realm_dictionary_insert_set(realm_dictionary_t*, realm_value_t);
RLM_API realm_dictionary_t* realm_dictionary_insert_dictionary(realm_dictionary_t*, realm_value_t);


/**
* Fetch a list from a dictionary.
Expand Down
33 changes: 29 additions & 4 deletions src/realm/object-store/c_api/dictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,42 @@ RLM_API realm_object_t* realm_dictionary_insert_embedded(realm_dictionary_t* dic
});
}

RLM_API bool realm_dictionary_insert_collection(realm_dictionary_t* dict, realm_value_t key,
realm_collection_type_e type)
RLM_API realm_list_t* realm_dictionary_insert_list(realm_dictionary_t* dictionary, realm_value_t key)
{
return wrap_err([&]() {
if (key.type != RLM_TYPE_STRING) {
throw InvalidArgument{"Only string keys are supported in dictionaries"};
}

StringData k{key.string.data, key.string.size};
dict->insert_collection(k, *from_capi(type));
return true;
dictionary->insert_collection(k, CollectionType::List);
return new realm_list_t{dictionary->get_list(k)};
});
}

RLM_API realm_set_t* realm_dictionary_insert_set(realm_dictionary_t* dictionary, realm_value_t key)
{
return wrap_err([&]() {
if (key.type != RLM_TYPE_STRING) {
throw InvalidArgument{"Only string keys are supported in dictionaries"};
}

StringData k{key.string.data, key.string.size};
dictionary->insert_collection(k, CollectionType::Set);
return new realm_set_t{dictionary->get_set(k)};
});
}

RLM_API realm_dictionary_t* realm_dictionary_insert_dictionary(realm_dictionary_t* dictionary, realm_value_t key)
{
return wrap_err([&]() {
if (key.type != RLM_TYPE_STRING) {
throw InvalidArgument{"Only string keys are supported in dictionaries"};
}

StringData k{key.string.data, key.string.size};
dictionary->insert_collection(k, CollectionType::Dictionary);
return new realm_dictionary_t{dictionary->get_dictionary(k)};
});
}

Expand Down
22 changes: 19 additions & 3 deletions src/realm/object-store/c_api/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,27 @@ RLM_API bool realm_list_insert(realm_list_t* list, size_t index, realm_value_t v
});
}

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

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

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

Expand Down
21 changes: 7 additions & 14 deletions test/object-store/c_api/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5060,19 +5060,16 @@ TEST_CASE("C API: nested collections", "[c_api]") {
auto dict = cptr_checked(realm_get_dictionary(obj1.get(), foo_any_col_key));
checked(realm_dictionary_insert(dict.get(), rlm_str_val("Hello"), rlm_str_val("world"), nullptr, nullptr));
// dict -> list
realm_dictionary_insert_collection(dict.get(), rlm_str_val("Godbye"), RLM_COLLECTION_TYPE_LIST);
auto list = cptr_checked(realm_dictionary_get_list(dict.get(), rlm_str_val("Godbye")));
auto list = cptr_checked(realm_dictionary_insert_list(dict.get(), rlm_str_val("Goodbye")));
realm_list_insert(list.get(), 0, rlm_str_val("Hello"));
realm_list_insert(list.get(), 0, rlm_str_val("42"));
realm_list_insert(list.get(), 0, rlm_int_val(42));
// dict -> dict
realm_dictionary_insert_collection(dict.get(), rlm_str_val("Hi"), RLM_COLLECTION_TYPE_DICTIONARY);
auto dict2 = cptr_checked(realm_dictionary_get_dictionary(dict.get(), rlm_str_val("Hi")));
auto dict2 = cptr_checked(realm_dictionary_insert_dictionary(dict.get(), rlm_str_val("Hi")));
checked(realm_dictionary_insert(dict2.get(), rlm_str_val("Nested-Hello"), rlm_str_val("Nested-World"),
nullptr, nullptr));
// dict -> set
realm_dictionary_insert_collection(dict.get(), rlm_str_val("Leaf-Set"), RLM_COLLECTION_TYPE_SET);
auto set = cptr_checked(realm_dictionary_get_set(dict.get(), rlm_str_val("Leaf-Set")));
auto set = cptr_checked(realm_dictionary_insert_set(dict.get(), rlm_str_val("Leaf-Set")));
bool inserted;
size_t index;
realm_set_insert(set.get(), rlm_str_val("Set-Hello"), &index, &inserted);
Expand All @@ -5092,17 +5089,14 @@ TEST_CASE("C API: nested collections", "[c_api]") {
realm_list_insert(list.get(), 0, rlm_str_val("Hello"));
realm_list_insert(list.get(), 1, rlm_str_val("World"));
// list -> dict
realm_list_insert_collection(list.get(), 1, RLM_COLLECTION_TYPE_DICTIONARY);
auto dict = cptr_checked(realm_list_get_dictionary(list.get(), 1));
auto dict = cptr_checked(realm_list_insert_dictionary(list.get(), 1));
checked(realm_dictionary_insert(dict.get(), rlm_str_val("Hello"), rlm_str_val("world"), nullptr, nullptr));
// list -> list
realm_list_insert_collection(list.get(), 2, RLM_COLLECTION_TYPE_LIST);
auto list2 = cptr_checked(realm_list_get_list(list.get(), 2));
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"));
// list -> set
realm_list_insert_collection(list.get(), 3, RLM_COLLECTION_TYPE_SET);
auto set = cptr_checked(realm_list_get_set(list.get(), 3));
auto set = cptr_checked(realm_list_insert_set(list.get(), 3));
bool inserted;
size_t index;
realm_set_insert(set.get(), rlm_str_val("Set-Hello"), &index, &inserted);
Expand All @@ -5119,8 +5113,7 @@ TEST_CASE("C API: nested collections", "[c_api]") {
realm_get_value(obj1.get(), foo_any_col_key, &value);
REQUIRE(value.type == RLM_TYPE_LIST);
auto list = cptr_checked(realm_get_list(obj1.get(), foo_any_col_key));
realm_list_insert_collection(list.get(), 0, RLM_COLLECTION_TYPE_LIST);
auto n_list = cptr_checked(realm_list_get_list(list.get(), 0));
auto n_list = cptr_checked(realm_list_insert_list(list.get(), 0));
size_t size;
checked(realm_list_size(list.get(), &size));
REQUIRE(size == 1);
Expand Down

0 comments on commit cc3c496

Please sign in to comment.