// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: requests.sql package dbq import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const approveRequest = `-- name: ApproveRequest :one UPDATE requests SET status = 'approved', decided_at = now(), decided_by = $2, updated_at = now() WHERE id = $1 AND status = 'pending' RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at ` type ApproveRequestParams struct { ID pgtype.UUID DecidedBy pgtype.UUID } func (q *Queries) ApproveRequest(ctx context.Context, arg ApproveRequestParams) (Request, error) { row := q.db.QueryRow(ctx, approveRequest, arg.ID, arg.DecidedBy) var i Request err := row.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ) return i, err } const cancelRequest = `-- name: CancelRequest :one UPDATE requests SET status = 'rejected', notes = 'cancelled by user', decided_at = now(), decided_by = $2, updated_at = now() WHERE id = $1 AND user_id = $2 AND status = 'pending' RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at ` type CancelRequestParams struct { ID pgtype.UUID DecidedBy pgtype.UUID } // $2 serves as both the ownership guard (user_id = $2) and the // decided_by audit field. The generated parameter struct names it // DecidedBy — callers must pass the cancelling user's UUID, and // a wrong UUID will silently no-op (zero rows updated) rather than // erroring at the SQL layer. func (q *Queries) CancelRequest(ctx context.Context, arg CancelRequestParams) (Request, error) { row := q.db.QueryRow(ctx, cancelRequest, arg.ID, arg.DecidedBy) var i Request err := row.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ) return i, err } const completeRequest = `-- name: CompleteRequest :one UPDATE requests SET status = 'completed', matched_track_id = $2, matched_album_id = $3, matched_artist_id = $4, completed_at = now(), updated_at = now() WHERE id = $1 AND status = 'approved' RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at ` type CompleteRequestParams struct { ID pgtype.UUID MatchedTrackID pgtype.UUID MatchedAlbumID pgtype.UUID MatchedArtistID pgtype.UUID } // Reconciler transitions an approved request to completed when its // target track/album/artist has appeared in the library. Callers // should set ONLY the matched_*_id corresponding to the request's // kind and pass pgtype.UUID{} (Valid: false) for the others — // per-kind one-of-three is the contract, NULL for the others // preserves auditability if the matched row is later evicted. func (q *Queries) CompleteRequest(ctx context.Context, arg CompleteRequestParams) (Request, error) { row := q.db.QueryRow(ctx, completeRequest, arg.ID, arg.MatchedTrackID, arg.MatchedAlbumID, arg.MatchedArtistID, ) var i Request err := row.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ) return i, err } const createRequest = `-- name: CreateRequest :one INSERT INTO requests ( user_id, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at ` type CreateRequestParams struct { UserID pgtype.UUID Kind RequestKind ArtistMbid string AlbumMbid *string TrackMbid *string ArtistName string AlbumTitle *string TrackTitle *string } func (q *Queries) CreateRequest(ctx context.Context, arg CreateRequestParams) (Request, error) { row := q.db.QueryRow(ctx, createRequest, arg.UserID, arg.Kind, arg.ArtistMbid, arg.AlbumMbid, arg.TrackMbid, arg.ArtistName, arg.AlbumTitle, arg.TrackTitle, ) var i Request err := row.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ) return i, err } const getNonTerminalRequestForMBID = `-- name: GetNonTerminalRequestForMBID :one SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests WHERE status IN ('pending', 'approved', 'completed') AND ((kind = 'artist' AND artist_mbid = $1) OR (kind = 'album' AND album_mbid = $1) OR (kind = 'track' AND track_mbid = $1)) ORDER BY requested_at ASC LIMIT 1 ` // Returns the oldest non-terminal (pending/approved/completed) request // whose own-kind MBID matches @mbid, or pgx.ErrNoRows when none. Create() // uses this to dedupe: a re-request for something already in flight // returns the existing row instead of inserting a duplicate. func (q *Queries) GetNonTerminalRequestForMBID(ctx context.Context, mbid string) (Request, error) { row := q.db.QueryRow(ctx, getNonTerminalRequestForMBID, mbid) var i Request err := row.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ) return i, err } const getRequestByID = `-- name: GetRequestByID :one SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests WHERE id = $1 ` func (q *Queries) GetRequestByID(ctx context.Context, id pgtype.UUID) (Request, error) { row := q.db.QueryRow(ctx, getRequestByID, id) var i Request err := row.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ) return i, err } const hasNonTerminalRequestForMBID = `-- name: HasNonTerminalRequestForMBID :one SELECT (EXISTS ( SELECT 1 FROM requests r WHERE r.status IN ('pending', 'approved', 'completed') AND ((r.kind = 'artist' AND r.artist_mbid = $1) OR (r.kind = 'album' AND r.album_mbid = $1) OR (r.kind = 'track' AND r.track_mbid = $1)) ) OR EXISTS ( SELECT 1 FROM wants w WHERE w.release_group_mbid = $1 AND w.fulfilled_at IS NULL ) OR EXISTS ( SELECT 1 FROM follows f WHERE f.artist_mbid = $1 ))::bool AS requested ` // Whether something is already on its way: a pending, approved or completed // request at the given level, an open want for the release group, or a // follow of the artist. Sets the `requested` flag on catalogue search. // Terminal-status (rejected, failed) requests do not count. MBIDs are unique // per entity type, so checking one id against every column cannot // false-match. func (q *Queries) HasNonTerminalRequestForMBID(ctx context.Context, mbid string) (bool, error) { row := q.db.QueryRow(ctx, hasNonTerminalRequestForMBID, mbid) var requested bool err := row.Scan(&requested) return requested, err } const listApprovedRequestsForReconcile = `-- name: ListApprovedRequestsForReconcile :many SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests WHERE status = 'approved' ORDER BY decided_at ASC LIMIT $1 ` func (q *Queries) ListApprovedRequestsForReconcile(ctx context.Context, limit int32) ([]Request, error) { rows, err := q.db.Query(ctx, listApprovedRequestsForReconcile, limit) if err != nil { return nil, err } defer rows.Close() var items []Request for rows.Next() { var i Request if err := rows.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listRequestsByStatus = `-- name: ListRequestsByStatus :many SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests WHERE status = $1 ORDER BY requested_at DESC LIMIT $2 ` type ListRequestsByStatusParams struct { Status RequestStatus Limit int32 } func (q *Queries) ListRequestsByStatus(ctx context.Context, arg ListRequestsByStatusParams) ([]Request, error) { rows, err := q.db.Query(ctx, listRequestsByStatus, arg.Status, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []Request for rows.Next() { var i Request if err := rows.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listRequestsForUser = `-- name: ListRequestsForUser :many SELECT id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at FROM requests WHERE user_id = $1 ORDER BY requested_at DESC LIMIT $2 ` type ListRequestsForUserParams struct { UserID pgtype.UUID Limit int32 } func (q *Queries) ListRequestsForUser(ctx context.Context, arg ListRequestsForUserParams) ([]Request, error) { rows, err := q.db.Query(ctx, listRequestsForUser, arg.UserID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []Request for rows.Next() { var i Request if err := rows.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const rejectRequest = `-- name: RejectRequest :one UPDATE requests SET status = 'rejected', notes = $2, decided_at = now(), decided_by = $3, updated_at = now() WHERE id = $1 AND status = 'pending' RETURNING id, user_id, status, kind, artist_mbid, album_mbid, track_mbid, artist_name, album_title, track_title, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at ` type RejectRequestParams struct { ID pgtype.UUID Notes *string DecidedBy pgtype.UUID } func (q *Queries) RejectRequest(ctx context.Context, arg RejectRequestParams) (Request, error) { row := q.db.QueryRow(ctx, rejectRequest, arg.ID, arg.Notes, arg.DecidedBy) var i Request err := row.Scan( &i.ID, &i.UserID, &i.Status, &i.Kind, &i.ArtistMbid, &i.AlbumMbid, &i.TrackMbid, &i.ArtistName, &i.AlbumTitle, &i.TrackTitle, &i.DecidedAt, &i.DecidedBy, &i.Notes, &i.CompletedAt, &i.MatchedTrackID, &i.MatchedAlbumID, &i.MatchedArtistID, &i.RequestedAt, &i.UpdatedAt, ) return i, err } const repointRequestsAlbumMbid = `-- name: RepointRequestsAlbumMbid :exec UPDATE requests SET album_mbid = $1, updated_at = now() WHERE album_mbid = $2 ` type RepointRequestsAlbumMbidParams struct { NewMbid *string OldMbid *string } // A want moved from a release id to its group (#5241) takes the requests // that name it along, so the reconciler finds it. func (q *Queries) RepointRequestsAlbumMbid(ctx context.Context, arg RepointRequestsAlbumMbidParams) error { _, err := q.db.Exec(ctx, repointRequestsAlbumMbid, arg.NewMbid, arg.OldMbid) return err }