From f8597727234bee53de31a5fe404046f7a2c6fea8 Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 2 Oct 2020 16:18:45 -0400 Subject: [PATCH] Remove dangling tracks after changing MusicFolder. Fix #445 --- model/datastore.go | 2 +- persistence/mediafile_repository.go | 13 ++++++++++++- persistence/mock_persistence.go | 2 +- persistence/persistence.go | 9 +++++++-- scanner/tag_scanner.go | 14 ++++++-------- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/model/datastore.go b/model/datastore.go index 819323ec6..136083b53 100644 --- a/model/datastore.go +++ b/model/datastore.go @@ -35,5 +35,5 @@ type DataStore interface { Resource(ctx context.Context, model interface{}) ResourceRepository WithTx(func(tx DataStore) error) error - GC(ctx context.Context) error + GC(ctx context.Context, rootFolder string) error } diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go index 8abf30e53..ffda9c17b 100644 --- a/persistence/mediafile_repository.go +++ b/persistence/mediafile_repository.go @@ -108,7 +108,7 @@ func (r mediaFileRepository) FindAllByPath(path string) (model.MediaFiles, error return res, err } -func pathStartsWith(path string) Sqlizer { +func pathStartsWith(path string) Eq { cleanPath := filepath.Clean(path) substr := fmt.Sprintf("substr(path, 1, %d)", utf8.RuneCountInString(cleanPath)) return Eq{substr: cleanPath} @@ -124,6 +124,17 @@ func (r mediaFileRepository) FindPathsRecursively(basePath string) ([]string, er return res, err } +func (r mediaFileRepository) deleteNotInPath(basePath string) error { + sel := Delete(r.tableName).Where(NotEq(pathStartsWith(basePath))) + c, err := r.executeSQL(sel) + if err == nil { + if c > 0 { + log.Debug(r.ctx, "Deleted dangling tracks", "totalDeleted", c) + } + } + return err +} + func (r mediaFileRepository) GetStarred(options ...model.QueryOptions) (model.MediaFiles, error) { sq := r.selectMediaFile(options...).Where("starred = true") starred := model.MediaFiles{} diff --git a/persistence/mock_persistence.go b/persistence/mock_persistence.go index e956831b5..3f88e8600 100644 --- a/persistence/mock_persistence.go +++ b/persistence/mock_persistence.go @@ -89,7 +89,7 @@ func (db *MockDataStore) Resource(ctx context.Context, m interface{}) model.Reso return struct{ model.ResourceRepository }{} } -func (db *MockDataStore) GC(ctx context.Context) error { +func (db *MockDataStore) GC(ctx context.Context, rootFolder string) error { return nil } diff --git a/persistence/persistence.go b/persistence/persistence.go index fac59e71f..eabe52d9f 100644 --- a/persistence/persistence.go +++ b/persistence/persistence.go @@ -111,8 +111,13 @@ func (s *SQLStore) WithTx(block func(tx model.DataStore) error) error { return nil } -func (s *SQLStore) GC(ctx context.Context) error { - err := s.Album(ctx).(*albumRepository).purgeEmpty() +func (s *SQLStore) GC(ctx context.Context, rootFolder string) error { + err := s.MediaFile(ctx).(*mediaFileRepository).deleteNotInPath(rootFolder) + if err != nil { + log.Error(ctx, "Error removing dangling tracks", err) + return err + } + err = s.Album(ctx).(*albumRepository).purgeEmpty() if err != nil { log.Error(ctx, "Error removing empty albums", err) return err diff --git a/scanner/tag_scanner.go b/scanner/tag_scanner.go index 13b95ae54..b9369f9f9 100644 --- a/scanner/tag_scanner.go +++ b/scanner/tag_scanner.go @@ -33,13 +33,11 @@ func NewTagScanner(rootFolder string, ds model.DataStore) *TagScanner { } } -type ( - counters struct { - added int64 - updated int64 - deleted int64 - } -) +type counters struct { + added int64 + updated int64 + deleted int64 +} const ( // filesBatchSize used for batching file metadata extraction @@ -125,7 +123,7 @@ func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time) erro log.Debug("Playlist auto-import is disabled") } - err = s.ds.GC(log.NewContext(ctx)) + err = s.ds.GC(log.NewContext(ctx), s.rootFolder) log.Info("Finished processing Music Folder", "folder", s.rootFolder, "elapsed", time.Since(start), "added", s.cnt.added, "updated", s.cnt.updated, "deleted", s.cnt.deleted, "playlistsImported", plsCount)