71a9bd8dee
- Composite PK (user_id, track_id) already serves WHERE user_id queries;
the secondary (user_id, created_at DESC) index just amplified writes.
- ListQuarantineForUser now selects only the joined fields the SPA card
actually renders (~10 columns) rather than embedding three full structs
(~35 columns); halves wire/DB bandwidth before consumers exist.
- max(q.created_at)::timestamptz cast emits pgtype.Timestamptz instead of
interface{} so handlers can read latest_at without a type-assert.
363 lines
9.6 KiB
Go
363 lines
9.6 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: lidarr_quarantine.sql
|
|
|
|
package dbq
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const countQuarantineForTrack = `-- name: CountQuarantineForTrack :one
|
|
SELECT count(*)::int FROM lidarr_quarantine WHERE track_id = $1
|
|
`
|
|
|
|
// Reads affected_users for the audit row before the delete fires.
|
|
func (q *Queries) CountQuarantineForTrack(ctx context.Context, trackID pgtype.UUID) (int32, error) {
|
|
row := q.db.QueryRow(ctx, countQuarantineForTrack, trackID)
|
|
var column_1 int32
|
|
err := row.Scan(&column_1)
|
|
return column_1, err
|
|
}
|
|
|
|
const deleteQuarantine = `-- name: DeleteQuarantine :one
|
|
DELETE FROM lidarr_quarantine
|
|
WHERE user_id = $1 AND track_id = $2
|
|
RETURNING user_id, track_id, reason, notes, created_at
|
|
`
|
|
|
|
type DeleteQuarantineParams struct {
|
|
UserID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
}
|
|
|
|
// Removes the caller's row. Returns the deleted row so the handler can
|
|
// distinguish "no row existed" (zero rows -> ErrNoRows) from success.
|
|
func (q *Queries) DeleteQuarantine(ctx context.Context, arg DeleteQuarantineParams) (LidarrQuarantine, error) {
|
|
row := q.db.QueryRow(ctx, deleteQuarantine, arg.UserID, arg.TrackID)
|
|
var i LidarrQuarantine
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.TrackID,
|
|
&i.Reason,
|
|
&i.Notes,
|
|
&i.CreatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteQuarantineForTrack = `-- name: DeleteQuarantineForTrack :exec
|
|
DELETE FROM lidarr_quarantine WHERE track_id = $1
|
|
`
|
|
|
|
// Clears all per-user rows for a given track. Used by Resolve and the
|
|
// two delete actions. Caller writes the audit row separately before
|
|
// this fires (so we can capture the affected_users count).
|
|
func (q *Queries) DeleteQuarantineForTrack(ctx context.Context, trackID pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, deleteQuarantineForTrack, trackID)
|
|
return err
|
|
}
|
|
|
|
const listAdminQuarantineQueue = `-- name: ListAdminQuarantineQueue :many
|
|
SELECT
|
|
t.id AS track_id,
|
|
t.title AS track_title,
|
|
ar.name AS artist_name,
|
|
al.title AS album_title,
|
|
al.id AS album_id,
|
|
al.mbid AS lidarr_album_mbid,
|
|
count(q.user_id)::int AS report_count,
|
|
max(q.created_at)::timestamptz AS latest_at
|
|
FROM lidarr_quarantine q
|
|
JOIN tracks t ON t.id = q.track_id
|
|
JOIN albums al ON al.id = t.album_id
|
|
JOIN artists ar ON ar.id = t.artist_id
|
|
GROUP BY t.id, ar.name, al.title, al.id, al.mbid
|
|
ORDER BY max(q.created_at) DESC
|
|
`
|
|
|
|
type ListAdminQuarantineQueueRow struct {
|
|
TrackID pgtype.UUID
|
|
TrackTitle string
|
|
ArtistName string
|
|
AlbumTitle string
|
|
AlbumID pgtype.UUID
|
|
LidarrAlbumMbid *string
|
|
ReportCount int32
|
|
LatestAt pgtype.Timestamptz
|
|
}
|
|
|
|
// Aggregated admin queue. One row per track. The handler post-processes
|
|
// the rows it gets from this query plus a per-track ListQuarantineReports
|
|
// call to materialize reason_counts and the per-user reports list.
|
|
func (q *Queries) ListAdminQuarantineQueue(ctx context.Context) ([]ListAdminQuarantineQueueRow, error) {
|
|
rows, err := q.db.Query(ctx, listAdminQuarantineQueue)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListAdminQuarantineQueueRow
|
|
for rows.Next() {
|
|
var i ListAdminQuarantineQueueRow
|
|
if err := rows.Scan(
|
|
&i.TrackID,
|
|
&i.TrackTitle,
|
|
&i.ArtistName,
|
|
&i.AlbumTitle,
|
|
&i.AlbumID,
|
|
&i.LidarrAlbumMbid,
|
|
&i.ReportCount,
|
|
&i.LatestAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listQuarantineActions = `-- name: ListQuarantineActions :many
|
|
SELECT id, track_id, track_title, artist_name, album_title, action, admin_id, lidarr_album_mbid, affected_users, created_at FROM lidarr_quarantine_actions
|
|
ORDER BY created_at DESC
|
|
LIMIT $1
|
|
`
|
|
|
|
func (q *Queries) ListQuarantineActions(ctx context.Context, limit int32) ([]LidarrQuarantineAction, error) {
|
|
rows, err := q.db.Query(ctx, listQuarantineActions, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []LidarrQuarantineAction
|
|
for rows.Next() {
|
|
var i LidarrQuarantineAction
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TrackID,
|
|
&i.TrackTitle,
|
|
&i.ArtistName,
|
|
&i.AlbumTitle,
|
|
&i.Action,
|
|
&i.AdminID,
|
|
&i.LidarrAlbumMbid,
|
|
&i.AffectedUsers,
|
|
&i.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listQuarantineForUser = `-- name: ListQuarantineForUser :many
|
|
SELECT
|
|
q.user_id, q.track_id, q.reason, q.notes, q.created_at,
|
|
t.id AS track_id_join,
|
|
t.title AS track_title,
|
|
t.duration_ms AS track_duration_ms,
|
|
al.id AS album_id,
|
|
al.title AS album_title,
|
|
al.cover_art_path AS album_cover_art_path,
|
|
ar.id AS artist_id,
|
|
ar.name AS artist_name
|
|
FROM lidarr_quarantine q
|
|
JOIN tracks t ON t.id = q.track_id
|
|
JOIN albums al ON al.id = t.album_id
|
|
JOIN artists ar ON ar.id = t.artist_id
|
|
WHERE q.user_id = $1
|
|
ORDER BY q.created_at DESC
|
|
`
|
|
|
|
type ListQuarantineForUserRow struct {
|
|
LidarrQuarantine LidarrQuarantine
|
|
TrackIDJoin pgtype.UUID
|
|
TrackTitle string
|
|
TrackDurationMs int32
|
|
AlbumID pgtype.UUID
|
|
AlbumTitle string
|
|
AlbumCoverArtPath *string
|
|
ArtistID pgtype.UUID
|
|
ArtistName string
|
|
}
|
|
|
|
// Caller's own quarantines plus just the joined fields the SPA's
|
|
// /library/hidden actually renders. Embedding the full tracks/albums/artists
|
|
// structs would drag ~28 columns of file_path / sort_* / mbid / etc. that
|
|
// the row card never uses.
|
|
func (q *Queries) ListQuarantineForUser(ctx context.Context, userID pgtype.UUID) ([]ListQuarantineForUserRow, error) {
|
|
rows, err := q.db.Query(ctx, listQuarantineForUser, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListQuarantineForUserRow
|
|
for rows.Next() {
|
|
var i ListQuarantineForUserRow
|
|
if err := rows.Scan(
|
|
&i.LidarrQuarantine.UserID,
|
|
&i.LidarrQuarantine.TrackID,
|
|
&i.LidarrQuarantine.Reason,
|
|
&i.LidarrQuarantine.Notes,
|
|
&i.LidarrQuarantine.CreatedAt,
|
|
&i.TrackIDJoin,
|
|
&i.TrackTitle,
|
|
&i.TrackDurationMs,
|
|
&i.AlbumID,
|
|
&i.AlbumTitle,
|
|
&i.AlbumCoverArtPath,
|
|
&i.ArtistID,
|
|
&i.ArtistName,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listQuarantineReportsForTrack = `-- name: ListQuarantineReportsForTrack :many
|
|
SELECT
|
|
q.user_id,
|
|
u.username,
|
|
q.reason,
|
|
q.notes,
|
|
q.created_at
|
|
FROM lidarr_quarantine q
|
|
JOIN users u ON u.id = q.user_id
|
|
WHERE q.track_id = $1
|
|
ORDER BY q.created_at DESC
|
|
`
|
|
|
|
type ListQuarantineReportsForTrackRow struct {
|
|
UserID pgtype.UUID
|
|
Username string
|
|
Reason LidarrQuarantineReason
|
|
Notes *string
|
|
CreatedAt pgtype.Timestamptz
|
|
}
|
|
|
|
// Per-user reports for a single track. Returned by ListAdminQuarantineQueue
|
|
// post-processing and exposed expandable in the SPA admin queue rows.
|
|
func (q *Queries) ListQuarantineReportsForTrack(ctx context.Context, trackID pgtype.UUID) ([]ListQuarantineReportsForTrackRow, error) {
|
|
rows, err := q.db.Query(ctx, listQuarantineReportsForTrack, trackID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListQuarantineReportsForTrackRow
|
|
for rows.Next() {
|
|
var i ListQuarantineReportsForTrackRow
|
|
if err := rows.Scan(
|
|
&i.UserID,
|
|
&i.Username,
|
|
&i.Reason,
|
|
&i.Notes,
|
|
&i.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const upsertQuarantine = `-- name: UpsertQuarantine :one
|
|
INSERT INTO lidarr_quarantine (user_id, track_id, reason, notes)
|
|
VALUES ($1, $2, $3, $4)
|
|
ON CONFLICT (user_id, track_id) DO UPDATE SET
|
|
reason = EXCLUDED.reason,
|
|
notes = EXCLUDED.notes,
|
|
created_at = now()
|
|
RETURNING user_id, track_id, reason, notes, created_at
|
|
`
|
|
|
|
type UpsertQuarantineParams struct {
|
|
UserID pgtype.UUID
|
|
TrackID pgtype.UUID
|
|
Reason LidarrQuarantineReason
|
|
Notes *string
|
|
}
|
|
|
|
// Insert a new quarantine row, or update reason/notes if the user has
|
|
// already flagged this track.
|
|
func (q *Queries) UpsertQuarantine(ctx context.Context, arg UpsertQuarantineParams) (LidarrQuarantine, error) {
|
|
row := q.db.QueryRow(ctx, upsertQuarantine,
|
|
arg.UserID,
|
|
arg.TrackID,
|
|
arg.Reason,
|
|
arg.Notes,
|
|
)
|
|
var i LidarrQuarantine
|
|
err := row.Scan(
|
|
&i.UserID,
|
|
&i.TrackID,
|
|
&i.Reason,
|
|
&i.Notes,
|
|
&i.CreatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const writeQuarantineAction = `-- name: WriteQuarantineAction :one
|
|
INSERT INTO lidarr_quarantine_actions (
|
|
track_id, track_title, artist_name, album_title,
|
|
action, admin_id, lidarr_album_mbid, affected_users
|
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
RETURNING id, track_id, track_title, artist_name, album_title, action, admin_id, lidarr_album_mbid, affected_users, created_at
|
|
`
|
|
|
|
type WriteQuarantineActionParams struct {
|
|
TrackID pgtype.UUID
|
|
TrackTitle string
|
|
ArtistName string
|
|
AlbumTitle *string
|
|
Action LidarrQuarantineActionKind
|
|
AdminID pgtype.UUID
|
|
LidarrAlbumMbid *string
|
|
AffectedUsers int32
|
|
}
|
|
|
|
// Audit row for an admin destructive action.
|
|
func (q *Queries) WriteQuarantineAction(ctx context.Context, arg WriteQuarantineActionParams) (LidarrQuarantineAction, error) {
|
|
row := q.db.QueryRow(ctx, writeQuarantineAction,
|
|
arg.TrackID,
|
|
arg.TrackTitle,
|
|
arg.ArtistName,
|
|
arg.AlbumTitle,
|
|
arg.Action,
|
|
arg.AdminID,
|
|
arg.LidarrAlbumMbid,
|
|
arg.AffectedUsers,
|
|
)
|
|
var i LidarrQuarantineAction
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.TrackID,
|
|
&i.TrackTitle,
|
|
&i.ArtistName,
|
|
&i.AlbumTitle,
|
|
&i.Action,
|
|
&i.AdminID,
|
|
&i.LidarrAlbumMbid,
|
|
&i.AffectedUsers,
|
|
&i.CreatedAt,
|
|
)
|
|
return i, err
|
|
}
|