use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use rb::errors::{RbError, RbOption, RbResult}; use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::schema::{sections, sections::dsl::*}; /// A section inside the database. #[derive(Queryable, Serialize)] pub struct Section { pub id: Uuid, pub title: String, pub shortname: String, pub description: Option, pub is_default: bool, pub has_titles: bool, } /// A new section to add. Any `Option` values will get replaced by their default value in the /// database. #[derive(Serialize, Deserialize, Insertable)] #[table_name = "sections"] #[serde(rename_all = "camelCase")] pub struct NewSection { pub title: String, pub shortname: String, pub description: Option, pub is_default: Option, pub has_titles: Option, } /// A patch to apply to a section. #[derive(Deserialize, AsChangeset)] #[table_name = "sections"] #[serde(rename_all = "camelCase")] pub struct PatchSection { title: Option, shortname: Option, description: Option, is_default: Option, has_titles: Option, } /// Get an amount of sections from the database, given an offset & limit. The maximum value for /// `limit_` is determined by `super::MAX_SECTIONS`. pub fn get(conn: &PgConnection, offset_: u32, limit_: u32) -> RbResult> { Ok(sections .offset(offset_.into()) .limit(std::cmp::min(limit_, super::MAX_SECTIONS).into()) .load(conn) .map_err(|_| RbError::DbError("Couldn't query sections."))?) } /// Try to find a section given its shortname. pub fn find_with_shortname(conn: &PgConnection, shortname_: &str) -> RbOption
{ match sections.filter(shortname.eq(shortname_)).first(conn) { Ok(val) => Ok(Some(val)), Err(diesel::NotFound) => Ok(None), _ => Err(RbError::DbError("Couldn't find section.")), } } /// Create a new section. pub fn create(conn: &PgConnection, new_section: &NewSection) -> RbResult
{ Ok(insert_into(sections) .values(new_section) .get_result(conn) .map_err(|_| RbError::DbError("Couldn't insert section."))?) // TODO check for conflict? } /// Update a section given its ID. pub fn update(conn: &PgConnection, post_id: &Uuid, patch_post: &PatchSection) -> RbResult
{ Ok(diesel::update(sections.filter(id.eq(post_id))) .set(patch_post) .get_result(conn) .map_err(|_| RbError::DbError("Couldn't update section."))?) } // Update a section given its shortname. pub fn update_with_shortname( conn: &PgConnection, shortname_: &str, patch_section: &PatchSection, ) -> RbResult
{ Ok(diesel::update(sections.filter(shortname.eq(shortname_))) .set(patch_section) .get_result(conn) .map_err(|_| RbError::DbError("Couldn't update section with shortname."))?) } /// Delete a section given its ID. pub fn delete(conn: &PgConnection, post_id: &Uuid) -> RbResult<()> { diesel::delete(sections.filter(id.eq(post_id))) .execute(conn) .map_err(|_| RbError::DbError("Couldn't delete section."))?; Ok(()) }