From c579e2dd70736c693cf694438ed5981e1d83f051 Mon Sep 17 00:00:00 2001 From: Harpreet Sangar Date: Fri, 18 Aug 2023 12:07:54 +0530 Subject: [PATCH] Support `id` field for reference. --- src/collection.cpp | 23 ++++++++++++++++++----- test/collection_join_test.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/collection.cpp b/src/collection.cpp index 6d259e01..792ee826 100644 --- a/src/collection.cpp +++ b/src/collection.cpp @@ -126,18 +126,31 @@ Option 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(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(); + auto ref_doc_id_op = ref_collection->doc_id_to_seq_id(value); + if (!ref_doc_id_op.ok()) { + return Option(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(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(400, "Referenced field `" + reference_field_name + "` in the collection `" + reference_collection_name + "` must be indexed."); } @@ -145,7 +158,7 @@ Option Collection::to_doc(const std::string & json_str, nlohmann:: // Get the doc id of the referenced document. auto value = document[field_name].get(); 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 + "` "; diff --git a/test/collection_join_test.cpp b/test/collection_join_test.cpp index 7ae07ce7..40c607ca 100644 --- a/test/collection_join_test.cpp +++ b/test/collection_join_test.cpp @@ -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) {