Rescanning library does not update the database #151

Merged
wojtek merged 2 commits from 150---rescanning-library-does-not-update-the-database into main 2024-03-01 15:34:21 +01:00
2 changed files with 38 additions and 17 deletions
Showing only changes of commit 12fcdd45b6 - Show all commits

View File

@ -72,7 +72,7 @@ impl<LIB, DB> MusicHoard<LIB, DB> {
} }
} }
fn merge_collections(&mut self) { fn merge_collections(&mut self) -> Collection {
let mut primary = self.library_cache.clone(); let mut primary = self.library_cache.clone();
for secondary_artist in self.database_cache.iter().cloned() { for secondary_artist in self.database_cache.iter().cloned() {
if let Some(ref mut primary_artist) = primary.get_mut(&secondary_artist.id) { if let Some(ref mut primary_artist) = primary.get_mut(&secondary_artist.id) {
@ -82,10 +82,10 @@ impl<LIB, DB> MusicHoard<LIB, DB> {
} }
} }
self.collection = primary.into_values().collect(); let mut collection: Collection = primary.into_values().collect();
Self::sort_artists(&mut self.collection); Self::sort_artists(&mut collection);
self.pre_commit = self.collection.clone(); collection
} }
fn items_to_artists(items: Vec<Item>) -> Result<HashMap<ArtistId, Artist>, Error> { fn items_to_artists(items: Vec<Item>) -> Result<HashMap<ArtistId, Artist>, Error> {
@ -190,17 +190,22 @@ impl<LIB: ILibrary> MusicHoard<LIB, NoDatabase> {
database_cache: vec![], database_cache: vec![],
} }
} }
/// Rescan the library and merge with the in-memory collection.
pub fn rescan_library(&mut self) -> Result<(), Error> {
self.pre_commit = self.rescan_library_inner()?;
self.collection = self.pre_commit.clone();
Ok(())
}
} }
impl<LIB: ILibrary, DB> MusicHoard<LIB, DB> { impl<LIB: ILibrary, DB> MusicHoard<LIB, DB> {
/// Rescan the library and merge with the in-memory collection. fn rescan_library_inner(&mut self) -> Result<Collection, Error> {
pub fn rescan_library(&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()); Self::sort_albums_and_tracks(self.library_cache.values_mut());
self.merge_collections(); Ok(self.merge_collections())
Ok(())
} }
} }
@ -226,7 +231,9 @@ impl<LIB, DB: IDatabase> MusicHoard<LIB, DB> {
self.database_cache = self.database.load()?; self.database_cache = self.database.load()?;
Self::sort_albums_and_tracks(self.database_cache.iter_mut()); Self::sort_albums_and_tracks(self.database_cache.iter_mut());
self.merge_collections(); self.collection = self.merge_collections();
self.pre_commit = self.collection.clone();
Ok(()) Ok(())
} }
@ -381,6 +388,12 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
mh.reload_database()?; mh.reload_database()?;
Ok(mh) Ok(mh)
} }
/// Rescan the library and merge with the in-memory collection.
pub fn rescan_library(&mut self) -> Result<(), Error> {
self.pre_commit = self.rescan_library_inner()?;
self.commit()
}
} }
#[cfg(test)] #[cfg(test)]
@ -672,7 +685,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
mh.merge_collections(); mh.collection = mh.merge_collections();
assert_eq!(expected, mh.collection); assert_eq!(expected, mh.collection);
// The merge is completely non-overlapping so it should be commutative. // The merge is completely non-overlapping so it should be commutative.
@ -686,7 +699,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
mh.merge_collections(); mh.collection = mh.merge_collections();
assert_eq!(expected, mh.collection); assert_eq!(expected, mh.collection);
} }
@ -710,7 +723,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
mh.merge_collections(); mh.collection = mh.merge_collections();
assert_eq!(expected, mh.collection); assert_eq!(expected, mh.collection);
// The merge does not overwrite any data so it should be commutative. // The merge does not overwrite any data so it should be commutative.
@ -724,7 +737,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
mh.merge_collections(); mh.collection = mh.merge_collections();
assert_eq!(expected, mh.collection); assert_eq!(expected, mh.collection);
} }
@ -761,7 +774,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
mh.merge_collections(); mh.collection = mh.merge_collections();
assert_eq!(expected, mh.collection); assert_eq!(expected, mh.collection);
// The merge overwrites the sort data, but no data is erased so it should be commutative. // The merge overwrites the sort data, but no data is erased so it should be commutative.
@ -775,13 +788,14 @@ mod tests {
..Default::default() ..Default::default()
}; };
mh.merge_collections(); mh.collection = mh.merge_collections();
assert_eq!(expected, mh.collection); assert_eq!(expected, mh.collection);
} }
#[test] #[test]
fn rescan_library_ordered() { fn rescan_library_ordered() {
let mut library = MockILibrary::new(); let mut library = MockILibrary::new();
let mut database = MockIDatabase::new();
let library_input = Query::new(); let library_input = Query::new();
let library_result = Ok(LIBRARY_ITEMS.to_owned()); let library_result = Ok(LIBRARY_ITEMS.to_owned());
@ -792,7 +806,14 @@ mod tests {
.times(1) .times(1)
.return_once(|_| library_result); .return_once(|_| library_result);
let mut music_hoard = MusicHoard::library(library); database.expect_load().times(1).returning(|| Ok(vec![]));
database
.expect_save()
.with(predicate::eq(&*LIBRARY_COLLECTION))
.times(1)
.return_once(|_| Ok(()));
let mut music_hoard = MusicHoard::new(library, database).unwrap();
music_hoard.rescan_library().unwrap(); music_hoard.rescan_library().unwrap();
assert_eq!(music_hoard.get_collection(), &*LIBRARY_COLLECTION); assert_eq!(music_hoard.get_collection(), &*LIBRARY_COLLECTION);

View File

@ -13,7 +13,7 @@ pub trait IMusicHoard {
// GRCOV_EXCL_START // GRCOV_EXCL_START
impl<LIB: ILibrary, DB: IDatabase> IMusicHoard for MusicHoard<LIB, DB> { impl<LIB: ILibrary, DB: IDatabase> IMusicHoard for MusicHoard<LIB, DB> {
fn rescan_library(&mut self) -> Result<(), musichoard::Error> { fn rescan_library(&mut self) -> Result<(), musichoard::Error> {
MusicHoard::rescan_library(self) MusicHoard::<LIB, DB>::rescan_library(self)
} }
fn reload_database(&mut self) -> Result<(), musichoard::Error> { fn reload_database(&mut self) -> Result<(), musichoard::Error> {