@@ -3,13 +3,17 @@ package com.powersync.db.internal
33import androidx.sqlite.SQLiteStatement
44import com.powersync.ExperimentalPowerSyncAPI
55import com.powersync.PowerSyncException
6+ import com.powersync.db.QueryRunner
67import com.powersync.db.SqlCursor
78import com.powersync.db.StatementBasedCursor
89import com.powersync.db.driver.SQLiteConnectionLease
10+ import kotlinx.coroutines.runBlocking
911
1012public interface ConnectionContext {
1113 // TODO (breaking): Make asynchronous, create shared superinterface with Queries
1214
15+ public val async: QueryRunner
16+
1317 @Throws(PowerSyncException ::class )
1418 public fun execute (
1519 sql : String ,
@@ -38,13 +42,53 @@ public interface ConnectionContext {
3842 ): RowType
3943}
4044
41- @ExperimentalPowerSyncAPI
42- internal class ConnectionContextImplementation (
43- private val rawConnection : SQLiteConnectionLease ,
44- ) : ConnectionContext {
45+ /* *
46+ * An implementation of a [ConnectionContext] that delegates to a [QueryRunner] via [runBlocking].
47+ */
48+ internal abstract class BaseConnectionContextImplementation () : ConnectionContext {
4549 override fun execute (
4650 sql : String ,
4751 parameters : List <Any ?>? ,
52+ ): Long = runBlocking { async.execute(sql, parameters) }
53+
54+ override fun <RowType : Any > getOptional (
55+ sql : String ,
56+ parameters : List <Any ?>? ,
57+ mapper : (SqlCursor ) -> RowType ,
58+ ): RowType ? = runBlocking {
59+ async.getOptional(sql, parameters, mapper)
60+ }
61+
62+ override fun <RowType : Any > getAll (
63+ sql : String ,
64+ parameters : List <Any ?>? ,
65+ mapper : (SqlCursor ) -> RowType ,
66+ ): List <RowType > =
67+ runBlocking {
68+ async.getAll(sql, parameters, mapper)
69+ }
70+
71+ override fun <RowType : Any > get (
72+ sql : String ,
73+ parameters : List <Any ?>? ,
74+ mapper : (SqlCursor ) -> RowType ,
75+ ): RowType = runBlocking {
76+ async.get(sql, parameters, mapper)
77+ }
78+ }
79+
80+ @OptIn(ExperimentalPowerSyncAPI ::class )
81+ internal class ConnectionContextImplementation (lease : SQLiteConnectionLease ): BaseConnectionContextImplementation() {
82+ override val async = ContextQueryRunner (lease)
83+ }
84+
85+ @OptIn(ExperimentalPowerSyncAPI ::class )
86+ internal class ContextQueryRunner (
87+ private val rawConnection : SQLiteConnectionLease
88+ ): QueryRunner {
89+ override suspend fun execute (
90+ sql : String ,
91+ parameters : List <Any ?>?
4892 ): Long {
4993 withStatement(sql, parameters) {
5094 while (it.step()) {
@@ -58,45 +102,43 @@ internal class ConnectionContextImplementation(
58102 }
59103 }
60104
61- override fun <RowType : Any > getOptional (
105+ override suspend fun <RowType : Any > get (
62106 sql : String ,
63107 parameters : List <Any ?>? ,
64- mapper : (SqlCursor ) -> RowType ,
65- ): RowType ? =
66- withStatement(sql, parameters) { stmt ->
67- if (stmt.step()) {
68- mapper(StatementBasedCursor (stmt))
69- } else {
70- null
71- }
72- }
108+ mapper : (SqlCursor ) -> RowType
109+ ): RowType = getOptional(sql, parameters, mapper) ? : throw PowerSyncException (" get() called with query that returned no rows" , null )
73110
74- override fun <RowType : Any > getAll (
111+ override suspend fun <RowType : Any > getAll (
75112 sql : String ,
76113 parameters : List <Any ?>? ,
77- mapper : (SqlCursor ) -> RowType ,
78- ): List <RowType > =
79- withStatement(sql, parameters) { stmt ->
80- buildList {
81- val cursor = StatementBasedCursor (stmt)
82- while (stmt.step()) {
83- add(mapper(cursor))
84- }
114+ mapper : (SqlCursor ) -> RowType
115+ ): List <RowType > = withStatement(sql, parameters) { stmt ->
116+ buildList {
117+ val cursor = StatementBasedCursor (stmt)
118+ while (stmt.step()) {
119+ add(mapper(cursor))
85120 }
86121 }
122+ }
87123
88- override fun <RowType : Any > get (
124+ override suspend fun <RowType : Any > getOptional (
89125 sql : String ,
90126 parameters : List <Any ?>? ,
91- mapper : (SqlCursor ) -> RowType ,
92- ): RowType = getOptional(sql, parameters, mapper) ? : throw PowerSyncException (" get() called with query that returned no rows" , null )
127+ mapper : (SqlCursor ) -> RowType
128+ ): RowType ? = withStatement(sql, parameters) { stmt ->
129+ if (stmt.step()) {
130+ mapper(StatementBasedCursor (stmt))
131+ } else {
132+ null
133+ }
134+ }
93135
94- private inline fun <T > withStatement (
136+ private suspend inline fun <T > withStatement (
95137 sql : String ,
96138 parameters : List <Any ?>? ,
97139 crossinline block : (SQLiteStatement ) -> T ,
98140 ): T {
99- return rawConnection.usePreparedSync (sql) { stmt ->
141+ return rawConnection.usePrepared (sql) { stmt ->
100142 stmt.bind(parameters)
101143 block(stmt)
102144 }
0 commit comments