Skip to content

Commit

Permalink
Merge pull request #19 from snamiki1212/refactor/query-builder
Browse files Browse the repository at this point in the history
refactor: add query builder for by/with name on tag
  • Loading branch information
snamiki1212 committed Jun 10, 2023
2 parents 4536446 + 5f38493 commit ca18a94
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 99 deletions.
86 changes: 50 additions & 36 deletions src/app/article/model.rs
@@ -1,8 +1,10 @@
use crate::app::favorite::model::Favorite;
use crate::app::user::model::User;
use crate::error::AppError;
use crate::schema::articles;
use crate::utils::converter;
use chrono::NaiveDateTime;
use diesel::dsl::Eq;
use diesel::pg::PgConnection;
use diesel::prelude::*;
use diesel::Insertable;
Expand All @@ -23,6 +25,24 @@ pub struct Article {
pub updated_at: NaiveDateTime,
}

type WithAuthorId<T> = Eq<articles::author_id, T>;
type WithSlug<T> = Eq<articles::slug, T>;
type WithId<T> = Eq<articles::id, T>;

impl Article {
fn with_author_id(author_id: &Uuid) -> WithAuthorId<&Uuid> {
articles::author_id.eq(author_id)
}

fn with_slug(slug: &str) -> WithSlug<&str> {
articles::slug.eq(slug)
}

fn with_id(id: &Uuid) -> WithId<&Uuid> {
articles::id.eq(id)
}
}

impl Article {
pub fn create(conn: &mut PgConnection, record: &CreateArticle) -> Result<Self, AppError> {
let article = diesel::insert_into(articles::table)
Expand All @@ -38,13 +58,10 @@ impl Article {
author_id: &Uuid,
record: &UpdateArticle,
) -> Result<Self, AppError> {
let article = diesel::update(
articles::table
.filter(articles::slug.eq(article_title_slug))
.filter(articles::author_id.eq_all(author_id)),
)
.set(record)
.get_result::<Article>(conn)?;
let t = articles::table
.filter(Self::with_slug(article_title_slug))
.filter(Self::with_author_id(author_id));
let article = diesel::update(t).set(record).get_result::<Article>(conn)?;
Ok(article)
}

Expand All @@ -56,10 +73,10 @@ impl Article {
conn: &mut PgConnection,
params: &FetchBySlugAndAuthorId,
) -> Result<Self, AppError> {
let item = articles::table
.filter(articles::slug.eq_all(params.slug.to_owned()))
.filter(articles::author_id.eq_all(params.author_id))
.first::<Self>(conn)?;
let t = articles::table
.filter(Self::with_slug(&params.slug))
.filter(Self::with_author_id(&params.author_id));
let item = t.first::<Self>(conn)?;
Ok(item)
}

Expand All @@ -68,10 +85,10 @@ impl Article {
slug: &str,
) -> Result<(Self, User), AppError> {
use crate::schema::users;
let result = articles::table
let t = articles::table
.inner_join(users::table)
.filter(articles::slug.eq(slug))
.get_result::<(Self, User)>(conn)?;
.filter(Self::with_slug(slug));
let result = t.get_result::<(Self, User)>(conn)?;
Ok(result)
}

Expand All @@ -80,30 +97,28 @@ impl Article {
name: &str,
) -> Result<Vec<Uuid>, AppError> {
use crate::schema::users;
let ids = users::table
let t = users::table
.inner_join(articles::table)
.filter(users::username.eq(name))
.select(articles::id)
.load::<Uuid>(conn)?;
.filter(User::with_username(name))
.select(articles::id);
let ids = t.load::<Uuid>(conn)?;
Ok(ids)
}

pub fn find_with_author(conn: &mut PgConnection, id: &Uuid) -> Result<(Self, User), AppError> {
use crate::schema::users;
let result = articles::table
let t = articles::table
.inner_join(users::table)
.filter(articles::id.eq(id))
.get_result::<(Article, User)>(conn)?;
.filter(Self::with_id(id));
let result = t.get_result::<(Article, User)>(conn)?;
Ok(result)
}

pub fn delete(conn: &mut PgConnection, params: &DeleteArticle) -> Result<(), AppError> {
diesel::delete(
articles::table
.filter(articles::slug.eq(&params.slug))
.filter(articles::author_id.eq(params.author_id)),
)
.execute(conn)?;
let t = articles::table
.filter(Self::with_slug(&params.slug))
.filter(Self::with_author_id(&params.author_id));
diesel::delete(t).execute(conn)?;
// NOTE: references tag rows are deleted automatically by DELETE CASCADE

Ok(())
Expand All @@ -117,21 +132,20 @@ impl Article {
user_id: &Uuid,
) -> Result<bool, AppError> {
use crate::schema::favorites;
let count = favorites::table
let t = favorites::table
.select(diesel::dsl::count(favorites::id))
.filter(favorites::article_id.eq_all(self.id))
.filter(favorites::user_id.eq_all(user_id))
.first::<i64>(conn)?;

.filter(Favorite::with_article_id(&self.id))
.filter(Favorite::with_user_id(user_id));
let count = t.first::<i64>(conn)?;
Ok(count >= 1)
}

pub fn fetch_favorites_count(&self, conn: &mut PgConnection) -> Result<i64, AppError> {
use crate::schema::favorites;
let favorites_count = favorites::table
.filter(favorites::article_id.eq_all(self.id))
.select(diesel::dsl::count(favorites::created_at))
.first::<i64>(conn)?;
let t = favorites::table
.filter(Favorite::with_article_id(&self.id))
.select(diesel::dsl::count(favorites::created_at));
let favorites_count = t.first::<i64>(conn)?;
Ok(favorites_count)
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/app/article/service.rs
Expand Up @@ -90,7 +90,7 @@ pub fn fetch_articles_list(
let mut query = articles::table.inner_join(users::table).into_boxed();

if let Some(tag_name) = &params.tag {
let ids = Tag::fetch_ids_by_name(conn, tag_name)
let ids = Tag::fetch_article_ids_by_name(conn, tag_name)
.expect("could not fetch tagged article ids."); // TODO: use ? or error handling
query = query.filter(articles::id.eq_any(ids));
}
Expand Down Expand Up @@ -119,7 +119,7 @@ pub fn fetch_articles_list(
let mut query = articles::table.inner_join(users::table).into_boxed();

if let Some(tag_name) = &params.tag {
let ids = Tag::fetch_ids_by_name(conn, tag_name)
let ids = Tag::fetch_article_ids_by_name(conn, tag_name)
.expect("could not fetch tagged article ids."); // TODO: use ? or error handling
query = query.filter(articles::id.eq_any(ids));
}
Expand Down Expand Up @@ -291,7 +291,7 @@ pub fn fetch_following_articles(
.collect::<Vec<_>>();

let list = follows::table
.filter(follows::follower_id.eq(params.current_user.id))
.filter(Follow::with_follower(&params.current_user.id))
.filter(follows::followee_id.eq_any(user_ids_list))
.get_results::<Follow>(conn)?;

Expand Down Expand Up @@ -371,7 +371,7 @@ pub fn update_article(
},
)?;

let tag_list = Tag::fetch_by_article_id(conn, article.id)?;
let tag_list = Tag::fetch_by_article_id(conn, &article.id)?;

let profile = params
.current_user
Expand Down
27 changes: 22 additions & 5 deletions src/app/comment/model.rs
Expand Up @@ -3,6 +3,7 @@ use crate::app::user::model::User;
use crate::error::AppError;
use crate::schema::comments;
use chrono::NaiveDateTime;
use diesel::dsl::Eq;
use diesel::pg::PgConnection;
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
Expand All @@ -21,6 +22,22 @@ pub struct Comment {
pub updated_at: NaiveDateTime,
}

type WithId<T> = Eq<comments::id, T>;
type WithAuthor<T> = Eq<comments::author_id, T>;
type WithArticle<T> = Eq<comments::article_id, T>;

impl Comment {
fn with_id(id: &Uuid) -> WithId<&Uuid> {
comments::id.eq(id)
}
fn with_author(author_id: &Uuid) -> WithAuthor<&Uuid> {
comments::author_id.eq(author_id)
}
fn with_article(article_id: &Uuid) -> WithArticle<&Uuid> {
comments::article_id.eq(article_id)
}
}

impl Comment {
pub fn create(conn: &mut PgConnection, record: &CreateComment) -> Result<Self, AppError> {
let new_comment = diesel::insert_into(comments::table)
Expand All @@ -30,11 +47,11 @@ impl Comment {
}

pub fn delete(conn: &mut PgConnection, params: &DeleteComment) -> Result<(), AppError> {
diesel::delete(comments::table)
.filter(comments::id.eq(params.comment_id))
.filter(comments::author_id.eq(params.author_id))
.filter(comments::article_id.eq(params.article_id))
.execute(conn)?;
let t = comments::table
.filter(Self::with_id(&params.comment_id))
.filter(Self::with_author(&params.author_id))
.filter(Self::with_article(&params.article_id));
diesel::delete(t).execute(conn)?;
Ok(())
}
}
Expand Down
30 changes: 22 additions & 8 deletions src/app/favorite/model.rs
Expand Up @@ -3,6 +3,7 @@ use crate::app::user::model::User;
use crate::error::AppError;
use crate::schema::favorites;
use chrono::NaiveDateTime;
use diesel::dsl::Eq;
use diesel::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
Expand All @@ -19,6 +20,19 @@ pub struct Favorite {
pub updated_at: NaiveDateTime,
}

type WithUserId<T> = Eq<favorites::user_id, T>;
type WithArticleId<T> = Eq<favorites::article_id, T>;

impl Favorite {
pub fn with_user_id(user_id: &Uuid) -> WithUserId<&Uuid> {
favorites::user_id.eq_all(user_id)
}

pub fn with_article_id(article_id: &Uuid) -> WithArticleId<&Uuid> {
favorites::article_id.eq_all(article_id)
}
}

impl Favorite {
pub fn create(conn: &mut PgConnection, record: &CreateFavorite) -> Result<usize, AppError> {
let item = diesel::insert_into(favorites::table)
Expand All @@ -34,10 +48,10 @@ impl Favorite {
article_id,
}: &DeleteFavorite,
) -> Result<usize, AppError> {
let item = diesel::delete(favorites::table)
.filter(favorites::user_id.eq_all(user_id))
.filter(favorites::article_id.eq_all(article_id))
.execute(conn)?;
let t = favorites::table
.filter(Self::with_user_id(user_id))
.filter(Self::with_article_id(article_id));
let item = diesel::delete(t).execute(conn)?;
Ok(item)
}

Expand All @@ -46,11 +60,11 @@ impl Favorite {
username: &str,
) -> Result<Vec<Uuid>, AppError> {
use crate::schema::users;
let ids = favorites::table
let t = favorites::table
.inner_join(users::table)
.filter(users::username.eq(username))
.select(favorites::article_id)
.load::<Uuid>(conn)?;
.filter(User::with_username(username))
.select(favorites::article_id);
let ids = t.load::<Uuid>(conn)?;
Ok(ids)
}
}
Expand Down
32 changes: 22 additions & 10 deletions src/app/follow/model.rs
Expand Up @@ -2,6 +2,7 @@ use crate::app::user::model::User;
use crate::error::AppError;
use crate::schema::follows;
use chrono::NaiveDateTime;
use diesel::dsl::Eq;
use diesel::pg::PgConnection;
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
Expand All @@ -17,6 +18,19 @@ pub struct Follow {
pub updated_at: NaiveDateTime,
}

type WithFollowee<T> = Eq<follows::followee_id, T>;
type WithFollower<T> = Eq<follows::follower_id, T>;

impl Follow {
pub fn with_followee(followee_id: &Uuid) -> WithFollowee<&Uuid> {
follows::followee_id.eq(followee_id)
}

pub fn with_follower(follower_id: &Uuid) -> WithFollower<&Uuid> {
follows::follower_id.eq(follower_id)
}
}

impl Follow {
pub fn create(conn: &mut PgConnection, params: &CreateFollow) -> Result<(), AppError> {
diesel::insert_into(follows::table)
Expand All @@ -26,23 +40,21 @@ impl Follow {
}

pub fn delete(conn: &mut PgConnection, params: &DeleteFollow) -> Result<(), AppError> {
diesel::delete(
follows::table
.filter(follows::followee_id.eq(params.followee_id))
.filter(follows::follower_id.eq(params.follower_id)),
)
.execute(conn)?;
let t = follows::table
.filter(Follow::with_followee(&params.followee_id))
.filter(Follow::with_follower(&params.follower_id));
diesel::delete(t).execute(conn)?;
Ok(())
}

pub fn fetch_folowee_ids_by_follower_id(
conn: &mut PgConnection,
follower_id: &Uuid,
) -> Result<Vec<Uuid>, AppError> {
let result = follows::table
.filter(follows::follower_id.eq(follower_id))
.select(follows::followee_id)
.get_results::<Uuid>(conn)?;
let t = follows::table
.filter(Follow::with_follower(follower_id))
.select(follows::followee_id);
let result = t.get_results::<Uuid>(conn)?;
Ok(result)
}
}
Expand Down

0 comments on commit ca18a94

Please sign in to comment.