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>
503 lines
14 KiB
Go
503 lines
14 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: loudness.sql
|
|
|
|
package dbq
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const deleteAlbumLoudness = `-- name: DeleteAlbumLoudness :exec
|
|
DELETE FROM album_loudness WHERE album_id = ANY($1::uuid[])
|
|
`
|
|
|
|
func (q *Queries) DeleteAlbumLoudness(ctx context.Context, albumIds []pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, deleteAlbumLoudness, albumIds)
|
|
return err
|
|
}
|
|
|
|
const deleteTrackLoudness = `-- name: DeleteTrackLoudness :exec
|
|
DELETE FROM track_loudness WHERE track_id = $1
|
|
`
|
|
|
|
// The scan saw new bytes at this path. The stored measurement describes the old
|
|
// ones, so it goes, and the backfill measures the file again.
|
|
func (q *Queries) DeleteTrackLoudness(ctx context.Context, trackID pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, deleteTrackLoudness, trackID)
|
|
return err
|
|
}
|
|
|
|
const getAlbumLoudness = `-- name: GetAlbumLoudness :one
|
|
SELECT integrated_lufs, true_peak_dbtp FROM album_loudness WHERE album_id = $1
|
|
`
|
|
|
|
type GetAlbumLoudnessRow struct {
|
|
IntegratedLufs *float32
|
|
TruePeakDbtp *float32
|
|
}
|
|
|
|
// The stored album values, read before a recompute so a sync change is
|
|
// logged only when they actually move.
|
|
func (q *Queries) GetAlbumLoudness(ctx context.Context, albumID pgtype.UUID) (GetAlbumLoudnessRow, error) {
|
|
row := q.db.QueryRow(ctx, getAlbumLoudness, albumID)
|
|
var i GetAlbumLoudnessRow
|
|
err := row.Scan(&i.IntegratedLufs, &i.TruePeakDbtp)
|
|
return i, err
|
|
}
|
|
|
|
const getAlbumLoudnessByIDs = `-- name: GetAlbumLoudnessByIDs :many
|
|
SELECT album_id, integrated_lufs, true_peak_dbtp
|
|
FROM album_loudness
|
|
WHERE album_id = ANY($1::uuid[])
|
|
`
|
|
|
|
type GetAlbumLoudnessByIDsRow struct {
|
|
AlbumID pgtype.UUID
|
|
IntegratedLufs *float32
|
|
TruePeakDbtp *float32
|
|
}
|
|
|
|
func (q *Queries) GetAlbumLoudnessByIDs(ctx context.Context, ids []pgtype.UUID) ([]GetAlbumLoudnessByIDsRow, error) {
|
|
rows, err := q.db.Query(ctx, getAlbumLoudnessByIDs, ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetAlbumLoudnessByIDsRow
|
|
for rows.Next() {
|
|
var i GetAlbumLoudnessByIDsRow
|
|
if err := rows.Scan(&i.AlbumID, &i.IntegratedLufs, &i.TruePeakDbtp); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getLoudnessCoverage = `-- name: GetLoudnessCoverage :one
|
|
SELECT count(*)::bigint AS total,
|
|
count(*) FILTER (
|
|
WHERE l.analysis_version >= $1
|
|
AND l.integrated_lufs IS NOT NULL
|
|
)::bigint AS measured,
|
|
count(*) FILTER (
|
|
WHERE l.analysis_version >= $1
|
|
AND l.integrated_lufs IS NULL AND NOT l.unreadable
|
|
)::bigint AS silent,
|
|
count(*) FILTER (
|
|
WHERE l.analysis_version >= $1
|
|
AND l.unreadable
|
|
)::bigint AS unreadable,
|
|
count(*) FILTER (
|
|
WHERE l.track_id IS NULL OR l.analysis_version < $1
|
|
)::bigint AS pending
|
|
FROM tracks t
|
|
LEFT JOIN track_loudness l ON l.track_id = t.id
|
|
WHERE t.missing_since IS NULL
|
|
`
|
|
|
|
type GetLoudnessCoverageRow struct {
|
|
Total int64
|
|
Measured int64
|
|
Silent int64
|
|
Unreadable int64
|
|
Pending int64
|
|
}
|
|
|
|
// The admin gauge. measured + silent + unreadable + pending = total. Missing
|
|
// tracks are excluded, or the gauge could never reach the end.
|
|
func (q *Queries) GetLoudnessCoverage(ctx context.Context, currentVersion int16) (GetLoudnessCoverageRow, error) {
|
|
row := q.db.QueryRow(ctx, getLoudnessCoverage, currentVersion)
|
|
var i GetLoudnessCoverageRow
|
|
err := row.Scan(
|
|
&i.Total,
|
|
&i.Measured,
|
|
&i.Silent,
|
|
&i.Unreadable,
|
|
&i.Pending,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getLoudnessSettings = `-- name: GetLoudnessSettings :one
|
|
SELECT id, enabled, backfill_concurrency, updated_at, leveled_cache_mb FROM loudness_settings WHERE id = true
|
|
`
|
|
|
|
func (q *Queries) GetLoudnessSettings(ctx context.Context) (LoudnessSetting, error) {
|
|
row := q.db.QueryRow(ctx, getLoudnessSettings)
|
|
var i LoudnessSetting
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Enabled,
|
|
&i.BackfillConcurrency,
|
|
&i.UpdatedAt,
|
|
&i.LeveledCacheMb,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getReplayGainByTrackIDs = `-- name: GetReplayGainByTrackIDs :many
|
|
SELECT t.id,
|
|
tl.integrated_lufs AS track_lufs,
|
|
tl.true_peak_dbtp AS track_peak_dbtp,
|
|
al.integrated_lufs AS album_lufs,
|
|
al.true_peak_dbtp AS album_peak_dbtp
|
|
FROM tracks t
|
|
LEFT JOIN track_loudness tl ON tl.track_id = t.id
|
|
LEFT JOIN album_loudness al ON al.album_id = t.album_id
|
|
WHERE t.id = ANY($1::uuid[])
|
|
`
|
|
|
|
type GetReplayGainByTrackIDsRow struct {
|
|
ID pgtype.UUID
|
|
TrackLufs *float32
|
|
TrackPeakDbtp *float32
|
|
AlbumLufs *float32
|
|
AlbumPeakDbtp *float32
|
|
}
|
|
|
|
// Track and album loudness for a set of tracks, for every surface that hands
|
|
// gains to a client. A measurement from an older analysis version is
|
|
// still delivered: it is a better gain than none until the backfill redoes it.
|
|
func (q *Queries) GetReplayGainByTrackIDs(ctx context.Context, ids []pgtype.UUID) ([]GetReplayGainByTrackIDsRow, error) {
|
|
rows, err := q.db.Query(ctx, getReplayGainByTrackIDs, ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetReplayGainByTrackIDsRow
|
|
for rows.Next() {
|
|
var i GetReplayGainByTrackIDsRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TrackLufs,
|
|
&i.TrackPeakDbtp,
|
|
&i.AlbumLufs,
|
|
&i.AlbumPeakDbtp,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listAlbumLoudnessInputs = `-- name: ListAlbumLoudnessInputs :many
|
|
SELECT t.id,
|
|
(l.track_id IS NOT NULL)::boolean AS settled,
|
|
l.true_peak_dbtp,
|
|
l.block_hist_start,
|
|
l.block_hist
|
|
FROM tracks t
|
|
LEFT JOIN track_loudness l
|
|
ON l.track_id = t.id AND l.analysis_version >= $1
|
|
WHERE t.album_id = $2
|
|
AND t.missing_since IS NULL
|
|
`
|
|
|
|
type ListAlbumLoudnessInputsParams struct {
|
|
CurrentVersion int16
|
|
AlbumID pgtype.UUID
|
|
}
|
|
|
|
type ListAlbumLoudnessInputsRow struct {
|
|
ID pgtype.UUID
|
|
Settled bool
|
|
TruePeakDbtp *float32
|
|
BlockHistStart *int16
|
|
BlockHist []int32
|
|
}
|
|
|
|
// Every present track on one album with its current measurement, if any.
|
|
// settled is false for a track not yet measured at the current version.
|
|
func (q *Queries) ListAlbumLoudnessInputs(ctx context.Context, arg ListAlbumLoudnessInputsParams) ([]ListAlbumLoudnessInputsRow, error) {
|
|
rows, err := q.db.Query(ctx, listAlbumLoudnessInputs, arg.CurrentVersion, arg.AlbumID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListAlbumLoudnessInputsRow
|
|
for rows.Next() {
|
|
var i ListAlbumLoudnessInputsRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Settled,
|
|
&i.TruePeakDbtp,
|
|
&i.BlockHistStart,
|
|
&i.BlockHist,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listAlbumsNeedingLoudness = `-- name: ListAlbumsNeedingLoudness :many
|
|
WITH present AS (
|
|
SELECT t.album_id,
|
|
md5(string_agg(
|
|
t.id::text || ':' || coalesce(
|
|
l.analysis_version::text || '@' || l.analyzed_at::text, '-'),
|
|
',' ORDER BY t.id)) AS digest
|
|
FROM tracks t
|
|
LEFT JOIN track_loudness l
|
|
ON l.track_id = t.id AND l.analysis_version >= $3::smallint
|
|
WHERE t.missing_since IS NULL
|
|
GROUP BY t.album_id
|
|
)
|
|
SELECT c.album_id, c.digest::text AS digest
|
|
FROM present c
|
|
LEFT JOIN album_loudness a ON a.album_id = c.album_id
|
|
WHERE (a.album_id IS NULL OR a.inputs_digest <> c.digest)
|
|
-- Casts: sqlc cannot infer a parameter's type through a CTE alias.
|
|
AND c.album_id > $1::uuid
|
|
ORDER BY c.album_id
|
|
LIMIT $2::integer
|
|
`
|
|
|
|
type ListAlbumsNeedingLoudnessParams struct {
|
|
AfterID pgtype.UUID
|
|
BatchLimit int32
|
|
CurrentVersion int16
|
|
}
|
|
|
|
type ListAlbumsNeedingLoudnessRow struct {
|
|
AlbumID pgtype.UUID
|
|
Digest string
|
|
}
|
|
|
|
// The album pass's work queue: albums whose present tracks or their
|
|
// measurements have changed since album loudness was last computed, or that
|
|
// never had it. The digest is over every present track's id and the
|
|
// measurement it holds at the current version ('-' for none), so a track
|
|
// joining, leaving or being re-measured changes it. Keyset-paged on album id
|
|
// so a pass ends even if storing one album keeps failing.
|
|
func (q *Queries) ListAlbumsNeedingLoudness(ctx context.Context, arg ListAlbumsNeedingLoudnessParams) ([]ListAlbumsNeedingLoudnessRow, error) {
|
|
rows, err := q.db.Query(ctx, listAlbumsNeedingLoudness, arg.AfterID, arg.BatchLimit, arg.CurrentVersion)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListAlbumsNeedingLoudnessRow
|
|
for rows.Next() {
|
|
var i ListAlbumsNeedingLoudnessRow
|
|
if err := rows.Scan(&i.AlbumID, &i.Digest); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listOrphanAlbumLoudness = `-- name: ListOrphanAlbumLoudness :many
|
|
SELECT a.album_id
|
|
FROM album_loudness a
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM tracks t WHERE t.album_id = a.album_id AND t.missing_since IS NULL
|
|
)
|
|
`
|
|
|
|
// Album rows whose album has no present track left (every file missing). The
|
|
// album row itself survives a missing file, so its loudness would otherwise
|
|
// stay behind describing tracks that are gone; it is recomputed if they return.
|
|
func (q *Queries) ListOrphanAlbumLoudness(ctx context.Context) ([]pgtype.UUID, error) {
|
|
rows, err := q.db.Query(ctx, listOrphanAlbumLoudness)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []pgtype.UUID
|
|
for rows.Next() {
|
|
var album_id pgtype.UUID
|
|
if err := rows.Scan(&album_id); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, album_id)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listTracksNeedingLoudness = `-- name: ListTracksNeedingLoudness :many
|
|
SELECT t.id, t.file_path, t.duration_ms
|
|
FROM tracks t
|
|
LEFT JOIN track_loudness l ON l.track_id = t.id
|
|
WHERE t.missing_since IS NULL
|
|
AND (l.track_id IS NULL OR l.analysis_version < $1)
|
|
AND t.id > $2
|
|
ORDER BY t.id
|
|
LIMIT $3
|
|
`
|
|
|
|
type ListTracksNeedingLoudnessParams struct {
|
|
CurrentVersion int16
|
|
AfterID pgtype.UUID
|
|
BatchLimit int32
|
|
}
|
|
|
|
type ListTracksNeedingLoudnessRow struct {
|
|
ID pgtype.UUID
|
|
FilePath string
|
|
DurationMs int32
|
|
}
|
|
|
|
// The backfill's work queue: tracks with no measurement, or one taken by an
|
|
// older method. Keyset-paged on id so a pass visits each track at most once;
|
|
// an inconclusive attempt writes no row, and without the cursor a file that
|
|
// keeps timing out would be listed again straight away. Missing tracks are
|
|
// skipped: there is no file to read.
|
|
func (q *Queries) ListTracksNeedingLoudness(ctx context.Context, arg ListTracksNeedingLoudnessParams) ([]ListTracksNeedingLoudnessRow, error) {
|
|
rows, err := q.db.Query(ctx, listTracksNeedingLoudness, arg.CurrentVersion, arg.AfterID, arg.BatchLimit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListTracksNeedingLoudnessRow
|
|
for rows.Next() {
|
|
var i ListTracksNeedingLoudnessRow
|
|
if err := rows.Scan(&i.ID, &i.FilePath, &i.DurationMs); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const updateLoudnessSettings = `-- name: UpdateLoudnessSettings :one
|
|
UPDATE loudness_settings
|
|
SET enabled = $1,
|
|
backfill_concurrency = $2,
|
|
leveled_cache_mb = $3,
|
|
updated_at = now()
|
|
WHERE id = true
|
|
RETURNING id, enabled, backfill_concurrency, updated_at, leveled_cache_mb
|
|
`
|
|
|
|
type UpdateLoudnessSettingsParams struct {
|
|
Enabled bool
|
|
BackfillConcurrency int32
|
|
LeveledCacheMb int32
|
|
}
|
|
|
|
// Whole-row write from the admin card; the migrations' CHECKs are the backstop
|
|
// behind the service's own validation.
|
|
func (q *Queries) UpdateLoudnessSettings(ctx context.Context, arg UpdateLoudnessSettingsParams) (LoudnessSetting, error) {
|
|
row := q.db.QueryRow(ctx, updateLoudnessSettings, arg.Enabled, arg.BackfillConcurrency, arg.LeveledCacheMb)
|
|
var i LoudnessSetting
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Enabled,
|
|
&i.BackfillConcurrency,
|
|
&i.UpdatedAt,
|
|
&i.LeveledCacheMb,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const upsertAlbumLoudness = `-- name: UpsertAlbumLoudness :exec
|
|
INSERT INTO album_loudness (
|
|
album_id, integrated_lufs, true_peak_dbtp, tracks_total, tracks_settled, inputs_digest
|
|
) VALUES (
|
|
$1, $2, $3,
|
|
$4, $5, $6
|
|
)
|
|
ON CONFLICT (album_id) DO UPDATE SET
|
|
integrated_lufs = EXCLUDED.integrated_lufs,
|
|
true_peak_dbtp = EXCLUDED.true_peak_dbtp,
|
|
tracks_total = EXCLUDED.tracks_total,
|
|
tracks_settled = EXCLUDED.tracks_settled,
|
|
inputs_digest = EXCLUDED.inputs_digest,
|
|
computed_at = now()
|
|
`
|
|
|
|
type UpsertAlbumLoudnessParams struct {
|
|
AlbumID pgtype.UUID
|
|
IntegratedLufs *float32
|
|
TruePeakDbtp *float32
|
|
TracksTotal int32
|
|
TracksSettled int32
|
|
InputsDigest string
|
|
}
|
|
|
|
func (q *Queries) UpsertAlbumLoudness(ctx context.Context, arg UpsertAlbumLoudnessParams) error {
|
|
_, err := q.db.Exec(ctx, upsertAlbumLoudness,
|
|
arg.AlbumID,
|
|
arg.IntegratedLufs,
|
|
arg.TruePeakDbtp,
|
|
arg.TracksTotal,
|
|
arg.TracksSettled,
|
|
arg.InputsDigest,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const upsertTrackLoudness = `-- name: UpsertTrackLoudness :exec
|
|
INSERT INTO track_loudness (
|
|
track_id, integrated_lufs, true_peak_dbtp, loudness_range_lu,
|
|
block_hist_start, block_hist, unreadable, analysis_version
|
|
) VALUES (
|
|
$1, $2, $3,
|
|
$4, $5, $6,
|
|
$7, $8
|
|
)
|
|
ON CONFLICT (track_id) DO UPDATE SET
|
|
integrated_lufs = EXCLUDED.integrated_lufs,
|
|
true_peak_dbtp = EXCLUDED.true_peak_dbtp,
|
|
loudness_range_lu = EXCLUDED.loudness_range_lu,
|
|
block_hist_start = EXCLUDED.block_hist_start,
|
|
block_hist = EXCLUDED.block_hist,
|
|
unreadable = EXCLUDED.unreadable,
|
|
analysis_version = EXCLUDED.analysis_version,
|
|
analyzed_at = now()
|
|
`
|
|
|
|
type UpsertTrackLoudnessParams struct {
|
|
TrackID pgtype.UUID
|
|
IntegratedLufs *float32
|
|
TruePeakDbtp *float32
|
|
LoudnessRangeLu *float32
|
|
BlockHistStart *int16
|
|
BlockHist []int32
|
|
Unreadable bool
|
|
AnalysisVersion int16
|
|
}
|
|
|
|
// Written when the backfill measures a track. Replaces the row
|
|
// wholesale: a measurement of the old bytes has no standing once the file has
|
|
// changed.
|
|
func (q *Queries) UpsertTrackLoudness(ctx context.Context, arg UpsertTrackLoudnessParams) error {
|
|
_, err := q.db.Exec(ctx, upsertTrackLoudness,
|
|
arg.TrackID,
|
|
arg.IntegratedLufs,
|
|
arg.TruePeakDbtp,
|
|
arg.LoudnessRangeLu,
|
|
arg.BlockHistStart,
|
|
arg.BlockHist,
|
|
arg.Unreadable,
|
|
arg.AnalysisVersion,
|
|
)
|
|
return err
|
|
}
|