feat: search & beginning of cache

This commit is contained in:
2022-03-23 03:53:48 +08:00
parent cfe39f7645
commit dcc7bb1268
11 changed files with 320 additions and 115 deletions

View File

@@ -1,9 +1,15 @@
#![allow(clippy::all)]
use diesel::{insert_into, ExpressionMethods, QueryDsl, QueryResult, RunQueryDsl};
use crate::db_conn::Db;
use crate::rds_conn::RdsConn;
use crate::rds_models::PostCache;
use crate::schema::*;
use chrono::{offset::Utc, DateTime};
use diesel::{
insert_into, BoolExpressionMethods, ExpressionMethods, QueryDsl, QueryResult, RunQueryDsl,
TextExpressionMethods,
};
use rocket::serde::{Deserialize, Serialize};
no_arg_sql_function!(RANDOM, (), "Represents the sql RANDOM() function");
@@ -23,6 +29,7 @@ macro_rules! get_multi {
db.run(move |c| {
$table::table
.filter($table::id.eq_any(ids))
.filter($table::is_deleted.eq(false))
.order($table::id.desc())
.load(c)
})
@@ -45,7 +52,14 @@ macro_rules! set_deleted {
};
}
use chrono::{offset::Utc, DateTime};
macro_rules! base_query {
($table:ident) => {
$table::table
.into_boxed()
.filter($table::is_deleted.eq(false))
};
}
#[derive(Queryable, Insertable)]
pub struct Comment {
pub id: i32,
@@ -59,7 +73,8 @@ pub struct Comment {
pub post_id: i32,
}
#[derive(Queryable, Insertable)]
#[derive(Queryable, Insertable, Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct Post {
pub id: i32,
pub author_hash: String,
@@ -105,29 +120,83 @@ impl Post {
set_deleted!(posts);
pub async fn get_with_cache(db: &Db, rconn: &RdsConn, id: i32) -> QueryResult<Self> {
let mut cacher = PostCache::init(&id, &rconn);
if let Some(p) = cacher.get().await {
dbg!("hint and use post cache");
Ok(p)
} else {
let p = Self::get(db, id).await?;
cacher.set(&p).await;
Ok(p)
}
}
pub async fn gets_by_page(
db: &Db,
order_mode: u8,
page: u32,
page_size: u32,
start: i64,
limit: i64,
) -> QueryResult<Vec<Self>> {
db.run(move |c| {
let mut query = posts::table.into_boxed();
query = query.filter(posts::is_deleted.eq(false));
let mut query = base_query!(posts);
if order_mode > 0 {
query = query.filter(posts::is_reported.eq(false))
}
match order_mode {
1 => query = query.order(posts::last_comment_time.desc()),
2 => query = query.order(posts::hot_score.desc()),
3 => query = query.order(RANDOM),
_ => query = query.order(posts::id.desc()),
}
query = match order_mode {
0 => query.order(posts::id.desc()),
1 => query.order(posts::last_comment_time.desc()),
2 => query.order(posts::hot_score.desc()),
3 => query.order(RANDOM),
_ => panic!("Wrong order mode!"),
};
query.offset(start).limit(limit).load(c)
})
.await
}
pub async fn search(
db: &Db,
search_mode: u8,
search_text: String,
start: i64,
limit: i64,
) -> QueryResult<Vec<Self>> {
let search_text2 = search_text.replace("%", "\\%");
db.run(move |c| {
let pat;
let mut query = base_query!(posts)
.distinct()
.left_join(comments::table)
.filter(comments::is_deleted.eq(false));
// 先用搜索+缓存性能有问题了再真的做tag表
query = match search_mode {
0 => {
pat = format!("%#{}%", &search_text2);
query
.filter(posts::cw.eq(&search_text))
.or_filter(posts::cw.eq(format!("#{}", &search_text)))
.or_filter(posts::content.like(&pat))
.or_filter(comments::content.like(&pat))
}
1 => {
pat = format!("%{}%", search_text2.replace(" ", "%"));
query
.filter(posts::content.like(&pat).or(comments::content.like(&pat)))
.filter(posts::allow_search.eq(true))
}
2 => query
.filter(posts::author_title.eq(&search_text))
.or_filter(comments::author_title.eq(&search_text)),
_ => panic!("Wrong search mode!"),
};
query
.offset(((page - 1) * page_size).into())
.limit(page_size.into())
.order(posts::id.desc())
.offset(start)
.limit(limit)
.load(c)
})
.await
@@ -149,25 +218,42 @@ impl Post {
.await
}
pub async fn change_n_comments(&self, db: &Db, delta: i32) -> QueryResult<usize> {
pub async fn change_n_comments(&self, db: &Db, delta: i32) -> QueryResult<Self> {
let pid = self.id;
db.run(move |c| {
diesel::update(posts::table.find(pid))
.set(posts::n_comments.eq(posts::n_comments + delta))
.execute(c)
.get_result(c)
})
.await
}
pub async fn change_n_attentions(&self, db: &Db, delta: i32) -> QueryResult<usize> {
pub async fn change_n_attentions(&self, db: &Db, delta: i32) -> QueryResult<Self> {
let pid = self.id;
db.run(move |c| {
diesel::update(posts::table.find(pid))
.set(posts::n_attentions.eq(posts::n_attentions + delta))
.execute(c)
.get_result(c)
})
.await
}
pub async fn change_hot_score(&self, db: &Db, delta: i32) -> QueryResult<Self> {
let pid = self.id;
db.run(move |c| {
diesel::update(posts::table.find(pid))
.set(posts::hot_score.eq(posts::hot_score + delta))
.get_result(c)
})
.await
}
pub async fn set_instance_cache(&self, rconn: &RdsConn) {
PostCache::init(&self.id, rconn).set(self).await;
}
pub async fn refresh_cache(&self, rconn: &RdsConn, is_new: bool) {
self.set_instance_cache(rconn).await;
}
}
impl User {