From b2cf8475c5a42e6263ec63b20d728b83bc763089 Mon Sep 17 00:00:00 2001 From: hole-thu Date: Sat, 26 Mar 2022 21:54:50 +0800 Subject: [PATCH] opt: use macro for sql updates, and merge updates --- Cargo.toml | 1 - src/api/attention.rs | 14 +++++++-- src/api/comment.rs | 39 +++++++++++++++---------- src/api/mod.rs | 9 ++++-- src/api/operation.rs | 14 +++++++-- src/api/post.rs | 5 +++- src/models.rs | 69 +++++++++++++------------------------------- 7 files changed, 76 insertions(+), 75 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index de1ad7e..6b02b58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,4 +19,3 @@ dotenv = "0.15.0" sha2 = "0.10.2" log = "0.4.16" env_logger = "0.9.0" -paste = "1.0.6" diff --git a/src/api/attention.rs b/src/api/attention.rs index 6a62131..60bbfbe 100644 --- a/src/api/attention.rs +++ b/src/api/attention.rs @@ -1,9 +1,12 @@ use crate::api::post::ps2outputs; use crate::api::{CurrentUser, JsonAPI, PolicyError::*, UGC}; use crate::db_conn::Db; +use crate::libs::diesel_logger::LoggingConnection; use crate::models::*; use crate::rds_conn::RdsConn; use crate::rds_models::*; +use crate::schema; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; use rocket::form::Form; use rocket::serde::json::json; @@ -37,10 +40,15 @@ pub async fn attention_post( att.remove(ai.pid).await?; delta = -1; } - p.change_n_attentions(&db, delta).await?; - p.change_hot_score(&db, delta * 2).await?; + update!( + p, + posts, + &db, + { n_attentions, add delta }, + { hot_score, add delta * 2 } + ); if switch_to && user.is_admin { - p.set_is_reported(&db, false).await?; + update!(p, posts, &db, { is_reported, to false }); } p.refresh_cache(&rconn, false).await; } diff --git a/src/api/comment.rs b/src/api/comment.rs index 4e8da4e..667b5f3 100644 --- a/src/api/comment.rs +++ b/src/api/comment.rs @@ -1,11 +1,14 @@ use crate::api::{APIError, CurrentUser, JsonAPI, PolicyError::*, UGC}; use crate::db_conn::Db; +use crate::libs::diesel_logger::LoggingConnection; use crate::models::*; use crate::rds_conn::RdsConn; use crate::rds_models::*; +use crate::schema; use chrono::{offset::Utc, DateTime}; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; use rocket::form::Form; -use rocket::futures::{future::TryFutureExt, join, try_join}; +use rocket::futures::join; use rocket::serde::{json::json, Serialize}; use std::collections::HashMap; @@ -100,26 +103,30 @@ pub async fn add_comment( }, ) .await?; - p.change_n_comments(&db, 1).await?; - p.set_last_comment_time(&db, c.create_time).await?; - // auto attention after comment - let mut att = Attention::init(&user.namehash, &rconn); - let mut hs_delta = 1; + let mut att = Attention::init(&user.namehash, &rconn); + let hs_delta; + let at_delta; if !att.has(p.id).await? { - hs_delta += 2; - try_join!( - att.add(p.id).err_into::(), - async { - p.change_n_attentions(&db, 1).await?; - Ok::<(), APIError>(()) - } - .err_into::(), - )?; + hs_delta = 3; + at_delta = 1; + att.add(p.id).await?; + } else { + hs_delta = 1; + at_delta = 0; } - p.change_hot_score(&db, hs_delta).await?; + update!( + p, + posts, + &db, + { n_comments, add 1 }, + { last_comment_time, to c.create_time }, + { n_attentions, add at_delta }, + { hot_score, add hs_delta } + ); + join!( p.refresh_cache(&rconn, false), p.clear_comments_cache(&rconn), diff --git a/src/api/mod.rs b/src/api/mod.rs index 7f00467..192960c 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,8 +1,11 @@ use crate::db_conn::Db; +use crate::libs::diesel_logger::LoggingConnection; use crate::models::*; use crate::random_hasher::RandomHasher; use crate::rds_conn::RdsConn; use crate::rds_models::BannedUsers; +use crate::schema; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; use rocket::http::Status; use rocket::outcome::try_outcome; use rocket::request::{FromRequest, Outcome, Request}; @@ -180,7 +183,8 @@ impl UGC for Post { self.n_comments == 0 } async fn do_set_deleted(&mut self, db: &Db) -> API<()> { - self.set_is_deleted(db, true).await.map_err(From::from) + update!(*self, posts, db, { is_deleted, to true }); + Ok(()) } } @@ -199,7 +203,8 @@ impl UGC for Comment { true } async fn do_set_deleted(&mut self, db: &Db) -> API<()> { - self.set_is_deleted(db, true).await.map_err(From::from) + update!(*self, comments, db, { is_deleted, to true }); + Ok(()) } } diff --git a/src/api/operation.rs b/src/api/operation.rs index 9bd5239..019a356 100644 --- a/src/api/operation.rs +++ b/src/api/operation.rs @@ -6,6 +6,9 @@ use crate::rds_models::*; use chrono::offset::Local; use rocket::form::Form; use rocket::serde::json::json; +use crate::libs::diesel_logger::LoggingConnection; +use crate::schema; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; #[derive(FromForm)] pub struct DeleteInput { @@ -25,8 +28,13 @@ pub async fn delete(di: Form, user: CurrentUser, db: Db, rconn: Rds c = Comment::get(&db, di.id).await?; c.soft_delete(&user, &db).await?; p = Post::get(&db, &rconn, c.post_id).await?; - p.change_n_comments(&db, -1).await?; - p.change_hot_score(&db, -1).await?; + update!( + p, + posts, + &db, + { n_comments, add -1 }, + { hot_score, add -1 } + ); p.refresh_cache(&rconn, false).await; p.clear_comments_cache(&rconn).await; @@ -86,7 +94,7 @@ pub async fn report(ri: Form, user: CurrentUser, db: Db, rconn: Rds user.id.ok_or_else(|| NotAllowed)?; let mut p = Post::get(&db, &rconn, ri.pid).await?; - p.set_is_reported(&db, true).await?; + update!(p, posts, &db, { is_reported, to true }); p.refresh_cache(&rconn, false).await; Systemlog { user_hash: user.namehash, diff --git a/src/api/post.rs b/src/api/post.rs index 36afa08..4879e8c 100644 --- a/src/api/post.rs +++ b/src/api/post.rs @@ -1,10 +1,13 @@ use crate::api::comment::{c2output, CommentOutput}; use crate::api::{CurrentUser, JsonAPI, UGC}; use crate::db_conn::Db; +use crate::libs::diesel_logger::LoggingConnection; use crate::models::*; use crate::rds_conn::RdsConn; use crate::rds_models::*; +use crate::schema; use chrono::{offset::Utc, DateTime}; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; use rocket::form::Form; use rocket::futures::future; use rocket::serde::{json::json, Serialize}; @@ -159,7 +162,7 @@ pub async fn publish_post( pub async fn edit_cw(cwi: Form, user: CurrentUser, db: Db, rconn: RdsConn) -> JsonAPI { let mut p = Post::get(&db, &rconn, cwi.pid).await?; p.check_permission(&user, "w")?; - p.set_cw(&db, cwi.cw.to_string()).await?; + update!(p, posts, &db, { cw, to cwi.cw.to_string() }); p.refresh_cache(&rconn, false).await; Ok(json!({"code": 0})) } diff --git a/src/models.rs b/src/models.rs index 155ff19..afba01f 100644 --- a/src/models.rs +++ b/src/models.rs @@ -48,42 +48,29 @@ macro_rules! _get_multi { }; } -macro_rules! impl_update_method { - ($self:expr, $db:expr, $table:ident, $col:ident, $to:expr) => {{ - let id = $self.id; - *$self = $db +macro_rules! op_to_col_expr { + ($col_obj:expr, to $v:expr) => { + $v + }; + ($col_obj:expr, add $v:expr) => { + $col_obj + $v + }; +} + +macro_rules! update { + ($obj:expr, $table:ident, $db:expr, $({ $col:ident, $op:ident $v:expr }), + ) => {{ + let id = $obj.id; + $obj = $db .run(move |c| { - diesel::update($table::table.find(id)) - .set($table::$col.eq($to)) + diesel::update(schema::$table::table.find(id)) + .set(( + $(schema::$table::$col.eq(op_to_col_expr!(schema::$table::$col, $op $v))), + + )) .get_result(with_log!(c)) }) .await?; - Ok(()) - }}; -} -macro_rules! make_set_column { - ($table:ident { $({ $col:ident, $col_type:ty }), * }) => { - paste::paste! { - $( - pub async fn [< set_ $col>](&mut self, db: &Db, v: $col_type) -> QueryResult<()> { - impl_update_method!(self, db, $table, $col, v) - } - )* - } - }; -} - -macro_rules! make_change_column { - ($table:ident { $({ $col:ident, $col_type:ty }), * }) => { - paste::paste! { - $( - pub async fn [< change_ $col>](&mut self, db: &Db, delta: $col_type) -> QueryResult<()> { - impl_update_method!(self, db, $table, $col, $table::$col + delta) - } - )* - } - }; + }}; } macro_rules! base_query { @@ -152,7 +139,6 @@ pub struct NewPost { pub is_tmp: bool, pub n_attentions: i32, pub allow_search: bool, - // TODO: tags } impl Post { @@ -160,19 +146,6 @@ impl Post { _get_multi!(posts); - make_set_column!(posts { - {is_reported, bool}, - {is_deleted, bool}, - {cw, String}, - {last_comment_time, DateTime} - }); - - make_change_column!(posts { - {n_comments, i32}, - {n_attentions, i32}, - {hot_score, i32} - }); - pub async fn get_multi(db: &Db, rconn: &RdsConn, ids: &Vec) -> QueryResult> { let mut cacher = PostCache::init(&rconn); let mut cached_posts = cacher.gets(ids).await; @@ -410,10 +383,6 @@ pub struct NewComment { impl Comment { _get!(comments); - make_set_column!(comments { - {is_deleted, bool} - }); - pub async fn get(db: &Db, id: i32) -> QueryResult { // no cache for single comment Self::_get(db, id).await @@ -439,3 +408,5 @@ impl Comment { .await } } + +pub(crate) use {op_to_col_expr, update, with_log};