41 lines
2.5 KiB
SQL
41 lines
2.5 KiB
SQL
-- Papierkorb: Löschen ist nicht mehr sofort endgültig (AUSBAUSTUFEN.md 3.9).
|
|
--
|
|
-- ── Warum? ───────────────────────────────────────────────────────────────────
|
|
--
|
|
-- Seit der Änderungshistorie (004) lässt sich jedes Überschreiben reparieren.
|
|
-- Löschen nicht: DELETE entfernte den Eintrag samt aller Fassungen (ON DELETE
|
|
-- CASCADE). Damit war "forget" der schlimmste Fall, den ein fehlgeleiteter
|
|
-- Agent anrichten konnte.
|
|
--
|
|
-- ── Aufbau ───────────────────────────────────────────────────────────────────
|
|
--
|
|
-- Löschen setzt jetzt nur noch deleted_at (Zeitpunkt) und deleted_by (Name des
|
|
-- Zugangs). Die Zeile bleibt mit Schlagworten, Verweisen und Verlauf stehen.
|
|
-- Endgültig entfernt wird sie erst, wenn ein Mensch den Papierkorb leert oder
|
|
-- die tägliche Aufgabe sie nach 30 Tagen abräumt — dann greift das bekannte
|
|
-- ON DELETE CASCADE.
|
|
--
|
|
-- deleted_at ist NULL für jeden normalen Eintrag. NULL statt eines leeren
|
|
-- Textes, weil "nicht gelöscht" kein Zeitpunkt ist — und weil sich
|
|
-- "deleted_at IS NULL" in jeder Abfrage eindeutig liest.
|
|
--
|
|
-- Jede lesende Abfrage auf entries braucht ab jetzt diese Bedingung. In Go
|
|
-- steht sie als Konstante (store.nichtImPapierkorb), damit sie sich leicht
|
|
-- finden lässt; ein Test prüft jeden lesenden Weg.
|
|
--
|
|
-- Der Bezeichner bleibt belegt, solange der Eintrag im Papierkorb liegt
|
|
-- (UNIQUE (project_id, slug) gilt weiter). Wer denselben Bezeichner neu
|
|
-- schreibt, holt den Eintrag zurück und überschreibt ihn — der Stand aus dem
|
|
-- Papierkorb wandert dabei in den Verlauf (siehe PutEntry).
|
|
ALTER TABLE entries ADD COLUMN deleted_at TEXT;
|
|
ALTER TABLE entries ADD COLUMN deleted_by TEXT NOT NULL DEFAULT '';
|
|
|
|
-- Ein Teilindex nur über die Einträge im Papierkorb. Er bleibt winzig, denn
|
|
-- dort liegt fast nie etwas, und bedient die drei Fragen, die nur den
|
|
-- Papierkorb betreffen: "was liegt im Papierkorb dieses Projekts" (Seite),
|
|
-- "was ist älter als die Frist" (tägliches Aufräumen) und "welche
|
|
-- Schlagworte gehören zu gelöschten Einträgen" (ListTags).
|
|
--
|
|
-- Teilindizes (CREATE INDEX … WHERE …) kennt PostgreSQL genauso — der Weg
|
|
-- dorthin bleibt offen.
|
|
CREATE INDEX idx_entries_trash ON entries (project_id, deleted_at) WHERE deleted_at IS NOT NULL;
|