WIP: Refactor the IDatabase calls to write directly to the database #271
@ -2,10 +2,9 @@ use crate::core::{
|
|||||||
collection::{
|
collection::{
|
||||||
album::{Album, AlbumId},
|
album::{Album, AlbumId},
|
||||||
artist::{Artist, ArtistId},
|
artist::{Artist, ArtistId},
|
||||||
merge::{MergeCollections, NormalMap},
|
Collection,
|
||||||
string, Collection,
|
|
||||||
},
|
},
|
||||||
musichoard::{filter::CollectionFilter, Error, LibArtist, MusicHoard},
|
musichoard::{filter::CollectionFilter, Error, MusicHoard},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait IMusicHoardBase {
|
pub trait IMusicHoardBase {
|
||||||
@ -32,7 +31,6 @@ impl<Database, Library> IMusicHoardBase for MusicHoard<Database, Library> {
|
|||||||
pub trait IMusicHoardBasePrivate {
|
pub trait IMusicHoardBasePrivate {
|
||||||
fn sort_albums_and_tracks<'a, COL: Iterator<Item = &'a mut Vec<Album>>>(collection: COL);
|
fn sort_albums_and_tracks<'a, COL: Iterator<Item = &'a mut Vec<Album>>>(collection: COL);
|
||||||
|
|
||||||
fn merge_collections<It: IntoIterator<Item = Artist>>(&self, database: It) -> Collection;
|
|
||||||
fn filter_collection(&self) -> Collection;
|
fn filter_collection(&self) -> Collection;
|
||||||
fn filter_artist(&self, artist: &Artist) -> Option<Artist>;
|
fn filter_artist(&self, artist: &Artist) -> Option<Artist>;
|
||||||
|
|
||||||
@ -63,26 +61,6 @@ impl<Database, Library> IMusicHoardBasePrivate for MusicHoard<Database, Library>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_collections<It: IntoIterator<Item = Artist>>(&self, database: It) -> Collection {
|
|
||||||
let mut primary = NormalMap::<LibArtist>::new();
|
|
||||||
let mut secondary = NormalMap::<Artist>::new();
|
|
||||||
|
|
||||||
for (normal_name, artist) in self.library_cache.clone().into_iter() {
|
|
||||||
primary.insert(normal_name, artist);
|
|
||||||
}
|
|
||||||
|
|
||||||
for artist in database.into_iter() {
|
|
||||||
secondary.insert(string::normalize_string(&artist.meta.name), artist);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (mut collection, left) = MergeCollections::merge_by_name(primary, secondary);
|
|
||||||
|
|
||||||
// TODO: Insert what's left into the DB to get IDs and then append to collection.
|
|
||||||
|
|
||||||
collection.sort_unstable();
|
|
||||||
collection
|
|
||||||
}
|
|
||||||
|
|
||||||
fn filter_collection(&self) -> Collection {
|
fn filter_collection(&self) -> Collection {
|
||||||
let iter = self.collection.iter();
|
let iter = self.collection.iter();
|
||||||
iter.flat_map(|a| self.filter_artist(a)).collect()
|
iter.flat_map(|a| self.filter_artist(a)).collect()
|
||||||
|
@ -4,7 +4,8 @@ use crate::{
|
|||||||
collection::{
|
collection::{
|
||||||
album::{AlbumInfo, AlbumMbRef, AlbumMeta},
|
album::{AlbumInfo, AlbumMbRef, AlbumMeta},
|
||||||
artist::ArtistInfo,
|
artist::ArtistInfo,
|
||||||
merge::Merge,
|
merge::{Merge, MergeCollections, NormalMap},
|
||||||
|
string,
|
||||||
},
|
},
|
||||||
core::{
|
core::{
|
||||||
collection::{
|
collection::{
|
||||||
@ -13,11 +14,15 @@ use crate::{
|
|||||||
Collection,
|
Collection,
|
||||||
},
|
},
|
||||||
interface::database::IDatabase,
|
interface::database::IDatabase,
|
||||||
musichoard::{base::IMusicHoardBasePrivate, Error, MusicHoard, NoDatabase},
|
musichoard::{
|
||||||
|
base::IMusicHoardBasePrivate, Error, IntoId, LibArtist, MusicHoard, NoDatabase,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait IMusicHoardDatabase {
|
pub trait IMusicHoardDatabase {
|
||||||
|
fn merge_collections(&mut self) -> Result<Collection, Error>;
|
||||||
|
|
||||||
fn reload_database(&mut self) -> Result<(), Error>;
|
fn reload_database(&mut self) -> Result<(), Error>;
|
||||||
|
|
||||||
fn merge_artist_info<Id: AsRef<ArtistId>>(
|
fn merge_artist_info<Id: AsRef<ArtistId>>(
|
||||||
@ -64,11 +69,34 @@ pub trait IMusicHoardDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database, Library> {
|
impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database, Library> {
|
||||||
fn reload_database(&mut self) -> Result<(), Error> {
|
fn merge_collections(&mut self) -> Result<Collection, Error> {
|
||||||
let mut database_cache = self.database.load()?;
|
let mut database = self.database.load()?;
|
||||||
Self::sort_albums_and_tracks(database_cache.iter_mut().map(|a| &mut a.albums));
|
Self::sort_albums_and_tracks(database.iter_mut().map(|a| &mut a.albums));
|
||||||
|
|
||||||
self.collection = self.merge_collections(database_cache);
|
let mut primary = NormalMap::<LibArtist>::new();
|
||||||
|
for (normal_name, artist) in self.library_cache.clone().into_iter() {
|
||||||
|
primary.insert(normal_name, artist);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut secondary = NormalMap::<Artist>::new();
|
||||||
|
for artist in database.into_iter() {
|
||||||
|
secondary.insert(string::normalize_string(&artist.meta.name), artist);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (mut collection, lib_artists) = MergeCollections::merge_by_name(primary, secondary);
|
||||||
|
|
||||||
|
for lib_artist in lib_artists.into_iter() {
|
||||||
|
let id = self.database.insert_artist(&lib_artist.meta)?;
|
||||||
|
collection.push(lib_artist.into_id(&id));
|
||||||
|
}
|
||||||
|
|
||||||
|
collection.sort_unstable();
|
||||||
|
|
||||||
|
Ok(collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reload_database(&mut self) -> Result<(), Error> {
|
||||||
|
self.collection = self.merge_collections()?;
|
||||||
self.filtered = self.filter_collection();
|
self.filtered = self.filter_collection();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
collection::string::{self, NormalString},
|
collection::{
|
||||||
|
artist::ArtistId,
|
||||||
|
merge::IntoId,
|
||||||
|
string::{self, NormalString},
|
||||||
|
},
|
||||||
core::{
|
core::{
|
||||||
collection::{
|
collection::{
|
||||||
album::{Album, AlbumDate, AlbumId, AlbumMbRef},
|
album::{Album, AlbumDate, AlbumId, AlbumMbRef},
|
||||||
track::{Track, TrackId, TrackNum, TrackQuality},
|
track::{Track, TrackId, TrackNum, TrackQuality},
|
||||||
Collection,
|
|
||||||
},
|
},
|
||||||
interface::{
|
interface::{
|
||||||
database::IDatabase,
|
database::IDatabase,
|
||||||
library::{ILibrary, Item, Query},
|
library::{ILibrary, Item, Query},
|
||||||
},
|
},
|
||||||
musichoard::{
|
musichoard::{
|
||||||
base::IMusicHoardBasePrivate, database::IMusicHoardDatabasePrivate, Error, LibArtist,
|
base::IMusicHoardBasePrivate,
|
||||||
MusicHoard, NoDatabase,
|
database::{IMusicHoardDatabase, IMusicHoardDatabasePrivate},
|
||||||
|
Error, LibArtist, MusicHoard, NoDatabase,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -25,28 +29,34 @@ pub trait IMusicHoardLibrary {
|
|||||||
|
|
||||||
impl<Library: ILibrary> IMusicHoardLibrary for MusicHoard<NoDatabase, Library> {
|
impl<Library: ILibrary> IMusicHoardLibrary for MusicHoard<NoDatabase, Library> {
|
||||||
fn rescan_library(&mut self) -> Result<(), Error> {
|
fn rescan_library(&mut self) -> Result<(), Error> {
|
||||||
self.collection = self.rescan_library_inner(vec![])?;
|
self.rescan_library_inner()?;
|
||||||
|
self.collection = self
|
||||||
|
.library_cache
|
||||||
|
.values()
|
||||||
|
.cloned()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(ix, la)| la.into_id(&ArtistId(ix)))
|
||||||
|
.collect();
|
||||||
|
self.collection.sort_unstable();
|
||||||
self.commit()
|
self.commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Database: IDatabase, Library: ILibrary> IMusicHoardLibrary for MusicHoard<Database, Library> {
|
impl<Database: IDatabase, Library: ILibrary> IMusicHoardLibrary for MusicHoard<Database, Library> {
|
||||||
fn rescan_library(&mut self) -> Result<(), Error> {
|
fn rescan_library(&mut self) -> Result<(), Error> {
|
||||||
let mut database_cache = self.database.load()?;
|
self.rescan_library_inner()?;
|
||||||
Self::sort_albums_and_tracks(database_cache.iter_mut().map(|a| &mut a.albums));
|
self.collection = self.merge_collections()?;
|
||||||
|
|
||||||
self.collection = self.rescan_library_inner(database_cache)?;
|
|
||||||
self.commit()
|
self.commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Database, Library: ILibrary> MusicHoard<Database, Library> {
|
impl<Database, Library: ILibrary> MusicHoard<Database, Library> {
|
||||||
fn rescan_library_inner(&mut self, database: Collection) -> Result<Collection, Error> {
|
fn rescan_library_inner(&mut self) -> Result<(), Error> {
|
||||||
let items = self.library.list(&Query::new())?;
|
let items = self.library.list(&Query::new())?;
|
||||||
self.library_cache = Self::items_to_artists(items)?;
|
self.library_cache = Self::items_to_artists(items)?;
|
||||||
Self::sort_albums_and_tracks(self.library_cache.values_mut().map(|la| &mut la.albums));
|
Self::sort_albums_and_tracks(self.library_cache.values_mut().map(|la| &mut la.albums));
|
||||||
|
Ok(())
|
||||||
Ok(self.merge_collections(database))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn items_to_artists(items: Vec<Item>) -> Result<HashMap<NormalString, LibArtist>, Error> {
|
fn items_to_artists(items: Vec<Item>) -> Result<HashMap<NormalString, LibArtist>, Error> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user