fix(data): AccountDao.upsert(REPLACE) cascade-deletes signatures+settings on account re-add #309

Closed
opened 2026-07-04 06:52:40 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-07-04 06:52:40 +00:00 (Migrated from github.com)

Phase-3 review (MEDIUM/data-loss). AccountDao.upsert(:30) is @Insert(onConflict=REPLACE); account_settings+signatures have ON DELETE CASCADE FKs to accounts.id. SQLite INSERT-OR-REPLACE on PK conflict = delete-then-insert, firing the cascade. So upsert of an EXISTING account id (re-adding an Outlook account — deterministic id outlook:$email; addOutlookAccount→insertAtEnd→upsert) cascade-deletes the account's settings + signatures permanently (ensureDefaults recreates settings but signatures are gone). No dup-account guard → reachable. Fix: @Update for edits + non-destructive insert (ABORT/IGNORE) for new accounts, or split create-vs-update so an existing row is never REPLACE-deleted (mirror the IGNORE already used in messages insertNew). Test.

Phase-3 review (MEDIUM/data-loss). `AccountDao.upsert`(:30) is `@Insert(onConflict=REPLACE)`; `account_settings`+`signatures` have `ON DELETE CASCADE` FKs to `accounts.id`. SQLite INSERT-OR-REPLACE on PK conflict = delete-then-insert, firing the cascade. So upsert of an EXISTING account id (re-adding an Outlook account — deterministic id `outlook:$email`; `addOutlookAccount`→`insertAtEnd`→`upsert`) cascade-deletes the account's settings + **signatures permanently** (ensureDefaults recreates settings but signatures are gone). No dup-account guard → reachable. **Fix:** `@Update` for edits + non-destructive insert (ABORT/IGNORE) for new accounts, or split create-vs-update so an existing row is never REPLACE-deleted (mirror the `IGNORE` already used in messages `insertNew`). Test.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#309