From 93b74321bf30ef33e82b0e9337d8cc3b6ca6e663 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Mon, 17 Feb 2025 19:19:25 +0100 Subject: feat(yt/storage/migrate): Add db version One This version finally removes the weird `is_changing` flag (which was most of the time an elaborate alias for something like: "is being watched".) Additionally, this change brings in the groundwork to move the mpv playlist tracking from in-memory to the database. --- yt/src/storage/migrate/mod.rs | 24 ++++++++++++++++++++++-- yt/src/storage/migrate/sql/01_zero_to_one.sql | 19 +++++++++++++++++++ yt/src/storage/video_database/mod.rs | 21 +++++++++++++++++++-- 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 yt/src/storage/migrate/sql/01_zero_to_one.sql diff --git a/yt/src/storage/migrate/mod.rs b/yt/src/storage/migrate/mod.rs index 4e956de..9696616 100644 --- a/yt/src/storage/migrate/mod.rs +++ b/yt/src/storage/migrate/mod.rs @@ -18,8 +18,11 @@ pub enum DbVersion { /// The first database version. /// Introduced: 2025-02-16. Zero, + + /// Introduced: 2025-02-17. + One, } -const CURRENT_VERSION: DbVersion = DbVersion::Zero; +const CURRENT_VERSION: DbVersion = DbVersion::One; async fn set_db_version( tx: &mut Transaction<'_, Sqlite>, @@ -59,13 +62,16 @@ impl DbVersion { match self { DbVersion::Empty => unreachable!("A empty version does not have an associated integer"), DbVersion::Zero => 0, + DbVersion::One => 1, } } fn from_db(number: i64, namespace: &str) -> Result { match (number, namespace) { (0, "yt") => Ok(DbVersion::Zero), + (1, "yt") => Ok(DbVersion::One), (0, other) => bail!("Db version is Zero, but got unknown namespace: '{other}'"), + (1, other) => bail!("Db version is One, but got unknown namespace: '{other}'"), (other, "yt") => bail!("Got unkown version for 'yt' namespace: {other}"), (num, nasp) => bail!("Got unkown version number ({num}) and namespace ('{nasp}')"), @@ -92,10 +98,24 @@ impl DbVersion { Box::pin(Self::Zero.update(app)).await } - // This is the current version DbVersion::Zero => { + let mut tx = app.database.begin().await?; debug!("Migrate: Zero -> One"); + sqlx::raw_sql(include_str!("./sql/01_zero_to_one.sql")) + .execute(&mut *tx) + .await?; + + set_db_version(&mut tx, Some(DbVersion::Zero), DbVersion::One).await?; + + tx.commit().await?; + Box::pin(Self::One.update(app)).await + } + + // This is the current_version + DbVersion::One => { + debug!("Migrate: One -> Two"); + assert_eq!(self, CURRENT_VERSION); assert_eq!(self, get_version(app).await?); Ok(()) diff --git a/yt/src/storage/migrate/sql/01_zero_to_one.sql b/yt/src/storage/migrate/sql/01_zero_to_one.sql new file mode 100644 index 0000000..42c3b02 --- /dev/null +++ b/yt/src/storage/migrate/sql/01_zero_to_one.sql @@ -0,0 +1,19 @@ +-- Is the video currently in a playlist? +ALTER TABLE videos ADD in_playlist INTEGER NOT NULL DEFAULT 0 CHECK (in_playlist IN (0, 1)); +UPDATE videos SET in_playlist = 0; + +-- Is it 'focused' (i.e., the select video)? +-- Only of video should be focused at a time. +ALTER TABLE videos +ADD COLUMN is_focused INTEGER NOT NULL DEFAULT 0 +CHECK (is_focused IN (0, 1)); +UPDATE videos SET is_focused = 0; + +-- The progress the user made in watching the video. +ALTER TABLE videos ADD watch_progress INTEGER NOT NULL DEFAULT 0 CHECK (watch_progress <= duration); + +-- Assume, that the user has watched the video to end, if it is marked as watched +UPDATE videos SET watch_progress = duration WHERE status = 3; +UPDATE videos SET watch_progress = 0 WHERE status != 3; + +ALTER TABLE videos DROP COLUMN status_change; diff --git a/yt/src/storage/video_database/mod.rs b/yt/src/storage/video_database/mod.rs index aff57b9..afcd179 100644 --- a/yt/src/storage/video_database/mod.rs +++ b/yt/src/storage/video_database/mod.rs @@ -26,16 +26,33 @@ pub struct Video { pub duration: Option, pub extractor_hash: ExtractorHash, pub last_status_change: i64, + /// The associated subscription this video was fetched from (null, when the video was `add`ed) pub parent_subscription_name: Option, pub priority: i64, pub publish_date: Option, pub status: VideoStatus, - /// The video is currently changing its state (for example from being `SELECT` to being `CACHE`) - pub status_change: bool, pub thumbnail_url: Option, pub title: String, pub url: Url, + + pub in_playlist: InPlaylist, + + /// The seconds the user has already watched the video + pub watch_progress: u32, +} + +#[derive(Clone, Copy, Debug)] +pub enum InPlaylist { + /// The video is not in the playlist. + Excluded, + + /// The video is in the playlist, but not visible + Hidden, + + /// It is visible and focused. + /// Only one video should have this state. + Focused, } #[derive(Debug)] -- cgit 1.4.1