From bbd427435318d871d4df4e2e302a839674c6b989 Mon Sep 17 00:00:00 2001 From: Nathan Cannon Date: Sat, 26 Mar 2016 14:07:55 +0000 Subject: [PATCH] Library updates now attempt to remove songs that weren't indexed during the update. --- .../musicplayer/db/HibernateDatabase.java | 29 +++++++++++++++---- src/main/java/musicplayer/db/IDatabase.java | 3 +- .../java/musicplayer/library/ILibrary.java | 8 ++++- .../musicplayer/db/HibernateDatabaseTest.java | 19 +++++++++++- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/main/java/musicplayer/db/HibernateDatabase.java b/src/main/java/musicplayer/db/HibernateDatabase.java index cbc6f3b..cdb2f70 100644 --- a/src/main/java/musicplayer/db/HibernateDatabase.java +++ b/src/main/java/musicplayer/db/HibernateDatabase.java @@ -104,6 +104,21 @@ public class HibernateDatabase implements IDatabase{ } } + /** + * Delete all songs that don't have ids in the given list. + * @param ids List of songs to keep. + */ + public void batchDeleteNot(Long[] ids){ + try(Session session = getSession()) { + session.beginTransaction(); + @SuppressWarnings("unchecked") + List songs = (List)session.createCriteria(Song.class).add(Restrictions.not(Restrictions.in("id", ids))).list(); + if(songs != null && !songs.isEmpty()) + songs.forEach(session::delete); + session.getTransaction().commit(); + } + } + /** * @param target Data of song to find in database. * @return Song found with metadata or Optional.empty() @@ -134,7 +149,7 @@ public class HibernateDatabase implements IDatabase{ * If the song already exists it will be updated instead. * @param metadata New song information. */ - public void addSong(ExtractedMetadata metadata) { + public Song addSong(ExtractedMetadata metadata) { try (Session session = getSession()) { session.beginTransaction(); Optional albumObj = getOneAlbum(metadata.getAlbum()); @@ -151,16 +166,20 @@ public class HibernateDatabase implements IDatabase{ artistObj = Optional.of(artist); } Optional songObj = getOneSong(metadata); - if(!songObj.isPresent()) - session.save(new Song(metadata.getTrackNumber(), metadata.getDiscNumber(), metadata.getTitle(), artistObj.get(), - albumObj.get(), metadata.getGenre(), metadata.getSongFile())); + Song song; + if(!songObj.isPresent()) { + song = new Song(metadata.getTrackNumber(), metadata.getDiscNumber(), metadata.getTitle(), artistObj.get(), + albumObj.get(), metadata.getGenre(), metadata.getSongFile()); + session.save(song); + } else { - Song song = songObj.get(); + song = songObj.get(); song.updateData(metadata.getTrackNumber(), metadata.getDiscNumber(), metadata.getTitle(), artistObj.get(), albumObj.get(), metadata.getGenre(), metadata.getSongFile()); session.merge(song); } session.getTransaction().commit(); + return song; } } diff --git a/src/main/java/musicplayer/db/IDatabase.java b/src/main/java/musicplayer/db/IDatabase.java index aa8bd9a..d3a9da0 100644 --- a/src/main/java/musicplayer/db/IDatabase.java +++ b/src/main/java/musicplayer/db/IDatabase.java @@ -9,7 +9,8 @@ public interface IDatabase { Optional getOneAlbum(String name); Optional getOneArtist(String name); Optional getOneSong(ExtractedMetadata metadata); + void batchDeleteNot(Long[] validIds); Optional> listAllT(Class typeClass); - void addSong(ExtractedMetadata metadata); + Song addSong(ExtractedMetadata metadata); void addSong(Song song); } diff --git a/src/main/java/musicplayer/library/ILibrary.java b/src/main/java/musicplayer/library/ILibrary.java index 68cf167..28a68a5 100644 --- a/src/main/java/musicplayer/library/ILibrary.java +++ b/src/main/java/musicplayer/library/ILibrary.java @@ -4,6 +4,7 @@ import musicplayer.callbacks.LibraryCallbackInterface; import musicplayer.db.IDatabase; import musicplayer.model.ExtractedMetadata; import musicplayer.model.HasSongs; +import musicplayer.model.Song; import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.audio.exceptions.CannotReadException; import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException; @@ -14,8 +15,10 @@ import org.jaudiotagger.tag.TagException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; public interface ILibrary { void showSongs(); @@ -34,13 +37,16 @@ public interface ILibrary { boolean callbacksEnabled = callbackInterface != null; rootDirectory.forEach(dir -> { try { + Set seenIds = new HashSet<>(); Files.walk(dir) .filter(f -> f.toString().matches(musicFileExtensionRegex)).map(ILibrary::autoParse) .forEach(x -> x.ifPresent(i -> { - database.addSong(i); + Song song = database.addSong(i); + seenIds.add(song.getId()); if (callbacksEnabled) callbackInterface.currentlyUpdating(i.toString()); })); + database.batchDeleteNot(seenIds.toArray(new Long[seenIds.size()])); } catch (IOException e) { if(callbacksEnabled) callbackInterface.libraryUpdated(e.getMessage()); diff --git a/src/test/java/musicplayer/db/HibernateDatabaseTest.java b/src/test/java/musicplayer/db/HibernateDatabaseTest.java index 0edf950..d5c43ea 100644 --- a/src/test/java/musicplayer/db/HibernateDatabaseTest.java +++ b/src/test/java/musicplayer/db/HibernateDatabaseTest.java @@ -14,6 +14,7 @@ import java.io.File; import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class HibernateDatabaseTest { @@ -197,6 +198,22 @@ public class HibernateDatabaseTest { Artist newArtist = new Artist("Test 2"); Song newSong = new Song("2", "2", "s2", newArtist, newAlbum, "g2", ""); // File same == Song same database.addSong(newSong); - assertEquals(database.listAllT(Song.class).get().size(), 1); + assertEquals(1, database.listAllT(Song.class).get().size()); + } + + @Test + public void testDeleteBatchNot() { + Song song1 = new Song("1", "1", "s1", new Artist("a"), new Album("a"), "", "1"); + Song song2 = new Song("2", "1","s2", new Artist("b"), new Album("a"), "", "2"); + Song song3 = new Song("1", "1","t1", new Artist("c"), new Album("b"), "", "3"); + database.addSong(song1); + database.addSong(song2); + database.addSong(song3); + database.batchDeleteNot(new Long[]{song1.getId(), song2.getId()}); + List db = database.listAllT(Song.class).get(); + assertEquals(2, db.size()); + assertTrue(db.contains(song1)); + assertTrue(db.contains(song2)); + assertFalse(db.contains(song3)); } } \ No newline at end of file