@@ -8,9 +8,11 @@ import androidx.room.useWriterConnection
88import androidx.sqlite.SQLiteStatement
99import com.powersync.db.driver.SQLiteConnectionLease
1010import com.powersync.db.driver.SQLiteConnectionPool
11+ import com.powersync.db.schema.Schema
1112import kotlinx.coroutines.currentCoroutineContext
1213import kotlinx.coroutines.flow.MutableSharedFlow
1314import kotlinx.coroutines.flow.SharedFlow
15+ import kotlinx.coroutines.launch
1416import kotlinx.coroutines.runBlocking
1517import kotlinx.serialization.json.Json
1618import kotlin.coroutines.CoroutineContext
@@ -23,16 +25,23 @@ import kotlin.coroutines.CoroutineContext
2325 *
2426 * Writes made from the wrapped PowerSync database, including writes made for the sync process, are
2527 * forwarded to Room and will update your flows automatically.
26- * On the other hand, the PowerSync SDK needs to be notified about updates in Room. For that, use
27- * the [transferRoomUpdatesToPowerSync] method as a collector of a Room flow listening on all your
28- * tables.
28+ *
29+ * On the other hand, the PowerSync SDK needs to be notified about updates in Room. For that, a
30+ * schema parameter can be used in the constructor. It will call [syncRoomUpdatesToPowerSync] to
31+ * collect a Room flow on all tables. Alternatively, [transferPendingRoomUpdatesToPowerSync] can be
32+ * called after issuing writes in Room to transfer them to PowerSync.
2933 */
3034public class RoomConnectionPool (
3135 private val db : RoomDatabase ,
36+ schema : Schema ? = null ,
3237) : SQLiteConnectionPool {
3338 private val _updates = MutableSharedFlow <Set <String >>()
3439 private var hasInstalledUpdateHook = false
3540
41+ init {
42+ schema?.let { syncRoomUpdatesToPowerSync(it) }
43+ }
44+
3645 override suspend fun <R > withAllConnections (action : suspend (SQLiteConnectionLease , List <SQLiteConnectionLease >) -> R ) {
3746 // We can't obtain a list of all connections on Room. That's fine though, we expect this to
3847 // be used with raw tables, and withAllConnections is only used to apply a PowerSync schema.
@@ -50,12 +59,25 @@ public class RoomConnectionPool(
5059 * Makes pending updates tracked by Room's invalidation tracker available to the PowerSync
5160 * database, updating flows and triggering CRUD uploads.
5261 */
53- public suspend fun transferRoomUpdatesToPowerSync () {
62+ public suspend fun transferPendingRoomUpdatesToPowerSync () {
5463 write {
5564 // The end of the write callback invokes powersync_update_hooks('get') for this
5665 }
5766 }
5867
68+ /* *
69+ * Registers a Room listener on all tables mentioned in the [schema] and invokes
70+ * [transferPendingRoomUpdatesToPowerSync] when they change.
71+ */
72+ public fun syncRoomUpdatesToPowerSync (schema : Schema ) {
73+ db.getCoroutineScope().launch {
74+ val tables = schema.rawTables.map { it.name }.toTypedArray()
75+ db.invalidationTracker.createFlow(* tables, emitInitialState = false ).collect {
76+ transferPendingRoomUpdatesToPowerSync()
77+ }
78+ }
79+ }
80+
5981 override suspend fun <T > write (callback : suspend (SQLiteConnectionLease ) -> T ): T =
6082 db.useWriterConnection {
6183 if (! hasInstalledUpdateHook) {
0 commit comments