@@ -2,6 +2,7 @@ package com.powersync.sync
22
33import app.cash.turbine.turbineScope
44import co.touchlab.kermit.ExperimentalKermitApi
5+ import com.powersync.ExperimentalPowerSyncAPI
56import com.powersync.PowerSyncDatabase
67import com.powersync.PowerSyncException
78import com.powersync.TestConnector
@@ -13,6 +14,9 @@ import com.powersync.bucket.OplogEntry
1314import com.powersync.bucket.WriteCheckpointData
1415import com.powersync.bucket.WriteCheckpointResponse
1516import com.powersync.db.PowerSyncDatabaseImpl
17+ import com.powersync.db.schema.PendingStatement
18+ import com.powersync.db.schema.PendingStatementParameter
19+ import com.powersync.db.schema.RawTable
1620import com.powersync.db.schema.Schema
1721import com.powersync.testutils.UserRow
1822import com.powersync.testutils.databaseTest
@@ -650,7 +654,7 @@ abstract class BaseSyncIntegrationTest(
650654class LegacySyncIntegrationTest : BaseSyncIntegrationTest (false )
651655
652656class NewSyncIntegrationTest : BaseSyncIntegrationTest (true ) {
653- // The legacy sync implementation doesn't prefetch credentials.
657+ // The legacy sync implementation doesn't prefetch credentials and doesn't support raw tables .
654658
655659 @OptIn(LegacySyncImplementation ::class )
656660 @Test
@@ -688,4 +692,88 @@ class NewSyncIntegrationTest : BaseSyncIntegrationTest(true) {
688692 turbine.cancel()
689693 }
690694 }
695+
696+ @Test
697+ @OptIn(ExperimentalPowerSyncAPI ::class , LegacySyncImplementation ::class )
698+ fun rawTables () = databaseTest(createInitialDatabase = false ) {
699+ val db = openDatabase(Schema (listOf (
700+ RawTable (
701+ name = " lists" ,
702+ put = PendingStatement (
703+ " INSERT OR REPLACE INTO lists (id, name) VALUES (?, ?)" ,
704+ listOf (PendingStatementParameter .Id , PendingStatementParameter .Column (" name" ))
705+ ),
706+ delete = PendingStatement (
707+ " DELETE FROM lists WHERE id = ?" , listOf (PendingStatementParameter .Id )
708+ )
709+ )
710+ )))
711+
712+ db.execute(" CREATE TABLE lists (id TEXT NOT NULL PRIMARY KEY, name TEXT)" )
713+ turbineScope(timeout = 10.0 .seconds) {
714+ val query = db.watch(" SELECT * FROM lists" , throttleMs = 0L ) {
715+ it.getString(0 ) to it.getString(1 )
716+ }.testIn(this )
717+ query.awaitItem() shouldBe emptyList()
718+
719+ db.connect(connector, options = options)
720+ syncLines.send(SyncLine .FullCheckpoint (Checkpoint (
721+ lastOpId = " 1" ,
722+ checksums = listOf (BucketChecksum (" a" , checksum = 0 )),
723+ )))
724+ syncLines.send(
725+ SyncLine .SyncDataBucket (
726+ bucket = " a" ,
727+ data =
728+ listOf (
729+ OplogEntry (
730+ checksum = 0L ,
731+ data =
732+ JsonUtil .json.encodeToString(
733+ mapOf (
734+ " name" to " custom list" ,
735+ ),
736+ ),
737+ op = OpType .PUT ,
738+ opId = " 1" ,
739+ rowId = " my_list" ,
740+ rowType = " lists" ,
741+ ),
742+ ),
743+ after = null ,
744+ nextAfter = null ,
745+ ),
746+ )
747+ syncLines.send(SyncLine .CheckpointComplete (" 1" ))
748+
749+ query.awaitItem() shouldBe listOf (" my_list" to " custom list" )
750+
751+ syncLines.send(SyncLine .FullCheckpoint (Checkpoint (
752+ lastOpId = " 2" ,
753+ checksums = listOf (BucketChecksum (" a" , checksum = 0 )),
754+ )))
755+ syncLines.send(
756+ SyncLine .SyncDataBucket (
757+ bucket = " a" ,
758+ data =
759+ listOf (
760+ OplogEntry (
761+ checksum = 0L ,
762+ data = null ,
763+ op = OpType .REMOVE ,
764+ opId = " 2" ,
765+ rowId = " my_list" ,
766+ rowType = " lists" ,
767+ ),
768+ ),
769+ after = null ,
770+ nextAfter = null ,
771+ ),
772+ )
773+ syncLines.send(SyncLine .CheckpointComplete (" 1" ))
774+
775+ query.awaitItem() shouldBe emptyList()
776+ query.cancelAndIgnoreRemainingEvents()
777+ }
778+ }
691779}
0 commit comments