github jessielw/Reclaimerr 0.4.2

2 hours ago

Fixed

  • Deleting a season failed with FOREIGN KEY constraint failed on DELETE FROM seasons for anyone running a linked media server, whether the season was reclaimed from the candidates view, moved instead of deleted, or pruned by a sync that no longer saw it. Supplemental matches -- the identity map a linked server writes so its watch data can be resolved back to local media -- pointed at the season and its episodes with no ON DELETE action, and none of the cleanup that runs before a season is removed touched that table, so the row blocked the delete outright. The constraint now cascades: a match is keyed to a single item on the linked server, so once the local season or episode is gone the row maps nothing and goes with it. Match rows already left dangling are cleaned up on upgrade; the next linked sync rebuilds a server's matches from scratch either way. Only installs with a second media server were affected -- the main server never writes supplemental matches.
  • Foreign keys are now enforced on every database connection, instead of only the ones serving a web request. PRAGMA foreign_keys is a property of a connection rather than of the database, and connections are pooled and reused, so a background task got enforcement or not depending on whether the connection it borrowed had served a request first. That made every ON DELETE rule in the schema a coin flip: the same cleanup run could delete a season and take its episodes with it, or delete the season and strand them. It is the reason the season delete above failed for some people and not others, and the reason the 0.4.1 fix for protections left behind by a replaced movie file had to repair the damage by hand. Enforcement is switched off for migrations alone, where rebuilding a table means dropping one that others reference.
  • Rows stranded by deletes that ran before the change are repaired on upgrade -- episodes whose season is gone, candidates and protections scoped to media that no longer exists, playback events pointing at nothing. They were mostly inert while foreign keys went unenforced, but SQLite re-checks a row's references whenever the row is written, so once enforcement is on a stale row stops being dead weight and becomes one the app cannot update. Each is retired the way the cleanup code already retires it: a candidate or protection covering media that is gone is removed, a request still awaiting a decision is removed, and a decided one is detached and kept as history. Worth knowing: a stranded row is dropped rather than emptied out, because a candidate with no episode means the whole season and a protection with no version means the whole movie -- emptying one would quietly widen what it covers instead of retiring it.

What's Changed

Full Changelog: 0.4.1...0.4.2

Don't miss a new Reclaimerr release

NewReleases is sending notifications on new releases.