summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahoo-inc.com>2017-01-31 15:34:36 +0100
committerTor Brede Vekterli <vekterli@yahoo-inc.com>2017-02-02 15:18:36 +0100
commit140da1c8d693ee646fdd6bad4619a6e7b94b19ee (patch)
tree251f23b10978c9a9bf21dde16f5e2a8f968fb152 /document
parenta689ebd4f603357473d5587aecd3bb2d9f1b1270 (diff)
Support reference data types in type repo
Diffstat (limited to 'document')
-rw-r--r--document/src/tests/repo/documenttyperepo_test.cpp30
-rw-r--r--document/src/vespa/document/config/documenttypes.def4
-rw-r--r--document/src/vespa/document/repo/configbuilder.h6
-rw-r--r--document/src/vespa/document/repo/documenttyperepo.cpp12
4 files changed, 52 insertions, 0 deletions
diff --git a/document/src/tests/repo/documenttyperepo_test.cpp b/document/src/tests/repo/documenttyperepo_test.cpp
index b3ff4ce098e..38ae51b980f 100644
--- a/document/src/tests/repo/documenttyperepo_test.cpp
+++ b/document/src/tests/repo/documenttyperepo_test.cpp
@@ -500,4 +500,34 @@ TEST("Require that Array can have nested DocumentType") {
ASSERT_TRUE(type);
}
+TEST("Reference fields are resolved to correct reference type") {
+ const int doc_with_refs_id = 5678;
+ const int type_2_id = doc_type_id + 1;
+ const int ref1_id = 777;
+ const int ref2_id = 888;
+ DocumenttypesConfigBuilderHelper builder;
+ builder.document(doc_type_id, type_name,
+ Struct(header_name), Struct(body_name));
+ builder.document(type_2_id, type_name_2,
+ Struct(header_name_2), Struct(body_name_2));
+ builder.document(doc_with_refs_id, "doc_with_refs",
+ Struct("doc_with_refs.header")
+ .addField("ref1", ref1_id),
+ Struct("doc_with_refs.body")
+ .addField("ref2", ref2_id)
+ .addField("ref3", ref1_id))
+ .referenceType(ref1_id, doc_type_id)
+ .referenceType(ref2_id, type_2_id);
+
+ DocumentTypeRepo repo(builder.config());
+ const DocumentType *type = repo.getDocumentType(doc_with_refs_id);
+ ASSERT_TRUE(type != nullptr);
+ const auto* ref1_type(repo.getDataType(*type, ref1_id));
+ const auto* ref2_type(repo.getDataType(*type, ref2_id));
+
+ EXPECT_EQUAL(*ref1_type, type->getFieldsType().getField("ref1").getDataType());
+ EXPECT_EQUAL(*ref2_type, type->getFieldsType().getField("ref2").getDataType());
+ EXPECT_EQUAL(*ref1_type, type->getFieldsType().getField("ref3").getDataType());
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/document/src/vespa/document/config/documenttypes.def b/document/src/vespa/document/config/documenttypes.def
index 21cde02ad54..5b820213e3e 100644
--- a/document/src/vespa/document/config/documenttypes.def
+++ b/document/src/vespa/document/config/documenttypes.def
@@ -100,3 +100,7 @@ documenttype[].annotationtype[].inherits[].id int
## Field sets
documenttype[].fieldsets{}.fields[] string
+
+documenttype[].referencetype[].id int
+
+documenttype[].referencetype[].target_type_id int
diff --git a/document/src/vespa/document/repo/configbuilder.h b/document/src/vespa/document/repo/configbuilder.h
index a1c52b81024..11d5c99bee3 100644
--- a/document/src/vespa/document/repo/configbuilder.h
+++ b/document/src/vespa/document/repo/configbuilder.h
@@ -137,6 +137,12 @@ struct DocTypeRep {
addType(type, doc_type);
return annotationType(id, name, type.id);
}
+ DocTypeRep& referenceType(int32_t id, int32_t target_type_id) {
+ doc_type.referencetype.resize(doc_type.referencetype.size() + 1);
+ doc_type.referencetype.back().id = id;
+ doc_type.referencetype.back().targetTypeId = target_type_id;
+ return *this;
+ }
};
class DocumenttypesConfigBuilderHelper {
diff --git a/document/src/vespa/document/repo/documenttyperepo.cpp b/document/src/vespa/document/repo/documenttyperepo.cpp
index 49a3bd32fe9..338cbf3bcc4 100644
--- a/document/src/vespa/document/repo/documenttyperepo.cpp
+++ b/document/src/vespa/document/repo/documenttyperepo.cpp
@@ -10,6 +10,7 @@
#include <vespa/document/datatype/positiondatatype.h>
#include <vespa/document/datatype/urldatatype.h>
#include <vespa/document/datatype/weightedsetdatatype.h>
+#include <vespa/document/datatype/referencedatatype.h>
#include <vespa/vespalib/objects/identifiable.h>
#include <vespa/vespalib/stllike/hash_map.hpp>
#include <vespa/vespalib/util/closure.h>
@@ -444,6 +445,16 @@ void addFieldSet(const DocumenttypesConfig::Documenttype::FieldsetsMap & fsv, Do
}
}
+void addReferenceTypes(
+ const vector<DocumenttypesConfig::Documenttype::Referencetype> &ref_types,
+ Repo& data_type_repo,
+ const DocumentTypeMap& doc_type_map) {
+ for (const auto& ref_type : ref_types) {
+ const auto* target_doc_type = lookupRepo(ref_type.targetTypeId, doc_type_map).doc_type;
+ data_type_repo.addDataType(std::make_unique<ReferenceDataType>(*target_doc_type, ref_type.id));
+ }
+}
+
void configureDataTypeRepo(
const DocumenttypesConfig::Documenttype &doc_type,
DocumentTypeMap &type_map) {
@@ -452,6 +463,7 @@ void configureDataTypeRepo(
doc_type.inherits, type_map, data_types->annotations);
addAnnotationTypes(doc_type.annotationtype, data_types->annotations);
inheritDataTypes(doc_type.inherits, type_map, data_types->repo);
+ addReferenceTypes(doc_type.referencetype, data_types->repo, type_map);
addDataTypes(doc_type.datatype, data_types->repo, data_types->annotations);
setAnnotationDataTypes(doc_type.annotationtype, data_types->annotations,
data_types->repo);