From 13b6fa65d2c7f1f7cfc9d8b097bc6ffa026a64e6 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Sat, 1 Feb 2025 00:39:48 +0300 Subject: [PATCH] Mechanism for reducing rows ('COUNT()', 'SUM()' etc. from SQL) --- .../api/misc/BuiltinExpressionsProvider.kt | 4 -- .../db/serdha0/api/misc/Expression.kt | 41 ----------- .../db/serdha0/api/misc/Mapper.kt | 41 +++++++++++ .../db/serdha0/api/misc/Reducer.kt | 41 +++++++++++ .../serdha0/api/queries/QueryConstructor.kt | 2 +- .../db/serdha0/api/queries/SelectQuery.kt | 72 +++++++++++++++---- .../db/serdha0/api/table/CheckConstraint.kt | 10 ++- .../db/serdha0/api/table/DefaultConstraint.kt | 10 ++- 8 files changed, 150 insertions(+), 71 deletions(-) delete mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/BuiltinExpressionsProvider.kt delete mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Expression.kt create mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Mapper.kt create mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Reducer.kt diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/BuiltinExpressionsProvider.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/BuiltinExpressionsProvider.kt deleted file mode 100644 index d26b862..0000000 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/BuiltinExpressionsProvider.kt +++ /dev/null @@ -1,4 +0,0 @@ -package ru.landgrafhomyak.db.serdha0.api.misc - -public interface BuiltinExpressionsProvider { -} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Expression.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Expression.kt deleted file mode 100644 index 14c0ba5..0000000 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Expression.kt +++ /dev/null @@ -1,41 +0,0 @@ -package ru.landgrafhomyak.db.serdha0.api.misc - -import ru.landgrafhomyak.db.serdha0.api.runtime.InputRow -import ru.landgrafhomyak.db.serdha0.api.runtime.OutputRow - -public interface Expression { - public val userExtension: ExpressionUserExtension - - public interface RuntimeExpressionInput, ExpressionUserExtension : Any> : Column - public interface RuntimeExpressionOutput, ExpressionUserExtension : Any> : QueryParam - - public fun interface InputLinker { - public fun link(linker: Scope) - - public interface Scope { - public operator fun > set(p: RuntimeExpressionInput, e: IntermediateColumn) - } - } - - public fun interface OutputLinker { - public fun link(linker: Scope) - - public interface Scope { - public operator fun > get(p: RuntimeExpressionOutput): IntermediateColumn - } - } - - public interface Creator { - public fun createExpression(creator: Scope): ExpressionUserExtension - - public interface Scope { - public fun > input(name: String, type: DT): RuntimeExpressionInput - public fun > output(name: String, type: DT): RuntimeExpressionOutput - public var action: Action - } - } - - public interface Action { - public fun calculate(input: OutputRow, output: InputRow) - } -} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Mapper.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Mapper.kt new file mode 100644 index 0000000..643df09 --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Mapper.kt @@ -0,0 +1,41 @@ +package ru.landgrafhomyak.db.serdha0.api.misc + +import ru.landgrafhomyak.db.serdha0.api.runtime.InputRow +import ru.landgrafhomyak.db.serdha0.api.runtime.OutputRow + +public interface Mapper { + public val userExtension: mUE + + public interface InputColumn, mUE : Any> : Column + public interface OutputColumn, mUE : Any> : QueryParam + + public fun interface InputLinker { + public fun link(linker: Scope) + + public interface Scope { + public operator fun > set(p: InputColumn, e: IntermediateColumn) + } + } + + public fun interface OutputLinker { + public fun link(linker: Scope): oUE + + public interface Scope { + public operator fun > get(p: OutputColumn): IntermediateColumn + } + } + + public interface Constructor { + public fun createMapper(context: Scope): mUE + + public interface Scope { + public fun > input(name: String, type: DT): InputColumn + public fun > output(name: String, type: DT): OutputColumn + public var action: Action + } + } + + public interface Action { + public fun calculate(ue: mUE, input: OutputRow, output: InputRow) + } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Reducer.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Reducer.kt new file mode 100644 index 0000000..ff2a769 --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/misc/Reducer.kt @@ -0,0 +1,41 @@ +package ru.landgrafhomyak.db.serdha0.api.misc + +import ru.landgrafhomyak.db.serdha0.api.runtime.InputRow +import ru.landgrafhomyak.db.serdha0.api.runtime.OutputRow + +public interface Reducer { + public val userExtension: rUE + + public interface IOColumn, rUE : Any> : Column, QueryParam + + + public fun interface ReduceLinker { + public fun link(linker: Scope): oUE + + public interface Scope { + public fun > link(io: IOColumn, src: IntermediateColumn): IntermediateColumn + } + } + + public fun interface FoldLinker { + public fun link(linker: Scope): oUE + + public interface Scope { + public fun > link(io: IOColumn, src: IntermediateColumn, initial: RT): IntermediateColumn + public fun > link(io: IOColumn, src: IntermediateColumn, initial: QueryParam): IntermediateColumn + } + } + + public interface Constructor { + public fun createReducer(creator: Scope): rUE + + public interface Scope { + public fun > io(name: String, type: DT): IOColumn + public var action: Action + } + } + + public interface Action { + public fun calculate(ue: rUE, acc: OutputRow, row: OutputRow, newAcc: InputRow) + } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/QueryConstructor.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/QueryConstructor.kt index a723240..8a5926d 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/QueryConstructor.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/QueryConstructor.kt @@ -15,7 +15,7 @@ public interface QueryConstructor { public fun insertFromSubquery(table: Table, selector: _Selectable, creator: InsertQuery.FromSubquery.Constructor): InsertQuery.FromSubquery public fun insertMultipleRows(table: Table, creator: InsertQuery.MultipleRows.Constructor): InsertQuery.MultipleRows - public fun select(table: _Selectable, creator: SelectQuery.FromTable.Constructor): SelectQuery.FromTable + public fun select(table: _Selectable, creator: SelectQuery.Simple.Constructor): SelectQuery.Simple public fun selectWithJoin(left: _Selectable, right: _Selectable, creator: SelectQuery.WithJoin.Constructor): SelectQuery.WithJoin public fun updateSingleRow(table: Table, creator: UpdateQuery.SingleRow.Constructor): UpdateQuery.SingleRow diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/SelectQuery.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/SelectQuery.kt index ef90513..82fc682 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/SelectQuery.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/queries/SelectQuery.kt @@ -1,12 +1,12 @@ package ru.landgrafhomyak.db.serdha0.api.queries -import ru.landgrafhomyak.db.serdha0.api.misc.BuiltinExpressionsProvider import ru.landgrafhomyak.db.serdha0.api.misc.Column import ru.landgrafhomyak.db.serdha0.api.misc.IntermediateColumn import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType -import ru.landgrafhomyak.db.serdha0.api.misc.Expression +import ru.landgrafhomyak.db.serdha0.api.misc.Mapper import ru.landgrafhomyak.db.serdha0.api.misc.FiltersScope import ru.landgrafhomyak.db.serdha0.api.misc.QueryParam +import ru.landgrafhomyak.db.serdha0.api.misc.Reducer import ru.landgrafhomyak.db.serdha0.api.misc._Selectable import ru.landgrafhomyak.db.serdha0.api.runtime.InputRow @@ -34,12 +34,12 @@ public interface SelectQuery : _Query { public fun > queryParam(name: String, type: DT): QueryParam public fun > paramAsColumn(param: QueryParam): IntermediateColumn - public val builtinExpressions: BuiltinExpressionsProvider - public fun mapColumns( - expression: Expression, - input: Expression.InputLinker, - output: Expression.OutputLinker - ) + public fun createMapper(constructor: Mapper.Constructor): Mapper + public fun mapColumns( + mapper: Mapper, + input: Mapper.InputLinker, + output: Mapper.OutputLinker + ): oUE public val filters: FiltersScope public fun orderBy(order: Order, vararg column: IntermediateColumn<*, *, qUE>) @@ -51,6 +51,21 @@ public interface SelectQuery : _Query { public fun > returnColumn(name: String, column: IntermediateColumn): Column } + public interface Simple : SelectQuery, _Query.Params2Table { + public interface Constructor { + public val source: _Selectable + + public fun createSelect(context: Scope): qUE + + public interface Scope : _CommonSelectCreatorScope { + public val sUExt: tUE + public val subqueryParams: InputRow.WithRedirect + + public fun > selectColumnFromSubquery(param: Column): IntermediateColumn + } + } + } + public interface WithJoin : SelectQuery, _Query.Params2Table { public interface Constructor : _CommonSelectCreatorScope { public val left: _Selectable @@ -75,17 +90,48 @@ public interface SelectQuery : _Query { } } - public interface FromTable : SelectQuery, _Query.Params2Table { + public interface Reduce : SelectQuery, _Query.Params2Table { public interface Constructor { - public val table: _Selectable + public val source: _Selectable - public fun createSelect(context: Scope): qUE + public fun createSelectWithReduce(context: Scope): qUE public interface Scope : _CommonSelectCreatorScope { - public val tUExt: tUE - public val subqueryParams: InputRow.WithRedirect + public val sUExt: tUE + public val sourceParams: InputRow.WithRedirect public fun > selectColumnFromSubquery(param: Column): IntermediateColumn + + public fun createReducer(constructor: Reducer.Constructor): Reducer + public fun reduceRows( + reducer: Reducer, + linker: Reducer.ReduceLinker, + ): oUE + + public fun groupBy(vararg columns: IntermediateColumn<*, *, qUE>) + } + } + } + + public interface Fold : SelectQuery, _Query.Params2Table { + public interface Constructor { + public val source: _Selectable + + public fun createSelectWithFold(context: Scope): qUE + + public interface Scope : _CommonSelectCreatorScope { + public val sUExt: tUE + public val sourceParams: InputRow.WithRedirect + + public fun > selectColumnFromSubquery(param: Column): IntermediateColumn + + public fun createReducer(constructor: Reducer.Constructor): Reducer + public fun foldRows( + reducer: Reducer, + linker: Reducer.FoldLinker, + ): oUE + + public fun groupBy(vararg columns: IntermediateColumn<*, *, qUE>) } } } diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/CheckConstraint.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/CheckConstraint.kt index 35e918b..b52bbd6 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/CheckConstraint.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/CheckConstraint.kt @@ -1,11 +1,10 @@ package ru.landgrafhomyak.db.serdha0.api.table import kotlin.jvm.JvmName -import ru.landgrafhomyak.db.serdha0.api.misc.BuiltinExpressionsProvider import ru.landgrafhomyak.db.serdha0.api.misc.Column import ru.landgrafhomyak.db.serdha0.api.misc.IntermediateColumn import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType -import ru.landgrafhomyak.db.serdha0.api.misc.Expression +import ru.landgrafhomyak.db.serdha0.api.misc.Mapper public interface CheckConstraint { @Suppress("INAPPLICABLE_JVM_NAME") @@ -30,11 +29,10 @@ public interface CheckConstraint { column: Column ): IntermediateColumn - public val builtinExpressions: BuiltinExpressionsProvider public fun mapColumns( - expression: Expression, - input: Expression.InputLinker, - output: Expression.OutputLinker + expression: Mapper, + input: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.InputLinker, + output: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.OutputLinker ) } } diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/DefaultConstraint.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/DefaultConstraint.kt index 64533e8..55a8cb5 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/DefaultConstraint.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/api/table/DefaultConstraint.kt @@ -1,11 +1,10 @@ package ru.landgrafhomyak.db.serdha0.api.table import kotlin.jvm.JvmName -import ru.landgrafhomyak.db.serdha0.api.misc.BuiltinExpressionsProvider import ru.landgrafhomyak.db.serdha0.api.misc.Column import ru.landgrafhomyak.db.serdha0.api.misc.IntermediateColumn import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType -import ru.landgrafhomyak.db.serdha0.api.misc.Expression +import ru.landgrafhomyak.db.serdha0.api.misc.Mapper public interface DefaultConstraint { @Suppress("INAPPLICABLE_JVM_NAME") @@ -30,11 +29,10 @@ public interface DefaultConstraint { column: Column ): IntermediateColumn - public val builtinExpressions: BuiltinExpressionsProvider public fun mapColumns( - expression: Expression, - input: Expression.InputLinker, - output: Expression.OutputLinker + expression: Mapper, + input: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.InputLinker, + output: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.OutputLinker ) } }