Fetching and then instantly reloading library loses data #256

Merged
wojtek merged 6 commits from 254---fetching-and-then-instantly-reloading-library-loses-data into main 2025-01-05 11:06:05 +01:00
6 changed files with 44 additions and 55 deletions
Showing only changes of commit 180a2edd83 - Show all commits

View File

@ -249,9 +249,9 @@ fn main() {
let db = JsonDatabase::new(JsonDatabaseFileBackend::new(&opt.database_file_path));
let mut music_hoard = MusicHoardBuilder::default()
.set_database(db)
.build()
.expect("failed to initialise MusicHoard");
let mut music_hoard = MusicHoardBuilder::default().set_database(db).build();
music_hoard
.reload_database()
.expect("failed to load MusicHoard database");
opt.command.handle(&mut music_hoard);
}

View File

@ -1,8 +1,6 @@
use crate::core::{
interface::{database::IDatabase, library::ILibrary},
musichoard::{
database::IMusicHoardDatabase, CollectionFilter, Error, MusicHoard, NoDatabase, NoLibrary,
},
musichoard::{CollectionFilter, MusicHoard, NoDatabase, NoLibrary},
};
/// Builder for [`MusicHoard`]. Its purpose is to make it easier to set various combinations of
@ -99,15 +97,15 @@ impl<Library: ILibrary> MusicHoard<NoDatabase, Library> {
impl<Database: IDatabase> MusicHoardBuilder<Database, NoLibrary> {
/// Build [`MusicHoard`] with the currently set library and database.
pub fn build(self) -> Result<MusicHoard<Database, NoLibrary>, Error> {
pub fn build(self) -> MusicHoard<Database, NoLibrary> {
MusicHoard::database(self.database)
}
}
impl<Database: IDatabase> MusicHoard<Database, NoLibrary> {
/// Create a new [`MusicHoard`] with the provided [`IDatabase`] and no library.
pub fn database(database: Database) -> Result<Self, Error> {
let mut mh = MusicHoard {
pub fn database(database: Database) -> Self {
MusicHoard {
filter: CollectionFilter::default(),
filtered: vec![],
collection: vec![],
@ -115,23 +113,21 @@ impl<Database: IDatabase> MusicHoard<Database, NoLibrary> {
database,
library: NoLibrary,
library_cache: vec![],
};
mh.reload_database()?;
Ok(mh)
}
}
}
impl<Database: IDatabase, Library: ILibrary> MusicHoardBuilder<Database, Library> {
/// Build [`MusicHoard`] with the currently set library and database.
pub fn build(self) -> Result<MusicHoard<Database, Library>, Error> {
pub fn build(self) -> MusicHoard<Database, Library> {
MusicHoard::new(self.database, self.library)
}
}
impl<Database: IDatabase, Library: ILibrary> MusicHoard<Database, Library> {
/// Create a new [`MusicHoard`] with the provided [`ILibrary`] and [`IDatabase`].
pub fn new(database: Database, library: Library) -> Result<Self, Error> {
let mut mh = MusicHoard {
pub fn new(database: Database, library: Library) -> Self {
MusicHoard {
filter: CollectionFilter::default(),
filtered: vec![],
collection: vec![],
@ -139,18 +135,16 @@ impl<Database: IDatabase, Library: ILibrary> MusicHoard<Database, Library> {
database,
library,
library_cache: vec![],
};
mh.reload_database()?;
Ok(mh)
}
}
}
#[cfg(test)]
mod tests {
use crate::core::{
use crate::{core::{
interface::{database::NullDatabase, library::NullLibrary},
musichoard::library::IMusicHoardLibrary,
};
}, IMusicHoardDatabase};
use super::*;
@ -177,8 +171,7 @@ mod tests {
fn no_library_with_database() {
let mut mh = MusicHoardBuilder::default()
.set_database(NullDatabase)
.build()
.unwrap();
.build();
assert!(mh.reload_database().is_ok());
}
@ -187,8 +180,7 @@ mod tests {
let mut mh = MusicHoardBuilder::default()
.set_library(NullLibrary)
.set_database(NullDatabase)
.build()
.unwrap();
.build();
assert!(mh.rescan_library().is_ok());
assert!(mh.reload_database().is_ok());
}

View File

@ -504,7 +504,8 @@ mod tests {
.with(predicate::eq(collection.clone()))
.returning(|_| Ok(()));
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
music_hoard.reload_database().unwrap();
assert_eq!(music_hoard.collection, collection);
assert!(music_hoard.add_artist(artist_id.clone()).is_ok());
@ -523,11 +524,10 @@ mod tests {
#[test]
fn artist_sort_set_clear() {
let mut database = MockIDatabase::new();
database.expect_load().times(1).returning(|| Ok(vec![]));
database.expect_save().times(4).returning(|_| Ok(()));
type MH = MusicHoard<MockIDatabase, NoLibrary>;
let mut music_hoard: MH = MusicHoard::database(database).unwrap();
let mut music_hoard: MH = MusicHoard::database(database);
let artist_1_id = ArtistId::new("the artist");
let artist_1_sort = String::from("artist, the");
@ -574,9 +574,8 @@ mod tests {
#[test]
fn collection_error() {
let mut database = MockIDatabase::new();
database.expect_load().times(1).returning(|| Ok(vec![]));
let mut music_hoard = MusicHoard::database(database).unwrap();
let database = MockIDatabase::new();
let mut music_hoard = MusicHoard::database(database);
let artist_id = ArtistId::new("an artist");
let actual_err = music_hoard
@ -591,12 +590,11 @@ mod tests {
#[test]
fn set_clear_artist_mb_ref() {
let mut database = MockIDatabase::new();
database.expect_load().times(1).returning(|| Ok(vec![]));
database.expect_save().times(3).returning(|_| Ok(()));
let mut artist_id = ArtistId::new("an artist");
let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
assert!(music_hoard.add_artist(artist_id.clone()).is_ok());
@ -637,12 +635,11 @@ mod tests {
#[test]
fn set_clear_artist_info() {
let mut database = MockIDatabase::new();
database.expect_load().times(1).returning(|| Ok(vec![]));
database.expect_save().times(3).returning(|_| Ok(()));
let artist_id = ArtistId::new("an artist");
let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
assert!(music_hoard.add_artist(artist_id.clone()).is_ok());
@ -681,12 +678,11 @@ mod tests {
#[test]
fn add_to_remove_from_property() {
let mut database = MockIDatabase::new();
database.expect_load().times(1).returning(|| Ok(vec![]));
database.expect_save().times(3).returning(|_| Ok(()));
let artist_id = ArtistId::new("an artist");
let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
assert!(music_hoard.add_artist(artist_id.clone()).is_ok());
@ -730,12 +726,11 @@ mod tests {
#[test]
fn set_clear_property() {
let mut database = MockIDatabase::new();
database.expect_load().times(1).returning(|| Ok(vec![]));
database.expect_save().times(3).returning(|_| Ok(()));
let artist_id = ArtistId::new("an artist");
let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
assert!(music_hoard.add_artist(artist_id.clone()).is_ok());
@ -805,7 +800,8 @@ mod tests {
.with(predicate::eq(collection.clone()))
.returning(|_| Ok(()));
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
music_hoard.reload_database().unwrap();
assert_eq!(music_hoard.collection, collection);
assert!(music_hoard
@ -844,7 +840,8 @@ mod tests {
.return_once(|| Ok(database_result));
database.expect_save().times(2).returning(|_| Ok(()));
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
music_hoard.reload_database().unwrap();
let album = &music_hoard.collection[0].albums[0];
assert_eq!(album.meta.id.mb_ref, AlbumMbRef::None);
@ -902,7 +899,8 @@ mod tests {
.return_once(|| Ok(database_result));
database.expect_save().times(2).returning(|_| Ok(()));
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
music_hoard.reload_database().unwrap();
assert_eq!(music_hoard.collection[0].albums[0].meta.seq, AlbumSeq(0));
// Seting seq on an album not belonging to the artist is an error.
@ -941,7 +939,8 @@ mod tests {
.times(1)
.return_once(|| Ok(database_result));
database.expect_save().times(2).returning(|_| Ok(()));
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
music_hoard.reload_database().unwrap();
let meta = &music_hoard.collection[0].albums[0].meta;
assert_eq!(meta.info.primary_type, None);
@ -986,7 +985,8 @@ mod tests {
.times(1)
.return_once(|| Ok(FULL_COLLECTION.to_owned()));
let music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
music_hoard.reload_database().unwrap();
assert_eq!(music_hoard.get_collection(), &*FULL_COLLECTION);
}
@ -1002,7 +1002,8 @@ mod tests {
.times(1)
.return_once(|| database_result);
let actual_err = MusicHoard::database(database).unwrap_err();
let mut music_hoard = MusicHoard::database(database);
let actual_err = music_hoard.reload_database().unwrap_err();
let expected_err = Error::DatabaseError(
database::LoadError::IoError(String::from("I/O error")).to_string(),
);
@ -1023,7 +1024,8 @@ mod tests {
.times(1)
.return_once(|_: &Collection| database_result);
let mut music_hoard = MusicHoard::database(database).unwrap();
let mut music_hoard = MusicHoard::database(database);
music_hoard.reload_database().unwrap();
let actual_err = music_hoard
.add_artist(ArtistId::new("an artist"))

View File

@ -157,11 +157,6 @@ mod tests {
// The database contents are not relevant in this test.
let mut seq = Sequence::new();
database
.expect_load()
.times(1)
.in_sequence(&mut seq)
.returning(|| Ok(vec![]));
database
.expect_load()
.times(1)
@ -174,7 +169,7 @@ mod tests {
.in_sequence(&mut seq)
.return_once(|_| Ok(()));
let mut music_hoard = MusicHoard::new(database, library).unwrap();
let mut music_hoard = MusicHoard::new(database, library);
music_hoard.rescan_library().unwrap();
assert_eq!(music_hoard.get_collection(), &*LIBRARY_COLLECTION);

View File

@ -97,7 +97,7 @@ fn default_filter() -> CollectionFilter {
fn with<Database: IDatabase + 'static, Library: ILibrary + 'static>(
builder: MusicHoardBuilder<Database, Library>,
) {
let mut music_hoard = builder.build().expect("failed to initialise MusicHoard");
let mut music_hoard = builder.build();
music_hoard.set_filter(default_filter());
// Initialize the terminal user interface.

View File

@ -31,7 +31,7 @@ fn merge_library_then_database() {
let backend = JsonDatabaseFileBackend::new(&*database::json::DATABASE_TEST_FILE);
let database = JsonDatabase::new(backend);
let mut music_hoard = MusicHoard::new(database, library).unwrap();
let mut music_hoard = MusicHoard::new(database, library);
music_hoard.rescan_library().unwrap();
music_hoard.reload_database().unwrap();
@ -54,7 +54,7 @@ fn merge_database_then_library() {
let backend = JsonDatabaseFileBackend::new(&*database::json::DATABASE_TEST_FILE);
let database = JsonDatabase::new(backend);
let mut music_hoard = MusicHoard::new(database, library).unwrap();
let mut music_hoard = MusicHoard::new(database, library);
music_hoard.reload_database().unwrap();
music_hoard.rescan_library().unwrap();