// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: tracks.sql package dbq import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const countTracksByAlbum = `-- name: CountTracksByAlbum :one SELECT count(*) FROM tracks WHERE album_id = $1 ` func (q *Queries) CountTracksByAlbum(ctx context.Context, albumID pgtype.UUID) (int64, error) { row := q.db.QueryRow(ctx, countTracksByAlbum, albumID) var count int64 err := row.Scan(&count) return count, err } const countTracksByArtist = `-- name: CountTracksByArtist :one SELECT COUNT(*) FROM tracks WHERE artist_id = $1 ` // Used by request-progress reporting to count tracks ingested under a // matched artist (sum across all the artist's albums) while a request // is still in flight. func (q *Queries) CountTracksByArtist(ctx context.Context, artistID pgtype.UUID) (int64, error) { row := q.db.QueryRow(ctx, countTracksByArtist, artistID) var count int64 err := row.Scan(&count) return count, err } const countTracksMatching = `-- name: CountTracksMatching :one SELECT COUNT(*) FROM tracks WHERE title ILIKE '%' || $1::text || '%' ` func (q *Queries) CountTracksMatching(ctx context.Context, dollar_1 string) (int64, error) { row := q.db.QueryRow(ctx, countTracksMatching, dollar_1) var count int64 err := row.Scan(&count) return count, err } const countTracksMatchingForUser = `-- name: CountTracksMatchingForUser :one SELECT COUNT(*) FROM tracks WHERE title ILIKE '%' || $1::text || '%' AND NOT EXISTS ( SELECT 1 FROM lidarr_quarantine q WHERE q.user_id = $2 AND q.track_id = tracks.id ) ` type CountTracksMatchingForUserParams struct { Column1 string UserID pgtype.UUID } // $1 = title query, $2 = user_id. func (q *Queries) CountTracksMatchingForUser(ctx context.Context, arg CountTracksMatchingForUserParams) (int64, error) { row := q.db.QueryRow(ctx, countTracksMatchingForUser, arg.Column1, arg.UserID) var count int64 err := row.Scan(&count) return count, err } const deleteTrack = `-- name: DeleteTrack :one DELETE FROM tracks WHERE id = $1 RETURNING id, album_id, artist_id, file_path, mbid ` type DeleteTrackRow struct { ID pgtype.UUID AlbumID pgtype.UUID ArtistID pgtype.UUID FilePath string Mbid *string } // M7 #372: hard delete with FK cascade. The CASCADE on track_id from // play_events / general_likes_tracks / lidarr_quarantine / // lidarr_quarantine_actions handles their cleanup. RETURNING gives us // album_id + artist_id for the album-empty / artist-empty cascade // checks the service does next. func (q *Queries) DeleteTrack(ctx context.Context, id pgtype.UUID) (DeleteTrackRow, error) { row := q.db.QueryRow(ctx, deleteTrack, id) var i DeleteTrackRow err := row.Scan( &i.ID, &i.AlbumID, &i.ArtistID, &i.FilePath, &i.Mbid, ) return i, err } const getTrackByID = `-- name: GetTrackByID :one SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE id = $1 ` func (q *Queries) GetTrackByID(ctx context.Context, id pgtype.UUID) (Track, error) { row := q.db.QueryRow(ctx, getTrackByID, id) var i Track err := row.Scan( &i.ID, &i.Title, &i.AlbumID, &i.ArtistID, &i.TrackNumber, &i.DiscNumber, &i.DurationMs, &i.FilePath, &i.FileSize, &i.FileFormat, &i.Bitrate, &i.Mbid, &i.Genre, &i.AddedAt, &i.UpdatedAt, ) return i, err } const getTrackByPath = `-- name: GetTrackByPath :one SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE file_path = $1 ` func (q *Queries) GetTrackByPath(ctx context.Context, filePath string) (Track, error) { row := q.db.QueryRow(ctx, getTrackByPath, filePath) var i Track err := row.Scan( &i.ID, &i.Title, &i.AlbumID, &i.ArtistID, &i.TrackNumber, &i.DiscNumber, &i.DurationMs, &i.FilePath, &i.FileSize, &i.FileFormat, &i.Bitrate, &i.Mbid, &i.Genre, &i.AddedAt, &i.UpdatedAt, ) return i, err } const listArtistTracksForUser = `-- name: ListArtistTracksForUser :many SELECT t.id, t.title, t.album_id, t.artist_id, t.track_number, t.disc_number, t.duration_ms, t.file_path, t.file_size, t.file_format, t.bitrate, t.mbid, t.genre, t.added_at, t.updated_at, albums.title AS album_title, artists.name AS artist_name FROM tracks t JOIN albums ON albums.id = t.album_id JOIN artists ON artists.id = t.artist_id WHERE t.artist_id = $1 AND NOT EXISTS ( SELECT 1 FROM lidarr_quarantine q WHERE q.user_id = $2 AND q.track_id = t.id ) ORDER BY albums.release_date NULLS LAST, albums.sort_title, t.disc_number NULLS FIRST, t.track_number NULLS FIRST, t.id ` type ListArtistTracksForUserParams struct { ArtistID pgtype.UUID UserID pgtype.UUID } type ListArtistTracksForUserRow struct { Track Track AlbumTitle string ArtistName string } // M6a: every track for the artist across their albums, with album_title // and artist_name joined. Honors per-user lidarr_quarantine. Used by // /api/artists/{id}/tracks for the artist-card play affordance, which // shuffles client-side. Ordering matches album/track natural order so // the shuffle has a deterministic input. func (q *Queries) ListArtistTracksForUser(ctx context.Context, arg ListArtistTracksForUserParams) ([]ListArtistTracksForUserRow, error) { rows, err := q.db.Query(ctx, listArtistTracksForUser, arg.ArtistID, arg.UserID) if err != nil { return nil, err } defer rows.Close() var items []ListArtistTracksForUserRow for rows.Next() { var i ListArtistTracksForUserRow if err := rows.Scan( &i.Track.ID, &i.Track.Title, &i.Track.AlbumID, &i.Track.ArtistID, &i.Track.TrackNumber, &i.Track.DiscNumber, &i.Track.DurationMs, &i.Track.FilePath, &i.Track.FileSize, &i.Track.FileFormat, &i.Track.Bitrate, &i.Track.Mbid, &i.Track.Genre, &i.Track.AddedAt, &i.Track.UpdatedAt, &i.AlbumTitle, &i.ArtistName, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listTracksByAlbum = `-- name: ListTracksByAlbum :many SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE album_id = $1 ORDER BY disc_number NULLS LAST, track_number NULLS LAST ` func (q *Queries) ListTracksByAlbum(ctx context.Context, albumID pgtype.UUID) ([]Track, error) { rows, err := q.db.Query(ctx, listTracksByAlbum, albumID) if err != nil { return nil, err } defer rows.Close() var items []Track for rows.Next() { var i Track if err := rows.Scan( &i.ID, &i.Title, &i.AlbumID, &i.ArtistID, &i.TrackNumber, &i.DiscNumber, &i.DurationMs, &i.FilePath, &i.FileSize, &i.FileFormat, &i.Bitrate, &i.Mbid, &i.Genre, &i.AddedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listTracksByAlbumForUser = `-- name: ListTracksByAlbumForUser :many SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE album_id = $1 AND NOT EXISTS ( SELECT 1 FROM lidarr_quarantine q WHERE q.user_id = $2 AND q.track_id = tracks.id ) ORDER BY disc_number NULLS LAST, track_number NULLS LAST ` type ListTracksByAlbumForUserParams struct { AlbumID pgtype.UUID UserID pgtype.UUID } // Same as ListTracksByAlbum but excludes tracks the user has quarantined. // $1 = album_id, $2 = user_id. func (q *Queries) ListTracksByAlbumForUser(ctx context.Context, arg ListTracksByAlbumForUserParams) ([]Track, error) { rows, err := q.db.Query(ctx, listTracksByAlbumForUser, arg.AlbumID, arg.UserID) if err != nil { return nil, err } defer rows.Close() var items []Track for rows.Next() { var i Track if err := rows.Scan( &i.ID, &i.Title, &i.AlbumID, &i.ArtistID, &i.TrackNumber, &i.DiscNumber, &i.DurationMs, &i.FilePath, &i.FileSize, &i.FileFormat, &i.Bitrate, &i.Mbid, &i.Genre, &i.AddedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const searchTracks = `-- name: SearchTracks :many SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE title ILIKE '%' || $1 || '%' ORDER BY title LIMIT $2 OFFSET $3 ` type SearchTracksParams struct { Column1 *string Limit int32 Offset int32 } func (q *Queries) SearchTracks(ctx context.Context, arg SearchTracksParams) ([]Track, error) { rows, err := q.db.Query(ctx, searchTracks, arg.Column1, arg.Limit, arg.Offset) if err != nil { return nil, err } defer rows.Close() var items []Track for rows.Next() { var i Track if err := rows.Scan( &i.ID, &i.Title, &i.AlbumID, &i.ArtistID, &i.TrackNumber, &i.DiscNumber, &i.DurationMs, &i.FilePath, &i.FileSize, &i.FileFormat, &i.Bitrate, &i.Mbid, &i.Genre, &i.AddedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const searchTracksForUser = `-- name: SearchTracksForUser :many SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE title ILIKE '%' || $1 || '%' AND NOT EXISTS ( SELECT 1 FROM lidarr_quarantine q WHERE q.user_id = $2 AND q.track_id = tracks.id ) ORDER BY title LIMIT $3 OFFSET $4 ` type SearchTracksForUserParams struct { Column1 *string UserID pgtype.UUID Limit int32 Offset int32 } // $1 = title query, $2 = user_id, $3 = limit, $4 = offset. func (q *Queries) SearchTracksForUser(ctx context.Context, arg SearchTracksForUserParams) ([]Track, error) { rows, err := q.db.Query(ctx, searchTracksForUser, arg.Column1, arg.UserID, arg.Limit, arg.Offset, ) if err != nil { return nil, err } defer rows.Close() var items []Track for rows.Next() { var i Track if err := rows.Scan( &i.ID, &i.Title, &i.AlbumID, &i.ArtistID, &i.TrackNumber, &i.DiscNumber, &i.DurationMs, &i.FilePath, &i.FileSize, &i.FileFormat, &i.Bitrate, &i.Mbid, &i.Genre, &i.AddedAt, &i.UpdatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const upsertTrack = `-- name: UpsertTrack :one INSERT INTO tracks ( title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) ON CONFLICT (file_path) DO UPDATE SET title = EXCLUDED.title, album_id = EXCLUDED.album_id, artist_id = EXCLUDED.artist_id, track_number = EXCLUDED.track_number, disc_number = EXCLUDED.disc_number, duration_ms = EXCLUDED.duration_ms, file_size = EXCLUDED.file_size, file_format = EXCLUDED.file_format, bitrate = EXCLUDED.bitrate, mbid = EXCLUDED.mbid, genre = EXCLUDED.genre, updated_at = now() RETURNING id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at ` type UpsertTrackParams struct { Title string AlbumID pgtype.UUID ArtistID pgtype.UUID TrackNumber *int32 DiscNumber *int32 DurationMs int32 FilePath string FileSize int64 FileFormat string Bitrate *int32 Mbid *string Genre *string } // file_path is the canonical identity for library scan; mbid is secondary. func (q *Queries) UpsertTrack(ctx context.Context, arg UpsertTrackParams) (Track, error) { row := q.db.QueryRow(ctx, upsertTrack, arg.Title, arg.AlbumID, arg.ArtistID, arg.TrackNumber, arg.DiscNumber, arg.DurationMs, arg.FilePath, arg.FileSize, arg.FileFormat, arg.Bitrate, arg.Mbid, arg.Genre, ) var i Track err := row.Scan( &i.ID, &i.Title, &i.AlbumID, &i.ArtistID, &i.TrackNumber, &i.DiscNumber, &i.DurationMs, &i.FilePath, &i.FileSize, &i.FileFormat, &i.Bitrate, &i.Mbid, &i.Genre, &i.AddedAt, &i.UpdatedAt, ) return i, err }