perf/fix(data): batch sync updates, paging tiebreaker, migration-registration test
#310: add a single-transaction MessageDao.updateHeaderContents(List<MessageEntity>) and route MailSyncer's per-message updateHeaderContent loop through it, so a folder's recent-window refresh commits once instead of once per message (fsync/journal write per message, amplified on the encrypted cache). #311: append the `id` primary key as a tiebreaker to the four paged MessageDao `ORDER BY timestampMillis DESC` queries for a total order, so rows sharing a second (bulk mail) can't duplicate or skip across a LIMIT/OFFSET page boundary. Pure query-text change: the exported Room schema (identityHash) is derived from table/index structure, not @Query SQL, so no schema re-export or version bump; id is already in the projection, so no new index. #312: expose the registered migration list as DatabaseModule.ALL_MIGRATIONS (spread into addMigrations) and assert in MigrationTest that it equals the reflectively-discovered set of every Migration val, so a migration forgotten in addMigrations fails a test instead of crash-looping all upgrading users at DB open (there is deliberately no destructive fallback). Tests: new MessageDaoTest cases for the batch update and the id tiebreaker (all four pagers), and the MigrationTest registration assertion; wired updateHeaderContents into MailSyncConcurrencyTest's fake DAO. Instrumented MessageDaoTest + MigrationTest (31 tests) green on a local emulator; unit tests + androidTest compile + ktlint + detekt green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -410,6 +410,11 @@ class MailSyncConcurrencyTest {
|
||||
coEvery { dao.updateHeaderContent(any(), any(), any(), any(), any(), any()) } answers {
|
||||
store.updateHeaderContent(firstArg(), secondArg(), thirdArg(), arg(3), arg(4), arg(5))
|
||||
}
|
||||
coEvery { dao.updateHeaderContents(any()) } answers {
|
||||
firstArg<List<MessageEntity>>().forEach {
|
||||
store.updateHeaderContent(it.id, it.sender, it.senderEmail, it.subject, it.timestampMillis, it.uid)
|
||||
}
|
||||
}
|
||||
coEvery { dao.deleteByIds(any()) } answers { store.deleteByIds(firstArg()) }
|
||||
coEvery { dao.deleteSyncedByAccountFolder(any(), any()) } answers {
|
||||
store.deleteSyncedByAccountFolder(firstArg(), secondArg())
|
||||
|
||||
Reference in New Issue
Block a user