From 3483efa55557cb9725e8229a2cc5f9ac721df279 Mon Sep 17 00:00:00 2001 From: Sascha Lisson Date: Wed, 20 Sep 2023 21:47:15 +0200 Subject: [PATCH 1/2] fix(modelql): ClassCastException in .mapIfNotNull fixes MODELIX-552 --- .../kotlin/org/modelix/modelql/core/IfEmpty.kt | 2 +- .../org/modelix/modelql/core/MapIfNotNullStep.kt | 6 +++--- .../kotlin/org/modelix/modelql/core/Query.kt | 9 ++++----- .../kotlin/org/modelix/modelql/core/ModelQLTest.kt | 10 +++++++++- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt index 8a41cc5b8d..6c9c471d5e 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt @@ -26,7 +26,7 @@ class IfEmptyStep(val alternative: UnboundQuery) : override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { val downCastedInput: StepFlow = input return downCastedInput.map { MultiplexedOutput(0, it) }.onEmpty { - emitAll(alternative.asFlow(context.evaluationContext, Unit).map { MultiplexedOutput(1, it) }) + emitAll(alternative.asFlow(context.evaluationContext, Unit.asStepOutput(null)).map { MultiplexedOutput(1, it) }) } } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt index fa04e4e1ef..4d15ca325b 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt @@ -32,9 +32,9 @@ class MapIfNotNullStep(val query: MonoUnboundQuery) : Mo } override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { - return input.flatMapConcat { - it.value?.let { query.asFlow(context.evaluationContext, it).map { MultiplexedOutput(1, it) } } - ?: flowOf(MultiplexedOutput(0, it as IStepOutput)) + return input.flatMapConcat { stepOutput -> + stepOutput.value?.let { query.asFlow(context.evaluationContext, stepOutput.upcast()).map { MultiplexedOutput(1, it) } } + ?: flowOf(MultiplexedOutput(0, stepOutput.upcast())) } } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt index 951b5882d1..715d1dbb8c 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt @@ -37,7 +37,7 @@ interface IQueryExecutor { class SimpleQueryExecutor(val input: E) : IQueryExecutor { override fun createFlow(query: IUnboundQuery): StepFlow { - return query.asFlow(QueryEvaluationContext.EMPTY, input) + return query.asFlow(QueryEvaluationContext.EMPTY, input.asStepOutput(null)) } } @@ -105,9 +105,8 @@ private class FluxBoundQuery(executor: IQueryExecutor, override val interface IUnboundQuery { val reference: IQueryReference> - suspend fun execute(evaluationContext: QueryEvaluationContext, input: In): IStepOutput + suspend fun execute(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput fun asFlow(evaluationContext: QueryEvaluationContext, input: StepFlow): StepFlow - fun asFlow(evaluationContext: QueryEvaluationContext, input: In): StepFlow = asFlow(evaluationContext, flowOf(input).asStepFlow(null)) fun asFlow(evaluationContext: QueryEvaluationContext, input: IStepOutput): StepFlow = asFlow(evaluationContext, flowOf(input)) fun asSequence(evaluationContext: QueryEvaluationContext, input: Sequence): Sequence @@ -165,7 +164,7 @@ class MonoUnboundQuery( override fun bind(executor: IQueryExecutor): IMonoQuery = MonoBoundQuery(executor, this) - override suspend fun execute(evaluationContext: QueryEvaluationContext, input: In): IStepOutput { + override suspend fun execute(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput { try { return asFlow(evaluationContext, input).single() } catch (ex: NoSuchElementException) { @@ -212,7 +211,7 @@ class FluxUnboundQuery( override fun bind(executor: IQueryExecutor): IFluxQuery = FluxBoundQuery(executor, this) - override suspend fun execute(evaluationContext: QueryEvaluationContext, input: In): IStepOutput>> { + override suspend fun execute(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput>> { return asFlow(evaluationContext, input).toList().asStepOutput(null) } diff --git a/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt b/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt index e4c0bec6a2..9ce3eaa310 100644 --- a/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt +++ b/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt @@ -329,6 +329,14 @@ class ModelQLTest { assertEquals(testDatabase.products, result) } + @Test + fun mapIfNotNull() = runTestWithTimeout { + val result = remoteProductDatabaseQuery { db -> + "a".asMono().mapIfNotNull { it.identity() }.mapIfNotNull { it.identity() } + } + assertEquals("a", result) + } + @Test fun zipElementAccess() = runTestWithTimeout { val result = remoteProductDatabaseQuery { db -> @@ -385,7 +393,7 @@ suspend fun doRemoteProductDatabaseQuery(body: (IMonoStep(serializedQuery).createRootQuery() as MonoUnboundQuery println("original query : $query") println("deserialized query: $deserializedQuery") - val remoteResult: IStepOutput = deserializedQuery.execute(QueryEvaluationContext.EMPTY, testDatabase) + val remoteResult: IStepOutput = deserializedQuery.execute(QueryEvaluationContext.EMPTY, testDatabase.asStepOutput(null)) val serializedResult = json.encodeToString(deserializedQuery.getAggregationOutputSerializer(json.serializersModule), remoteResult) // println(serializedResult) return json.decodeFromString(query.getAggregationOutputSerializer(json.serializersModule), serializedResult).value From cf51cc9a0c2f545a63be6c6a53476c4fcc866baf Mon Sep 17 00:00:00 2001 From: Sascha Lisson Date: Wed, 20 Sep 2023 15:47:07 +0200 Subject: [PATCH 2/2] fix(modelql): removed duplicate definitions of the semantic in IProducingStep In IProducing step there were the methods createFlow, createSequence and evaluate which all did basically the same computation, but on different types of input. In some cases this can have a performance benefit, but it's hard to maintain and to guarantee that they all do the same. It's not worth to keep them. --- .../modelix/modelql/core/AndOperatorStep.kt | 2 +- .../modelql/core/CollectionSizeStep.kt | 2 +- .../org/modelix/modelql/core/CollectorStep.kt | 24 -------- .../modelql/core/ConstantSourceStep.kt | 10 +--- .../org/modelix/modelql/core/CountingStep.kt | 2 - .../modelql/core/EmptyStringIfNullStep.kt | 21 ++++++- .../org/modelix/modelql/core/FilteringStep.kt | 9 --- .../modelix/modelql/core/FirstElementStep.kt | 8 --- .../modelix/modelql/core/FirstOrNullStep.kt | 4 -- .../org/modelix/modelql/core/FlatMapStep.kt | 4 -- .../org/modelix/modelql/core/FoldingStep.kt | 4 -- .../kotlin/org/modelix/modelql/core/IStep.kt | 58 +------------------ .../org/modelix/modelql/core/IdentityStep.kt | 4 -- .../org/modelix/modelql/core/IfEmpty.kt | 5 -- .../org/modelix/modelql/core/IntSumStep.kt | 2 +- .../org/modelix/modelql/core/IsEmptyStep.kt | 2 - .../modelql/core/IsNullPredicateStep.kt | 2 +- .../org/modelix/modelql/core/JoinStep.kt | 4 -- .../modelix/modelql/core/LocalMappingStep.kt | 5 +- .../modelix/modelql/core/MapIfNotNullStep.kt | 8 --- .../org/modelix/modelql/core/MappingStep.kt | 12 ---- .../modelix/modelql/core/NotOperatorStep.kt | 2 +- .../org/modelix/modelql/core/NullIfEmpty.kt | 4 -- .../modelix/modelql/core/OrOperatorStep.kt | 2 +- .../org/modelix/modelql/core/PrintStep.kt | 9 ++- .../kotlin/org/modelix/modelql/core/Query.kt | 35 ++++------- .../org/modelix/modelql/core/QueryCallStep.kt | 5 -- .../modelix/modelql/core/RegexPredicate.kt | 2 +- .../org/modelix/modelql/core/SharedStep.kt | 4 -- .../org/modelix/modelql/core/SingleStep.kt | 4 -- .../modelql/core/StringContainsPredicate.kt | 2 +- .../modelql/core/StringToBooleanStep.kt | 2 +- .../modelix/modelql/core/StringToIntStep.kt | 2 +- .../org/modelix/modelql/core/ToStringStep.kt | 2 +- .../core/TransformingStepWithParameter.kt | 26 --------- .../org/modelix/modelql/core/WhenStep.kt | 22 ------- .../org/modelix/modelql/core/WithIndexStep.kt | 12 ---- .../modelql/core/ZipElementAccessStep.kt | 12 +--- .../org/modelix/modelql/core/ZipStep.kt | 4 -- .../org/modelix/modelql/core/ModelQLTest.kt | 14 +---- .../modelix/modelql/core/PerformanceTests.kt | 12 ---- .../org/modelix/modelql/typed/TypedModelQL.kt | 9 --- .../modelql/untyped/AddNewChildNodeStep.kt | 4 +- .../untyped/AllChildrenTraversalStep.kt | 5 -- .../untyped/AllReferencesTraversalStep.kt | 5 -- .../modelql/untyped/ChildrenTraversalStep.kt | 5 -- .../untyped/ConceptReferenceTraversalStep.kt | 4 +- .../ConceptReferenceUIDTraversalStep.kt | 4 +- .../untyped/DescendantsTraversalStep.kt | 6 -- .../NodeReferenceAsStringTraversalStep.kt | 4 +- .../untyped/NodeReferenceTraversalStep.kt | 4 +- .../modelix/modelql/untyped/OfConceptStep.kt | 11 ---- .../modelql/untyped/ParentTraversalStep.kt | 9 --- .../modelql/untyped/PropertyTraversalStep.kt | 4 +- .../modelql/untyped/ReferenceTraversalStep.kt | 6 -- .../modelix/modelql/untyped/RemoveNodeStep.kt | 4 -- .../modelql/untyped/ResolveNodeStep.kt | 5 -- .../untyped/RoleInParentTraversalStep.kt | 4 +- 58 files changed, 73 insertions(+), 389 deletions(-) diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/AndOperatorStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/AndOperatorStep.kt index 9c868cfb5d..85365c793f 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/AndOperatorStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/AndOperatorStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class AndOperatorStep() : MonoTransformingStep, Boolean>() { +class AndOperatorStep() : SimpleMonoTransformingStep, Boolean>() { override fun transform(evaluationContext: QueryEvaluationContext, input: IZipOutput): Boolean { return input.values.all { it == true } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectionSizeStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectionSizeStep.kt index 74e02a6088..34e1f5598c 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectionSizeStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectionSizeStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class CollectionSizeStep : MonoTransformingStep, Int>() { +class CollectionSizeStep : SimpleMonoTransformingStep, Int>() { override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectorStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectorStep.kt index cff5d5ac85..e4894f32f5 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectorStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CollectorStep.kt @@ -99,11 +99,6 @@ class ListCollectorStep : CollectorStep>() { val outputList = inputList.map { it.value } return CollectorStepOutput(inputList, inputList, outputList) } - override fun aggregate(input: Sequence>): IStepOutput> { - val inputList = input.toList() - val outputList = inputList.map { it.value } - return CollectorStepOutput(inputList, inputList, outputList) - } @Serializable @SerialName("toList") @@ -132,12 +127,6 @@ class SetCollectorStep : CollectorStep>() { input.collect { if (outputSet.add(it.value)) inputList.add(it) } return CollectorStepOutput(inputList, inputList, outputSet) } - override fun aggregate(input: Sequence>): IStepOutput> { - val inputList = ArrayList>() - val outputSet = HashSet() - input.forEach { if (outputSet.add(it.value)) inputList.add(it) } - return CollectorStepOutput(inputList, inputList, outputSet) - } @Serializable @SerialName("toSet") @@ -173,19 +162,6 @@ class MapCollectorStep : CollectorStep, Map> val outputMap: Map = internalMap.mapValues { it.value.value } return CollectorStepOutput(inputList, internalMap, outputMap) } - override fun aggregate(input: Sequence>>): IStepOutput> { - val inputList = ArrayList>>() - val internalMap = HashMap>() - input.forEach { - val zipStepOutput = it as ZipStepOutput, Any?> - if (!internalMap.containsKey(it.value.first)) { - inputList.add(it) - internalMap.put(zipStepOutput.values[0].value as K, zipStepOutput.values[1] as IStepOutput) - } - } - val outputMap: Map = internalMap.mapValues { it.value.value } - return CollectorStepOutput(inputList, internalMap, outputMap) - } @Serializable @SerialName("toMap") diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ConstantSourceStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ConstantSourceStep.kt index 9fdffb27c3..b01606a523 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ConstantSourceStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ConstantSourceStep.kt @@ -56,14 +56,6 @@ open class ConstantSourceStep(val element: E, val type: KType) : ProducingSte override fun requiresWriteAccess(): Boolean = false override fun needsCoroutineScope(): Boolean = false - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return sequenceOf(element) - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - return Optional.of(element) - } - override fun evaluateStatically(): E { return element } @@ -172,3 +164,5 @@ fun String?.asMono() = createConstantSourceStep(this) @JvmName("asMono_nullable") fun Set.asMono() = createConstantSourceStep(this) + +inline fun nullMono(): IMonoStep = ConstantSourceStep(null, typeOf()) diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CountingStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CountingStep.kt index 580b66e0d1..1c3e9dbee1 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CountingStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/CountingStep.kt @@ -25,8 +25,6 @@ class CountingStep() : AggregationStep() { return input.count().asStepOutput(this) } - override fun aggregate(input: Sequence>): IStepOutput = input.count().asStepOutput(this) - override fun createDescriptor(context: QueryGraphDescriptorBuilder) = CountDescriptor() @Serializable diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/EmptyStringIfNullStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/EmptyStringIfNullStep.kt index cc9a1e3e12..a6024f2bb9 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/EmptyStringIfNullStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/EmptyStringIfNullStep.kt @@ -13,6 +13,7 @@ */ package org.modelix.modelql.core +import kotlinx.coroutines.flow.map import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -20,12 +21,26 @@ import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer class EmptyStringIfNullStep : MonoTransformingStep() { + override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { - return serializersModule.serializer().stepOutputSerializer(this) + val inputSerializer: KSerializer> = getProducer().getOutputSerializer(serializersModule).upcast() + return MultiplexedOutputSerializer( + this, + listOf>>( + inputSerializer as KSerializer>, + serializersModule.serializer().stepOutputSerializer(this).upcast(), + ), + ) } - override fun transform(evaluationContext: QueryEvaluationContext, input: String?): String { - return input ?: "" + override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { + return input.map { + if (it.value == null) { + MultiplexedOutput(1, "".asStepOutput(this)) + } else { + MultiplexedOutput(0, it.upcast()) + } + } } override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FilteringStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FilteringStep.kt index 582084ebf6..097c572a11 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FilteringStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FilteringStep.kt @@ -43,15 +43,6 @@ class FilteringStep(val condition: MonoUnboundQuery) : Transform // return input.filter { condition.evaluate(it.value).presentAndEqual(true) } } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput).filter { - condition.evaluate( - evaluationContext, - it, - ).presentAndEqual(true) - } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return getProducer().getOutputSerializer(serializersModule) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstElementStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstElementStep.kt index d2a12c4263..f39ed47573 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstElementStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstElementStep.kt @@ -28,14 +28,6 @@ class FirstElementStep() : MonoTransformingStep() { override fun requiresSingularQueryInput(): Boolean = true - override fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput { - return input - } - - override fun transform(evaluationContext: QueryEvaluationContext, input: E): E { - return input - } - override fun toString(): String { return getProducer().toString() + ".first()" } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstOrNullStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstOrNullStep.kt index 6841f36eba..f6ddbdbd5c 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstOrNullStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstOrNullStep.kt @@ -26,10 +26,6 @@ class FirstOrNullStep() : AggregationStep() { ?: MultiplexedOutput(1, null.asStepOutput(this)) } - override fun aggregate(input: Sequence>): IStepOutput { - return input.firstOrNull() ?: null.asStepOutput(this) - } - override fun toString(): String { return "${getProducer()}.firstOrNull()" } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FlatMapStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FlatMapStep.kt index 42bf9f8386..0ada86bf2f 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FlatMapStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FlatMapStep.kt @@ -36,10 +36,6 @@ class FlatMapStep(val query: FluxUnboundQuery) : TransformingS return input.flatMapConcat { query.asFlow(context.evaluationContext, it) } } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return query.asSequence(evaluationContext, getProducer().createSequence(evaluationContext, queryInput)) - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return query.outputStep.getOutputSerializer(serializersModule) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FoldingStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FoldingStep.kt index 4c65985ba4..4defb690af 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FoldingStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FoldingStep.kt @@ -21,10 +21,6 @@ abstract class FoldingStep(private val initial: Out) : AggregationStep< return input.fold(initial) { acc, value -> fold(acc, value.value) }.asStepOutput(this) } - override fun aggregate(input: Sequence>): IStepOutput { - return input.fold(initial) { acc, value -> fold(acc, value.value) }.asStepOutput(this) - } - private var result: Out = initial protected abstract fun fold(acc: Out, value: In): Out diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IStep.kt index 247dacfff5..310a5b600f 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IStep.kt @@ -70,21 +70,6 @@ interface IProducingStep : IStep { fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> fun createFlow(context: IFlowInstantiationContext): StepFlow - /** - * Flows usually provide better performance, but if suspending is not possible you can iterate using a sequence. - */ - fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence - - /** - * Even higher performance for producers that output exactly one element - */ - fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - return createSequence(evaluationContext, sequenceOf(queryInput)) - .map { Optional.of(it) } - .ifEmpty { sequenceOf(Optional.empty()) } - .single() - } - fun outputIsConsumedMultipleTimes(): Boolean { return getConsumers().size > 1 || getConsumers().any { it.inputIsConsumedMultipleTimes() } } @@ -181,30 +166,12 @@ abstract class MonoTransformingStep : TransformingStep(), IMon fun connectAndDowncast(producer: IMonoStep): IMonoStep = also { producer.connect(it) } fun connectAndDowncast(producer: IFluxStep): IFluxStep = also { producer.connect(it) } +} +abstract class SimpleMonoTransformingStep : MonoTransformingStep() { override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { - return input.map { transform(context.evaluationContext, it) } - } - - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return createTransformingSequence( - evaluationContext, - getProducer().createSequence(evaluationContext, queryInput), - ) - } - - open fun createTransformingSequence(evaluationContext: QueryEvaluationContext, input: Sequence): Sequence { - return input.map { transform(evaluationContext, it) } - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - return getProducer().evaluate(evaluationContext, queryInput).map { transform(evaluationContext, it) } + return input.map { transform(context.evaluationContext, it.value).asStepOutput(this) } } - - protected open fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput { - return transform(evaluationContext, input.value).asStepOutput(this) - } - abstract fun transform(evaluationContext: QueryEvaluationContext, input: In): Out } @@ -233,24 +200,6 @@ abstract class AggregationStep : MonoTransformingStep() { } } - override fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput { - return aggregate(sequenceOf(input)) - } - - override fun transform(evaluationContext: QueryEvaluationContext, input: In): Out { - return aggregate(sequenceOf(input.asStepOutput(null))).value - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - return Optional.of( - aggregate( - getProducer().createSequence(evaluationContext, sequenceOf(queryInput)).map { - it.asStepOutput(null) - }, - ).value, - ) - } - override fun needsCoroutineScope() = outputIsConsumedMultipleTimes() override fun inputIsConsumedMultipleTimes(): Boolean { @@ -258,5 +207,4 @@ abstract class AggregationStep : MonoTransformingStep() { } protected abstract suspend fun aggregate(input: StepFlow): IStepOutput - protected abstract fun aggregate(input: Sequence>): IStepOutput } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IdentityStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IdentityStep.kt index 9079c57fd0..843a20b8cf 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IdentityStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IdentityStep.kt @@ -27,10 +27,6 @@ open class IdentityStep : TransformingStep(), IFluxOrMonoStep { return input } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput) - } - override fun canBeEmpty(): Boolean = getProducer().canBeEmpty() override fun canBeMultiple(): Boolean = getProducer().canBeMultiple() diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt index 6c9c471d5e..31fbafaf72 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt @@ -30,11 +30,6 @@ class IfEmptyStep(val alternative: UnboundQuery) : } } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput) - .ifEmpty { alternative.outputStep.createSequence(evaluationContext, sequenceOf(Unit)) } - } - override fun canBeEmpty(): Boolean = alternative.outputStep.canBeEmpty() override fun canBeMultiple(): Boolean = getProducer().canBeMultiple() || alternative.outputStep.canBeMultiple() diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IntSumStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IntSumStep.kt index f95a29f4db..b07e3f182b 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IntSumStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IntSumStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class IntSumStep(val operand: Int) : MonoTransformingStep() { +class IntSumStep(val operand: Int) : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: Int): Int { return input + operand diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsEmptyStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsEmptyStep.kt index e1c323aab6..46c9942e7c 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsEmptyStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsEmptyStep.kt @@ -28,8 +28,6 @@ class IsEmptyStep() : AggregationStep() { return input.take(1).map { false }.onEmpty { emit(true) }.single().asStepOutput(this) } - override fun aggregate(input: Sequence>): IStepOutput = input.none().asStepOutput(this) - override fun createDescriptor(context: QueryGraphDescriptorBuilder) = Descriptor() @Serializable diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsNullPredicateStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsNullPredicateStep.kt index 534c88b1a4..9afa6d286c 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsNullPredicateStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IsNullPredicateStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class IsNullPredicateStep() : MonoTransformingStep() { +class IsNullPredicateStep() : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: In): Boolean { return input == null diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/JoinStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/JoinStep.kt index de2ce706f6..35f1ede9be 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/JoinStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/JoinStep.kt @@ -53,10 +53,6 @@ class JoinStep() : ProducingStep(), IConsumingStep, IFluxStep { .asFlow().flattenConcat() } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return producers.asSequence().flatMap { it.createSequence(evaluationContext, queryInput) } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return MultiplexedOutputSerializer(this, getProducers().map { it.getOutputSerializer(serializersModule).upcast() }) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/LocalMappingStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/LocalMappingStep.kt index 49fc94fba2..7536c2a163 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/LocalMappingStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/LocalMappingStep.kt @@ -13,6 +13,7 @@ */ package org.modelix.modelql.core +import kotlinx.coroutines.flow.map import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder @@ -25,8 +26,8 @@ open class LocalMappingStep(val transformation: (In) -> Out) : MonoTran return LocalMappingSerializer(this, getProducer().getOutputSerializer(serializersModule)).stepOutputSerializer(this) } - override fun transform(evaluationContext: QueryEvaluationContext, input: In): Out { - return transformation(input) + override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { + return input.map { transformation(it.value).asStepOutput(this) } } override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt index 4d15ca325b..630e027b94 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt @@ -38,14 +38,6 @@ class MapIfNotNullStep(val query: MonoUnboundQuery) : Mo } } - override fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput { - throw UnsupportedOperationException("use MapIfNotNullStep.createFlow") - } - - override fun transform(evaluationContext: QueryEvaluationContext, input: In?): Out? { - return input?.let { query.outputStep.evaluate(evaluationContext, it).getOrElse(null) } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { val inputSerializer: KSerializer> = getProducer().getOutputSerializer(serializersModule) val mappedSerializer: KSerializer> = query.getElementOutputSerializer(serializersModule) diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MappingStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MappingStep.kt index cf06eb0f4b..5af97bb34c 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MappingStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MappingStep.kt @@ -40,18 +40,6 @@ class MappingStep(val query: MonoUnboundQuery) : MonoTransform return query.asFlow(context.evaluationContext, input) } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return query.asSequence(evaluationContext, queryInput as Sequence) - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - return getProducer().evaluate(evaluationContext, queryInput).flatMap { query.evaluate(evaluationContext, it) } - } - - override fun transform(evaluationContext: QueryEvaluationContext, input: In): Out { - return query.evaluate(evaluationContext, input).get() - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return query.getAggregationOutputSerializer(serializersModule) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NotOperatorStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NotOperatorStep.kt index 58a2d51a94..ef142bf5e5 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NotOperatorStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NotOperatorStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class NotOperatorStep() : MonoTransformingStep() { +class NotOperatorStep() : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: Boolean): Boolean { return !input diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NullIfEmpty.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NullIfEmpty.kt index f5dea6bb08..ee0506b8e7 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NullIfEmpty.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/NullIfEmpty.kt @@ -39,10 +39,6 @@ class NullIfEmpty() : MonoTransformingStep() { } } - override fun transform(evaluationContext: QueryEvaluationContext, input: E): E? { - return input - } - override fun createDescriptor(context: QueryGraphDescriptorBuilder) = OrNullDescriptor() @Serializable diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/OrOperatorStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/OrOperatorStep.kt index 59466a6337..21bd32c440 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/OrOperatorStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/OrOperatorStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class OrOperatorStep() : MonoTransformingStep, Boolean>() { +class OrOperatorStep() : SimpleMonoTransformingStep, Boolean>() { override fun transform(evaluationContext: QueryEvaluationContext, input: IZipOutput): Boolean { return input.values.any { it == true } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/PrintStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/PrintStep.kt index 16007561f3..41076c2060 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/PrintStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/PrintStep.kt @@ -13,6 +13,7 @@ */ package org.modelix.modelql.core +import kotlinx.coroutines.flow.map import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -23,9 +24,11 @@ class PrintStep(val prefix: String) : MonoTransformingStep() { return getProducer().getOutputSerializer(serializersModule) } - override fun transform(evaluationContext: QueryEvaluationContext, input: E): E { - println(prefix + input) - return input + override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { + return input.map { + println(prefix + input) + it + } } override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor = Descriptor(prefix) diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt index 715d1dbb8c..f587b373e3 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt @@ -20,6 +20,8 @@ import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEmpty import kotlinx.coroutines.flow.single import kotlinx.coroutines.flow.toList import kotlinx.serialization.KSerializer @@ -108,7 +110,6 @@ interface IUnboundQuery { suspend fun execute(evaluationContext: QueryEvaluationContext, input: IStepOutput): IStepOutput fun asFlow(evaluationContext: QueryEvaluationContext, input: StepFlow): StepFlow fun asFlow(evaluationContext: QueryEvaluationContext, input: IStepOutput): StepFlow = asFlow(evaluationContext, flowOf(input)) - fun asSequence(evaluationContext: QueryEvaluationContext, input: Sequence): Sequence fun requiresWriteAccess(): Boolean fun canBeEmpty(): Boolean @@ -129,7 +130,14 @@ interface IMonoUnboundQuery : IUnboundQuery { fun map(query: IFluxUnboundQuery): IFluxUnboundQuery fun map(body: (IMonoStep) -> IMonoStep): IMonoUnboundQuery = map(buildMonoQuery { body(it) }) fun flatMap(body: (IMonoStep) -> IFluxStep): IFluxUnboundQuery = map(buildFluxQuery { body(it) }) - fun evaluate(evaluationContext: QueryEvaluationContext, input: In): Optional +} + +suspend fun IMonoUnboundQuery.evaluate(evaluationContext: QueryEvaluationContext, input: In): Optional { + return SimpleQueryExecutor(input) + .createFlow(this) + .map { Optional.of(it.value) } + .onEmpty { Optional.empty() } + .single() } fun IMonoUnboundQuery.map(query: IUnboundQuery): IUnboundQuery { @@ -187,10 +195,6 @@ class MonoUnboundQuery( override fun getElementOutputSerializer(serializersModule: SerializersModule): KSerializer> { return outputStep.getOutputSerializer(serializersModule).upcast() } - - override fun evaluate(evaluationContext: QueryEvaluationContext, input: In): Optional { - return outputStep.evaluate(evaluationContext, input) - } } class FluxUnboundQuery( @@ -376,17 +380,6 @@ abstract class UnboundQuery( } } - override fun asSequence(evaluationContext: QueryEvaluationContext, input: Sequence): Sequence { - check(validated) { "call validate() first" } - require(unconsumedSideEffectSteps.isEmpty()) - require(!anyStepNeedsCoroutineScope) - return if (requiresSingularInput) { - input.flatMap { outputStep.createSequence(evaluationContext, sequenceOf(it)) } - } else { - outputStep.createSequence(evaluationContext, input) - } - } - private fun getUnconsumedSteps(): List> { return (getOwnSteps() - outputStep) .filterIsInstance>() @@ -489,14 +482,6 @@ class QueryInput : ProducingStep(), IMonoStep { internal var indirectConsumer: IConsumingStep? = null override fun toString(): String = "it<${owner.queryId}>" - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return queryInput as Sequence - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - return Optional.of(queryInput as E) - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { val c = checkNotNull(indirectConsumer) { "Input of query unknown: $this" } return (c.getProducers().single() as IProducingStep).getOutputSerializer(serializersModule) diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/QueryCallStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/QueryCallStep.kt index 8c34bc2b07..bd3206d9d1 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/QueryCallStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/QueryCallStep.kt @@ -43,11 +43,6 @@ class QueryCallStep(val queryRef: QueryReference): Sequence { - val query = getQuery() - return getProducer().createSequence(evaluationContext, queryInput).flatMap { query.asSequence(evaluationContext, sequenceOf(it)) } - } - override fun requiresSingularQueryInput(): Boolean = true override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/RegexPredicate.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/RegexPredicate.kt index ffd53a54a8..5ba841147b 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/RegexPredicate.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/RegexPredicate.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class RegexPredicate(val regex: Regex) : MonoTransformingStep() { +class RegexPredicate(val regex: Regex) : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: String?): Boolean { return input?.matches(regex) ?: false diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SharedStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SharedStep.kt index e7f05b65ee..5da05f49fb 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SharedStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SharedStep.kt @@ -23,10 +23,6 @@ class SharedStep() : MonoTransformingStep() { return getProducer().getOutputSerializer(serializersModule) } - override fun transform(evaluationContext: QueryEvaluationContext, input: E): E { - return input - } - override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { throw RuntimeException("The flow for shared steps is expected to be created by the query") } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SingleStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SingleStep.kt index a10c172fae..6d6017aad8 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SingleStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/SingleStep.kt @@ -25,10 +25,6 @@ class SingleStep() : AggregationStep() { return input.single() } - override fun aggregate(input: Sequence>): IStepOutput { - return input.single() - } - override fun toString(): String { return "${getProducer()}.single()" } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringContainsPredicate.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringContainsPredicate.kt index c3b7737ea6..0720c0fa9b 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringContainsPredicate.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringContainsPredicate.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class StringContainsPredicate(val substring: String) : MonoTransformingStep() { +class StringContainsPredicate(val substring: String) : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: String?): Boolean { return input?.contains(substring) ?: false diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToBooleanStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToBooleanStep.kt index e484606ca0..94e85ac562 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToBooleanStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToBooleanStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class StringToBooleanStep : MonoTransformingStep() { +class StringToBooleanStep : SimpleMonoTransformingStep() { override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToIntStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToIntStep.kt index d35841309d..006a0dc0c4 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToIntStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/StringToIntStep.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer -class StringToIntStep : MonoTransformingStep() { +class StringToIntStep : SimpleMonoTransformingStep() { override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ToStringStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ToStringStep.kt index 8f34ca9e69..fb516b9bcb 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ToStringStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ToStringStep.kt @@ -21,7 +21,7 @@ import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer import kotlin.jvm.JvmName -class ToStringStep : MonoTransformingStep() { +class ToStringStep : SimpleMonoTransformingStep() { override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().nullable.stepOutputSerializer(this) } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/TransformingStepWithParameter.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/TransformingStepWithParameter.kt index 141d887639..e4650a0d05 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/TransformingStepWithParameter.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/TransformingStepWithParameter.kt @@ -48,32 +48,6 @@ abstract class TransformingStepWithParameter): Sequence { - val parameterValue: IStepOutput? = if (hasStaticParameter) { - staticParameterValue - } else { - getParameterProducer().evaluate( - evaluationContext, - queryInput, - ).map { it.asStepOutput(null) }.getOrElse(null) - } - return getInputProducer().createSequence(evaluationContext, queryInput).map { transformElement(it.asStepOutput(null), parameterValue).value } - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - val input = getInputProducer().evaluate(evaluationContext, queryInput) - if (!input.isPresent()) return Optional.empty() - val parameter: IStepOutput? = getParameterProducer() - .evaluate(evaluationContext, queryInput) - .map { it.asStepOutput(null) } - .getOrElse(null) - return Optional.of(transformElement(input.get().asStepOutput(null), parameter).value) - } - - override fun transform(evaluationContext: QueryEvaluationContext, input: CommonIn): Out { - throw UnsupportedOperationException() - } - protected abstract fun transformElement(input: IStepOutput, parameter: IStepOutput?): IStepOutput override fun getProducers(): List> { diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WhenStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WhenStep.kt index 9643a66463..c3b26e05c6 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WhenStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WhenStep.kt @@ -75,10 +75,6 @@ class WhenStep( ) } - override fun transform(evaluationContext: QueryEvaluationContext, input: In): Out { - throw UnsupportedOperationException() - } - override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow { return input.flatMapConcat { for ((index, case) in cases.withIndex()) { @@ -91,24 +87,6 @@ class WhenStep( ?: emptyFlow().asStepFlow(this) } } - - override fun createTransformingSequence(evaluationContext: QueryEvaluationContext, input: Sequence): Sequence { - return input.flatMap { - for (case in cases) { - if (case.first.evaluate(evaluationContext, it).presentAndEqual(true)) { - return@flatMap case.second.asSequence(evaluationContext, sequenceOf(it)) - } - } - return@flatMap elseCase?.asSequence(evaluationContext, sequenceOf(it)) ?: emptySequence() - } - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional { - return createSequence(evaluationContext, sequenceOf(queryInput)) - .map { Optional.of(it) } - .ifEmpty { sequenceOf(Optional.empty()) } - .first() - } } @OptIn(ExperimentalTypeInference::class) diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WithIndexStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WithIndexStep.kt index 012406644a..899e804a20 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WithIndexStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/WithIndexStep.kt @@ -35,22 +35,10 @@ class WithIndexStep : MonoTransformingStep>() { ) } - override fun transform(evaluationContext: QueryEvaluationContext, input: E): IZip2Output { - throw UnsupportedOperationException() - } - override fun createFlow(input: StepFlow, context: IFlowInstantiationContext): StepFlow> { return input.withIndex().map { ZipStepOutput(listOf(it.value, it.index.asStepOutput(this))) } } - override fun createTransformingSequence(evaluationContext: QueryEvaluationContext, input: Sequence): Sequence> { - return input.mapIndexed { index, value -> ZipNOutput(listOf(value, index)) as IZip2Output } - } - - override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional> { - return getProducer().evaluate(evaluationContext, queryInput).map { transform(evaluationContext, it) } - } - override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { return Descriptor() } diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipElementAccessStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipElementAccessStep.kt index 94f20f5456..8de56342b8 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipElementAccessStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipElementAccessStep.kt @@ -13,6 +13,7 @@ */ package org.modelix.modelql.core +import kotlinx.coroutines.flow.map import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -25,15 +26,8 @@ class ZipElementAccessStep(val index: Int) : MonoTransformingStep>, - ): IStepOutput { - return (input as ZipStepOutput<*, *>).values[index] as IStepOutput - } - - override fun transform(evaluationContext: QueryEvaluationContext, input: IZipOutput): Out { - return input.values[index] as Out + override fun createFlow(input: StepFlow>, context: IFlowInstantiationContext): StepFlow { + return input.map { (it as ZipStepOutput<*, *>).values[index].upcast() } } override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { diff --git a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipStep.kt b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipStep.kt index d43cf0e52e..1213de1673 100644 --- a/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipStep.kt +++ b/modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipStep.kt @@ -131,10 +131,6 @@ open class ZipStep>() : ProducingStep // ZipNOutput(values.toList()) as Out // } } - - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return CombiningSequence(producers.map { it.createSequence(evaluationContext, queryInput) }.toTypedArray()).map { it.upcast() } - } } class AllowEmptyStep() : IdentityStep() { diff --git a/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt b/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt index 9ce3eaa310..8dc51da09b 100644 --- a/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt +++ b/modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt @@ -404,10 +404,6 @@ class ProductsTraversal() : FluxTransformingStep() { return input.flatMapConcat { it.value.products.asFlow() }.asStepFlow(this) } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput).flatMap { it.products } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> = serializersModule.serializer().stepOutputSerializer(this) override fun createDescriptor(context: QueryGraphDescriptorBuilder) = Descriptor() @@ -423,7 +419,7 @@ class ProductsTraversal() : FluxTransformingStep() { } } -class ProductTitleTraversal : MonoTransformingStep() { +class ProductTitleTraversal : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: Product): String { return input.title } @@ -443,7 +439,7 @@ class ProductTitleTraversal : MonoTransformingStep() { } } } -class ProductCategoryTraversal : MonoTransformingStep() { +class ProductCategoryTraversal : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: Product): String { return input.category } @@ -463,7 +459,7 @@ class ProductCategoryTraversal : MonoTransformingStep() { } } } -class ProductIdTraversal : MonoTransformingStep() { +class ProductIdTraversal : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: Product): Int { return input.id } @@ -487,10 +483,6 @@ class ProductImagesTraversal : FluxTransformingStep() { return input.flatMapConcat { it.value.images.asFlow() }.asStepFlow(this) } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput).flatMap { it.images } - } - override fun toString(): String { return "${getProducer()}.images" } diff --git a/modelql-core/src/jvmTest/kotlin/org/modelix/modelql/core/PerformanceTests.kt b/modelql-core/src/jvmTest/kotlin/org/modelix/modelql/core/PerformanceTests.kt index 1901fa0ecd..c7e2e45f6d 100644 --- a/modelql-core/src/jvmTest/kotlin/org/modelix/modelql/core/PerformanceTests.kt +++ b/modelql-core/src/jvmTest/kotlin/org/modelix/modelql/core/PerformanceTests.kt @@ -42,18 +42,6 @@ class PerformanceTests { }) } - @Test - fun sequenceBasedFilterPerformance() = runTest { - val query = buildMonoQuery { it.filter { it.equalTo(0) } } - val intRange = 1..100000 - - compareBenchmark(100, 20.0, { - query.asSequence(QueryEvaluationContext.EMPTY, intRange.asSequence()).count() - }, { - intRange.asSequence().filter { it == 0 }.count() - }) - } - @Test fun flowVsSequence() = runTest { compareBenchmark(100, 2.0, { diff --git a/modelql-typed/src/commonMain/kotlin/org/modelix/modelql/typed/TypedModelQL.kt b/modelql-typed/src/commonMain/kotlin/org/modelix/modelql/typed/TypedModelQL.kt index 33a995b371..03e4b99d13 100644 --- a/modelql-typed/src/commonMain/kotlin/org/modelix/modelql/typed/TypedModelQL.kt +++ b/modelql-typed/src/commonMain/kotlin/org/modelix/modelql/typed/TypedModelQL.kt @@ -44,7 +44,6 @@ import org.modelix.modelql.core.IProducingStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.IdentityStep import org.modelix.modelql.core.MonoTransformingStep -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -185,10 +184,6 @@ class TypedNodeStep(val nodeClass: KClass) : Mono return input.map { it.value.typed(nodeClass).asStepOutput(this) } } - override fun transform(evaluationContext: QueryEvaluationContext, input: INode): Typed { - return input.typed(nodeClass) - } - override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { return IdentityStep.IdentityStepDescriptor() } @@ -231,10 +226,6 @@ class UntypedNodeStep : MonoTransformingStep() { return input.map { it.value.unwrap().asStepOutput(this) } } - override fun transform(evaluationContext: QueryEvaluationContext, input: ITypedNode): INode { - return input.unwrap() - } - override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { return IdentityStep.IdentityStepDescriptor() } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AddNewChildNodeStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AddNewChildNodeStep.kt index e09f91f7ac..c8f1c51a66 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AddNewChildNodeStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AddNewChildNodeStep.kt @@ -26,16 +26,16 @@ import org.modelix.model.api.resolveChildLinkOrFallback import org.modelix.modelql.core.IMonoStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput -import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder +import org.modelix.modelql.core.SimpleMonoTransformingStep import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.connect import org.modelix.modelql.core.stepOutputSerializer class AddNewChildNodeStep(val role: String?, val index: Int, val concept: ConceptReference?) : - MonoTransformingStep() { + SimpleMonoTransformingStep() { override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllChildrenTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllChildrenTraversalStep.kt index 8fcd08106b..6865c28639 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllChildrenTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllChildrenTraversalStep.kt @@ -27,7 +27,6 @@ import org.modelix.modelql.core.IProducingStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -40,10 +39,6 @@ class AllChildrenTraversalStep() : FluxTransformingStep() { return input.flatMapConcat { it.value.getAllChildrenAsFlow() }.asStepFlow(this) } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput).flatMap { it.allChildren } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllReferencesTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllReferencesTraversalStep.kt index c99afc8ea9..67d8d08b59 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllReferencesTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/AllReferencesTraversalStep.kt @@ -29,7 +29,6 @@ import org.modelix.modelql.core.IProducingStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -42,10 +41,6 @@ class AllReferencesTraversalStep() : FluxTransformingStep(), IMono return input.flatMapConcat { it.value.getAllReferenceTargetsAsFlow().map { it.second } }.asStepFlow(this) } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput).flatMap { it.getAllReferenceTargets().map { it.second } } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ChildrenTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ChildrenTraversalStep.kt index 5855d8f16f..e62df391ed 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ChildrenTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ChildrenTraversalStep.kt @@ -28,7 +28,6 @@ import org.modelix.modelql.core.IProducingStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -41,10 +40,6 @@ class ChildrenTraversalStep(val role: String?) : FluxTransformingStep): Sequence { - return getProducer().createSequence(evaluationContext, queryInput).flatMap { it.getChildren(it.resolveChildLinkOrFallback(role)) } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceTraversalStep.kt index 9918555737..2eac422a0c 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceTraversalStep.kt @@ -25,14 +25,14 @@ import org.modelix.modelql.core.IFluxStep import org.modelix.modelql.core.IMonoStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput -import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder +import org.modelix.modelql.core.SimpleMonoTransformingStep import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.stepOutputSerializer -class ConceptReferenceTraversalStep() : MonoTransformingStep() { +class ConceptReferenceTraversalStep() : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: INode?): ConceptReference? { return input?.getConceptReference() as ConceptReference? } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceUIDTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceUIDTraversalStep.kt index 86bd95f085..50d7834179 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceUIDTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ConceptReferenceUIDTraversalStep.kt @@ -23,16 +23,16 @@ import org.modelix.modelql.core.IFluxStep import org.modelix.modelql.core.IMonoStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput -import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder +import org.modelix.modelql.core.SimpleMonoTransformingStep import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.mapIfNotNull import org.modelix.modelql.core.stepOutputSerializer import kotlin.jvm.JvmName -class ConceptReferenceUIDTraversalStep() : MonoTransformingStep() { +class ConceptReferenceUIDTraversalStep() : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: ConceptReference): String { return input.getUID() } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/DescendantsTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/DescendantsTraversalStep.kt index b8a28ed511..943396ee70 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/DescendantsTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/DescendantsTraversalStep.kt @@ -20,7 +20,6 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.serializer import org.modelix.model.api.INode -import org.modelix.model.api.getDescendants import org.modelix.modelql.core.FluxTransformingStep import org.modelix.modelql.core.IFlowInstantiationContext import org.modelix.modelql.core.IFluxStep @@ -28,7 +27,6 @@ import org.modelix.modelql.core.IProducingStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -41,10 +39,6 @@ class DescendantsTraversalStep(val includeSelf: Boolean) : FluxTransformingStep< return input.flatMapConcat { it.value.getDescendantsAsFlow(includeSelf) }.asStepFlow(this) } - override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence): Sequence { - return getProducer().createSequence(evaluationContext, queryInput).flatMap { it.getDescendants(includeSelf) } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceAsStringTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceAsStringTraversalStep.kt index 584bbe3822..31e4cce417 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceAsStringTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceAsStringTraversalStep.kt @@ -24,14 +24,14 @@ import org.modelix.modelql.core.IFluxStep import org.modelix.modelql.core.IMonoStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput -import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder +import org.modelix.modelql.core.SimpleMonoTransformingStep import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.stepOutputSerializer -class NodeReferenceAsStringTraversalStep() : MonoTransformingStep() { +class NodeReferenceAsStringTraversalStep() : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: INodeReference): String { return input.serialize() } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceTraversalStep.kt index 5ef48d6286..85e1387d9d 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/NodeReferenceTraversalStep.kt @@ -24,14 +24,14 @@ import org.modelix.modelql.core.IFluxStep import org.modelix.modelql.core.IMonoStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput -import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder +import org.modelix.modelql.core.SimpleMonoTransformingStep import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.stepOutputSerializer -class NodeReferenceTraversalStep() : MonoTransformingStep() { +class NodeReferenceTraversalStep() : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: INode): INodeReference { return input.reference } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/OfConceptStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/OfConceptStep.kt index a7998bef37..15911d0091 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/OfConceptStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/OfConceptStep.kt @@ -28,7 +28,6 @@ import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -45,16 +44,6 @@ class OfConceptStep(val conceptUIDs: Set) : MonoTransformingStep> } - override fun transform(evaluationContext: QueryEvaluationContext, input: INode?): INode { - require(input != null) { "node is null" } - require(conceptUIDs.contains(input.concept?.getUID())) { "$input is not an instance of $conceptUIDs" } - return input - } - - override fun createTransformingSequence(evaluationContext: QueryEvaluationContext, input: Sequence): Sequence { - return input.filterNotNull().filter { conceptUIDs.contains(it.concept?.getUID()) } - } - override fun createDescriptor(context: QueryGraphDescriptorBuilder) = Descriptor(conceptUIDs) @Serializable diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ParentTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ParentTraversalStep.kt index 6b19716633..982e529279 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ParentTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ParentTraversalStep.kt @@ -27,7 +27,6 @@ import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -44,14 +43,6 @@ class ParentTraversalStep() : MonoTransformingStep(), IMonoStep): Sequence { - return input.mapNotNull { it.parent } - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/PropertyTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/PropertyTraversalStep.kt index 0707ff7ca1..9730ae1c6f 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/PropertyTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/PropertyTraversalStep.kt @@ -24,14 +24,14 @@ import org.modelix.modelql.core.IFluxStep import org.modelix.modelql.core.IMonoStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput -import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder +import org.modelix.modelql.core.SimpleMonoTransformingStep import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.stepOutputSerializer -class PropertyTraversalStep(val role: String) : MonoTransformingStep(), IMonoStep { +class PropertyTraversalStep(val role: String) : SimpleMonoTransformingStep(), IMonoStep { override fun transform(evaluationContext: QueryEvaluationContext, input: INode): String? { return input.getPropertyValue(input.resolvePropertyOrFallback(role)) } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ReferenceTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ReferenceTraversalStep.kt index 8b4d2000c6..14390d55b7 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ReferenceTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ReferenceTraversalStep.kt @@ -28,7 +28,6 @@ import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -43,11 +42,6 @@ class ReferenceTraversalStep(val role: String) : MonoTransformingStep() { return input.map { it.value.remove() }.count().asStepOutput(this) } - override fun aggregate(input: Sequence>): IStepOutput { - return input.map { it.value.remove() }.count().asStepOutput(this) - } - override fun createDescriptor(context: QueryGraphDescriptorBuilder): StepDescriptor { return Descriptor() } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ResolveNodeStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ResolveNodeStep.kt index 7347bb78bf..c8873aa573 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ResolveNodeStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/ResolveNodeStep.kt @@ -29,7 +29,6 @@ import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext -import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.StepFlow @@ -43,10 +42,6 @@ class ResolveNodeStep() : MonoTransformingStep() { }.asStepFlow(this) } - override fun transform(evaluationContext: QueryEvaluationContext, input: INodeReference): INode { - return input.resolveInCurrentContext() ?: throw IllegalArgumentException("Node not found: $input") - } - override fun getOutputSerializer(serializersModule: SerializersModule): KSerializer> { return serializersModule.serializer().stepOutputSerializer(this) } diff --git a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/RoleInParentTraversalStep.kt b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/RoleInParentTraversalStep.kt index 3e411eae25..40c04c457c 100644 --- a/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/RoleInParentTraversalStep.kt +++ b/modelql-untyped/src/commonMain/kotlin/org/modelix/modelql/untyped/RoleInParentTraversalStep.kt @@ -24,14 +24,14 @@ import org.modelix.modelql.core.IFluxStep import org.modelix.modelql.core.IMonoStep import org.modelix.modelql.core.IStep import org.modelix.modelql.core.IStepOutput -import org.modelix.modelql.core.MonoTransformingStep import org.modelix.modelql.core.QueryDeserializationContext import org.modelix.modelql.core.QueryEvaluationContext import org.modelix.modelql.core.QueryGraphDescriptorBuilder +import org.modelix.modelql.core.SimpleMonoTransformingStep import org.modelix.modelql.core.StepDescriptor import org.modelix.modelql.core.stepOutputSerializer -class RoleInParentTraversalStep() : MonoTransformingStep() { +class RoleInParentTraversalStep() : SimpleMonoTransformingStep() { override fun transform(evaluationContext: QueryEvaluationContext, input: INode): String? { return input.roleInParent }