use diesel::prelude::*; use diesel::dsl::{AsSelect, Filter, Select, Eq, auto_type}; use diesel::sqlite::Sqlite; use futures::task::waker; use serde::{Deserialize, Serialize}; use crate::schema::{artists, collections, tracks}; use crate::library::Library; type All = Select>; #[derive(Debug, Clone, Queryable, Selectable, Identifiable)] #[diesel(table_name = artists)] #[diesel(check_for_backend(diesel::sqlite::Sqlite))] pub struct Artist { pub id: i32, pub original_name: String, pub display_name: String, } impl Artist { pub fn all() -> All { artists::table.select(Self::as_select()) } #[auto_type(no_type_alias)] pub fn by_id(id: i32) -> _ { let all: All = Self::all(); let filter = artists::id.eq(id); all.filter(filter) } #[auto_type(no_type_alias)] pub fn by_original_name(name: &str) -> _ { let all: All = Self::all(); let filter = artists::original_name.eq(name); all.filter(filter) } } #[derive(Debug, Clone, Queryable, Selectable, Identifiable)] #[diesel(table_name = collections)] #[diesel(check_for_backend(diesel::sqlite::Sqlite))] pub struct Collection { pub id: i32, pub artist_id: Option, pub collection_type: String, pub original_name: String, pub display_name: String, } impl Collection { pub fn all() -> All { collections::table.select(Self::as_select()) } #[auto_type(no_type_alias)] pub fn by_id(id: i32) -> _ { let all: All = Self::all(); let filter = collections::id.eq(id); all.filter(filter) } #[auto_type(no_type_alias)] pub fn by_original_name(name: &str) -> _ { let all: All = Self::all(); let filter = collections::original_name.eq(name); all.filter(filter) } } #[derive( Debug, Clone, Queryable, Selectable, Identifiable, Associations, Serialize, Deserialize, )] #[diesel(table_name = tracks)] #[diesel(belongs_to(Artist, foreign_key = artist_id))] #[diesel(belongs_to(Collection, foreign_key = collection_id))] #[diesel(check_for_backend(diesel::sqlite::Sqlite))] pub struct Track { pub id: i32, pub file_path: String, pub artist_id: Option, pub collection_id: Option, pub original_title: Option, pub display_title: Option, pub track_number: Option, pub genre: Option, pub track_datetime: Option, pub length_sec: i32, } impl Track { pub fn all() -> All { tracks::table.select(Self::as_select()) } #[auto_type(no_type_alias)] pub fn by_id(id: i32) -> _ { let all: All = Self::all(); let filter = tracks::id.eq(id); all.filter(filter) } #[auto_type(no_type_alias)] pub fn by_original_title(title: &str) -> _ { let all: All = Self::all(); let filter = tracks::original_title.eq(title); all.filter(filter) } } #[derive(Debug, Serialize)] pub struct DetailedArtist { pub id: i32, pub original_name: String, pub display_name: String, } #[derive(Debug, Serialize)] pub struct DetailedCollection<'a> { pub id: i32, pub artist: Option<&'a DetailedArtist>, pub collection_type: String, pub original_name: String, pub display_name: String, } #[derive(Debug, Serialize)] pub struct DetailedTrack<'a> { pub id: i32, pub file_path: String, pub artist: Option<&'a DetailedArtist>, // a collection could be under another artist (e.g. mixtapes) pub collection: Option<&'a DetailedCollection<'a>>, pub original_title: Option, pub display_title: Option, pub track_number: Option, pub genre: Option, pub track_datetime: Option, pub length_sec: i32, } #[derive(Debug, Clone, Insertable)] #[diesel(table_name = artists)] pub struct NewArtist<'a> { pub original_name: &'a str, pub display_name: &'a str, } #[derive(Debug, Clone, Insertable)] #[diesel(table_name = collections)] pub struct NewCollection<'a> { pub artist_id: Option, pub collection_type: &'a str, pub original_name: &'a str, pub display_name: &'a str, } #[derive(Debug, Clone, Insertable)] #[diesel(table_name = tracks)] pub struct NewTrack<'a> { pub file_path: &'a str, pub artist_id: Option, pub collection_id: Option, pub original_title: Option<&'a str>, pub display_title: Option<&'a str>, pub track_number: Option, pub genre: Option<&'a str>, pub track_datetime: Option<&'a str>, pub length_sec: i32, }