Remove dangling tracks after changing MusicFolder. Fix #445

This commit is contained in:
Deluan 2020-10-02 16:18:45 -04:00
parent 1be79fa945
commit f859772723
5 changed files with 27 additions and 13 deletions

View file

@ -35,5 +35,5 @@ type DataStore interface {
Resource(ctx context.Context, model interface{}) ResourceRepository Resource(ctx context.Context, model interface{}) ResourceRepository
WithTx(func(tx DataStore) error) error WithTx(func(tx DataStore) error) error
GC(ctx context.Context) error GC(ctx context.Context, rootFolder string) error
} }

View file

@ -108,7 +108,7 @@ func (r mediaFileRepository) FindAllByPath(path string) (model.MediaFiles, error
return res, err return res, err
} }
func pathStartsWith(path string) Sqlizer { func pathStartsWith(path string) Eq {
cleanPath := filepath.Clean(path) cleanPath := filepath.Clean(path)
substr := fmt.Sprintf("substr(path, 1, %d)", utf8.RuneCountInString(cleanPath)) substr := fmt.Sprintf("substr(path, 1, %d)", utf8.RuneCountInString(cleanPath))
return Eq{substr: cleanPath} return Eq{substr: cleanPath}
@ -124,6 +124,17 @@ func (r mediaFileRepository) FindPathsRecursively(basePath string) ([]string, er
return res, err 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) { func (r mediaFileRepository) GetStarred(options ...model.QueryOptions) (model.MediaFiles, error) {
sq := r.selectMediaFile(options...).Where("starred = true") sq := r.selectMediaFile(options...).Where("starred = true")
starred := model.MediaFiles{} starred := model.MediaFiles{}

View file

@ -89,7 +89,7 @@ func (db *MockDataStore) Resource(ctx context.Context, m interface{}) model.Reso
return struct{ model.ResourceRepository }{} return struct{ model.ResourceRepository }{}
} }
func (db *MockDataStore) GC(ctx context.Context) error { func (db *MockDataStore) GC(ctx context.Context, rootFolder string) error {
return nil return nil
} }

View file

@ -111,8 +111,13 @@ func (s *SQLStore) WithTx(block func(tx model.DataStore) error) error {
return nil return nil
} }
func (s *SQLStore) GC(ctx context.Context) error { func (s *SQLStore) GC(ctx context.Context, rootFolder string) error {
err := s.Album(ctx).(*albumRepository).purgeEmpty() 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 { if err != nil {
log.Error(ctx, "Error removing empty albums", err) log.Error(ctx, "Error removing empty albums", err)
return err return err

View file

@ -33,13 +33,11 @@ func NewTagScanner(rootFolder string, ds model.DataStore) *TagScanner {
} }
} }
type ( type counters struct {
counters struct { added int64
added int64 updated int64
updated int64 deleted int64
deleted int64 }
}
)
const ( const (
// filesBatchSize used for batching file metadata extraction // 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") 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), 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) "added", s.cnt.added, "updated", s.cnt.updated, "deleted", s.cnt.deleted, "playlistsImported", plsCount)