use std::collections::HashSet; use sqlite::OpenFlags; use crate::artifacts::{Album, Artifact, Artist, SourceID, Track}; #[derive(Debug)] #[allow(unused)] pub enum MixxxError { Sql(sqlite::Error) } impl From for MixxxError { fn from(value: sqlite::Error) -> Self { Self::Sql(value) } } pub struct MixxxDB(()); impl MixxxDB { pub fn load(playlist_name: &str) -> Result, MixxxError> { let mut ret = vec![]; log::info!("Loading Mixxx playlist {}", playlist_name); let connection = sqlite::Connection::open_thread_safe_with_flags("mixxxdb.sqlite", OpenFlags::new().with_read_only())?; let query = "SELECT id FROM Playlists WHERE name = ? ORDER BY id DESC LIMIT 1"; let mut statement = connection.prepare(query)?; statement.bind((1, playlist_name))?; statement.next()?; let latest_id = statement.read::("id")?; let query = "SELECT title, artist, album, comment, url, bpm FROM library LEFT JOIN PlaylistTracks ON PlaylistTracks.track_id = library.id WHERE PlaylistTracks.playlist_id = ? ORDER BY position"; for track in connection.prepare(query)?.into_iter().bind((1, latest_id))? { let track = track?; let title = track.try_read::<&str, _>("title").unwrap_or("Untitled Track"); let artist = track.try_read::<&str, _>("artist").unwrap_or("Unknown Artist"); let album = track.try_read::<&str, _>("album").unwrap_or("Unknown Album"); let bpm = track.try_read::("bpm").unwrap_or(0.); ret.push(Artifact::Track(Track { artist: Some(artist.into()), album: Some(album.into()), title: title.into(), bpm: Some(bpm), sources: HashSet::from([SourceID::Mixxx]), ..Default::default() })); ret.push(Artifact::Album(Album { artist: artist.into(), title: album.into(), sources: HashSet::from([SourceID::Mixxx]), ..Default::default() })); ret.push(Artifact::Artist(Artist { name: artist.into(), sources: HashSet::from([SourceID::Mixxx]), ..Default::default() })); } Ok(ret) } }