feat: room(分区)
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
ALTER TABLE posts
|
||||||
|
DROP COLUMN room_id
|
||||||
3
migrations/postgres/2022-08-18-234900_add_room_id/up.sql
Normal file
3
migrations/postgres/2022-08-18-234900_add_room_id/up.sql
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
ALTER TABLE posts
|
||||||
|
ADD COLUMN room_id INTEGER NOT NULL DEFAULT 0
|
||||||
@@ -235,7 +235,7 @@ impl Ugc for Post {
|
|||||||
self.is_deleted
|
self.is_deleted
|
||||||
}
|
}
|
||||||
fn extra_delete_condition(&self) -> bool {
|
fn extra_delete_condition(&self) -> bool {
|
||||||
!self.content.starts_with("[系统自动代发]\n")
|
self.room_id != 42
|
||||||
}
|
}
|
||||||
async fn do_set_deleted(&mut self, db: &Db) -> Api<()> {
|
async fn do_set_deleted(&mut self, db: &Db) -> Api<()> {
|
||||||
update!(*self, posts, db, { is_deleted, to true });
|
update!(*self, posts, db, { is_deleted, to true });
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ pub async fn report(ri: Form<ReportInput>, user: CurrentUser, db: Db, rconn: Rds
|
|||||||
is_tmp: false,
|
is_tmp: false,
|
||||||
n_attentions: 1,
|
n_attentions: 1,
|
||||||
allow_search: true,
|
allow_search: true,
|
||||||
|
room_id: 42,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -26,12 +26,14 @@ pub struct PostInput {
|
|||||||
use_title: Option<i8>,
|
use_title: Option<i8>,
|
||||||
#[field(validate = len(0..97))]
|
#[field(validate = len(0..97))]
|
||||||
poll_options: Vec<String>,
|
poll_options: Vec<String>,
|
||||||
|
room_id: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
pub struct PostOutput {
|
pub struct PostOutput {
|
||||||
pid: i32,
|
pid: i32,
|
||||||
|
room_id: i32,
|
||||||
text: String,
|
text: String,
|
||||||
cw: Option<String>,
|
cw: Option<String>,
|
||||||
author_title: Option<String>,
|
author_title: Option<String>,
|
||||||
@@ -84,6 +86,7 @@ async fn p2output(p: &Post, user: &CurrentUser, db: &Db, rconn: &RdsConn) -> Api
|
|||||||
user.is_admin || (!is_blocked && user.id.is_some() || user.namehash.eq(&p.author_hash));
|
user.is_admin || (!is_blocked && user.id.is_some() || user.namehash.eq(&p.author_hash));
|
||||||
Ok(PostOutput {
|
Ok(PostOutput {
|
||||||
pid: p.id,
|
pid: p.id,
|
||||||
|
room_id: p.room_id,
|
||||||
text: can_view.then(|| p.content.clone()).unwrap_or_default(),
|
text: can_view.then(|| p.content.clone()).unwrap_or_default(),
|
||||||
cw: (!p.cw.is_empty()).then(|| p.cw.clone()),
|
cw: (!p.cw.is_empty()).then(|| p.cw.clone()),
|
||||||
n_attentions: p.n_attentions,
|
n_attentions: p.n_attentions,
|
||||||
@@ -144,10 +147,11 @@ pub async fn get_one(pid: i32, user: CurrentUser, db: Db, rconn: RdsConn) -> Jso
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/getlist?<p>&<order_mode>")]
|
#[get("/getlist?<p>&<order_mode>&<room_id>")]
|
||||||
pub async fn get_list(
|
pub async fn get_list(
|
||||||
p: Option<u32>,
|
p: Option<u32>,
|
||||||
order_mode: u8,
|
order_mode: u8,
|
||||||
|
room_id: Option<i32>,
|
||||||
user: CurrentUser,
|
user: CurrentUser,
|
||||||
db: Db,
|
db: Db,
|
||||||
rconn: RdsConn,
|
rconn: RdsConn,
|
||||||
@@ -156,7 +160,15 @@ pub async fn get_list(
|
|||||||
let page = p.unwrap_or(1);
|
let page = p.unwrap_or(1);
|
||||||
let page_size = 25;
|
let page_size = 25;
|
||||||
let start = (page - 1) * page_size;
|
let start = (page - 1) * page_size;
|
||||||
let ps = Post::gets_by_page(&db, &rconn, order_mode, start.into(), page_size.into()).await?;
|
let ps = Post::gets_by_page(
|
||||||
|
&db,
|
||||||
|
&rconn,
|
||||||
|
room_id,
|
||||||
|
order_mode,
|
||||||
|
start.into(),
|
||||||
|
page_size.into(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
let ps_data = ps2outputs(&ps, &user, &db, &rconn).await?;
|
let ps_data = ps2outputs(&ps, &user, &db, &rconn).await?;
|
||||||
Ok(json!({
|
Ok(json!({
|
||||||
"data": ps_data,
|
"data": ps_data,
|
||||||
@@ -184,6 +196,7 @@ pub async fn publish_post(
|
|||||||
is_tmp: user.id.is_none(),
|
is_tmp: user.id.is_none(),
|
||||||
n_attentions: 1,
|
n_attentions: 1,
|
||||||
allow_search: poi.allow_search.is_some(),
|
allow_search: poi.allow_search.is_some(),
|
||||||
|
room_id: poi.room_id.unwrap_or_default(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ use crate::models::*;
|
|||||||
use crate::rds_conn::RdsConn;
|
use crate::rds_conn::RdsConn;
|
||||||
use rocket::serde::json::json;
|
use rocket::serde::json::json;
|
||||||
|
|
||||||
#[get("/search?<search_mode>&<page>&<keywords>")]
|
#[get("/search?<search_mode>&<page>&<keywords>&<room_id>")]
|
||||||
pub async fn search(
|
pub async fn search(
|
||||||
|
room_id: Option<i32>,
|
||||||
keywords: String,
|
keywords: String,
|
||||||
search_mode: u8,
|
search_mode: u8,
|
||||||
page: i32,
|
page: i32,
|
||||||
@@ -25,6 +26,7 @@ pub async fn search(
|
|||||||
Post::search(
|
Post::search(
|
||||||
&db,
|
&db,
|
||||||
&rconn,
|
&rconn,
|
||||||
|
room_id,
|
||||||
search_mode,
|
search_mode,
|
||||||
keywords.to_string(),
|
keywords.to_string(),
|
||||||
start.into(),
|
start.into(),
|
||||||
|
|||||||
15
src/cache.rs
15
src/cache.rs
@@ -172,17 +172,24 @@ impl PostCommentCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PostListCommentCache {
|
pub struct PostListCache {
|
||||||
key: String,
|
key: String,
|
||||||
mode: u8,
|
mode: u8,
|
||||||
rconn: RdsConn,
|
rconn: RdsConn,
|
||||||
length: isize,
|
length: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PostListCommentCache {
|
impl PostListCache {
|
||||||
pub fn init(mode: u8, rconn: &RdsConn) -> Self {
|
pub fn init(room_id: Option<i32>, mode: u8, rconn: &RdsConn) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key: format!("hole_v2:cache:post_list:{}", &mode),
|
key: format!(
|
||||||
|
"hole_v2:cache:post_list:{}:{}",
|
||||||
|
match room_id {
|
||||||
|
Some(i) => i.to_string(),
|
||||||
|
None => "".to_owned(),
|
||||||
|
},
|
||||||
|
&mode
|
||||||
|
),
|
||||||
mode,
|
mode,
|
||||||
rconn: rconn.clone(),
|
rconn: rconn.clone(),
|
||||||
length: 0,
|
length: 0,
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ async fn main() -> Result<(), rocket::Error> {
|
|||||||
let rconn = RdsConn(rmc.clone());
|
let rconn = RdsConn(rmc.clone());
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
cache::PostListCommentCache::init(3, &rconn).clear().await;
|
for room_id in [None, Some(0), Some(1), Some(42)] {
|
||||||
|
cache::PostListCache::init(room_id, 3, &rconn).clear().await;
|
||||||
|
}
|
||||||
sleep(Duration::from_secs(5 * 60)).await;
|
sleep(Duration::from_secs(5 * 60)).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ pub struct Post {
|
|||||||
pub is_reported: bool,
|
pub is_reported: bool,
|
||||||
pub hot_score: i32,
|
pub hot_score: i32,
|
||||||
pub allow_search: bool,
|
pub allow_search: bool,
|
||||||
|
pub room_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug)]
|
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug)]
|
||||||
@@ -140,6 +141,7 @@ 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,
|
||||||
|
pub room_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Post {
|
impl Post {
|
||||||
@@ -215,19 +217,21 @@ impl Post {
|
|||||||
pub async fn gets_by_page(
|
pub async fn gets_by_page(
|
||||||
db: &Db,
|
db: &Db,
|
||||||
rconn: &RdsConn,
|
rconn: &RdsConn,
|
||||||
|
room_id: Option<i32>,
|
||||||
order_mode: u8,
|
order_mode: u8,
|
||||||
start: i64,
|
start: i64,
|
||||||
limit: i64,
|
limit: i64,
|
||||||
) -> QueryResult<Vec<Self>> {
|
) -> QueryResult<Vec<Self>> {
|
||||||
let mut cacher = PostListCommentCache::init(order_mode, &rconn);
|
let mut cacher = PostListCache::init(room_id, order_mode, &rconn);
|
||||||
if cacher.need_fill().await {
|
if cacher.need_fill().await {
|
||||||
let pids =
|
let pids =
|
||||||
Self::_get_ids_by_page(db, order_mode.clone(), 0, cacher.i64_minlen()).await?;
|
Self::_get_ids_by_page(db, room_id, order_mode.clone(), 0, cacher.i64_minlen())
|
||||||
|
.await?;
|
||||||
let ps = Self::get_multi(db, rconn, &pids).await?;
|
let ps = Self::get_multi(db, rconn, &pids).await?;
|
||||||
cacher.fill(&ps).await;
|
cacher.fill(&ps).await;
|
||||||
}
|
}
|
||||||
let pids = if start + limit > cacher.i64_len() {
|
let pids = if start + limit > cacher.i64_len() {
|
||||||
Self::_get_ids_by_page(db, order_mode, start, limit).await?
|
Self::_get_ids_by_page(db, room_id, order_mode, start, limit).await?
|
||||||
} else {
|
} else {
|
||||||
cacher.get_pids(start, limit).await
|
cacher.get_pids(start, limit).await
|
||||||
};
|
};
|
||||||
@@ -236,6 +240,7 @@ impl Post {
|
|||||||
}
|
}
|
||||||
async fn _get_ids_by_page(
|
async fn _get_ids_by_page(
|
||||||
db: &Db,
|
db: &Db,
|
||||||
|
room_id: Option<i32>,
|
||||||
order_mode: u8,
|
order_mode: u8,
|
||||||
start: i64,
|
start: i64,
|
||||||
limit: i64,
|
limit: i64,
|
||||||
@@ -243,7 +248,11 @@ impl Post {
|
|||||||
db.run(move |c| {
|
db.run(move |c| {
|
||||||
let mut query = base_query!(posts).select(posts::id);
|
let mut query = base_query!(posts).select(posts::id);
|
||||||
if order_mode > 0 {
|
if order_mode > 0 {
|
||||||
query = query.filter(posts::is_reported.eq(false))
|
query = query.filter(posts::is_reported.eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ri) = room_id {
|
||||||
|
query = query.filter(posts::room_id.eq(ri));
|
||||||
}
|
}
|
||||||
|
|
||||||
query = match order_mode {
|
query = match order_mode {
|
||||||
@@ -262,6 +271,7 @@ impl Post {
|
|||||||
pub async fn search(
|
pub async fn search(
|
||||||
db: &Db,
|
db: &Db,
|
||||||
rconn: &RdsConn,
|
rconn: &RdsConn,
|
||||||
|
room_id: Option<i32>,
|
||||||
search_mode: u8,
|
search_mode: u8,
|
||||||
search_text: String,
|
search_text: String,
|
||||||
start: i64,
|
start: i64,
|
||||||
@@ -276,6 +286,9 @@ impl Post {
|
|||||||
.distinct()
|
.distinct()
|
||||||
.left_join(comments::table)
|
.left_join(comments::table)
|
||||||
.filter(posts::is_reported.eq(false));
|
.filter(posts::is_reported.eq(false));
|
||||||
|
if let Some(ri) = room_id {
|
||||||
|
query = query.filter(posts::room_id.eq(ri));
|
||||||
|
}
|
||||||
// 先用搜索+缓存,性能有问题了再真的做tag表
|
// 先用搜索+缓存,性能有问题了再真的做tag表
|
||||||
query = match search_mode {
|
query = match search_mode {
|
||||||
0 => {
|
0 => {
|
||||||
@@ -334,9 +347,12 @@ impl Post {
|
|||||||
join!(
|
join!(
|
||||||
self.set_instance_cache(rconn),
|
self.set_instance_cache(rconn),
|
||||||
future::join_all((if is_new { 0..4 } else { 1..4 }).map(|mode| async move {
|
future::join_all((if is_new { 0..4 } else { 1..4 }).map(|mode| async move {
|
||||||
PostListCommentCache::init(mode, &rconn.clone())
|
PostListCache::init(None, mode, &rconn.clone())
|
||||||
.put(self)
|
.put(self)
|
||||||
.await
|
.await;
|
||||||
|
PostListCache::init(Some(self.room_id), mode, &rconn.clone())
|
||||||
|
.put(self)
|
||||||
|
.await;
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -349,7 +365,9 @@ impl Post {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
PostCache::init(&rconn).clear_all().await;
|
PostCache::init(&rconn).clear_all().await;
|
||||||
PostListCommentCache::init(2, rconn).clear().await
|
for room_id in [None, Some(0), Some(1), Some(42)] {
|
||||||
|
PostListCache::init(room_id, 2, rconn).clear().await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ table! {
|
|||||||
is_reported -> Bool,
|
is_reported -> Bool,
|
||||||
hot_score -> Int4,
|
hot_score -> Int4,
|
||||||
allow_search -> Bool,
|
allow_search -> Bool,
|
||||||
|
room_id -> Int4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user