Support id field for reference.

This commit is contained in:
Harpreet Sangar 2023-08-18 12:07:54 +05:30
parent eee222a8e2
commit c579e2dd70
2 changed files with 45 additions and 7 deletions

View File

@ -126,18 +126,31 @@ Option<doc_seq_id_t> Collection::to_doc(const std::string & json_str, nlohmann::
auto reference_collection_name = reference_pair.collection;
auto reference_field_name = reference_pair.field;
auto& cm = CollectionManager::get_instance();
auto collection = cm.get_collection(reference_collection_name);
if (collection == nullptr) {
auto ref_collection = cm.get_collection(reference_collection_name);
if (ref_collection == nullptr) {
return Option<doc_seq_id_t>(400, "Referenced collection `" + reference_collection_name
+ "` not found.");
}
if (collection->get_schema().count(reference_field_name) == 0) {
if (reference_field_name == "id") {
auto value = document[field_name].get<std::string>();
auto ref_doc_id_op = ref_collection->doc_id_to_seq_id(value);
if (!ref_doc_id_op.ok()) {
return Option<doc_seq_id_t>(400, "Referenced document having `id: " + value +
"` not found in the collection `" +
reference_collection_name + "`." );
}
document[field_name + REFERENCE_HELPER_FIELD_SUFFIX] = ref_doc_id_op.get();
continue;
}
if (ref_collection->get_schema().count(reference_field_name) == 0) {
return Option<doc_seq_id_t>(400, "Referenced field `" + reference_field_name +
"` not found in the collection `" + reference_collection_name + "`.");
}
if (!collection->get_schema().at(reference_field_name).index) {
if (!ref_collection->get_schema().at(reference_field_name).index) {
return Option<doc_seq_id_t>(400, "Referenced field `" + reference_field_name +
"` in the collection `" + reference_collection_name + "` must be indexed.");
}
@ -145,7 +158,7 @@ Option<doc_seq_id_t> Collection::to_doc(const std::string & json_str, nlohmann::
// Get the doc id of the referenced document.
auto value = document[field_name].get<std::string>();
filter_result_t filter_result;
collection->get_filter_ids(reference_field_name + ":=" + value, filter_result);
ref_collection->get_filter_ids(reference_field_name + ":=" + value, filter_result);
if (filter_result.count != 1) {
auto match = " `" + reference_field_name + ": " + value + "` ";

View File

@ -162,7 +162,7 @@ TEST_F(CollectionJoinTest, IndexDocumentHavingReferenceField) {
{"name": "customer_id", "type": "string"},
{"name": "customer_name", "type": "string"},
{"name": "product_price", "type": "float"},
{"name": "reference_id", "type": "string", "reference": "Products.id"}
{"name": "reference_id", "type": "string", "reference": "Products.foo"}
]
})"_json;
collection_create_op = collectionManager.create_collection(customers_schema_json);
@ -183,7 +183,7 @@ TEST_F(CollectionJoinTest, IndexDocumentHavingReferenceField) {
add_doc_op = customer_collection->add(customer_json.dump());
ASSERT_FALSE(add_doc_op.ok());
ASSERT_EQ("Referenced field `id` not found in the collection `Products`.", add_doc_op.error());
ASSERT_EQ("Referenced field `foo` not found in the collection `Products`.", add_doc_op.error());
collectionManager.drop_collection("Customers");
customers_schema_json =
@ -294,8 +294,33 @@ TEST_F(CollectionJoinTest, IndexDocumentHavingReferenceField) {
ASSERT_EQ(document["product_id"], "product_a");
ASSERT_EQ(document["product_name"], "shampoo");
auto id_ref_schema_json =
R"({
"name": "id_ref",
"fields": [
{"name": "reference", "type": "string", "reference": "Products.id"}
]
})"_json;
collection_create_op = collectionManager.create_collection(id_ref_schema_json);
ASSERT_TRUE(collection_create_op.ok());
auto id_ref_collection = collection_create_op.get();
auto id_ref_json = R"({
"reference": "foo"
})"_json;
add_doc_op = id_ref_collection->add(id_ref_json.dump());
ASSERT_FALSE(add_doc_op.ok());
ASSERT_EQ("Referenced document having `id: foo` not found in the collection `Products`.", add_doc_op.error());
id_ref_json = R"({
"reference": "1"
})"_json;
add_doc_op = id_ref_collection->add(id_ref_json.dump());
ASSERT_TRUE(add_doc_op.ok());
collectionManager.drop_collection("Customers");
collectionManager.drop_collection("Products");
collectionManager.drop_collection("id_ref");
}
TEST_F(CollectionJoinTest, FilterByReference_SingleMatch) {