Enable fetch to apply modifications to the database #221

Merged
wojtek merged 14 commits from 189---enable-fetch-to-apply-modifications-to-the-database into main 2024-09-29 10:44:38 +02:00
14 changed files with 41 additions and 54 deletions
Showing only changes of commit 50779e2a32 - Show all commits

View File

@ -173,7 +173,7 @@ impl SortCommand {
SortCommand::Set(artist_sort_value) => music_hoard SortCommand::Set(artist_sort_value) => music_hoard
.set_artist_sort( .set_artist_sort(
ArtistId::new(artist_name), ArtistId::new(artist_name),
ArtistId::new(artist_sort_value.sort), String::from(artist_sort_value.sort),
) )
.expect("faild to set artist sort name"), .expect("faild to set artist sort name"),
SortCommand::Clear => music_hoard SortCommand::Clear => music_hoard

View File

@ -21,7 +21,7 @@ pub struct Artist {
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct ArtistMeta { pub struct ArtistMeta {
pub id: ArtistId, pub id: ArtistId,
pub sort: Option<ArtistId>, pub sort: Option<String>,
pub musicbrainz: MbRefOption<MbArtistRef>, pub musicbrainz: MbRefOption<MbArtistRef>,
pub properties: HashMap<String, Vec<String>>, pub properties: HashMap<String, Vec<String>>,
} }
@ -80,11 +80,11 @@ impl ArtistMeta {
} }
} }
pub fn get_sort_key(&self) -> (&ArtistId,) { pub fn get_sort_key(&self) -> (&str,) {
(self.sort.as_ref().unwrap_or(&self.id),) (self.sort.as_ref().unwrap_or(&self.id.name),)
} }
pub fn set_sort_key<SORT: Into<ArtistId>>(&mut self, sort: SORT) { pub fn set_sort_key<S: Into<String>>(&mut self, sort: S) {
self.sort = Some(sort.into()); self.sort = Some(sort.into());
} }
@ -207,14 +207,14 @@ mod tests {
#[test] #[test]
fn artist_sort_set_clear() { fn artist_sort_set_clear() {
let artist_id = ArtistId::new("an artist"); let artist_id = ArtistId::new("an artist");
let sort_id_1 = ArtistId::new("sort id 1"); let sort_id_1 = String::from("sort id 1");
let sort_id_2 = ArtistId::new("sort id 2"); let sort_id_2 = String::from("sort id 2");
let mut artist = Artist::new(&artist_id.name); let mut artist = Artist::new(&artist_id.name);
assert_eq!(artist.meta.id, artist_id); assert_eq!(artist.meta.id, artist_id);
assert_eq!(artist.meta.sort, None); assert_eq!(artist.meta.sort, None);
assert_eq!(artist.meta.get_sort_key(), (&artist_id,)); assert_eq!(artist.meta.get_sort_key(), (artist_id.name.as_str(),));
assert!(artist.meta < ArtistMeta::new(sort_id_1.clone())); assert!(artist.meta < ArtistMeta::new(sort_id_1.clone()));
assert!(artist.meta < ArtistMeta::new(sort_id_2.clone())); assert!(artist.meta < ArtistMeta::new(sort_id_2.clone()));
assert!(artist < Artist::new(sort_id_1.clone())); assert!(artist < Artist::new(sort_id_1.clone()));
@ -224,7 +224,7 @@ mod tests {
assert_eq!(artist.meta.id, artist_id); assert_eq!(artist.meta.id, artist_id);
assert_eq!(artist.meta.sort.as_ref(), Some(&sort_id_1)); assert_eq!(artist.meta.sort.as_ref(), Some(&sort_id_1));
assert_eq!(artist.meta.get_sort_key(), (&sort_id_1,)); assert_eq!(artist.meta.get_sort_key(), (sort_id_1.as_str(),));
assert!(artist.meta > ArtistMeta::new(artist_id.clone())); assert!(artist.meta > ArtistMeta::new(artist_id.clone()));
assert!(artist.meta < ArtistMeta::new(sort_id_2.clone())); assert!(artist.meta < ArtistMeta::new(sort_id_2.clone()));
assert!(artist > Artist::new(artist_id.clone())); assert!(artist > Artist::new(artist_id.clone()));
@ -234,7 +234,7 @@ mod tests {
assert_eq!(artist.meta.id, artist_id); assert_eq!(artist.meta.id, artist_id);
assert_eq!(artist.meta.sort.as_ref(), Some(&sort_id_2)); assert_eq!(artist.meta.sort.as_ref(), Some(&sort_id_2));
assert_eq!(artist.meta.get_sort_key(), (&sort_id_2,)); assert_eq!(artist.meta.get_sort_key(), (sort_id_2.as_str(),));
assert!(artist.meta > ArtistMeta::new(artist_id.clone())); assert!(artist.meta > ArtistMeta::new(artist_id.clone()));
assert!(artist.meta > ArtistMeta::new(sort_id_1.clone())); assert!(artist.meta > ArtistMeta::new(sort_id_1.clone()));
assert!(artist > Artist::new(artist_id.clone())); assert!(artist > Artist::new(artist_id.clone()));
@ -244,7 +244,7 @@ mod tests {
assert_eq!(artist.meta.id, artist_id); assert_eq!(artist.meta.id, artist_id);
assert_eq!(artist.meta.sort, None); assert_eq!(artist.meta.sort, None);
assert_eq!(artist.meta.get_sort_key(), (&artist_id,)); assert_eq!(artist.meta.get_sort_key(), (artist_id.name.as_str(),));
assert!(artist.meta < ArtistMeta::new(sort_id_1.clone())); assert!(artist.meta < ArtistMeta::new(sort_id_1.clone()));
assert!(artist.meta < ArtistMeta::new(sort_id_2.clone())); assert!(artist.meta < ArtistMeta::new(sort_id_2.clone()));
assert!(artist < Artist::new(sort_id_1.clone())); assert!(artist < Artist::new(sort_id_1.clone()));

View File

@ -97,7 +97,7 @@ impl<Database, Library> IMusicHoardBasePrivate for MusicHoard<Database, Library>
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::core::{collection::artist::ArtistId, testmod::FULL_COLLECTION}; use crate::core::testmod::FULL_COLLECTION;
use super::*; use super::*;
@ -190,7 +190,7 @@ mod tests {
let mut right: Vec<Artist> = vec![left.last().unwrap().clone()]; let mut right: Vec<Artist> = vec![left.last().unwrap().clone()];
assert!(right.first().unwrap() > left.first().unwrap()); assert!(right.first().unwrap() > left.first().unwrap());
let artist_sort = Some(ArtistId::new("Album_Artist 0")); let artist_sort = Some(String::from("Album_Artist 0"));
right[0].meta.sort = artist_sort.clone(); right[0].meta.sort = artist_sort.clone();
assert!(right.first().unwrap() < left.first().unwrap()); assert!(right.first().unwrap() < left.first().unwrap());

View File

@ -21,10 +21,10 @@ pub trait IMusicHoardDatabase {
fn add_artist<IntoId: Into<ArtistId>>(&mut self, artist_id: IntoId) -> Result<(), Error>; fn add_artist<IntoId: Into<ArtistId>>(&mut self, artist_id: IntoId) -> Result<(), Error>;
fn remove_artist<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>; fn remove_artist<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>;
fn set_artist_sort<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>( fn set_artist_sort<Id: AsRef<ArtistId>, S: Into<String>>(
&mut self, &mut self,
artist_id: Id, artist_id: Id,
artist_sort: IntoId, artist_sort: S,
) -> Result<(), Error>; ) -> Result<(), Error>;
fn clear_artist_sort<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>; fn clear_artist_sort<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>;
@ -139,10 +139,10 @@ impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
}) })
} }
fn set_artist_sort<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>( fn set_artist_sort<Id: AsRef<ArtistId>, S: Into<String>>(
&mut self, &mut self,
artist_id: Id, artist_id: Id,
artist_sort: IntoId, artist_sort: S,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.update_artist_and( self.update_artist_and(
artist_id.as_ref(), artist_id.as_ref(),
@ -478,12 +478,12 @@ mod tests {
let mut music_hoard: MH = MusicHoard::database(database).unwrap(); let mut music_hoard: MH = MusicHoard::database(database).unwrap();
let artist_1_id = ArtistId::new("the artist"); let artist_1_id = ArtistId::new("the artist");
let artist_1_sort = ArtistId::new("artist, the"); let artist_1_sort = String::from("artist, the");
// Must be after "artist, the", but before "the artist" // Must be after "artist, the", but before "the artist"
let artist_2_id = ArtistId::new("b-artist"); let artist_2_id = ArtistId::new("b-artist");
assert!(artist_1_sort < artist_2_id); assert!(artist_1_sort < artist_2_id.name);
assert!(artist_2_id < artist_1_id); assert!(artist_2_id < artist_1_id);
assert!(music_hoard.add_artist(artist_1_id.clone()).is_ok()); assert!(music_hoard.add_artist(artist_1_id.clone()).is_ok());

View File

@ -52,7 +52,7 @@ impl<Database, Library: ILibrary> MusicHoard<Database, Library> {
name: item.album_artist, name: item.album_artist,
}; };
let artist_sort = item.album_artist_sort.map(|s| ArtistId { name: s }); let artist_sort = item.album_artist_sort;
let album_id = AlbumId { let album_id = AlbumId {
title: item.album_title, title: item.album_title,

View File

@ -114,7 +114,7 @@ impl From<DeserializeArtist> for Artist {
Artist { Artist {
meta: ArtistMeta { meta: ArtistMeta {
id: ArtistId::new(artist.name), id: ArtistId::new(artist.name),
sort: artist.sort.map(ArtistId::new), sort: artist.sort,
musicbrainz: artist.musicbrainz.into(), musicbrainz: artist.musicbrainz.into(),
properties: artist.properties, properties: artist.properties,
}, },

View File

@ -72,7 +72,7 @@ impl<'a> From<&'a Artist> for SerializeArtist<'a> {
fn from(artist: &'a Artist) -> Self { fn from(artist: &'a Artist) -> Self {
SerializeArtist { SerializeArtist {
name: &artist.meta.id.name, name: &artist.meta.id.name,
sort: artist.meta.sort.as_ref().map(|id| id.name.as_ref()), sort: artist.meta.sort.as_deref(),
musicbrainz: (&artist.meta.musicbrainz).into(), musicbrainz: (&artist.meta.musicbrainz).into(),
properties: artist properties: artist
.meta .meta

View File

@ -4,8 +4,7 @@ use serde::{de::Visitor, Deserialize, Deserializer};
use crate::{ use crate::{
collection::{ collection::{
album::{AlbumDate, AlbumId, AlbumPrimaryType, AlbumSecondaryType}, album::{AlbumDate, AlbumPrimaryType, AlbumSecondaryType},
artist::ArtistId,
musicbrainz::Mbid, musicbrainz::Mbid,
Error as CollectionError, Error as CollectionError,
}, },
@ -62,8 +61,8 @@ impl<Http> MusicBrainzClient<Http> {
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct MbArtistMeta { pub struct MbArtistMeta {
pub id: Mbid, pub id: Mbid,
pub name: ArtistId, pub name: String,
pub sort_name: ArtistId, pub sort_name: String,
pub disambiguation: Option<String>, pub disambiguation: Option<String>,
} }
@ -90,7 +89,7 @@ impl From<SerdeMbArtistMeta> for MbArtistMeta {
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct MbReleaseGroupMeta { pub struct MbReleaseGroupMeta {
pub id: Mbid, pub id: Mbid,
pub title: AlbumId, pub title: String,
pub first_release_date: AlbumDate, pub first_release_date: AlbumDate,
pub primary_type: AlbumPrimaryType, pub primary_type: AlbumPrimaryType,
pub secondary_types: Option<Vec<AlbumSecondaryType>>, pub secondary_types: Option<Vec<AlbumSecondaryType>>,

View File

@ -315,9 +315,7 @@ macro_rules! full_collection {
id: ArtistId { id: ArtistId {
name: "The Album_Artist C".to_string(), name: "The Album_Artist C".to_string(),
}, },
sort: Some(ArtistId { sort: Some("Album_Artist C, The".to_string()),
name: "Album_Artist C, The".to_string(),
}),
musicbrainz: MbRefOption::CannotHaveMbid, musicbrainz: MbRefOption::CannotHaveMbid,
properties: HashMap::new(), properties: HashMap::new(),
}, },

View File

@ -284,9 +284,7 @@ macro_rules! library_collection {
id: ArtistId { id: ArtistId {
name: "The Album_Artist C".to_string(), name: "The Album_Artist C".to_string(),
}, },
sort: Some(ArtistId { sort: Some("Album_Artist C, The".to_string()),
name: "Album_Artist C, The".to_string(),
}),
musicbrainz: MbRefOption::None, musicbrainz: MbRefOption::None,
properties: HashMap::new(), properties: HashMap::new(),
}, },

View File

@ -182,7 +182,7 @@ impl IAppInteractSearchPrivate for AppMachine<SearchState> {
if let Some(ref probe_sort) = probe.meta.sort { if let Some(ref probe_sort) = probe.meta.sort {
if !result { if !result {
let name = Self::normalize_search(&probe_sort.name, !case_sens, !char_sens); let name = Self::normalize_search(&probe_sort, !case_sens, !char_sens);
result = name.starts_with(search); result = name.starts_with(search);
} }
} }

View File

@ -205,14 +205,14 @@ impl KeySelectArtist {
let artist = &artists[index]; let artist = &artists[index];
let key = artist.meta.get_sort_key(); let key = artist.meta.get_sort_key();
KeySelectArtist { KeySelectArtist {
key: (key.0.to_owned(),), key: (key.0.into(),),
album: KeySelectAlbum::get(&artist.albums, &selection.album), album: KeySelectAlbum::get(&artist.albums, &selection.album),
} }
}) })
} }
pub fn get_sort_key(&self) -> (&ArtistId,) { pub fn get_sort_key(&self) -> (&str,) {
(&self.key.0,) (&self.key.0.name,)
} }
} }

View File

@ -5,7 +5,7 @@ use std::collections::HashMap;
use musichoard::{ use musichoard::{
collection::{ collection::{
album::{AlbumDate, AlbumMeta, AlbumSeq}, album::{AlbumDate, AlbumMeta, AlbumSeq},
artist::{ArtistId, ArtistMeta}, artist::ArtistMeta,
musicbrainz::{MbRefOption, Mbid}, musicbrainz::{MbRefOption, Mbid},
}, },
external::musicbrainz::{ external::musicbrainz::{
@ -93,12 +93,10 @@ impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
} }
fn from_lookup_artist_response(entity: LookupArtistResponse) -> Lookup<ArtistMeta> { fn from_lookup_artist_response(entity: LookupArtistResponse) -> Lookup<ArtistMeta> {
let sort: Option<ArtistId> = Some(entity.meta.sort_name) let sort = Some(entity.meta.sort_name).filter(|s| s != &entity.meta.name);
.filter(|s| s != &entity.meta.name)
.map(Into::into);
Lookup { Lookup {
item: ArtistMeta { item: ArtistMeta {
id: entity.meta.name, id: entity.meta.name.into(),
sort, sort,
musicbrainz: MbRefOption::Some(entity.meta.id.into()), musicbrainz: MbRefOption::Some(entity.meta.id.into()),
properties: HashMap::new(), properties: HashMap::new(),
@ -110,7 +108,7 @@ fn from_lookup_artist_response(entity: LookupArtistResponse) -> Lookup<ArtistMet
fn from_lookup_release_group_response(entity: LookupReleaseGroupResponse) -> Lookup<AlbumMeta> { fn from_lookup_release_group_response(entity: LookupReleaseGroupResponse) -> Lookup<AlbumMeta> {
Lookup { Lookup {
item: AlbumMeta { item: AlbumMeta {
id: entity.meta.title, id: entity.meta.title.into(),
date: entity.meta.first_release_date, date: entity.meta.first_release_date,
seq: AlbumSeq::default(), seq: AlbumSeq::default(),
musicbrainz: MbRefOption::Some(entity.meta.id.into()), musicbrainz: MbRefOption::Some(entity.meta.id.into()),
@ -122,13 +120,11 @@ fn from_lookup_release_group_response(entity: LookupReleaseGroupResponse) -> Loo
} }
fn from_search_artist_response_artist(entity: SearchArtistResponseArtist) -> Match<ArtistMeta> { fn from_search_artist_response_artist(entity: SearchArtistResponseArtist) -> Match<ArtistMeta> {
let sort: Option<ArtistId> = Some(entity.meta.sort_name) let sort = Some(entity.meta.sort_name).filter(|s| s != &entity.meta.name);
.filter(|s| s != &entity.meta.name)
.map(Into::into);
Match { Match {
score: entity.score, score: entity.score,
item: ArtistMeta { item: ArtistMeta {
id: entity.meta.name, id: entity.meta.name.into(),
sort, sort,
musicbrainz: MbRefOption::Some(entity.meta.id.into()), musicbrainz: MbRefOption::Some(entity.meta.id.into()),
properties: HashMap::new(), properties: HashMap::new(),
@ -143,7 +139,7 @@ fn from_search_release_group_response_release_group(
Match { Match {
score: entity.score, score: entity.score,
item: AlbumMeta { item: AlbumMeta {
id: entity.meta.title, id: entity.meta.title.into(),
date: entity.meta.first_release_date, date: entity.meta.first_release_date,
seq: AlbumSeq::default(), seq: AlbumSeq::default(),
musicbrainz: MbRefOption::Some(entity.meta.id.into()), musicbrainz: MbRefOption::Some(entity.meta.id.into()),

View File

@ -16,9 +16,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
id: ArtistId { id: ArtistId {
name: String::from("Аркона"), name: String::from("Аркона"),
}, },
sort: Some(ArtistId{ sort: Some(String::from("Arkona")),
name: String::from("Arkona")
}),
musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str(
"https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212" "https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212"
).unwrap()), ).unwrap()),
@ -609,9 +607,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
id: ArtistId { id: ArtistId {
name: String::from("Heavens Basement"), name: String::from("Heavens Basement"),
}, },
sort: Some(ArtistId { sort: Some(String::from("Heavens Basement")),
name: String::from("Heavens Basement"),
}),
musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str(
"https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc" "https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc"
).unwrap()), ).unwrap()),