diff --git a/kgraphql-ktor-stitched/src/main/kotlin/de/stuebingerb/kgraphql/stitched/schema/structure/StitchedSchemaCompilation.kt b/kgraphql-ktor-stitched/src/main/kotlin/de/stuebingerb/kgraphql/stitched/schema/structure/StitchedSchemaCompilation.kt index 315bfd3c..d7e97c8d 100644 --- a/kgraphql-ktor-stitched/src/main/kotlin/de/stuebingerb/kgraphql/stitched/schema/structure/StitchedSchemaCompilation.kt +++ b/kgraphql-ktor-stitched/src/main/kotlin/de/stuebingerb/kgraphql/stitched/schema/structure/StitchedSchemaCompilation.kt @@ -32,10 +32,13 @@ class StitchedSchemaCompilation( introspectTypes() - val typesByName = - (queryTypeProxies.values + enums.values + scalars.values + inputTypeProxies.values + unions.values).associateByTo( - mutableMapOf() - ) { it.name } + val typesByName = mutableMapOf().apply { + queryTypeProxies.values.forEach { put(it.name, it) } + enums.values.forEach { put(it.name, it) } + scalars.values.forEach { put(it.name, it) } + inputTypeProxies.values.forEach { put(it.name, it) } + unions.values.forEach { put(it.name, it) } + } (remoteSchemaCompilation.remoteQueryTypeProxies + remoteSchemaCompilation.remoteInputTypeProxies).forEach { if (typesByName[it.key] == null) { typesByName[it.key] = it.value diff --git a/kgraphql-ktor/api/kgraphql-ktor.api b/kgraphql-ktor/api/kgraphql-ktor.api index 61bd87a0..44d21bcd 100644 --- a/kgraphql-ktor/api/kgraphql-ktor.api +++ b/kgraphql-ktor/api/kgraphql-ktor.api @@ -66,9 +66,3 @@ public final class de/stuebingerb/kgraphql/GraphqlRequest$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public final class de/stuebingerb/kgraphql/KtorGraphQLConfiguration : de/stuebingerb/kgraphql/configuration/PluginConfiguration { - public fun (ZLjava/lang/String;)V - public final fun getEndpoint ()Ljava/lang/String; - public final fun getPlayground ()Z -} - diff --git a/kgraphql-ktor/src/main/kotlin/de/stuebingerb/kgraphql/KtorFeature.kt b/kgraphql-ktor/src/main/kotlin/de/stuebingerb/kgraphql/KtorFeature.kt index c19e483d..eb7d5536 100644 --- a/kgraphql-ktor/src/main/kotlin/de/stuebingerb/kgraphql/KtorFeature.kt +++ b/kgraphql-ktor/src/main/kotlin/de/stuebingerb/kgraphql/KtorFeature.kt @@ -63,7 +63,7 @@ class GraphQL(val schema: Schema) { class FeatureInstance(featureKey: String = "KGraphQL") : Plugin { companion object { private val playgroundHtml: ByteArray? by lazy { - KtorGraphQLConfiguration::class.java.classLoader.getResource("playground.html")?.readBytes() + GraphQL::class.java.classLoader.getResource("playground.html")?.readBytes() } } diff --git a/kgraphql-ktor/src/main/kotlin/de/stuebingerb/kgraphql/KtorGraphQLConfiguration.kt b/kgraphql-ktor/src/main/kotlin/de/stuebingerb/kgraphql/KtorGraphQLConfiguration.kt deleted file mode 100644 index 0e884111..00000000 --- a/kgraphql-ktor/src/main/kotlin/de/stuebingerb/kgraphql/KtorGraphQLConfiguration.kt +++ /dev/null @@ -1,8 +0,0 @@ -package de.stuebingerb.kgraphql - -import de.stuebingerb.kgraphql.configuration.PluginConfiguration - -class KtorGraphQLConfiguration( - val playground: Boolean, - val endpoint: String -) : PluginConfiguration diff --git a/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/Kraph.kt b/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/Kraph.kt index b0150cd7..f4dc71aa 100644 --- a/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/Kraph.kt +++ b/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/Kraph.kt @@ -2,7 +2,6 @@ package de.stuebingerb.kgraphql import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObjectBuilder -import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.buildJsonObject // MARK: Using this is a temporary solution as JCenter is closed down. @@ -37,14 +36,6 @@ class Kraph( Variable(name, typeName, buildJsonObject(block)) ) - fun variable(name: String, typeName: String, value: String) = variables.add( - Variable(name, typeName, JsonPrimitive(value)) - ) - - fun variable(name: String, typeName: String, value: Int) = variables.add( - Variable(name, typeName, JsonPrimitive(value)) - ) - private fun print(): String = buildString { append("$type ") if (variables.isNotEmpty() && root) { @@ -52,7 +43,7 @@ class Kraph( } if (fields.isNotEmpty()) { appendLine("{") - fields.map { appendLine(it.print()) } + fields.forEach { appendLine(it.print()) } appendLine("}") } else { appendLine() @@ -66,7 +57,7 @@ class Kraph( if (variables.isNotEmpty()) { append(",") append("\"variables\": {") - variables.map { + variables.forEach { append("\"${it.name}\": ${it.value}") } append("}") diff --git a/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/KtorMultipleEndpointsTest.kt b/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/KtorMultipleEndpointsTest.kt index 7b97018c..caf9e071 100644 --- a/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/KtorMultipleEndpointsTest.kt +++ b/kgraphql-ktor/src/test/kotlin/de/stuebingerb/kgraphql/KtorMultipleEndpointsTest.kt @@ -72,7 +72,7 @@ class KtorMultipleEndpointsTest : KtorTest() { } @Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") val playgroundHtml = - KtorGraphQLConfiguration::class.java.classLoader.getResource("playground.html") + GraphQL::class.java.classLoader.getResource("playground.html") .readText() val response = client.get("/graphql") diff --git a/kgraphql/api/kgraphql.api b/kgraphql/api/kgraphql.api index 8729f6fa..217782e3 100644 --- a/kgraphql/api/kgraphql.api +++ b/kgraphql/api/kgraphql.api @@ -965,12 +965,6 @@ public final class de/stuebingerb/kgraphql/schema/introspection/__Type$DefaultIm public static fun unwrapped (Lde/stuebingerb/kgraphql/schema/introspection/__Type;)Lde/stuebingerb/kgraphql/schema/introspection/__Type; } -public final class de/stuebingerb/kgraphql/schema/model/Add : de/stuebingerb/kgraphql/schema/model/DataActor { - public fun (Ljava/lang/Object;Lkotlinx/coroutines/CompletableDeferred;)V - public final fun getKey ()Ljava/lang/Object; - public final fun getResult ()Lkotlinx/coroutines/CompletableDeferred; -} - public abstract class de/stuebingerb/kgraphql/schema/model/BaseOperationDef : de/stuebingerb/kgraphql/schema/model/Definition, de/stuebingerb/kgraphql/schema/model/FunctionWrapper, de/stuebingerb/kgraphql/schema/model/OperationDef { public fun (Ljava/lang/String;Lde/stuebingerb/kgraphql/schema/model/FunctionWrapper;Ljava/util/List;Lkotlin/jvm/functions/Function2;Lkotlin/reflect/KType;)V public fun arity ()I @@ -988,43 +982,11 @@ public abstract class de/stuebingerb/kgraphql/schema/model/BaseOperationDef : de public fun valueParameters ()Ljava/util/List; } -public abstract class de/stuebingerb/kgraphql/schema/model/DataActor { -} - -public final class de/stuebingerb/kgraphql/schema/model/DataLoader { - public fun (Lkotlin/jvm/functions/Function2;)V - public final fun begin (ILkotlinx/coroutines/CoroutineScope;)Lde/stuebingerb/kgraphql/schema/model/DataLoader$DataScope; -} - -public final class de/stuebingerb/kgraphql/schema/model/DataLoader$DataScope : kotlinx/coroutines/CoroutineScope { - public fun (Lde/stuebingerb/kgraphql/schema/model/DataLoader;ILkotlinx/coroutines/CoroutineScope;)V - public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; - public final fun load (Ljava/lang/Object;Lkotlinx/coroutines/CompletableDeferred;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; -} - -public final class de/stuebingerb/kgraphql/schema/model/DataLoaderKt { - public static final fun dataActor (Lkotlinx/coroutines/CoroutineScope;ILkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/channels/SendChannel; - public static final fun log (Ljava/lang/String;)V -} - public abstract class de/stuebingerb/kgraphql/schema/model/Definition { public fun (Ljava/lang/String;)V public final fun getName ()Ljava/lang/String; } -public final class de/stuebingerb/kgraphql/schema/model/Deprecation { - public fun (Ljava/lang/Object;Ljava/lang/String;)V - public final fun component1 ()Ljava/lang/Object; - public final fun component2 ()Ljava/lang/String; - public final fun copy (Ljava/lang/Object;Ljava/lang/String;)Lde/stuebingerb/kgraphql/schema/model/Deprecation; - public static synthetic fun copy$default (Lde/stuebingerb/kgraphql/schema/model/Deprecation;Ljava/lang/Object;Ljava/lang/String;ILjava/lang/Object;)Lde/stuebingerb/kgraphql/schema/model/Deprecation; - public fun equals (Ljava/lang/Object;)Z - public final fun getReason ()Ljava/lang/String; - public final fun getTarget ()Ljava/lang/Object; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - public abstract interface class de/stuebingerb/kgraphql/schema/model/Depreciable { public abstract fun getDeprecationReason ()Ljava/lang/String; public abstract fun isDeprecated ()Z @@ -1226,11 +1188,6 @@ public final class de/stuebingerb/kgraphql/schema/model/FunctionWrapper$DefaultI public static fun valueParameters (Lde/stuebingerb/kgraphql/schema/model/FunctionWrapper;)Ljava/util/List; } -public final class de/stuebingerb/kgraphql/schema/model/Increment : de/stuebingerb/kgraphql/schema/model/DataActor { - public fun (I)V - public final fun getCount ()I -} - public final class de/stuebingerb/kgraphql/schema/model/InputValueDef : de/stuebingerb/kgraphql/schema/model/Depreciable, de/stuebingerb/kgraphql/schema/model/DescribedDef { public fun (Lkotlin/reflect/KClass;Ljava/lang/String;Ljava/lang/Object;ZLjava/lang/String;Ljava/lang/String;Lkotlin/reflect/KType;Ljava/lang/String;)V public synthetic fun (Lkotlin/reflect/KClass;Ljava/lang/String;Ljava/lang/Object;ZLjava/lang/String;Ljava/lang/String;Lkotlin/reflect/KType;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -2166,7 +2123,6 @@ public final class de/stuebingerb/kgraphql/schema/structure/SchemaModel : de/stu public fun getMutationType ()Lde/stuebingerb/kgraphql/schema/structure/Type; public synthetic fun getQueryType ()Lde/stuebingerb/kgraphql/schema/introspection/__Type; public fun getQueryType ()Lde/stuebingerb/kgraphql/schema/structure/Type; - public final fun getQueryTypesByName ()Ljava/util/Map; public final fun getRemoteTypesBySchema ()Ljava/util/Map; public synthetic fun getSubscriptionType ()Lde/stuebingerb/kgraphql/schema/introspection/__Type; public fun getSubscriptionType ()Lde/stuebingerb/kgraphql/schema/structure/Type; diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/Execution.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/Execution.kt index 880e314f..efd05317 100644 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/Execution.kt +++ b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/Execution.kt @@ -30,7 +30,11 @@ sealed class Execution { val key = selectionNode.name.value val aliasOrKey = selectionNode.aliasOrName.value - override val fullPath = parent?.fullPath.orEmpty() + aliasOrKey + listOfNotNull(arrayIndex) + override val fullPath = buildList { + parent?.let { addAll(it.fullPath) } + add(aliasOrKey) + arrayIndex?.let { add(it) } + } internal fun withIndex(index: Int): Node = Node( selectionNode, diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/ParallelRequestExecutor.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/ParallelRequestExecutor.kt index c879b431..264554d0 100644 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/ParallelRequestExecutor.kt +++ b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/execution/ParallelRequestExecutor.kt @@ -50,7 +50,7 @@ internal class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecu execution.children.inspect() if (execution.field is Field.DataLoader<*, *, *>) { loaders[execution.field] = - execution.field.loader.constructNew(coroutineContext.job) as DataLoader + execution.field.loader.constructNew(this@coroutineScope.coroutineContext.job) as DataLoader } } } @@ -476,11 +476,10 @@ internal class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecu return when { hasReceiver -> CompletableDeferred(invoke(receiver, *transformedArgs.toTypedArray())) isSubscription -> { - fun Execution.getSubscriptionArgs(): List = when { - this is Execution.Node && children.isEmpty() -> listOf(aliasOrKey) - this is Execution.Node -> children.flatMap { it.getSubscriptionArgs() } - this is Execution.Fragment -> elements.flatMap { it.getSubscriptionArgs() } - else -> error("Unexpected type of node: $this") + fun Execution.getSubscriptionArgs(): List = when (this) { + is Execution.Node if children.isEmpty() -> listOf(aliasOrKey) + is Execution.Node -> children.flatMap { it.getSubscriptionArgs() } + is Execution.Fragment -> elements.flatMap { it.getSubscriptionArgs() } } CompletableDeferred(invoke(transformedArgs, executionNode.getSubscriptionArgs(), objectWriter)) diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/DataLoader.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/DataLoader.kt deleted file mode 100644 index 87ba5130..00000000 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/DataLoader.kt +++ /dev/null @@ -1,78 +0,0 @@ -package de.stuebingerb.kgraphql.schema.model - -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ObsoleteCoroutinesApi -import kotlinx.coroutines.channels.actor -import java.util.Stack - -class DataLoader(private val batchLoader: suspend (List) -> Map) { - - inner class DataScope(totalTimes: Int, scope: CoroutineScope) : CoroutineScope by scope { - @OptIn(ObsoleteCoroutinesApi::class) - private val actor = dataActor(totalTimes, batchLoader) - - suspend fun load(key: K, valueResult: CompletableDeferred) { - actor.send(Add(key, valueResult)) - } - } - - fun begin(totalTimes: Int, scope: CoroutineScope): DataScope { - return DataScope(totalTimes, scope) - } -} - -sealed class DataActor -class Add(val key: K, val result: CompletableDeferred) : DataActor() -class Increment(val count: Int) : DataActor() - -@ObsoleteCoroutinesApi -fun CoroutineScope.dataActor(totalTimes: Int, batchLoader: suspend (List) -> Map) = actor { - var counter = totalTimes - - log("Starting dataActor with totalCount: $counter") - - val cache = mutableMapOf() - val promiseMap = mutableMapOf>>() - - suspend fun doJoin() { - val toLoad = promiseMap - .map { it.key } - .filterNot { cache.containsKey(it) } - .toList() - if (toLoad.isNotEmpty()) { - batchLoader(toLoad).forEach { (key, value) -> - cache[key] = value - } - } - promiseMap.forEach { (key, promises) -> - var promise: CompletableDeferred? = promises.pop() - while (promise != null) { - promise.complete(cache[key]) - promise = if (promises.isNotEmpty()) { - promises.pop() - } else { - null - } - } - } - promiseMap.clear() - } - - for (msg in channel) { - if (msg is Add<*, *>) { - @Suppress("UNCHECKED_CAST") - msg as Add - if (!promiseMap.containsKey(msg.key)) { - promiseMap[msg.key] = Stack() - } - promiseMap[msg.key]?.add(msg.result) ?: error("Couldn't find any '${msg.key}' in map") - log("$counter") - if (--counter == 0) { - doJoin() - } - } - } -} - -fun log(str: String) = println("DATALOADER: $str") diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/Deprecation.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/Deprecation.kt deleted file mode 100644 index ed370753..00000000 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/Deprecation.kt +++ /dev/null @@ -1,3 +0,0 @@ -package de.stuebingerb.kgraphql.schema.model - -data class Deprecation(val target: T, val reason: String?) diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/MutableSchemaDefinition.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/MutableSchemaDefinition.kt index 02039610..0eea1e17 100644 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/MutableSchemaDefinition.kt +++ b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/MutableSchemaDefinition.kt @@ -14,6 +14,7 @@ import de.stuebingerb.kgraphql.schema.introspection.__InputValue import de.stuebingerb.kgraphql.schema.introspection.__Schema import de.stuebingerb.kgraphql.schema.introspection.__Type import de.stuebingerb.kgraphql.schema.structure.validateName +import kotlin.enums.enumEntries import kotlin.reflect.KClass import kotlin.reflect.full.isSubclassOf @@ -36,12 +37,12 @@ open class MutableSchemaDefinition { TypeDef.Enumeration( "__" + TypeKind::class.defaultKQLTypeName(), TypeKind::class, - enumValues().map { EnumValueDef(it) } + enumEntries().map { EnumValueDef(it) } ), TypeDef.Enumeration( "__" + DirectiveLocation::class.defaultKQLTypeName(), DirectiveLocation::class, - enumValues().map { EnumValueDef(it) } + enumEntries().map { EnumValueDef(it) } ) ) protected val unions: ArrayList = arrayListOf() diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/ast/Location.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/ast/Location.kt index 57131626..392b3053 100644 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/ast/Location.kt +++ b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/model/ast/Location.kt @@ -52,7 +52,7 @@ data class Location( var line = 1 var column = position + 1 - lineRegexp.findAll(source.body).toList().map { + lineRegexp.findAll(source.body).forEach { if (it.range.first < position) { line += 1 column = position + 1 - (it.range.first + it.value.length) diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt index b7e60e09..4afe496b 100644 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt +++ b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt @@ -80,13 +80,16 @@ open class SchemaCompilation( query = queryType, mutation = mutationType, subscription = subscriptionType, - allTypes = queryTypeProxies.values - + inputTypeProxies.values - + enums.values - + scalars.values - + unions.values - + queryType - + listOfNotNull(mutationType, subscriptionType), + allTypes = buildList { + addAll(queryTypeProxies.values) + addAll(inputTypeProxies.values) + addAll(enums.values) + addAll(scalars.values) + addAll(unions.values) + add(queryType) + mutationType?.let { add(it) } + subscriptionType?.let { add(it) } + }, directives = definition.directives.map { handlePartialDirective(it) }, remoteTypesBySchema = emptyMap(), description = schemaDescription @@ -167,7 +170,12 @@ open class SchemaCompilation( return Type.OperationObject( name = "Query", description = "Query object", - fields = declaredFields + __typenameField + introspectionSchemaQuery() + introspectionTypeQuery() + fields = buildList { + addAll(declaredFields) + add(__typenameField) + add(introspectionSchemaQuery()) + add(introspectionTypeQuery()) + } ) } @@ -316,6 +324,10 @@ open class SchemaCompilation( ) } + private fun String.checkForEqualName(vararg types: Collection): Boolean { + return types.any { list -> list.any { it.name == this } } + } + private suspend fun handleObjectType(kClass: KClass<*>): Type { assertValidObjectType(kClass) val objectDefs = definition.objects.filter { it.kClass.isSuperclassOf(kClass) } @@ -323,7 +335,7 @@ open class SchemaCompilation( if (!objectDef.isIntrospectionType()) { validateName(objectDef.name) - if ((enums.values + scalars.values + inputTypeProxies.values + unions.values).any { it.name == objectDef.name }) { + if (objectDef.name.checkForEqualName(enums.values, scalars.values, inputTypeProxies.values, unions.values)) { throw SchemaException("Cannot add object type with duplicated name '${objectDef.name}'") } if (queryTypeProxies.any { it.key != kClass && it.value.name == objectDef.name }) { @@ -440,7 +452,7 @@ open class SchemaCompilation( }, kClass, isOneOf = kClass.isSealed) validateName(inputObjectDef.name) - if ((enums.values + scalars.values + queryTypeProxies.values + unions.values).any { it.name == inputObjectDef.name }) { + if (inputObjectDef.name.checkForEqualName(enums.values, scalars.values, queryTypeProxies.values, unions.values)) { throw SchemaException("Cannot add input type with duplicated name '${inputObjectDef.name}'") } if (inputTypeProxies.any { it.key != kClass && it.value.name == inputObjectDef.name }) { @@ -494,7 +506,7 @@ open class SchemaCompilation( // parameters of this constructor for the fields (cf. https://github.com/stuebingerb/KGraphQL/issues/235). // Member properties are sorted by name (https://youtrack.jetbrains.com/issue/KT-41042), and SDL is // sorting by name, so we'll also sort constructor parameters to be consistent. - primaryConstructor.parameters.sortedBy { it.name }.map { parameter -> + primaryConstructor.parameters.sortedBy { it.name }.forEach { parameter -> // kProperty is used to configure deprecation and description in the DSL, so we use it // if available val kProperty = memberPropertiesByName[parameter.name] @@ -554,7 +566,8 @@ open class SchemaCompilation( unions[union.name to union.members]?.let { return it } validateName(union.name) - if ((enums.values + scalars.values + inputTypeProxies.values + unions.values).any { it.name == union.name }) { + + if (union.name.checkForEqualName(enums.values, scalars.values, inputTypeProxies.values, unions.values)) { throw SchemaException("Cannot add union type with duplicated name '${union.name}'") } diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaModel.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaModel.kt index 93f6b2c3..33af4e52 100644 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaModel.kt +++ b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaModel.kt @@ -17,9 +17,6 @@ data class SchemaModel( val allTypesByName = allTypes.associateBy { it.name } - // (only) used for resolving fragment conditions, which cannot be specified on any input type - val queryTypesByName = allTypes.filterNot { it.isInputType() }.associateBy { it.name } - override val types: List = toTypeList() private fun toTypeList(): List = allTypes diff --git a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/blockString.kt b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/blockString.kt index b800bc75..3e1f61fe 100644 --- a/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/blockString.kt +++ b/kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/blockString.kt @@ -26,10 +26,10 @@ internal fun dedentBlockStringValue(rawString: String): String { } // Remove leading and trailing blank lines. - while (lines.size > 0 && isBlank(lines[0])) { + while (lines.isNotEmpty() && isBlank(lines[0])) { lines = lines.drop(1).toMutableList() } - while (lines.size > 0 && isBlank(lines[lines.size - 1])) { + while (lines.isNotEmpty() && isBlank(lines[lines.size - 1])) { lines = lines.dropLast(1).toMutableList() } diff --git a/kgraphql/src/test/kotlin/de/stuebingerb/kgraphql/DataLoaderTest.kt b/kgraphql/src/test/kotlin/de/stuebingerb/kgraphql/DataLoaderTest.kt index 8b4a7935..a29f69f4 100644 --- a/kgraphql/src/test/kotlin/de/stuebingerb/kgraphql/DataLoaderTest.kt +++ b/kgraphql/src/test/kotlin/de/stuebingerb/kgraphql/DataLoaderTest.kt @@ -6,16 +6,19 @@ import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.ints.shouldBeLessThanOrEqual import io.kotest.matchers.shouldBe +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext import nidomiro.kdataloader.ExecutionResult import org.junit.jupiter.api.DynamicTest import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestFactory import java.util.concurrent.atomic.AtomicInteger +import kotlin.time.Duration.Companion.milliseconds class DataLoaderTest { @@ -90,7 +93,7 @@ class DataLoaderTest { dataProperty>("colleagues") { prepare { it.id } loader { keys -> - delay(10) + delay(10.milliseconds) println("== Running [colleagues] loader with keys: $keys ==") keys.map { ExecutionResult.Success(colleagues[it] ?: listOf()) } } @@ -142,9 +145,11 @@ class DataLoaderTest { property("simpleChild") { resolver { - delay((1..5L).random()) - Thread.sleep((1..5L).random()) - delay((1..5L).random()) + delay((1..5L).random().milliseconds) + withContext(Dispatchers.IO) { + Thread.sleep((1..5L).random()) + } + delay((1..5L).random().milliseconds) ABC("NewChild!") } } @@ -153,7 +158,7 @@ class DataLoaderTest { prepare { it.personId } loader { personIds -> personIds.map { - delay(1) + delay(1.milliseconds) ExecutionResult.Success( if (it == null || it < 1) { null @@ -167,7 +172,7 @@ class DataLoaderTest { property("personOld") { resolver { - delay(1) + delay(1.milliseconds) if (it.personId == null || it.personId < 1) { null } else { @@ -187,7 +192,7 @@ class DataLoaderTest { "Testing 3" -> "Jógvan" to "Høgni" else -> "${key}Nest-0" to "${key}Nest-1" } - delay(1) + delay(1.milliseconds) ExecutionResult.Success( (1..7).map { if (it % 2 == 0) {