Skip to content

Commit c8fe9bc

Browse files
committed
added support for executeAsFlow()
1 parent 632f60e commit c8fe9bc

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

src/jsMain/kotlin/cz/sazel/sqldelight/node/sqlite3/SQLite3Cursor.kt

+1-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import kotlin.coroutines.resume
99
import kotlin.coroutines.resumeWithException
1010
import kotlin.coroutines.suspendCoroutine
1111

12-
internal class SQLite3Cursor(val statementInit: suspend () -> Sqlite3.Statement) : SqlCursor {
12+
internal class SQLite3Cursor internal constructor(val statementInit: suspend () -> Sqlite3.Statement) : SqlCursor {
1313

1414
private val jsObject = js("Object") //TODO this is weird, find way to improve
1515
private lateinit var statement: Sqlite3.Statement
@@ -26,7 +26,6 @@ internal class SQLite3Cursor(val statementInit: suspend () -> Sqlite3.Statement)
2626
}
2727
row = fetchRow()
2828
if (row == null) {
29-
_close()
3029
return@AsyncValue false
3130
}
3231
counter++
@@ -49,11 +48,6 @@ internal class SQLite3Cursor(val statementInit: suspend () -> Sqlite3.Statement)
4948
return result
5049
}
5150

52-
@Suppress("FunctionNaming")
53-
internal suspend fun _close() {
54-
statement.finalizeSuspending()
55-
}
56-
5751
private suspend fun reset() {
5852
suspendCoroutine { cont ->
5953
val callback: (Nothing?) -> Unit = {

src/jsMain/kotlin/cz/sazel/sqldelight/node/sqlite3/utils.kt

+27-16
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,42 @@ package cz.sazel.sqldelight.node.sqlite3
22

33
import app.cash.sqldelight.Query
44
import app.cash.sqldelight.db.QueryResult
5-
import app.cash.sqldelight.db.SqlCursor
5+
import kotlinx.coroutines.channels.awaitClose
6+
import kotlinx.coroutines.coroutineScope
7+
import kotlinx.coroutines.flow.Flow
8+
import kotlinx.coroutines.flow.callbackFlow
9+
import kotlinx.coroutines.flow.toList
610

711
/**
812
* Workaround suspending method to use with SQLite3 async driver.
913
* Use this instead of non-async method [Query.executeAsList].
1014
* @return The result set of the underlying SQL statement as a list of RowType.
1115
*/
12-
suspend fun <T : Any> Query<T>.executeSuspendingAsList(): List<T> {
13-
val list = execute<List<T>> { cursor ->
14-
QueryResult.AsyncValue {
15-
val result = mutableListOf<T>()
16-
while (cursor.next().await()) result.add(mapper(cursor))
17-
result
18-
}
19-
}.await()
20-
return list
21-
}
16+
suspend fun <T : Any> Query<T>.executeSuspendingAsList(): List<T> =
17+
executeAsFlow().toList(mutableListOf())
2218

2319
/**
24-
* Function that must be used only with [SQLite3Cursor], used to close cursor when no longer used.
20+
* Workaround suspending method to use with SQLite3 async driver.
21+
* Use this instead of non-async method [Query.executeAsList].
22+
* @return The result set of the underlying SQL statement as a list of RowType.
2523
*/
26-
suspend fun SqlCursor.close() {
27-
require(this is SQLite3Cursor)
28-
_close()
29-
}
24+
suspend fun <T : Any> Query<T>.executeAsFlow(): Flow<T> =
25+
coroutineScope {
26+
execute<Flow<T>> { cursor ->
27+
return@execute QueryResult.Value(callbackFlow {
28+
do {
29+
val hasNext = cursor.next().await()
30+
if (!hasNext) {
31+
close()
32+
} else {
33+
val row = mapper(cursor)
34+
send(row)
35+
}
36+
} while (hasNext)
37+
awaitClose()
38+
})
39+
}.await()
40+
}
3041

3142
internal val <T> T?.nullable: T?
3243
get() = when (this) {

0 commit comments

Comments
 (0)