fix: merge duplicate series created by pre-rename scanner bug
Add migration 0063 to fuse series where the scanner recreated an old filesystem-named entry alongside the user-renamed canonical one (e.g. "LES MYTHICS" alongside "Mythics"). Uses the original_name column from 0062 to identify and collapse all such duplicates: reassigns books, external_metadata_links, anilist_series_links, then deletes the stale series_metadata row. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
64
infra/migrations/0063_merge_duplicate_renamed_series.sql
Normal file
64
infra/migrations/0063_merge_duplicate_renamed_series.sql
Normal file
@@ -0,0 +1,64 @@
|
||||
-- Fix duplicate series created when the scanner recreated a filesystem-named
|
||||
-- series alongside a user-renamed one.
|
||||
-- Example: user renamed "LES MYTHICS" → "Mythics" via UI, but the scanner
|
||||
-- also kept (or recreated) a "LES MYTHICS" entry. This migration merges
|
||||
-- all such duplicates by using the original_name column added in 0062.
|
||||
--
|
||||
-- For each canonical series (original_name IS NOT NULL), if a duplicate still
|
||||
-- exists with name = original_name in the same library, we:
|
||||
-- 1. Reassign books from the duplicate to the canonical series
|
||||
-- 2. Update external_metadata_links
|
||||
-- 3. Update anilist_series_links
|
||||
-- 4. Delete the duplicate series_metadata row
|
||||
|
||||
-- 1. Reassign books
|
||||
UPDATE books b
|
||||
SET series = sm_canonical.name
|
||||
FROM series_metadata sm_canonical
|
||||
JOIN series_metadata sm_dup
|
||||
ON sm_dup.library_id = sm_canonical.library_id
|
||||
AND sm_dup.name = sm_canonical.original_name
|
||||
WHERE b.library_id = sm_canonical.library_id
|
||||
AND b.series = sm_dup.name
|
||||
AND sm_canonical.original_name IS NOT NULL;
|
||||
|
||||
-- 2. Update external_metadata_links (skip if a row for the canonical name already exists)
|
||||
UPDATE external_metadata_links eml
|
||||
SET series_name = sm_canonical.name
|
||||
FROM series_metadata sm_canonical
|
||||
JOIN series_metadata sm_dup
|
||||
ON sm_dup.library_id = sm_canonical.library_id
|
||||
AND sm_dup.name = sm_canonical.original_name
|
||||
WHERE eml.library_id = sm_canonical.library_id
|
||||
AND eml.series_name = sm_dup.name
|
||||
AND sm_canonical.original_name IS NOT NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM external_metadata_links eml2
|
||||
WHERE eml2.library_id = eml.library_id
|
||||
AND eml2.series_name = sm_canonical.name
|
||||
AND eml2.provider = eml.provider
|
||||
);
|
||||
|
||||
-- 3. Update anilist_series_links (skip if a row for the canonical name already exists)
|
||||
UPDATE anilist_series_links asl
|
||||
SET series_name = sm_canonical.name
|
||||
FROM series_metadata sm_canonical
|
||||
JOIN series_metadata sm_dup
|
||||
ON sm_dup.library_id = sm_canonical.library_id
|
||||
AND sm_dup.name = sm_canonical.original_name
|
||||
WHERE asl.library_id = sm_canonical.library_id
|
||||
AND asl.series_name = sm_dup.name
|
||||
AND sm_canonical.original_name IS NOT NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM anilist_series_links asl2
|
||||
WHERE asl2.library_id = asl.library_id
|
||||
AND asl2.series_name = sm_canonical.name
|
||||
AND asl2.provider = asl.provider
|
||||
);
|
||||
|
||||
-- 4. Delete duplicate series_metadata rows
|
||||
DELETE FROM series_metadata sm_dup
|
||||
USING series_metadata sm_canonical
|
||||
WHERE sm_canonical.library_id = sm_dup.library_id
|
||||
AND sm_canonical.original_name = sm_dup.name
|
||||
AND sm_canonical.original_name IS NOT NULL;
|
||||
Reference in New Issue
Block a user