cleanup at death
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 4m44s

This commit is contained in:
Torsten Schulz (local)
2026-11-04 15:14:08 +01:00
parent 30f5c22974
commit da2b32e877
5 changed files with 124 additions and 9 deletions

View 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;

View File

@@ -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
```