Skip to content

refactor(core): preserve playlist data during SQLite schema drift recovery#932

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/deprecate-file-storage-migrate-to-sqlite
Draft

refactor(core): preserve playlist data during SQLite schema drift recovery#932
Copilot wants to merge 2 commits into
mainfrom
copilot/deprecate-file-storage-migrate-to-sqlite

Conversation

Copilot AI commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Playlist data should survive schema drift, unlike cache-like tables (library/media/progress). This change moves recovery from “recreate DB” to table-level reconciliation and simplifies playlist item persistence to only durable identifiers.

  • Database recovery strategy

    • Reworked DatabaseService initialization to detect per-table schema drift via PRAGMA table_info.
    • Replaces only drifted cache tables (library_folders, media_records, playback_progress).
    • Migrates playlists and playlist_items through *_new tables to preserve playlist data.
    • Keeps full DB file deletion as last-resort fallback only.
  • Playlist schema simplification

    • Reduced playlist_items to minimal durable fields:
      • id, playlist_id, path, sort_order
    • Removed duplicated metadata columns previously copied from media records.
  • Runtime data composition for playlists

    • Updated PlaylistService writes to persist only path/order.
    • Updated reads to hydrate playlist item metadata by joining playlist_items with media_records on path.
    • Added safe fallback title derivation from path when joined metadata is missing.
  • Internal DB DTOs (no tuple transport)

    • Introduced internal DTOs in Screenbox.Core (DatabaseDtos.cs) for cache load/write and SQL parameter transport.
    • Refactored LibraryService DB transport paths to use DTOs instead of tuple-based contracts.
SELECT pi.path,
       mr.title, mr.media_type, mr.date_added, mr.duration_ticks, mr.year,
       mr.artist, mr.album, mr.album_artist, mr.composers, mr.genre, mr.track_number,
       mr.subtitle, mr.producers, mr.writers
FROM playlist_items pi
LEFT JOIN media_records mr ON mr.path = pi.path
WHERE pi.playlist_id = @pid
ORDER BY pi.sort_order, pi.id;

…lite)

- Add IDatabaseService/DatabaseService with 5-table SQLite schema
- Register DatabaseService as singleton in DI container
- Migrate LibraryService from protobuf .bin files to SQLite media_records table
- Migrate PlaybackProgressTracker from last_positions.bin to playback_progress table
- Migrate PlaylistService from JSON files to playlists/playlist_items tables
- Strip all [ProtoContract]/[ProtoMember] annotations from model classes
- Delete PersistentStorageLibrary.cs (now redundant)
- Remove SaveToDiskAsync/LoadFromDiskAsync generic methods from IFilesService/FilesService
- Remove protobuf-net package, add Microsoft.Data.Sqlite 8.0.6
- Delete stale .bin and Playlists folder on startup in App.xaml.cs
- Update docs/PROJECT_STRUCTURE.md to reflect SQLite migration

Co-authored-by: huynhsontung <31434093+huynhsontung@users.noreply.github.com>
Co-authored-by: huynhsontung <31434093+huynhsontung@users.noreply.github.com>
Copilot AI changed the title feat: replace Protobuf/JSON file storage with SQLite cache layer refactor(core): preserve playlist data during SQLite schema drift recovery Jun 16, 2026
Copilot AI requested a review from huynhsontung June 16, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants