sdmaid-se/app-common-data
darken f68dffa669 Fix: Restore backup databases without ATTACH so Room keeps tracking changes
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.
2026-11-06 18:08:40 +01:00
..
src Fix: Restore backup databases without ATTACH so Room keeps tracking changes 2026-11-06 18:08:40 +01:00
build.gradle.kts General: Replace Moshi with Kotlin X serialization 2026-03-28 09:17:10 +01:00
consumer-rules.pro General: Keep more class names readable in obfuscated gplay logs 2026-09-06 12:49:26 +02:00