Library updates now attempt to remove songs that weren't indexed during the update.

This commit is contained in:
neviyn 2016-03-26 14:07:55 +00:00
parent 43b7585cd1
commit bbd4274353
4 changed files with 51 additions and 8 deletions

View File

@ -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<Song> songs = (List<Song>)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. * @param target Data of song to find in database.
* @return Song found with metadata or Optional.empty() * @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. * If the song already exists it will be updated instead.
* @param metadata New song information. * @param metadata New song information.
*/ */
public void addSong(ExtractedMetadata metadata) { public Song addSong(ExtractedMetadata metadata) {
try (Session session = getSession()) { try (Session session = getSession()) {
session.beginTransaction(); session.beginTransaction();
Optional<Album> albumObj = getOneAlbum(metadata.getAlbum()); Optional<Album> albumObj = getOneAlbum(metadata.getAlbum());
@ -151,16 +166,20 @@ public class HibernateDatabase implements IDatabase{
artistObj = Optional.of(artist); artistObj = Optional.of(artist);
} }
Optional<Song> songObj = getOneSong(metadata); Optional<Song> songObj = getOneSong(metadata);
if(!songObj.isPresent()) Song song;
session.save(new Song(metadata.getTrackNumber(), metadata.getDiscNumber(), metadata.getTitle(), artistObj.get(), if(!songObj.isPresent()) {
albumObj.get(), metadata.getGenre(), metadata.getSongFile())); song = new Song(metadata.getTrackNumber(), metadata.getDiscNumber(), metadata.getTitle(), artistObj.get(),
albumObj.get(), metadata.getGenre(), metadata.getSongFile());
session.save(song);
}
else { else {
Song song = songObj.get(); song = songObj.get();
song.updateData(metadata.getTrackNumber(), metadata.getDiscNumber(), metadata.getTitle(), artistObj.get(), song.updateData(metadata.getTrackNumber(), metadata.getDiscNumber(), metadata.getTitle(), artistObj.get(),
albumObj.get(), metadata.getGenre(), metadata.getSongFile()); albumObj.get(), metadata.getGenre(), metadata.getSongFile());
session.merge(song); session.merge(song);
} }
session.getTransaction().commit(); session.getTransaction().commit();
return song;
} }
} }

View File

@ -9,7 +9,8 @@ public interface IDatabase {
Optional<Album> getOneAlbum(String name); Optional<Album> getOneAlbum(String name);
Optional<Artist> getOneArtist(String name); Optional<Artist> getOneArtist(String name);
Optional<Song> getOneSong(ExtractedMetadata metadata); Optional<Song> getOneSong(ExtractedMetadata metadata);
void batchDeleteNot(Long[] validIds);
<T extends IDBType> Optional<List<T>> listAllT(Class<T> typeClass); <T extends IDBType> Optional<List<T>> listAllT(Class<T> typeClass);
void addSong(ExtractedMetadata metadata); Song addSong(ExtractedMetadata metadata);
void addSong(Song song); void addSong(Song song);
} }

View File

@ -4,6 +4,7 @@ import musicplayer.callbacks.LibraryCallbackInterface;
import musicplayer.db.IDatabase; import musicplayer.db.IDatabase;
import musicplayer.model.ExtractedMetadata; import musicplayer.model.ExtractedMetadata;
import musicplayer.model.HasSongs; import musicplayer.model.HasSongs;
import musicplayer.model.Song;
import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException; import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException; import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
@ -14,8 +15,10 @@ import org.jaudiotagger.tag.TagException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
public interface ILibrary { public interface ILibrary {
void showSongs(); void showSongs();
@ -34,13 +37,16 @@ public interface ILibrary {
boolean callbacksEnabled = callbackInterface != null; boolean callbacksEnabled = callbackInterface != null;
rootDirectory.forEach(dir -> { rootDirectory.forEach(dir -> {
try { try {
Set<Long> seenIds = new HashSet<>();
Files.walk(dir) Files.walk(dir)
.filter(f -> f.toString().matches(musicFileExtensionRegex)).map(ILibrary::autoParse) .filter(f -> f.toString().matches(musicFileExtensionRegex)).map(ILibrary::autoParse)
.forEach(x -> x.ifPresent(i -> { .forEach(x -> x.ifPresent(i -> {
database.addSong(i); Song song = database.addSong(i);
seenIds.add(song.getId());
if (callbacksEnabled) if (callbacksEnabled)
callbackInterface.currentlyUpdating(i.toString()); callbackInterface.currentlyUpdating(i.toString());
})); }));
database.batchDeleteNot(seenIds.toArray(new Long[seenIds.size()]));
} catch (IOException e) { } catch (IOException e) {
if(callbacksEnabled) if(callbacksEnabled)
callbackInterface.libraryUpdated(e.getMessage()); callbackInterface.libraryUpdated(e.getMessage());

View File

@ -14,6 +14,7 @@ import java.io.File;
import java.util.List; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class HibernateDatabaseTest { public class HibernateDatabaseTest {
@ -197,6 +198,22 @@ public class HibernateDatabaseTest {
Artist newArtist = new Artist("Test 2"); Artist newArtist = new Artist("Test 2");
Song newSong = new Song("2", "2", "s2", newArtist, newAlbum, "g2", ""); // File same == Song same Song newSong = new Song("2", "2", "s2", newArtist, newAlbum, "g2", ""); // File same == Song same
database.addSong(newSong); 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<Song> db = database.listAllT(Song.class).get();
assertEquals(2, db.size());
assertTrue(db.contains(song1));
assertTrue(db.contains(song2));
assertFalse(db.contains(song3));
} }
} }