deckhearth/migrations/1781442175729_normalize-lorcana-set-codes.js

120 lines
3.4 KiB
JavaScript
Raw Permalink Normal View History

/**
* Normalize legacy Lorcana set_code values and scryfall_id (external id) shapes
* so bulk import from lorcana-api.com upserts cleanly instead of inserting duplicates.
*
* Legacy imports used numeric set codes (1/2/3) or lowercase abbreviations (tfc/rotf/ink).
* The bulk API uses Set_ID values TFC, ROF, INK, etc., and Unique_ID like TFC-001.
*/
export const shorthands = undefined;
export const up = (pgm) => {
pgm.sql(`
UPDATE cards
SET game = 'Lorcana'
WHERE game ILIKE 'lorcana' AND game <> 'Lorcana';
UPDATE cards
SET set_code = 'TFC', set_name = 'The First Chapter'
WHERE game = 'Lorcana' AND set_code IN ('1', 'tfc', 'TFC');
UPDATE cards
SET set_code = 'ROF', set_name = 'Rise of the Floodborn'
WHERE game = 'Lorcana' AND set_code IN ('2', 'rotf', 'ROF');
UPDATE cards
SET set_code = 'INK', set_name = 'Into the Inklands'
WHERE game = 'Lorcana' AND set_code IN ('3', 'ink', 'INK', 'ITI');
UPDATE cards
SET set_code = 'TFC', set_name = 'The First Chapter'
WHERE game = 'Lorcana'
AND set_code IS NULL
AND set_name ILIKE '%first chapter%';
UPDATE cards
SET set_code = 'ROF', set_name = 'Rise of the Floodborn'
WHERE game = 'Lorcana'
AND set_code IS NULL
AND set_name ILIKE '%rise of the floodborn%';
UPDATE cards
SET set_code = 'INK', set_name = 'Into the Inklands'
WHERE game = 'Lorcana'
AND set_code IS NULL
AND set_name ILIKE '%into the inklands%';
`);
// Drop legacy duplicate rows when the canonical Unique_ID row already exists.
pgm.sql(`
DELETE FROM cards AS dup
WHERE dup.game = 'Lorcana'
AND dup.set_code IS NOT NULL
AND TRIM(dup.card_number) <> ''
AND dup.scryfall_id IS DISTINCT FROM (
dup.set_code || '-' || LPAD(
REGEXP_REPLACE(TRIM(dup.card_number), '/.*$', ''),
3,
'0'
)
)
AND EXISTS (
SELECT 1
FROM cards AS keeper
WHERE keeper.scryfall_id = dup.set_code || '-' || LPAD(
REGEXP_REPLACE(TRIM(dup.card_number), '/.*$', ''),
3,
'0'
)
);
`);
// Keep one row per set + collector number before scryfall_id unification.
pgm.sql(`
DELETE FROM cards AS dup
WHERE dup.game = 'Lorcana'
AND dup.set_code IS NOT NULL
AND TRIM(dup.card_number) <> ''
AND dup.id <> (
SELECT MIN(peer.id)
FROM cards AS peer
WHERE peer.game = 'Lorcana'
AND peer.set_code = dup.set_code
AND REGEXP_REPLACE(TRIM(peer.card_number), '/.*$', '') = REGEXP_REPLACE(TRIM(dup.card_number), '/.*$', '')
);
`);
// Unify remaining legacy scryfall_id values to Unique_ID shape (SET-NNN).
pgm.sql(`
UPDATE cards AS c
SET scryfall_id = c.set_code || '-' || LPAD(
REGEXP_REPLACE(TRIM(c.card_number), '/.*$', ''),
3,
'0'
)
WHERE c.game = 'Lorcana'
AND c.set_code IS NOT NULL
AND TRIM(c.card_number) <> ''
AND c.scryfall_id IS DISTINCT FROM (
c.set_code || '-' || LPAD(
REGEXP_REPLACE(TRIM(c.card_number), '/.*$', ''),
3,
'0'
)
)
AND NOT EXISTS (
SELECT 1
FROM cards AS other
WHERE other.scryfall_id = c.set_code || '-' || LPAD(
REGEXP_REPLACE(TRIM(c.card_number), '/.*$', ''),
3,
'0'
)
);
`);
};
export const down = () => {
throw new Error('Irreversible data migration');
};