2021-11-23 09:32:08 +01:00
|
|
|
create table sections (
|
|
|
|
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
|
|
|
|
|
|
-- Title of the section
|
|
|
|
title varchar(255) UNIQUE NOT NULL,
|
|
|
|
-- Name to use when routing (this just makes for prettier URLs)
|
|
|
|
shortname varchar(32) UNIQUE NOT NULL,
|
|
|
|
-- Optional description of the section
|
|
|
|
description text,
|
|
|
|
-- Wether to show the section in the default list on the homepage
|
|
|
|
is_default boolean NOT NULL DEFAULT false,
|
|
|
|
-- Wether the posts should contain titles or not
|
2021-12-23 16:28:43 +01:00
|
|
|
has_titles boolean NOT NULL DEFAULT true,
|
|
|
|
-- Wether posts in this section should be shown publicly
|
|
|
|
is_private boolean NOT NULL DEFAULT false
|
2021-11-23 09:32:08 +01:00
|
|
|
);
|
|
|
|
|
2021-12-25 10:42:36 +01:00
|
|
|
create index sections_shortname_index on sections(shortname);
|
|
|
|
|
2021-11-23 09:32:08 +01:00
|
|
|
create table posts (
|
|
|
|
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
|
|
|
2021-12-23 16:28:43 +01:00
|
|
|
-- Posts shouldn't get deleted when we delete a section, as they're the
|
|
|
|
-- most valuable part of a blog
|
|
|
|
section_id uuid NOT NULL REFERENCES sections(id) ON DELETE SET NULL,
|
|
|
|
|
|
|
|
-- Wether a post should be private
|
|
|
|
is_private boolean NOT NULL DEFAULT false,
|
|
|
|
-- Wether the post is archived
|
|
|
|
is_archived boolean NOT NULL DEFAULT false
|
|
|
|
);
|
|
|
|
|
|
|
|
create table versions (
|
|
|
|
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
|
|
|
|
|
|
-- A version should be deleted when its referenced post is deleted
|
|
|
|
post_id uuid NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
|
|
|
|
|
|
|
|
-- Title of the post. Wether this is NULL or not is enforced using the
|
|
|
|
-- enforce_post_titles trigger.
|
2021-11-23 09:32:08 +01:00
|
|
|
title varchar(255),
|
2021-12-23 16:28:43 +01:00
|
|
|
-- Publish date
|
|
|
|
publish_date date,
|
|
|
|
-- Content of the post, in Markdown
|
|
|
|
content text NOT NULL DEFAULT '',
|
|
|
|
-- Wether the version is still a draft
|
|
|
|
is_draft boolean NOT NULL default true,
|
|
|
|
|
|
|
|
-- This check allows draft posts to be created without having to enter a
|
|
|
|
-- publish date, but forces them to have one if they're not a draft.
|
2021-12-23 23:28:26 +01:00
|
|
|
CONSTRAINT no_null_published_date CHECK (is_draft OR publish_date IS NOT NULL)
|
|
|
|
);
|
|
|
|
|
|
|
|
create table tags (
|
|
|
|
post_id uuid NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
|
|
|
|
value varchar(64) NOT NULL,
|
|
|
|
|
|
|
|
PRIMARY KEY (post_id, value)
|
2021-11-23 09:32:08 +01:00
|
|
|
);
|
|
|
|
|
2021-12-23 16:28:43 +01:00
|
|
|
create function enforce_version_titles() returns trigger as $$
|
2021-11-23 09:32:08 +01:00
|
|
|
begin
|
2021-12-23 16:28:43 +01:00
|
|
|
-- Draft versions shouldn't be evaluated.
|
|
|
|
if new.is_draft then
|
|
|
|
return new;
|
|
|
|
end if;
|
|
|
|
|
2021-11-23 09:32:08 +01:00
|
|
|
-- Check for a wrongfully null title
|
|
|
|
if new.title is null and exists (
|
2021-12-23 16:28:43 +01:00
|
|
|
select 1 from posts
|
|
|
|
inner join sections on posts.section_id = sections.id
|
|
|
|
where posts.id = new.post_id and sections.has_titles
|
2021-11-23 09:32:08 +01:00
|
|
|
) then
|
|
|
|
raise exception 'Expected a post title, but got null.';
|
|
|
|
end if;
|
|
|
|
|
|
|
|
if new.title is not null and exists (
|
2021-12-23 16:28:43 +01:00
|
|
|
select 1 from posts
|
|
|
|
inner join sections on posts.section_id = sections.id
|
|
|
|
where posts.id = new.post_id and not sections.has_titles
|
2021-11-23 09:32:08 +01:00
|
|
|
) then
|
|
|
|
raise exception 'Expected an empty post title, but got a value.';
|
|
|
|
end if;
|
|
|
|
|
|
|
|
return new;
|
|
|
|
end;
|
2021-12-23 16:28:43 +01:00
|
|
|
$$ language plpgsql;
|
2021-11-23 09:32:08 +01:00
|
|
|
|
2021-12-23 16:28:43 +01:00
|
|
|
create trigger insert_enforce_version_titles
|
|
|
|
before insert on versions
|
2021-11-23 09:32:08 +01:00
|
|
|
for each row
|
2021-12-23 16:28:43 +01:00
|
|
|
execute function enforce_version_titles();
|
2021-11-23 09:32:08 +01:00
|
|
|
|
2021-12-23 16:28:43 +01:00
|
|
|
create trigger update_enforce_version_titles
|
|
|
|
before update of title on versions
|
2021-11-23 09:32:08 +01:00
|
|
|
for each row
|
|
|
|
when (old.title is distinct from new.title)
|
2021-12-23 16:28:43 +01:00
|
|
|
execute function enforce_version_titles();
|