Files
minstrel/internal/db/dbq/acoustid.sql.go
T
bvandeusenandClaude Opus 5.5 1d4ef1a23f docs: query comments say what each query selects and why, not how it came to be (#6277)
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>
2026-10-23 12:31:13 -04:00

310 lines
8.7 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: acoustid.sql
package dbq
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const clearTrackAcoustIDMbid = `-- name: ClearTrackAcoustIDMbid :exec
UPDATE tracks
SET mbid = NULL, mbid_source = NULL
WHERE id = $1
AND mbid_source = 'acoustid'
`
// A re-lookup of changed bytes that no longer matches takes back the id an
// earlier lookup wrote. A tag id is never touched.
func (q *Queries) ClearTrackAcoustIDMbid(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, clearTrackAcoustIDMbid, id)
return err
}
const deleteAcoustIDLookup = `-- name: DeleteAcoustIDLookup :exec
DELETE FROM track_acoustid_lookups WHERE track_id = $1
`
// The scan drops the lookup of bytes that are gone, so the worker checks the
// new ones.
func (q *Queries) DeleteAcoustIDLookup(ctx context.Context, trackID pgtype.UUID) error {
_, err := q.db.Exec(ctx, deleteAcoustIDLookup, trackID)
return err
}
const getAcoustIDSettings = `-- name: GetAcoustIDSettings :one
SELECT id, enabled, api_key, min_score, updated_at FROM acoustid_settings WHERE id = true
`
func (q *Queries) GetAcoustIDSettings(ctx context.Context) (AcoustidSetting, error) {
row := q.db.QueryRow(ctx, getAcoustIDSettings)
var i AcoustidSetting
err := row.Scan(
&i.ID,
&i.Enabled,
&i.ApiKey,
&i.MinScore,
&i.UpdatedAt,
)
return i, err
}
const getMbidCoverage = `-- name: GetMbidCoverage :one
SELECT count(*)::bigint AS total,
count(*) FILTER (WHERE t.mbid_source = 'tag')::bigint AS from_tag,
count(*) FILTER (WHERE t.mbid_source = 'acoustid')::bigint AS from_acoustid,
count(*) FILTER (WHERE l.state = 'ambiguous')::bigint AS ambiguous,
count(*) FILTER (WHERE l.state = 'no_match')::bigint AS no_match,
count(*) FILTER (WHERE l.state = 'failed')::bigint AS failed,
count(*) FILTER (
WHERE l.track_id IS NULL AND (t.mbid IS NULL OR t.mbid_source = 'acoustid')
)::bigint AS pending
FROM tracks t
LEFT JOIN track_acoustid_lookups l ON l.track_id = t.id
WHERE t.missing_since IS NULL
`
type GetMbidCoverageRow struct {
Total int64
FromTag int64
FromAcoustid int64
Ambiguous int64
NoMatch int64
Failed int64
Pending int64
}
// The admin gauge: present tracks by where their MBID came from, and the
// lookup states of those a lookup has seen. pending is what the worker's
// queue holds.
func (q *Queries) GetMbidCoverage(ctx context.Context) (GetMbidCoverageRow, error) {
row := q.db.QueryRow(ctx, getMbidCoverage)
var i GetMbidCoverageRow
err := row.Scan(
&i.Total,
&i.FromTag,
&i.FromAcoustid,
&i.Ambiguous,
&i.NoMatch,
&i.Failed,
&i.Pending,
)
return i, err
}
const listTracksNeedingAcoustIDLookup = `-- name: ListTracksNeedingAcoustIDLookup :many
SELECT t.id, t.file_path, t.title, t.duration_ms
FROM tracks t
WHERE (t.mbid IS NULL OR t.mbid_source = 'acoustid')
AND t.missing_since IS NULL
AND t.id > $1::uuid
AND NOT EXISTS (SELECT 1 FROM track_acoustid_lookups l WHERE l.track_id = t.id)
ORDER BY t.id
LIMIT $2
`
type ListTracksNeedingAcoustIDLookupParams struct {
AfterID pgtype.UUID
BatchLimit int32
}
type ListTracksNeedingAcoustIDLookupRow struct {
ID pgtype.UUID
FilePath string
Title string
DurationMs int32
}
// AcoustID recording-id lookup. Migration 0069 says what each
// lookup state means.
// The lookup worker's queue: present tracks with no tag MBID and no lookup
// since their file last changed. A looked-up id is included once its row is
// gone (the file changed), so the new bytes are checked rather than trusted.
// Keyset-paged on id, as the loudness queue is, so a pass ends even when
// every attempt is inconclusive and writes nothing.
func (q *Queries) ListTracksNeedingAcoustIDLookup(ctx context.Context, arg ListTracksNeedingAcoustIDLookupParams) ([]ListTracksNeedingAcoustIDLookupRow, error) {
rows, err := q.db.Query(ctx, listTracksNeedingAcoustIDLookup, arg.AfterID, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListTracksNeedingAcoustIDLookupRow
for rows.Next() {
var i ListTracksNeedingAcoustIDLookupRow
if err := rows.Scan(
&i.ID,
&i.FilePath,
&i.Title,
&i.DurationMs,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listUnsettledAcoustIDLookups = `-- name: ListUnsettledAcoustIDLookups :many
SELECT t.id, t.title, t.file_path, ar.name AS artist_name, al.title AS album_title,
l.state, l.best_score, l.candidates, l.detail, l.looked_up_at
FROM track_acoustid_lookups l
JOIN tracks t ON t.id = l.track_id
JOIN artists ar ON ar.id = t.artist_id
JOIN albums al ON al.id = t.album_id
WHERE l.state IN ('ambiguous', 'failed')
AND t.missing_since IS NULL
ORDER BY ar.name, al.title, t.disc_number NULLS FIRST, t.track_number NULLS FIRST, t.title
LIMIT $1
`
type ListUnsettledAcoustIDLookupsRow struct {
ID pgtype.UUID
Title string
FilePath string
ArtistName string
AlbumTitle string
State string
BestScore *float32
Candidates int32
Detail *string
LookedUpAt pgtype.Timestamptz
}
// The admin list of tracks a lookup could not settle (ambiguous or failed),
// so they are findable rather than silently empty.
func (q *Queries) ListUnsettledAcoustIDLookups(ctx context.Context, rowLimit int32) ([]ListUnsettledAcoustIDLookupsRow, error) {
rows, err := q.db.Query(ctx, listUnsettledAcoustIDLookups, rowLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListUnsettledAcoustIDLookupsRow
for rows.Next() {
var i ListUnsettledAcoustIDLookupsRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.FilePath,
&i.ArtistName,
&i.AlbumTitle,
&i.State,
&i.BestScore,
&i.Candidates,
&i.Detail,
&i.LookedUpAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const recordAcoustIDLookup = `-- name: RecordAcoustIDLookup :exec
INSERT INTO track_acoustid_lookups (track_id, state, best_score, candidates, recording_mbid, detail)
VALUES ($1, $2, $3, $4,
$5, $6)
ON CONFLICT (track_id) DO UPDATE SET
state = EXCLUDED.state,
best_score = EXCLUDED.best_score,
candidates = EXCLUDED.candidates,
recording_mbid = EXCLUDED.recording_mbid,
detail = EXCLUDED.detail,
looked_up_at = now()
`
type RecordAcoustIDLookupParams struct {
TrackID pgtype.UUID
State string
BestScore *float32
Candidates int32
RecordingMbid *string
Detail *string
}
func (q *Queries) RecordAcoustIDLookup(ctx context.Context, arg RecordAcoustIDLookupParams) error {
_, err := q.db.Exec(ctx, recordAcoustIDLookup,
arg.TrackID,
arg.State,
arg.BestScore,
arg.Candidates,
arg.RecordingMbid,
arg.Detail,
)
return err
}
const setTrackMbidFromAcoustID = `-- name: SetTrackMbidFromAcoustID :execrows
UPDATE tracks
SET mbid = $1, mbid_source = 'acoustid'
WHERE id = $2
AND (mbid IS NULL OR mbid_source = 'acoustid')
`
type SetTrackMbidFromAcoustIDParams struct {
Mbid *string
ID pgtype.UUID
}
// Never over a tag id: the guard is here, not only in the worker, so a
// tag the scan read between the worker's list and this write still wins.
// updated_at is left alone: it gates the scan's mtime skip, and moving it
// past a file's mtime would hide a change made just before the lookup.
func (q *Queries) SetTrackMbidFromAcoustID(ctx context.Context, arg SetTrackMbidFromAcoustIDParams) (int64, error) {
result, err := q.db.Exec(ctx, setTrackMbidFromAcoustID, arg.Mbid, arg.ID)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const updateAcoustIDSettings = `-- name: UpdateAcoustIDSettings :one
UPDATE acoustid_settings
SET enabled = $1,
min_score = $2,
api_key = CASE WHEN $3::boolean
THEN NULLIF($4::text, '')
ELSE api_key END,
updated_at = now()
WHERE id = true
RETURNING id, enabled, api_key, min_score, updated_at
`
type UpdateAcoustIDSettingsParams struct {
Enabled bool
MinScore float32
SetApiKey bool
ApiKey string
}
// The key is write-only from the admin card: set_api_key false keeps the
// stored one, and an empty api_key with set_api_key true clears it.
func (q *Queries) UpdateAcoustIDSettings(ctx context.Context, arg UpdateAcoustIDSettingsParams) (AcoustidSetting, error) {
row := q.db.QueryRow(ctx, updateAcoustIDSettings,
arg.Enabled,
arg.MinScore,
arg.SetApiKey,
arg.ApiKey,
)
var i AcoustidSetting
err := row.Scan(
&i.ID,
&i.Enabled,
&i.ApiKey,
&i.MinScore,
&i.UpdatedAt,
)
return i, err
}