diff --git a/migration/src/lib.rs b/migration/src/lib.rs index ecbbf54..ddf6b1b 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -4,6 +4,8 @@ mod m20240719_00001_create_main_data_table; mod m20240719_00002_create_long_data_table; mod m20240721_221623_create_indexs; +pub use m20240721_221623_create_indexs::FULL_DATA_VIEW; + pub struct Migrator; #[async_trait::async_trait] diff --git a/migration/src/m20240721_221623_create_indexs.rs b/migration/src/m20240721_221623_create_indexs.rs index 5acd253..2ad838d 100644 --- a/migration/src/m20240721_221623_create_indexs.rs +++ b/migration/src/m20240721_221623_create_indexs.rs @@ -9,6 +9,23 @@ use crate::m20240719_00002_create_long_data_table::LongData; pub const MAIN_SAVETYPE_SAVEID_IDX: &str = "maindata_savetype_saveid_idx"; pub const LONG_SAVEID_IDX: &str = "longdata_saveid_idx"; +pub const FULL_DATA_VIEW: &str = "full_data"; +pub const FULL_DATA_VIEW_SQL: &str = r#" +CREATE OR REPLACE VIEW full_data as +SELECT + md.save_id, + md.save_type, + md.blake_hash, + md.len, + CASE + WHEN md.len > 1024 THEN + ld.text + ELSE md.short_data + END AS data +FROM main_data md +LEFT JOIN long_data ld ON md.save_id = ld.save_id +"#; + #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { @@ -44,6 +61,9 @@ impl MigrationTrait for Migration { .name(LONG_SAVEID_IDX); manager.create_index(save_type_idx).await?; + let db = manager.get_connection(); + db.execute_unprepared(FULL_DATA_VIEW_SQL).await?; // 谁管你是什么后端啊, 老子就是 PostgreSQL + Ok(()) } @@ -59,6 +79,15 @@ impl MigrationTrait for Migration { manager.drop_index(dropping_index).await?; } + if manager.has_index("long_data", LONG_SAVEID_IDX).await? { + let mut dropping_index = Index::drop(); + dropping_index.name(LONG_SAVEID_IDX).table(LongData::Table); + manager.drop_index(dropping_index).await?; + } + + let db = manager.get_connection(); + db.execute_unprepared("DROP VIEW full_data").await?; // 谁管你是什么后端啊, 老子就是 PostgreSQL + Ok(()) } } diff --git a/sr_download/src/db_part.rs b/sr_download/src/db_part.rs index 98165a8..3b1dba5 100644 --- a/sr_download/src/db_part.rs +++ b/sr_download/src/db_part.rs @@ -1,15 +1,15 @@ use blake3::Hasher; use sea_orm::{ - ActiveModelTrait, ColumnTrait, ConnectOptions, Database, DatabaseConnection, DbErr, - EntityTrait, IntoActiveModel, ModelTrait, QueryFilter, QueryOrder, QuerySelect, - TransactionTrait, + ActiveModelTrait, ColumnTrait, ConnectOptions, ConnectionTrait, Database, DatabaseConnection, + DbErr, EntityTrait, IntoActiveModel, ModelTrait, QueryFilter, QueryOrder, QuerySelect, + Statement, TransactionTrait, }; use tracing::{event, Level}; use crate::model::sea_orm_active_enums::SaveType; use crate::{config::ConfigFile, SaveId}; use crate::{model, TEXT_DATA_MAX_LEN}; -use migration::{Migrator, MigratorTrait}; +use migration::{Migrator, MigratorTrait, FULL_DATA_VIEW}; pub async fn connect(conf: &ConfigFile) -> anyhow::Result { let mut opt = ConnectOptions::new(conf.db_url.clone()); @@ -48,6 +48,24 @@ pub async fn find_max_id(db: &DatabaseConnection) -> SaveId { } } +/// 直接从数据库中查询数据, 这里数据库已经准备好了根据长度区分过的数据 +/// 可以从 full view 里直接选数据 +pub async fn get_raw_data(save_id: SaveId, db: &DatabaseConnection) -> Option { + let sql = format!( + "SELECT data FROM {} WHERE save_id = {}", + FULL_DATA_VIEW, save_id + ); + db.query_one(Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + sql, + )) + .await + .ok()?? + .try_get_by_index(0) + .ok() + .flatten() +} + pub async fn check_data_len(db: &DatabaseConnection, save_id: SaveId) -> Option { // SELECT save_id from main_data WHERE save_id = $1 AND len > 0 model::main_data::Entity::find() @@ -98,6 +116,7 @@ where let exitst_data: Option = { model::main_data::Entity::find() .filter(model::main_data::Column::SaveId.eq(save_id as i32)) + .limit(1) .one(db) .await .ok()