Mechanism for reducing rows ('COUNT()', 'SUM()' etc. from SQL)

This commit is contained in:
Andrew Golovashevich 2025-02-01 00:39:48 +03:00
parent dd18416f70
commit 13b6fa65d2
8 changed files with 150 additions and 71 deletions

View File

@ -1,4 +0,0 @@
package ru.landgrafhomyak.db.serdha0.api.misc
public interface BuiltinExpressionsProvider<OwnerQueryUserExtension: Any> {
}

View File

@ -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<ExpressionUserExtension : Any> {
public val userExtension: ExpressionUserExtension
public interface RuntimeExpressionInput<RT, DT : DatabaseType<RT>, ExpressionUserExtension : Any> : Column<RT, DT, ExpressionUserExtension>
public interface RuntimeExpressionOutput<RT, DT : DatabaseType<RT>, ExpressionUserExtension : Any> : QueryParam<RT, DT, ExpressionUserExtension>
public fun interface InputLinker<ExpressionUserExtension : Any, QueryUserExtension : Any> {
public fun link(linker: Scope<ExpressionUserExtension, QueryUserExtension>)
public interface Scope<ExpressionUserExtension : Any, QueryUserExtension : Any> {
public operator fun <RT, DT : DatabaseType<RT>> set(p: RuntimeExpressionInput<RT, DT, ExpressionUserExtension>, e: IntermediateColumn<RT, DT, QueryUserExtension>)
}
}
public fun interface OutputLinker<ExpressionUserExtension : Any, QueryUserExtension : Any> {
public fun link(linker: Scope<ExpressionUserExtension, QueryUserExtension>)
public interface Scope<ExpressionUserExtension : Any, QueryUserExtension : Any> {
public operator fun <RT, DT : DatabaseType<RT>> get(p: RuntimeExpressionOutput<RT, DT, ExpressionUserExtension>): IntermediateColumn<RT, DT, QueryUserExtension>
}
}
public interface Creator<ExpressionUserExtension : Any> {
public fun createExpression(creator: Scope<ExpressionUserExtension>): ExpressionUserExtension
public interface Scope<ExpressionUserExtension : Any> {
public fun <RT, DT : DatabaseType<RT>> input(name: String, type: DT): RuntimeExpressionInput<RT, DT, ExpressionUserExtension>
public fun <RT, DT : DatabaseType<RT>> output(name: String, type: DT): RuntimeExpressionOutput<RT, DT, ExpressionUserExtension>
public var action: Action<ExpressionUserExtension>
}
}
public interface Action<ExpressionUserExtension : Any> {
public fun calculate(input: OutputRow<ExpressionUserExtension>, output: InputRow<ExpressionUserExtension>)
}
}

View File

@ -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<mUE : Any> {
public val userExtension: mUE
public interface InputColumn<RT, DT : DatabaseType<RT>, mUE : Any> : Column<RT, DT, mUE>
public interface OutputColumn<RT, DT : DatabaseType<RT>, mUE : Any> : QueryParam<RT, DT, mUE>
public fun interface InputLinker<mUE : Any, qUE : Any> {
public fun link(linker: Scope<mUE, qUE>)
public interface Scope<mUE : Any, qUE : Any> {
public operator fun <RT, DT : DatabaseType<RT>> set(p: InputColumn<RT, DT, mUE>, e: IntermediateColumn<RT, DT, qUE>)
}
}
public fun interface OutputLinker<mUE : Any, qUE : Any, oUE : Any> {
public fun link(linker: Scope<mUE, qUE>): oUE
public interface Scope<ExpressionUserExtension : Any, QueryUserExtension : Any> {
public operator fun <RT, DT : DatabaseType<RT>> get(p: OutputColumn<RT, DT, ExpressionUserExtension>): IntermediateColumn<RT, DT, QueryUserExtension>
}
}
public interface Constructor<mUE : Any> {
public fun createMapper(context: Scope<mUE>): mUE
public interface Scope<mUE : Any> {
public fun <RT, DT : DatabaseType<RT>> input(name: String, type: DT): InputColumn<RT, DT, mUE>
public fun <RT, DT : DatabaseType<RT>> output(name: String, type: DT): OutputColumn<RT, DT, mUE>
public var action: Action<mUE>
}
}
public interface Action<mUE : Any> {
public fun calculate(ue: mUE, input: OutputRow<mUE>, output: InputRow<mUE>)
}
}

View File

@ -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<rUE : Any> {
public val userExtension: rUE
public interface IOColumn<RT, DT : DatabaseType<RT>, rUE : Any> : Column<RT, DT, rUE>, QueryParam<RT, DT, rUE>
public fun interface ReduceLinker<rUE : Any, qUE : Any, oUE : Any> {
public fun link(linker: Scope<rUE, qUE>): oUE
public interface Scope<rUE : Any, qUE : Any> {
public fun <RT, DT : DatabaseType<RT>> link(io: IOColumn<RT, DT, rUE>, src: IntermediateColumn<RT, DT, rUE>): IntermediateColumn<RT, DT, qUE>
}
}
public fun interface FoldLinker<rUE : Any, qUE : Any, oUE : Any> {
public fun link(linker: Scope<rUE, qUE>): oUE
public interface Scope<rUE : Any, qUE : Any> {
public fun <RT, DT : DatabaseType<RT>> link(io: IOColumn<RT, DT, rUE>, src: IntermediateColumn<RT, DT, rUE>, initial: RT): IntermediateColumn<RT, DT, qUE>
public fun <RT, DT : DatabaseType<RT>> link(io: IOColumn<RT, DT, rUE>, src: IntermediateColumn<RT, DT, rUE>, initial: QueryParam<RT, DT, qUE>): IntermediateColumn<RT, DT, qUE>
}
}
public interface Constructor<rUE : Any> {
public fun createReducer(creator: Scope<rUE>): rUE
public interface Scope<rUE : Any> {
public fun <RT, DT : DatabaseType<RT>> io(name: String, type: DT): IOColumn<RT, DT, rUE>
public var action: Action<rUE>
}
}
public interface Action<rUE : Any> {
public fun calculate(ue: rUE, acc: OutputRow<rUE>, row: OutputRow<rUE>, newAcc: InputRow<rUE>)
}
}

View File

@ -15,7 +15,7 @@ public interface QueryConstructor<qUE : Any> {
public fun <qUE : Any, tUE : Any, sUE : Any> insertFromSubquery(table: Table<tUE, *>, selector: _Selectable<sUE>, creator: InsertQuery.FromSubquery.Constructor<qUE, tUE, sUE>): InsertQuery.FromSubquery<qUE>
public fun <qUE : Any, tUE : Any> insertMultipleRows(table: Table<tUE, *>, creator: InsertQuery.MultipleRows.Constructor<qUE, tUE>): InsertQuery.MultipleRows<qUE>
public fun <qUE : Any, tUE : Any> select(table: _Selectable<tUE>, creator: SelectQuery.FromTable.Constructor<qUE, tUE>): SelectQuery.FromTable<qUE>
public fun <qUE : Any, tUE : Any> select(table: _Selectable<tUE>, creator: SelectQuery.Simple.Constructor<qUE, tUE>): SelectQuery.Simple<qUE>
public fun <qUE : Any, lUE : Any, rUE : Any> selectWithJoin(left: _Selectable<lUE>, right: _Selectable<rUE>, creator: SelectQuery.WithJoin.Constructor<qUE, lUE, rUE>): SelectQuery.WithJoin<qUE>
public fun <qUE : Any, tUE : Any> updateSingleRow(table: Table<tUE, *>, creator: UpdateQuery.SingleRow.Constructor<qUE, tUE>): UpdateQuery.SingleRow<qUE>

View File

@ -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<qUE : Any> : _Query<qUE> {
public fun <RT, DT : DatabaseType<RT>> queryParam(name: String, type: DT): QueryParam<RT, DT, qUE>
public fun <RT, DT : DatabaseType<RT>> paramAsColumn(param: QueryParam<RT, DT, qUE>): IntermediateColumn<RT, DT, qUE>
public val builtinExpressions: BuiltinExpressionsProvider<qUE>
public fun <eUE : Any> mapColumns(
expression: Expression<eUE>,
input: Expression.InputLinker<eUE, qUE>,
output: Expression.OutputLinker<eUE, qUE>
)
public fun <mUE : Any> createMapper(constructor: Mapper.Constructor<mUE>): Mapper<mUE>
public fun <mUE : Any, oUE : Any> mapColumns(
mapper: Mapper<mUE>,
input: Mapper.InputLinker<mUE, qUE>,
output: Mapper.OutputLinker<mUE, qUE, oUE>
): oUE
public val filters: FiltersScope<qUE>
public fun orderBy(order: Order, vararg column: IntermediateColumn<*, *, qUE>)
@ -51,6 +51,21 @@ public interface SelectQuery<qUE : Any> : _Query<qUE> {
public fun <RT, DT : DatabaseType<RT>> returnColumn(name: String, column: IntermediateColumn<RT, DT, qUE>): Column<RT, DT, qUE>
}
public interface Simple<qUE : Any> : SelectQuery<qUE>, _Query.Params2Table<qUE> {
public interface Constructor<qUE : Any, tUE : Any> {
public val source: _Selectable<tUE>
public fun createSelect(context: Scope<qUE, tUE>): qUE
public interface Scope<qUE : Any, tUE : Any> : _CommonSelectCreatorScope<qUE> {
public val sUExt: tUE
public val subqueryParams: InputRow.WithRedirect<tUE, qUE>
public fun <RT, DT : DatabaseType<RT>> selectColumnFromSubquery(param: Column<RT, DT, tUE>): IntermediateColumn<RT, DT, qUE>
}
}
}
public interface WithJoin<qUE : Any> : SelectQuery<qUE>, _Query.Params2Table<qUE> {
public interface Constructor<qUE : Any, lsqUE : Any, rsqUE : Any> : _CommonSelectCreatorScope<qUE> {
public val left: _Selectable<lsqUE>
@ -75,17 +90,48 @@ public interface SelectQuery<qUE : Any> : _Query<qUE> {
}
}
public interface FromTable<qUE : Any> : SelectQuery<qUE>, _Query.Params2Table<qUE> {
public interface Reduce<qUE : Any> : SelectQuery<qUE>, _Query.Params2Table<qUE> {
public interface Constructor<qUE : Any, tUE : Any> {
public val table: _Selectable<tUE>
public val source: _Selectable<tUE>
public fun createSelect(context: Scope<qUE, tUE>): qUE
public fun createSelectWithReduce(context: Scope<qUE, tUE>): qUE
public interface Scope<qUE : Any, tUE : Any> : _CommonSelectCreatorScope<qUE> {
public val tUExt: tUE
public val subqueryParams: InputRow.WithRedirect<tUE, qUE>
public val sUExt: tUE
public val sourceParams: InputRow.WithRedirect<tUE, qUE>
public fun <RT, DT : DatabaseType<RT>> selectColumnFromSubquery(param: Column<RT, DT, tUE>): IntermediateColumn<RT, DT, qUE>
public fun <rUE : Any> createReducer(constructor: Reducer.Constructor<rUE>): Reducer<rUE>
public fun <mUE : Any, oUE : Any> reduceRows(
reducer: Reducer<mUE>,
linker: Reducer.ReduceLinker<mUE, qUE, oUE>,
): oUE
public fun groupBy(vararg columns: IntermediateColumn<*, *, qUE>)
}
}
}
public interface Fold<qUE : Any> : SelectQuery<qUE>, _Query.Params2Table<qUE> {
public interface Constructor<qUE : Any, tUE : Any> {
public val source: _Selectable<tUE>
public fun createSelectWithFold(context: Scope<qUE, tUE>): qUE
public interface Scope<qUE : Any, tUE : Any> : _CommonSelectCreatorScope<qUE> {
public val sUExt: tUE
public val sourceParams: InputRow.WithRedirect<tUE, qUE>
public fun <RT, DT : DatabaseType<RT>> selectColumnFromSubquery(param: Column<RT, DT, tUE>): IntermediateColumn<RT, DT, qUE>
public fun <rUE : Any> createReducer(constructor: Reducer.Constructor<rUE>): Reducer<rUE>
public fun <mUE : Any, oUE : Any> foldRows(
reducer: Reducer<mUE>,
linker: Reducer.FoldLinker<mUE, qUE, oUE>,
): oUE
public fun groupBy(vararg columns: IntermediateColumn<*, *, qUE>)
}
}
}

View File

@ -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<tUE : Any> {
@Suppress("INAPPLICABLE_JVM_NAME")
@ -30,11 +29,10 @@ public interface CheckConstraint<tUE : Any> {
column: Column<RT, DT, rtUE>
): IntermediateColumn<RT, DT, rtUE>
public val builtinExpressions: BuiltinExpressionsProvider<cUE>
public fun <eUE : Any> mapColumns(
expression: Expression<eUE>,
input: Expression.InputLinker<eUE, cUE>,
output: Expression.OutputLinker<eUE, cUE>
expression: Mapper<eUE>,
input: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.InputLinker<eUE, cUE>,
output: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.OutputLinker<eUE, cUE>
)
}
}

View File

@ -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<tUE : Any> {
@Suppress("INAPPLICABLE_JVM_NAME")
@ -30,11 +29,10 @@ public interface DefaultConstraint<tUE : Any> {
column: Column<RT, DT, rtUE>
): IntermediateColumn<RT, DT, rtUE>
public val builtinExpressions: BuiltinExpressionsProvider<cUE>
public fun <eUE : Any> mapColumns(
expression: Expression<eUE>,
input: Expression.InputLinker<eUE, cUE>,
output: Expression.OutputLinker<eUE, cUE>
expression: Mapper<eUE>,
input: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.InputLinker<eUE, cUE>,
output: ru.landgrafhomyak.db.serdha0.api.misc.Expression.Map.OutputLinker<eUE, cUE>
)
}
}