@@ -82,7 +82,7 @@ open class ProjectionBase {
8282 }
8383 ?.let { parseFilter(it as ObjectValue , type) }
8484 ?.let {
85- val filterCondition = handleQuery(normalizeName(FILTER , variable), " " , propertyContainer, it, type)
85+ val filterCondition = handleQuery(normalizeName(FILTER , variable), " " , propertyContainer, it, type)
8686 result.and (filterCondition)
8787 }
8888 ? : result
@@ -118,7 +118,7 @@ open class ProjectionBase {
118118 RelationOperator .NONE -> Predicates .none(cond)
119119 else -> null
120120 }?.let {
121- val targetNode = predicate.relNode.named(normalizeName(variablePrefix,predicate.relationshipInfo.typeName))
121+ val targetNode = predicate.relNode.named(normalizeName(variablePrefix, predicate.relationshipInfo.typeName))
122122 val parsedQuery2 = parseFilter(objectField.value as ObjectValue , type)
123123 val condition = handleQuery(targetNode.requiredSymbolicName.value, " " , targetNode, parsedQuery2, type)
124124 var where = it
@@ -338,12 +338,42 @@ open class ProjectionBase {
338338 return if (inverse) relInfo0.copy(direction = relInfo0.direction.invert(), startField = relInfo0.endField, endField = relInfo0.startField) else relInfo0
339339 }
340340
341- private fun projectRelationshipParent (node : PropertyContainer , variable : SymbolicName , field : Field , fieldDefinition : GraphQLFieldDefinition , parent : GraphQLFieldsContainer , env : DataFetchingEnvironment , variableSuffix : String? ): Expression {
341+ private fun projectRelationshipParent (propertyContainer : PropertyContainer , variable : SymbolicName , field : Field , fieldDefinition : GraphQLFieldDefinition , parent : GraphQLFieldsContainer , env : DataFetchingEnvironment , variableSuffix : String? ): Expression {
342342 val fieldObjectType = fieldDefinition.type.inner() as ? GraphQLFieldsContainer
343343 ? : throw IllegalArgumentException (" field ${fieldDefinition.name} of type ${parent.name} is not an object (fields container) and can not be handled as relationship" )
344- val projectionEntries = projectFields(anyNode(variable), name(variable.value + (variableSuffix?.capitalize()
345- ? : " " )), field, fieldObjectType, env, variableSuffix)
346- return node.project(projectionEntries)
344+ return when (propertyContainer) {
345+ is Node -> {
346+ val projectionEntries = projectFields(propertyContainer, name(variable.value + (variableSuffix?.capitalize()
347+ ? : " " )), field, fieldObjectType, env, variableSuffix)
348+ propertyContainer.project(projectionEntries)
349+ }
350+ is Relationship -> projectNodeFromRichRelationship(parent, fieldDefinition, variable, field, env)
351+ else -> throw IllegalArgumentException (" ${propertyContainer.javaClass.name} cannot be handled for field ${fieldDefinition.name} of type ${parent.name} " )
352+ }
353+ }
354+
355+ private fun projectNodeFromRichRelationship (
356+ parent : GraphQLFieldsContainer ,
357+ fieldDefinition : GraphQLFieldDefinition ,
358+ variable : SymbolicName ,
359+ field : Field ,
360+ env : DataFetchingEnvironment
361+ ): Expression {
362+ val relInfo = parent.relationship()
363+ ? : throw IllegalStateException (parent.name + " is not an relation type" )
364+
365+ val node = CypherDSL .node(fieldDefinition.type.name()).named(fieldDefinition.name)
366+ val (start, end, target) = when (fieldDefinition.name) {
367+ relInfo.startField -> Triple (node, anyNode(), node)
368+ relInfo.endField -> Triple (anyNode(), node, node)
369+ else -> throw IllegalArgumentException (" type ${parent.name} does not have a matching field with name ${fieldDefinition.name} " )
370+ }
371+ val rel = when (relInfo.direction) {
372+ RelationDirection .IN -> start.relationshipFrom(end).named(variable)
373+ RelationDirection .OUT -> start.relationshipTo(end).named(variable)
374+ RelationDirection .BOTH -> start.relationshipBetween(end).named(variable)
375+ }
376+ return head(CypherDSL .listBasedOn(rel).returning(target.project(projectFields(target, field, fieldDefinition.type as GraphQLFieldsContainer , env))))
347377 }
348378
349379 private fun projectRichAndRegularRelationship (variable : SymbolicName , field : Field , fieldDefinition : GraphQLFieldDefinition , parent : GraphQLFieldsContainer , env : DataFetchingEnvironment ): Expression {
@@ -366,7 +396,7 @@ open class ProjectionBase {
366396
367397 val (endNodePattern, variableSuffix) = when {
368398 isRelFromType -> {
369- val label = nodeType.getFieldDefinition(relInfo.endField!! )!! .type.innerName()
399+ val label = nodeType.getFieldDefinition(relInfo.endField)!! .type.innerName()
370400 node(label).named(" $childVariable${relInfo.endField.capitalize()} " ) to relInfo.endField
371401 }
372402 else -> node(nodeType.name).named(childVariableName) to null
0 commit comments