From e84378099f9591d7e074bab37ef88c1f075a4f41 Mon Sep 17 00:00:00 2001 From: Deluan Date: Wed, 8 Jul 2026 17:47:49 -0400 Subject: [PATCH] refactor: apply cleanup review findings - drop forceFullRescan's inline ANALYZE: Init already runs a full ANALYZE after any migration batch with schema changes, so upgrades including a full-rescan migration analyzed the whole DB twice - resumingFullScan uses a filtered CountAll instead of fetching and scanning all libraries - document why CallScan (CLI) deliberately skips the post-scan Optimize --- db/migrations/migration.go | 4 ---- scanner/controller.go | 12 +++++------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/db/migrations/migration.go b/db/migrations/migration.go index 0aec63fb9..df1c392a5 100644 --- a/db/migrations/migration.go +++ b/db/migrations/migration.go @@ -20,10 +20,6 @@ func notice(ctx context.Context, tx *sql.Tx, msg string) { // Call this in migrations that requires a full rescan func forceFullRescan(ctx context.Context, tx *sql.Tx) error { - // If a full scan is required, most probably the query optimizer is outdated, so we run `analyze`. - if _, err := tx.ExecContext(ctx, `ANALYZE;`); err != nil { - return err - } _, err := tx.ExecContext(ctx, fmt.Sprintf(` INSERT OR REPLACE into property (id, value) values ('%s', '1'); `, consts.FullScanAfterMigrationFlagKey)) diff --git a/scanner/controller.go b/scanner/controller.go index 118515d28..346d728a9 100644 --- a/scanner/controller.go +++ b/scanner/controller.go @@ -4,10 +4,10 @@ import ( "context" "errors" "fmt" - "slices" "sync/atomic" "time" + "github.com/Masterminds/squirrel" "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/consts" "github.com/navidrome/navidrome/core/artwork" @@ -53,7 +53,8 @@ func (s *controller) getScanner() scanner { // CallScan starts an in-process scan of specific library/folder pairs. // If targets is empty, it scans all libraries. -// This is meant to be called from the command line (see cmd/scan.go). +// This is meant to be called from the command line (see cmd/scan.go). It deliberately skips the +// post-scan Optimize: the daily job and the post-migration ANALYZE keep the statistics healthy. func CallScan(ctx context.Context, ds model.DataStore, pls playlists.Playlists, fullScan bool, targets []model.ScanTarget) (<-chan *ProgressInfo, error) { release, err := lockScan(ctx) if err != nil { @@ -285,11 +286,8 @@ func lockScan(ctx context.Context) (func(), error) { // resumingFullScan reports whether any library still has an interrupted full scan to resume. func (s *controller) resumingFullScan(ctx context.Context) bool { - libs, err := s.ds.Library(ctx).GetAll() - if err != nil { - return false - } - return slices.ContainsFunc(libs, func(lib model.Library) bool { return lib.FullScanInProgress }) + count, err := s.ds.Library(ctx).CountAll(model.QueryOptions{Filters: squirrel.Eq{"full_scan_in_progress": true}}) + return err == nil && count > 0 } func (s *controller) trackProgress(ctx context.Context, progress <-chan *ProgressInfo) ([]string, error) {