// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: reacquisition.sql package dbq import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const countAlbumsMissingWithoutMbid = `-- name: CountAlbumsMissingWithoutMbid :one SELECT COUNT(DISTINCT albums.id)::bigint FROM albums JOIN artists ON artists.id = albums.artist_id JOIN tracks ON tracks.album_id = albums.id WHERE tracks.missing_since IS NOT NULL AND (albums.mbid IS NULL OR artists.mbid IS NULL) ` // Albums with missing files that can never be wanted automatically because // nothing identifies them to MusicBrainz. Surfaced on the admin card so the // gap is visible: silently doing nothing for these would read as broken. func (q *Queries) CountAlbumsMissingWithoutMbid(ctx context.Context) (int64, error) { row := q.db.QueryRow(ctx, countAlbumsMissingWithoutMbid) var column_1 int64 err := row.Scan(&column_1) return column_1, err } const getReacquisitionSettings = `-- name: GetReacquisitionSettings :one SELECT id, enabled, grace_hours, max_per_pass FROM reacquisition_settings WHERE id = true ` // Re-acquisition of missing files (milestone #290, reworked for M502 #5520). // The unit is the album: an album whose files went missing becomes a want for // its release group, and the search schedule (#5521) looks for it. func (q *Queries) GetReacquisitionSettings(ctx context.Context) (ReacquisitionSetting, error) { row := q.db.QueryRow(ctx, getReacquisitionSettings) var i ReacquisitionSetting err := row.Scan( &i.ID, &i.Enabled, &i.GraceHours, &i.MaxPerPass, ) return i, err } const getWantsForAlbums = `-- name: GetWantsForAlbums :many SELECT a.id AS album_id, w.id AS want_id, w.wanted_at, w.fulfilled_at FROM albums a JOIN wants w ON w.album_id = a.id OR w.release_group_mbid = a.release_group_mbid WHERE a.id = ANY($1::uuid[]) ORDER BY w.wanted_at DESC ` type GetWantsForAlbumsRow struct { AlbumID pgtype.UUID WantID pgtype.UUID WantedAt pgtype.Timestamptz FulfilledAt pgtype.Timestamptz } // What the wanted list says about each album on the missing-files page. func (q *Queries) GetWantsForAlbums(ctx context.Context, albumIds []pgtype.UUID) ([]GetWantsForAlbumsRow, error) { rows, err := q.db.Query(ctx, getWantsForAlbums, albumIds) if err != nil { return nil, err } defer rows.Close() var items []GetWantsForAlbumsRow for rows.Next() { var i GetWantsForAlbumsRow if err := rows.Scan( &i.AlbumID, &i.WantID, &i.WantedAt, &i.FulfilledAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listAlbumsDueReacquisition = `-- name: ListAlbumsDueReacquisition :many SELECT albums.id AS album_id, albums.title AS album_title, albums.mbid AS album_mbid, albums.release_group_mbid AS album_release_group_mbid, artists.name AS artist_name, artists.mbid AS artist_mbid, COUNT(tracks.id)::bigint AS missing_track_count, MAX(tracks.missing_since)::timestamptz AS last_missing_since FROM albums JOIN artists ON artists.id = albums.artist_id JOIN tracks ON tracks.album_id = albums.id WHERE tracks.missing_since IS NOT NULL AND tracks.missing_since <= now() - make_interval(hours => $1::int) AND albums.mbid IS NOT NULL AND artists.mbid IS NOT NULL GROUP BY albums.id, albums.title, albums.mbid, albums.release_group_mbid, artists.name, artists.mbid HAVING EXISTS ( SELECT 1 FROM wants w WHERE w.album_id = albums.id OR w.release_group_mbid = albums.release_group_mbid) AND NOT EXISTS ( SELECT 1 FROM wants w WHERE (w.album_id = albums.id OR w.release_group_mbid = albums.release_group_mbid) AND (w.fulfilled_at IS NULL OR w.fulfilled_at > MAX(tracks.missing_since))) ORDER BY MIN(tracks.missing_since), albums.sort_title LIMIT $2 ` type ListAlbumsDueReacquisitionParams struct { GraceHours int32 PageLimit int32 } type ListAlbumsDueReacquisitionRow struct { AlbumID pgtype.UUID AlbumTitle string AlbumMbid *string AlbumReleaseGroupMbid *string ArtistName string ArtistMbid *string MissingTrackCount int64 LastMissingSince pgtype.Timestamptz } // The sweeper's selection. An album qualifies when: // // - it still has at least one track whose file has been missing longer than // the grace window. Measured on missing_since, which reconcile never // re-stamps (#2523), so it is a genuine "gone since" clock; // - MusicBrainz can name it: the album and its artist have MBIDs. Albums // failing this are counted separately (CountAlbumsMissingWithoutMbid); // - it is on the wanted list (#5567): an album taken off the list, or // dropped into the library by hand, is not fetched back; // - no want already covers it: none open, and none held since its files // went missing. A want held after the loss means the library has a full // copy despite the missing rows (#5245), so asking again would loop. func (q *Queries) ListAlbumsDueReacquisition(ctx context.Context, arg ListAlbumsDueReacquisitionParams) ([]ListAlbumsDueReacquisitionRow, error) { rows, err := q.db.Query(ctx, listAlbumsDueReacquisition, arg.GraceHours, arg.PageLimit) if err != nil { return nil, err } defer rows.Close() var items []ListAlbumsDueReacquisitionRow for rows.Next() { var i ListAlbumsDueReacquisitionRow if err := rows.Scan( &i.AlbumID, &i.AlbumTitle, &i.AlbumMbid, &i.AlbumReleaseGroupMbid, &i.ArtistName, &i.ArtistMbid, &i.MissingTrackCount, &i.LastMissingSince, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const updateReacquisitionSettings = `-- name: UpdateReacquisitionSettings :one UPDATE reacquisition_settings SET enabled = $1, grace_hours = $2, max_per_pass = $3 WHERE id = true RETURNING id, enabled, grace_hours, max_per_pass ` type UpdateReacquisitionSettingsParams struct { Enabled bool GraceHours int32 MaxPerPass int32 } // Whole-row write from the admin card; the CHECKs in migration 0056 are the // validation, so a bad value fails loudly rather than being clamped silently. func (q *Queries) UpdateReacquisitionSettings(ctx context.Context, arg UpdateReacquisitionSettingsParams) (ReacquisitionSetting, error) { row := q.db.QueryRow(ctx, updateReacquisitionSettings, arg.Enabled, arg.GraceHours, arg.MaxPerPass) var i ReacquisitionSetting err := row.Scan( &i.ID, &i.Enabled, &i.GraceHours, &i.MaxPerPass, ) return i, err } const wantMissingAlbum = `-- name: WantMissingAlbum :one INSERT INTO wants (release_group_mbid, artist_mbid, artist_name, title, reason, album_id) VALUES ($1, $2, $3, $4, 'missing', $5) ON CONFLICT (release_group_mbid) DO UPDATE SET reason = 'missing', album_id = EXCLUDED.album_id, wanted_at = now(), fulfilled_at = NULL, updated_at = now() WHERE wants.fulfilled_at IS NOT NULL RETURNING id, release_group_mbid, artist_mbid, artist_name, title, primary_type, first_release_date, reason, album_id, created_by, wanted_at, fulfilled_at, created_at, updated_at, searched_at, search_outcome, search_considered, best_release, best_verdict, search_error ` type WantMissingAlbumParams struct { ReleaseGroupMbid string ArtistMbid string ArtistName string Title string AlbumID pgtype.UUID } // Records an album with missing files as wanted. A held want for the same // group is reopened; an open one is left as it is, and no row comes back. func (q *Queries) WantMissingAlbum(ctx context.Context, arg WantMissingAlbumParams) (Want, error) { row := q.db.QueryRow(ctx, wantMissingAlbum, arg.ReleaseGroupMbid, arg.ArtistMbid, arg.ArtistName, arg.Title, arg.AlbumID, ) var i Want err := row.Scan( &i.ID, &i.ReleaseGroupMbid, &i.ArtistMbid, &i.ArtistName, &i.Title, &i.PrimaryType, &i.FirstReleaseDate, &i.Reason, &i.AlbumID, &i.CreatedBy, &i.WantedAt, &i.FulfilledAt, &i.CreatedAt, &i.UpdatedAt, &i.SearchedAt, &i.SearchOutcome, &i.SearchConsidered, &i.BestRelease, &i.BestVerdict, &i.SearchError, ) return i, err }