From a7d533d5800c445b6a386c6a9e8830f656a5ede3 Mon Sep 17 00:00:00 2001 From: cucadmuh <49571317+cucadmuh@users.noreply.github.com> Date: Sat, 30 May 2026 00:08:05 +0300 Subject: [PATCH] chore(library): squash pre-RC migrations into single 001_initial baseline (#919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(library): squash pre-RC migrations into single 001_initial baseline Library SQLite never shipped in a release, so fold migrations 002–008 into 001_initial.sql and drop the dev-only mood-facts purge (009). Sets LIBRARY_DB_SCHEMA_VERSION to 1 for the RC baseline; analysis migrations unchanged. * docs: note library migration squash in CHANGELOG and credits (PR #919) * fix(library): keep migration SQL files on disk after RC baseline squash Restore 002–009 as historical dev migration scripts. Runner still ships only 001 for fresh installs; existing DBs with applied versions are unchanged. Drop credits/CHANGELOG note for this small internal change. --- .../migrations/001_initial.sql | 48 +++++++++++++++++++ .../crates/psysonic-library/src/store.rs | 28 ++--------- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src-tauri/crates/psysonic-library/migrations/001_initial.sql b/src-tauri/crates/psysonic-library/migrations/001_initial.sql index f1a0c8f8..0ef06d66 100644 --- a/src-tauri/crates/psysonic-library/migrations/001_initial.sql +++ b/src-tauri/crates/psysonic-library/migrations/001_initial.sql @@ -45,6 +45,7 @@ CREATE TABLE sync_state ( initial_sync_cursor_json TEXT NOT NULL DEFAULT '{}', sync_phase TEXT NOT NULL DEFAULT 'idle', last_error TEXT, + n1_bulk_unreliable INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (server_id, library_scope) ); @@ -108,6 +109,7 @@ CREATE TABLE track ( content_hash TEXT, server_updated_at INTEGER, server_created_at INTEGER, + resync_gen INTEGER NOT NULL DEFAULT 0, deleted INTEGER NOT NULL DEFAULT 0, synced_at INTEGER NOT NULL, raw_json TEXT NOT NULL, @@ -233,6 +235,19 @@ CREATE TABLE canonical_enrichment_link ( FOREIGN KEY (canonical_id) REFERENCES canonical_track(id) ); +CREATE TABLE play_session ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + server_id TEXT NOT NULL, + track_id TEXT NOT NULL, + started_at_ms INTEGER NOT NULL, + listened_sec REAL NOT NULL, + position_max_sec REAL NOT NULL, + completion TEXT NOT NULL, + end_reason TEXT NOT NULL, + FOREIGN KEY (server_id, track_id) REFERENCES track(server_id, id), + CHECK (completion IN ('partial', 'full')) +); + CREATE INDEX idx_track_album ON track(server_id, album_id) WHERE deleted = 0; CREATE INDEX idx_track_artist ON track(server_id, artist_id) WHERE deleted = 0; CREATE INDEX idx_track_updated ON track(server_id, server_updated_at DESC) WHERE deleted = 0; @@ -245,3 +260,36 @@ CREATE INDEX idx_track_artifact_lookup ON track_artifact(server_id, track_id, ar CREATE INDEX idx_track_offline_hash ON track_offline(server_id, content_hash); CREATE INDEX idx_track_id_history_new ON track_id_history(server_id, new_id); CREATE INDEX idx_canonical_identity_lookup ON canonical_identity(kind, value); + +CREATE INDEX idx_track_remap_path + ON track(server_id, server_path) + WHERE deleted = 0 AND server_path IS NOT NULL AND server_path != ''; + +CREATE INDEX idx_track_remap_hash + ON track(server_id, content_hash) + WHERE deleted = 0 AND content_hash IS NOT NULL AND content_hash != ''; + +CREATE INDEX idx_track_title + ON track(server_id, title COLLATE NOCASE) + WHERE deleted = 0; + +CREATE INDEX idx_track_genre + ON track(server_id, genre COLLATE NOCASE) + WHERE deleted = 0 AND genre IS NOT NULL; + +CREATE INDEX idx_track_year + ON track(server_id, year) + WHERE deleted = 0 AND year IS NOT NULL; + +CREATE INDEX idx_play_session_server_time + ON play_session(server_id, started_at_ms DESC); + +CREATE INDEX idx_play_session_track + ON play_session(server_id, track_id, started_at_ms DESC); + +CREATE INDEX idx_play_session_started + ON play_session(started_at_ms DESC); + +CREATE INDEX idx_track_fact_mood_tag + ON track_fact(server_id, fact_kind, value_text, track_id) + WHERE fact_kind = 'mood_tag'; diff --git a/src-tauri/crates/psysonic-library/src/store.rs b/src-tauri/crates/psysonic-library/src/store.rs index 7088ab7a..27335b32 100644 --- a/src-tauri/crates/psysonic-library/src/store.rs +++ b/src-tauri/crates/psysonic-library/src/store.rs @@ -9,7 +9,7 @@ use tauri::Manager; /// Current head of the embedded migrations. Bump each time a new /// `migrations/NNN_*.sql` is added. -pub const LIBRARY_DB_SCHEMA_VERSION: i64 = 9; +pub const LIBRARY_DB_SCHEMA_VERSION: i64 = 1; /// Lowest applied schema version the current code can advance from purely /// additively. If a DB carries a version below this, the breaking-bump hook @@ -22,33 +22,10 @@ pub const LIBRARY_DB_SCHEMA_VERSION: i64 = 9; pub const LIBRARY_DB_MIN_COMPATIBLE_VERSION: i64 = 1; pub(crate) const INITIAL_SQL: &str = include_str!("../migrations/001_initial.sql"); -const MIGRATION_002_N1_BULK_UNRELIABLE: &str = - include_str!("../migrations/002_n1_bulk_unreliable.sql"); -const MIGRATION_003_TRACK_REMAP_INDEXES: &str = - include_str!("../migrations/003_track_remap_indexes.sql"); -const MIGRATION_004_TRACK_TITLE_INDEX: &str = - include_str!("../migrations/004_track_title_index.sql"); -const MIGRATION_005_TRACK_GENRE_YEAR_INDEXES: &str = - include_str!("../migrations/005_track_genre_year_indexes.sql"); -const MIGRATION_006_PLAY_SESSION: &str = include_str!("../migrations/006_play_session.sql"); -const MIGRATION_007_RESYNC_GEN: &str = include_str!("../migrations/007_resync_gen.sql"); -const MIGRATION_008_MOOD_TAG_INDEX: &str = include_str!("../migrations/008_mood_tag_index.sql"); -const MIGRATION_009_PURGE_MOOD_FACTS: &str = - include_str!("../migrations/009_purge_mood_facts.sql"); /// Embedded migrations. Ordered ascending by `version`; the runner sorts /// defensively before applying so the source order can stay readable. -const MIGRATIONS: &[(i64, &str)] = &[ - (1, INITIAL_SQL), - (2, MIGRATION_002_N1_BULK_UNRELIABLE), - (3, MIGRATION_003_TRACK_REMAP_INDEXES), - (4, MIGRATION_004_TRACK_TITLE_INDEX), - (5, MIGRATION_005_TRACK_GENRE_YEAR_INDEXES), - (6, MIGRATION_006_PLAY_SESSION), - (7, MIGRATION_007_RESYNC_GEN), - (8, MIGRATION_008_MOOD_TAG_INDEX), - (9, MIGRATION_009_PURGE_MOOD_FACTS), -]; +const MIGRATIONS: &[(i64, &str)] = &[(1, INITIAL_SQL)]; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum MigrationOutcome { @@ -553,6 +530,7 @@ mod tests { "track_fact", "track_id_history", "track_offline", + "play_session", ] { assert!( tables.iter().any(|t| t == expected),