Skip to content

Commit 0af7a84

Browse files
authored
Update API to latest version of neo4j-graphql (#329)
1 parent 6ac4a87 commit 0af7a84

File tree

487 files changed

+23507
-45554
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

487 files changed

+23507
-45554
lines changed

.run/AsciidocReformater.run.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<component name="ProjectRunConfigurationManager">
2-
<configuration default="false" name="org.neo4j.graphql.tools.AsciidocReformater" type="JetRunConfigurationType" nameIsGenerated="true">
2+
<configuration default="false" name="AsciidocReformater" type="JetRunConfigurationType" nameIsGenerated="true">
33
<option name="MAIN_CLASS_NAME" value="org.neo4j.graphql.tools.AsciidocReformater" />
44
<module name="neo4j-graphql-java" />
55
<shortenClasspath name="NONE" />
@@ -8,4 +8,4 @@
88
<option name="Make" enabled="true" />
99
</method>
1010
</configuration>
11-
</component>
11+
</component>

.run/JsTemplateDeleter.run.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="JsTemplateDeleter" type="JetRunConfigurationType" nameIsGenerated="true">
3+
<option name="MAIN_CLASS_NAME" value="org.neo4j.graphql.tools.JsTemplateDeleter" />
4+
<module name="neo4j-graphql-java" />
5+
<shortenClasspath name="NONE" />
6+
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
7+
<method v="2">
8+
<option name="Make" enabled="true" />
9+
</method>
10+
</configuration>
11+
</component>

.run/JsTestCaseSync.run.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<component name="ProjectRunConfigurationManager">
2-
<configuration default="false" name="org.neo4j.graphql.tools.JsTestCaseSync" type="JetRunConfigurationType" nameIsGenerated="true">
2+
<configuration default="false" name="JsTestCaseSync" type="JetRunConfigurationType" nameIsGenerated="true">
33
<option name="MAIN_CLASS_NAME" value="org.neo4j.graphql.tools.JsTestCaseSync" />
44
<module name="neo4j-graphql-java" />
55
<shortenClasspath name="NONE" />
@@ -8,4 +8,4 @@
88
<option name="Make" enabled="true" />
99
</method>
1010
</configuration>
11-
</component>
11+
</component>

core/src/main/kotlin/org/atteo/evo/inflector/EnglischInflector.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ object EnglischInflector : English() {
88
workaround_irregular("person", "people")
99
// TODO
1010
workaround_irregular("two", "twos")
11+
workaround_irregular("aircraft", "aircraft")
1112
}
1213

1314
private fun workaround_irregular(singular: String, plural: String) {

core/src/main/kotlin/org/neo4j/graphql/Constants.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ object Constants {
2525
const val CURSOR_FIELD = "cursor"
2626
const val NODE_FIELD = "node"
2727
const val RELATIONSHIP_FIELD = "relationship"
28-
const val TYPENAME_IN = "typename_IN"
28+
const val TYPENAME_IN = "typename"
2929

3030
const val RESOLVE_TYPE = TYPE_NAME
3131
const val RESOLVE_ID = "__id"
@@ -60,7 +60,6 @@ object Constants {
6060
RelationshipDirective.NAME,
6161
)
6262

63-
const val OPTIONS = "options"
6463
const val WHERE = "where"
6564

6665
object Types {
@@ -71,7 +70,6 @@ object Constants {
7170
val Boolean = TypeName("Boolean")
7271

7372
val PageInfo = TypeName("PageInfo")
74-
val QueryOptions = TypeName("QueryOptions")
7573
val SortDirection = TypeName("SortDirection")
7674
val PointDistance = TypeName("PointDistance")
7775
val CartesianPointDistance = TypeName("CartesianPointDistance")

core/src/main/kotlin/org/neo4j/graphql/QueryContext.kt

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,27 @@ data class QueryContext @JvmOverloads constructor(
1414
private var paramKeysPerValues = mutableMapOf<String, MutableMap<Any?, Parameter<*>>>()
1515

1616
fun resolve(string: String): String {
17-
return contextParams?.let { params ->
18-
CONTEXT_VARIABLE_PATTERN.replace(string) {
19-
val path = it.groups[1] ?: it.groups[2] ?: throw IllegalStateException("expected a group")
20-
val parts = path.value.split(".")
21-
var o: Any = params
22-
for (part in parts) {
23-
if (o is Map<*, *>) {
24-
o = o[part] ?: return@replace ""
17+
return CONTEXT_VARIABLE_PATTERN.replace(string) {
18+
val path = it.groups[1] ?: it.groups[2] ?: throw IllegalStateException("expected a group")
19+
val parts = path.value.split(".")
20+
var o: Any? = null
21+
for ((index, part) in parts.withIndex()) {
22+
if (index == 0) {
23+
if (part == "context") {
24+
o = contextParams
25+
continue
2526
} else {
26-
TODO("only maps are currently supported")
27+
TODO("query context does not provide a `$part`")
2728
}
2829
}
29-
return@replace o.toString()
30+
if (o is Map<*, *>) {
31+
o = o[part] ?: return@replace ""
32+
} else {
33+
TODO("only maps are currently supported")
34+
}
3035
}
31-
} ?: string
36+
return@replace o.toString()
37+
}
3238
}
3339

3440
fun getNextVariable(relationField: RelationField) = getNextVariable(
@@ -61,6 +67,8 @@ data class QueryContext @JvmOverloads constructor(
6167
const val KEY = "Neo4jGraphQLQueryContext"
6268

6369
private const val PATH_PATTERN = "([a-zA-Z_][a-zA-Z_0-9]*(?:.[a-zA-Z_][a-zA-Z_0-9]*)*)"
70+
71+
// matches ${path} or $path
6472
private val CONTEXT_VARIABLE_PATTERN = Regex("\\\$(?:\\{$PATH_PATTERN}|$PATH_PATTERN)")
6573
}
6674
}

core/src/main/kotlin/org/neo4j/graphql/domain/Node.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ class Node(
3737
}
3838

3939
fun asCypherNode(queryContext: QueryContext?, name: String? = null) =
40-
Cypher.node(mainLabel, additionalLabels(queryContext)).let {
40+
Cypher.node(mapLabelWithContext(mainLabel, queryContext), additionalLabels(queryContext)).let {
4141
when {
4242
name != null -> it.named(name)
4343
else -> it
4444
}
4545
}
4646

4747
fun asCypherNode(queryContext: QueryContext?, name: SymbolicName) =
48-
Cypher.node(mainLabel, additionalLabels(queryContext)).named(name)
48+
Cypher.node(mapLabelWithContext(mainLabel, queryContext), additionalLabels(queryContext)).named(name)
4949

5050
}
5151

core/src/main/kotlin/org/neo4j/graphql/domain/NodeFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object NodeFactory {
2222
val schemeDirectives =
2323
typeDefinitionRegistry.schemaExtensionDefinitions?.map { it.directives }?.flatten() ?: emptyList()
2424
val annotations = Annotations(schemeDirectives + definition.directives, typeDefinitionRegistry, definition.name)
25-
if (annotations.relationshipProperties != null) {
25+
if (annotations.node == null || annotations.relationshipProperties != null) {
2626
return null
2727
}
2828
val interfaces = definition.implements.mapNotNull { interfaceFactory(it.name()) }

core/src/main/kotlin/org/neo4j/graphql/domain/directives/RelationshipDirective.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class RelationshipDirective private constructor(
2626

2727
val queryDirection =
2828
directive.readArgument(RelationshipDirective::queryDirection) { RelationField.QueryDirection.valueOf((it as EnumValue).name) }
29-
?: RelationField.QueryDirection.DEFAULT_DIRECTED
29+
?: RelationField.QueryDirection.DIRECTED
3030

3131
return RelationshipDirective(direction, type, properties, queryDirection)
3232
}

core/src/main/kotlin/org/neo4j/graphql/domain/fields/PointField.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ class PointField(
3131
override val predicateDefinitions: Map<String, ScalarPredicateDefinition> = initPredicates()
3232
override val whereType
3333
get() = when (coordinateType) {
34-
CoordinateType.GEOGRAPHIC -> POINT_INPUT_TYPE.asType()
35-
CoordinateType.CARTESIAN -> CARTESIAN_POINT_INPUT_TYPE.asType()
34+
CoordinateType.GEOGRAPHIC -> TypeName(POINT_INPUT_TYPE)
35+
CoordinateType.CARTESIAN -> TypeName(CARTESIAN_POINT_INPUT_TYPE)
3636
}
3737

3838
private fun initPredicates(): Map<String, ScalarPredicateDefinition> {
3939
val result = mutableMapOf<String, ScalarPredicateDefinition>()
40+
.add(FieldOperator.IMPLICIT_EQUAL, deprecated = "Please use the explicit _EQ version")
4041
.add(FieldOperator.EQUAL)
4142
if (isList()) {
4243
result.addIncludesResolver(FieldOperator.INCLUDES)
@@ -77,7 +78,7 @@ class PointField(
7778
val paramPointArray = Cypher.listWith(p).`in`(parameter).returning(Cypher.point(p))
7879
op.conditionCreator(property, paramPointArray)
7980
},
80-
type = whereType.NonNull.List
81+
type = whereType.makeRequired(type.isRequired()).List
8182
)
8283
}
8384

@@ -88,7 +89,7 @@ class PointField(
8889
val paramPoint = Cypher.point(parameter)
8990
op.conditionCreator(property, paramPoint)
9091
},
91-
type = whereType.inner()
92+
type = whereType
9293
)
9394
}
9495

core/src/main/kotlin/org/neo4j/graphql/domain/fields/RelationField.kt

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,39 +41,22 @@ class RelationField(
4141
}
4242

4343
enum class QueryDirection {
44-
DEFAULT_DIRECTED,
45-
DEFAULT_UNDIRECTED,
46-
DIRECTED_ONLY,
47-
UNDIRECTED_ONLY,
44+
DIRECTED,
45+
UNDIRECTED,
4846
}
4947

5048
fun createQueryDslRelation(
5149
start: Node,
5250
end: Node,
53-
directed: Boolean?,
5451
): Relationship {
55-
val useDirected = when (queryDirection) {
56-
QueryDirection.DEFAULT_DIRECTED -> directed ?: true
57-
QueryDirection.DEFAULT_UNDIRECTED -> directed ?: false
58-
QueryDirection.DIRECTED_ONLY -> {
59-
check(directed == null || directed == true, { "Invalid direction in 'DIRECTED_ONLY' relationship" })
60-
true
52+
return when (queryDirection) {
53+
QueryDirection.DIRECTED -> when (direction) {
54+
Direction.IN -> end.relationshipTo(start, relationType)
55+
Direction.OUT -> start.relationshipTo(end, relationType)
6156
}
6257

63-
QueryDirection.UNDIRECTED_ONLY -> {
64-
check(directed == null || directed == false, { "Invalid direction in 'UNDIRECTED_ONLY' relationship" })
65-
false
66-
}
67-
}
68-
if (useDirected) {
69-
return createDslRelation(start, end)
58+
QueryDirection.UNDIRECTED -> start.relationshipBetween(end, relationType)
7059
}
71-
return start.relationshipBetween(end, relationType)
7260
}
7361

74-
fun createDslRelation(start: Node, end: Node, name: String? = null): Relationship = when (direction) {
75-
Direction.IN -> end.relationshipTo(start, relationType)
76-
Direction.OUT -> start.relationshipTo(end, relationType)
77-
}.let { if (name != null) it.named(name) else it }
78-
7962
}

core/src/main/kotlin/org/neo4j/graphql/domain/fields/ScalarField.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ abstract class ScalarField(
3737
}
3838

3939
val result = mutableMapOf<String, ScalarPredicateDefinition>()
40+
.add(FieldOperator.IMPLICIT_EQUAL, resolver, deprecated = "Please use the explicit _EQ version")
4041
.add(FieldOperator.EQUAL, resolver)
4142
if (fieldType == Constants.BOOLEAN) {
4243
return result

core/src/main/kotlin/org/neo4j/graphql/domain/naming/ImplementingTypeNames.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ sealed class ImplementingTypeNames(
88
) : EntityNames(name, annotations) {
99

1010
val connectOrCreateWhereInputTypeName get() = "${name}ConnectOrCreateWhere"
11-
val optionsInputTypeName get() = "${name}Options"
1211
val sortInputTypeName get() = "${name}Sort"
1312
override val rootTypeFieldNames get() = ImplementingTypeRootTypeFieldNames()
1413
val rootTypeSelection get() = ImplementingTypeRootTypeSelection()

core/src/main/kotlin/org/neo4j/graphql/domain/predicates/FieldOperator.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ enum class FieldOperator(
99
val conditionCreator: (Expression, Expression) -> Condition,
1010
val conditionEvaluator: (Any?, Any?) -> Boolean,
1111
) {
12-
EQUAL("",
12+
IMPLICIT_EQUAL("",
13+
{ lhs, rhs -> if (rhs == Cypher.literalNull()) lhs.isNull else lhs.eq(rhs) },
14+
{ lhs, rhs -> lhs == rhs }
15+
),
16+
EQUAL("EQ",
1317
{ lhs, rhs -> if (rhs == Cypher.literalNull()) lhs.isNull else lhs.eq(rhs) },
1418
{ lhs, rhs -> lhs == rhs }
1519
),

core/src/main/kotlin/org/neo4j/graphql/domain/predicates/RelationOperator.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ enum class RelationOperator(
1414
NONE("NONE", list = true, wrapInNotIfNeeded = { it.not() }),
1515
SINGLE("SINGLE", list = true),
1616
SOME("SOME", list = true),
17-
NOT_EQUAL("NOT", list = false, wrapInNotIfNeeded = { it.not() }),
1817
EQUAL(null, list = false);
1918

2019
fun createRelationCondition(

core/src/main/kotlin/org/neo4j/graphql/handler/BaseDataFetcher.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ internal abstract class BaseDataFetcher(protected val schemaConfig: SchemaConfig
3939
}
4040

4141
val result = neo4jAdapter.executeQuery(query, params)
42+
return mapResult(env, result)
43+
}
44+
45+
protected abstract fun generateCypher(env: DataFetchingEnvironment): Statement
46+
47+
protected open fun mapResult(env: DataFetchingEnvironment, result: List<Map<String, Any?>>): Any {
4248
return if (env.fieldDefinition.type?.isList() == true) {
4349
result.map { it[RESULT_VARIABLE] }
4450
} else {
@@ -47,8 +53,6 @@ internal abstract class BaseDataFetcher(protected val schemaConfig: SchemaConfig
4753
}
4854
}
4955

50-
protected abstract fun generateCypher(env: DataFetchingEnvironment): Statement
51-
5256
companion object {
5357
const val RESULT_VARIABLE = "this"
5458
}

core/src/main/kotlin/org/neo4j/graphql/handler/ConnectionResolver.kt

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import org.neo4j.graphql.schema.model.inputs.options.SortInput
1818
import org.neo4j.graphql.schema.model.outputs.root_connection.RootNodeConnectionSelection
1919
import org.neo4j.graphql.translate.ProjectionTranslator
2020
import org.neo4j.graphql.translate.TopLevelMatchTranslator
21+
import org.neo4j.graphql.utils.PagingUtils
2122
import org.neo4j.graphql.utils.ResolveTree
2223

2324
/**
@@ -75,7 +76,7 @@ internal class ConnectionResolver private constructor(
7576

7677
SortInput.Companion.Augmentation
7778
.generateSortIT(implementingType, ctx)
78-
?.let { args += inputValue(Constants.SORT, it.List) }
79+
?.let { args += inputValue(Constants.SORT, it.NonNull.List) }
7980

8081
args += inputValue(Constants.FIRST, Constants.Types.Int)
8182
args += inputValue(Constants.AFTER, Constants.Types.String)
@@ -119,10 +120,6 @@ internal class ConnectionResolver private constructor(
119120

120121
val alias = queryContext.getNextVariable(edgesSelection.aliasOrName)
121122

122-
123-
edgeSelection?.forEachField(Constants.CURSOR_FIELD) {
124-
TODO()
125-
}
126123
val subQueriesBeforeSort = mutableListOf<Statement>()
127124
val subQueriesAfterSort = mutableListOf<Statement>()
128125

@@ -187,4 +184,34 @@ internal class ConnectionResolver private constructor(
187184
.returning(Cypher.mapOf(*topProjection.toTypedArray()).`as`(RESULT_VARIABLE))
188185
.build()
189186
}
187+
188+
override fun mapResult(env: DataFetchingEnvironment, result: List<Map<String, Any?>>): Any {
189+
val data = result.map { it[RESULT_VARIABLE] }.firstOrNull() ?: return emptyMap<String, Any>()
190+
191+
val resolveTree = ResolveTree.resolve(env)
192+
193+
val mutableData = (data as? Map<*, *>)?.toMutableMap() ?: return data
194+
195+
val connectionSelection = resolveTree.fieldsByTypeName[implementingType.namings.rootTypeSelection.connection]
196+
connectionSelection?.forEachField(Constants.EDGES_FIELD) { edgesSelection ->
197+
val edgeSelection = edgesSelection.fieldsByTypeName[implementingType.namings.rootTypeSelection.edge]
198+
199+
mutableData[edgesSelection.aliasOrName] = mutableData[edgesSelection.aliasOrName]?.let {
200+
if (it !is List<*>) {
201+
return@forEachField
202+
}
203+
val input = InputArguments(implementingType, resolveTree.args)
204+
val sliceStart = (input.options.offset ?: -1) + 1
205+
206+
it.mapIndexed{ index, edge ->
207+
val mutableEdge = (edge as? Map<*, *>)?.toMutableMap() ?: return@mapIndexed edge
208+
edgeSelection?.forEachField(Constants.CURSOR_FIELD) {
209+
mutableEdge[it.aliasOrName] = PagingUtils.createCursor(sliceStart + index)
210+
}
211+
mutableEdge
212+
}
213+
}
214+
}
215+
return mutableData
216+
}
190217
}

0 commit comments

Comments
 (0)