Compare commits
2 Commits
f08f82ba98
...
f71de5c149
Author | SHA1 | Date | |
---|---|---|---|
f71de5c149 | |||
69b75d8e8f |
@ -9,7 +9,7 @@ use crate::model;
|
|||||||
use crate::model::sea_orm_active_enums::SaveType;
|
use crate::model::sea_orm_active_enums::SaveType;
|
||||||
use migration::{SaveId, FULL_DATA_VIEW, TEXT_DATA_MAX_LEN};
|
use migration::{SaveId, FULL_DATA_VIEW, TEXT_DATA_MAX_LEN};
|
||||||
|
|
||||||
pub mod definitions;
|
pub mod defines;
|
||||||
pub mod search;
|
pub mod search;
|
||||||
pub mod updates;
|
pub mod updates;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
use sea_orm::sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Table};
|
|
||||||
use sea_orm::{ConnectionTrait, DatabaseBackend, DatabaseConnection, Statement};
|
use sea_orm::{ConnectionTrait, DatabaseBackend, DatabaseConnection, Statement};
|
||||||
|
|
||||||
use crate::config::ConfigFile;
|
use crate::config::ConfigFile;
|
||||||
|
|
||||||
|
pub mod full_data_view;
|
||||||
|
pub mod long_data_table;
|
||||||
|
pub mod main_data_table;
|
||||||
|
pub mod ships_table;
|
||||||
|
|
||||||
pub mod db_names {
|
pub mod db_names {
|
||||||
/// 主数据表
|
/// 主数据表
|
||||||
pub const MAIN_DATA_TABLE: &str = "main_data";
|
pub const MAIN_DATA_TABLE: &str = "main_data";
|
||||||
@ -16,52 +20,43 @@ pub mod db_names {
|
|||||||
pub const SEA_ORM_TABLE: &str = "seaql_migrations";
|
pub const SEA_ORM_TABLE: &str = "seaql_migrations";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_table_exists(
|
pub const CURRENT_DB_VERSION: i32 = 1;
|
||||||
db: &DatabaseConnection,
|
|
||||||
table_name: &str,
|
pub const TEXT_DATA_MAX_LEN: usize = 1024;
|
||||||
schema: &str,
|
pub type SaveId = u32;
|
||||||
) -> Option<bool> {
|
|
||||||
|
pub async fn check_table_exists(db: &DatabaseConnection, table_name: &str, schema: &str) -> bool {
|
||||||
let sql = format!(
|
let sql = format!(
|
||||||
"SELECT EXISTS (SELECT FROM pg_tables WHERE tablename = '{}' AND schemaname = '{}');",
|
"SELECT EXISTS (SELECT FROM pg_tables WHERE tablename = '{}' AND schemaname = '{}');",
|
||||||
table_name, schema
|
table_name, schema
|
||||||
);
|
);
|
||||||
let exists = db
|
if let Ok(Some(exists)) = db
|
||||||
.query_one(Statement::from_string(DatabaseBackend::Postgres, sql))
|
.query_one(Statement::from_string(DatabaseBackend::Postgres, sql))
|
||||||
.await.ok()?;
|
.await
|
||||||
exists?.try_get("", "exists").ok()
|
{
|
||||||
|
if let Ok(exists) = exists.try_get("", "exists") {
|
||||||
|
return exists;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_main_data_exists(
|
pub async fn check_main_data_exists(db: &DatabaseConnection, conf: &ConfigFile) -> bool {
|
||||||
db: &DatabaseConnection,
|
|
||||||
conf: &ConfigFile,
|
|
||||||
) -> Option<bool> {
|
|
||||||
check_table_exists(db, db_names::MAIN_DATA_TABLE, &conf.db.schema).await
|
check_table_exists(db, db_names::MAIN_DATA_TABLE, &conf.db.schema).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_long_data_exists(
|
pub async fn check_long_data_exists(db: &DatabaseConnection, conf: &ConfigFile) -> bool {
|
||||||
db: &DatabaseConnection,
|
|
||||||
conf: &ConfigFile,
|
|
||||||
) -> Option<bool> {
|
|
||||||
check_table_exists(db, db_names::LONG_DATA_TABLE, &conf.db.schema).await
|
check_table_exists(db, db_names::LONG_DATA_TABLE, &conf.db.schema).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_full_data_exists(
|
pub async fn check_full_data_exists(db: &DatabaseConnection, conf: &ConfigFile) -> bool {
|
||||||
db: &DatabaseConnection,
|
|
||||||
conf: &ConfigFile,
|
|
||||||
) -> Option<bool> {
|
|
||||||
check_table_exists(db, db_names::FULL_DATA_TABLE, &conf.db.schema).await
|
check_table_exists(db, db_names::FULL_DATA_TABLE, &conf.db.schema).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_db_version_exists(
|
pub async fn check_db_version_exists(db: &DatabaseConnection, conf: &ConfigFile) -> bool {
|
||||||
db: &DatabaseConnection,
|
|
||||||
conf: &ConfigFile,
|
|
||||||
) -> Option<bool> {
|
|
||||||
check_table_exists(db, db_names::DB_VERSION_TABLE, &conf.db.schema).await
|
check_table_exists(db, db_names::DB_VERSION_TABLE, &conf.db.schema).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_sea_orm_exists(
|
pub async fn check_sea_orm_exists(db: &DatabaseConnection, conf: &ConfigFile) -> bool {
|
||||||
db: &DatabaseConnection,
|
|
||||||
conf: &ConfigFile,
|
|
||||||
) -> Option<bool> {
|
|
||||||
check_table_exists(db, db_names::SEA_ORM_TABLE, &conf.db.schema).await
|
check_table_exists(db, db_names::SEA_ORM_TABLE, &conf.db.schema).await
|
||||||
}
|
}
|
42
sr_download/src/db_part/defines/full_data_view.rs
Normal file
42
sr_download/src/db_part/defines/full_data_view.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
use sea_orm::DeriveIden;
|
||||||
|
|
||||||
|
pub const FULL_DATA_SQL: &str = r"
|
||||||
|
CREATE OR REPLACE VIEW full_data as
|
||||||
|
SELECT
|
||||||
|
md.save_id,
|
||||||
|
md.save_type,
|
||||||
|
md.blake_hash,
|
||||||
|
md.xml_tested,
|
||||||
|
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
|
||||||
|
";
|
||||||
|
|
||||||
|
#[derive(DeriveIden)]
|
||||||
|
pub enum FullData {
|
||||||
|
/// 表 (实际上是个视图)
|
||||||
|
Table,
|
||||||
|
/// 这个存档的 Id
|
||||||
|
SaveId,
|
||||||
|
/// 存档类型
|
||||||
|
/// - ship: 船
|
||||||
|
/// - save: 存档
|
||||||
|
/// - unknown: 未知 (没下载呢)
|
||||||
|
/// - none: 没有存档 (这个 Id 为 空)
|
||||||
|
SaveType,
|
||||||
|
/// blake3 hash
|
||||||
|
/// len = 64
|
||||||
|
/// 64 位的 blake3 hash
|
||||||
|
BlakeHash,
|
||||||
|
/// 存档的长度 (用来过滤太长的存档)
|
||||||
|
Len,
|
||||||
|
/// 完整的数据
|
||||||
|
Data,
|
||||||
|
/// 数据是不是合法的 XML 数据
|
||||||
|
XmlTested,
|
||||||
|
}
|
39
sr_download/src/db_part/defines/long_data_table.rs
Normal file
39
sr_download/src/db_part/defines/long_data_table.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use sea_orm::sea_query::{ColumnDef, ForeignKey, Table};
|
||||||
|
use sea_orm::{DatabaseBackend, DeriveIden, ForeignKeyAction, Iden, Statement};
|
||||||
|
|
||||||
|
use super::main_data_table::MainData;
|
||||||
|
|
||||||
|
pub fn long_data_table() -> Statement {
|
||||||
|
let mut table = Table::create();
|
||||||
|
table
|
||||||
|
.table(LongData::Table)
|
||||||
|
.if_not_exists()
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(LongData::SaveId)
|
||||||
|
.integer()
|
||||||
|
.not_null()
|
||||||
|
.primary_key(),
|
||||||
|
)
|
||||||
|
.foreign_key(
|
||||||
|
ForeignKey::create()
|
||||||
|
.name(LongData::SaveId.to_string())
|
||||||
|
.to(MainData::Table, MainData::SaveId)
|
||||||
|
.from(LongData::Table, LongData::SaveId)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade),
|
||||||
|
)
|
||||||
|
.col(ColumnDef::new(LongData::Len).big_integer().not_null())
|
||||||
|
.col(ColumnDef::new(LongData::Text).string().not_null());
|
||||||
|
DatabaseBackend::Postgres.build(&table)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(DeriveIden)]
|
||||||
|
pub enum LongData {
|
||||||
|
Table,
|
||||||
|
/// 存档 ID
|
||||||
|
SaveId,
|
||||||
|
/// 二次校验长度(?)
|
||||||
|
Len,
|
||||||
|
/// 1024 ~ 2MB 长度的数据
|
||||||
|
Text,
|
||||||
|
}
|
76
sr_download/src/db_part/defines/main_data_table.rs
Normal file
76
sr_download/src/db_part/defines/main_data_table.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
use sea_orm::sea_query::{ColumnDef, Table};
|
||||||
|
use sea_orm::{DatabaseBackend, DeriveIden, EnumIter, Iterable, Statement};
|
||||||
|
|
||||||
|
use super::TEXT_DATA_MAX_LEN;
|
||||||
|
|
||||||
|
pub fn main_table() -> Statement {
|
||||||
|
let mut table = Table::create();
|
||||||
|
table
|
||||||
|
.table(MainData::Table)
|
||||||
|
.if_not_exists()
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(MainData::SaveId)
|
||||||
|
.integer()
|
||||||
|
.not_null()
|
||||||
|
.primary_key(),
|
||||||
|
)
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(MainData::SaveType)
|
||||||
|
.enumeration(SaveTypeEnum, SaveTypeVariants::iter())
|
||||||
|
.not_null(),
|
||||||
|
)
|
||||||
|
// blake hash:
|
||||||
|
// ad4a4c99162bac6766fa9a658651688c6db4955922f8e5447cb14ad1c1b05825
|
||||||
|
// len = 64
|
||||||
|
.col(ColumnDef::new(MainData::BlakeHash).char_len(64).not_null())
|
||||||
|
.col(ColumnDef::new(MainData::Len).big_integer().not_null())
|
||||||
|
.col(ColumnDef::new(MainData::ShortData).string_len(TEXT_DATA_MAX_LEN as u32))
|
||||||
|
.col(ColumnDef::new(MainData::XmlTested).boolean().null());
|
||||||
|
DatabaseBackend::Postgres.build(&table)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(DeriveIden)]
|
||||||
|
#[sea_orm(iden = "save_type")]
|
||||||
|
pub struct SaveTypeEnum;
|
||||||
|
|
||||||
|
#[derive(DeriveIden, EnumIter)]
|
||||||
|
pub enum SaveTypeVariants {
|
||||||
|
#[sea_orm(iden = "ship")]
|
||||||
|
/// 飞船
|
||||||
|
Ship,
|
||||||
|
#[sea_orm(iden = "save")]
|
||||||
|
/// 存档
|
||||||
|
Save,
|
||||||
|
#[sea_orm(iden = "unknown")]
|
||||||
|
/// 未知 (预计用作下载中的占位符)
|
||||||
|
Unknown,
|
||||||
|
#[sea_orm(iden = "none")]
|
||||||
|
/// 没有存档 (这个 Id 为 空)
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(DeriveIden)]
|
||||||
|
pub enum MainData {
|
||||||
|
/// 表
|
||||||
|
Table,
|
||||||
|
/// 这个存档的 Id
|
||||||
|
SaveId,
|
||||||
|
/// 存档类型
|
||||||
|
/// - ship: 船
|
||||||
|
/// - save: 存档
|
||||||
|
/// - unknown: 未知 (没下载呢)
|
||||||
|
/// - none: 没有存档 (这个 Id 为 空)
|
||||||
|
SaveType,
|
||||||
|
/// blake3 hash
|
||||||
|
/// len = 64
|
||||||
|
/// 64 位的 blake3 hash
|
||||||
|
BlakeHash,
|
||||||
|
/// 存档的长度 (用来过滤太长的存档)
|
||||||
|
/// 长度 > 1024 的存档会存在隔壁表
|
||||||
|
Len,
|
||||||
|
/// 如果长度 < 1024
|
||||||
|
/// 那就直接存在这
|
||||||
|
ShortData,
|
||||||
|
/// 数据是不是合法的 XML 数据
|
||||||
|
XmlTested,
|
||||||
|
}
|
44
sr_download/src/db_part/defines/ships_table.rs
Normal file
44
sr_download/src/db_part/defines/ships_table.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use sea_orm::sea_query::{ColumnDef, ForeignKey, Table};
|
||||||
|
use sea_orm::{DatabaseBackend, DeriveIden, ForeignKeyAction, Iden, Statement};
|
||||||
|
|
||||||
|
use super::main_data_table::MainData;
|
||||||
|
|
||||||
|
pub fn ships_table() -> Statement {
|
||||||
|
let mut table = Table::create();
|
||||||
|
table
|
||||||
|
.table(Ships::Table)
|
||||||
|
.if_not_exists()
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(Ships::SaveId)
|
||||||
|
.integer()
|
||||||
|
.not_null()
|
||||||
|
.primary_key(),
|
||||||
|
)
|
||||||
|
.foreign_key(
|
||||||
|
ForeignKey::create()
|
||||||
|
.name(Ships::SaveId.to_string())
|
||||||
|
.to(MainData::Table, MainData::SaveId)
|
||||||
|
.from(Ships::Table, Ships::SaveId)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade),
|
||||||
|
);
|
||||||
|
DatabaseBackend::Postgres.build(&table)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(DeriveIden)]
|
||||||
|
pub enum Ships {
|
||||||
|
Table,
|
||||||
|
/// 存档 ID
|
||||||
|
SaveId,
|
||||||
|
/// 解析过的 xml 数据
|
||||||
|
/// 这样就不用每次解析一遍了
|
||||||
|
XmlData,
|
||||||
|
/// 飞船质量
|
||||||
|
/// (按照原版数据计算, 经过比例缩放)
|
||||||
|
Mass,
|
||||||
|
/// 是否检查到了使用 mod 的迹象
|
||||||
|
/// 比如 多 pod 之类的
|
||||||
|
ModUsed,
|
||||||
|
/// 是否有 docxConnection (xml使用迹象)
|
||||||
|
DocxConnectionUsed,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user