Files
probably-rendering-one-more…/apps/dashboard/db/004_flat_notes.sql
T

49 lines
3.4 KiB
PL/PgSQL

BEGIN;
-- Preserve references before removing the old screenshot catalogue.
INSERT INTO post_assets(post_id,asset_id,position,role)
SELECT ps.post_id,ps.asset_id,
COALESCE((SELECT max(pa.position)+1 FROM post_assets pa WHERE pa.post_id=ps.post_id),0)
+row_number() OVER(PARTITION BY ps.post_id ORDER BY ps.page_index)::integer-1,'content'
FROM page_snapshots ps WHERE NOT EXISTS(SELECT 1 FROM post_assets pa WHERE pa.post_id=ps.post_id AND pa.asset_id=ps.asset_id);
DROP TABLE render_jobs;
DROP TABLE page_snapshots;
ALTER TABLE posts DROP COLUMN page_key;
-- Every processed file is an ordinary asset, retaining its original storage key.
ALTER TABLE assets ADD COLUMN source_asset_id uuid REFERENCES assets(id) ON DELETE RESTRICT;
ALTER TABLE assets ADD COLUMN derivation text CHECK(derivation IN ('silent_video','audio_track','poster'));
ALTER TABLE assets ADD CONSTRAINT assets_derivation_source CHECK((source_asset_id IS NULL)=(derivation IS NULL));
CREATE UNIQUE INDEX assets_source_derivation ON assets(source_asset_id,derivation) WHERE source_asset_id IS NOT NULL;
INSERT INTO assets(id,kind,filename,storage_key,mime_type,byte_size,source_asset_id,derivation)
SELECT md5(v.storage_key)::uuid,CASE v.role WHEN 'poster' THEN 'image' WHEN 'audio_track' THEN 'audio' ELSE 'video' END,
v.role,v.storage_key,v.mime_type,v.byte_size,v.asset_id,v.role FROM asset_variants v WHERE true
ON CONFLICT(storage_key) DO UPDATE SET source_asset_id=excluded.source_asset_id,derivation=excluded.derivation;
ALTER TABLE post_assets DROP CONSTRAINT post_assets_role_check;
ALTER TABLE post_assets ADD CONSTRAINT post_assets_role_check CHECK(role IN ('content','caption','silent_video','audio_track','poster'));
INSERT INTO post_assets(post_id,asset_id,position,role)
SELECT sources.post_id,a.id,
COALESCE((SELECT max(pa.position)+1 FROM post_assets pa WHERE pa.post_id=sources.post_id),0)
+row_number() OVER(PARTITION BY sources.post_id ORDER BY a.id)::integer-1,a.derivation
FROM (SELECT DISTINCT post_id,asset_id FROM post_assets WHERE role='content') sources
JOIN assets a ON a.source_asset_id=sources.asset_id
WHERE NOT EXISTS(SELECT 1 FROM post_assets pa WHERE pa.post_id=sources.post_id AND pa.asset_id=a.id);
DROP TABLE asset_variants;
-- Flatten tags, merging equal names without losing either kind of association.
DROP TRIGGER tags_no_cycles ON tags;
DROP FUNCTION prevent_tag_cycle();
CREATE TEMP TABLE tag_slugs ON COMMIT DROP AS SELECT id,slug,row_number() OVER(PARTITION BY slug ORDER BY id) AS rank FROM tags;
UPDATE tags SET slug='tag-'||replace(id::text,'-','');
UPDATE tags SET parent_id=NULL;
CREATE TEMP TABLE tag_merge ON COMMIT DROP AS
SELECT id,first_value(id) OVER(PARTITION BY lower(btrim(name)) ORDER BY id) AS keep_id FROM tags;
INSERT INTO post_tags(post_id,tag_id) SELECT pt.post_id,m.keep_id FROM post_tags pt JOIN tag_merge m ON m.id=pt.tag_id WHERE true ON CONFLICT DO NOTHING;
INSERT INTO asset_tags(asset_id,tag_id) SELECT at.asset_id,m.keep_id FROM asset_tags at JOIN tag_merge m ON m.id=at.tag_id WHERE true ON CONFLICT DO NOTHING;
DELETE FROM tags t USING tag_merge m WHERE t.id=m.id AND m.id<>m.keep_id;
ALTER TABLE tags DROP COLUMN parent_id;
UPDATE tags t SET slug=CASE WHEN s.rank=1 THEN s.slug ELSE 'tag-'||replace(t.id::text,'-','') END FROM tag_slugs s WHERE s.id=t.id;
CREATE UNIQUE INDEX tags_slug_unique ON tags(slug);
CREATE UNIQUE INDEX tags_name_unique ON tags(lower(btrim(name)));
INSERT INTO schema_migrations(version) VALUES('004_flat_notes');
COMMIT;