From 9629efb66ce6d66eb33c7d833f498f96043e67da Mon Sep 17 00:00:00 2001 From: Alexander Ioffe Date: Tue, 2 Dec 2025 21:57:34 -0500 Subject: [PATCH 1/2] Cleanup API, add special streamBoth/runBoth --- controller-android/build.gradle.kts | 6 ++ .../android/AndroidDatabaseController.kt | 5 +- controller-core/build.gradle.kts | 6 ++ .../io/exoquery/controller/Annotations.kt | 7 +- .../io/exoquery/controller/Controller.kt | 76 ++++++++++-------- controller-jdbc/build.gradle.kts | 6 ++ .../controller/jdbc/JdbcController.kt | 78 +++++++++++++++++-- .../controller/jdbc/JdbcControllers.kt | 1 - controller-native/build.gradle.kts | 5 ++ controller-r2dbc/build.gradle.kts | 6 ++ .../instrumented/InstrumentedPerfSpec.kt | 7 +- .../io/exoquery/sql/android/BasicQuerySpec.kt | 7 +- .../io/exoquery/sql/android/EncodingSpec.kt | 7 +- .../kotlin/io/exoquery/sql/BasicActionOps.kt | 6 +- .../io/exoquery/sql/TransactionSpecOps.kt | 6 +- .../io/exoquery/sql/WalConcurrencyOps.kt | 6 +- .../io/exoquery/controller/Transactions.kt | 3 + .../io/exoquery/r2dbc/h2/BasicActionSpec.kt | 6 +- .../io/exoquery/r2dbc/h2/BasicQuerySpec.kt | 6 +- .../io/exoquery/r2dbc/h2/BatchValuesSpec.kt | 8 +- .../io/exoquery/r2dbc/h2/EncodingSpec.kt | 7 +- .../io/exoquery/r2dbc/h2/InQuerySpec.kt | 6 +- .../io/exoquery/r2dbc/h2/TransactionSpec.kt | 6 +- .../exoquery/r2dbc/mysql/BasicActionSpec.kt | 6 +- .../io/exoquery/r2dbc/mysql/BasicQuerySpec.kt | 6 +- .../io/exoquery/r2dbc/mysql/EncodingSpec.kt | 7 +- .../io/exoquery/r2dbc/mysql/InQuerySpec.kt | 6 +- .../io/exoquery/r2dbc/mysql/InjectionSpec.kt | 6 +- .../exoquery/r2dbc/mysql/TransactionSpec.kt | 6 +- .../exoquery/r2dbc/oracle/BasicActionSpec.kt | 6 +- .../exoquery/r2dbc/oracle/BasicQuerySpec.kt | 6 +- .../io/exoquery/r2dbc/oracle/EncodingSpec.kt | 7 +- .../io/exoquery/r2dbc/oracle/InQuerySpec.kt | 6 +- .../io/exoquery/r2dbc/oracle/InjectionSpec.kt | 6 +- .../exoquery/r2dbc/oracle/TransactionSpec.kt | 6 +- .../r2dbc/postgres/BasicActionSpec.kt | 6 +- .../exoquery/r2dbc/postgres/BasicQuerySpec.kt | 6 +- .../r2dbc/postgres/BatchValuesSpec.kt | 6 +- .../exoquery/r2dbc/postgres/EncodingSpec.kt | 7 +- .../io/exoquery/r2dbc/postgres/InQuerySpec.kt | 6 +- .../exoquery/r2dbc/postgres/InjectionSpec.kt | 6 +- .../io/exoquery/r2dbc/postgres/JsonSpec.kt | 6 +- .../r2dbc/postgres/TransactionSpec.kt | 6 +- .../r2dbc/sqlserver/BasicActionSpec.kt | 6 +- .../r2dbc/sqlserver/BasicQuerySpec.kt | 6 +- .../exoquery/r2dbc/sqlserver/EncodingSpec.kt | 7 +- .../exoquery/r2dbc/sqlserver/InQuerySpec.kt | 6 +- .../exoquery/r2dbc/sqlserver/InjectionSpec.kt | 6 +- .../r2dbc/sqlserver/TransactionSpec.kt | 6 +- 49 files changed, 310 insertions(+), 127 deletions(-) diff --git a/controller-android/build.gradle.kts b/controller-android/build.gradle.kts index 9a7e177..81d3648 100644 --- a/controller-android/build.gradle.kts +++ b/controller-android/build.gradle.kts @@ -35,6 +35,12 @@ android { } kotlin { + compilerOptions { + optIn.addAll( + "io.exoquery.controller.TerpalSqlInternal" + ) + } + if (HostManager.hostIsLinux || !project.hasProperty("isCI")) { androidTarget { diff --git a/controller-android/src/androidMain/kotlin/io/exoquery/controller/android/AndroidDatabaseController.kt b/controller-android/src/androidMain/kotlin/io/exoquery/controller/android/AndroidDatabaseController.kt index 2e00283..457b5b5 100644 --- a/controller-android/src/androidMain/kotlin/io/exoquery/controller/android/AndroidDatabaseController.kt +++ b/controller-android/src/androidMain/kotlin/io/exoquery/controller/android/AndroidDatabaseController.kt @@ -230,6 +230,7 @@ class AndroidDatabaseController internal constructor( protected fun wrap(stmt: SupportSQLiteStatement) = AndroidxStatementWrapper(stmt) + @OptIn(TerpalSqlInternal::class) suspend fun runActionScoped(sql: String, options: UnusedOpts, params: List>): Long = withConnection(options) { val conn = localConnection() @@ -376,10 +377,6 @@ class AndroidDatabaseController internal constructor( override suspend fun stream(query: ControllerBatchActionReturning, options: UnusedOpts): Flow = throw IllegalArgumentException("Batch Queries are not supported in NativeContext.") - fun runRaw(sql: String, options: UnusedOpts = UnusedOpts) = runBlocking { - sql.split(";").forEach { if (it.trim().isNotEmpty()) runActionScoped(it, options, emptyList()) } - } - override fun close() = this.pool.finalize() } diff --git a/controller-core/build.gradle.kts b/controller-core/build.gradle.kts index 47b2d0d..69f2a95 100644 --- a/controller-core/build.gradle.kts +++ b/controller-core/build.gradle.kts @@ -12,6 +12,12 @@ plugins { version = extra["controllerVersion"].toString() kotlin { + compilerOptions { + optIn.addAll( + "io.exoquery.controller.TerpalSqlInternal" + ) + } + jvmToolchain(17) jvm { } diff --git a/controller-core/src/commonMain/kotlin/io/exoquery/controller/Annotations.kt b/controller-core/src/commonMain/kotlin/io/exoquery/controller/Annotations.kt index a8e5a13..ebd86cc 100644 --- a/controller-core/src/commonMain/kotlin/io/exoquery/controller/Annotations.kt +++ b/controller-core/src/commonMain/kotlin/io/exoquery/controller/Annotations.kt @@ -2,5 +2,10 @@ package io.exoquery.controller @RequiresOptIn(message = "This is internal Terpal-SQL API and may change in the future.") @Retention(AnnotationRetention.BINARY) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.FIELD) annotation class TerpalSqlInternal + +@RequiresOptIn(message = "This is an unsafe raw-SQL API. Injections are possible.") +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +annotation class TerpalSqlUnsafe diff --git a/controller-core/src/commonMain/kotlin/io/exoquery/controller/Controller.kt b/controller-core/src/commonMain/kotlin/io/exoquery/controller/Controller.kt index a5672eb..e391e0f 100644 --- a/controller-core/src/commonMain/kotlin/io/exoquery/controller/Controller.kt +++ b/controller-core/src/commonMain/kotlin/io/exoquery/controller/Controller.kt @@ -14,6 +14,7 @@ import org.intellij.lang.annotations.Language import kotlin.coroutines.AbstractCoroutineContextElement import kotlin.experimental.ExperimentalTypeInference +@TerpalSqlInternal class CoroutineSession(val session: Session, val sessionKey: CoroutineContext.Key>) : AbstractCoroutineContextElement(sessionKey) { override fun toString() = "CoroutineSession($sessionKey)" } @@ -22,7 +23,7 @@ class TerpalException(msg: String, cause: Throwable?): Exception(msg, cause) { constructor(msg: String): this(msg, null) } -@OptIn(TerpalSqlInternal::class) +@TerpalSqlInternal interface EncodingConfig { val additionalEncoders: Set> val additionalDecoders: Set> @@ -33,7 +34,7 @@ interface EncodingConfig { val debugMode: Boolean } -@OptIn(TerpalSqlInternal::class) +@TerpalSqlInternal interface WithEncoding { val encodingConfig: EncodingConfig val startingStatementIndex: StartingIndex get() = StartingIndex.Zero // default for JDBC is 1 so this needs to be overrideable @@ -85,22 +86,34 @@ interface WithEncoding { } } -@OptIn(TerpalSqlInternal::class) +@TerpalSqlInternal interface RequiresSession { // Methods that implementors need to provide val sessionKey: CoroutineContext.Key> + + @TerpalSqlInternal abstract suspend fun newSession(executionOptions: ExecutionOpts): Session + + @TerpalSqlInternal abstract suspend fun closeSession(session: Session): Unit + + @TerpalSqlInternal abstract suspend fun isClosedSession(session: Session): Boolean + + @TerpalSqlInternal suspend fun accessStmt(sql: String, conn: Session, block: suspend (Stmt) -> R): R + + @TerpalSqlInternal suspend fun accessStmtReturning(sql: String, conn: Session, options: ExecutionOpts, returningColumns: List, block: suspend (Stmt) -> R): R + @TerpalSqlInternal suspend fun CoroutineContext.hasOpenConnection(): Boolean { val session = get(sessionKey)?.session return session != null && !isClosedSession(session) } + @TerpalSqlInternal suspend fun withConnection(executionOptions: ExecutionOpts, block: suspend CoroutineScope.() -> T): T { return if (coroutineContext.hasOpenConnection()) { withContext(coroutineContext + Dispatchers.IO) { block() } @@ -115,7 +128,7 @@ interface RequiresSession { } } - + @TerpalSqlInternal suspend fun localConnection() = coroutineContext.get(sessionKey)?.session ?: error("No connection detected in withConnection scope. This should be impossible.") @@ -140,9 +153,11 @@ interface RequiresSession { } } +@TerpalSqlInternal interface RequiresTransactionality: RequiresSession { abstract suspend fun runTransactionally(block: suspend CoroutineScope.() -> T): T + @TerpalSqlInternal suspend fun withTransactionScope(executionOptions: ExecutionOpts, block: suspend CoroutineScope.() -> T): T { val existingTransaction = coroutineContext[CoroutineTransaction] @@ -159,31 +174,29 @@ interface RequiresTransactionality: RequiresSessio } } -@OptIn(TerpalSqlInternal::class) interface ControllerVerbs { fun DefaultOpts(): ExecutionOpts - suspend fun stream(query: ControllerQuery, options: ExecutionOpts): Flow - suspend fun stream(query: ControllerBatchActionReturning, options: ExecutionOpts): Flow - suspend fun stream(query: ControllerActionReturning, options: ExecutionOpts): Flow - suspend fun run(query: ControllerQuery, options: ExecutionOpts): List - suspend fun run(query: ControllerAction, options: ExecutionOpts): Long - suspend fun run(query: ControllerBatchAction, options: ExecutionOpts): List - suspend fun run(query: ControllerActionReturning, options: ExecutionOpts): T - suspend fun run(query: ControllerBatchActionReturning, options: ExecutionOpts): List - - suspend fun runRaw(query: ControllerQuery, options: ExecutionOpts): List>> - - suspend fun stream(query: ControllerQuery): Flow = stream(query, DefaultOpts()) - suspend fun stream(query: ControllerBatchActionReturning): Flow = stream(query, DefaultOpts()) - suspend fun stream(query: ControllerActionReturning): Flow = stream(query, DefaultOpts()) - suspend fun run(query: ControllerQuery): List = run(query, DefaultOpts()) - suspend fun run(query: ControllerAction): Long = run(query, DefaultOpts()) - suspend fun run(query: ControllerBatchAction): List = run(query, DefaultOpts()) - suspend fun run(query: ControllerActionReturning): T = run(query, DefaultOpts()) - suspend fun run(query: ControllerBatchActionReturning): List = run(query, DefaultOpts()) - - suspend fun runRaw(query: ControllerQuery): List>> = runRaw(query, DefaultOpts()) + @TerpalSqlInternal suspend fun stream(query: ControllerQuery, options: ExecutionOpts): Flow + @TerpalSqlInternal suspend fun stream(query: ControllerBatchActionReturning, options: ExecutionOpts): Flow + @TerpalSqlInternal suspend fun stream(query: ControllerActionReturning, options: ExecutionOpts): Flow + @TerpalSqlInternal suspend fun run(query: ControllerQuery, options: ExecutionOpts): List + @TerpalSqlInternal suspend fun run(query: ControllerAction, options: ExecutionOpts): Long + @TerpalSqlInternal suspend fun run(query: ControllerBatchAction, options: ExecutionOpts): List + @TerpalSqlInternal suspend fun run(query: ControllerActionReturning, options: ExecutionOpts): T + @TerpalSqlInternal suspend fun run(query: ControllerBatchActionReturning, options: ExecutionOpts): List + + @TerpalSqlInternal suspend fun stream(query: ControllerQuery): Flow = stream(query, DefaultOpts()) + @TerpalSqlInternal suspend fun stream(query: ControllerBatchActionReturning): Flow = stream(query, DefaultOpts()) + @TerpalSqlInternal suspend fun stream(query: ControllerActionReturning): Flow = stream(query, DefaultOpts()) + @TerpalSqlInternal suspend fun run(query: ControllerQuery): List = run(query, DefaultOpts()) + @TerpalSqlInternal suspend fun run(query: ControllerAction): Long = run(query, DefaultOpts()) + @TerpalSqlInternal suspend fun run(query: ControllerBatchAction): List = run(query, DefaultOpts()) + @TerpalSqlInternal suspend fun run(query: ControllerActionReturning): T = run(query, DefaultOpts()) + @TerpalSqlInternal suspend fun run(query: ControllerBatchActionReturning): List = run(query, DefaultOpts()) + + @TerpalSqlInternal suspend fun runRaw(query: ControllerQuery, options: ExecutionOpts): List>> + @TerpalSqlInternal suspend fun runRaw(query: ControllerQuery): List>> = runRaw(query, DefaultOpts()) } /** @@ -191,16 +204,16 @@ interface ControllerVerbs { * This is a minimal set of semantics needed to support Sql-interpolated query executions. This makes minimal assumptions * about how the context functionality is composed. Typically implementations will want to start with ContextBase or ContextCannonical. */ -@OptIn(TerpalSqlInternal::class) interface Controller: ControllerVerbs { } -@OptIn(TerpalSqlInternal::class) -suspend fun Controller<*>.runActions(@Language("SQL") actions: String): List = +@TerpalSqlUnsafe +suspend fun Controller<*>.runActionsUnsafe(@Language("SQL") actions: String): Unit { actions.split(";").map { it.trim() }.filter { it.isNotEmpty() }.map { run(ControllerAction(it, listOf()), DefaultOpts()) } +} + -@OptIn(TerpalSqlInternal::class) interface ControllerTransactional: Controller, RequiresSession, RequiresTransactionality { fun showStats(): String = "" } @@ -210,7 +223,7 @@ interface ControllerTransactional: Controller: ControllerTransactional, RequiresSession, RequiresTransactionality, WithEncoding suspend fun ControllerQuery.runOn(ctx: Controller<*>) = ctx.run(this) @@ -218,6 +231,7 @@ suspend fun ControllerQuery.streamOn(ctx: Controller<*>) = ctx.stream(thi suspend fun ControllerQuery.runRawOn(ctx: Controller<*>) = ctx.runRaw(this) suspend fun ControllerAction.runOn(ctx: Controller<*>) = ctx.run(this) suspend fun ControllerActionReturning.runOn(ctx: Controller<*>) = ctx.run(this) +suspend fun ControllerActionReturning.streamOn(ctx: Controller<*>) = ctx.stream(this) suspend fun ControllerBatchAction.runOn(ctx: Controller<*>) = ctx.run(this) suspend fun ControllerBatchActionReturning.runOn(ctx: Controller<*>) = ctx.run(this) suspend fun ControllerBatchActionReturning.streamOn(ctx: Controller<*>) = ctx.stream(this) diff --git a/controller-jdbc/build.gradle.kts b/controller-jdbc/build.gradle.kts index 2b5e62b..7466c37 100644 --- a/controller-jdbc/build.gradle.kts +++ b/controller-jdbc/build.gradle.kts @@ -38,6 +38,12 @@ tasks.withType().configureEach { } kotlin { + compilerOptions { + optIn.addAll( + "io.exoquery.controller.TerpalSqlInternal" + ) + } + jvmToolchain(17) jvm { } diff --git a/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcController.kt b/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcController.kt index 6cc351e..62be138 100644 --- a/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcController.kt +++ b/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcController.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.flow.* import javax.sql.DataSource import java.sql.* +typealias RawColumnSet = List> /** * This is a Terpal Driver, NOT a JDBC driver! It is the base class for all JDBC-based implementations of the @@ -29,11 +30,23 @@ abstract class JdbcController internal constructor( override val startingStatementIndex = StartingIndex.One override val startingResultRowIndex = StartingIndex.One + @TerpalSqlInternal override fun extractColumnInfo(row: ResultSet): List = (1..row.metaData.columnCount).map { idx -> ColumnInfo(row.metaData.getColumnName(idx), row.metaData.getColumnTypeName(idx) ?: "") } + @TerpalSqlInternal + suspend fun FlowCollector>.emitResultSetBoth(conn: Connection, rs: ResultSet, extract: (Connection, ResultSet) -> T) { + val meta = rs.metaData + while (rs.next()) { + val extracted = extract(conn, rs) + val rowByRow = rs.makeColumnSet(meta) + emit(extracted to rowByRow) + } + } + + @TerpalSqlInternal suspend fun FlowCollector.emitResultSet(conn: Connection, rs: ResultSet, extract: (Connection, ResultSet) -> T) { while (rs.next()) { //val meta = rs.metaData @@ -42,6 +55,7 @@ abstract class JdbcController internal constructor( } } + @TerpalSqlInternal protected open suspend fun runActionReturningScoped(act: ControllerActionReturning, options: JdbcExecutionOptions): Flow = flowWithConnection(options) { val conn = localConnection() @@ -52,6 +66,18 @@ abstract class JdbcController internal constructor( } } + @TerpalSqlInternal + protected open suspend fun runActionReturningBothScoped(act: ControllerActionReturning, options: JdbcExecutionOptions): Flow> = + flowWithConnection(options) { + val conn = localConnection() + accessStmtReturning(act.sql, conn, options, act.returningColumns) { stmt -> + prepare(stmt, conn, act.params) + stmt.executeUpdate() + emitResultSetBoth(conn, options.prepareResult(stmt.generatedKeys), act.resultMaker.makeExtractor(QueryDebugInfo(act.sql))) + } + } + + @TerpalSqlInternal protected open suspend fun runBatchActionScoped(query: ControllerBatchAction, options: JdbcExecutionOptions): List = withConnection(options) { val conn = localConnection() @@ -65,6 +91,22 @@ abstract class JdbcController internal constructor( } } + @TerpalSqlInternal + protected open suspend fun runBatchActionReturningBothScoped(act: ControllerBatchActionReturning, options: JdbcExecutionOptions): Flow> = + flowWithConnection(options) { + val conn = localConnection() + accessStmtReturning(act.sql, conn, options, act.returningColumns) { stmt -> + // Each set of params is a batch + act.params.forEach { batch -> + prepare(stmt, conn, batch) + stmt.addBatch() + } + stmt.executeBatch() + emitResultSetBoth(conn, options.prepareResult(stmt.generatedKeys), act.resultMaker.makeExtractor(QueryDebugInfo(act.sql))) + } + } + + @TerpalSqlInternal protected open suspend fun runBatchActionReturningScoped(act: ControllerBatchActionReturning, options: JdbcExecutionOptions): Flow = flowWithConnection(options) { val conn = localConnection() @@ -79,6 +121,7 @@ abstract class JdbcController internal constructor( } } + @TerpalSqlInternal protected open suspend fun runActionScoped(sql: String, params: List>, options: JdbcExecutionOptions): Long = withConnection(options) { val conn = localConnection() @@ -90,7 +133,8 @@ abstract class JdbcController internal constructor( } } - override suspend fun runRaw(query: ControllerQuery, options: JdbcExecutionOptions) = + @TerpalSqlInternal + override suspend fun runRaw(query: ControllerQuery, options: JdbcExecutionOptions): List>> = withConnection(options) { val conn = localConnection() accessStmt(query.sql, conn) { stmt -> @@ -100,11 +144,7 @@ abstract class JdbcController internal constructor( options.prepareResult(stmt.executeQuery()).use { rs -> val meta = rs.metaData while (rs.next()) { - for (i in 1..meta.columnCount) { - val row = mutableListOf>() - row.add(meta.getColumnName(i) to rs.getString(i)) - result.add(row) - } + result.add(rs.makeColumnSet(meta)) } } } @@ -112,6 +152,14 @@ abstract class JdbcController internal constructor( } } + private fun ResultSet.makeColumnSet(meta: ResultSetMetaData): RawColumnSet { + val columns = mutableListOf>() + for (i in 1..meta.columnCount) { + columns.add(meta.getColumnName(i) to this.getString(i)) + } + return columns + } + override open suspend fun stream(query: ControllerQuery, options: JdbcExecutionOptions): Flow = flowWithConnection(options) { val conn = localConnection() @@ -125,6 +173,20 @@ abstract class JdbcController internal constructor( } } + @TerpalSqlInternal + suspend fun streamBoth(query: ControllerQuery, options: JdbcExecutionOptions): Flow> = + flowWithConnection(options) { + val conn = localConnection() + accessStmt(query.sql, conn) { stmt -> + prepare(stmt, conn, query.params) + tryCatchQuery(query.sql) { + options.prepareResult(stmt.executeQuery()).use { rs -> + emitResultSetBoth(conn, rs, query.resultMaker.makeExtractor(QueryDebugInfo(query.sql))) + } + } + } + } + private inline fun tryCatchQuery(sql: String, op: () -> T): T = try { op() @@ -132,6 +194,10 @@ abstract class JdbcController internal constructor( throw SQLException("Error executing query: ${sql}", e) } + @TerpalSqlInternal open suspend fun runBoth(query: ControllerQuery, options: JdbcExecutionOptions): List> = streamBoth(query, options).toList() + @TerpalSqlInternal open suspend fun streamBoth(query: ControllerBatchActionReturning, options: JdbcExecutionOptions): Flow> = runBatchActionReturningBothScoped(query, options) + @TerpalSqlInternal open suspend fun streamBoth(query: ControllerActionReturning, options: JdbcExecutionOptions): Flow> = runActionReturningBothScoped(query, options) + override open suspend fun stream(query: ControllerBatchActionReturning, options: JdbcExecutionOptions): Flow = runBatchActionReturningScoped(query, options) override open suspend fun stream(query: ControllerActionReturning, options: JdbcExecutionOptions): Flow = runActionReturningScoped(query, options) override open suspend fun run(query: ControllerQuery, options: JdbcExecutionOptions): List = stream(query, options).toList() diff --git a/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcControllers.kt b/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcControllers.kt index cda0daf..f586ddb 100644 --- a/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcControllers.kt +++ b/controller-jdbc/src/main/kotlin/io/exoquery/controller/jdbc/JdbcControllers.kt @@ -219,7 +219,6 @@ object JdbcControllers { val conn = localConnection() when (act) { is ControllerActionReturning.Id -> { - // TODO error looks like it should be impossible! accessStmtReturning(act.sql, conn, options, act.returningColumns) { stmt -> prepare(stmt, conn, act.params) // This is another oddity in SQL Server where the statement needs to be executed before .getGeneratedKeys() can be called. diff --git a/controller-native/build.gradle.kts b/controller-native/build.gradle.kts index a365f3c..1fa6260 100644 --- a/controller-native/build.gradle.kts +++ b/controller-native/build.gradle.kts @@ -23,6 +23,11 @@ tasks.named { it == "mingwX64Test" }.configureEach { enabled = HostManager.hostI tasks.named { it == "linkDebugTestMingwX64" }.configureEach { enabled = HostManager.hostIsMingw } kotlin { + compilerOptions { + optIn.addAll( + "io.exoquery.controller.TerpalSqlInternal" + ) + } val thisVersion = version diff --git a/controller-r2dbc/build.gradle.kts b/controller-r2dbc/build.gradle.kts index d6b3b94..f7deb04 100644 --- a/controller-r2dbc/build.gradle.kts +++ b/controller-r2dbc/build.gradle.kts @@ -13,6 +13,12 @@ repositories { } kotlin { + compilerOptions { + optIn.addAll( + "io.exoquery.controller.TerpalSqlInternal" + ) + } + jvmToolchain(17) jvm { } diff --git a/terpal-sql-android/src/androidInstrumentedTest/kotlin/io/exoquery/sql/android/instrumented/InstrumentedPerfSpec.kt b/terpal-sql-android/src/androidInstrumentedTest/kotlin/io/exoquery/sql/android/instrumented/InstrumentedPerfSpec.kt index 2794746..02a815b 100644 --- a/terpal-sql-android/src/androidInstrumentedTest/kotlin/io/exoquery/sql/android/instrumented/InstrumentedPerfSpec.kt +++ b/terpal-sql-android/src/androidInstrumentedTest/kotlin/io/exoquery/sql/android/instrumented/InstrumentedPerfSpec.kt @@ -6,6 +6,8 @@ import app.cash.sqldelight.driver.android.AndroidSqliteDriver import io.exoquery.sql.PerfSchema import io.exoquery.sql.WallPerformanceTest import io.exoquery.controller.android.AndroidDatabaseController +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import kotlinx.coroutines.runBlocking import org.junit.runner.RunWith import org.junit.Test @@ -20,6 +22,7 @@ class InstrumentedPerfTest: InstrumentedSpec { data class TestConfig(val maxReaders: Int?, val poolingMode: AndroidDatabaseController.PoolingMode) @Test + @OptIn(TerpalSqlUnsafe::class) fun runTest() { val name = "perf_test.db" val basePath = "./" @@ -37,9 +40,9 @@ class InstrumentedPerfTest: InstrumentedSpec { val driver = AndroidDatabaseController.fromApplicationContext(name, appContext, AndroidSqliteDriver.Callback(schema), poolingMode = poolingMode) println("------- Clearing Pref Table -------") - driver.runRaw(schema.clearQuery) + driver.runActionsUnsafe(schema.clearQuery) println("------- Reloading Pef Table Values -------") - driver.runRaw(schema.loadQuery) + driver.runActionsUnsafe(schema.loadQuery) messages.add( "[====== WAL Performance Test: ${conf} ======]" + WallPerformanceTest(driver, maxRow, 100, 1000, rand = random, maxReaders = conf.maxReaders).walPerfTest() diff --git a/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/BasicQuerySpec.kt b/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/BasicQuerySpec.kt index 18b6cb0..2970664 100644 --- a/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/BasicQuerySpec.kt +++ b/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/BasicQuerySpec.kt @@ -1,5 +1,7 @@ package io.exoquery.sql.android +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.sql.Sql import io.exoquery.sql.encodingdata.shouldBe @@ -16,8 +18,9 @@ class BasicQuerySpec { val ctx get() = TestDatabase.ctx @BeforeTest - fun clearTables() { - ctx.runRaw( + @OptIn(TerpalSqlUnsafe::class) + fun clearTables() = runBlocking { + ctx.runActionsUnsafe( """ DELETE FROM Person; DELETE FROM Address; diff --git a/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/EncodingSpec.kt b/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/EncodingSpec.kt index e99c285..53dffcf 100644 --- a/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/EncodingSpec.kt +++ b/terpal-sql-android/src/androidUnitTest/kotlin/io/exoquery/sql/android/EncodingSpec.kt @@ -1,6 +1,7 @@ package io.exoquery.sql.android -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.sql.Sql import io.exoquery.sql.android.encodingdata.JavaTestEntity @@ -10,7 +11,6 @@ import io.exoquery.sql.android.encodingdata.insertTimeEntity import io.exoquery.sql.encodingdata.insert import io.exoquery.sql.encodingdata.EncodingTestEntity import io.exoquery.sql.encodingdata.KmpTestEntity -import io.exoquery.sql.encodingdata.insertBatch import io.exoquery.sql.encodingdata.verify import kotlinx.coroutines.runBlocking import java.time.ZoneId @@ -26,8 +26,9 @@ class EncodingSpec { val ctx = TestDatabase.ctx @BeforeTest + @OptIn(TerpalSqlUnsafe::class) fun setup(): Unit = runBlocking { - ctx.runActions("DELETE FROM EncodingTestEntity") + ctx.runActionsUnsafe("DELETE FROM EncodingTestEntity") } @Test diff --git a/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/BasicActionOps.kt b/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/BasicActionOps.kt index dc9ea19..6cdc829 100644 --- a/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/BasicActionOps.kt +++ b/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/BasicActionOps.kt @@ -1,7 +1,8 @@ package io.exoquery.sql import io.exoquery.controller.ControllerTransactional -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.sql.encodingdata.shouldBe import kotlinx.coroutines.runBlocking @@ -10,8 +11,9 @@ import kotlinx.serialization.Serializable class BasicActionOps( val ctx: ControllerTransactional ) { + @OptIn(TerpalSqlUnsafe::class) fun clearTables(): Unit = runBlocking { - ctx.runActions( + ctx.runActionsUnsafe( """ DELETE FROM Person; DELETE FROM Address; diff --git a/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/TransactionSpecOps.kt b/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/TransactionSpecOps.kt index 4d21168..9e4912a 100644 --- a/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/TransactionSpecOps.kt +++ b/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/TransactionSpecOps.kt @@ -1,7 +1,8 @@ package io.exoquery.sql import io.exoquery.controller.ControllerTransactional -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.transaction import io.exoquery.sql.encodingdata.shouldBe @@ -12,8 +13,9 @@ class TransactionSpecOps( val ctx: ControllerTransactional, ) { + @OptIn(TerpalSqlUnsafe::class) fun clearTables(): Unit = runBlocking { - ctx.runActions( + ctx.runActionsUnsafe( """ DELETE FROM Person; DELETE FROM Address; diff --git a/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/WalConcurrencyOps.kt b/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/WalConcurrencyOps.kt index 96c4b49..e92bb21 100644 --- a/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/WalConcurrencyOps.kt +++ b/terpal-sql-core-testing/src/commonMain/kotlin/io/exoquery/sql/WalConcurrencyOps.kt @@ -1,7 +1,8 @@ package io.exoquery.sql import io.exoquery.controller.ControllerTransactional -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.transaction import kotlinx.atomicfu.atomic @@ -13,8 +14,9 @@ import kotlin.test.assertEquals class WalConcurrencyOps(val ctx: ControllerTransactional) { + @OptIn(TerpalSqlUnsafe::class) fun clearTables(): Unit = runBlocking { - ctx.runActions( + ctx.runActionsUnsafe( """ DELETE FROM MiscTest """ diff --git a/terpal-sql-core/src/commonMain/kotlin/io/exoquery/controller/Transactions.kt b/terpal-sql-core/src/commonMain/kotlin/io/exoquery/controller/Transactions.kt index fe23b93..1f5ecbe 100644 --- a/terpal-sql-core/src/commonMain/kotlin/io/exoquery/controller/Transactions.kt +++ b/terpal-sql-core/src/commonMain/kotlin/io/exoquery/controller/Transactions.kt @@ -2,15 +2,18 @@ package io.exoquery.controller import kotlinx.coroutines.CoroutineScope +@OptIn(TerpalSqlInternal::class) suspend fun ControllerTransactional.transaction(executionOptions: ExecutionOpts, block: suspend ExternalTransactionScope.() -> T): T = withTransactionScope(executionOptions) { val coroutineScope = this block(ExternalTransactionScope(coroutineScope, this@transaction)) } +@OptIn(TerpalSqlInternal::class) suspend fun ControllerTransactional.transaction(block: suspend ExternalTransactionScope.() -> T): T = transaction(this.DefaultOpts(), block) +@OptIn(TerpalSqlInternal::class) class ExternalTransactionScope(private val scope: CoroutineScope, private val ctx: Controller) { suspend fun ControllerQuery.run(options: ExecutionOpts = ctx.DefaultOpts()): List = ctx.run(this, options) suspend fun ControllerAction.run(options: ExecutionOpts = ctx.DefaultOpts()): Long = ctx.run(this, options) diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicActionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicActionSpec.kt index fdade7c..6f05a98 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicActionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicActionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.h2 +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -14,7 +15,8 @@ class BasicActionSpec : FreeSpec({ val cf = TestDatabasesR2dbc.h2 val ctx: R2dbcController by lazy { R2dbcControllers.H2(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicQuerySpec.kt index ed8e658..8065d09 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BasicQuerySpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.h2 +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -15,7 +16,8 @@ class BasicQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.h2 val ctx: R2dbcController by lazy { R2dbcControllers.H2(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeSpec { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BatchValuesSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BatchValuesSpec.kt index c37507e..d60a61d 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BatchValuesSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/BatchValuesSpec.kt @@ -1,14 +1,13 @@ package io.exoquery.r2dbc.h2 +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.Ex1_BatchInsertNormal import io.exoquery.r2dbc.Ex2_BatchInsertMixed -import io.exoquery.r2dbc.Ex3_BatchReturnIds import io.exoquery.r2dbc.Ex3_BatchReturnIdsExplicit -import io.exoquery.r2dbc.Ex4_BatchReturnRecord import io.exoquery.r2dbc.TestDatabasesR2dbc import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe @@ -18,7 +17,8 @@ class BatchValuesSpec: FreeSpec ({ val cf = TestDatabasesR2dbc.h2 val ctx: R2dbcController by lazy { R2dbcControllers.H2(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions("TRUNCATE TABLE Product; ALTER TABLE Product ALTER COLUMN id RESTART WITH 1;") diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/EncodingSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/EncodingSpec.kt index 43d3992..43b0fd1 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/EncodingSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/EncodingSpec.kt @@ -1,9 +1,10 @@ package io.exoquery.r2dbc.h2 +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.sql.encodingdata.* import io.exoquery.sql.Sql import io.exoquery.controller.runOn -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.kotest.core.spec.style.FreeSpec import java.time.ZoneId import io.exoquery.controller.r2dbc.R2dbcController @@ -11,7 +12,6 @@ import io.exoquery.controller.r2dbc.R2dbcControllers import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.r2dbc.encodingdata.JavaTestEntity import io.exoquery.r2dbc.encodingdata.SimpleTimeEntity -import io.exoquery.r2dbc.encodingdata.encodingConfig import io.exoquery.r2dbc.encodingdata.insert import io.exoquery.r2dbc.encodingdata.verify @@ -20,7 +20,8 @@ class EncodingSpec: FreeSpec({ val cf = TestDatabasesR2dbc.h2 val ctx: R2dbcController by lazy { R2dbcControllers.H2(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { // The main table used across many tests diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/InQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/InQuerySpec.kt index 7fab28b..b312c1a 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/InQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/InQuerySpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.h2 +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Params @@ -16,7 +17,8 @@ class InQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.h2 val ctx: R2dbcController by lazy { R2dbcControllers.H2(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeSpec { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/TransactionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/TransactionSpec.kt index 10c6c90..a9a622a 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/TransactionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/h2/TransactionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.h2 +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.transaction import io.exoquery.r2dbc.TestDatabasesR2dbc @@ -12,11 +13,12 @@ import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.Serializable +@OptIn(TerpalSqlUnsafe::class) class TransactionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.h2 val ctx: R2dbcController by lazy { R2dbcControllers.H2(connectionFactory = cf) } beforeEach { - ctx.runActions( + ctx.runActionsUnsafe( """ DELETE FROM Person; DELETE FROM Address; diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicActionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicActionSpec.kt index 23bfa03..8e761fa 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicActionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicActionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.mysql +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -14,7 +15,8 @@ class BasicActionSpec : FreeSpec({ val cf = TestDatabasesR2dbc.mysql val ctx: R2dbcController by lazy { R2dbcControllers.Mysql(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicQuerySpec.kt index 9be243f..8622abf 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/BasicQuerySpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.mysql +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -15,7 +16,8 @@ class BasicQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.mysql val ctx: R2dbcController by lazy { R2dbcControllers.Mysql(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeSpec { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/EncodingSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/EncodingSpec.kt index 0643f69..8db1f85 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/EncodingSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/EncodingSpec.kt @@ -1,9 +1,10 @@ package io.exoquery.r2dbc.mysql +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.sql.encodingdata.* import io.exoquery.sql.Sql import io.exoquery.controller.runOn -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.kotest.core.spec.style.FreeSpec import java.time.ZoneId import io.exoquery.controller.r2dbc.R2dbcController @@ -11,7 +12,6 @@ import io.exoquery.controller.r2dbc.R2dbcControllers import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.r2dbc.encodingdata.JavaTestEntity import io.exoquery.r2dbc.encodingdata.SimpleTimeEntity -import io.exoquery.r2dbc.encodingdata.encodingConfig import io.exoquery.r2dbc.encodingdata.insert import io.exoquery.r2dbc.encodingdata.verify @@ -20,7 +20,8 @@ class EncodingSpec: FreeSpec({ val cf = TestDatabasesR2dbc.mysql val ctx: R2dbcController by lazy { R2dbcControllers.Mysql(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { // The main table used across many tests diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InQuerySpec.kt index c211a25..85120b9 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InQuerySpec.kt @@ -1,6 +1,7 @@ package io.exoquery.r2dbc.mysql -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers @@ -16,7 +17,8 @@ class InQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.mysql val ctx: R2dbcController by lazy { R2dbcControllers.Mysql(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) @Serializable data class Person(val id: Int, val firstName: String, val lastName: String, val age: Int) diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InjectionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InjectionSpec.kt index 3a5f11d..74c4555 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InjectionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/InjectionSpec.kt @@ -1,6 +1,7 @@ package io.exoquery.r2dbc.mysql -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers @@ -18,7 +19,8 @@ class InjectionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.mysql val ctx: R2dbcController by lazy { R2dbcControllers.Mysql(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/TransactionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/TransactionSpec.kt index c3493ad..90924eb 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/TransactionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/mysql/TransactionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.mysql +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.transaction import io.exoquery.r2dbc.TestDatabasesR2dbc @@ -12,11 +13,12 @@ import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.Serializable +@OptIn(TerpalSqlUnsafe::class) class TransactionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.mysql val ctx: R2dbcController by lazy { R2dbcControllers.Mysql(connectionFactory = cf) } beforeEach { - ctx.runActions( + ctx.runActionsUnsafe( """ DELETE FROM Person; ALTER TABLE Person AUTO_INCREMENT = 1; diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicActionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicActionSpec.kt index 38995b5..5a4697e 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicActionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicActionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.oracle +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -14,7 +15,8 @@ class BasicActionSpec : FreeSpec({ val cf = TestDatabasesR2dbc.oracle val ctx: R2dbcController by lazy { R2dbcControllers.Oracle(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicQuerySpec.kt index e8c6dae..f59a851 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/BasicQuerySpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.oracle +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -15,7 +16,8 @@ class BasicQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.oracle val ctx: R2dbcController by lazy { R2dbcControllers.Oracle(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeSpec { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/EncodingSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/EncodingSpec.kt index 14ee9cb..a5f1d26 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/EncodingSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/EncodingSpec.kt @@ -1,9 +1,10 @@ package io.exoquery.r2dbc.oracle +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.sql.encodingdata.* import io.exoquery.sql.Sql import io.exoquery.controller.runOn -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.kotest.core.spec.style.FreeSpec import java.time.ZoneId import io.exoquery.controller.r2dbc.R2dbcController @@ -11,7 +12,6 @@ import io.exoquery.controller.r2dbc.R2dbcControllers import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.r2dbc.encodingdata.JavaTestEntity import io.exoquery.r2dbc.encodingdata.SimpleTimeEntity -import io.exoquery.r2dbc.encodingdata.encodingConfig import io.exoquery.r2dbc.encodingdata.insert import io.exoquery.r2dbc.encodingdata.verify @@ -20,7 +20,8 @@ class EncodingSpec: FreeSpec({ val cf = TestDatabasesR2dbc.oracle val ctx: R2dbcController by lazy { R2dbcControllers.Oracle(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { // The main table used across many tests diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InQuerySpec.kt index 9d5718a..82693d1 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InQuerySpec.kt @@ -1,6 +1,7 @@ package io.exoquery.r2dbc.oracle -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers @@ -16,7 +17,8 @@ class InQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.oracle val ctx: R2dbcController by lazy { R2dbcControllers.Oracle(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) @Serializable data class Person(val id: Int, val firstName: String, val lastName: String, val age: Int) diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InjectionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InjectionSpec.kt index 961ac25..ee41e92 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InjectionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/InjectionSpec.kt @@ -1,6 +1,7 @@ package io.exoquery.r2dbc.oracle -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers @@ -18,7 +19,8 @@ class InjectionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.oracle val ctx: R2dbcController by lazy { R2dbcControllers.Oracle(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/TransactionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/TransactionSpec.kt index 7614ac5..a373be7 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/TransactionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/oracle/TransactionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.oracle +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.transaction import io.exoquery.r2dbc.TestDatabasesR2dbc @@ -12,11 +13,12 @@ import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.Serializable +@OptIn(TerpalSqlUnsafe::class) class TransactionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.oracle val ctx: R2dbcController by lazy { R2dbcControllers.Oracle(connectionFactory = cf) } beforeEach { - ctx.runActions( + ctx.runActionsUnsafe( """ DELETE FROM Person; DELETE FROM Address; diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicActionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicActionSpec.kt index 14c1455..3f99b67 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicActionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicActionSpec.kt @@ -1,7 +1,8 @@ package io.exoquery.r2dbc.postgres +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.runOn -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.sql.Sql import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe @@ -16,7 +17,8 @@ class BasicActionSpec : FreeSpec({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicQuerySpec.kt index c7489dc..56354d3 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BasicQuerySpec.kt @@ -1,7 +1,8 @@ package io.exoquery.r2dbc.postgres +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.runOn -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.sql.Sql import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe @@ -17,7 +18,8 @@ class BasicQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeSpec { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BatchValuesSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BatchValuesSpec.kt index dc4c8a9..7e0b5ea 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BatchValuesSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/BatchValuesSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.postgres +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.Ex1_BatchInsertNormal import io.exoquery.r2dbc.Ex2_BatchInsertMixed @@ -17,7 +18,8 @@ class BatchValuesSpec: FreeSpec ({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions("TRUNCATE TABLE Product RESTART IDENTITY CASCADE") diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/EncodingSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/EncodingSpec.kt index b14bb69..6f3b9a5 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/EncodingSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/EncodingSpec.kt @@ -1,9 +1,10 @@ package io.exoquery.r2dbc.postgres +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.sql.encodingdata.* import io.exoquery.sql.Sql import io.exoquery.controller.runOn -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.kotest.core.spec.style.FreeSpec import java.time.ZoneId import io.exoquery.controller.r2dbc.R2dbcController @@ -11,7 +12,6 @@ import io.exoquery.controller.r2dbc.R2dbcControllers import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.r2dbc.encodingdata.JavaTestEntity import io.exoquery.r2dbc.encodingdata.SimpleTimeEntity -import io.exoquery.r2dbc.encodingdata.encodingConfig import io.exoquery.r2dbc.encodingdata.insert import io.exoquery.r2dbc.encodingdata.verify @@ -20,7 +20,8 @@ class EncodingSpec: FreeSpec({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { // The main table used across many tests diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InQuerySpec.kt index a0aec17..cedb96c 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InQuerySpec.kt @@ -1,6 +1,7 @@ package io.exoquery.r2dbc.postgres -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers @@ -17,7 +18,8 @@ class InQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeSpec { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InjectionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InjectionSpec.kt index d0206c4..2fe6866 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InjectionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/InjectionSpec.kt @@ -1,6 +1,7 @@ package io.exoquery.r2dbc.postgres -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers @@ -18,7 +19,8 @@ class InjectionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions("DELETE FROM Person") diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/JsonSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/JsonSpec.kt index c32bec1..ee7b63a 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/JsonSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/JsonSpec.kt @@ -2,9 +2,10 @@ package io.exoquery.r2dbc.postgres import io.exoquery.controller.JsonValue import io.exoquery.controller.SqlJsonValue +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Param @@ -30,7 +31,8 @@ class JsonSpec: FreeSpec({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions("DELETE FROM JsonbExample") diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/TransactionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/TransactionSpec.kt index 03f92b6..7ef4c64 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/TransactionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/postgres/TransactionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.sql.postgres +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.transaction import io.exoquery.r2dbc.TestDatabasesR2dbc @@ -12,11 +13,12 @@ import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.Serializable +@OptIn(TerpalSqlUnsafe::class) class TransactionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.postgres val ctx: R2dbcController by lazy { R2dbcControllers.Postgres(connectionFactory = cf) } beforeEach { - ctx.runActions( + ctx.runActionsUnsafe( """ DELETE FROM Person; DELETE FROM Address; diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicActionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicActionSpec.kt index 5c0656a..6189894 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicActionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicActionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.sqlserver +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -14,7 +15,8 @@ class BasicActionSpec : FreeSpec({ val cf = TestDatabasesR2dbc.sqlServer val ctx: R2dbcController by lazy { R2dbcControllers.SqlServer(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicQuerySpec.kt index df838ae..7ba1e89 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/BasicQuerySpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.sqlserver +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Sql @@ -15,7 +16,8 @@ class BasicQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.sqlServer val ctx: R2dbcController by lazy { R2dbcControllers.SqlServer(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeSpec { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/EncodingSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/EncodingSpec.kt index fa9f4fd..4cb1a65 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/EncodingSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/EncodingSpec.kt @@ -1,9 +1,10 @@ package io.exoquery.r2dbc.sqlserver +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.sql.encodingdata.* import io.exoquery.sql.Sql import io.exoquery.controller.runOn -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.kotest.core.spec.style.FreeSpec import java.time.ZoneId import io.exoquery.controller.r2dbc.R2dbcController @@ -11,7 +12,6 @@ import io.exoquery.controller.r2dbc.R2dbcControllers import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.r2dbc.encodingdata.JavaTestEntity import io.exoquery.r2dbc.encodingdata.SimpleTimeEntity -import io.exoquery.r2dbc.encodingdata.encodingConfig import io.exoquery.r2dbc.encodingdata.insert import io.exoquery.r2dbc.encodingdata.verify @@ -20,7 +20,8 @@ class EncodingSpec: FreeSpec({ val cf = TestDatabasesR2dbc.sqlServer val ctx: R2dbcController by lazy { R2dbcControllers.SqlServer(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { // The main table used across many tests diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InQuerySpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InQuerySpec.kt index 4fe016c..61a2d3d 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InQuerySpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InQuerySpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.sqlserver +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.r2dbc.TestDatabasesR2dbc import io.exoquery.sql.Params @@ -16,7 +17,8 @@ class InQuerySpec : FreeSpec({ val cf = TestDatabasesR2dbc.sqlServer val ctx: R2dbcController by lazy { R2dbcControllers.SqlServer(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) @Serializable data class Person(val id: Int, val firstName: String, val lastName: String, val age: Int) diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InjectionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InjectionSpec.kt index 2ac2742..ce9e45b 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InjectionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/InjectionSpec.kt @@ -1,6 +1,7 @@ package io.exoquery.r2dbc.sqlserver -import io.exoquery.controller.runActions +import io.exoquery.controller.TerpalSqlUnsafe +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers @@ -18,7 +19,8 @@ class InjectionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.sqlServer val ctx: R2dbcController by lazy { R2dbcControllers.SqlServer(connectionFactory = cf) } - suspend fun runActions(actions: String) = ctx.runActions(actions) + @OptIn(TerpalSqlUnsafe::class) + suspend fun runActions(actions: String) = ctx.runActionsUnsafe(actions) beforeEach { runActions( diff --git a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/TransactionSpec.kt b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/TransactionSpec.kt index 36492fc..8d1aabe 100644 --- a/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/TransactionSpec.kt +++ b/terpal-sql-r2dbc/src/test/kotlin/io/exoquery/r2dbc/sqlserver/TransactionSpec.kt @@ -1,8 +1,9 @@ package io.exoquery.r2dbc.sqlserver +import io.exoquery.controller.TerpalSqlUnsafe import io.exoquery.controller.r2dbc.R2dbcController import io.exoquery.controller.r2dbc.R2dbcControllers -import io.exoquery.controller.runActions +import io.exoquery.controller.runActionsUnsafe import io.exoquery.controller.runOn import io.exoquery.controller.transaction import io.exoquery.r2dbc.TestDatabasesR2dbc @@ -12,11 +13,12 @@ import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.Serializable +@OptIn(TerpalSqlUnsafe::class) class TransactionSpec: FreeSpec({ val cf = TestDatabasesR2dbc.sqlServer val ctx: R2dbcController by lazy { R2dbcControllers.SqlServer(connectionFactory = cf) } beforeEach { - ctx.runActions( + ctx.runActionsUnsafe( """ TRUNCATE TABLE Person; DBCC CHECKIDENT ('Person', RESEED, 1); DELETE FROM Address; From 2b20cf9e980183e7d5afc207856ae88134e89498 Mon Sep 17 00:00:00 2001 From: Alexander Ioffe Date: Tue, 2 Dec 2025 21:58:39 -0500 Subject: [PATCH 2/2] Bump to 4.3.0 --- build-logic/src/main/kotlin/conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-logic/src/main/kotlin/conventions.gradle.kts b/build-logic/src/main/kotlin/conventions.gradle.kts index e07cf1e..92a2d5f 100644 --- a/build-logic/src/main/kotlin/conventions.gradle.kts +++ b/build-logic/src/main/kotlin/conventions.gradle.kts @@ -7,7 +7,7 @@ repositories { mavenLocal() } -val controllerVersion = "4.2.0" +val controllerVersion = "4.3.0" val pluginVersion = "2.0.0.PL" extra["controllerVersion"] = controllerVersion