diff --git a/migrations/2021-09-13-143540_sections/down.sql b/migrations/2021-09-13-143540_sections/down.sql new file mode 100644 index 0000000..7af43ff --- /dev/null +++ b/migrations/2021-09-13-143540_sections/down.sql @@ -0,0 +1,7 @@ +-- This file should undo anything in `up.sql` +drop trigger insert_enforce_post_titles on posts; +drop trigger update_enforce_post_titles on posts; +drop function enforce_post_titles; + +drop table posts cascade; +drop table sections cascade; diff --git a/migrations/2021-09-13-143540_sections/up.sql b/migrations/2021-09-13-143540_sections/up.sql new file mode 100644 index 0000000..0c5ca76 --- /dev/null +++ b/migrations/2021-09-13-143540_sections/up.sql @@ -0,0 +1,56 @@ +-- Your SQL goes here +create table sections ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + + -- Title of the section + title varchar(255) 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 + has_titles boolean NOT NULL DEFAULT true +); + +create table posts ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + + section_id uuid NOT NULL REFERENCES sections(id) ON DELETE CASCADE, + -- Title of the post + -- Wether this is NULL or not is enforced using the enforce_post_titles trigger + title varchar(255), + -- Post date, defaults to today + publish_date date NOT NULL DEFAULT now(), + -- Content of the post + content text NOT NULL +); + +create function enforce_post_titles() returns trigger as $enforce_post_titles$ + begin + -- Check for a wrongfully null title + if new.title is null and exists ( + select 1 from sections where id = new.section_id and has_titles + ) then + raise exception 'Expected a post title, but got null.'; + end if; + + if new.title is not null and exists ( + select 1 from sections where id = new.section_id and not has_titles + ) then + raise exception 'Expected an empty post title, but got a value.'; + end if; + + return new; + end; +$enforce_post_titles$ language plpgsql; + +create trigger insert_enforce_post_titles + before insert on posts + for each row + execute function enforce_post_titles(); + +create trigger update_enforce_post_titles + before update of title on posts + for each row + when (old.title is distinct from new.title) + execute function enforce_post_titles(); diff --git a/src/schema.rs b/src/schema.rs index e3854e3..a38f572 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,3 +1,13 @@ +table! { + posts (id) { + id -> Uuid, + section_id -> Uuid, + title -> Nullable, + publish_date -> Date, + content -> Text, + } +} + table! { refresh_tokens (token) { token -> Bytea, @@ -7,6 +17,16 @@ table! { } } +table! { + sections (id) { + id -> Uuid, + title -> Varchar, + description -> Nullable, + is_default -> Bool, + has_titles -> Bool, + } +} + table! { users (id) { id -> Uuid, @@ -17,6 +37,12 @@ table! { } } +joinable!(posts -> sections (section_id)); joinable!(refresh_tokens -> users (user_id)); -allow_tables_to_appear_in_same_query!(refresh_tokens, users,); +allow_tables_to_appear_in_same_query!( + posts, + refresh_tokens, + sections, + users, +);