feat(infra): schedule history list, get-by-id, delete-after methods
This commit is contained in:
@@ -4,6 +4,7 @@ use chrono::{DateTime, Utc};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use domain::{BlockId, ChannelId, DomainError, DomainResult, GeneratedSchedule, MediaItemId, PlaybackRecord, ScheduleRepository};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::mapping::{map_schedule, LastSlotRow, PlaybackRecordRow, ScheduleRow, SlotRow};
|
||||
|
||||
@@ -183,6 +184,77 @@ impl ScheduleRepository for SqliteScheduleRepository {
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
async fn list_schedule_history(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
) -> DomainResult<Vec<GeneratedSchedule>> {
|
||||
let rows: Vec<ScheduleRow> = sqlx::query_as(
|
||||
"SELECT id, channel_id, valid_from, valid_until, generation \
|
||||
FROM generated_schedules WHERE channel_id = ? ORDER BY generation DESC",
|
||||
)
|
||||
.bind(channel_id.to_string())
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
|
||||
|
||||
rows.into_iter()
|
||||
.map(|r| map_schedule(r, vec![]))
|
||||
.collect()
|
||||
}
|
||||
|
||||
async fn get_schedule_by_id(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
schedule_id: Uuid,
|
||||
) -> DomainResult<Option<GeneratedSchedule>> {
|
||||
let row: Option<ScheduleRow> = sqlx::query_as(
|
||||
"SELECT id, channel_id, valid_from, valid_until, generation \
|
||||
FROM generated_schedules WHERE id = ? AND channel_id = ?",
|
||||
)
|
||||
.bind(schedule_id.to_string())
|
||||
.bind(channel_id.to_string())
|
||||
.fetch_optional(&self.pool)
|
||||
.await
|
||||
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
|
||||
|
||||
match row {
|
||||
None => Ok(None),
|
||||
Some(r) => {
|
||||
let slots = self.fetch_slots(&r.id).await?;
|
||||
Some(map_schedule(r, slots)).transpose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_schedules_after(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
target_generation: u32,
|
||||
) -> DomainResult<()> {
|
||||
let target_gen = target_generation as i64;
|
||||
let ch = channel_id.to_string();
|
||||
|
||||
sqlx::query(
|
||||
"DELETE FROM playback_records WHERE channel_id = ? AND generation > ?",
|
||||
)
|
||||
.bind(&ch)
|
||||
.bind(target_gen)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
|
||||
|
||||
sqlx::query(
|
||||
"DELETE FROM generated_schedules WHERE channel_id = ? AND generation > ?",
|
||||
)
|
||||
.bind(&ch)
|
||||
.bind(target_gen)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn save_playback_record(&self, record: &PlaybackRecord) -> DomainResult<()> {
|
||||
sqlx::query(
|
||||
r#"
|
||||
|
||||
Reference in New Issue
Block a user