-- Migration 001: Revisionshistorie fuer Items -- -- Fuer bestehende Installationen. Bei einer Neuinstallation deckt schema.sql -- das bereits ab; diese Datei ist dann ein No-op. -- -- psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f migrations/001-revisionen.sql begin; alter table raw_items add column if not exists inhalt_hash text, add column if not exists revisionen integer not null default 0, add column if not exists zuletzt_geaendert timestamptz; -- Bestandsdaten nachziehen. Die Formel muss zeichengleich zu -- poller.inhalt_hash() sein, sonst gilt beim naechsten Lauf jedes Altitem -- als geaendert. Trennzeichen ist U+001F (unit separator). update raw_items set inhalt_hash = md5(coalesce(titel, '') || E'\x1f' || coalesce(teaser, '') || E'\x1f' || coalesce(url, '')) where inhalt_hash is null; alter table raw_items alter column inhalt_hash set not null; create index if not exists raw_items_revidiert_idx on raw_items (zuletzt_geaendert desc) where revisionen > 0; create table if not exists raw_item_versionen ( id bigserial primary key, raw_item_id bigint not null references raw_items(id) on delete cascade, gesehen_am timestamptz not null default now(), slot timestamptz not null, titel text not null, teaser text, url text, inhalt_hash text not null, unique (raw_item_id, inhalt_hash) ); create index if not exists raw_item_versionen_item_idx on raw_item_versionen (raw_item_id, gesehen_am); -- Erstfassung der Bestandsitems eintragen, damit die Historie vollstaendig ist. -- gesehen_am auf abgerufen_am setzen, nicht auf now(): die Fassung ist alt. insert into raw_item_versionen (raw_item_id, gesehen_am, slot, titel, teaser, url, inhalt_hash) select id, abgerufen_am, slot, titel, teaser, url, inhalt_hash from raw_items on conflict (raw_item_id, inhalt_hash) do nothing; alter table poll_laeufe add column if not exists items_geaendert integer not null default 0; drop view if exists titel_revisionen; create view titel_revisionen as select r.id, r.quelle, r.url, r.revisionen, count(*) as fassungen, (array_agg(v.titel order by v.gesehen_am))[1] as erste_fassung, (array_agg(v.titel order by v.gesehen_am desc))[1] as letzte_fassung, min(v.gesehen_am) as erstmals, max(v.gesehen_am) as zuletzt from raw_items r join raw_item_versionen v on v.raw_item_id = r.id where r.revisionen > 0 group by r.id, r.quelle, r.url, r.revisionen; create or replace view quellen_stillstand as select q.id, q.name, max(r.abgerufen_am) as letztes_item, now() - max(r.abgerufen_am) as stille from quellen q left join raw_items r on r.quelle = q.id where q.aktiv group by q.id, q.name having max(r.abgerufen_am) is null or now() - max(r.abgerufen_am) > interval '6 hours' order by stille desc nulls first; commit;