diff --git a/migrations/2021-09-13-143540_sections/down.sql b/migrations/2021-09-13-143540_sections/down.sql index bd985fd..c3b5ba5 100644 --- a/migrations/2021-09-13-143540_sections/down.sql +++ b/migrations/2021-09-13-143540_sections/down.sql @@ -2,7 +2,9 @@ drop trigger insert_enforce_version_titles on versions; drop trigger update_enforce_version_titles on versions; drop function enforce_version_titles; +drop index sections_shortname_index; drop table versions cascade; +drop table tags cascade; 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 index 93a9196..ca30c71 100644 --- a/migrations/2021-09-13-143540_sections/up.sql +++ b/migrations/2021-09-13-143540_sections/up.sql @@ -6,17 +6,17 @@ create table sections ( -- Name to use when routing (this just makes for prettier URLs) shortname varchar(32) UNIQUE NOT NULL, -- Optional description of the section - description text NOT NULL DEFAULT '', + 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, -- Wether posts in this section should be shown publicly - is_private boolean NOT NULL DEFAULT false, - -- Wether the section is archived - is_archived boolean NOT NULL DEFAULT false + is_private boolean NOT NULL DEFAULT false ); +create index sections_shortname_index on sections(shortname); + create table posts ( id uuid DEFAULT gen_random_uuid() PRIMARY KEY, @@ -51,6 +51,13 @@ create table versions ( 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) +); + create function enforce_version_titles() returns trigger as $$ begin -- Draft versions shouldn't be evaluated. diff --git a/src/db/mod.rs b/src/db/mod.rs index 8831437..2ce2174 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -3,12 +3,9 @@ pub mod posts; pub mod sections; -pub mod versions; pub use posts::{NewPost, PatchPost, Post}; pub use sections::{NewSection, PatchSection, Section}; -pub use versions::{NewVersion, PatchVersion, Version}; pub const MAX_POSTS: u32 = 64; pub const MAX_SECTIONS: u32 = 64; -pub const MAX_VERSIONS: u32 = 16; diff --git a/src/db/posts.rs b/src/db/posts.rs index 3952425..e2d11d1 100644 --- a/src/db/posts.rs +++ b/src/db/posts.rs @@ -1,3 +1,4 @@ +use chrono::NaiveDate; use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use rb::errors::{RbError, RbOption, RbResult}; use serde::{Deserialize, Serialize}; @@ -11,8 +12,9 @@ pub struct Post { pub id: Uuid, pub section_id: Uuid, - pub is_private: bool, - pub is_archived: bool, + pub title: Option, + pub publish_date: NaiveDate, + pub content: String, } /// A new post to be added to the database. @@ -22,8 +24,9 @@ pub struct Post pub struct NewPost { pub section_id: Uuid, - pub is_private: Option, - pub is_archived: Option, + pub title: Option, + pub publish_date: NaiveDate, + pub content: String, } /// A patch to be applied to a row in the database. @@ -32,8 +35,9 @@ pub struct NewPost pub struct PatchPost { pub section_id: Option, - pub is_private: Option, - pub is_archived: Option, + pub title: Option, + pub publish_date: Option, + pub content: Option, } /// Get a list of posts, specified by the offset & a limit. The maximum for `limit_` is determined diff --git a/src/db/sections.rs b/src/db/sections.rs index e78ea65..c68b0a4 100644 --- a/src/db/sections.rs +++ b/src/db/sections.rs @@ -12,11 +12,9 @@ pub struct Section pub id: Uuid, pub title: String, pub shortname: String, - pub description: String, + pub description: Option, pub is_default: bool, pub has_titles: bool, - pub is_private: bool, - pub is_archived: bool, } /// A new section to add. Any `Option` values will get replaced by their default value in the @@ -31,8 +29,6 @@ pub struct NewSection pub description: Option, pub is_default: Option, pub has_titles: Option, - pub is_private: Option, - pub is_archived: Option, } /// A patch to apply to a section. @@ -46,8 +42,6 @@ pub struct PatchSection description: Option, is_default: Option, has_titles: Option, - pub is_private: Option, - pub is_archived: Option, } /// Get an amount of sections from the database, given an offset & limit. The maximum value for diff --git a/src/db/versions.rs b/src/db/versions.rs deleted file mode 100644 index ae7e020..0000000 --- a/src/db/versions.rs +++ /dev/null @@ -1,103 +0,0 @@ -use chrono::NaiveDate; -use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; -use rb::errors::{RbError, RbOption, RbResult}; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -use crate::schema::{versions, versions::dsl::*}; - -/// A version inside the database. -#[derive(Queryable, Serialize)] -pub struct Version -{ - pub id: Uuid, - pub post_id: Uuid, - pub title: Option, - pub publish_date: Option, - pub content: String, - pub is_draft: bool, -} - -#[derive(Deserialize, Insertable)] -#[table_name = "versions"] -#[serde(rename_all = "camelCase")] -pub struct NewVersion -{ - pub post_id: Uuid, - pub title: Option, - pub publish_date: Option, - pub content: Option, - pub is_draft: Option, -} - -#[derive(Deserialize, AsChangeset)] -#[table_name = "versions"] -pub struct PatchVersion -{ - pub id: Uuid, - pub post_id: Option, - pub title: Option, - pub publish_date: Option, - pub content: Option, - pub is_draft: Option, -} - -pub fn get(conn: &PgConnection, offset_: u32, limit_: u32) -> RbResult> -{ - Ok(versions - .offset(offset_.into()) - .limit(std::cmp::min(limit_, super::MAX_VERSIONS).into()) - .load(conn) - .map_err(|_| RbError::DbError("Couldn't query versions."))?) -} - -pub fn get_for_post( - conn: &PgConnection, - post_id_: &Uuid, - offset_: u32, - limit_: u32, -) -> RbResult> -{ - Ok(versions - .offset(offset_.into()) - .filter(post_id.eq(post_id_)) - .limit(std::cmp::min(limit_, super::MAX_VERSIONS).into()) - .load(conn) - .map_err(|_| RbError::DbError("Couldn't query versions."))?) -} - -pub fn find(conn: &PgConnection, id_: &Uuid) -> RbOption -{ - match versions.find(id_).first(conn) { - Ok(val) => Ok(Some(val)), - Err(diesel::NotFound) => Ok(None), - _ => Err(RbError::DbError("Couldn't find version.")), - } -} - -pub fn create(conn: &PgConnection, new: &NewVersion) -> RbResult -{ - Ok(insert_into(versions) - .values(new) - .get_result(conn) - .map_err(|_| RbError::DbError("Couldn't insert version."))?) - - // TODO check for conflict? -} - -pub fn update(conn: &PgConnection, id_: &Uuid, patch: &PatchVersion) -> RbResult -{ - Ok(diesel::update(versions.filter(id.eq(id_))) - .set(patch) - .get_result(conn) - .map_err(|_| RbError::DbError("Couldn't update version."))?) -} - -pub fn delete(conn: &PgConnection, id_: &Uuid) -> RbResult<()> -{ - diesel::delete(versions.filter(id.eq(id_))) - .execute(conn) - .map_err(|_| RbError::DbError("Couldn't delete version."))?; - - Ok(()) -} diff --git a/src/main.rs b/src/main.rs index 002115f..7ca6841 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,17 +95,6 @@ fn rocket() -> _ v1::posts::patch, v1::posts::delete ], - ) - .mount( - "/v1/versions", - routes![ - v1::versions::get, - v1::versions::get_for_post, - v1::versions::create, - v1::versions::find, - v1::versions::patch, - v1::versions::delete - ], ); let new_figment = rocket.figment(); diff --git a/src/schema.rs b/src/schema.rs index cadb6f0..b032c41 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -12,11 +12,17 @@ table! { id -> Uuid, title -> Varchar, shortname -> Varchar, - description -> Text, + description -> Nullable, is_default -> Bool, has_titles -> Bool, is_private -> Bool, - is_archived -> Bool, + } +} + +table! { + tags (post_id, value) { + post_id -> Uuid, + value -> Varchar, } } @@ -32,10 +38,12 @@ table! { } joinable!(posts -> sections (section_id)); +joinable!(tags -> posts (post_id)); joinable!(versions -> posts (post_id)); allow_tables_to_appear_in_same_query!( posts, sections, + tags, versions, ); diff --git a/src/v1/mod.rs b/src/v1/mod.rs index b5e6454..ac3e36c 100644 --- a/src/v1/mod.rs +++ b/src/v1/mod.rs @@ -1,3 +1,2 @@ pub mod posts; pub mod sections; -pub mod versions; diff --git a/src/v1/versions.rs b/src/v1/versions.rs deleted file mode 100644 index 449583f..0000000 --- a/src/v1/versions.rs +++ /dev/null @@ -1,74 +0,0 @@ -use rb::{ - errors::{RbOption, RbResult}, - guards::Admin, -}; -use rb_blog::db; -use rocket::serde::json::Json; -use uuid::Uuid; - -use crate::RbDbConn; - -#[get("/?&", rank = 1)] -pub async fn get(conn: RbDbConn, offset: u32, limit: u32) -> RbResult>> -{ - Ok(Json( - conn.run(move |c| db::versions::get(c, offset, limit)) - .await?, - )) -} - -#[get("/?&&", rank = 0)] -pub async fn get_for_post( - conn: RbDbConn, - post_id: Uuid, - offset: u32, - limit: u32, -) -> RbResult>> -{ - Ok(Json( - conn.run(move |c| db::versions::get_for_post(c, &post_id, offset, limit)) - .await?, - )) -} - -#[post("/", data = "")] -pub async fn create( - _admin: Admin, - conn: RbDbConn, - new: Json, -) -> RbResult> -{ - Ok(Json( - conn.run(move |c| db::versions::create(c, &new.into_inner())) - .await?, - )) -} - -#[get("/")] -pub async fn find(conn: RbDbConn, id: uuid::Uuid) -> RbOption> -{ - Ok(conn - .run(move |c| db::versions::find(c, &id)) - .await? - .and_then(|p| Some(Json(p)))) -} - -#[patch("/", data = "")] -pub async fn patch( - _admin: Admin, - conn: RbDbConn, - id: uuid::Uuid, - patch: Json, -) -> RbResult> -{ - Ok(Json( - conn.run(move |c| db::versions::update(c, &id, &patch.into_inner())) - .await?, - )) -} - -#[delete("/")] -pub async fn delete(_admin: Admin, conn: RbDbConn, id: uuid::Uuid) -> RbResult<()> -{ - Ok(conn.run(move |c| db::versions::delete(c, &id)).await?) -}