This repository has been archived on 2023-07-04. You can view files and clone it, but cannot push or open issues/pull-requests.
blog/src/db/posts.rs

89 lines
2.5 KiB
Rust

use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable};
use rb::errors::{RbError, RbOption, RbResult};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::schema::{posts, posts::dsl::*};
/// A post inside the database.
#[derive(Queryable, Serialize)]
pub struct Post
{
pub id: Uuid,
pub section_id: Uuid,
pub is_private: bool,
pub is_archived: bool,
}
/// A new post to be added to the database.
#[derive(Deserialize, Insertable)]
#[table_name = "posts"]
#[serde(rename_all = "camelCase")]
pub struct NewPost
{
pub section_id: Uuid,
pub is_private: Option<bool>,
pub is_archived: Option<bool>,
}
/// A patch to be applied to a row in the database.
#[derive(Deserialize, AsChangeset)]
#[table_name = "posts"]
pub struct PatchPost
{
pub section_id: Option<Uuid>,
pub is_private: Option<bool>,
pub is_archived: Option<bool>,
}
/// Get a list of posts, specified by the offset & a limit. The maximum for `limit_` is determined
/// by `super::MAX_POSTS`.
pub fn get(conn: &PgConnection, offset_: u32, limit_: u32) -> RbResult<Vec<Post>>
{
Ok(posts
.offset(offset_.into())
.limit(std::cmp::min(limit_, super::MAX_POSTS).into())
.load(conn)
.map_err(|_| RbError::DbError("Couldn't query posts."))?)
}
/// Try to find a post given its id (primary key).
pub fn find(conn: &PgConnection, id_: &Uuid) -> RbOption<Post>
{
match posts.find(id_).first(conn) {
Ok(val) => Ok(Some(val)),
Err(diesel::NotFound) => Ok(None),
_ => Err(RbError::DbError("Couldn't find post.")),
}
}
/// Create a new post & store it in the database.
pub fn create(conn: &PgConnection, new_post: &NewPost) -> RbResult<Post>
{
Ok(insert_into(posts)
.values(new_post)
.get_result(conn)
.map_err(|_| RbError::DbError("Couldn't insert post."))?)
// TODO check for conflict?
}
/// Update a post in the database with a given ID, returning the updated row.
pub fn update(conn: &PgConnection, post_id: &Uuid, patch_post: &PatchPost) -> RbResult<Post>
{
Ok(diesel::update(posts.filter(id.eq(post_id)))
.set(patch_post)
.get_result(conn)
.map_err(|_| RbError::DbError("Couldn't update post."))?)
}
/// Delete a post with a given ID.
pub fn delete(conn: &PgConnection, post_id: &Uuid) -> RbResult<()>
{
diesel::delete(posts.filter(id.eq(post_id)))
.execute(conn)
.map_err(|_| RbError::DbError("Couldn't delete post."))?;
Ok(())
}