refactor: database structure

This commit is contained in:
2025-01-03 04:42:42 +08:00
parent 70932900cd
commit 917af7320e
462 changed files with 1223 additions and 724 deletions

118
apps/recorder/src/models/episodes.rs Normal file → Executable file
View File

@@ -1,10 +1,10 @@
use std::sync::Arc;
use loco_rs::app::AppContext;
use sea_orm::{entity::prelude::*, sea_query::OnConflict, ActiveValue};
use sea_orm::{entity::prelude::*, sea_query::OnConflict, ActiveValue, FromJsonQueryResult};
use serde::{Deserialize, Serialize};
use super::bangumi;
pub use super::entities::episodes::*;
use super::{bangumi, query::InsertManyReturningExt, subscription_episode};
use crate::{
app::AppContextExt,
extract::{
@@ -13,6 +13,92 @@ use crate::{
},
};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult, Default)]
pub struct EpisodeExtra {
pub name_zh: Option<String>,
pub s_name_zh: Option<String>,
pub name_en: Option<String>,
pub s_name_en: Option<String>,
pub name_jp: Option<String>,
pub s_name_jp: Option<String>,
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "episodes")]
pub struct Model {
pub created_at: DateTime,
pub updated_at: DateTime,
#[sea_orm(primary_key)]
pub id: i32,
#[sea_orm(indexed)]
pub mikan_episode_id: Option<String>,
pub raw_name: String,
pub display_name: String,
pub bangumi_id: i32,
pub subscriber_id: i32,
pub save_path: Option<String>,
pub resolution: Option<String>,
pub season: i32,
pub season_raw: Option<String>,
pub fansub: Option<String>,
pub poster_link: Option<String>,
pub episode_index: i32,
pub homepage: Option<String>,
pub subtitle: Option<Vec<String>>,
#[sea_orm(default = "false")]
pub deleted: bool,
pub source: Option<String>,
pub extra: EpisodeExtra,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::subscribers::Entity",
from = "Column::SubscriberId",
to = "super::subscribers::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Subscriber,
#[sea_orm(
belongs_to = "super::bangumi::Entity",
from = "Column::BangumiId",
to = "super::bangumi::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Bangumi,
#[sea_orm(has_many = "super::subscriptions::Entity")]
Subscriptions,
#[sea_orm(has_one = "super::downloads::Entity")]
Downloads,
}
impl Related<super::bangumi::Entity> for Entity {
fn to() -> RelationDef {
Relation::Bangumi.def()
}
}
impl Related<super::downloads::Entity> for Entity {
fn to() -> RelationDef {
Relation::Downloads.def()
}
}
impl Related<super::subscriptions::Entity> for Entity {
fn to() -> RelationDef {
Relation::Subscriptions.def()
}
}
impl Related<super::subscribers::Entity> for Entity {
fn to() -> RelationDef {
Relation::Subscriber.def()
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct MikanEpsiodeCreation {
pub episode: MikanEpisodeMeta,
@@ -22,6 +108,7 @@ pub struct MikanEpsiodeCreation {
impl Model {
pub async fn add_episodes(
ctx: &AppContext,
subscription_id: i32,
creations: impl IntoIterator<Item = MikanEpsiodeCreation>,
) -> eyre::Result<()> {
let db = &ctx.db;
@@ -35,13 +122,33 @@ impl Model {
})
.flatten();
Entity::insert_many(new_episode_active_modes)
let inserted_episodes = Entity::insert_many(new_episode_active_modes)
.on_conflict(
OnConflict::columns([Column::BangumiId, Column::MikanEpisodeId])
.do_nothing()
.to_owned(),
)
.on_empty_do_nothing()
.exec_with_returning_columns(db, [Column::Id])
.await?
.into_iter()
.flat_map(|r| r.try_get_many_by_index::<i32>());
let insert_subscription_episode_links = inserted_episodes.into_iter().map(|episode_id| {
subscription_episode::ActiveModel::from_subscription_and_episode(
subscription_id,
episode_id,
)
});
subscription_episode::Entity::insert_many(insert_subscription_episode_links)
.on_conflict(
OnConflict::columns([
subscription_episode::Column::SubscriptionId,
subscription_episode::Column::EpisodeId,
])
.do_nothing()
.to_owned(),
)
.exec(db)
.await?;
@@ -72,7 +179,6 @@ impl ActiveModel {
raw_name: ActiveValue::Set(item.episode_title.clone()),
display_name: ActiveValue::Set(item.episode_title.clone()),
bangumi_id: ActiveValue::Set(bgm.id),
subscription_id: ActiveValue::Set(bgm.subscription_id),
subscriber_id: ActiveValue::Set(bgm.subscriber_id),
resolution: ActiveValue::Set(raw_meta.resolution),
season: ActiveValue::Set(if raw_meta.season > 0 {