opt: use macro for sql updates, and merge updates
This commit is contained in:
@@ -19,4 +19,3 @@ dotenv = "0.15.0"
|
|||||||
sha2 = "0.10.2"
|
sha2 = "0.10.2"
|
||||||
log = "0.4.16"
|
log = "0.4.16"
|
||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
paste = "1.0.6"
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
use crate::api::post::ps2outputs;
|
use crate::api::post::ps2outputs;
|
||||||
use crate::api::{CurrentUser, JsonAPI, PolicyError::*, UGC};
|
use crate::api::{CurrentUser, JsonAPI, PolicyError::*, UGC};
|
||||||
use crate::db_conn::Db;
|
use crate::db_conn::Db;
|
||||||
|
use crate::libs::diesel_logger::LoggingConnection;
|
||||||
use crate::models::*;
|
use crate::models::*;
|
||||||
use crate::rds_conn::RdsConn;
|
use crate::rds_conn::RdsConn;
|
||||||
use crate::rds_models::*;
|
use crate::rds_models::*;
|
||||||
|
use crate::schema;
|
||||||
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
use rocket::form::Form;
|
use rocket::form::Form;
|
||||||
use rocket::serde::json::json;
|
use rocket::serde::json::json;
|
||||||
|
|
||||||
@@ -37,10 +40,15 @@ pub async fn attention_post(
|
|||||||
att.remove(ai.pid).await?;
|
att.remove(ai.pid).await?;
|
||||||
delta = -1;
|
delta = -1;
|
||||||
}
|
}
|
||||||
p.change_n_attentions(&db, delta).await?;
|
update!(
|
||||||
p.change_hot_score(&db, delta * 2).await?;
|
p,
|
||||||
|
posts,
|
||||||
|
&db,
|
||||||
|
{ n_attentions, add delta },
|
||||||
|
{ hot_score, add delta * 2 }
|
||||||
|
);
|
||||||
if switch_to && user.is_admin {
|
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;
|
p.refresh_cache(&rconn, false).await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
use crate::api::{APIError, CurrentUser, JsonAPI, PolicyError::*, UGC};
|
use crate::api::{APIError, CurrentUser, JsonAPI, PolicyError::*, UGC};
|
||||||
use crate::db_conn::Db;
|
use crate::db_conn::Db;
|
||||||
|
use crate::libs::diesel_logger::LoggingConnection;
|
||||||
use crate::models::*;
|
use crate::models::*;
|
||||||
use crate::rds_conn::RdsConn;
|
use crate::rds_conn::RdsConn;
|
||||||
use crate::rds_models::*;
|
use crate::rds_models::*;
|
||||||
|
use crate::schema;
|
||||||
use chrono::{offset::Utc, DateTime};
|
use chrono::{offset::Utc, DateTime};
|
||||||
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
use rocket::form::Form;
|
use rocket::form::Form;
|
||||||
use rocket::futures::{future::TryFutureExt, join, try_join};
|
use rocket::futures::join;
|
||||||
use rocket::serde::{json::json, Serialize};
|
use rocket::serde::{json::json, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -100,26 +103,30 @@ pub async fn add_comment(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.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? {
|
if !att.has(p.id).await? {
|
||||||
hs_delta += 2;
|
hs_delta = 3;
|
||||||
try_join!(
|
at_delta = 1;
|
||||||
att.add(p.id).err_into::<APIError>(),
|
att.add(p.id).await?;
|
||||||
async {
|
} else {
|
||||||
p.change_n_attentions(&db, 1).await?;
|
hs_delta = 1;
|
||||||
Ok::<(), APIError>(())
|
at_delta = 0;
|
||||||
}
|
|
||||||
.err_into::<APIError>(),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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!(
|
join!(
|
||||||
p.refresh_cache(&rconn, false),
|
p.refresh_cache(&rconn, false),
|
||||||
p.clear_comments_cache(&rconn),
|
p.clear_comments_cache(&rconn),
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
use crate::db_conn::Db;
|
use crate::db_conn::Db;
|
||||||
|
use crate::libs::diesel_logger::LoggingConnection;
|
||||||
use crate::models::*;
|
use crate::models::*;
|
||||||
use crate::random_hasher::RandomHasher;
|
use crate::random_hasher::RandomHasher;
|
||||||
use crate::rds_conn::RdsConn;
|
use crate::rds_conn::RdsConn;
|
||||||
use crate::rds_models::BannedUsers;
|
use crate::rds_models::BannedUsers;
|
||||||
|
use crate::schema;
|
||||||
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::outcome::try_outcome;
|
use rocket::outcome::try_outcome;
|
||||||
use rocket::request::{FromRequest, Outcome, Request};
|
use rocket::request::{FromRequest, Outcome, Request};
|
||||||
@@ -180,7 +183,8 @@ impl UGC for Post {
|
|||||||
self.n_comments == 0
|
self.n_comments == 0
|
||||||
}
|
}
|
||||||
async fn do_set_deleted(&mut self, db: &Db) -> API<()> {
|
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
|
true
|
||||||
}
|
}
|
||||||
async fn do_set_deleted(&mut self, db: &Db) -> API<()> {
|
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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ use crate::rds_models::*;
|
|||||||
use chrono::offset::Local;
|
use chrono::offset::Local;
|
||||||
use rocket::form::Form;
|
use rocket::form::Form;
|
||||||
use rocket::serde::json::json;
|
use rocket::serde::json::json;
|
||||||
|
use crate::libs::diesel_logger::LoggingConnection;
|
||||||
|
use crate::schema;
|
||||||
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
|
|
||||||
#[derive(FromForm)]
|
#[derive(FromForm)]
|
||||||
pub struct DeleteInput {
|
pub struct DeleteInput {
|
||||||
@@ -25,8 +28,13 @@ pub async fn delete(di: Form<DeleteInput>, user: CurrentUser, db: Db, rconn: Rds
|
|||||||
c = Comment::get(&db, di.id).await?;
|
c = Comment::get(&db, di.id).await?;
|
||||||
c.soft_delete(&user, &db).await?;
|
c.soft_delete(&user, &db).await?;
|
||||||
p = Post::get(&db, &rconn, c.post_id).await?;
|
p = Post::get(&db, &rconn, c.post_id).await?;
|
||||||
p.change_n_comments(&db, -1).await?;
|
update!(
|
||||||
p.change_hot_score(&db, -1).await?;
|
p,
|
||||||
|
posts,
|
||||||
|
&db,
|
||||||
|
{ n_comments, add -1 },
|
||||||
|
{ hot_score, add -1 }
|
||||||
|
);
|
||||||
|
|
||||||
p.refresh_cache(&rconn, false).await;
|
p.refresh_cache(&rconn, false).await;
|
||||||
p.clear_comments_cache(&rconn).await;
|
p.clear_comments_cache(&rconn).await;
|
||||||
@@ -86,7 +94,7 @@ pub async fn report(ri: Form<ReportInput>, user: CurrentUser, db: Db, rconn: Rds
|
|||||||
user.id.ok_or_else(|| NotAllowed)?;
|
user.id.ok_or_else(|| NotAllowed)?;
|
||||||
|
|
||||||
let mut p = Post::get(&db, &rconn, ri.pid).await?;
|
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;
|
p.refresh_cache(&rconn, false).await;
|
||||||
Systemlog {
|
Systemlog {
|
||||||
user_hash: user.namehash,
|
user_hash: user.namehash,
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
use crate::api::comment::{c2output, CommentOutput};
|
use crate::api::comment::{c2output, CommentOutput};
|
||||||
use crate::api::{CurrentUser, JsonAPI, UGC};
|
use crate::api::{CurrentUser, JsonAPI, UGC};
|
||||||
use crate::db_conn::Db;
|
use crate::db_conn::Db;
|
||||||
|
use crate::libs::diesel_logger::LoggingConnection;
|
||||||
use crate::models::*;
|
use crate::models::*;
|
||||||
use crate::rds_conn::RdsConn;
|
use crate::rds_conn::RdsConn;
|
||||||
use crate::rds_models::*;
|
use crate::rds_models::*;
|
||||||
|
use crate::schema;
|
||||||
use chrono::{offset::Utc, DateTime};
|
use chrono::{offset::Utc, DateTime};
|
||||||
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
use rocket::form::Form;
|
use rocket::form::Form;
|
||||||
use rocket::futures::future;
|
use rocket::futures::future;
|
||||||
use rocket::serde::{json::json, Serialize};
|
use rocket::serde::{json::json, Serialize};
|
||||||
@@ -159,7 +162,7 @@ pub async fn publish_post(
|
|||||||
pub async fn edit_cw(cwi: Form<CwInput>, user: CurrentUser, db: Db, rconn: RdsConn) -> JsonAPI {
|
pub async fn edit_cw(cwi: Form<CwInput>, user: CurrentUser, db: Db, rconn: RdsConn) -> JsonAPI {
|
||||||
let mut p = Post::get(&db, &rconn, cwi.pid).await?;
|
let mut p = Post::get(&db, &rconn, cwi.pid).await?;
|
||||||
p.check_permission(&user, "w")?;
|
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;
|
p.refresh_cache(&rconn, false).await;
|
||||||
Ok(json!({"code": 0}))
|
Ok(json!({"code": 0}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,44 +48,31 @@ macro_rules! _get_multi {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_update_method {
|
macro_rules! op_to_col_expr {
|
||||||
($self:expr, $db:expr, $table:ident, $col:ident, $to:expr) => {{
|
($col_obj:expr, to $v:expr) => {
|
||||||
let id = $self.id;
|
$v
|
||||||
*$self = $db
|
};
|
||||||
|
($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| {
|
.run(move |c| {
|
||||||
diesel::update($table::table.find(id))
|
diesel::update(schema::$table::table.find(id))
|
||||||
.set($table::$col.eq($to))
|
.set((
|
||||||
|
$(schema::$table::$col.eq(op_to_col_expr!(schema::$table::$col, $op $v))), +
|
||||||
|
))
|
||||||
.get_result(with_log!(c))
|
.get_result(with_log!(c))
|
||||||
})
|
})
|
||||||
.await?;
|
.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 {
|
macro_rules! base_query {
|
||||||
($table:ident) => {
|
($table:ident) => {
|
||||||
$table::table
|
$table::table
|
||||||
@@ -152,7 +139,6 @@ pub struct NewPost {
|
|||||||
pub is_tmp: bool,
|
pub is_tmp: bool,
|
||||||
pub n_attentions: i32,
|
pub n_attentions: i32,
|
||||||
pub allow_search: bool,
|
pub allow_search: bool,
|
||||||
// TODO: tags
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Post {
|
impl Post {
|
||||||
@@ -160,19 +146,6 @@ impl Post {
|
|||||||
|
|
||||||
_get_multi!(posts);
|
_get_multi!(posts);
|
||||||
|
|
||||||
make_set_column!(posts {
|
|
||||||
{is_reported, bool},
|
|
||||||
{is_deleted, bool},
|
|
||||||
{cw, String},
|
|
||||||
{last_comment_time, DateTime<Utc>}
|
|
||||||
});
|
|
||||||
|
|
||||||
make_change_column!(posts {
|
|
||||||
{n_comments, i32},
|
|
||||||
{n_attentions, i32},
|
|
||||||
{hot_score, i32}
|
|
||||||
});
|
|
||||||
|
|
||||||
pub async fn get_multi(db: &Db, rconn: &RdsConn, ids: &Vec<i32>) -> QueryResult<Vec<Self>> {
|
pub async fn get_multi(db: &Db, rconn: &RdsConn, ids: &Vec<i32>) -> QueryResult<Vec<Self>> {
|
||||||
let mut cacher = PostCache::init(&rconn);
|
let mut cacher = PostCache::init(&rconn);
|
||||||
let mut cached_posts = cacher.gets(ids).await;
|
let mut cached_posts = cacher.gets(ids).await;
|
||||||
@@ -410,10 +383,6 @@ pub struct NewComment {
|
|||||||
impl Comment {
|
impl Comment {
|
||||||
_get!(comments);
|
_get!(comments);
|
||||||
|
|
||||||
make_set_column!(comments {
|
|
||||||
{is_deleted, bool}
|
|
||||||
});
|
|
||||||
|
|
||||||
pub async fn get(db: &Db, id: i32) -> QueryResult<Self> {
|
pub async fn get(db: &Db, id: i32) -> QueryResult<Self> {
|
||||||
// no cache for single comment
|
// no cache for single comment
|
||||||
Self::_get(db, id).await
|
Self::_get(db, id).await
|
||||||
@@ -439,3 +408,5 @@ impl Comment {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) use {op_to_col_expr, update, with_log};
|
||||||
|
|||||||
Reference in New Issue
Block a user