Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add query builder for by/with name on tag #19

Merged
merged 26 commits into from
Jun 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ba28ea9
refactor: add query builder for by/with name on tag
snamiki1212 Apr 26, 2023
43a5d56
refactor: add query-builder for article_id on tag
snamiki1212 Apr 26, 2023
99673fb
refactor: update use syntax
snamiki1212 Apr 26, 2023
4069e0d
revert: fix article-id query builder
snamiki1212 Apr 26, 2023
49f2a8c
tmp: try e2e test on ci
snamiki1212 Apr 28, 2023
7311c0a
tmp: try e2e test on ci
snamiki1212 Apr 28, 2023
616bbab
tmp: try e2e on ci
snamiki1212 Apr 28, 2023
65bf15d
tmp: try e2e test on ic
snamiki1212 Apr 28, 2023
2488607
Merge branch 'main' into refactor/query-builder
snamiki1212 Jun 1, 2023
f1c03c0
fix: add by_name on tag model
snamiki1212 Jun 9, 2023
15ab7aa
refactor: update fetcher
snamiki1212 Jun 9, 2023
8840b2d
fix: add article_id helpers
snamiki1212 Jun 10, 2023
85d7555
refactor: remove unused comments
snamiki1212 Jun 10, 2023
da075de
fix: control fn private
snamiki1212 Jun 10, 2023
99316cf
fix: add with_username on users
snamiki1212 Jun 10, 2023
dc4cc39
refactor: add username helper on user
snamiki1212 Jun 10, 2023
b7fcea3
refactor: add by_email on user model
snamiki1212 Jun 10, 2023
537896c
fix: add with_author_id fn on article
snamiki1212 Jun 10, 2023
0d3da3b
fix: add with_author on article
snamiki1212 Jun 10, 2023
e5af407
fix: add by_id on article
snamiki1212 Jun 10, 2023
38c91c5
fix: add favorite helper fn
snamiki1212 Jun 10, 2023
32502ca
fix: add follow helper
snamiki1212 Jun 10, 2023
7f75da5
refactor: polish delete way
snamiki1212 Jun 10, 2023
6f779ef
refactor: organize query and runner
snamiki1212 Jun 10, 2023
6c26690
fix: update query
snamiki1212 Jun 10, 2023
5f38493
refactor: polish query builder
snamiki1212 Jun 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 50 additions & 36 deletions src/app/article/model.rs
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading