Startup merge fails when the database has two albums with the same title as an album in the library #246
@ -6,7 +6,7 @@ use std::{
|
|||||||
|
|
||||||
use crate::core::collection::{
|
use crate::core::collection::{
|
||||||
album::{Album, AlbumLibId},
|
album::{Album, AlbumLibId},
|
||||||
merge::{Merge, MergeCollections},
|
merge::{Merge, MergeCollections, TitleMap},
|
||||||
musicbrainz::{MbArtistRef, MbRefOption},
|
musicbrainz::{MbArtistRef, MbRefOption},
|
||||||
string::{self, NormalString},
|
string::{self, NormalString},
|
||||||
};
|
};
|
||||||
@ -65,8 +65,8 @@ impl Merge for Artist {
|
|||||||
struct MergeAlbums {
|
struct MergeAlbums {
|
||||||
primary_by_lib_id: HashMap<u32, Album>,
|
primary_by_lib_id: HashMap<u32, Album>,
|
||||||
primary_by_singleton: HashMap<NormalString, Album>,
|
primary_by_singleton: HashMap<NormalString, Album>,
|
||||||
primary_by_title: HashMap<NormalString, Vec<Album>>,
|
primary_by_title: TitleMap<Album>,
|
||||||
secondary_by_title: HashMap<NormalString, Vec<Album>>,
|
secondary_by_title: TitleMap<Album>,
|
||||||
merged: Vec<Album>,
|
merged: Vec<Album>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,16 +104,13 @@ impl MergeAlbums {
|
|||||||
self.merge_album_by_lib_id(secondary_album);
|
self.merge_album_by_lib_id(secondary_album);
|
||||||
}
|
}
|
||||||
for (_, primary_album) in self.primary_by_lib_id.drain() {
|
for (_, primary_album) in self.primary_by_lib_id.drain() {
|
||||||
self.primary_by_title
|
self.primary_by_title.insert(
|
||||||
.entry(string::normalize_string(&primary_album.meta.id.title))
|
string::normalize_string(&primary_album.meta.id.title),
|
||||||
.or_default()
|
primary_album,
|
||||||
.push(primary_album);
|
);
|
||||||
}
|
}
|
||||||
for (title, primary_album) in self.primary_by_singleton.drain() {
|
for (title, primary_album) in self.primary_by_singleton.drain() {
|
||||||
self.primary_by_title
|
self.primary_by_title.insert(title, primary_album);
|
||||||
.entry(title.clone())
|
|
||||||
.or_default()
|
|
||||||
.push(primary_album);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,10 +131,10 @@ impl MergeAlbums {
|
|||||||
}
|
}
|
||||||
|
|
||||||
secondary_album.meta.id.lib_id = AlbumLibId::None;
|
secondary_album.meta.id.lib_id = AlbumLibId::None;
|
||||||
self.secondary_by_title
|
self.secondary_by_title.insert(
|
||||||
.entry(string::normalize_string(&secondary_album.meta.id.title))
|
string::normalize_string(&secondary_album.meta.id.title),
|
||||||
.or_default()
|
secondary_album,
|
||||||
.push(secondary_album);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,16 +82,35 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TitleMap<T>(HashMap<NormalString, Vec<T>>);
|
||||||
|
|
||||||
|
impl<T> Default for TitleMap<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
TitleMap(HashMap::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> TitleMap<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
TitleMap(HashMap::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, key: NormalString, item: T) {
|
||||||
|
self.0.entry(key).or_default().push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, key: &NormalString) -> Option<Vec<T>> {
|
||||||
|
self.0.remove(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MergeCollections;
|
pub struct MergeCollections;
|
||||||
|
|
||||||
impl MergeCollections {
|
impl MergeCollections {
|
||||||
pub fn merge_by_name<T, It>(mut primary: HashMap<NormalString, Vec<T>>, secondary: It) -> Vec<T>
|
pub fn merge_by_name<T: Merge>(mut primary: TitleMap<T>, secondary: TitleMap<T>) -> Vec<T> {
|
||||||
where
|
|
||||||
T: Merge,
|
|
||||||
It: IntoIterator<Item = (NormalString, Vec<T>)>,
|
|
||||||
{
|
|
||||||
let mut merged = vec![];
|
let mut merged = vec![];
|
||||||
for (title, mut secondary_items) in secondary.into_iter() {
|
for (title, mut secondary_items) in secondary.0.into_iter() {
|
||||||
match primary.remove(&title) {
|
match primary.remove(&title) {
|
||||||
Some(mut primary_items) => {
|
Some(mut primary_items) => {
|
||||||
// We do not support merging multiple items with same name yet. Support will be
|
// We do not support merging multiple items with same name yet. Support will be
|
||||||
@ -105,7 +124,7 @@ impl MergeCollections {
|
|||||||
None => merged.extend(secondary_items),
|
None => merged.extend(secondary_items),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
merged.extend(primary.into_values().flatten());
|
merged.extend(primary.0.into_values().flatten());
|
||||||
merged
|
merged
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
collection::{
|
collection::{
|
||||||
album::{Album, AlbumId},
|
album::{Album, AlbumId},
|
||||||
artist::{Artist, ArtistId},
|
artist::{Artist, ArtistId},
|
||||||
merge::MergeCollections,
|
merge::{MergeCollections, TitleMap},
|
||||||
string::{self, NormalString},
|
string, Collection,
|
||||||
Collection,
|
|
||||||
},
|
},
|
||||||
musichoard::{Error, MusicHoard},
|
musichoard::{Error, MusicHoard},
|
||||||
};
|
};
|
||||||
@ -60,21 +57,15 @@ impl<Database, Library> IMusicHoardBasePrivate for MusicHoard<Database, Library>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn merge_collections(&self) -> Collection {
|
fn merge_collections(&self) -> Collection {
|
||||||
let mut primary = HashMap::<NormalString, Vec<Artist>>::new();
|
let mut primary = TitleMap::<Artist>::new();
|
||||||
let mut secondary = HashMap::<NormalString, Vec<Artist>>::new();
|
let mut secondary = TitleMap::<Artist>::new();
|
||||||
|
|
||||||
for artist in self.library_cache.iter().cloned() {
|
for artist in self.library_cache.iter().cloned() {
|
||||||
primary
|
primary.insert(string::normalize_string(&artist.meta.id.name), artist);
|
||||||
.entry(string::normalize_string(&artist.meta.id.name))
|
|
||||||
.or_default()
|
|
||||||
.push(artist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for artist in self.database_cache.iter().cloned() {
|
for artist in self.database_cache.iter().cloned() {
|
||||||
secondary
|
secondary.insert(string::normalize_string(&artist.meta.id.name), artist);
|
||||||
.entry(string::normalize_string(&artist.meta.id.name))
|
|
||||||
.or_default()
|
|
||||||
.push(artist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut collection = MergeCollections::merge_by_name(primary, secondary);
|
let mut collection = MergeCollections::merge_by_name(primary, secondary);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user