DELETE, fixes, auto-transactions

This commit is contained in:
Andrew Golovashevich 2024-11-28 21:33:42 +03:00
parent a2f2bc497c
commit ae1430b696
14 changed files with 503 additions and 27 deletions

View File

@ -2,4 +2,9 @@ package ru.landgrafhomyak.serdha.api.v0
import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType
public interface Expression<RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>, OwnerBuilderUserWrapper : Any> public interface Expression<RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>, OwnerBuilderUserWrapper : Any> {
public class Equals<RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>, OwnerBuilderUserWrapper : Any>(
public val left: Expression<RuntimeType, DatabaseType, OwnerBuilderUserWrapper>,
public val right: Expression<RuntimeType, DatabaseType, OwnerBuilderUserWrapper>,
) : Expression<Boolean, ColumnType.BOOLEAN, OwnerBuilderUserWrapper>
}

View File

@ -1,7 +1,11 @@
package ru.landgrafhomyak.serdha.api.v0.ddl package ru.landgrafhomyak.serdha.api.v0.ddl
import ru.landgrafhomyak.serdha.api.v0.runtime.SynchronizedDatabase
public interface Module<W : Any> { public interface Module<W : Any> {
public val wrapper: W public val wrapper: W
public val versionKey: String public val versionKey: String
public val ownerDatabase: SynchronizedDatabase<*>
} }

View File

@ -1,5 +1,7 @@
package ru.landgrafhomyak.serdha.api.v0.ddl package ru.landgrafhomyak.serdha.api.v0.ddl
import ru.landgrafhomyak.serdha.api.v0.dml.Delete
import ru.landgrafhomyak.serdha.api.v0.dml.DeleteCreator
import ru.landgrafhomyak.serdha.api.v0.dml.Insert import ru.landgrafhomyak.serdha.api.v0.dml.Insert
import ru.landgrafhomyak.serdha.api.v0.dml.InsertCreator import ru.landgrafhomyak.serdha.api.v0.dml.InsertCreator
import ru.landgrafhomyak.serdha.api.v0.dml.Select import ru.landgrafhomyak.serdha.api.v0.dml.Select
@ -8,15 +10,19 @@ import ru.landgrafhomyak.serdha.api.v0.dml.Update
import ru.landgrafhomyak.serdha.api.v0.dml.UpdateCreator import ru.landgrafhomyak.serdha.api.v0.dml.UpdateCreator
public interface ModuleModifyingRound { public interface ModuleModifyingRound {
public fun <TableUserWrapper : Any> createTable( public fun interface CreateTable<TableUserWrapper : Any> {
namespace: Namespace, public fun createTable(creator: TableCreator<TableUserWrapper>): TableUserWrapper
name: String, }
initializer: (TableCreator<TableUserWrapper>) -> TableUserWrapper
): Table<TableUserWrapper, Nothing> public fun <TableUserWrapper : Any> createTable(namespace: Namespace, name: String, initializer: CreateTable<TableUserWrapper>): Table<TableUserWrapper, Nothing>
public fun interface UpdateTable<TableNewUserWrapper : Any, TableOldUserWrapper : Any> {
public fun updateTable(oldTable: Table<TableOldUserWrapper, *>, updater: TableUpdater<TableNewUserWrapper, TableOldUserWrapper>): TableNewUserWrapper
}
public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateTable( public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateTable(
oldTable: Table<TableOldUserWrapper, *>, oldTable: Table<TableOldUserWrapper, *>,
initializer: (TableUpdater<TableNewUserWrapper, TableOldUserWrapper>) -> TableNewUserWrapper initializer: UpdateTable<TableNewUserWrapper, TableOldUserWrapper>
): Table<TableNewUserWrapper, TableOldUserWrapper> ): Table<TableNewUserWrapper, TableOldUserWrapper>
public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> renameTable( public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> renameTable(
@ -33,19 +39,39 @@ public interface ModuleModifyingRound {
public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateAndRenameTable( public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateAndRenameTable(
table: Table<TableOldUserWrapper, *>, table: Table<TableOldUserWrapper, *>,
newName: String, newName: String,
initializer: (TableUpdater<TableNewUserWrapper, TableOldUserWrapper>) -> TableNewUserWrapper initializer: UpdateTable<TableNewUserWrapper, TableOldUserWrapper>
): Table<TableNewUserWrapper, TableOldUserWrapper> ): Table<TableNewUserWrapper, TableOldUserWrapper>
public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateAndRenameTable( public fun <TableNewUserWrapper : Any, TableOldUserWrapper : Any> updateAndRenameTable(
table: Table<TableNewUserWrapper, TableOldUserWrapper>, table: Table<TableNewUserWrapper, TableOldUserWrapper>,
newNamespace: Namespace, newNamespace: Namespace,
newName: String, newName: String,
initializer: (TableUpdater<TableNewUserWrapper, TableOldUserWrapper>) -> TableNewUserWrapper initializer: UpdateTable<TableNewUserWrapper, TableOldUserWrapper>
): Table<TableNewUserWrapper, TableOldUserWrapper> ): Table<TableNewUserWrapper, TableOldUserWrapper>
public fun <QueryUserWrapper : Any> createSelect(initializer: (SelectCreator<QueryUserWrapper>) -> QueryUserWrapper): Select<QueryUserWrapper> public fun interface CreateSelect<QueryUserWrapper : Any> {
public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createInsert(table: Table<TableUserWrapper, *>, initializer: (InsertCreator<TableUserWrapper, QueryUserWrapper>) -> QueryUserWrapper): Insert<QueryUserWrapper> public fun createSelect(creator: SelectCreator<QueryUserWrapper>): QueryUserWrapper
public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createUpdate(table: Table<TableUserWrapper, *>, initializer: (UpdateCreator<TableUserWrapper, QueryUserWrapper>) -> QueryUserWrapper): Update<QueryUserWrapper> }
public fun <QueryUserWrapper : Any> createSelect(initializer: CreateSelect<QueryUserWrapper>): Select<QueryUserWrapper>
public fun interface CreateInsert<TableUserWrapper : Any, QueryUserWrapper : Any> {
public fun createInsert(table: Table<TableUserWrapper, *>, creator: InsertCreator<TableUserWrapper, QueryUserWrapper>): QueryUserWrapper
}
public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createInsert(table: Table<TableUserWrapper, *>, initializer: CreateInsert<TableUserWrapper, QueryUserWrapper>): Insert<QueryUserWrapper>
public fun interface CreateUpdate<TableUserWrapper : Any, QueryUserWrapper : Any> {
public fun createUpdate(table: Table<TableUserWrapper, *>, creator: UpdateCreator<TableUserWrapper, QueryUserWrapper>): QueryUserWrapper
}
public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createUpdate(table: Table<TableUserWrapper, *>, initializer: CreateUpdate<TableUserWrapper, QueryUserWrapper>): Update<QueryUserWrapper>
public fun interface CreateDelete<TableUserWrapper : Any, QueryUserWrapper : Any> {
public fun createDelete(table: Table<TableUserWrapper, *>, creator: DeleteCreator<TableUserWrapper, QueryUserWrapper>): QueryUserWrapper
}
public fun <TableUserWrapper : Any, QueryUserWrapper : Any> createDelete(table: Table<TableUserWrapper, *>, initializer: CreateDelete<TableUserWrapper, QueryUserWrapper>): Delete<QueryUserWrapper>
public fun <W : Any> substituteModule(rootNs: Namespace, template: ModuleTemplate<W>): Module<W> public fun <W : Any> substituteModule(rootNs: Namespace, template: ModuleTemplate<W>): Module<W>
public fun <W : Any> upgradeModule(oldModule: Module<*>, rootNs: Namespace, template: ModuleTemplate<W>): Module<W> public fun <W : Any> upgradeModule(oldModule: Module<*>, rootNs: Namespace, template: ModuleTemplate<W>): Module<W>

View File

@ -25,9 +25,15 @@ public interface TableCreator<TableUserWrapper : Any> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> nullableColumn(name: String, type: DatabaseType): Column<RuntimeType?, DatabaseType, TableUserWrapper> public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> nullableColumn(name: String, type: DatabaseType): Column<RuntimeType?, DatabaseType, TableUserWrapper>
public fun index(name: String, vararg columns: Column<*, *, TableUserWrapper>): Index<TableUserWrapper> public fun index(name: String, vararg columns: Column<*, *, TableUserWrapper>): Index<TableUserWrapper>
// todo not-null column uniqueness
public fun unique(name: String, distinctNulls: Boolean, vararg columns: Column<*, *, TableUserWrapper>): UniqueConstraint<TableUserWrapper> public fun unique(name: String, distinctNulls: Boolean, vararg columns: Column<*, *, TableUserWrapper>): UniqueConstraint<TableUserWrapper>
public fun check(name: String, constraint: Expression<Boolean, ColumnType.BOOLEAN, TableUserWrapper>): CheckConstraint<TableUserWrapper> public fun check(name: String, constraint: Expression<Boolean, ColumnType.BOOLEAN, TableUserWrapper>): CheckConstraint<TableUserWrapper>
public fun rowIdColumn(): Column<RowId<TableUserWrapper>, ColumnType<RowId<TableUserWrapper>>, TableUserWrapper>
public fun rowIdUniqueConstraint(): UniqueConstraint<TableUserWrapper>
public fun <TargetTableUserWrapper : Any, ColumnType1 : ColumnType<*>> foreignKey( public fun <TargetTableUserWrapper : Any, ColumnType1 : ColumnType<*>> foreignKey(
fromColumn: Column<*, ColumnType1, TableUserWrapper>, fromColumn: Column<*, ColumnType1, TableUserWrapper>,
toTable: Table<TargetTableUserWrapper, *>, toTable: Table<TargetTableUserWrapper, *>,

View File

@ -0,0 +1,5 @@
package ru.landgrafhomyak.serdha.api.v0.dml
public interface Delete<QueryUserWrapper : Any> {
public val userWrapper: QueryUserWrapper
}

View File

@ -0,0 +1,16 @@
package ru.landgrafhomyak.serdha.api.v0.dml
import ru.landgrafhomyak.serdha.api.v0.Expression
import ru.landgrafhomyak.serdha.api.v0.ddl.Column
import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType
import ru.landgrafhomyak.serdha.api.v0.ddl.Table
public interface DeleteCreator<TargetTableUserWrapper : Any, QueryUserWrapper : Any> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> selectColumn(column: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>): SelectedColumn<RuntimeType, DatabaseType, TargetTableUserWrapper, QueryUserWrapper>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> param(name: String, type: DatabaseType): InputParam<RuntimeType, DatabaseType, QueryUserWrapper>
public fun where(expression: Expression<Boolean, ColumnType.BOOLEAN, QueryUserWrapper>)
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> returning(e: Expression<RuntimeType, DatabaseType, QueryUserWrapper>): Column<RuntimeType, DatabaseType, QueryUserWrapper>
}

View File

@ -6,7 +6,7 @@ import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType
import ru.landgrafhomyak.serdha.api.v0.ddl.UniqueConstraint import ru.landgrafhomyak.serdha.api.v0.ddl.UniqueConstraint
public interface InsertCreator<TargetTableUserWrapper : Any, QueryUserWrapper : Any> { public interface InsertCreator<TargetTableUserWrapper : Any, QueryUserWrapper : Any> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> insert(c: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>): InputParam<RuntimeType, DatabaseType, QueryUserWrapper> public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> insertTo(c: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>): InputParam<RuntimeType, DatabaseType, QueryUserWrapper>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> selectColumn(c: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>): SelectedColumn<RuntimeType, DatabaseType, TargetTableUserWrapper, QueryUserWrapper> public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> selectColumn(c: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>): SelectedColumn<RuntimeType, DatabaseType, TargetTableUserWrapper, QueryUserWrapper>

View File

@ -8,6 +8,7 @@ import ru.landgrafhomyak.serdha.api.v0.ddl.Table
public interface SelectCreator<QueryUserWrapper : Any> { public interface SelectCreator<QueryUserWrapper : Any> {
public fun <SelectedTableUserWrapper : Any> selectTable(t: Table<SelectedTableUserWrapper, *>): SelectedTable<SelectedTableUserWrapper, QueryUserWrapper> public fun <SelectedTableUserWrapper : Any> selectTable(t: Table<SelectedTableUserWrapper, *>): SelectedTable<SelectedTableUserWrapper, QueryUserWrapper>
public fun <SelectedQueryUserWrapper : Any> selectQuery(t: Select<SelectedQueryUserWrapper>): SelectedTable<SelectedQueryUserWrapper, QueryUserWrapper> public fun <SelectedQueryUserWrapper : Any> selectQuery(t: Select<SelectedQueryUserWrapper>): SelectedTable<SelectedQueryUserWrapper, QueryUserWrapper>
public fun where(expression: Expression<Boolean, ColumnType.BOOLEAN, QueryUserWrapper>) public fun where(expression: Expression<Boolean, ColumnType.BOOLEAN, QueryUserWrapper>)
// default false // default false
@ -18,4 +19,6 @@ public interface SelectCreator<QueryUserWrapper : Any> {
public fun orderBy(vararg columns: Column<*, *, QueryUserWrapper>) public fun orderBy(vararg columns: Column<*, *, QueryUserWrapper>)
public fun groupBy(vararg columns: Column<*, *, QueryUserWrapper>) public fun groupBy(vararg columns: Column<*, *, QueryUserWrapper>)
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> param(name: String, type: DatabaseType): InputParam<RuntimeType, DatabaseType, QueryUserWrapper>
} }

View File

@ -3,6 +3,6 @@ package ru.landgrafhomyak.serdha.api.v0.dml
import ru.landgrafhomyak.serdha.api.v0.Expression import ru.landgrafhomyak.serdha.api.v0.Expression
import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType
public interface SelectedColumn<RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>, OwnerTypeUserWrapper : Any, QueryUserWrapper : Any> : Expression<RuntimeType, DatabaseType, QueryUserWrapper> { public interface SelectedColumn<RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>, OwnerTableUserWrapper : Any, QueryUserWrapper : Any> : Expression<RuntimeType, DatabaseType, QueryUserWrapper> {
} }

View File

@ -3,9 +3,11 @@ package ru.landgrafhomyak.serdha.api.v0.dml
import ru.landgrafhomyak.serdha.api.v0.Expression import ru.landgrafhomyak.serdha.api.v0.Expression
import ru.landgrafhomyak.serdha.api.v0.ddl.Column import ru.landgrafhomyak.serdha.api.v0.ddl.Column
import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType import ru.landgrafhomyak.serdha.api.v0.ddl.ColumnType
import ru.landgrafhomyak.serdha.api.v0.ddl.Table
public interface UpdateCreator<TargetTableUserWrapper : Any, QueryUserWrapper : Any> { public interface UpdateCreator<TargetTableUserWrapper : Any, QueryUserWrapper : Any> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> selectColumn(c: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>): SelectedColumn<RuntimeType, DatabaseType, TargetTableUserWrapper, QueryUserWrapper> public fun <SelectedTableUserWrapper : Any> selectTable(t: Table<SelectedTableUserWrapper, *>): SelectedTable<SelectedTableUserWrapper, QueryUserWrapper>
public fun <SelectedQueryUserWrapper : Any> selectQuery(t: Select<SelectedQueryUserWrapper>): SelectedTable<SelectedQueryUserWrapper, QueryUserWrapper>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> updateColumn(c: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>, e: Expression<RuntimeType, DatabaseType, QueryUserWrapper>) public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> updateColumn(c: Column<RuntimeType, DatabaseType, TargetTableUserWrapper>, e: Expression<RuntimeType, DatabaseType, QueryUserWrapper>)

View File

@ -1,18 +1,19 @@
package ru.landgrafhomyak.serdha.api.v0.runtime package ru.landgrafhomyak.serdha.api.v0.runtime
import ru.landgrafhomyak.serdha.api.v0.ddl.Column import ru.landgrafhomyak.serdha.api.v0.ddl.Column
import ru.landgrafhomyak.serdha.api.v0.dml.InputParam
public interface ParametersSetter<QueryUserWrapper : Any> { public interface ParametersSetter<QueryUserWrapper : Any> {
public operator fun <RuntimeType> set(c: Column<RuntimeType, *, QueryUserWrapper>, value: RuntimeType) public operator fun <RuntimeType> set(c: InputParam<RuntimeType, *, QueryUserWrapper>, value: RuntimeType)
public operator fun set(c: Column<Byte, *, QueryUserWrapper>, value: Byte): Unit = this.set<Byte>(c, value) public operator fun set(c: InputParam<Byte, *, QueryUserWrapper>, value: Byte): Unit = this.set<Byte>(c, value)
public operator fun set(c: Column<UByte, *, QueryUserWrapper>, value: UByte): Unit = this.set<UByte>(c, value) public operator fun set(c: InputParam<UByte, *, QueryUserWrapper>, value: UByte): Unit = this.set<UByte>(c, value)
public operator fun set(c: Column<Short, *, QueryUserWrapper>, value: Short): Unit = this.set<Short>(c, value) public operator fun set(c: InputParam<Short, *, QueryUserWrapper>, value: Short): Unit = this.set<Short>(c, value)
public operator fun set(c: Column<UShort, *, QueryUserWrapper>, value: UShort): Unit = this.set<UShort>(c, value) public operator fun set(c: InputParam<UShort, *, QueryUserWrapper>, value: UShort): Unit = this.set<UShort>(c, value)
public operator fun set(c: Column<Int, *, QueryUserWrapper>, value: Int): Unit = this.set<Int>(c, value) public operator fun set(c: InputParam<Int, *, QueryUserWrapper>, value: Int): Unit = this.set<Int>(c, value)
public operator fun set(c: Column<UInt, *, QueryUserWrapper>, value: UInt): Unit = this.set<UInt>(c, value) public operator fun set(c: InputParam<UInt, *, QueryUserWrapper>, value: UInt): Unit = this.set<UInt>(c, value)
public operator fun set(c: Column<Long, *, QueryUserWrapper>, value: Long): Unit = this.set<Long>(c, value) public operator fun set(c: InputParam<Long, *, QueryUserWrapper>, value: Long): Unit = this.set<Long>(c, value)
public operator fun set(c: Column<ULong, *, QueryUserWrapper>, value: ULong): Unit = this.set<ULong>(c, value) public operator fun set(c: InputParam<ULong, *, QueryUserWrapper>, value: ULong): Unit = this.set<ULong>(c, value)
public operator fun set(c: Column<Char, *, QueryUserWrapper>, value: Char): Unit = this.set<Char>(c, value) public operator fun set(c: InputParam<Char, *, QueryUserWrapper>, value: Char): Unit = this.set<Char>(c, value)
public operator fun set(c: Column<Boolean, *, QueryUserWrapper>, value: Boolean): Unit = this.set<Boolean>(c, value) public operator fun set(c: InputParam<Boolean, *, QueryUserWrapper>, value: Boolean): Unit = this.set<Boolean>(c, value)
} }

View File

@ -2,12 +2,38 @@ package ru.landgrafhomyak.serdha.api.v0.runtime
import ru.landgrafhomyak.serdha.api.v0.LowLevelApi import ru.landgrafhomyak.serdha.api.v0.LowLevelApi
import ru.landgrafhomyak.serdha.api.v0.ddl.Module import ru.landgrafhomyak.serdha.api.v0.ddl.Module
import ru.landgrafhomyak.serdha.api.v0.dml.Delete
import ru.landgrafhomyak.serdha.api.v0.dml.Insert
import ru.landgrafhomyak.serdha.api.v0.dml.Select
import ru.landgrafhomyak.serdha.api.v0.dml.Update
public interface SynchronizedDatabase<W : Any> : Module<W> { public interface SynchronizedDatabase<W : Any> : Module<W> {
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun _startTransaction(): Transaction public suspend fun _startTransaction(): Transaction
@Suppress("FunctionName")
@LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedSelect(query: Select<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>>
@Suppress("FunctionName")
@LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedInsert(query: Insert<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?>
@Suppress("FunctionName")
@LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedUpdate(query: Update<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?>
@Suppress("FunctionName")
@LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedDelete(query: Delete<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?>
public interface AtomicScript<C, A, R> {
public suspend fun executeTransaction(transaction: Transaction, context: C, args: A): R
}
public suspend fun <C, A, R> transaction(script: AtomicScript<C, A, R>, context: C, args: A): R
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun _close() public suspend fun _close()

View File

@ -1,6 +1,7 @@
package ru.landgrafhomyak.serdha.api.v0.runtime package ru.landgrafhomyak.serdha.api.v0.runtime
import ru.landgrafhomyak.serdha.api.v0.LowLevelApi import ru.landgrafhomyak.serdha.api.v0.LowLevelApi
import ru.landgrafhomyak.serdha.api.v0.dml.Delete
import ru.landgrafhomyak.serdha.api.v0.dml.Insert import ru.landgrafhomyak.serdha.api.v0.dml.Insert
import ru.landgrafhomyak.serdha.api.v0.dml.Select import ru.landgrafhomyak.serdha.api.v0.dml.Select
import ru.landgrafhomyak.serdha.api.v0.dml.Update import ru.landgrafhomyak.serdha.api.v0.dml.Update
@ -18,6 +19,10 @@ public interface Transaction {
@LowLevelApi @LowLevelApi
public fun <QueryUserWrapper : Any> _update(compiledQuery: Update<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?> public fun <QueryUserWrapper : Any> _update(compiledQuery: Update<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?>
@Suppress("FunctionName")
@LowLevelApi
public fun <QueryUserWrapper : Any> _delete(compiledQuery: Delete<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?>
public suspend fun rollback() public suspend fun rollback()
public suspend fun commit() public suspend fun commit()

View File

@ -6,6 +6,7 @@ import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
import ru.landgrafhomyak.serdha.api.v0.LowLevelApi import ru.landgrafhomyak.serdha.api.v0.LowLevelApi
import ru.landgrafhomyak.serdha.api.v0.dml.Delete
import ru.landgrafhomyak.serdha.api.v0.dml.Insert import ru.landgrafhomyak.serdha.api.v0.dml.Insert
import ru.landgrafhomyak.serdha.api.v0.dml.Select import ru.landgrafhomyak.serdha.api.v0.dml.Select
import ru.landgrafhomyak.serdha.api.v0.dml.Update import ru.landgrafhomyak.serdha.api.v0.dml.Update
@ -166,6 +167,26 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasMap(
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedSelectSingleOrNull(
compiledQuery: Select<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.AT_MOST_ONCE)
}
return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedSelect(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectSingleOrNull( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectSingleOrNull(
compiledQuery: Select<QueryUserWrapper>, compiledQuery: Select<QueryUserWrapper>,
@ -186,6 +207,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectSingleOr
) )
} }
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.selectThenIterate( public suspend inline fun <QueryUserWrapper : Any> Transaction.selectThenIterate(
compiledQuery: Select<QueryUserWrapper>, compiledQuery: Select<QueryUserWrapper>,
@ -206,6 +228,26 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.selectThenIterate
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedSelectThenIterate(
compiledQuery: Select<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
_wrapWithLambdasIterate(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedSelect(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectThenMap( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectThenMap(
compiledQuery: Select<QueryUserWrapper>, compiledQuery: Select<QueryUserWrapper>,
@ -227,6 +269,27 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.selectThenMap(
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedSelectThenMap(
compiledQuery: Select<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
return _wrapWithLambdasMap(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedSelect(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.insert( public suspend inline fun <QueryUserWrapper : Any> Transaction.insert(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert<QueryUserWrapper>,
@ -245,6 +308,24 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.insert(
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedInsert(
compiledQuery: Insert<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
}
_wrapWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedInsert(compiledQuery) },
parameters = parameters,
hasReturning = false,
returning = {},
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningSingleOrNull( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningSingleOrNull(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert<QueryUserWrapper>,
@ -265,6 +346,26 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturnin
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedInsertReturningSingleOrNull(
compiledQuery: Insert<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.AT_MOST_ONCE)
}
return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedInsert(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.insertReturningIterate( public suspend inline fun <QueryUserWrapper : Any> Transaction.insertReturningIterate(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert<QueryUserWrapper>,
@ -285,6 +386,26 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.insertReturningIt
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedInsertReturningIterate(
compiledQuery: Insert<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
_wrapWithLambdasIterate(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedInsert(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningMap( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningMap(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert<QueryUserWrapper>,
@ -305,6 +426,26 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturnin
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedInsertReturningMap(
compiledQuery: Insert<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
return _wrapWithLambdasMap(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedInsert(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.update( public suspend inline fun <QueryUserWrapper : Any> Transaction.update(
compiledQuery: Update<QueryUserWrapper>, compiledQuery: Update<QueryUserWrapper>,
@ -323,6 +464,24 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.update(
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedUpdate(
compiledQuery: Update<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
}
_wrapWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) },
parameters = parameters,
hasReturning = false,
returning = {},
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningSingleOrNull( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningSingleOrNull(
compiledQuery: Update<QueryUserWrapper>, compiledQuery: Update<QueryUserWrapper>,
@ -343,6 +502,27 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturnin
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedUpdateReturningSingleOrNull(
compiledQuery: Update<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.AT_MOST_ONCE)
}
return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.updateReturningIterate( public suspend inline fun <QueryUserWrapper : Any> Transaction.updateReturningIterate(
compiledQuery: Update<QueryUserWrapper>, compiledQuery: Update<QueryUserWrapper>,
@ -363,6 +543,26 @@ public suspend inline fun <QueryUserWrapper : Any> Transaction.updateReturningIt
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedUpdateReturningIterate(
compiledQuery: Update<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
_wrapWithLambdasIterate(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningMap( public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturningMap(
compiledQuery: Update<QueryUserWrapper>, compiledQuery: Update<QueryUserWrapper>,
@ -383,6 +583,183 @@ public suspend inline fun <QueryUserWrapper : Any, R> Transaction.updateReturnin
) )
} }
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedUpdateReturningMap(
compiledQuery: Update<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
return _wrapWithLambdasMap(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.delete(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
}
_wrapWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._delete(compiledQuery) },
parameters = parameters,
hasReturning = false,
returning = {},
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedDelete(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
}
_wrapWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) },
parameters = parameters,
hasReturning = false,
returning = {},
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.deleteReturningSingleOrNull(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.AT_MOST_ONCE)
}
return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery,
queryGetter = { this._delete(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedDeleteReturningSingleOrNull(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (Row<QueryUserWrapper>) -> R
): R? {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.AT_MOST_ONCE)
}
return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.deleteReturningIterate(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
_wrapWithLambdasIterate(
compiledQuery = compiledQuery,
queryGetter = { this._delete(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedDeleteReturningIterate(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> Unit
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
_wrapWithLambdasIterate(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.deleteReturningMap(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
return _wrapWithLambdasMap(
compiledQuery = compiledQuery,
queryGetter = { this._delete(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedDeleteReturningMap(
compiledQuery: Delete<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit,
rowsConsumer: (Row<QueryUserWrapper>) -> R
): List<R> {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN)
}
return _wrapWithLambdasMap(
compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend fun <R> SynchronizedDatabase<*>.transaction(body: (Transaction) -> R): R { public suspend fun <R> SynchronizedDatabase<*>.transaction(body: (Transaction) -> R): R {
contract { contract {