cleanup at death
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 4m44s
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 4m44s
This commit is contained in:
77
migrations/020_falukant_character_relation_cleanup.sql
Normal file
77
migrations/020_falukant_character_relation_cleanup.sql
Normal file
@@ -0,0 +1,77 @@
|
||||
-- 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;
|
||||
@@ -65,3 +65,20 @@ negativen Ruf- und Eheeffekte für niedrige und mittlere Stände).
|
||||
Der Backend-Auftrag verwendet `performer_id`, `victim_id` und optional in
|
||||
`parameters` `goal` (`expose`, Standard; oder `blackmail`) sowie
|
||||
`relationship_id`. Details: `docs/FALUKANT_UNDERGROUND_INVESTIGATE_AFFAIR.md`.
|
||||
|
||||
## `020_falukant_character_relation_cleanup.sql`
|
||||
|
||||
Entfernt bestehende verwaiste Einträge aus `relationship`, `relationship_state`
|
||||
und `child_relation`. Sichert anschließend beide Beziehungspartner sowie Kind,
|
||||
Vater und Mutter mit Fremdschlüsseln und `ON DELETE CASCADE` ab. Damit werden
|
||||
die Verknüpfungen bei jeder Charakter-Löschung entfernt, auch außerhalb des
|
||||
Daemons. `relationship_state` wird zusammen mit der Beziehung gelöscht.
|
||||
Zeilen mit unbekanntem Elternteil (`NULL`) bleiben gültig.
|
||||
|
||||
Voraussetzung: Migration `001` ist eingespielt. Die Migration läuft atomar,
|
||||
ist wiederholbar und sperrt Schreibzugriffe auf die betroffenen Tabellen für
|
||||
ihre Laufzeit. Nach Backup manuell auf der Ziel-DB ausführen:
|
||||
|
||||
```bash
|
||||
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f migrations/020_falukant_character_relation_cleanup.sql
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user