Skip to content

Commit 77db3af

Browse files
committed
fix(modelql): CCE from SimpleStepOutput to MultiplexedOutput
1 parent 31a340e commit 77db3af

File tree

8 files changed

+47
-9
lines changed

8 files changed

+47
-9
lines changed

modelql-client/src/commonMain/kotlin/org/modelix/modelql/client/ModelQLNode.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ import org.modelix.modelql.core.IMonoUnboundQuery
3838
import org.modelix.modelql.core.IQueryExecutor
3939
import org.modelix.modelql.core.IUnboundQuery
4040
import org.modelix.modelql.core.IZip2Output
41-
import org.modelix.modelql.core.SimpleStepOutput
4241
import org.modelix.modelql.core.StepFlow
4342
import org.modelix.modelql.core.asMono
43+
import org.modelix.modelql.core.asStepOutput
4444
import org.modelix.modelql.core.filterNotNull
4545
import org.modelix.modelql.core.first
4646
import org.modelix.modelql.core.flatMap
@@ -79,7 +79,7 @@ abstract class ModelQLNode(val client: ModelQLClient) : INode, ISupportsModelQL,
7979
is IMonoUnboundQuery<*, *> -> {
8080
val castedQuery = query as IMonoUnboundQuery<INode, Out>
8181
val queryOnNode = IUnboundQuery.buildMono { replaceQueryRoot(it).map(castedQuery) }
82-
emit(SimpleStepOutput(client.runQuery(queryOnNode), null))
82+
emit(client.runQuery(queryOnNode).asStepOutput(null))
8383
}
8484
is IFluxUnboundQuery<*, *> -> {
8585
val castedQuery = query as IFluxUnboundQuery<INode, Out>

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/FirstElementStep.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class FirstElementStep<E>() : MonoTransformingStep<E, E>() {
2828

2929
override fun requiresSingularQueryInput(): Boolean = true
3030

31+
override fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput<E>): IStepOutput<E> {
32+
return input
33+
}
34+
3135
override fun transform(evaluationContext: QueryEvaluationContext, input: E): E {
3236
return input
3337
}

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IStep.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ abstract class MonoTransformingStep<In, Out> : TransformingStep<In, Out>(), IMon
183183
fun connectAndDowncast(producer: IFluxStep<In>): IFluxStep<Out> = also { producer.connect(it) }
184184

185185
override fun createFlow(input: StepFlow<In>, context: IFlowInstantiationContext): StepFlow<Out> {
186-
return input.map { transform(context.evaluationContext, it.value).asStepOutput(this) }
186+
return input.map { transform(context.evaluationContext, it) }
187187
}
188188

189189
override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence<Any?>): Sequence<Out> {
@@ -200,6 +200,11 @@ abstract class MonoTransformingStep<In, Out> : TransformingStep<In, Out>(), IMon
200200
override fun evaluate(evaluationContext: QueryEvaluationContext, queryInput: Any?): Optional<Out> {
201201
return getProducer().evaluate(evaluationContext, queryInput).map { transform(evaluationContext, it) }
202202
}
203+
204+
protected open fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput<In>): IStepOutput<Out> {
205+
return transform(evaluationContext, input.value).asStepOutput(this)
206+
}
207+
203208
abstract fun transform(evaluationContext: QueryEvaluationContext, input: In): Out
204209
}
205210

@@ -228,6 +233,10 @@ abstract class AggregationStep<In, Out> : MonoTransformingStep<In, Out>() {
228233
}
229234
}
230235

236+
override fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput<In>): IStepOutput<Out> {
237+
return aggregate(sequenceOf(input))
238+
}
239+
231240
override fun transform(evaluationContext: QueryEvaluationContext, input: In): Out {
232241
return aggregate(sequenceOf(input.asStepOutput(null))).value
233242
}

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IStepOutput.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ interface IStepOutput<out E> {
2727
val value: E
2828
}
2929

30+
fun <T> IStepOutput<*>.upcast(): IStepOutput<T> = this as IStepOutput<T>
31+
3032
typealias StepFlow<E> = Flow<IStepOutput<E>>
3133
val <T> Flow<IStepOutput<T>>.value: Flow<T> get() = map { it.value }
32-
fun <T> Flow<T>.asStepFlow(owner: IProducingStep<T>?): StepFlow<T> = map { SimpleStepOutput(it, owner) }
34+
fun <T> Flow<T>.asStepFlow(owner: IProducingStep<T>?): StepFlow<T> = map { it.asStepOutput(owner) }
3335

3436
class SimpleStepOutput<out E>(override val value: E, val owner: IProducingStep<E>?) : IStepOutput<E>
3537

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class MapIfNotNullStep<In : Any, Out>(val query: MonoUnboundQuery<In, Out>) : Mo
3838
}
3939
}
4040

41+
override fun transform(evaluationContext: QueryEvaluationContext, input: IStepOutput<In?>): IStepOutput<Out?> {
42+
throw UnsupportedOperationException("use MapIfNotNullStep.createFlow")
43+
}
44+
4145
override fun transform(evaluationContext: QueryEvaluationContext, input: In?): Out? {
4246
return input?.let { query.outputStep.evaluate(evaluationContext, it).getOrElse(null) }
4347
}

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/TransformingStepWithParameter.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.map
2020

2121
abstract class TransformingStepWithParameter<In : CommonIn, ParameterT : CommonIn, CommonIn, Out> : MonoTransformingStep<CommonIn, Out>() {
2222
private var hasStaticParameter: Boolean = false
23-
private var staticParameterValue: ParameterT? = null
23+
private var staticParameterValue: IStepOutput<ParameterT>? = null
2424

2525
private var targetProducer: IProducingStep<ParameterT>? = null
2626

@@ -32,25 +32,25 @@ abstract class TransformingStepWithParameter<In : CommonIn, ParameterT : CommonI
3232
require(!getParameterProducer().canBeMultiple()) { "only mono parameters are supported: ${getParameterProducer()}" }
3333
hasStaticParameter = getParameterProducer().canEvaluateStatically()
3434
if (hasStaticParameter) {
35-
staticParameterValue = getParameterProducer().evaluateStatically()
35+
staticParameterValue = getParameterProducer().evaluateStatically().asStepOutput(null)
3636
}
3737
}
3838

3939
override fun createFlow(input: StepFlow<CommonIn>, context: IFlowInstantiationContext): StepFlow<Out> {
4040
if (hasStaticParameter) {
41-
return input.map { transformElement(it as IStepOutput<In>, (staticParameterValue as ParameterT).asStepOutput(null)) }
41+
return input.map { transformElement(it.upcast<In>(), staticParameterValue as IStepOutput<ParameterT>) }
4242
} else {
4343
val parameterFlow = context.getOrCreateFlow<ParameterT>(getParameterProducer())
4444
return flow {
4545
val parameterValue = parameterFlow.firstOrNull()
46-
emitAll(input.map { transformElement(it as IStepOutput<In>, parameterValue) })
46+
emitAll(input.map { transformElement(it.upcast<In>(), parameterValue) })
4747
}
4848
}
4949
}
5050

5151
override fun createSequence(evaluationContext: QueryEvaluationContext, queryInput: Sequence<Any?>): Sequence<Out> {
5252
val parameterValue: IStepOutput<ParameterT>? = if (hasStaticParameter) {
53-
(staticParameterValue as ParameterT).asStepOutput(null)
53+
staticParameterValue
5454
} else {
5555
getParameterProducer().evaluate(
5656
evaluationContext,

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/ZipElementAccessStep.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ class ZipElementAccessStep<Out>(val index: Int) : MonoTransformingStep<IZipOutpu
2525
return zipSerializer.elementSerializers[index]
2626
}
2727

28+
override fun transform(
29+
evaluationContext: QueryEvaluationContext,
30+
input: IStepOutput<IZipOutput<Any?>>,
31+
): IStepOutput<Out> {
32+
return (input as ZipStepOutput<*, *>).values[index] as IStepOutput<Out>
33+
}
34+
2835
override fun transform(evaluationContext: QueryEvaluationContext, input: IZipOutput<Any?>): Out {
2936
return input.values[index] as Out
3037
}

modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,18 @@ class ModelQLTest {
295295
assertEquals(testDatabase.products, result)
296296
}
297297

298+
@Test
299+
fun zipElementAccess() = runTestWithTimeout {
300+
val result = remoteProductDatabaseQuery { db ->
301+
db.products.flatMap { enum ->
302+
enum.images.allowEmpty().zip(enum.title.firstOrNull()).map { it ->
303+
it.first.zip(it.second).mapLocal { "" }
304+
}
305+
}.toList()
306+
}
307+
assertEquals(testDatabase.products.flatMap { it.images }.map { "" }, result)
308+
}
309+
298310
// @Test
299311
// fun testIndexLookup() {
300312
// val result = remoteProductDatabaseQuery { db ->

0 commit comments

Comments
 (0)