Skip to content

Restore DAV database invariants and sync indexes#276

Open
AnnoyingTechnology wants to merge 1 commit into
tchapi:mainfrom
AnnoyingTechnology:database-invariants
Open

Restore DAV database invariants and sync indexes#276
AnnoyingTechnology wants to merge 1 commit into
tchapi:mainfrom
AnnoyingTechnology:database-invariants

Conversation

@AnnoyingTechnology

@AnnoyingTechnology AnnoyingTechnology commented Jul 20, 2026

Copy link
Copy Markdown

Why

The schema omits database invariants assumed by the SabreDAV PDO backends. SQLite is affected most sharply: its migration-created tables have no foreign keys at all, and SQLite does not enforce declared foreign keys unless every connection enables them.

This is also correctness-sensitive in propertystorage: PostgreSQL uses ON CONFLICT (path, name), which requires a matching unique key, while SQLite and MariaDB use REPLACE, which only replaces the existing property when that key is unique. DAV resource identifiers are likewise collection-scoped in the application but not consistently constrained in the database. Finally, incremental sync filters and orders change rows by collection and token while the schema indexes only the collection.

SQLite should be a first-class database here. The same integrity semantics must remain true on MariaDB and PostgreSQL; this PR does not remove or reduce support for either.

What changed

  • add the seven DAV relationship foreign keys missing from SQLite and enable enforcement on every SQLite connection
  • make wholly owned DAV rows and principal memberships cascade on parent deletion across SQLite, MariaDB, and PostgreSQL, matching application deletion semantics and avoiding order-dependent cleanup
  • preflight every relationship and abort with the exact orphaned key instead of changing or deleting user data
  • add database-level unique constraints for DAV collection and resource keys
  • add (calendarid, synctoken) and (addressbookid, synctoken) indexes for incremental sync
  • declare the same constraints and indexes in Doctrine metadata
  • preflight candidate unique keys, preserving SQL null semantics and reporting the exact conflict

Verification

  • SQLite: fresh migration; real FK enforcement; cascade behavior; orphan rejection without data loss; migration down/up; index preservation; query-plan inspection
  • MariaDB 10.11: fresh migration; FK enforcement and cascade behavior; migration down/up; exact Doctrine schema validation; full suite passes (60 tests / 406 assertions, one SQLite-only skip)
  • PostgreSQL 15: fresh migration; FK enforcement and cascade behavior; migration down/up; index preservation
  • combined with the first-class SQLite test work: full suite passes (60 tests / 410 assertions)

@AnnoyingTechnology
AnnoyingTechnology force-pushed the database-invariants branch 2 times, most recently from 182af78 to 937639f Compare July 20, 2026 17:42
Add the collection-scoped uniqueness constraints expected by the SabreDAV PDO backends, including the path/name constraint required by property upserts. Add compound indexes matching calendar and address-book sync queries.\n\nAbort with an actionable message when legacy duplicates would make a unique index unsafe rather than deleting or merging user data.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant