Merge pull request 'fix(library): drop out-of-range release years instead of failing the album' (#12) from dev into main
This commit was merged in pull request #12.
This commit is contained in:
@@ -208,15 +208,33 @@ func (s *Scanner) resolveAlbum(ctx context.Context, q *dbq.Queries, artistID pgt
|
||||
SortTitle: sortKey(title),
|
||||
ArtistID: artistID,
|
||||
}
|
||||
if year > 0 {
|
||||
params.ReleaseDate = pgtype.Date{
|
||||
Time: time.Date(year, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
Valid: true,
|
||||
}
|
||||
if d, ok := releaseDateFromYear(year); ok {
|
||||
params.ReleaseDate = d
|
||||
} else if year != 0 {
|
||||
// year=0 is the no-tag case; anything else getting rejected is a tag
|
||||
// we couldn't trust (typo, OOB number, …). Log it so users can chase
|
||||
// down the file but don't fail the album insert over a soft field.
|
||||
s.logger.Warn("library scan: dropping invalid release year",
|
||||
"year", year, "album", title)
|
||||
}
|
||||
return q.UpsertAlbum(ctx, params)
|
||||
}
|
||||
|
||||
// releaseDateFromYear converts a tag-supplied year into a Postgres date,
|
||||
// returning ok=false if the year is outside what we'll accept. We're
|
||||
// deliberately strict (1..9999): Postgres' date type goes much wider, but
|
||||
// 5-digit years from ID3 tags are always garbage in practice and trigger
|
||||
// SQLSTATE 22008 (datetime field overflow) at insert time.
|
||||
func releaseDateFromYear(year int) (pgtype.Date, bool) {
|
||||
if year < 1 || year > 9999 {
|
||||
return pgtype.Date{}, false
|
||||
}
|
||||
return pgtype.Date{
|
||||
Time: time.Date(year, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
Valid: true,
|
||||
}, true
|
||||
}
|
||||
|
||||
// sortKey drops a leading "The " for sortable ordering. Non-English articles
|
||||
// (Los, Die, Les) can be added if users ask — keeping the rule obvious for now.
|
||||
func sortKey(s string) string {
|
||||
|
||||
@@ -16,6 +16,31 @@ import (
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||
)
|
||||
|
||||
func TestReleaseDateFromYear(t *testing.T) {
|
||||
cases := []struct {
|
||||
in int
|
||||
ok bool
|
||||
label string
|
||||
}{
|
||||
{0, false, "missing tag"},
|
||||
{-1, false, "negative"},
|
||||
{1, true, "lower bound"},
|
||||
{1999, true, "ordinary"},
|
||||
{9999, true, "upper bound"},
|
||||
{10000, false, "five digits"},
|
||||
{99999999, false, "tag corruption"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got, ok := releaseDateFromYear(c.in)
|
||||
if ok != c.ok {
|
||||
t.Errorf("%s: ok = %v, want %v", c.label, ok, c.ok)
|
||||
}
|
||||
if ok && (!got.Valid || got.Time.Year() != c.in) {
|
||||
t.Errorf("%s: date = %+v, want year=%d", c.label, got, c.in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestScanner_Integration exercises walk → tag-parse → upsert → incremental
|
||||
// skip against a real Postgres. Gated on MINSTREL_TEST_DATABASE_URL.
|
||||
func TestScanner_Integration(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user