Insert clarification

This commit is contained in:
Andrew Golovashevich 2024-12-04 05:33:21 +03:00
parent 14d6868307
commit 042bf20444
15 changed files with 596 additions and 159 deletions

View File

@ -8,5 +8,13 @@ public interface Expression<RuntimeType, DatabaseType : ColumnType<RuntimeType &
left: Expression<RuntimeType, DatabaseType, OwnerBuilderUserExtension>, left: Expression<RuntimeType, DatabaseType, OwnerBuilderUserExtension>,
right: Expression<RuntimeType, DatabaseType, OwnerBuilderUserExtension> right: Expression<RuntimeType, DatabaseType, OwnerBuilderUserExtension>
): Expression<Boolean, ColumnType.BOOLEAN, OwnerBuilderUserExtension> ): Expression<Boolean, ColumnType.BOOLEAN, OwnerBuilderUserExtension>
public fun isNull(
e: Expression<*, *, OwnerBuilderUserExtension>,
): Expression<Boolean, ColumnType.BOOLEAN, OwnerBuilderUserExtension>
public fun isNotNull(
e: Expression<*, *, OwnerBuilderUserExtension>,
): Expression<Boolean, ColumnType.BOOLEAN, OwnerBuilderUserExtension>
} }
} }

View File

@ -55,11 +55,17 @@ public interface ModuleCreator {
public fun <QueryUserWrapper : Any> createSelect(initializer: CreateSelect<QueryUserWrapper>): Select<QueryUserWrapper> public fun <QueryUserWrapper : Any> createSelect(initializer: CreateSelect<QueryUserWrapper>): Select<QueryUserWrapper>
public interface CreateInsert<TableUserExtension : Any, QueryUserWrapper : Any> { public interface CreateInsertParam<TableUserExtension : Any, QueryUserWrapper : Any> {
public fun createInsert(table: Table<TableUserExtension, *>, creator: InsertCreator<TableUserExtension, QueryUserWrapper>): QueryUserWrapper public fun createInsert(table: Table<TableUserExtension, *>, creator: InsertCreator.InsertParams<TableUserExtension, QueryUserWrapper>): QueryUserWrapper
} }
public fun <TableUserExtension : Any, QueryUserWrapper : Any> createInsert(table: Table<TableUserExtension, *>, initializer: CreateInsert<TableUserExtension, QueryUserWrapper>): Insert<QueryUserWrapper> public fun <TableUserExtension : Any, QueryUserWrapper : Any> createInsertParams(table: Table<TableUserExtension, *>, initializer: CreateInsertParam<TableUserExtension, QueryUserWrapper>): Insert.InsertParams<QueryUserWrapper>
public interface CreateInsertFromQuery<TableUserExtension : Any, QueryUserWrapper : Any> {
public fun createInsert(table: Table<TableUserExtension, *>, creator: InsertCreator.InsertFromQuery<TableUserExtension, QueryUserWrapper>): QueryUserWrapper
}
public fun <TableUserExtension : Any, QueryUserWrapper : Any> createInsertFromQuery(table: Table<TableUserExtension, *>, initializer: CreateInsertFromQuery<TableUserExtension, QueryUserWrapper>): Insert.InsertFromQuery<QueryUserWrapper>
public interface CreateUpdate<TableUserExtension : Any, QueryUserWrapper : Any> { public interface CreateUpdate<TableUserExtension : Any, QueryUserWrapper : Any> {
public fun createUpdate(table: Table<TableUserExtension, *>, creator: UpdateCreator<TableUserExtension, QueryUserWrapper>): QueryUserWrapper public fun createUpdate(table: Table<TableUserExtension, *>, creator: UpdateCreator<TableUserExtension, QueryUserWrapper>): QueryUserWrapper

View File

@ -1,5 +1,5 @@
package ru.landgrafhomyak.serdha.api.v0.dml package ru.landgrafhomyak.serdha.api.v0.dml
public interface Delete<QueryUserExtension : Any> { public interface Delete<QueryUserExtension : Any> : _CommonQueryMethods.CanBeSubquery<QueryUserExtension> {
public val userExtension: QueryUserExtension public val userExtension: QueryUserExtension
} }

View File

@ -10,5 +10,5 @@ public interface DeleteCreator<TargetTableUserExtension : Any, QueryUserExtensio
public fun limit(size: UInt) public fun limit(size: UInt)
public val returning: _CommonQueryMethods._Returning<QueryUserExtension> public fun returning(s: (_CommonQueryMethods._Returning<QueryUserExtension>) -> Unit)
} }

View File

@ -1,5 +1,9 @@
package ru.landgrafhomyak.serdha.api.v0.dml package ru.landgrafhomyak.serdha.api.v0.dml
public interface Insert<UserExtension : Any> { public interface Insert<QueryUserExtension : Any> {
public val userExtension: UserExtension public val userExtension: QueryUserExtension
public interface InsertParams<QueryUserExtension : Any> : Insert<QueryUserExtension>
public interface InsertFromQuery<QueryUserExtension : Any> : Insert<QueryUserExtension>
} }

View File

@ -8,24 +8,66 @@ import ru.landgrafhomyak.serdha.api.v0.ddl.UniqueConstraint
public interface InsertCreator<TargetTableUserExtension : Any, QueryUserExtension : Any> : _CommonQueryMethods<QueryUserExtension> { public interface InsertCreator<TargetTableUserExtension : Any, QueryUserExtension : Any> : _CommonQueryMethods<QueryUserExtension> {
public val insertedValues: SelectedTable<TargetTableUserExtension, QueryUserExtension> public val insertedValues: SelectedTable<TargetTableUserExtension, QueryUserExtension>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> insert(column: Column<RuntimeType, DatabaseType, TargetTableUserExtension>, expression: Expression<RuntimeType, DatabaseType, QueryUserExtension>) @Suppress("ClassName")
public interface _UpsertCreator<TargetTableUserExtension : Any, QueryUserExtension : Any> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> oldColumnValue(c: Column<RuntimeType, DatabaseType, TargetTableUserExtension>): Expression<RuntimeType, DatabaseType, QueryUserExtension>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> insertParam(
column: Column<RuntimeType, DatabaseType, TargetTableUserExtension>,
paramName: String = column.name
): InputParam<RuntimeType, DatabaseType, QueryUserExtension>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> oldColumnValue(c: Column<RuntimeType, DatabaseType, QueryUserExtension>): Expression<RuntimeType?, DatabaseType, QueryUserExtension>
public interface UpsertCreator<TargetTableUserExtension : Any, QueryUserExtension : Any> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> updateColumn(c: Column<RuntimeType, DatabaseType, TargetTableUserExtension>, e: Expression<RuntimeType, DatabaseType, QueryUserExtension>) public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> updateColumn(c: Column<RuntimeType, DatabaseType, TargetTableUserExtension>, e: Expression<RuntimeType, DatabaseType, QueryUserExtension>)
} }
public fun onConflictUpdate(u: UniqueConstraint<TargetTableUserExtension>, c: UpsertCreator<TargetTableUserExtension, QueryUserExtension>.() -> Unit) public fun onConflictUpdate(u: UniqueConstraint<TargetTableUserExtension>, c: (_UpsertCreator<TargetTableUserExtension, QueryUserExtension>) -> Unit)
public fun onConflictThrow(u: UniqueConstraint<TargetTableUserExtension>) public fun onConflictThrow(u: UniqueConstraint<TargetTableUserExtension>)
public fun onConflictIgnore(u: UniqueConstraint<TargetTableUserExtension>) public fun onConflictIgnore(u: UniqueConstraint<TargetTableUserExtension>)
public val returning: _CommonQueryMethods._Returning<QueryUserExtension> public fun returningInserted(s: (_CommonQueryMethods._Returning<QueryUserExtension>) -> Unit)
@Suppress("ClassName")
public interface _ReturningUpdated<TargetTableUserExtension : Any, QueryUserExtension : Any> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> oldColumnValue(c: Column<RuntimeType, DatabaseType, TargetTableUserExtension>): Expression<RuntimeType, DatabaseType, QueryUserExtension>
} }
public fun returningUpdated(s: (_ReturningUpdated<TargetTableUserExtension, QueryUserExtension>) -> Unit)
public interface InsertParams<TargetTableUserExtension : Any, QueryUserExtension : Any> : InsertCreator<TargetTableUserExtension, QueryUserExtension> {
public class DataParam<@Suppress("unused") QueryUserExtension : Any> private constructor()
public val dataExpressionBuilder: Expression.Builder<DataParam<QueryUserExtension>>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> dataParam(name: String, type: DatabaseType): InputParam<RuntimeType, DatabaseType, DataParam<QueryUserExtension>>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> nullableDataParam(name: String, type: DatabaseType): InputParam<RuntimeType?, DatabaseType, DataParam<QueryUserExtension>>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> insertParam(
column: Column<RuntimeType, DatabaseType, TargetTableUserExtension>,
paramName: String = column.name
): InputParam<RuntimeType, DatabaseType, DataParam<QueryUserExtension>>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> insert(column: Column<RuntimeType, DatabaseType, TargetTableUserExtension>, expression: Expression<RuntimeType, DatabaseType, DataParam<QueryUserExtension>>)
}
public interface InsertFromQuery<TargetTableUserExtension : Any, QueryUserExtension : Any> : InsertCreator<TargetTableUserExtension, QueryUserExtension> {
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> insert(column: Column<RuntimeType, DatabaseType, TargetTableUserExtension>, expression: Expression<RuntimeType, DatabaseType, QueryUserExtension>)
}
}

View File

@ -1,6 +1,6 @@
package ru.landgrafhomyak.serdha.api.v0.dml package ru.landgrafhomyak.serdha.api.v0.dml
public interface Select<QueryUserExtension : Any> { public interface Select<QueryUserExtension : Any>: _CommonQueryMethods.CanBeSubquery<QueryUserExtension> {
public val userExtension: QueryUserExtension public val userExtension: QueryUserExtension
public enum class Order { public enum class Order {

View File

@ -1,5 +1,5 @@
package ru.landgrafhomyak.serdha.api.v0.dml package ru.landgrafhomyak.serdha.api.v0.dml
public interface Update<QueryUserExtension : Any> { public interface Update<QueryUserExtension : Any> : _CommonQueryMethods.CanBeSubquery<QueryUserExtension> {
public val userExtension: QueryUserExtension public val userExtension: QueryUserExtension
} }

View File

@ -19,5 +19,5 @@ public interface UpdateCreator<TargetTableUserExtension : Any, QueryUserExtensio
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
public fun offsetedLimit(offset: ULong, size: UInt) public fun offsetedLimit(offset: ULong, size: UInt)
public val returning: _CommonQueryMethods._Returning<QueryUserExtension> public fun returning(s: (_CommonQueryMethods._Returning<QueryUserExtension>) -> Unit)
} }

View File

@ -4,11 +4,20 @@ 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 import ru.landgrafhomyak.serdha.api.v0.ddl.Table
import ru.landgrafhomyak.serdha.api.v0.runtime.ParametersSetter
@Suppress("ClassName") @Suppress("ClassName")
public interface _CommonQueryMethods<QueryUserExtension : Any> { public interface _CommonQueryMethods<QueryUserExtension : Any> {
public fun <SelectedTableUserExtension : Any> selectTable(t: Table<SelectedTableUserExtension, *>): SelectedTable<SelectedTableUserExtension, QueryUserExtension> public fun <SelectedTableUserExtension : Any> selectTable(t: Table<SelectedTableUserExtension, *>): SelectedTable<SelectedTableUserExtension, QueryUserExtension>
public fun <SelectedQueryUserExtension : Any> selectQuery(t: Select<SelectedQueryUserExtension>): SelectedTable<SelectedQueryUserExtension, QueryUserExtension>
public interface CanBeSubquery<@Suppress("unused") SelectedQueryUserExtension : Any>
public interface SubqueryParametersSetter<SubqueryUserExtension : Any, QueryUserExtension : Any> : ParametersSetter<SubqueryUserExtension> {
public operator fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> set(c: InputParam<RuntimeType, DatabaseType, QueryUserExtension>, value: Expression<RuntimeType, DatabaseType, QueryUserExtension>)
}
public fun <SubqueryUserExtension : Any> selectingQuery(q: CanBeSubquery<SubqueryUserExtension>, p: (SubqueryParametersSetter<SubqueryUserExtension, QueryUserExtension>) -> Unit): SelectedTable<SubqueryUserExtension, QueryUserExtension>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> param(name: String, type: DatabaseType): InputParam<RuntimeType, DatabaseType, QueryUserExtension> public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> param(name: String, type: DatabaseType): InputParam<RuntimeType, DatabaseType, QueryUserExtension>
public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> nullableParam(name: String, type: DatabaseType): InputParam<RuntimeType?, DatabaseType, QueryUserExtension> public fun <RuntimeType, DatabaseType : ColumnType<RuntimeType & Any>> nullableParam(name: String, type: DatabaseType): InputParam<RuntimeType?, DatabaseType, QueryUserExtension>

View File

@ -4,6 +4,7 @@ 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.Delete
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.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
@ -14,19 +15,23 @@ public interface SynchronizedDatabase<DatabaseUserExtension : Any> : Module<Data
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedSelect(query: Select<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>> public suspend fun <QueryUserWrapper : Any> _autoTransactedSelect(query: Select<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>>
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedInsert(query: Insert<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?> public suspend fun <QueryUserWrapper : Any> _autoTransactedInsertParams(query: Insert.InsertParams<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ParametersSetter._Multi<InsertCreator.InsertParams.DataParam<QueryUserWrapper>, _ResultSet<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>>?>>
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedUpdate(query: Update<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?> public suspend fun <QueryUserWrapper : Any> _autoTransactedInsertFromQuery(query: Insert.InsertFromQuery<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>>?>
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun <QueryUserWrapper : Any> _startAutoTransactedDelete(query: Delete<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?> public suspend fun <QueryUserWrapper : Any> _autoTransactedUpdate(query: Update<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>?>
@Suppress("FunctionName")
@LowLevelApi
public suspend fun <QueryUserWrapper : Any> _autoTransactedDelete(query: Delete<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>?>
public interface AtomicScript<C, A, R> { public interface AtomicScript<C, A, R> {
public suspend fun executeTransaction(transaction: Transaction, context: C, args: A): R public suspend fun executeTransaction(transaction: Transaction, context: C, args: A): R

View File

@ -3,25 +3,30 @@ 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.Delete
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.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
public interface Transaction { public interface Transaction {
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public fun <QueryUserWrapper : Any> _select(compiledQuery: Select<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>> public fun <QueryUserWrapper : Any> _select(compiledQuery: Select<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>>
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public fun <QueryUserWrapper : Any> _insert(compiledQuery: Insert<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?> public fun <QueryUserWrapper : Any> _insertParams(compiledQuery: Insert.InsertParams<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ParametersSetter._Multi<InsertCreator.InsertParams.DataParam<QueryUserWrapper>, _ResultSet<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>>?>>
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public fun <QueryUserWrapper : Any> _update(compiledQuery: Update<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?> public fun <QueryUserWrapper : Any> _insertFromQuery(compiledQuery: Insert.InsertFromQuery<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>>?>
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public fun <QueryUserWrapper : Any> _delete(compiledQuery: Delete<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper>?> public fun <QueryUserWrapper : Any> _update(compiledQuery: Update<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>?>
@Suppress("FunctionName")
@LowLevelApi
public fun <QueryUserWrapper : Any> _delete(compiledQuery: Delete<QueryUserWrapper>): _ParametersSetter<QueryUserWrapper, _ResultSet<QueryUserWrapper, Unit>?>
public suspend fun rollback() public suspend fun rollback()

View File

@ -10,4 +10,10 @@ public interface _ParametersSetter<QueryUserExtension : Any, out Result> : Param
@LowLevelApi @LowLevelApi
public suspend fun _abort() public suspend fun _abort()
@LowLevelApi
public interface _Multi<QueryUserExtension : Any, out Result> : _ParametersSetter<QueryUserExtension, Result> {
@LowLevelApi
public fun _next(): Boolean
}
} }

View File

@ -4,12 +4,16 @@ import ru.landgrafhomyak.serdha.api.v0.LowLevelApi
@Suppress("ClassName") @Suppress("ClassName")
@LowLevelApi @LowLevelApi
public interface _ResultSet<QueryUserExtension : Any> : Row<QueryUserExtension> { public interface _ResultSet<QueryUserExtension : Any, out Next> : Row<QueryUserExtension> {
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun _next(): Boolean public suspend fun _next(): Boolean
@Suppress("FunctionName") @Suppress("FunctionName")
@LowLevelApi @LowLevelApi
public suspend fun _close() public suspend fun _abort()
@Suppress("FunctionName")
@LowLevelApi
public suspend fun _close(): Next
} }

View File

@ -8,6 +8,7 @@ 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.Delete
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.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
@ -47,15 +48,15 @@ internal inline fun <R> _safeAutoClose(finally: () -> Unit, action: () -> R): R
public class QueryWithoutReturnError(message: String, public val query: Any) : Error(message) public class QueryWithoutReturnError(message: String, public val query: Any) : Error(message)
@Suppress("FunctionName") @Suppress("FunctionName", "DuplicatedCode")
@PublishedApi @PublishedApi
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
internal suspend inline fun <Q : Any> _wrapWithLambdas( internal suspend inline fun <Q : Any> _wrapWithLambdas(
compiledQuery: Any, compiledQuery: Any,
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q, Unit>?>,
parameters: (ParametersSetter<Q>) -> Unit, parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean, hasReturning: Boolean,
returning: (_ResultSet<Q>) -> Unit, returning: (_ResultSet<Q, *>) -> Unit,
queryWithoutErrorMessage: String queryWithoutErrorMessage: String
) { ) {
contract { contract {
@ -76,7 +77,7 @@ internal suspend inline fun <Q : Any> _wrapWithLambdas(
return return
} }
_safeAutoClose(finally = { rows._close() }) { _safeAutoClose(onAbort = { rows._abort() }, onSuccess = { rows._close() }) {
returning(rows) returning(rows)
} }
} }
@ -88,7 +89,7 @@ public class ResultNotSingleError : Error()
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
internal suspend inline fun <Q : Any, R> _wrapWithLambdasSingleOrNull( internal suspend inline fun <Q : Any, R> _wrapWithLambdasSingleOrNull(
compiledQuery: Any, compiledQuery: Any,
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q, Unit>?>,
parameters: (ParametersSetter<Q>) -> Unit, parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean, hasReturning: Boolean,
returning: (Row<Q>) -> R, returning: (Row<Q>) -> R,
@ -121,7 +122,7 @@ internal suspend inline fun <Q : Any, R> _wrapWithLambdasSingleOrNull(
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
internal suspend inline fun <Q : Any> _wrapWithLambdasIterate( internal suspend inline fun <Q : Any> _wrapWithLambdasIterate(
compiledQuery: Any, compiledQuery: Any,
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q, Unit>?>,
parameters: (ParametersSetter<Q>) -> Unit, parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean, hasReturning: Boolean,
returning: (Row<Q>) -> Unit, returning: (Row<Q>) -> Unit,
@ -141,7 +142,7 @@ internal suspend inline fun <Q : Any> _wrapWithLambdasIterate(
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
internal suspend inline fun <Q : Any, R> _wrapWithLambdasMap( internal suspend inline fun <Q : Any, R> _wrapWithLambdasMap(
compiledQuery: Any, compiledQuery: Any,
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q>?>, queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q, Unit>?>,
parameters: (ParametersSetter<Q>) -> Unit, parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean, hasReturning: Boolean,
returning: (Row<Q>) -> R, returning: (Row<Q>) -> R,
@ -179,7 +180,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.au
} }
return _wrapWithLambdasSingleOrNull( return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedSelect(compiledQuery) }, queryGetter = { this._autoTransactedSelect(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -240,7 +241,7 @@ public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoT
} }
_wrapWithLambdasIterate( _wrapWithLambdasIterate(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedSelect(compiledQuery) }, queryGetter = { this._autoTransactedSelect(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -281,7 +282,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.au
} }
return _wrapWithLambdasMap( return _wrapWithLambdasMap(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedSelect(compiledQuery) }, queryGetter = { this._autoTransactedSelect(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -289,161 +290,508 @@ public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.au
) )
} }
@Suppress("FunctionName", "DuplicatedCode")
@PublishedApi
@OptIn(LowLevelApi::class)
internal suspend inline fun <Q : Any, T> _wrapInsertParamsWithLambdas(
compiledQuery: Insert.InsertParams<Q>,
queryGetter: () -> _ParametersSetter<Q, _ParametersSetter._Multi<InsertCreator.InsertParams.DataParam<Q>, _ResultSet<Q, _ResultSet<Q, Unit>>?>>,
parameters: (ParametersSetter<Q>) -> Unit,
data: Iterable<T>,
rowFormatter: (T, ParametersSetter<InsertCreator.InsertParams.DataParam<Q>>) -> Unit,
hasReturning: Boolean,
returningInserted: (_ResultSet<Q, *>) -> Unit,
returningUpdated: (_ResultSet<Q, *>) -> Unit,
queryWithoutErrorMessage: String
) {
contract {
callsInPlace(queryGetter, InvocationKind.EXACTLY_ONCE)
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowFormatter, InvocationKind.UNKNOWN)
callsInPlace(returningInserted, InvocationKind.AT_MOST_ONCE)
callsInPlace(returningUpdated, InvocationKind.AT_MOST_ONCE)
}
val paramsSetter = queryGetter()
_safeAutoClose(onAbort = { paramsSetter._abort() }) {
parameters(paramsSetter)
}
val insertableValues = paramsSetter._execute()
_safeAutoClose(onAbort = { insertableValues._abort() }) {
for (e in data) {
insertableValues._next()
rowFormatter(e, insertableValues)
}
}
val insertedRows = insertableValues._execute()
if (insertedRows == null) {
if (hasReturning)
throw QueryWithoutReturnError(queryWithoutErrorMessage, compiledQuery)
return
}
_safeAutoClose(onAbort = { insertedRows._abort() }) {
returningInserted(insertedRows)
}
val updatedRows = insertedRows._close()
_safeAutoClose(onAbort = { insertedRows._abort() }, onSuccess = { updatedRows._abort() }) {
returningInserted(insertedRows)
}
}
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.insert( public suspend inline fun <QueryUserWrapper : Any, T> Transaction.insertParams(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
data: Iterable<T>,
rowFormatter: (T, ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit,
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowFormatter, InvocationKind.UNKNOWN)
}
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._insertParams(compiledQuery) },
parameters = parameters,
data = data,
rowFormatter = rowFormatter,
hasReturning = false,
returningInserted = {},
returningUpdated = {},
queryWithoutErrorMessage = ""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, T> SynchronizedDatabase<*>.autoTransactedInsertParams(
compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
data: Iterable<T>,
rowFormatter: (T, ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit,
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowFormatter, InvocationKind.UNKNOWN)
}
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._autoTransactedInsertParams(compiledQuery) },
parameters = parameters,
data = data,
rowFormatter = rowFormatter,
hasReturning = false,
returningInserted = {},
returningUpdated = {},
queryWithoutErrorMessage = ""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, T> Transaction.insertParamsReturningIterate(
compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
data: Iterable<T>,
rowFormatter: (T, ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit,
insertedRows: (Row<QueryUserWrapper>) -> Unit,
updatedRows: (Row<QueryUserWrapper>) -> Unit,
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowFormatter, InvocationKind.UNKNOWN)
}
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._insertParams(compiledQuery) },
parameters = parameters,
data = data,
rowFormatter = rowFormatter,
hasReturning = true,
returningInserted = { rs -> while (rs._next()) insertedRows(rs) },
returningUpdated = { rs -> while (rs._next()) updatedRows(rs) },
queryWithoutErrorMessage = ""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, T> SynchronizedDatabase<*>.autoTransactedInsertParametersReturningIterate(
compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
data: Iterable<T>,
rowFormatter: (T, ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit,
insertedRows: (Row<QueryUserWrapper>) -> Unit,
updatedRows: (Row<QueryUserWrapper>) -> Unit,
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowFormatter, InvocationKind.UNKNOWN)
}
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._autoTransactedInsertParams(compiledQuery) },
parameters = parameters,
data = data,
rowFormatter = rowFormatter,
hasReturning = true,
returningInserted = { rs -> while (rs._next()) insertedRows(rs) },
returningUpdated = { rs -> while (rs._next()) updatedRows(rs) },
queryWithoutErrorMessage = ""
)
}
@PublishedApi
internal object SingleIterable : Iterable<Unit>, Iterator<Unit> {
private var isReturned = false
override fun iterator(): Iterator<Unit> = this
override fun hasNext(): Boolean = !this.isReturned
override fun next(): Unit {
if (this.isReturned) throw IllegalStateException()
this.isReturned = true
}
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.insertSingle(
compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowData: (ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit,
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowData, InvocationKind.EXACTLY_ONCE)
}
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._insertParams(compiledQuery) },
parameters = parameters,
data = SingleIterable,
rowFormatter = { _, r -> rowData(r) },
hasReturning = false,
returningInserted = {},
returningUpdated = {},
queryWithoutErrorMessage = ""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedInsertSingle(
compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowData: (ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit,
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowData, InvocationKind.EXACTLY_ONCE)
}
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._autoTransactedInsertParams(compiledQuery) },
parameters = parameters,
data = SingleIterable,
rowFormatter = { _, r -> rowData(r) },
hasReturning = false,
returningInserted = {},
returningUpdated = {},
queryWithoutErrorMessage = ""
)
}
@Suppress("DuplicatedCode")
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertSingleReturning(
compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowData: (ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit = {},
insertedRows: (Row<QueryUserWrapper>) -> R,
updatedRows: (Row<QueryUserWrapper>) -> R
): R {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowData, InvocationKind.EXACTLY_ONCE)
callsInPlace(insertedRows, InvocationKind.AT_MOST_ONCE)
callsInPlace(updatedRows, InvocationKind.AT_MOST_ONCE)
}
var isReturned = false
var ret: R? = null
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._insertParams(compiledQuery) },
parameters = parameters,
hasReturning = true,
data = SingleIterable,
rowFormatter = { _, r -> rowData(r) },
returningInserted = returningInserted@{ rs ->
if (!rs._next()) return@returningInserted
isReturned = true
ret = insertedRows(rs)
if (rs._next()) throw ResultNotSingleError()
},
returningUpdated = returningUpdated@{ rs ->
if (!rs._next()) return@returningUpdated
if (isReturned) throw ResultNotSingleError()
isReturned = true
ret = insertedRows(rs)
if (rs._next()) throw ResultNotSingleError()
},
queryWithoutErrorMessage = ""
)
if (!isReturned)
throw QueryWithoutReturnError("", compiledQuery)
@Suppress("UNCHECKED_CAST")
return ret as R
}
@Suppress("DuplicatedCode")
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedInsertSingleReturning(
compiledQuery: Insert.InsertParams<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowData: (ParametersSetter<InsertCreator.InsertParams.DataParam<QueryUserWrapper>>) -> Unit = {},
insertedRows: (Row<QueryUserWrapper>) -> R,
updatedRows: (Row<QueryUserWrapper>) -> R
): R {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowData, InvocationKind.EXACTLY_ONCE)
callsInPlace(insertedRows, InvocationKind.AT_MOST_ONCE)
callsInPlace(updatedRows, InvocationKind.AT_MOST_ONCE)
}
var isReturned = false
var ret: R? = null
_wrapInsertParamsWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._autoTransactedInsertParams(compiledQuery) },
parameters = parameters,
hasReturning = true,
data = SingleIterable,
rowFormatter = { _, r -> rowData(r) },
returningInserted = returningInserted@{ rs ->
if (!rs._next()) return@returningInserted
isReturned = true
ret = insertedRows(rs)
if (rs._next()) throw ResultNotSingleError()
},
returningUpdated = returningUpdated@{ rs ->
if (!rs._next()) return@returningUpdated
if (isReturned) throw ResultNotSingleError()
isReturned = true
ret = insertedRows(rs)
if (rs._next()) throw ResultNotSingleError()
},
queryWithoutErrorMessage = ""
)
if (!isReturned)
throw QueryWithoutReturnError("", compiledQuery)
@Suppress("UNCHECKED_CAST")
return ret as R
}
@Suppress("FunctionName", "DuplicatedCode")
@PublishedApi
@OptIn(LowLevelApi::class)
internal suspend inline fun <Q : Any> _wrapInsertFromQueryWithLambdas(
compiledQuery: Insert.InsertFromQuery<Q>,
queryGetter: () -> _ParametersSetter<Q, _ResultSet<Q, _ResultSet<Q, Unit>>?>,
parameters: (ParametersSetter<Q>) -> Unit,
hasReturning: Boolean,
returningInserted: (_ResultSet<Q, *>) -> Unit,
returningUpdated: (_ResultSet<Q, *>) -> Unit,
queryWithoutErrorMessage: String
) {
contract {
callsInPlace(queryGetter, InvocationKind.EXACTLY_ONCE)
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(returningInserted, InvocationKind.AT_MOST_ONCE)
callsInPlace(returningUpdated, InvocationKind.AT_MOST_ONCE)
}
val paramsSetter = queryGetter()
_safeAutoClose(onAbort = { paramsSetter._abort() }) {
parameters(paramsSetter)
}
val insertedRows = paramsSetter._execute()
if (insertedRows == null) {
if (hasReturning)
throw QueryWithoutReturnError(queryWithoutErrorMessage, compiledQuery)
return
}
_safeAutoClose(onAbort = { insertedRows._abort() }) {
returningInserted(insertedRows)
}
val updatedRows = insertedRows._close()
_safeAutoClose(onAbort = { insertedRows._abort() }, onSuccess = { updatedRows._abort() }) {
returningInserted(insertedRows)
}
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> Transaction.insertFromQuery(
compiledQuery: Insert.InsertFromQuery<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
) { ) {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
} }
_wrapWithLambdas( _wrapInsertFromQueryWithLambdas(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._insert(compiledQuery) }, queryGetter = { this._insertFromQuery(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = false, hasReturning = false,
returning = {}, returningInserted = {},
"" returningUpdated = {},
queryWithoutErrorMessage = ""
) )
} }
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedInsert( public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedInsertFromQuery(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert.InsertFromQuery<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
) { ) {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
} }
_wrapWithLambdas( _wrapInsertFromQueryWithLambdas(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedInsert(compiledQuery) }, queryGetter = { this._autoTransactedInsertFromQuery(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = false, hasReturning = false,
returning = {}, returningInserted = {},
"" returningUpdated = {},
queryWithoutErrorMessage = ""
) )
} }
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningSingleOrNull( public suspend inline fun <QueryUserWrapper : Any> Transaction.insertFromQueryReturningIterate(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert.InsertFromQuery<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (Row<QueryUserWrapper>) -> R insertedRows: (Row<QueryUserWrapper>) -> Unit,
updatedRows: (Row<QueryUserWrapper>) -> Unit
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(insertedRows, InvocationKind.UNKNOWN)
callsInPlace(updatedRows, InvocationKind.UNKNOWN)
}
_wrapInsertFromQueryWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._insertFromQuery(compiledQuery) },
parameters = parameters,
hasReturning = true,
returningInserted = { rs -> while (rs._next()) insertedRows(rs) },
returningUpdated = { rs -> while (rs._next()) updatedRows(rs) },
queryWithoutErrorMessage = ""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoTransactedInsertFromQueryReturningIterate(
compiledQuery: Insert.InsertFromQuery<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
insertedRows: (Row<QueryUserWrapper>) -> Unit,
updatedRows: (Row<QueryUserWrapper>) -> Unit
) {
contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(insertedRows, InvocationKind.UNKNOWN)
callsInPlace(updatedRows, InvocationKind.UNKNOWN)
}
_wrapInsertFromQueryWithLambdas(
compiledQuery = compiledQuery,
queryGetter = { this._autoTransactedInsertFromQuery(compiledQuery) },
parameters = parameters,
hasReturning = true,
returningInserted = { rs -> while (rs._next()) insertedRows(rs) },
returningUpdated = { rs -> while (rs._next()) updatedRows(rs) },
queryWithoutErrorMessage = ""
)
}
@OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertFromQueryReturningSingleOrNull(
compiledQuery: Insert.InsertFromQuery<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
insertedRows: (Row<QueryUserWrapper>) -> R,
updatedRows: (Row<QueryUserWrapper>) -> R
): R? { ): R? {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.AT_MOST_ONCE) callsInPlace(insertedRows, InvocationKind.AT_MOST_ONCE)
callsInPlace(updatedRows, InvocationKind.AT_MOST_ONCE)
} }
return _wrapWithLambdasSingleOrNull( var isReturned = false
var ret: R? = null
_wrapInsertFromQueryWithLambdas(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._insert(compiledQuery) }, queryGetter = { this._insertFromQuery(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returningInserted = returningInserted@{ rs ->
"" if (!rs._next()) return@returningInserted
isReturned = true
ret = insertedRows(rs)
if (rs._next()) throw ResultNotSingleError()
},
returningUpdated = returningUpdated@{ rs ->
if (!rs._next()) return@returningUpdated
if (isReturned) throw ResultNotSingleError()
isReturned = true
ret = insertedRows(rs)
if (rs._next()) throw ResultNotSingleError()
},
queryWithoutErrorMessage = ""
) )
if (!isReturned)
return null
return ret
} }
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedInsertReturningSingleOrNull( public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.autoTransactedInsertFromQueryReturningSingleOrNull(
compiledQuery: Insert<QueryUserWrapper>, compiledQuery: Insert.InsertFromQuery<QueryUserWrapper>,
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {}, parameters: (ParametersSetter<QueryUserWrapper>) -> Unit = {},
rowsConsumer: (Row<QueryUserWrapper>) -> R insertedRows: (Row<QueryUserWrapper>) -> R,
updatedRows: (Row<QueryUserWrapper>) -> R
): R? { ): R? {
contract { contract {
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) callsInPlace(parameters, InvocationKind.EXACTLY_ONCE)
callsInPlace(rowsConsumer, InvocationKind.AT_MOST_ONCE) callsInPlace(insertedRows, InvocationKind.AT_MOST_ONCE)
callsInPlace(updatedRows, InvocationKind.AT_MOST_ONCE)
} }
return _wrapWithLambdasSingleOrNull( var isReturned = false
var ret: R? = null
_wrapInsertFromQueryWithLambdas(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedInsert(compiledQuery) }, queryGetter = { this._autoTransactedInsertFromQuery(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returningInserted = returningInserted@{ rs ->
"" if (!rs._next()) return@returningInserted
) isReturned = true
} ret = insertedRows(rs)
if (rs._next()) throw ResultNotSingleError()
@OptIn(LowLevelApi::class) },
public suspend inline fun <QueryUserWrapper : Any> Transaction.insertReturningIterate( returningUpdated = returningUpdated@{ rs ->
compiledQuery: Insert<QueryUserWrapper>, if (!rs._next()) return@returningUpdated
parameters: (ParametersSetter<QueryUserWrapper>) -> Unit, if (isReturned) throw ResultNotSingleError()
rowsConsumer: (Row<QueryUserWrapper>) -> Unit isReturned = true
) { ret = insertedRows(rs)
contract { if (rs._next()) throw ResultNotSingleError()
callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) },
callsInPlace(rowsConsumer, InvocationKind.UNKNOWN) queryWithoutErrorMessage = ""
}
_wrapWithLambdasIterate(
compiledQuery = compiledQuery,
queryGetter = { this._insert(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@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)
public suspend inline fun <QueryUserWrapper : Any, R> Transaction.insertReturningMap(
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._insert(compiledQuery) },
parameters = parameters,
hasReturning = true,
returning = rowsConsumer,
""
)
}
@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,
""
) )
if (!isReturned)
return null
return ret
} }
@OptIn(LowLevelApi::class) @OptIn(LowLevelApi::class)
@ -474,7 +822,7 @@ public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoT
} }
_wrapWithLambdas( _wrapWithLambdas(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) }, queryGetter = { this._autoTransactedUpdate(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = false, hasReturning = false,
returning = {}, returning = {},
@ -515,7 +863,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.au
} }
return _wrapWithLambdasSingleOrNull( return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) }, queryGetter = { this._autoTransactedUpdate(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -555,7 +903,7 @@ public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoT
} }
_wrapWithLambdasIterate( _wrapWithLambdasIterate(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) }, queryGetter = { this._autoTransactedUpdate(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -595,7 +943,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.au
} }
return _wrapWithLambdasMap( return _wrapWithLambdasMap(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedUpdate(compiledQuery) }, queryGetter = { this._autoTransactedUpdate(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -631,7 +979,7 @@ public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoT
} }
_wrapWithLambdas( _wrapWithLambdas(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) }, queryGetter = { this._autoTransactedDelete(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = false, hasReturning = false,
returning = {}, returning = {},
@ -672,7 +1020,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.au
} }
return _wrapWithLambdasSingleOrNull( return _wrapWithLambdasSingleOrNull(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) }, queryGetter = { this._autoTransactedDelete(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -712,7 +1060,7 @@ public suspend inline fun <QueryUserWrapper : Any> SynchronizedDatabase<*>.autoT
} }
_wrapWithLambdasIterate( _wrapWithLambdasIterate(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) }, queryGetter = { this._autoTransactedDelete(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,
@ -752,7 +1100,7 @@ public suspend inline fun <QueryUserWrapper : Any, R> SynchronizedDatabase<*>.au
} }
return _wrapWithLambdasMap( return _wrapWithLambdasMap(
compiledQuery = compiledQuery, compiledQuery = compiledQuery,
queryGetter = { this._startAutoTransactedDelete(compiledQuery) }, queryGetter = { this._autoTransactedDelete(compiledQuery) },
parameters = parameters, parameters = parameters,
hasReturning = true, hasReturning = true,
returning = rowsConsumer, returning = rowsConsumer,