mirror of
https://github.com/VibedByKaKi/sdmaid-se.git
synced 2026-11-12 09:37:17 +01:00
RoomDbBackupContributor.restoreFrom ATTACHed the backup file to the live Room connection and copied rows with INSERT ... SELECT. On a WAL database, SQLiteDatabase.executeSql calls disableWriteAheadLogging() at the first ATTACH. That clears ENABLE_WRITE_AHEAD_LOGGING from the open flags, and SQLiteConnectionPool.reconfigure handles changed open flags by opening a new primary connection (API 36 sources: SQLiteDatabase.java:2218, SQLiteConnectionPool.java:352). Room's TEMP table room_table_modification_log and its TEMP triggers live only on the old connection. The next Flow that started tracking a table then failed in TriggerBasedInvalidationTracker.startTrackingTable with "no such table: room_table_modification_log", and the exception crashed the app. Play vitals show this as four nativePrepareStatement SQLiteException clusters (about 26 users since 2.0.1, when database backups shipped). Rows are now read through the standalone read-only connection that validation already uses and inserted with a compiled statement on the live connection, inside the same single transaction. WAL and Room's TEMP objects stay intact. Rows that don't fit a CursorWindow (about 2 MB) can no longer be restored; Room's own DAOs read through the same window, so the app can't use such rows anyway, and the restore rolls back. Restore writes go through the open helper, not Room's transaction API, so Room never re-checked its tables and open Flows kept showing the pre-restore data. Each contributor now passes an onRestored hook that calls InvalidationTracker.refreshAsync(). StatsDbBackupContributorTest runs a file-backed ReportsRoomDb in WAL mode. It failed with the Play stack trace before the change, and the observer case timed out before the refresh hook existed. |
||
|---|---|---|
| .. | ||
| src | ||
| build.gradle.kts | ||
| consumer-rules.pro | ||