From 81c0f266e69409b43d102227418eee3b98d83e17 Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 10:30:51 -0400 Subject: [PATCH 01/10] Improve async support for Cursors --- .../driver/android/AndroidSqliteDriver.kt | 8 ++-- .../cash/sqldelight/driver/jdbc/JdbcDriver.kt | 12 +++--- .../driver/native/NativeSqlDatabase.kt | 10 ++--- .../driver/native/SqliterSqlCursor.kt | 3 +- .../sqldelight/driver/r2dbc/R2dbcDriver.kt | 6 +-- .../sqldelight/driver/sqljs/JsSqlDriver.kt | 6 +-- .../driver/worker/WebWorkerDriver.kt | 6 +-- .../async/coroutines/DriverExtensions.kt | 5 ++- .../async/coroutines/QueryExtensions.kt | 19 +++++---- .../kotlin/app/cash/sqldelight/Query.kt | 16 +++---- .../app/cash/sqldelight/db/SqlCursor.kt | 2 +- .../app/cash/sqldelight/db/SqlDriver.kt | 2 +- .../cash/sqldelight/logs/LogSqliteDriver.kt | 2 +- .../sqldelight/logs/LogSqliteDriverTest.kt | 10 ++--- .../core/compiler/SelectQueryGenerator.kt | 6 ++- .../cash/sqldelight/core/QueriesTypeTest.kt | 6 +-- .../core/async/AsyncQueriesTypeTest.kt | 2 +- .../core/queries/InterfaceGeneration.kt | 6 +-- .../core/queries/SelectQueryFunctionTest.kt | 4 +- .../core/queries/SelectQueryTypeTest.kt | 42 +++++++++---------- .../queries/async/AsyncSelectQueryTypeTest.kt | 4 +- .../shared/common/data/SharedDatabase.kt | 9 ++-- .../main/kotlin/com/example/db/DbHelper.kt | 7 ++-- 23 files changed, 98 insertions(+), 95 deletions(-) diff --git a/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt b/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt index 3bbe7396fc0..4ca4dd42c5c 100644 --- a/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt +++ b/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt @@ -141,7 +141,7 @@ class AndroidSqliteDriver private constructor( createStatement: () -> AndroidStatement, binders: (SqlPreparedStatement.() -> Unit)?, result: AndroidStatement.() -> T, - ): QueryResult { + ): QueryResult.Value { var statement: AndroidStatement? = null if (identifier != null) { statement = statements.remove(identifier) @@ -171,10 +171,10 @@ class AndroidSqliteDriver private constructor( override fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, - ) = execute(identifier, { AndroidQuery(sql, database, parameters) }, binders) { executeQuery(mapper) } + ) = execute(identifier, { AndroidQuery(sql, database, parameters) }, binders) { executeQuery(mapper) }.value override fun close() { statements.evictAll() @@ -303,7 +303,7 @@ private class AndroidQuery( private class AndroidCursor( private val cursor: Cursor, ) : SqlCursor { - override fun next() = cursor.moveToNext() + override fun next(): QueryResult.Value = QueryResult.Value(cursor.moveToNext()) override fun getString(index: Int) = if (cursor.isNull(index)) null else cursor.getString(index) override fun getLong(index: Int) = if (cursor.isNull(index)) null else cursor.getLong(index) override fun getBytes(index: Int) = if (cursor.isNull(index)) null else cursor.getBlob(index) diff --git a/drivers/jdbc-driver/src/main/kotlin/app/cash/sqldelight/driver/jdbc/JdbcDriver.kt b/drivers/jdbc-driver/src/main/kotlin/app/cash/sqldelight/driver/jdbc/JdbcDriver.kt index f8422840d61..24068138840 100644 --- a/drivers/jdbc-driver/src/main/kotlin/app/cash/sqldelight/driver/jdbc/JdbcDriver.kt +++ b/drivers/jdbc-driver/src/main/kotlin/app/cash/sqldelight/driver/jdbc/JdbcDriver.kt @@ -141,17 +141,15 @@ abstract class JdbcDriver : SqlDriver, ConnectionManager { override fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, ): QueryResult { val (connection, onClose) = connectionAndClose() try { - return QueryResult.Value( - JdbcPreparedStatement(connection.prepareStatement(sql)) - .apply { if (binders != null) this.binders() } - .executeQuery(mapper), - ) + return JdbcPreparedStatement(connection.prepareStatement(sql)) + .apply { if (binders != null) this.binders() } + .executeQuery(mapper) } finally { onClose() } @@ -310,5 +308,5 @@ class JdbcCursor(val resultSet: ResultSet) : SqlCursor { private fun getAtIndex(index: Int, converter: (Int) -> T): T? = converter(index + 1).takeUnless { resultSet.wasNull() } - override fun next() = resultSet.next() + override fun next(): QueryResult.Value = QueryResult.Value(resultSet.next()) } diff --git a/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/NativeSqlDatabase.kt b/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/NativeSqlDatabase.kt index af2f7bb4059..d0f9bee05a0 100644 --- a/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/NativeSqlDatabase.kt +++ b/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/NativeSqlDatabase.kt @@ -63,14 +63,12 @@ sealed class ConnectionWrapper : SqlDriver { final override fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, - ): QueryResult = QueryResult.Value( - accessStatement(true, identifier, sql, binders) { statement -> - mapper(SqliterSqlCursor(statement.query())) - }, - ) + ): QueryResult = accessStatement(true, identifier, sql, binders) { statement -> + mapper(SqliterSqlCursor(statement.query())) + } } /** diff --git a/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/SqliterSqlCursor.kt b/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/SqliterSqlCursor.kt index ff4ccff4447..e1a4cd02a94 100644 --- a/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/SqliterSqlCursor.kt +++ b/drivers/native-driver/src/nativeMain/kotlin/app/cash/sqldelight/driver/native/SqliterSqlCursor.kt @@ -1,5 +1,6 @@ package app.cash.sqldelight.driver.native +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import co.touchlab.sqliter.Cursor import co.touchlab.sqliter.getBytesOrNull @@ -25,5 +26,5 @@ internal class SqliterSqlCursor(private val cursor: Cursor) : SqlCursor { return (cursor.getLongOrNull(index) ?: return null) == 1L } - override fun next(): Boolean = cursor.next() + override fun next(): QueryResult.Value = QueryResult.Value(cursor.next()) } diff --git a/drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt b/drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt index 86b75bda024..54bb82876b4 100644 --- a/drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt +++ b/drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt @@ -17,7 +17,7 @@ class R2dbcDriver(val connection: Connection) : SqlDriver { override fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, ): QueryResult { @@ -32,7 +32,7 @@ class R2dbcDriver(val connection: Connection) : SqlDriver { List(rowMetadata.columnMetadatas.size) { index -> row.get(index) } }.asFlow().toList() - return@AsyncValue mapper(R2dbcCursor(rowSet)) + return@AsyncValue mapper(R2dbcCursor(rowSet)).await() } } @@ -157,7 +157,7 @@ class R2dbcCursor(val rowSet: List>) : SqlCursor { var row = -1 private set - override fun next(): Boolean = ++row < rowSet.size + override fun next(): QueryResult.Value = QueryResult.Value(++row < rowSet.size) override fun getString(index: Int): String? = rowSet[row][index] as String? diff --git a/drivers/sqljs-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/sqljs/JsSqlDriver.kt b/drivers/sqljs-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/sqljs/JsSqlDriver.kt index c6561547f58..2ce1719d673 100644 --- a/drivers/sqljs-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/sqljs/JsSqlDriver.kt +++ b/drivers/sqljs-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/sqljs/JsSqlDriver.kt @@ -50,7 +50,7 @@ class JsSqlDriver(private val db: Database) : SqlDriver { override fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, ): QueryResult { @@ -60,7 +60,7 @@ class JsSqlDriver(private val db: Database) : SqlDriver { } return try { - QueryResult.Value(mapper(cursor)) + mapper(cursor) } finally { cursor.close() } @@ -120,7 +120,7 @@ class JsSqlDriver(private val db: Database) : SqlDriver { } private class JsSqlCursor(private val statement: Statement) : SqlCursor { - override fun next(): Boolean = statement.step() + override fun next(): QueryResult.Value = QueryResult.Value(statement.step()) override fun getString(index: Int): String? = statement.get()[index] override fun getLong(index: Int): Long? = (statement.get()[index] as? Double)?.toLong() override fun getBytes(index: Int): ByteArray? = (statement.get()[index] as? Uint8Array)?.let { diff --git a/drivers/web-worker-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/worker/WebWorkerDriver.kt b/drivers/web-worker-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/worker/WebWorkerDriver.kt index 5e983fc3866..cd9810f0a4f 100644 --- a/drivers/web-worker-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/worker/WebWorkerDriver.kt +++ b/drivers/web-worker-driver/src/jsMain/kotlin/app/cash/sqldelight/driver/worker/WebWorkerDriver.kt @@ -34,7 +34,7 @@ class WebWorkerDriver(private val worker: Worker) : SqlDriver { private var messageCounter = 0 private var transaction: Transacter.Transaction? = null - override fun executeQuery(identifier: Int?, sql: String, mapper: (SqlCursor) -> R, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?): QueryResult { + override fun executeQuery(identifier: Int?, sql: String, mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?): QueryResult { val bound = JsWorkerSqlPreparedStatement() binders?.invoke(bound) @@ -44,7 +44,7 @@ class WebWorkerDriver(private val worker: Worker) : SqlDriver { this.params = bound.parameters.toTypedArray() } - return@AsyncValue mapper(JsWorkerSqlCursor(checkWorkerResults(response.results))) + return@AsyncValue mapper(JsWorkerSqlCursor(checkWorkerResults(response.results))).await() } } @@ -168,7 +168,7 @@ private external interface RequestBuilder { internal class JsWorkerSqlCursor(private val values: Array>) : SqlCursor { private var currentRow = -1 - override fun next(): Boolean = ++currentRow < values.size + override fun next(): QueryResult.Value = QueryResult.Value(++currentRow < values.size) override fun getString(index: Int): String? = values[currentRow][index].unsafeCast() diff --git a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/DriverExtensions.kt b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/DriverExtensions.kt index 3d371f4a94e..40e25a7c578 100644 --- a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/DriverExtensions.kt +++ b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/DriverExtensions.kt @@ -1,5 +1,6 @@ package app.cash.sqldelight.async.coroutines +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlPreparedStatement @@ -8,10 +9,10 @@ import app.cash.sqldelight.db.SqlSchema suspend fun SqlDriver.awaitQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: suspend (SqlCursor) -> R, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)? = null, -): R = executeQuery(identifier, sql, mapper, parameters, binders).await() +): R = executeQuery(identifier, sql, { QueryResult.AsyncValue { mapper(it) } }, parameters, binders).await() suspend fun SqlDriver.await( identifier: Int?, diff --git a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt index 52808bc141a..3873aa3a376 100644 --- a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt +++ b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt @@ -1,11 +1,14 @@ package app.cash.sqldelight.async.coroutines import app.cash.sqldelight.ExecutableQuery +import app.cash.sqldelight.db.QueryResult suspend fun ExecutableQuery.awaitAsList(): List = execute { cursor -> - val result = mutableListOf() - while (cursor.next()) result.add(mapper(cursor)) - result + QueryResult.AsyncValue { + val result = mutableListOf() + while (cursor.next().await()) result.add(mapper(cursor)) + result + } }.await() suspend fun ExecutableQuery.awaitAsOne(): T { @@ -14,8 +17,10 @@ suspend fun ExecutableQuery.awaitAsOne(): T { } suspend fun ExecutableQuery.awaitAsOneOrNull(): T? = execute { cursor -> - if (!cursor.next()) return@execute null - val value = mapper(cursor) - check(!cursor.next()) { "ResultSet returned more than 1 row for $this" } - value + QueryResult.AsyncValue { + if (!cursor.next().await()) return@AsyncValue null + val value = mapper(cursor) + check(!cursor.next().await()) { "ResultSet returned more than 1 row for $this" } + value + } }.await() diff --git a/runtime/src/commonMain/kotlin/app/cash/sqldelight/Query.kt b/runtime/src/commonMain/kotlin/app/cash/sqldelight/Query.kt index 05d95b10820..bce2417fb1d 100644 --- a/runtime/src/commonMain/kotlin/app/cash/sqldelight/Query.kt +++ b/runtime/src/commonMain/kotlin/app/cash/sqldelight/Query.kt @@ -94,7 +94,7 @@ private class SimpleQuery( private val query: String, mapper: (SqlCursor) -> RowType, ) : Query(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return driver.executeQuery(identifier, query, mapper, 0, null) } @@ -117,7 +117,7 @@ private class SimpleExecutableQuery( private val query: String, mapper: (SqlCursor) -> RowType, ) : ExecutableQuery(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return driver.executeQuery(identifier, query, mapper, 0, null) } @@ -166,15 +166,15 @@ abstract class ExecutableQuery( * * The cursor is closed automatically after the block returns. */ - abstract fun execute(mapper: (SqlCursor) -> R): QueryResult + abstract fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult /** * @return The result set of the underlying SQL statement as a list of [RowType]. */ fun executeAsList(): List = execute { cursor -> val result = mutableListOf() - while (cursor.next()) result.add(mapper(cursor)) - result + while (cursor.next().value) result.add(mapper(cursor)) + QueryResult.Value(result) }.value /** @@ -196,9 +196,9 @@ abstract class ExecutableQuery( * @throws IllegalStateException if when executed this query has multiple rows in its result set. */ fun executeAsOneOrNull(): RowType? = execute { cursor -> - if (!cursor.next()) return@execute null + if (!cursor.next().value) return@execute QueryResult.Value(null) val value = mapper(cursor) - check(!cursor.next()) { "ResultSet returned more than 1 row for $this" } - value + check(!cursor.next().value) { "ResultSet returned more than 1 row for $this" } + QueryResult.Value(value) }.value } diff --git a/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlCursor.kt b/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlCursor.kt index 99fd71730a8..6872efbe9fa 100644 --- a/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlCursor.kt +++ b/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlCursor.kt @@ -26,7 +26,7 @@ interface SqlCursor { * @return true if the cursor successfully moved to a new row, false if there was no row to * iterate to. */ - fun next(): Boolean + fun next(): QueryResult /** * @return The string or null value of column [index] for the current row of the result set. diff --git a/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlDriver.kt b/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlDriver.kt index 36a1e1b21ea..657df367b71 100644 --- a/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlDriver.kt +++ b/runtime/src/commonMain/kotlin/app/cash/sqldelight/db/SqlDriver.kt @@ -40,7 +40,7 @@ interface SqlDriver : Closeable { fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)? = null, ): QueryResult diff --git a/runtime/src/commonMain/kotlin/app/cash/sqldelight/logs/LogSqliteDriver.kt b/runtime/src/commonMain/kotlin/app/cash/sqldelight/logs/LogSqliteDriver.kt index d838596cad0..18ec442baba 100644 --- a/runtime/src/commonMain/kotlin/app/cash/sqldelight/logs/LogSqliteDriver.kt +++ b/runtime/src/commonMain/kotlin/app/cash/sqldelight/logs/LogSqliteDriver.kt @@ -45,7 +45,7 @@ class LogSqliteDriver( override fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, ): QueryResult { diff --git a/runtime/src/commonTest/kotlin/com/squareup/sqldelight/logs/LogSqliteDriverTest.kt b/runtime/src/commonTest/kotlin/com/squareup/sqldelight/logs/LogSqliteDriverTest.kt index 7b21571e1fe..a2508303f7e 100644 --- a/runtime/src/commonTest/kotlin/com/squareup/sqldelight/logs/LogSqliteDriverTest.kt +++ b/runtime/src/commonTest/kotlin/com/squareup/sqldelight/logs/LogSqliteDriverTest.kt @@ -52,7 +52,7 @@ class LogSqliteDriverTest { @Test fun queryLogsAreCorrect() { val query = { - driver.executeQuery(3, "SELECT * FROM test", {}, 0) + driver.executeQuery(3, "SELECT * FROM test", { QueryResult.Unit }, 0) } query() @@ -90,11 +90,11 @@ class FakeSqlDriver : SqlDriver { override fun executeQuery( identifier: Int?, sql: String, - mapper: (SqlCursor) -> R, + mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, ): QueryResult { - return QueryResult.Value(mapper(FakeSqlCursor())) + return mapper(FakeSqlCursor()) } override fun execute( @@ -128,8 +128,8 @@ class FakeSqlDriver : SqlDriver { } class FakeSqlCursor : SqlCursor { - override fun next(): Boolean { - return false + override fun next(): QueryResult.Value { + return QueryResult.Value(false) } override fun getString(index: Int): String? { diff --git a/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/SelectQueryGenerator.kt b/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/SelectQueryGenerator.kt index f29b4cb32f1..fc03abd1b67 100644 --- a/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/SelectQueryGenerator.kt +++ b/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/SelectQueryGenerator.kt @@ -305,9 +305,11 @@ class SelectQueryGenerator( val genericResultType = TypeVariableName("R") val createStatementFunction = FunSpec.builder(EXECUTE_METHOD) - .addModifiers(OVERRIDE) + .addModifiers( + OVERRIDE, + ) .addTypeVariable(genericResultType) - .addParameter(MAPPER_NAME, LambdaTypeName.get(parameters = arrayOf(CURSOR_TYPE), returnType = genericResultType)) + .addParameter(MAPPER_NAME, LambdaTypeName.get(parameters = arrayOf(CURSOR_TYPE), returnType = QUERY_RESULT_TYPE.parameterizedBy(genericResultType))) .returns(QUERY_RESULT_TYPE.parameterizedBy(genericResultType)) .addCode(executeBlock()) diff --git a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/QueriesTypeTest.kt b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/QueriesTypeTest.kt index 307cd9f31be..92a74788f20 100644 --- a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/QueriesTypeTest.kt +++ b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/QueriesTypeTest.kt @@ -198,7 +198,7 @@ class QueriesTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + | public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = | driver.executeQuery(${select.id}, ""${'"'} | |SELECT * | |FROM data @@ -532,7 +532,7 @@ class QueriesTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + | public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = | driver.executeQuery(${select.id}, ""${'"'} | |SELECT * | |FROM data @@ -688,7 +688,7 @@ class QueriesTypeTest { | driver.removeListener(listener, arrayOf("search")) | } | - | public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + | public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = | driver.executeQuery(${offsets.id}, ""${'"'} | |SELECT id, offsets(search) | |FROM search diff --git a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/async/AsyncQueriesTypeTest.kt b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/async/AsyncQueriesTypeTest.kt index 91b633ceb2b..73840f5f36a 100644 --- a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/async/AsyncQueriesTypeTest.kt +++ b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/async/AsyncQueriesTypeTest.kt @@ -201,7 +201,7 @@ class AsyncQueriesTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + | public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = | driver.executeQuery(${select.id}, ""${'"'} | |SELECT * | |FROM data diff --git a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/InterfaceGeneration.kt b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/InterfaceGeneration.kt index 1530a664f03..c687e0ea7a5 100644 --- a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/InterfaceGeneration.kt +++ b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/InterfaceGeneration.kt @@ -829,7 +829,7 @@ class InterfaceGeneration { | driver.removeListener(listener, arrayOf("song")) | } | - | public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + | public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = | driver.executeQuery(null, | ""${'"'}SELECT * FROM song WHERE album_id ${'$'}{ if (album_id == null) "IS" else "=" } ?""${'"'}, mapper, | 1) { @@ -928,7 +928,7 @@ class InterfaceGeneration { | driver.removeListener(listener, arrayOf("userEntity")) | } | - | public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + | public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = | driver.executeQuery(${result.compiledFile.namedQueries[0].id}, ""${'"'} | |WITH inserted_ids AS ( | | INSERT INTO userEntity(slack_user_id) @@ -1042,7 +1042,7 @@ class InterfaceGeneration { | driver.removeListener(listener, arrayOf("item")) | } | - | public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + | public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = | driver.executeQuery(${query.id}, ""${'"'} | |WITH RECURSIVE | |descendants AS ( diff --git a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryFunctionTest.kt b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryFunctionTest.kt index 0ebab165f3a..0e17a5043ee 100644 --- a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryFunctionTest.kt +++ b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryFunctionTest.kt @@ -303,7 +303,7 @@ class SelectQueryFunctionTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult { | val goodIndexes = createArguments(count = good.size) | val badIndexes = createArguments(count = bad.size) | return driver.executeQuery(null, ""${'"'} @@ -392,7 +392,7 @@ class SelectQueryFunctionTest { | driver.removeListener(listener, arrayOf("person")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} | |SELECT * | |FROM person | |WHERE first_name = ? AND last_name = ? diff --git a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryTypeTest.kt b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryTypeTest.kt index 9c44cba7669..8fc94d7f9ec 100644 --- a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryTypeTest.kt +++ b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/SelectQueryTypeTest.kt @@ -144,7 +144,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} | |SELECT * | |FROM data | |WHERE id = ? @@ -177,7 +177,7 @@ class SelectQueryTypeTest { |private inner class SelectWithoutFromQuery( | mapper: (app.cash.sqldelight.db.SqlCursor) -> T, |) : app.cash.sqldelight.ExecutableQuery(mapper) { - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'}SELECT 42""${'"'}, mapper, 0) + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'}SELECT 42""${'"'}, mapper, 0) | | public override fun toString(): kotlin.String = "Test.sq:selectWithoutFrom" |} @@ -221,7 +221,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} | |SELECT * | |FROM data | |WHERE id = ? @@ -270,7 +270,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult { | val idIndexes = createArguments(count = id.size) | return driver.executeQuery(null, ""${'"'} | |SELECT * @@ -324,7 +324,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult { | val idIndexes = createArguments(count = id.size) | return driver.executeQuery(null, ""${'"'} | |SELECT * @@ -381,7 +381,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("socialFeedItem")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'}SELECT * FROM socialFeedItem WHERE message IS NOT NULL AND userId ${"$"}{ if (userId == null) "IS" else "=" } ? ORDER BY datetime(creation_time) DESC""${'"'}, mapper, 1) { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'}SELECT * FROM socialFeedItem WHERE message IS NOT NULL AND userId ${"$"}{ if (userId == null) "IS" else "=" } ? ORDER BY datetime(creation_time) DESC""${'"'}, mapper, 1) { | bindString(0, userId) | } | @@ -424,7 +424,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("socialFeedItem")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${treatNullAsUnknownQuery.id}, ""${'"'}SELECT * FROM socialFeedItem WHERE message IS NOT NULL AND userId = ? ORDER BY datetime(creation_time) DESC""${'"'}, mapper, 1) { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${treatNullAsUnknownQuery.id}, ""${'"'}SELECT * FROM socialFeedItem WHERE message IS NOT NULL AND userId = ? ORDER BY datetime(creation_time) DESC""${'"'}, mapper, 1) { | bindString(0, userId) | } | @@ -472,7 +472,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("Friend")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} | |SELECT _id, username | |FROM Friend | |WHERE userId${'$'}{ if (userId == null) " IS " else "=" }? OR username=? LIMIT 2 @@ -523,7 +523,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("Friend")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} | |SELECT _id, username | |FROM Friend | |WHERE userId=? OR username=? LIMIT 2 @@ -583,7 +583,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} | |SELECT * | |FROM data | |WHERE val ${"$"}{ if (val_ == null) "IS" else "=" } ? @@ -651,7 +651,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} | |SELECT * | |FROM data | |WHERE val = ? @@ -710,7 +710,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} | |SELECT * | |FROM data | |WHERE data MATCH ? AND rowid = ? @@ -761,7 +761,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} | |SELECT * | |FROM data | |WHERE data MATCH '"one ' || ? || '" * ' @@ -816,7 +816,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult { | val idIndexes = createArguments(count = id.size) | val token_Indexes = createArguments(count = token_.size) | return driver.executeQuery(null, ""${'"'} @@ -885,7 +885,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} | |WITH child_ids AS (SELECT id FROM data WHERE id ${'$'}{ if (id == null) "IS" else "=" } ?) | |SELECT * | |FROM data @@ -943,7 +943,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} | |WITH child_ids AS (SELECT id FROM data WHERE id = ?) | |SELECT * | |FROM data @@ -998,7 +998,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult { | val idIndexes = createArguments(count = id.size) | return driver.executeQuery(null, ""${'"'} | |SELECT * @@ -1066,7 +1066,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(null, ""${'"'} | |SELECT * | |FROM data | |WHERE token ${"$"}{ if (token == null) "IS" else "=" } ? OR ? IS NULL @@ -1115,7 +1115,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${nullAsUnknownQuery.id}, ""${'"'} | |SELECT * | |FROM data | |WHERE token = ? OR ? IS NULL @@ -1719,7 +1719,7 @@ class SelectQueryTypeTest { | driver.removeListener(listener, arrayOf("ComboData", "ComboData2")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult { | val valuesIndexes = createArguments(count = values.size) | return driver.executeQuery(null, ""${'"'} | |SELECT (SELECT count(*) FROM ComboData WHERE value IN ${"$"}valuesIndexes) + @@ -1772,7 +1772,7 @@ class SelectQueryTypeTest { | public val value_: kotlin.Long, | mapper: (app.cash.sqldelight.db.SqlCursor) -> T, |) : app.cash.sqldelight.ExecutableQuery(mapper) { - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = transactionWithResult { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = transactionWithResult { | driver.execute(${query.idForIndex(0)}, ""${'"'} | |INSERT INTO data (value) | | VALUES (?) diff --git a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/async/AsyncSelectQueryTypeTest.kt b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/async/AsyncSelectQueryTypeTest.kt index 209b51eb5cf..16eda8b0d53 100644 --- a/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/async/AsyncSelectQueryTypeTest.kt +++ b/sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/queries/async/AsyncSelectQueryTypeTest.kt @@ -139,7 +139,7 @@ class AsyncSelectQueryTypeTest { | driver.removeListener(listener, arrayOf("data")) | } | - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = driver.executeQuery(${query.id}, ""${'"'} | |SELECT * | |FROM data | |WHERE id = ? @@ -238,7 +238,7 @@ class AsyncSelectQueryTypeTest { | public val value_: kotlin.Long, | mapper: (app.cash.sqldelight.db.SqlCursor) -> T, |) : app.cash.sqldelight.ExecutableQuery(mapper) { - | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> R): app.cash.sqldelight.db.QueryResult = app.cash.sqldelight.db.QueryResult.AsyncValue { + | public override fun execute(mapper: (app.cash.sqldelight.db.SqlCursor) -> app.cash.sqldelight.db.QueryResult): app.cash.sqldelight.db.QueryResult = app.cash.sqldelight.db.QueryResult.AsyncValue { | transactionWithResult { | driver.execute(${query.idForIndex(0)}, ""${'"'} | |INSERT INTO data (value) diff --git a/sqldelight-gradle-plugin/src/test/integration-multiplatform-async/src/commonMain/kotlin/app/sqltest/shared/common/data/SharedDatabase.kt b/sqldelight-gradle-plugin/src/test/integration-multiplatform-async/src/commonMain/kotlin/app/sqltest/shared/common/data/SharedDatabase.kt index 101ef967fd1..7f3632d9bfe 100644 --- a/sqldelight-gradle-plugin/src/test/integration-multiplatform-async/src/commonMain/kotlin/app/sqltest/shared/common/data/SharedDatabase.kt +++ b/sqldelight-gradle-plugin/src/test/integration-multiplatform-async/src/commonMain/kotlin/app/sqltest/shared/common/data/SharedDatabase.kt @@ -4,6 +4,7 @@ import app.cash.sqldelight.async.coroutines.await import app.cash.sqldelight.async.coroutines.awaitCreate import app.cash.sqldelight.async.coroutines.awaitMigrate import app.cash.sqldelight.async.coroutines.awaitQuery +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlDriver import app.sqltest.shared.SqlTestDb import kotlinx.coroutines.sync.Mutex @@ -50,7 +51,7 @@ class SharedDatabase(private val driverFactory: DriverFactory) { identifier = null, sql = "PRAGMA $versionPragma", mapper = { cursor -> - if (cursor.next()) { + if (cursor.next().await()) { cursor.getLong(0)?.toInt() } else { null @@ -78,11 +79,7 @@ class SharedDatabase(private val driverFactory: DriverFactory) { identifier = null, sql = "PRAGMA $versionPragma", mapper = { cursor -> - if (cursor.next()) { - cursor.getLong(0)?.toInt() - } else { - null - } + QueryResult.Value(if (cursor.next().value) cursor.getLong(0)?.toInt() else null) }, parameters = 0, ).await() ?: 0 diff --git a/sqldelight-gradle-plugin/src/test/multithreaded-sqlite/src/main/kotlin/com/example/db/DbHelper.kt b/sqldelight-gradle-plugin/src/test/multithreaded-sqlite/src/main/kotlin/com/example/db/DbHelper.kt index 3fc49203827..dfad3e00892 100644 --- a/sqldelight-gradle-plugin/src/test/multithreaded-sqlite/src/main/kotlin/com/example/db/DbHelper.kt +++ b/sqldelight-gradle-plugin/src/test/multithreaded-sqlite/src/main/kotlin/com/example/db/DbHelper.kt @@ -1,5 +1,6 @@ package com.example.db +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver import com.example.db.Database.Companion.Schema @@ -49,9 +50,9 @@ class DbHelper( private var version: Int get() { - fun mapper(cursor: SqlCursor): Int { - check(cursor.next()) - return cursor.getLong(0)!!.toInt() + fun mapper(cursor: SqlCursor): QueryResult.Value { + check(cursor.next().value) + return QueryResult.Value(cursor.getLong(0)!!.toInt()) } return driver.executeQuery(null, "PRAGMA user_version;", ::mapper, 0, null).value } From c4f92ff6b63be10980894853bc7af691bce03477 Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 10:57:04 -0400 Subject: [PATCH 02/10] Fix Android cursor return type(s) Fix DriverTest implementations --- .../driver/android/AndroidSqliteDriver.kt | 10 ++--- .../sqldelight/driver/test/DriverTest.kt | 38 +++++++++++-------- .../sqldelight/driver/test/QueryTest.kt | 2 +- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt b/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt index 4ca4dd42c5c..66ad9897031 100644 --- a/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt +++ b/drivers/android-driver/src/main/java/app/cash/sqldelight/driver/android/AndroidSqliteDriver.kt @@ -174,7 +174,7 @@ class AndroidSqliteDriver private constructor( mapper: (SqlCursor) -> QueryResult, parameters: Int, binders: (SqlPreparedStatement.() -> Unit)?, - ) = execute(identifier, { AndroidQuery(sql, database, parameters) }, binders) { executeQuery(mapper) }.value + ) = execute(identifier, { AndroidQuery(sql, database, parameters) }, binders) { executeQuery(mapper) } override fun close() { statements.evictAll() @@ -207,7 +207,7 @@ class AndroidSqliteDriver private constructor( internal interface AndroidStatement : SqlPreparedStatement { fun execute(): Long - fun executeQuery(mapper: (SqlCursor) -> R): R + fun executeQuery(mapper: (SqlCursor) -> QueryResult): R fun close() } @@ -238,7 +238,7 @@ private class AndroidPreparedStatement( } } - override fun executeQuery(mapper: (SqlCursor) -> R): R = throw UnsupportedOperationException() + override fun executeQuery(mapper: (SqlCursor) -> QueryResult): R = throw UnsupportedOperationException() override fun execute(): Long { return statement.executeUpdateDelete().toLong() @@ -284,9 +284,9 @@ private class AndroidQuery( override fun execute() = throw UnsupportedOperationException() - override fun executeQuery(mapper: (SqlCursor) -> R): R { + override fun executeQuery(mapper: (SqlCursor) -> QueryResult): R { return database.query(this) - .use { cursor -> mapper(AndroidCursor(cursor)) } + .use { cursor -> mapper(AndroidCursor(cursor)).value } } override fun bindTo(statement: SupportSQLiteProgram) { diff --git a/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/DriverTest.kt b/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/DriverTest.kt index 472722e44c8..83eb2479807 100644 --- a/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/DriverTest.kt +++ b/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/DriverTest.kt @@ -64,9 +64,9 @@ abstract class DriverTest { private fun changes(): Long? { // wrap in a transaction to ensure read happens on transaction thread/connection return transacter.value!!.transactionWithResult { - val mapper: (SqlCursor) -> Long? = { + val mapper: (SqlCursor) -> QueryResult = { it.next() - it.getLong(0) + QueryResult.Value(it.getLong(0)) } driver.executeQuery(null, "SELECT changes()", mapper, 0).value } @@ -87,12 +87,13 @@ abstract class DriverTest { val insert = { binders: SqlPreparedStatement.() -> Unit -> driver.execute(2, "INSERT INTO test VALUES (?, ?);", 2, binders) } - fun query(mapper: (SqlCursor) -> Unit) { + fun query(mapper: (SqlCursor) -> QueryResult) { driver.executeQuery(3, "SELECT * FROM test", mapper, 0) } query { - assertFalse(it.next()) + assertFalse(it.next().value) + QueryResult.Unit } insert { @@ -101,16 +102,18 @@ abstract class DriverTest { } query { - assertTrue(it.next()) - assertFalse(it.next()) + assertTrue(it.next().value) + assertFalse(it.next().value) + QueryResult.Unit } assertEquals(1, changes()) query { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(1, it.getLong(0)) assertEquals("Alec", it.getString(1)) + QueryResult.Unit } insert { @@ -120,19 +123,21 @@ abstract class DriverTest { assertEquals(1, changes()) query { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(1, it.getLong(0)) assertEquals("Alec", it.getString(1)) - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) + QueryResult.Unit } driver.execute(5, "DELETE FROM test", 0) assertEquals(2, changes()) query { - assertFalse(it.next()) + assertFalse(it.next().value) + QueryResult.Unit } } @@ -153,7 +158,7 @@ abstract class DriverTest { } assertEquals(1, changes()) - fun query(binders: SqlPreparedStatement.() -> Unit, mapper: (SqlCursor) -> Unit) { + fun query(binders: SqlPreparedStatement.() -> Unit, mapper: (SqlCursor) -> QueryResult) { driver.executeQuery(6, "SELECT * FROM test WHERE value = ?", mapper, 1, binders) } @@ -162,9 +167,10 @@ abstract class DriverTest { bindString(0, "Jake") }, mapper = { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) + QueryResult.Unit }, ) @@ -174,9 +180,10 @@ abstract class DriverTest { bindString(0, "Jake") }, mapper = { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) + QueryResult.Unit }, ) } @@ -194,13 +201,14 @@ abstract class DriverTest { } assertEquals(1, changes()) - val mapper: (SqlCursor) -> Unit = { - assertTrue(it.next()) + val mapper: (SqlCursor) -> QueryResult = { + assertTrue(it.next().value) assertEquals(1, it.getLong(0)) assertNull(it.getLong(1)) assertNull(it.getString(2)) assertNull(it.getBytes(3)) assertNull(it.getDouble(4)) + QueryResult.Unit } driver.executeQuery(8, "SELECT * FROM nullability_test", mapper, 0) } diff --git a/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/QueryTest.kt b/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/QueryTest.kt index 0ab9227a24b..1dab384e67f 100644 --- a/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/QueryTest.kt +++ b/drivers/driver-test/src/commonMain/kotlin/com/squareup/sqldelight/driver/test/QueryTest.kt @@ -174,7 +174,7 @@ abstract class QueryTest { private fun testDataQuery(): Query { return object : Query(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return driver.executeQuery(0, "SELECT * FROM test", mapper, 0, null) } From 601297cd41233929db4028826f0b1d0bae810f35 Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 11:10:32 -0400 Subject: [PATCH 03/10] Fix paging mapper declaration --- .../kotlin/app/cash/sqldelight/paging3/QueryPagingSource.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/androidx-paging3/src/commonMain/kotlin/app/cash/sqldelight/paging3/QueryPagingSource.kt b/extensions/androidx-paging3/src/commonMain/kotlin/app/cash/sqldelight/paging3/QueryPagingSource.kt index 20fbaeb7dee..d6b2e79d05e 100755 --- a/extensions/androidx-paging3/src/commonMain/kotlin/app/cash/sqldelight/paging3/QueryPagingSource.kt +++ b/extensions/androidx-paging3/src/commonMain/kotlin/app/cash/sqldelight/paging3/QueryPagingSource.kt @@ -19,6 +19,7 @@ import app.cash.paging.PagingConfig import app.cash.paging.PagingSource import app.cash.sqldelight.Query import app.cash.sqldelight.Transacter +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import kotlin.coroutines.CoroutineContext import kotlin.jvm.JvmName @@ -97,7 +98,7 @@ fun QueryPagingSource( private fun Query.toInt(): Query = object : Query({ cursor -> mapper(cursor).toInt() }) { - override fun execute(mapper: (SqlCursor) -> R) = this@toInt.execute(mapper) + override fun execute(mapper: (SqlCursor) -> QueryResult) = this@toInt.execute(mapper) override fun addListener(listener: Listener) = this@toInt.addListener(listener) override fun removeListener(listener: Listener) = this@toInt.removeListener(listener) } From 5594a4ee62b161c6296eb8c3ffd98375b22c136e Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 11:35:15 -0400 Subject: [PATCH 04/10] Fix a bunch of test overrides of execute --- .../native/connectionpool/BaseConcurrencyTest.kt | 2 +- .../native/connectionpool/WalConcurrencyTest.kt | 2 +- .../squareup/sqldelight/drivers/sqljs/JsQueryTest.kt | 2 +- .../sqldelight/paging3/KeyedQueryPagingSourceTest.kt | 5 +++-- .../sqldelight/paging3/OffsetQueryPagingSourceTest.kt | 2 +- .../app/cash/sqldelight/coroutines/MappingTest.kt | 10 +++++----- .../kotlin/app/cash/sqldelight/coroutines/TestDb.kt | 10 +++++----- .../app/cash/sqldelight/rx2/QueryObservableTest.kt | 5 +++-- .../src/test/kotlin/app/cash/sqldelight/rx2/TestDb.kt | 8 ++++---- .../app/cash/sqldelight/rx3/QueryObservableTest.kt | 5 +++-- .../src/test/kotlin/app/cash/sqldelight/rx3/TestDb.kt | 8 ++++---- .../src/test/kotlin/com/example/PlayerQueries.kt | 6 +++--- .../src/test/kotlin/com/example/TeamQueries.kt | 4 ++-- 13 files changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/BaseConcurrencyTest.kt b/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/BaseConcurrencyTest.kt index a298d2bf2e3..f2dd768473b 100644 --- a/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/BaseConcurrencyTest.kt +++ b/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/BaseConcurrencyTest.kt @@ -20,7 +20,7 @@ abstract class BaseConcurrencyTest { return myDriver.executeQuery( 0, "SELECT count(*) FROM test", - { it.next(); it.getLong(0)!! }, + { it.next(); QueryResult.Value(it.getLong(0)!!) }, 0, ).value } diff --git a/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/WalConcurrencyTest.kt b/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/WalConcurrencyTest.kt index 9fafee441af..6ce78747515 100644 --- a/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/WalConcurrencyTest.kt +++ b/drivers/native-driver/src/nativeTest/kotlin/com/squareup/sqldelight/drivers/native/connectionpool/WalConcurrencyTest.kt @@ -103,7 +103,7 @@ class WalConcurrencyTest : BaseConcurrencyTest() { private fun testDataQuery(): Query { return object : Query(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return driver.executeQuery(0, "SELECT * FROM test", mapper, 0, null) } diff --git a/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsQueryTest.kt b/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsQueryTest.kt index 6f12dd1b1d1..8485bea893f 100644 --- a/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsQueryTest.kt +++ b/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsQueryTest.kt @@ -173,7 +173,7 @@ class JsQueryTest { private fun SqlDriver.testDataQuery(): Query { return object : Query(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return executeQuery(0, "SELECT * FROM test", mapper, 0, null) } diff --git a/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/KeyedQueryPagingSourceTest.kt b/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/KeyedQueryPagingSourceTest.kt index 0d71adf0492..9d8b17c9983 100755 --- a/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/KeyedQueryPagingSourceTest.kt +++ b/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/KeyedQueryPagingSourceTest.kt @@ -22,6 +22,7 @@ import app.cash.paging.PagingState import app.cash.sqldelight.Query import app.cash.sqldelight.Transacter import app.cash.sqldelight.TransacterImpl +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import app.cash.sqldelight.db.SqlDriver import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -143,7 +144,7 @@ class KeyedQueryPagingSourceTest : DbTest { """.trimMargin() return object : Query({ cursor -> cursor.getLong(0)!! }) { - override fun execute(mapper: (SqlCursor) -> R) = driver.executeQuery(identifier = 3, sql = sql, mapper = mapper, parameters = 2) { + override fun execute(mapper: (SqlCursor) -> QueryResult) = driver.executeQuery(identifier = 3, sql = sql, mapper = mapper, parameters = 2) { bindLong(0, limit) bindLong(1, anchor) } @@ -163,7 +164,7 @@ class KeyedQueryPagingSourceTest : DbTest { return object : Query( { cursor -> cursor.getLong(0)!! }, ) { - override fun execute(mapper: (SqlCursor) -> R) = driver.executeQuery(identifier = 2, sql = sql, mapper = mapper, parameters = 2) { + override fun execute(mapper: (SqlCursor) -> QueryResult) = driver.executeQuery(identifier = 2, sql = sql, mapper = mapper, parameters = 2) { bindLong(0, beginInclusive) bindLong(1, endExclusive) } diff --git a/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt b/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt index c4fab3180f4..f23decea336 100755 --- a/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt +++ b/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt @@ -518,7 +518,7 @@ class OffsetQueryPagingSourceTest : DbTest { TestItem(cursor.getLong(0)!!) }, ) { - override fun execute(mapper: (SqlCursor) -> R) = driver.executeQuery(20, "SELECT id FROM TestItem LIMIT ? OFFSET ?", mapper, 2) { + override fun execute(mapper: (SqlCursor) -> QueryResult) = driver.executeQuery(20, "SELECT id FROM TestItem LIMIT ? OFFSET ?", mapper, 2) { bindLong(0, limit) bindLong(1, offset) } diff --git a/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/MappingTest.kt b/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/MappingTest.kt index 306a30ab2d7..2a1f36ff26e 100644 --- a/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/MappingTest.kt +++ b/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/MappingTest.kt @@ -48,7 +48,7 @@ class MappingTest : DbTest { val expected = IllegalStateException("test exception") val query = object : Query({ fail() }) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult = throw expected + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = throw expected override fun addListener(listener: Listener) = Unit override fun removeListener(listener: Listener) = Unit } @@ -101,7 +101,7 @@ class MappingTest : DbTest { val expected = IllegalStateException("test exception") val query = object : Query({ fail() }) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult = throw expected + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = throw expected override fun addListener(listener: Listener) = Unit override fun removeListener(listener: Listener) = Unit } @@ -173,7 +173,7 @@ class MappingTest : DbTest { val expected = IllegalStateException("test exception") val query = object : Query({ fail() }) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult = throw expected + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = throw expected override fun addListener(listener: Listener) = Unit override fun removeListener(listener: Listener) = Unit } @@ -225,7 +225,7 @@ class MappingTest : DbTest { val expected = IllegalStateException("test exception") val query = object : Query({ fail() }) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult = throw expected + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = throw expected override fun addListener(listener: Listener) = Unit override fun removeListener(listener: Listener) = Unit } @@ -288,7 +288,7 @@ class MappingTest : DbTest { val expected = IllegalStateException("test exception") val query = object : Query({ fail() }) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult = throw expected + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = throw expected override fun addListener(listener: Listener) = Unit override fun removeListener(listener: Listener) = Unit } diff --git a/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/TestDb.kt b/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/TestDb.kt index 96c98caf5e5..08d5a771960 100644 --- a/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/TestDb.kt +++ b/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/TestDb.kt @@ -33,7 +33,7 @@ class TestDb( fun createQuery(key: String, query: String, mapper: (SqlCursor) -> T): Query { return object : Query(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return db.executeQuery(null, query, mapper, 0, null) } @@ -71,9 +71,9 @@ class TestDb( notify(TABLE_EMPLOYEE) // last_insert_rowid is connection-specific, so run it in the transaction thread/connection return transactionWithResult { - val mapper: (SqlCursor) -> Long = { + val mapper: (SqlCursor) -> QueryResult = { it.next() - it.getLong(0)!! + QueryResult.Value(it.getLong(0)!!) } db.executeQuery(2, "SELECT last_insert_rowid()", mapper, 0).value } @@ -98,9 +98,9 @@ class TestDb( notify(TABLE_MANAGER) // last_insert_rowid is connection-specific, so run it in the transaction thread/connection return transactionWithResult { - val mapper: (SqlCursor) -> Long = { + val mapper: (SqlCursor) -> QueryResult = { it.next() - it.getLong(0)!! + QueryResult.Value(it.getLong(0)!!) } db.executeQuery(2, "SELECT last_insert_rowid()", mapper, 0).value } diff --git a/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/QueryObservableTest.kt b/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/QueryObservableTest.kt index 308ba10ea5d..28894d2d97f 100644 --- a/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/QueryObservableTest.kt +++ b/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/QueryObservableTest.kt @@ -1,6 +1,7 @@ package app.cash.sqldelight.rx2 import app.cash.sqldelight.Query +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import app.cash.sqldelight.rx2.Employee.Companion.SELECT_EMPLOYEES import app.cash.sqldelight.rx2.TestDb.Companion.TABLE_EMPLOYEE @@ -13,7 +14,7 @@ class QueryObservableTest { val error = IllegalStateException("test exception") val query = object : Query({ throw AssertionError("Must not be called") }) { - override fun execute(mapper: (SqlCursor) -> R) = throw error + override fun execute(mapper: (SqlCursor) -> QueryResult) = throw error override fun addListener(listener: Listener) = throw error override fun removeListener(listener: Listener) = throw error } @@ -42,7 +43,7 @@ class QueryObservableTest { val queriesWithListeners = mutableListOf() val query = object : Query({ throw AssertionError("Must not be called") }) { - override fun execute(mapper: (SqlCursor) -> R) = error("Must not be called") + override fun execute(mapper: (SqlCursor) -> QueryResult) = error("Must not be called") override fun addListener(listener: Listener) = error("Must not be called") override fun removeListener(listener: Listener) = error("Must not be called") } diff --git a/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/TestDb.kt b/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/TestDb.kt index 88d7d37c244..314f0cdbbdd 100644 --- a/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/TestDb.kt +++ b/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/TestDb.kt @@ -32,7 +32,7 @@ class TestDb( fun createQuery(key: String, query: String, mapper: (SqlCursor) -> T): Query { return object : Query(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return db.executeQuery(null, query, mapper, 0) } @@ -144,7 +144,7 @@ data class Employee(val username: String, val name: String) { } } -private fun getLong(cursor: SqlCursor): Long { - check(cursor.next()) - return cursor.getLong(0)!! +private fun getLong(cursor: SqlCursor): QueryResult { + check(cursor.next().value) + return QueryResult.Value(cursor.getLong(0)!!) } diff --git a/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/QueryObservableTest.kt b/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/QueryObservableTest.kt index eca0cc27519..1c6963e89fd 100644 --- a/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/QueryObservableTest.kt +++ b/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/QueryObservableTest.kt @@ -1,6 +1,7 @@ package app.cash.sqldelight.rx3 import app.cash.sqldelight.Query +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import app.cash.sqldelight.rx3.Employee.Companion.SELECT_EMPLOYEES import app.cash.sqldelight.rx3.TestDb.Companion.TABLE_EMPLOYEE @@ -13,7 +14,7 @@ class QueryObservableTest { val error = IllegalStateException("test exception") val query = object : Query({ throw AssertionError("Must not be called") }) { - override fun execute(mapper: (SqlCursor) -> R) = throw error + override fun execute(mapper: (SqlCursor) -> QueryResult) = throw error override fun addListener(listener: Listener) = throw error override fun removeListener(listener: Listener) = throw error } @@ -42,7 +43,7 @@ class QueryObservableTest { val queriesWithListeners = mutableListOf() val query = object : Query({ throw AssertionError("Must not be called") }) { - override fun execute(mapper: (SqlCursor) -> R) = error("Must not be called") + override fun execute(mapper: (SqlCursor) -> QueryResult) = error("Must not be called") override fun addListener(listener: Listener) = error("Must not be called") override fun removeListener(listener: Listener) = error("Must not be called") } diff --git a/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/TestDb.kt b/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/TestDb.kt index 31f5574ff39..acf2f96db86 100644 --- a/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/TestDb.kt +++ b/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/TestDb.kt @@ -31,7 +31,7 @@ class TestDb( fun createQuery(key: String, query: String, mapper: (SqlCursor) -> T): Query { return object : Query(mapper) { - override fun execute(mapper: (SqlCursor) -> R): QueryResult { + override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { return db.executeQuery(null, query, mapper, 0) } @@ -143,7 +143,7 @@ data class Employee(val username: String, val name: String) { } } -private fun getLong(cursor: SqlCursor): Long { - check(cursor.next()) - return cursor.getLong(0)!! +private fun getLong(cursor: SqlCursor): QueryResult { + check(cursor.next().value) + return QueryResult.Value(cursor.getLong(0)!!) } diff --git a/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/PlayerQueries.kt b/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/PlayerQueries.kt index 999eecb04ba..c714402b5a3 100644 --- a/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/PlayerQueries.kt +++ b/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/PlayerQueries.kt @@ -208,7 +208,7 @@ public class PlayerQueries( public val shoots: Shoots, mapper: (SqlCursor) -> T, ) : ExecutableQuery(mapper) { - public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = transactionWithResult { driver.execute(-452007405, """ |INSERT INTO player @@ -241,7 +241,7 @@ public class PlayerQueries( driver.removeListener(listener, arrayOf("player")) } - public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = driver.executeQuery(null, """ |SELECT * |FROM player @@ -265,7 +265,7 @@ public class PlayerQueries( driver.removeListener(listener, arrayOf("player")) } - public override fun execute(mapper: (SqlCursor) -> R): QueryResult { + public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult { val numberIndexes = createArguments(count = number.size) return driver.executeQuery(null, """ |SELECT * diff --git a/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/TeamQueries.kt b/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/TeamQueries.kt index caa61bb399a..0c1e187a5b3 100644 --- a/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/TeamQueries.kt +++ b/sqldelight-compiler/integration-tests/src/test/kotlin/com/example/TeamQueries.kt @@ -84,7 +84,7 @@ public class TeamQueries( driver.removeListener(listener, arrayOf("team")) } - public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = driver.executeQuery(1839882838, """ |SELECT name, captain |FROM team @@ -108,7 +108,7 @@ public class TeamQueries( driver.removeListener(listener, arrayOf("team")) } - public override fun execute(mapper: (SqlCursor) -> R): QueryResult = + public override fun execute(mapper: (SqlCursor) -> QueryResult): QueryResult = driver.executeQuery(null, """ |SELECT * |FROM team From 9565ae4b2318ab340d39c7af7ec5998a8a3a3a41 Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 12:00:20 -0400 Subject: [PATCH 05/10] Fix AndroidDriverTest --- .../squareup/sqldelight/android/AndroidDriverTest.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/android-driver/src/test/java/com/squareup/sqldelight/android/AndroidDriverTest.kt b/drivers/android-driver/src/test/java/com/squareup/sqldelight/android/AndroidDriverTest.kt index b3f136ebd65..04c31100d61 100644 --- a/drivers/android-driver/src/test/java/com/squareup/sqldelight/android/AndroidDriverTest.kt +++ b/drivers/android-driver/src/test/java/com/squareup/sqldelight/android/AndroidDriverTest.kt @@ -26,12 +26,12 @@ class AndroidDriverTest : DriverTest() { fun `cached statement can be reused`() { val driver = AndroidSqliteDriver(schema, getApplicationContext(), cacheSize = 1) lateinit var bindable: SqlPreparedStatement - driver.executeQuery(1, "SELECT * FROM test", {}, 0, { bindable = this }) + driver.executeQuery(1, "SELECT * FROM test", { QueryResult.Unit }, 0, { bindable = this }) driver.executeQuery( 1, "SELECT * FROM test", - {}, + { QueryResult.Unit }, 0, { assertSame(bindable, this) @@ -43,14 +43,14 @@ class AndroidDriverTest : DriverTest() { fun `cached statement is evicted and closed`() { val driver = AndroidSqliteDriver(schema, getApplicationContext(), cacheSize = 1) lateinit var bindable: SqlPreparedStatement - driver.executeQuery(1, "SELECT * FROM test", {}, 0, { bindable = this }) + driver.executeQuery(1, "SELECT * FROM test", { QueryResult.Unit }, 0, { bindable = this }) - driver.executeQuery(2, "SELECT * FROM test", {}, 0) + driver.executeQuery(2, "SELECT * FROM test", { QueryResult.Unit }, 0) driver.executeQuery( 1, "SELECT * FROM test", - {}, + { QueryResult.Unit }, 0, { assertNotSame(bindable, this) From 78c66d1b0e80176c23f26ecb18400c4c43c5c943 Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 12:30:48 -0400 Subject: [PATCH 06/10] Fix some more test compile errors --- .../cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt | 1 + .../kotlin/app/cash/sqldelight/coroutines/QueryAssert.kt | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt b/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt index f23decea336..b7691be367f 100755 --- a/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt +++ b/extensions/androidx-paging3/src/commonTest/kotlin/app/cash/sqldelight/paging3/OffsetQueryPagingSourceTest.kt @@ -31,6 +31,7 @@ import app.cash.paging.PagingState import app.cash.sqldelight.Query import app.cash.sqldelight.Transacter import app.cash.sqldelight.TransacterImpl +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import app.cash.sqldelight.db.SqlDriver import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/QueryAssert.kt b/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/QueryAssert.kt index 8fa0ef32064..f5d9c34c81a 100644 --- a/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/QueryAssert.kt +++ b/extensions/coroutines-extensions/src/commonTest/kotlin/app/cash/sqldelight/coroutines/QueryAssert.kt @@ -16,6 +16,7 @@ package app.cash.sqldelight.coroutines import app.cash.sqldelight.Query +import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlCursor import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -24,7 +25,7 @@ fun Query.assert(body: QueryAssert.() -> Unit) { execute { cursor -> QueryAssert(cursor).apply(body) val remainingRows = mutableListOf() - while (cursor.next()) { + while (cursor.next().value) { remainingRows += buildString { try { for (i in 0..Int.MAX_VALUE) { @@ -39,6 +40,7 @@ fun Query.assert(body: QueryAssert.() -> Unit) { } } assertEquals(emptyList(), remainingRows, "remaining cursor rows") + QueryResult.Unit } } @@ -48,7 +50,7 @@ class QueryAssert(private val cursor: SqlCursor) { fun hasRow(vararg values: String) { row += 1 - assertTrue(cursor.next(), "row $row does not exist") + assertTrue(cursor.next().value, "row $row does not exist") for (i in values.indices) { assertEquals(values[i], cursor.getString(i), "row $row column '$i'") } From 14b84ef0cc3163b05c66f580cf75928a02c71b39 Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 14:18:00 -0400 Subject: [PATCH 07/10] Tentative fix for coroutines extensions tests --- .../async/coroutines/QueryExtensions.kt | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt index 3873aa3a376..79e67d54a66 100644 --- a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt +++ b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt @@ -4,10 +4,20 @@ import app.cash.sqldelight.ExecutableQuery import app.cash.sqldelight.db.QueryResult suspend fun ExecutableQuery.awaitAsList(): List = execute { cursor -> - QueryResult.AsyncValue { - val result = mutableListOf() - while (cursor.next().await()) result.add(mapper(cursor)) - result + val first = cursor.next() + val result = mutableListOf() + + // If the cursor isn't async, we want to preserve the blocking semantics and execute it synchronously + if (first is QueryResult.AsyncValue) { + QueryResult.AsyncValue { + if (first.await()) result.add(mapper(cursor)) else return@AsyncValue result + while (cursor.next().value) result.add(mapper(cursor)) + result + } + } else { + if (first.value) result.add(mapper(cursor)) else return@execute QueryResult.Value(result) + while (cursor.next().value) result.add(mapper(cursor)) + QueryResult.Value(result) } }.await() @@ -17,10 +27,20 @@ suspend fun ExecutableQuery.awaitAsOne(): T { } suspend fun ExecutableQuery.awaitAsOneOrNull(): T? = execute { cursor -> - QueryResult.AsyncValue { - if (!cursor.next().await()) return@AsyncValue null + val next = cursor.next() + + // If the cursor isn't async, we want to preserve the blocking semantics and execute it synchronously + if (next is QueryResult.AsyncValue) { + QueryResult.AsyncValue { + if (!next.await()) return@AsyncValue null + val value = mapper(cursor) + check(!cursor.next().value) { "ResultSet returned more than 1 row for $this" } + value + } + } else { + if (!next.value) return@execute QueryResult.Value(null) val value = mapper(cursor) - check(!cursor.next().await()) { "ResultSet returned more than 1 row for $this" } - value + check(!cursor.next().value) { "ResultSet returned more than 1 row for $this" } + QueryResult.Value(value) } }.await() From 592fb4b66ea145a1fb9ecf509008839745e4e271 Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 14:49:50 -0400 Subject: [PATCH 08/10] Fix js-related driver test compile errors --- .../sqldelight/drivers/sqljs/JsDriverTest.kt | 57 +++++++++++-------- .../drivers/worker/WebWorkerDriverTest.kt | 32 +++++------ 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsDriverTest.kt b/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsDriverTest.kt index 78ad06770b2..84b6058cbb8 100644 --- a/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsDriverTest.kt +++ b/drivers/sqljs-driver/src/jsTest/kotlin/com/squareup/sqldelight/drivers/sqljs/JsDriverTest.kt @@ -73,15 +73,16 @@ class JsDriverTest { val insert = { binders: SqlPreparedStatement.() -> Unit -> driver.execute(2, "INSERT INTO test VALUES (?, ?);", 2, binders) } - fun query(mapper: (SqlCursor) -> Unit) { + fun query(mapper: (SqlCursor) -> QueryResult) { driver.executeQuery(3, "SELECT * FROM test", mapper, 0) } - fun changes(mapper: (SqlCursor) -> Long?): Long? { + fun changes(mapper: (SqlCursor) -> QueryResult): Long? { return driver.executeQuery(4, "SELECT changes()", mapper, 0).value } query { - assertFalse(it.next()) + assertFalse(it.next().value) + QueryResult.Unit } insert { @@ -90,38 +91,42 @@ class JsDriverTest { } query { - assertTrue(it.next()) - assertFalse(it.next()) + assertTrue(it.next().value) + assertFalse(it.next().value) + QueryResult.Unit } - assertEquals(1, changes { it.next(); it.getLong(0) }) + assertEquals(1, changes { it.next(); QueryResult.Value(it.getLong(0)) }) query { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(1, it.getLong(0)) assertEquals("Alec", it.getString(1)) + QueryResult.Unit } insert { bindLong(0, 2) bindString(1, "Jake") } - assertEquals(1, changes { it.next(); it.getLong(0) }) + assertEquals(1, changes { it.next(); QueryResult.Value(it.getLong(0)) }) query { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(1, it.getLong(0)) assertEquals("Alec", it.getString(1)) - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) + QueryResult.Unit } driver.execute(5, "DELETE FROM test", 0) - assertEquals(2, changes { it.next(); it.getLong(0) }) + assertEquals(2, changes { it.next(); QueryResult.Value(it.getLong(0)) }) query { - assertFalse(it.next()) + assertFalse(it.next().value) + QueryResult.Unit } } @@ -130,7 +135,7 @@ class JsDriverTest { val insert = { binders: SqlPreparedStatement.() -> Unit -> driver.execute(2, "INSERT INTO test VALUES (?, ?);", 2, binders) } - fun changes(mapper: (SqlCursor) -> Long?): Long? { + fun changes(mapper: (SqlCursor) -> QueryResult): Long? { return driver.executeQuery(4, "SELECT changes()", mapper, 0).value } @@ -138,14 +143,14 @@ class JsDriverTest { bindLong(0, 1) bindString(1, "Alec") } - assertEquals(1, changes { it.next(); it.getLong(0) }) + assertEquals(1, changes { it.next(); QueryResult.Value(it.getLong(0)) }) insert { bindLong(0, 2) bindString(1, "Jake") } - assertEquals(1, changes { it.next(); it.getLong(0) }) + assertEquals(1, changes { it.next(); QueryResult.Value(it.getLong(0)) }) - fun query(binders: SqlPreparedStatement.() -> Unit, mapper: (SqlCursor) -> Unit) { + fun query(binders: SqlPreparedStatement.() -> Unit, mapper: (SqlCursor) -> QueryResult) { driver.executeQuery(6, "SELECT * FROM test WHERE value = ?", mapper, 1, binders) } query( @@ -153,9 +158,10 @@ class JsDriverTest { bindString(0, "Jake") }, mapper = { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) + QueryResult.Unit }, ) @@ -165,9 +171,10 @@ class JsDriverTest { bindString(0, "Jake") }, mapper = { - assertTrue(it.next()) + assertTrue(it.next().value) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) + QueryResult.Unit }, ) } @@ -177,7 +184,7 @@ class JsDriverTest { val insert = { binders: SqlPreparedStatement.() -> Unit -> driver.execute(7, "INSERT INTO nullability_test VALUES (?, ?, ?, ?, ?);", 5, binders) } - fun changes(mapper: (SqlCursor) -> Long?): Long? { + fun changes(mapper: (SqlCursor) -> QueryResult): Long? { return driver.executeQuery(4, "SELECT changes()", mapper, 0).value } @@ -188,15 +195,16 @@ class JsDriverTest { bindBytes(3, null) bindDouble(4, null) } - assertEquals(1, changes { it.next(); it.getLong(0) }) + assertEquals(1, changes { it.next(); QueryResult.Value(it.getLong(0)) }) - val mapper: (SqlCursor) -> Unit = { - assertTrue(it.next()) + val mapper: (SqlCursor) -> QueryResult = { + assertTrue(it.next().value) assertEquals(1, it.getLong(0)) assertNull(it.getLong(1)) assertNull(it.getString(2)) assertNull(it.getBytes(3)) assertNull(it.getDouble(4)) + QueryResult.Unit } driver.executeQuery(8, "SELECT * FROM nullability_test", mapper, 0) } @@ -215,13 +223,14 @@ class JsDriverTest { bindDouble(4, Float.MAX_VALUE.toDouble()) } - val mapper: (SqlCursor) -> Unit = { - assertTrue(it.next()) + val mapper: (SqlCursor) -> QueryResult = { + assertTrue(it.next().value) assertEquals(1, it.getLong(0)) assertEquals(Long.MAX_VALUE, it.getLong(1)) assertEquals("Hello", it.getString(2)) it.getBytes(3)?.forEachIndexed { index, byte -> assertEquals(index.toByte(), byte) } assertEquals(Float.MAX_VALUE.toDouble(), it.getDouble(4)) + QueryResult.Unit } driver.executeQuery(8, "SELECT * FROM nullability_test", mapper, 0) } diff --git a/drivers/web-worker-driver/src/jsTest/kotlin/app/cash/sqldelight/drivers/worker/WebWorkerDriverTest.kt b/drivers/web-worker-driver/src/jsTest/kotlin/app/cash/sqldelight/drivers/worker/WebWorkerDriverTest.kt index 416ba770350..eda2ba361b0 100644 --- a/drivers/web-worker-driver/src/jsTest/kotlin/app/cash/sqldelight/drivers/worker/WebWorkerDriverTest.kt +++ b/drivers/web-worker-driver/src/jsTest/kotlin/app/cash/sqldelight/drivers/worker/WebWorkerDriverTest.kt @@ -78,16 +78,16 @@ class WebWorkerDriverTest { driver.await(2, "INSERT INTO test VALUES (?, ?);", 2, binders) } - suspend fun query(mapper: (SqlCursor) -> Unit) { + suspend fun query(mapper: suspend (SqlCursor) -> Unit) { driver.awaitQuery(3, "SELECT * FROM test", mapper, 0) } - suspend fun changes(mapper: (SqlCursor) -> Long?): Long? { + suspend fun changes(mapper: suspend (SqlCursor) -> Long?): Long? { return driver.awaitQuery(4, "SELECT changes()", mapper, 0) } query { - assertFalse(it.next()) + assertFalse(it.next().await()) } insert { @@ -96,14 +96,14 @@ class WebWorkerDriverTest { } query { - assertTrue(it.next()) - assertFalse(it.next()) + assertTrue(it.next().await()) + assertFalse(it.next().await()) } assertEquals(1, changes { it.next(); it.getLong(0) }) query { - assertTrue(it.next()) + assertTrue(it.next().await()) assertEquals(1, it.getLong(0)) assertEquals("Alec", it.getString(1)) } @@ -115,10 +115,10 @@ class WebWorkerDriverTest { assertEquals(1, changes { it.next(); it.getLong(0) }) query { - assertTrue(it.next()) + assertTrue(it.next().await()) assertEquals(1, it.getLong(0)) assertEquals("Alec", it.getString(1)) - assertTrue(it.next()) + assertTrue(it.next().await()) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) } @@ -127,7 +127,7 @@ class WebWorkerDriverTest { assertEquals(2, changes { it.next(); it.getLong(0) }) query { - assertFalse(it.next()) + assertFalse(it.next().await()) } } @@ -153,7 +153,7 @@ class WebWorkerDriverTest { } assertEquals(1, changes { it.next(); it.getLong(0) }) - suspend fun query(binders: SqlPreparedStatement.() -> Unit, mapper: (SqlCursor) -> Unit) { + suspend fun query(binders: SqlPreparedStatement.() -> Unit, mapper: suspend (SqlCursor) -> Unit) { driver.awaitQuery(6, "SELECT * FROM test WHERE value = ?", mapper, 1, binders) } query( @@ -161,7 +161,7 @@ class WebWorkerDriverTest { bindString(0, "Jake") }, mapper = { - assertTrue(it.next()) + assertTrue(it.next().await()) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) }, @@ -173,7 +173,7 @@ class WebWorkerDriverTest { bindString(0, "Jake") }, mapper = { - assertTrue(it.next()) + assertTrue(it.next().await()) assertEquals(2, it.getLong(0)) assertEquals("Jake", it.getString(1)) }, @@ -198,8 +198,8 @@ class WebWorkerDriverTest { bindDouble(4, null) } - val mapper: (SqlCursor) -> Unit = { - assertTrue(it.next()) + val mapper: suspend (SqlCursor) -> Unit = { + assertTrue(it.next().await()) assertEquals(1, it.getLong(0)) assertNull(it.getLong(1)) assertNull(it.getString(2)) @@ -224,8 +224,8 @@ class WebWorkerDriverTest { bindDouble(4, Float.MAX_VALUE.toDouble()) } - val mapper: (SqlCursor) -> Unit = { - assertTrue(it.next()) + val mapper: suspend (SqlCursor) -> Unit = { + assertTrue(it.next().await()) assertEquals(1, it.getLong(0)) assertEquals(Long.MAX_VALUE, it.getLong(1)) assertEquals("Hello", it.getString(2)) From fcb46f8c673daba2ce5e0cb1ba2c9b76c450872b Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 14:56:52 -0400 Subject: [PATCH 09/10] Fix missing `await()` --- .../app/cash/sqldelight/async/coroutines/QueryExtensions.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt index 79e67d54a66..709c216f5a5 100644 --- a/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt +++ b/extensions/async-extensions/src/commonMain/kotlin/app/cash/sqldelight/async/coroutines/QueryExtensions.kt @@ -11,7 +11,7 @@ suspend fun ExecutableQuery.awaitAsList(): List = execute { curs if (first is QueryResult.AsyncValue) { QueryResult.AsyncValue { if (first.await()) result.add(mapper(cursor)) else return@AsyncValue result - while (cursor.next().value) result.add(mapper(cursor)) + while (cursor.next().await()) result.add(mapper(cursor)) result } } else { @@ -34,7 +34,7 @@ suspend fun ExecutableQuery.awaitAsOneOrNull(): T? = execute { curs QueryResult.AsyncValue { if (!next.await()) return@AsyncValue null val value = mapper(cursor) - check(!cursor.next().value) { "ResultSet returned more than 1 row for $this" } + check(!cursor.next().await()) { "ResultSet returned more than 1 row for $this" } value } } else { From 64c729f83e87514866f86d94e8a85751805ee7ad Mon Sep 17 00:00:00 2001 From: Derek Ellis Date: Tue, 25 Apr 2023 15:15:09 -0400 Subject: [PATCH 10/10] Continue the game of compiler error whack-a-mole --- .../test/kotlin/app/cash/sqldelight/rx2/RecordingObserver.kt | 5 +++-- .../test/kotlin/app/cash/sqldelight/rx3/RecordingObserver.kt | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/RecordingObserver.kt b/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/RecordingObserver.kt index e89c4fb4a4e..1b2f40a1975 100644 --- a/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/RecordingObserver.kt +++ b/extensions/rxjava2-extensions/src/test/kotlin/app/cash/sqldelight/rx2/RecordingObserver.kt @@ -16,6 +16,7 @@ package app.cash.sqldelight.rx2 import app.cash.sqldelight.Query +import app.cash.sqldelight.db.QueryResult import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import io.reactivex.observers.DisposableObserver @@ -37,9 +38,9 @@ internal class RecordingObserver(val numberOfColumns: Int) : DisposableObserver< override fun onNext(value: Query<*>) { val allRows = value.execute { cursor -> val data = mutableListOf>() - while (cursor.next()) + while (cursor.next().value) data.add((0 until numberOfColumns).map(cursor::getString)) - data + QueryResult.Value(data) }.value events.add(allRows) } diff --git a/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/RecordingObserver.kt b/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/RecordingObserver.kt index e339c4118fd..e0fc3ba94b7 100644 --- a/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/RecordingObserver.kt +++ b/extensions/rxjava3-extensions/src/test/kotlin/app/cash/sqldelight/rx3/RecordingObserver.kt @@ -16,6 +16,7 @@ package app.cash.sqldelight.rx3 import app.cash.sqldelight.Query +import app.cash.sqldelight.db.QueryResult import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import io.reactivex.rxjava3.observers.DisposableObserver @@ -37,9 +38,9 @@ internal class RecordingObserver(val numberOfColumns: Int) : DisposableObserver< override fun onNext(value: Query<*>) { val allRows = value.execute { cursor -> val data = mutableListOf>() - while (cursor.next()) + while (cursor.next().value) data.add((0 until numberOfColumns).map(cursor::getString)) - data + QueryResult.Value(data) }.value events.add(allRows) }