feat(server/m7-379): heal existing artist+album mbid on rescan
This commit is contained in:
@@ -515,6 +515,25 @@ func (q *Queries) SearchAlbums(ctx context.Context, arg SearchAlbumsParams) ([]A
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setAlbumMbidIfNull = `-- name: SetAlbumMbidIfNull :exec
|
||||||
|
UPDATE albums
|
||||||
|
SET mbid = $2,
|
||||||
|
updated_at = now()
|
||||||
|
WHERE id = $1 AND mbid IS NULL
|
||||||
|
`
|
||||||
|
|
||||||
|
type SetAlbumMbidIfNullParams struct {
|
||||||
|
ID pgtype.UUID
|
||||||
|
Mbid *string
|
||||||
|
}
|
||||||
|
|
||||||
|
// M7 #379: heal MBID on existing album rows during rescan. Idempotent —
|
||||||
|
// only updates when the existing mbid is NULL.
|
||||||
|
func (q *Queries) SetAlbumMbidIfNull(ctx context.Context, arg SetAlbumMbidIfNullParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, setAlbumMbidIfNull, arg.ID, arg.Mbid)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const upsertAlbum = `-- name: UpsertAlbum :one
|
const upsertAlbum = `-- name: UpsertAlbum :one
|
||||||
INSERT INTO albums (title, sort_title, artist_id, release_date, mbid, cover_art_path)
|
INSERT INTO albums (title, sort_title, artist_id, release_date, mbid, cover_art_path)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
|
|||||||
@@ -327,6 +327,26 @@ func (q *Queries) SearchArtists(ctx context.Context, arg SearchArtistsParams) ([
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setArtistMbidIfNull = `-- name: SetArtistMbidIfNull :exec
|
||||||
|
UPDATE artists
|
||||||
|
SET mbid = $2,
|
||||||
|
updated_at = now()
|
||||||
|
WHERE id = $1 AND mbid IS NULL
|
||||||
|
`
|
||||||
|
|
||||||
|
type SetArtistMbidIfNullParams struct {
|
||||||
|
ID pgtype.UUID
|
||||||
|
Mbid *string
|
||||||
|
}
|
||||||
|
|
||||||
|
// M7 #379: heal MBID on existing artist rows during rescan. Idempotent —
|
||||||
|
// only updates when the existing mbid is NULL, so concurrent scans don't
|
||||||
|
// overwrite an existing value with a stale one.
|
||||||
|
func (q *Queries) SetArtistMbidIfNull(ctx context.Context, arg SetArtistMbidIfNullParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, setArtistMbidIfNull, arg.ID, arg.Mbid)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const upsertArtist = `-- name: UpsertArtist :one
|
const upsertArtist = `-- name: UpsertArtist :one
|
||||||
INSERT INTO artists (name, sort_name, mbid)
|
INSERT INTO artists (name, sort_name, mbid)
|
||||||
VALUES ($1, $2, $3)
|
VALUES ($1, $2, $3)
|
||||||
|
|||||||
@@ -96,3 +96,11 @@ DELETE FROM albums a
|
|||||||
WHERE a.id = $1
|
WHERE a.id = $1
|
||||||
AND NOT EXISTS (SELECT 1 FROM tracks t WHERE t.album_id = a.id)
|
AND NOT EXISTS (SELECT 1 FROM tracks t WHERE t.album_id = a.id)
|
||||||
RETURNING a.id, a.artist_id;
|
RETURNING a.id, a.artist_id;
|
||||||
|
|
||||||
|
-- name: SetAlbumMbidIfNull :exec
|
||||||
|
-- M7 #379: heal MBID on existing album rows during rescan. Idempotent —
|
||||||
|
-- only updates when the existing mbid is NULL.
|
||||||
|
UPDATE albums
|
||||||
|
SET mbid = $2,
|
||||||
|
updated_at = now()
|
||||||
|
WHERE id = $1 AND mbid IS NULL;
|
||||||
|
|||||||
@@ -74,3 +74,12 @@ WHERE a.id = $1
|
|||||||
AND NOT EXISTS (SELECT 1 FROM albums al WHERE al.artist_id = a.id)
|
AND NOT EXISTS (SELECT 1 FROM albums al WHERE al.artist_id = a.id)
|
||||||
AND NOT EXISTS (SELECT 1 FROM tracks t WHERE t.artist_id = a.id)
|
AND NOT EXISTS (SELECT 1 FROM tracks t WHERE t.artist_id = a.id)
|
||||||
RETURNING a.id;
|
RETURNING a.id;
|
||||||
|
|
||||||
|
-- name: SetArtistMbidIfNull :exec
|
||||||
|
-- M7 #379: heal MBID on existing artist rows during rescan. Idempotent —
|
||||||
|
-- only updates when the existing mbid is NULL, so concurrent scans don't
|
||||||
|
-- overwrite an existing value with a stale one.
|
||||||
|
UPDATE artists
|
||||||
|
SET mbid = $2,
|
||||||
|
updated_at = now()
|
||||||
|
WHERE id = $1 AND mbid IS NULL;
|
||||||
|
|||||||
@@ -201,6 +201,19 @@ func (s *Scanner) scanFile(ctx context.Context, q *dbq.Queries, path string, sta
|
|||||||
func (s *Scanner) resolveArtist(ctx context.Context, q *dbq.Queries, name, mbid string) (dbq.Artist, error) {
|
func (s *Scanner) resolveArtist(ctx context.Context, q *dbq.Queries, name, mbid string) (dbq.Artist, error) {
|
||||||
existing, err := q.GetArtistByName(ctx, name)
|
existing, err := q.GetArtistByName(ctx, name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
// Heal: backfill mbid on a previously-imported row if we have one now.
|
||||||
|
if mbid != "" && (existing.Mbid == nil || *existing.Mbid == "") {
|
||||||
|
m := mbid
|
||||||
|
if uerr := q.SetArtistMbidIfNull(ctx, dbq.SetArtistMbidIfNullParams{
|
||||||
|
ID: existing.ID,
|
||||||
|
Mbid: &m,
|
||||||
|
}); uerr != nil {
|
||||||
|
s.logger.Warn("library scan: heal artist mbid failed",
|
||||||
|
"artist_id", existing.ID, "err", uerr)
|
||||||
|
} else {
|
||||||
|
existing.Mbid = &m
|
||||||
|
}
|
||||||
|
}
|
||||||
return existing, nil
|
return existing, nil
|
||||||
}
|
}
|
||||||
if !errors.Is(err, pgx.ErrNoRows) {
|
if !errors.Is(err, pgx.ErrNoRows) {
|
||||||
@@ -220,6 +233,19 @@ func (s *Scanner) resolveArtist(ctx context.Context, q *dbq.Queries, name, mbid
|
|||||||
func (s *Scanner) resolveAlbum(ctx context.Context, q *dbq.Queries, artistID pgtype.UUID, title string, year int, mbid string) (dbq.Album, error) {
|
func (s *Scanner) resolveAlbum(ctx context.Context, q *dbq.Queries, artistID pgtype.UUID, title string, year int, mbid string) (dbq.Album, error) {
|
||||||
existing, err := q.GetAlbumByArtistAndTitle(ctx, dbq.GetAlbumByArtistAndTitleParams{ArtistID: artistID, Title: title})
|
existing, err := q.GetAlbumByArtistAndTitle(ctx, dbq.GetAlbumByArtistAndTitleParams{ArtistID: artistID, Title: title})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
// Heal: backfill mbid on a previously-imported row if we have one now.
|
||||||
|
if mbid != "" && (existing.Mbid == nil || *existing.Mbid == "") {
|
||||||
|
m := mbid
|
||||||
|
if uerr := q.SetAlbumMbidIfNull(ctx, dbq.SetAlbumMbidIfNullParams{
|
||||||
|
ID: existing.ID,
|
||||||
|
Mbid: &m,
|
||||||
|
}); uerr != nil {
|
||||||
|
s.logger.Warn("library scan: heal album mbid failed",
|
||||||
|
"album_id", existing.ID, "err", uerr)
|
||||||
|
} else {
|
||||||
|
existing.Mbid = &m
|
||||||
|
}
|
||||||
|
}
|
||||||
return existing, nil
|
return existing, nil
|
||||||
}
|
}
|
||||||
if !errors.Is(err, pgx.ErrNoRows) {
|
if !errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
|||||||
Reference in New Issue
Block a user