diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer0.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer0.kt index 6baba1d..d336a55 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer0.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer0.kt @@ -2,6 +2,6 @@ package ru.landgrafhomyak.db.serdha0.user_commons.executors import ru.landgrafhomyak.db.serdha0.api.runtime.OutputRow -public fun interface RowConsumer0 { +public interface RowConsumer0 { public fun transformRow(row: OutputRow): R } \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer1.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer1.kt index 2c54ae0..46e2806 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer1.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/RowConsumer1.kt @@ -2,6 +2,6 @@ package ru.landgrafhomyak.db.serdha0.user_commons.executors import ru.landgrafhomyak.db.serdha0.api.runtime.OutputRow -public fun interface RowConsumer1 { +public interface RowConsumer1 { public fun transformRow(row: OutputRow, index: Int): R } \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2row.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2row.kt index a4e9ddf..bf5ebb4 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2row.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2row.kt @@ -4,9 +4,12 @@ package ru.landgrafhomyak.db.serdha0.user_commons.executors +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract import kotlin.jvm.JvmName import ru.landgrafhomyak.db.serdha0.api.LowLevelApi import ru.landgrafhomyak.db.serdha0.api.queries._Query +import ru.landgrafhomyak.db.serdha0.api.runtime.OutputRow import ru.landgrafhomyak.db.serdha0.api.runtime.Transaction public class ExpectedOneRowException : Error("Expected at least one row, but table is empty") @@ -15,18 +18,45 @@ public class TooManyRowsException : Error("Expected exactly one row, but got mor public suspend inline fun Transaction.selectExactlyOneOrError( compiledQuery: _Query.Params2Table, params: RowProducer0, - result: RowConsumer0 + result: (OutputRow) -> R ): R { + contract { + callsInPlace(result, InvocationKind.EXACTLY_ONCE) + } _safeAutoClose_IO( iRow = this._executeQuery(compiledQuery), inputAction = params::initializeRow, outputAction = { oRow -> if (!oRow._next()) throw ExpectedOneRowException() - val ret = result.transformRow(oRow) - if (oRow._next()) - throw TooManyRowsException() - return ret + _safeAutoClose(onSuccess = { if (oRow._next()) throw TooManyRowsException() }) { + return result(oRow) + } + } + ) +} + +public suspend inline fun Transaction.selectExactlyOneOrError( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + result: RowConsumer0 +): R = this.selectExactlyOneOrError(compiledQuery, params, result::transformRow) + +public suspend inline fun Transaction.selectExactlyOneOrError( + compiledQuery: _Query.Void2Table, + result: (OutputRow) -> R +): R { + contract { + callsInPlace(result, InvocationKind.EXACTLY_ONCE) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), + outputAction = { oRow -> + if (!oRow._next()) + throw ExpectedOneRowException() + _safeAutoClose(onSuccess = { if (oRow._next()) throw TooManyRowsException() }) { + return result(oRow) + } } ) } @@ -34,16 +64,25 @@ public suspend inline fun Transaction.selectExactlyOneOrError( public suspend inline fun Transaction.selectExactlyOneOrError( compiledQuery: _Query.Void2Table, result: RowConsumer0 -): R { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), +): R = this.selectExactlyOneOrError(compiledQuery, result::transformRow) + +public suspend inline fun Transaction.selectExactlyOneOrNull( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + result: (OutputRow) -> R +): R? { + contract { + callsInPlace(result, InvocationKind.AT_MOST_ONCE) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> if (!oRow._next()) - throw ExpectedOneRowException() - val ret = result.transformRow(oRow) - if (oRow._next()) - throw TooManyRowsException() - return ret + return null + _safeAutoClose(onSuccess = { if (oRow._next()) throw TooManyRowsException() }) { + return result(oRow) + } } ) } @@ -52,17 +91,23 @@ public suspend inline fun Transaction.selectExactlyOneOrNull( compiledQuery: _Query.Params2Table, params: RowProducer0, result: RowConsumer0 +): R? = this.selectExactlyOneOrNull(compiledQuery, params, result::transformRow) + +public suspend inline fun Transaction.selectExactlyOneOrNull( + compiledQuery: _Query.Void2Table, + result: (OutputRow) -> R ): R? { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(result, InvocationKind.AT_MOST_ONCE) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> if (!oRow._next()) return null - val ret = result.transformRow(oRow) - if (oRow._next()) - throw TooManyRowsException() - return ret + _safeAutoClose(onSuccess = { if (oRow._next()) throw TooManyRowsException() }) { + return result(oRow) + } } ) } @@ -70,16 +115,23 @@ public suspend inline fun Transaction.selectExactlyOneOrNull( public suspend inline fun Transaction.selectExactlyOneOrNull( compiledQuery: _Query.Void2Table, result: RowConsumer0 -): R? { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), +): R? = this.selectExactlyOneOrNull(compiledQuery, result::transformRow) + +public suspend inline fun Transaction.selectFirstOrError( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + result: (OutputRow) -> R +): R { + contract { + callsInPlace(result, InvocationKind.EXACTLY_ONCE) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> if (!oRow._next()) - return null - val ret = result.transformRow(oRow) - if (oRow._next()) - throw TooManyRowsException() - return ret + throw ExpectedOneRowException() + return result(oRow) } ) } @@ -88,14 +140,21 @@ public suspend inline fun Transaction.selectFirstOrError( compiledQuery: _Query.Params2Table, params: RowProducer0, result: RowConsumer0 +): R = this.selectFirstOrError(compiledQuery, params, result::transformRow) + +public suspend inline fun Transaction.selectFirstOrError( + compiledQuery: _Query.Void2Table, + result: (OutputRow) -> R ): R { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(result, InvocationKind.EXACTLY_ONCE) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> if (!oRow._next()) throw ExpectedOneRowException() - return result.transformRow(oRow) + return result(oRow) } ) } @@ -103,13 +162,23 @@ public suspend inline fun Transaction.selectFirstOrError( public suspend inline fun Transaction.selectFirstOrError( compiledQuery: _Query.Void2Table, result: RowConsumer0 -): R { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), +): R = this.selectFirstOrError(compiledQuery, result::transformRow) + +public suspend inline fun Transaction.selectFirstOrNull( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + result: (OutputRow) -> R +): R? { + contract { + callsInPlace(result, InvocationKind.AT_MOST_ONCE) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> if (!oRow._next()) - throw ExpectedOneRowException() - return result.transformRow(oRow) + return null + return result(oRow) } ) } @@ -118,14 +187,21 @@ public suspend inline fun Transaction.selectFirstOrNull( compiledQuery: _Query.Params2Table, params: RowProducer0, result: RowConsumer0 +): R? = this.selectFirstOrNull(compiledQuery, params, result::transformRow) + +public suspend inline fun Transaction.selectFirstOrNull( + compiledQuery: _Query.Void2Table, + result: (OutputRow) -> R ): R? { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(result, InvocationKind.AT_MOST_ONCE) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> if (!oRow._next()) return null - return result.transformRow(oRow) + return result(oRow) } ) } @@ -133,13 +209,4 @@ public suspend inline fun Transaction.selectFirstOrNull( public suspend inline fun Transaction.selectFirstOrNull( compiledQuery: _Query.Void2Table, result: RowConsumer0 -): R? { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), - outputAction = { oRow -> - if (!oRow._next()) - return null - return result.transformRow(oRow) - } - ) -} \ No newline at end of file +): R? = this.selectFirstOrNull(compiledQuery, result::transformRow) \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2table.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2table.kt index fc299e6..347429e 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2table.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/row2table.kt @@ -4,22 +4,50 @@ package ru.landgrafhomyak.db.serdha0.user_commons.executors +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract import kotlin.jvm.JvmName import ru.landgrafhomyak.db.serdha0.api.LowLevelApi import ru.landgrafhomyak.db.serdha0.api.queries._Query +import ru.landgrafhomyak.db.serdha0.api.runtime.OutputRow import ru.landgrafhomyak.db.serdha0.api.runtime.Transaction public suspend inline fun Transaction.select( compiledQuery: _Query.Params2Table, params: RowProducer0, - transform: RowConsumer0 + transform: (OutputRow) -> Unit ) { + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } _safeAutoClose_IO( iRow = this._executeQuery(compiledQuery), inputAction = params::initializeRow, outputAction = { oRow -> while (oRow._next()) - transform.transformRow(oRow) + transform(oRow) + } + ) +} + +public suspend inline fun Transaction.select( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + transform: RowConsumer0 +): Unit = this.select(compiledQuery, params, transform::transformRow) + +public suspend inline fun Transaction.select( + compiledQuery: _Query.Void2Table, + transform: (OutputRow) -> Unit +) { + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), + outputAction = { oRow -> + while (oRow._next()) + transform(oRow) } ) } @@ -27,12 +55,24 @@ public suspend inline fun Transaction.select( public suspend inline fun Transaction.select( compiledQuery: _Query.Void2Table, transform: RowConsumer0 -) { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), +): Unit = this.select(compiledQuery, transform::transformRow) + +public suspend inline fun Transaction.mapRows( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + transform: (OutputRow) -> E +): List { + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> + val dst = ArrayList() while (oRow._next()) - transform.transformRow(oRow) + dst.add(transform(oRow)) + return dst } ) } @@ -41,14 +81,21 @@ public suspend inline fun Transaction.mapRows( compiledQuery: _Query.Params2Table, params: RowProducer0, transform: RowConsumer0 +): List = this.mapRows(compiledQuery, params, transform::transformRow) + +public suspend inline fun Transaction.mapRows( + compiledQuery: _Query.Void2Table, + transform: (OutputRow) -> E ): List { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> val dst = ArrayList() while (oRow._next()) - dst.add(transform.transformRow(oRow)) + dst.add(transform(oRow)) return dst } ) @@ -57,13 +104,25 @@ public suspend inline fun Transaction.mapRows( public suspend inline fun Transaction.mapRows( compiledQuery: _Query.Void2Table, transform: RowConsumer0 +): List = this.mapRows(compiledQuery, transform::transformRow) + +public suspend inline fun Transaction.mapRowsIndexed( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + firstIndex: Int = 0, + transform: (OutputRow, Int) -> E ): List { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> val dst = ArrayList() + var i = firstIndex while (oRow._next()) - dst.add(transform.transformRow(oRow)) + dst.add(transform(oRow, i++)) return dst } ) @@ -74,15 +133,23 @@ public suspend inline fun Transaction.mapRowsIndexed( params: RowProducer0, firstIndex: Int = 0, transform: RowConsumer1 +): List = this.mapRowsIndexed(compiledQuery, params, firstIndex, transform::transformRow) + +public suspend inline fun Transaction.mapRowsIndexed( + compiledQuery: _Query.Void2Table, + firstIndex: Int = 0, + transform: (OutputRow, Int) -> E ): List { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> val dst = ArrayList() var i = firstIndex while (oRow._next()) - dst.add(transform.transformRow(oRow, i++)) + dst.add(transform(oRow, i++)) return dst } ) @@ -92,14 +159,23 @@ public suspend inline fun Transaction.mapRowsIndexed( compiledQuery: _Query.Void2Table, firstIndex: Int = 0, transform: RowConsumer1 -): List { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), +): List = this.mapRowsIndexed(compiledQuery, firstIndex, transform::transformRow) + +public suspend inline fun > Transaction.mapRowsTo( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + dst: C, + transform: (OutputRow) -> E +): C { + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> - val dst = ArrayList() - var i = firstIndex while (oRow._next()) - dst.add(transform.transformRow(oRow, i++)) + dst.add(transform(oRow)) return dst } ) @@ -110,13 +186,21 @@ public suspend inline fun > Transaction.m params: RowProducer0, dst: C, transform: RowConsumer0 +): C = this.mapRowsTo(compiledQuery, params, dst, transform::transformRow) + +public suspend inline fun > Transaction.mapRowsTo( + compiledQuery: _Query.Void2Table, + dst: C, + transform: (OutputRow) -> E ): C { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> while (oRow._next()) - dst.add(transform.transformRow(oRow)) + dst.add(transform(oRow)) return dst } ) @@ -126,12 +210,24 @@ public suspend inline fun > Transaction.m compiledQuery: _Query.Void2Table, dst: C, transform: RowConsumer0 +): C = this.mapRowsTo(compiledQuery, dst, transform::transformRow) + +public suspend inline fun > Transaction.mapRowsIndexedTo( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + dst: C, firstIndex: Int = 0, + transform: (OutputRow, Int) -> E ): C { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> + var i = firstIndex while (oRow._next()) - dst.add(transform.transformRow(oRow)) + dst.add(transform(oRow, i++)) return dst } ) @@ -142,14 +238,22 @@ public suspend inline fun > Transaction.m params: RowProducer0, dst: C, firstIndex: Int = 0, transform: RowConsumer1 +): C = this.mapRowsIndexedTo(compiledQuery, params, dst, firstIndex, transform::transformRow) + +public suspend inline fun > Transaction.mapRowsIndexedTo( + compiledQuery: _Query.Void2Table, + dst: C, firstIndex: Int = 0, + transform: (OutputRow, Int) -> E ): C { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> var i = firstIndex while (oRow._next()) - dst.add(transform.transformRow(oRow, i++)) + dst.add(transform(oRow, i++)) return dst } ) @@ -159,13 +263,24 @@ public suspend inline fun > Transaction.m compiledQuery: _Query.Void2Table, dst: C, firstIndex: Int = 0, transform: RowConsumer1 -): C { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), +): C = this.mapRowsIndexedTo(compiledQuery, dst, firstIndex, transform::transformRow) + +public suspend inline fun Transaction.mapRowsTo( + compiledQuery: _Query.Params2Table, + params: RowProducer0, + dst: Array, dstOffset: Int = 0, + transform: (OutputRow) -> E +): Array { + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_IO( + iRow = this._executeQuery(compiledQuery), + inputAction = params::initializeRow, outputAction = { oRow -> - var i = firstIndex + var i = dstOffset while (oRow._next()) - dst.add(transform.transformRow(oRow, i++)) + dst[i++] = transform(oRow) return dst } ) @@ -176,14 +291,22 @@ public suspend inline fun Transaction.mapRowsTo( params: RowProducer0, dst: Array, dstOffset: Int = 0, transform: RowConsumer0 +): Array = this.mapRowsTo(compiledQuery, params, dst, dstOffset, transform::transformRow) + +public suspend inline fun Transaction.mapRowsTo( + compiledQuery: _Query.Void2Table, + dst: Array, dstOffset: Int = 0, + transform: (OutputRow) -> E ): Array { - _safeAutoClose_IO( - iRow = this._executeQuery(compiledQuery), - inputAction = params::initializeRow, + contract { + callsInPlace(transform, InvocationKind.UNKNOWN) + } + _safeAutoClose_O( + oRow = this._executeQuery(compiledQuery), outputAction = { oRow -> var i = dstOffset while (oRow._next()) - dst[i++] = transform.transformRow(oRow) + dst[i++] = transform(oRow) return dst } ) @@ -193,14 +316,4 @@ public suspend inline fun Transaction.mapRowsTo( compiledQuery: _Query.Void2Table, dst: Array, dstOffset: Int = 0, transform: RowConsumer0 -): Array { - _safeAutoClose_O( - oRow = this._executeQuery(compiledQuery), - outputAction = { oRow -> - var i = dstOffset - while (oRow._next()) - dst[i++] = transform.transformRow(oRow) - return dst - } - ) -} \ No newline at end of file +): Array = this.mapRowsTo(compiledQuery, dst, dstOffset, transform::transformRow) \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/transaction.kt b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/transaction.kt index 72503a2..1d33821 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/transaction.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/db/serdha0/user_commons/executors/transaction.kt @@ -1,9 +1,10 @@ @file:OptIn(LowLevelApi::class) +@file:JvmName("_TransactionsKt") package ru.landgrafhomyak.db.serdha0.user_commons.executors +import kotlin.jvm.JvmName import ru.landgrafhomyak.db.serdha0.api.LowLevelApi - import ru.landgrafhomyak.db.serdha0.api.runtime.Executor import ru.landgrafhomyak.db.serdha0.api.runtime.Transaction