WIP: Refactor the IDatabase calls to write directly to the database #271

Draft
wojtek wants to merge 12 commits from 268---refactor-the-idatabase-calls-to-write-directly-to-the-database into main
3 changed files with 57 additions and 41 deletions
Showing only changes of commit 38a2e1f33c - Show all commits

View File

@ -2,10 +2,9 @@ use crate::core::{
collection::{
album::{Album, AlbumId},
artist::{Artist, ArtistId},
merge::{MergeCollections, NormalMap},
string, Collection,
Collection,
},
musichoard::{filter::CollectionFilter, Error, LibArtist, MusicHoard},
musichoard::{filter::CollectionFilter, Error, MusicHoard},
};
pub trait IMusicHoardBase {
@ -32,7 +31,6 @@ impl<Database, Library> IMusicHoardBase for MusicHoard<Database, Library> {
pub trait IMusicHoardBasePrivate {
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_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 {
let iter = self.collection.iter();
iter.flat_map(|a| self.filter_artist(a)).collect()

View File

@ -4,7 +4,8 @@ use crate::{
collection::{
album::{AlbumInfo, AlbumMbRef, AlbumMeta},
artist::ArtistInfo,
merge::Merge,
merge::{Merge, MergeCollections, NormalMap},
string,
},
core::{
collection::{
@ -13,11 +14,15 @@ use crate::{
Collection,
},
interface::database::IDatabase,
musichoard::{base::IMusicHoardBasePrivate, Error, MusicHoard, NoDatabase},
musichoard::{
base::IMusicHoardBasePrivate, Error, IntoId, LibArtist, MusicHoard, NoDatabase,
},
},
};
pub trait IMusicHoardDatabase {
fn merge_collections(&mut self) -> Result<Collection, Error>;
fn reload_database(&mut self) -> Result<(), Error>;
fn merge_artist_info<Id: AsRef<ArtistId>>(
@ -64,11 +69,34 @@ pub trait IMusicHoardDatabase {
}
impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database, Library> {
fn reload_database(&mut self) -> Result<(), Error> {
let mut database_cache = self.database.load()?;
Self::sort_albums_and_tracks(database_cache.iter_mut().map(|a| &mut a.albums));
fn merge_collections(&mut self) -> Result<Collection, Error> {
let mut database = self.database.load()?;
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();
Ok(())

View File

@ -1,20 +1,24 @@
use std::collections::HashMap;
use crate::{
collection::string::{self, NormalString},
collection::{
artist::ArtistId,
merge::IntoId,
string::{self, NormalString},
},
core::{
collection::{
album::{Album, AlbumDate, AlbumId, AlbumMbRef},
track::{Track, TrackId, TrackNum, TrackQuality},
Collection,
},
interface::{
database::IDatabase,
library::{ILibrary, Item, Query},
},
musichoard::{
base::IMusicHoardBasePrivate, database::IMusicHoardDatabasePrivate, Error, LibArtist,
MusicHoard, NoDatabase,
base::IMusicHoardBasePrivate,
database::{IMusicHoardDatabase, IMusicHoardDatabasePrivate},
Error, LibArtist, MusicHoard, NoDatabase,
},
},
};
@ -25,28 +29,34 @@ pub trait IMusicHoardLibrary {
impl<Library: ILibrary> IMusicHoardLibrary for MusicHoard<NoDatabase, Library> {
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()
}
}
impl<Database: IDatabase, Library: ILibrary> IMusicHoardLibrary for MusicHoard<Database, Library> {
fn rescan_library(&mut self) -> Result<(), Error> {
let mut database_cache = self.database.load()?;
Self::sort_albums_and_tracks(database_cache.iter_mut().map(|a| &mut a.albums));
self.rescan_library_inner()?;
self.collection = self.merge_collections()?;
self.collection = self.rescan_library_inner(database_cache)?;
self.commit()
}
}
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())?;
self.library_cache = Self::items_to_artists(items)?;
Self::sort_albums_and_tracks(self.library_cache.values_mut().map(|la| &mut la.albums));
Ok(self.merge_collections(database))
Ok(())
}
fn items_to_artists(items: Vec<Item>) -> Result<HashMap<NormalString, LibArtist>, Error> {