Merge 311d5ad04248d58bc09e632a76a937e0185af1b3 into be201a2d7972d9580bef5533bfcb8bc49a2675d2

This commit is contained in:
Cristian 2026-10-16 22:16:46 +03:00 committed by GitHub
commit d75be4aae6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 1 deletions

View File

@ -506,7 +506,7 @@ func (r *mediaFileRepository) GetMissingAndMatching(ctx context.Context, libId i
Where("pid in ("+subQText+")", subQArgs...).
Where(Or{
Eq{"missing": true},
ConcatExpr("media_file.created_at > library.last_scan_started_at"),
ConcatExpr("media_file.created_at >= library.last_scan_started_at"),
}).
OrderBy("pid")
cursor, err := queryWithStableResults[dbMediaFile](ctx, r.sqlRepository, sel)

View File

@ -378,6 +378,50 @@ var _ = Describe("MediaRepository", func() {
Expect(err).To(MatchError(model.ErrNotFound))
})
Describe("GetMissingAndMatching", func() {
var lastScanStartedAt time.Time
BeforeEach(func() {
lib, err := NewLibraryRepository(GetDBXBuilder()).Get(ctx, 1)
Expect(err).ToNot(HaveOccurred())
lastScanStartedAt = lib.LastScanStartedAt
})
AfterEach(func() {
_, err := GetDBXBuilder().NewQuery("UPDATE library SET last_scan_started_at = {:t} WHERE id = 1").
Bind(dbx.Params{"t": lastScanStartedAt}).Execute()
Expect(err).ToNot(HaveOccurred())
})
// A coarse clock (15.6 ms on Windows) can give the scan start and a track
// written in the same scan the same timestamp (#6342)
It("matches a track created at the same instant the scan started", func() {
scanStart := time.Now()
_, err := GetDBXBuilder().NewQuery("UPDATE library SET last_scan_started_at = {:t} WHERE id = 1").
Bind(dbx.Params{"t": scanStart}).Execute()
Expect(err).ToNot(HaveOccurred())
pid := id.NewRandom()
missing := model.MediaFile{ID: id.NewRandom(), LibraryID: 1, PID: pid, Path: "old/moved.mp3"}
moved := model.MediaFile{ID: id.NewRandom(), LibraryID: 1, PID: pid, Path: "new/moved.mp3", CreatedAt: scanStart}
Expect(mr.Put(ctx, &missing)).To(Succeed())
Expect(mr.MarkMissing(ctx, true, &missing)).To(Succeed())
Expect(mr.Put(ctx, &moved)).To(Succeed())
DeferCleanup(func() { _ = mr.Delete(ctx, missing.ID); _ = mr.Delete(ctx, moved.ID) })
cursor, err := mr.GetMissingAndMatching(ctx, 1)
Expect(err).ToNot(HaveOccurred())
var ids []string
for mf, err := range cursor {
Expect(err).ToNot(HaveOccurred())
if mf.PID == pid {
ids = append(ids, mf.ID)
}
}
Expect(ids).To(ConsistOf(missing.ID, moved.ID))
})
})
It("deletes all missing files", func() {
new1 := model.MediaFile{ID: id.NewRandom(), LibraryID: 1}
new2 := model.MediaFile{ID: id.NewRandom(), LibraryID: 1}