Rewrites the internal/db/queries comments to rule 32 and regenerates dbq, whose doc comments and embedded SQL carry them. The bugs behind the tiered mixes, the md5 order seed, the score bands and the round-robin arms are restated as the constraint each one enforces; counts from one library and stale cross-references are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
217 lines
5.9 KiB
Go
217 lines
5.9 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: covers.sql
|
|
|
|
package dbq
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const clearAlbumCover = `-- name: ClearAlbumCover :exec
|
|
UPDATE albums
|
|
SET cover_art_path = NULL,
|
|
cover_art_source = NULL
|
|
WHERE id = $1
|
|
`
|
|
|
|
// Used by the admin retry endpoint to wipe state before re-running the
|
|
// enricher. Sets both fields to NULL.
|
|
func (q *Queries) ClearAlbumCover(ctx context.Context, id pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, clearAlbumCover, id)
|
|
return err
|
|
}
|
|
|
|
const clearAlbumCoverNone = `-- name: ClearAlbumCoverNone :exec
|
|
UPDATE albums
|
|
SET cover_art_source = NULL
|
|
WHERE id = $1 AND cover_art_source = 'none'
|
|
`
|
|
|
|
// When MBID backfill heals an album, clear its 'none' cover_art_source
|
|
// back to NULL so the enricher's next batch retries the MBCAA fetch.
|
|
// Idempotent — only updates rows currently stamped 'none'.
|
|
func (q *Queries) ClearAlbumCoverNone(ctx context.Context, id pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, clearAlbumCoverNone, id)
|
|
return err
|
|
}
|
|
|
|
const countAlbumCoverSources = `-- name: CountAlbumCoverSources :one
|
|
SELECT
|
|
COUNT(*) FILTER (WHERE cover_art_source IS NULL) ::bigint AS untried,
|
|
COUNT(*) FILTER (WHERE cover_art_source = 'sidecar') ::bigint AS sidecar,
|
|
COUNT(*) FILTER (WHERE cover_art_source = 'embedded')::bigint AS embedded,
|
|
COUNT(*) FILTER (WHERE cover_art_source = 'mbcaa') ::bigint AS mbcaa,
|
|
COUNT(*) FILTER (WHERE cover_art_source = 'none') ::bigint AS none
|
|
FROM albums
|
|
`
|
|
|
|
type CountAlbumCoverSourcesRow struct {
|
|
Untried int64
|
|
Sidecar int64
|
|
Embedded int64
|
|
Mbcaa int64
|
|
None int64
|
|
}
|
|
|
|
// Diagnostic for the admin overview: counts by source, including NULL.
|
|
// Returns one row with named tallies.
|
|
func (q *Queries) CountAlbumCoverSources(ctx context.Context) (CountAlbumCoverSourcesRow, error) {
|
|
row := q.db.QueryRow(ctx, countAlbumCoverSources)
|
|
var i CountAlbumCoverSourcesRow
|
|
err := row.Scan(
|
|
&i.Untried,
|
|
&i.Sidecar,
|
|
&i.Embedded,
|
|
&i.Mbcaa,
|
|
&i.None,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getAlbumWithFirstTrackPath = `-- name: GetAlbumWithFirstTrackPath :one
|
|
SELECT a.id, a.mbid, a.title, a.cover_art_path, a.cover_art_source,
|
|
ar.name AS artist_name,
|
|
t.file_path AS track_file_path
|
|
FROM albums a
|
|
JOIN artists ar ON ar.id = a.artist_id
|
|
LEFT JOIN tracks t ON t.album_id = a.id
|
|
WHERE a.id = $1
|
|
ORDER BY t.disc_number NULLS LAST, t.track_number NULLS LAST, t.id
|
|
LIMIT 1
|
|
`
|
|
|
|
type GetAlbumWithFirstTrackPathRow struct {
|
|
ID pgtype.UUID
|
|
Mbid *string
|
|
Title string
|
|
CoverArtPath *string
|
|
CoverArtSource *string
|
|
ArtistName string
|
|
TrackFilePath *string
|
|
}
|
|
|
|
// Returns the album row, the artist's name (used by name-based art
|
|
// providers like Deezer/Last.fm), and one of its track file paths
|
|
// (used to derive the album directory for sidecar writes). Pick
|
|
// lowest position track for determinism.
|
|
func (q *Queries) GetAlbumWithFirstTrackPath(ctx context.Context, id pgtype.UUID) (GetAlbumWithFirstTrackPathRow, error) {
|
|
row := q.db.QueryRow(ctx, getAlbumWithFirstTrackPath, id)
|
|
var i GetAlbumWithFirstTrackPathRow
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Mbid,
|
|
&i.Title,
|
|
&i.CoverArtPath,
|
|
&i.CoverArtSource,
|
|
&i.ArtistName,
|
|
&i.TrackFilePath,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const listAlbumsMissingCover = `-- name: ListAlbumsMissingCover :many
|
|
|
|
SELECT a.id
|
|
FROM albums a
|
|
WHERE a.cover_art_source IS NULL
|
|
OR (a.cover_art_source = 'none' AND a.cover_art_sources_version != $1)
|
|
ORDER BY a.created_at
|
|
LIMIT $2
|
|
`
|
|
|
|
type ListAlbumsMissingCoverParams struct {
|
|
CoverArtSourcesVersion int32
|
|
Limit int32
|
|
}
|
|
|
|
// Album cover enrichment queries.
|
|
// Returns rows the enricher should attempt. Eligible:
|
|
// cover_art_source IS NULL (never tried), OR cover_art_source = 'none'
|
|
// AND cover_art_sources_version != current (settled under an older
|
|
// source set; recheck against the current chain). LIMIT supplied by
|
|
// caller for batching.
|
|
func (q *Queries) ListAlbumsMissingCover(ctx context.Context, arg ListAlbumsMissingCoverParams) ([]pgtype.UUID, error) {
|
|
rows, err := q.db.Query(ctx, listAlbumsMissingCover, arg.CoverArtSourcesVersion, arg.Limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []pgtype.UUID
|
|
for rows.Next() {
|
|
var id pgtype.UUID
|
|
if err := rows.Scan(&id); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, id)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listAlbumsRetryMissing = `-- name: ListAlbumsRetryMissing :many
|
|
SELECT a.id, a.mbid, a.title, a.artist_id
|
|
FROM albums a
|
|
WHERE a.cover_art_source IS NULL OR a.cover_art_source = 'none'
|
|
ORDER BY a.created_at ASC
|
|
LIMIT $1
|
|
`
|
|
|
|
type ListAlbumsRetryMissingRow struct {
|
|
ID pgtype.UUID
|
|
Mbid *string
|
|
Title string
|
|
ArtistID pgtype.UUID
|
|
}
|
|
|
|
// Bulk-retry candidates: NULL (never tried) plus 'none' (tried, failed).
|
|
// Used by the admin "refetch missing covers" endpoint. LIMIT supplied.
|
|
func (q *Queries) ListAlbumsRetryMissing(ctx context.Context, limit int32) ([]ListAlbumsRetryMissingRow, error) {
|
|
rows, err := q.db.Query(ctx, listAlbumsRetryMissing, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListAlbumsRetryMissingRow
|
|
for rows.Next() {
|
|
var i ListAlbumsRetryMissingRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Mbid,
|
|
&i.Title,
|
|
&i.ArtistID,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const setAlbumCover = `-- name: SetAlbumCover :exec
|
|
UPDATE albums
|
|
SET cover_art_path = NULLIF($2::text, ''),
|
|
cover_art_source = $3
|
|
WHERE id = $1
|
|
`
|
|
|
|
type SetAlbumCoverParams struct {
|
|
ID pgtype.UUID
|
|
Column2 string
|
|
CoverArtSource *string
|
|
}
|
|
|
|
// Persist enrichment result. Pass cover_art_path = ” to clear (turns into NULL).
|
|
func (q *Queries) SetAlbumCover(ctx context.Context, arg SetAlbumCoverParams) error {
|
|
_, err := q.db.Exec(ctx, setAlbumCover, arg.ID, arg.Column2, arg.CoverArtSource)
|
|
return err
|
|
}
|