fix: cascade-clean ignored/blocked rows on hard contact delete

hard_delete_contact() failed with FOREIGN KEY constraint when the
contact had a row in ignored_contacts or blocked_contacts, since those
FKs lacked ON DELETE CASCADE. Delete dependent rows first in the same
transaction; also update schema for new deployments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-04-15 08:35:31 +02:00
parent bd0a6b492e
commit 8ccb3100c2
2 changed files with 11 additions and 7 deletions
+9 -5
View File
@@ -197,12 +197,16 @@ class Database:
return cursor.rowcount > 0
def hard_delete_contact(self, public_key: str) -> bool:
"""Permanently delete a contact from the database."""
"""Permanently delete a contact from the database.
Also clears ignored/blocked rows that reference this contact
via FK without ON DELETE CASCADE.
"""
pk = public_key.lower()
with self._connect() as conn:
cursor = conn.execute(
"DELETE FROM contacts WHERE public_key = ?",
(public_key.lower(),)
)
conn.execute("DELETE FROM ignored_contacts WHERE public_key = ?", (pk,))
conn.execute("DELETE FROM blocked_contacts WHERE public_key = ?", (pk,))
cursor = conn.execute("DELETE FROM contacts WHERE public_key = ?", (pk,))
return cursor.rowcount > 0
def downgrade_stale_device_contacts(self, active_device_keys: set) -> int:
+2 -2
View File
@@ -152,13 +152,13 @@ CREATE TABLE IF NOT EXISTS read_status (
-- Ignored contacts (adverts cached but not pending/auto-added)
CREATE TABLE IF NOT EXISTS ignored_contacts (
public_key TEXT PRIMARY KEY REFERENCES contacts(public_key),
public_key TEXT PRIMARY KEY REFERENCES contacts(public_key) ON DELETE CASCADE,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Blocked contacts (ignored + messages hidden from display)
CREATE TABLE IF NOT EXISTS blocked_contacts (
public_key TEXT PRIMARY KEY REFERENCES contacts(public_key),
public_key TEXT PRIMARY KEY REFERENCES contacts(public_key) ON DELETE CASCADE,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);