Files
yourpart-daemon/migrations/020_falukant_character_relation_cleanup.sql
Torsten Schulz (local) da2b32e877
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 4m44s
cleanup at death
2026-11-04 15:14:08 +01:00

78 lines
3.3 KiB
PL/PgSQL

-- Charakter-Verknüpfungen auch bei DELETEs außerhalb der Worker bereinigen.
-- Löscht bestehende verwaiste Beziehungen; vorher auf der Ziel-DB sichern.
BEGIN;
LOCK TABLE falukant_data.character, falukant_data.relationship,
falukant_data.relationship_state, falukant_data.child_relation
IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM falukant_data.relationship_state rs
WHERE NOT EXISTS (
SELECT 1 FROM falukant_data.relationship r WHERE r.id = rs.relationship_id
)
OR EXISTS (
SELECT 1 FROM falukant_data.relationship r
WHERE r.id = rs.relationship_id
AND ((r.character1_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM falukant_data.character c WHERE c.id = r.character1_id))
OR (r.character2_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM falukant_data.character c WHERE c.id = r.character2_id)))
);
DELETE FROM falukant_data.relationship r
WHERE (r.character1_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM falukant_data.character c WHERE c.id = r.character1_id
)) OR (r.character2_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM falukant_data.character c WHERE c.id = r.character2_id
));
DELETE FROM falukant_data.child_relation cr
WHERE (cr.child_character_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM falukant_data.character c WHERE c.id = cr.child_character_id
)) OR (cr.father_character_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM falukant_data.character c WHERE c.id = cr.father_character_id
)) OR (cr.mother_character_id IS NOT NULL AND NOT EXISTS (
SELECT 1 FROM falukant_data.character c WHERE c.id = cr.mother_character_id
));
-- Vorhandene einspaltige FKs ersetzen (deren Namen sind je nach Backend verschieden).
-- Auch relationship_state absichern, damit es die Kaskade nicht blockieren kann.
DO $$
DECLARE
target record;
existing_fk record;
BEGIN
FOR target IN
SELECT * FROM (VALUES
('relationship', 'character1_id', 'character'),
('relationship', 'character2_id', 'character'),
('child_relation', 'child_character_id', 'character'),
('child_relation', 'father_character_id', 'character'),
('child_relation', 'mother_character_id', 'character'),
('relationship_state', 'relationship_id', 'relationship')
) AS targets(table_name, column_name, referenced_table)
LOOP
FOR existing_fk IN
SELECT con.conname
FROM pg_constraint con
JOIN pg_attribute att ON att.attrelid = con.conrelid
AND con.conkey = ARRAY[att.attnum]
WHERE con.contype = 'f'
AND con.conrelid = format('falukant_data.%I', target.table_name)::regclass
AND con.confrelid = format('falukant_data.%I', target.referenced_table)::regclass
AND att.attname = target.column_name
LOOP
EXECUTE format('ALTER TABLE falukant_data.%I DROP CONSTRAINT %I',
target.table_name, existing_fk.conname);
END LOOP;
EXECUTE format(
'ALTER TABLE falukant_data.%I ADD CONSTRAINT %I FOREIGN KEY (%I) REFERENCES falukant_data.%I (id) ON DELETE CASCADE',
target.table_name, target.table_name || '_' || target.column_name || '_fkey',
target.column_name, target.referenced_table);
END LOOP;
END;
$$;
COMMIT;