diff --git a/scanner/scanner.go b/scanner/scanner.go index aefa4c11..3da322f0 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -610,20 +610,34 @@ func (s *Scanner) cleanGenres(st *State) error { //nolint:unparam subTrack := s.db. Select("genres.id"). - Model(&db.Genre{}). + Model(db.Genre{}). Joins("LEFT JOIN track_genres ON track_genres.genre_id=genres.id"). Where("track_genres.genre_id IS NULL"). SubQuery() subAlbum := s.db. Select("genres.id"). - Model(&db.Genre{}). + Model(db.Genre{}). Joins("LEFT JOIN album_genres ON album_genres.genre_id=genres.id"). Where("album_genres.genre_id IS NULL"). SubQuery() q := s.db. Where("genres.id IN ? AND genres.id IN ?", subTrack, subAlbum). - Delete(&db.Genre{}) - st.genresMissing = int(q.RowsAffected) + Delete(db.Genre{}) + st.genresMissing += int(q.RowsAffected) + + subAlbumGenresNoTracks := s.db. + Select("album_genres.genre_id"). + Model(db.AlbumGenre{}). + Joins("JOIN albums ON albums.id=album_genres.album_id"). + Joins("LEFT JOIN tracks ON tracks.album_id=albums.id"). + Group("album_genres.genre_id"). + Having("count(tracks.id)=0"). + SubQuery() + q = s.db. + Where("genres.id IN ?", subAlbumGenresNoTracks). + Delete(db.Genre{}) + st.genresMissing += int(q.RowsAffected) + return nil } diff --git a/scanner/scanner_test.go b/scanner/scanner_test.go index 77f4b1c6..c49b6f86 100644 --- a/scanner/scanner_test.go +++ b/scanner/scanner_test.go @@ -643,6 +643,41 @@ func TestNoOrphanedGenres(t *testing.T) { assert.Equal(t, 0, genreCount) } +// https://github.com/sentriz/gonic/issues/466 +func TestNoOrphanedGenresButOnlyDeleteTracks(t *testing.T) { + t.Parallel() + m := mockfs.New(t) + + m.AddItems() + m.SetTags("artist-0/album-0/track-0.flac", func(tags *mockfs.TagInfo) { tags.RawGenre = "genre-a" }) + m.ScanAndClean() + + trackPaths, err := filepath.Glob(filepath.Join(m.TmpDir(), "*", "*", "*.flac")) + assert.NoError(t, err) + + for _, path := range trackPaths { + assert.NoError(t, os.Remove(path)) + } + + m.ScanAndClean() + + var tracks []*db.Track + assert.NoError(t, m.DB().Find(&tracks).Error) + assert.Len(t, tracks, 0) + + var genres []*db.Genre + assert.NoError(t, m.DB().Find(&genres).Error) + assert.Len(t, genres, 0) + + var trackGenres []*db.TrackGenre + assert.NoError(t, m.DB().Find(&trackGenres).Error) + assert.Len(t, trackGenres, 0) + + var albumGenres []*db.AlbumGenre + assert.NoError(t, m.DB().Find(&albumGenres).Error) + assert.Len(t, albumGenres, 0) +} + func TestMultiArtistSupport(t *testing.T) { t.Parallel() m := mockfs.New(t)