feat(13-01): add library-filtered sqlc queries for all browse views

- GetAllTracksWithFullMetadataByLibrary for tracks filtered by library
- GetAudioFilesByReleaseGroupByLibrary for album tracks in a library
- GetAllAlbumsWithDetailsByLibrary for albums with tracks in a library
- GetAlbumsByArtistByLibrary for artist albums in a library
- GetAlbumArtistsByLibrary for artists with albums in a library
- GetAllGenresWithCountsByLibrary for genre counts within a library
- GetTracksByGenreByLibrary for genre tracks within a library
This commit is contained in:
2026-03-16 09:26:42 -04:00
parent 66ba5ad1a6
commit 5cc58ce66a
8 changed files with 698 additions and 0 deletions
+18
View File
@@ -38,3 +38,21 @@ JOIN artist_credit_artist aca ON aca.artist_id = a.id
JOIN artist_credit ac ON ac.id = aca.credit_id JOIN artist_credit ac ON ac.id = aca.credit_id
JOIN release_groups rg ON rg.album_artist_credit_id = ac.id JOIN release_groups rg ON rg.album_artist_credit_id = ac.id
ORDER BY a.name; ORDER BY a.name;
-- name: GetAlbumArtistsByLibrary :many
SELECT DISTINCT a.id, a.name
FROM artists a
JOIN artist_credit_artist aca ON aca.artist_id = a.id
JOIN artist_credit ac ON ac.id = aca.credit_id
JOIN release_groups rg ON rg.album_artist_credit_id = ac.id
WHERE a.id IN (
SELECT DISTINCT aca2.artist_id
FROM artist_credit_artist aca2
JOIN artist_credit ac2 ON ac2.id = aca2.credit_id
JOIN release_groups rg2 ON rg2.album_artist_credit_id = ac2.id
JOIN release_group_recordings rgr2 ON rgr2.release_group_id = rg2.id
JOIN recordings r2 ON r2.id = rgr2.recording_id
JOIN audio_files af2 ON af2.recording_id = r2.id
WHERE af2.library_id = ?
)
ORDER BY a.name;
@@ -136,6 +136,38 @@ SELECT COUNT(*) AS count FROM audio_files WHERE library_id = ?;
-- name: DeleteAllAudioFiles :exec -- name: DeleteAllAudioFiles :exec
DELETE FROM audio_files; DELETE FROM audio_files;
-- name: GetAllTracksWithFullMetadataByLibrary :many
SELECT
af.file_path,
af.length_milliseconds,
COALESCE(r.name, '') AS title,
COALESCE(ac.text, '') AS artist_name,
r.track_number,
r.disc_number,
COALESCE(rg.name, '') AS album,
CAST(COALESCE(
(SELECT GROUP_CONCAT(g.name, '||')
FROM recording_genres rg_sub
JOIN genres g ON rg_sub.genre_id = g.id
WHERE rg_sub.recording_id = r.id),
''
) AS TEXT) AS genre,
COALESCE(r.year, 0) AS year,
COALESCE(r.composer, '') AS composer,
COALESCE(ft.extension, '') AS file_type,
af.sample_rate,
af.bit_depth,
af.channels,
af.bitrate,
af.file_size
FROM audio_files af
JOIN recordings r ON af.recording_id = r.id
JOIN artist_credit ac ON r.artist_credit_id = ac.id
LEFT JOIN release_group_recordings rgr ON r.id = rgr.recording_id
LEFT JOIN release_groups rg ON rgr.release_group_id = rg.id
LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE af.library_id = ?;
-- name: GetAudioFilesByReleaseGroup :many -- name: GetAudioFilesByReleaseGroup :many
SELECT SELECT
af.file_path, af.file_path,
@@ -168,3 +200,36 @@ LEFT JOIN release_groups rg ON rgr.release_group_id = rg.id
LEFT JOIN file_types ft ON af.file_type_id = ft.id LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE rgr.release_group_id = ? WHERE rgr.release_group_id = ?
ORDER BY rgr.disc_number, rgr.track_number; ORDER BY rgr.disc_number, rgr.track_number;
-- name: GetAudioFilesByReleaseGroupByLibrary :many
SELECT
af.file_path,
af.length_milliseconds,
COALESCE(r.name, '') AS title,
COALESCE(ac.text, '') AS artist_name,
rgr.track_number,
rgr.disc_number,
COALESCE(rg.name, '') AS album,
CAST(COALESCE(
(SELECT GROUP_CONCAT(g.name, '||')
FROM recording_genres rg_sub
JOIN genres g ON rg_sub.genre_id = g.id
WHERE rg_sub.recording_id = r.id),
''
) AS TEXT) AS genre,
COALESCE(r.year, 0) AS year,
COALESCE(r.composer, '') AS composer,
COALESCE(ft.extension, '') AS file_type,
af.sample_rate,
af.bit_depth,
af.channels,
af.bitrate,
af.file_size
FROM release_group_recordings rgr
JOIN recordings r ON rgr.recording_id = r.id
JOIN audio_files af ON af.recording_id = r.id
LEFT JOIN artist_credit ac ON r.artist_credit_id = ac.id
LEFT JOIN release_groups rg ON rgr.release_group_id = rg.id
LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE rgr.release_group_id = ? AND af.library_id = ?
ORDER BY rgr.disc_number, rgr.track_number;
+50
View File
@@ -63,9 +63,59 @@ LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE g.name = ? WHERE g.name = ?
ORDER BY r.name; ORDER BY r.name;
-- name: GetTracksByGenreByLibrary :many
SELECT
af.file_path,
af.length_milliseconds,
COALESCE(r.name, '') AS title,
COALESCE(ac.text, '') AS artist_name,
r.track_number,
r.disc_number,
COALESCE(rlg.name, '') AS album,
CAST(COALESCE(
(SELECT GROUP_CONCAT(g2.name, '||')
FROM recording_genres rg2
JOIN genres g2 ON rg2.genre_id = g2.id
WHERE rg2.recording_id = r.id),
''
) AS TEXT) AS genre,
COALESCE(r.year, 0) AS year,
COALESCE(r.composer, '') AS composer,
COALESCE(ft.extension, '') AS file_type,
af.sample_rate,
af.bit_depth,
af.channels,
af.bitrate,
af.file_size
FROM genres g
JOIN recording_genres rg ON g.id = rg.genre_id
JOIN recordings r ON rg.recording_id = r.id
JOIN audio_files af ON af.recording_id = r.id
JOIN artist_credit ac ON r.artist_credit_id = ac.id
LEFT JOIN (
SELECT recording_id,
MIN(release_group_id) AS release_group_id
FROM release_group_recordings
GROUP BY recording_id
) rgr ON r.id = rgr.recording_id
LEFT JOIN release_groups rlg ON rgr.release_group_id = rlg.id
LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE g.name = ? AND af.library_id = ?
ORDER BY r.name;
-- name: GetAllGenresWithCounts :many -- name: GetAllGenresWithCounts :many
SELECT g.name, COUNT(rg.recording_id) AS track_count SELECT g.name, COUNT(rg.recording_id) AS track_count
FROM genres g FROM genres g
JOIN recording_genres rg ON g.id = rg.genre_id JOIN recording_genres rg ON g.id = rg.genre_id
GROUP BY g.id, g.name GROUP BY g.id, g.name
ORDER BY g.name; ORDER BY g.name;
-- name: GetAllGenresWithCountsByLibrary :many
SELECT g.name, COUNT(rg.recording_id) AS track_count
FROM genres g
JOIN recording_genres rg ON g.id = rg.genre_id
JOIN recordings r ON rg.recording_id = r.id
JOIN audio_files af ON af.recording_id = r.id
WHERE af.library_id = ?
GROUP BY g.id, g.name
ORDER BY g.name;
@@ -64,6 +64,32 @@ LEFT JOIN (
) fallback_ac ON fallback_ac.release_group_id = rg.id ) fallback_ac ON fallback_ac.release_group_id = rg.id
ORDER BY rg.name; ORDER BY rg.name;
-- name: GetAllAlbumsWithDetailsByLibrary :many
SELECT
rg.id,
rg.name,
rg.year,
COALESCE(ac.text, fallback_ac.text, '') as artist_name,
COALESCE(ca.file_path, '') as cover_art_path
FROM release_groups rg
LEFT JOIN artist_credit ac ON rg.album_artist_credit_id = ac.id
LEFT JOIN cover_art ca ON rg.cover_art_id = ca.id
LEFT JOIN (
SELECT rgr.release_group_id, ac2.text
FROM release_group_recordings rgr
JOIN recordings rec ON rec.id = rgr.recording_id
JOIN artist_credit ac2 ON ac2.id = rec.artist_credit_id
GROUP BY rgr.release_group_id
) fallback_ac ON fallback_ac.release_group_id = rg.id
WHERE rg.id IN (
SELECT DISTINCT rgr2.release_group_id
FROM release_group_recordings rgr2
JOIN recordings r2 ON r2.id = rgr2.recording_id
JOIN audio_files af2 ON af2.recording_id = r2.id
WHERE af2.library_id = ?
)
ORDER BY rg.name;
-- name: GetAlbumsByArtist :many -- name: GetAlbumsByArtist :many
SELECT SELECT
rg.id, rg.id,
@@ -84,3 +110,31 @@ LEFT JOIN (
) fallback_ac ON fallback_ac.release_group_id = rg.id ) fallback_ac ON fallback_ac.release_group_id = rg.id
WHERE aca.artist_id = ? WHERE aca.artist_id = ?
ORDER BY rg.name; ORDER BY rg.name;
-- name: GetAlbumsByArtistByLibrary :many
SELECT
rg.id,
rg.name,
rg.year,
COALESCE(ac.text, fallback_ac.text, '') as artist_name,
COALESCE(ca.file_path, '') as cover_art_path
FROM release_groups rg
JOIN artist_credit ac ON rg.album_artist_credit_id = ac.id
JOIN artist_credit_artist aca ON aca.credit_id = ac.id
LEFT JOIN cover_art ca ON rg.cover_art_id = ca.id
LEFT JOIN (
SELECT rgr.release_group_id, ac2.text
FROM release_group_recordings rgr
JOIN recordings rec ON rec.id = rgr.recording_id
JOIN artist_credit ac2 ON ac2.id = rec.artist_credit_id
GROUP BY rgr.release_group_id
) fallback_ac ON fallback_ac.release_group_id = rg.id
WHERE aca.artist_id = ?
AND rg.id IN (
SELECT DISTINCT rgr2.release_group_id
FROM release_group_recordings rgr2
JOIN recordings r2 ON r2.id = rgr2.recording_id
JOIN audio_files af2 ON af2.recording_id = r2.id
WHERE af2.library_id = ?
)
ORDER BY rg.name;
@@ -72,6 +72,48 @@ func (q *Queries) GetAlbumArtists(ctx context.Context) ([]Artist, error) {
return items, nil return items, nil
} }
const getAlbumArtistsByLibrary = `-- name: GetAlbumArtistsByLibrary :many
SELECT DISTINCT a.id, a.name
FROM artists a
JOIN artist_credit_artist aca ON aca.artist_id = a.id
JOIN artist_credit ac ON ac.id = aca.credit_id
JOIN release_groups rg ON rg.album_artist_credit_id = ac.id
WHERE a.id IN (
SELECT DISTINCT aca2.artist_id
FROM artist_credit_artist aca2
JOIN artist_credit ac2 ON ac2.id = aca2.credit_id
JOIN release_groups rg2 ON rg2.album_artist_credit_id = ac2.id
JOIN release_group_recordings rgr2 ON rgr2.release_group_id = rg2.id
JOIN recordings r2 ON r2.id = rgr2.recording_id
JOIN audio_files af2 ON af2.recording_id = r2.id
WHERE af2.library_id = ?
)
ORDER BY a.name
`
func (q *Queries) GetAlbumArtistsByLibrary(ctx context.Context, libraryID int64) ([]Artist, error) {
rows, err := q.db.QueryContext(ctx, getAlbumArtistsByLibrary, libraryID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Artist
for rows.Next() {
var i Artist
if err := rows.Scan(&i.ID, &i.Name); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getAllArtists = `-- name: GetAllArtists :many const getAllArtists = `-- name: GetAllArtists :many
SELECT id, name FROM artists SELECT id, name FROM artists
ORDER BY name ORDER BY name
@@ -321,6 +321,98 @@ func (q *Queries) GetAllTracksWithFullMetadata(ctx context.Context) ([]GetAllTra
return items, nil return items, nil
} }
const getAllTracksWithFullMetadataByLibrary = `-- name: GetAllTracksWithFullMetadataByLibrary :many
SELECT
af.file_path,
af.length_milliseconds,
COALESCE(r.name, '') AS title,
COALESCE(ac.text, '') AS artist_name,
r.track_number,
r.disc_number,
COALESCE(rg.name, '') AS album,
CAST(COALESCE(
(SELECT GROUP_CONCAT(g.name, '||')
FROM recording_genres rg_sub
JOIN genres g ON rg_sub.genre_id = g.id
WHERE rg_sub.recording_id = r.id),
''
) AS TEXT) AS genre,
COALESCE(r.year, 0) AS year,
COALESCE(r.composer, '') AS composer,
COALESCE(ft.extension, '') AS file_type,
af.sample_rate,
af.bit_depth,
af.channels,
af.bitrate,
af.file_size
FROM audio_files af
JOIN recordings r ON af.recording_id = r.id
JOIN artist_credit ac ON r.artist_credit_id = ac.id
LEFT JOIN release_group_recordings rgr ON r.id = rgr.recording_id
LEFT JOIN release_groups rg ON rgr.release_group_id = rg.id
LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE af.library_id = ?
`
type GetAllTracksWithFullMetadataByLibraryRow struct {
FilePath string
LengthMilliseconds int64
Title string
ArtistName string
TrackNumber sql.NullInt64
DiscNumber sql.NullInt64
Album string
Genre string
Year int64
Composer string
FileType string
SampleRate int64
BitDepth int64
Channels int64
Bitrate int64
FileSize int64
}
func (q *Queries) GetAllTracksWithFullMetadataByLibrary(ctx context.Context, libraryID int64) ([]GetAllTracksWithFullMetadataByLibraryRow, error) {
rows, err := q.db.QueryContext(ctx, getAllTracksWithFullMetadataByLibrary, libraryID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetAllTracksWithFullMetadataByLibraryRow
for rows.Next() {
var i GetAllTracksWithFullMetadataByLibraryRow
if err := rows.Scan(
&i.FilePath,
&i.LengthMilliseconds,
&i.Title,
&i.ArtistName,
&i.TrackNumber,
&i.DiscNumber,
&i.Album,
&i.Genre,
&i.Year,
&i.Composer,
&i.FileType,
&i.SampleRate,
&i.BitDepth,
&i.Channels,
&i.Bitrate,
&i.FileSize,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getAudioFile = `-- name: GetAudioFile :one const getAudioFile = `-- name: GetAudioFile :one
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id FROM audio_files SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id FROM audio_files
WHERE id = ? LIMIT 1 WHERE id = ? LIMIT 1
@@ -504,6 +596,104 @@ func (q *Queries) GetAudioFilesByReleaseGroup(ctx context.Context, releaseGroupI
return items, nil return items, nil
} }
const getAudioFilesByReleaseGroupByLibrary = `-- name: GetAudioFilesByReleaseGroupByLibrary :many
SELECT
af.file_path,
af.length_milliseconds,
COALESCE(r.name, '') AS title,
COALESCE(ac.text, '') AS artist_name,
rgr.track_number,
rgr.disc_number,
COALESCE(rg.name, '') AS album,
CAST(COALESCE(
(SELECT GROUP_CONCAT(g.name, '||')
FROM recording_genres rg_sub
JOIN genres g ON rg_sub.genre_id = g.id
WHERE rg_sub.recording_id = r.id),
''
) AS TEXT) AS genre,
COALESCE(r.year, 0) AS year,
COALESCE(r.composer, '') AS composer,
COALESCE(ft.extension, '') AS file_type,
af.sample_rate,
af.bit_depth,
af.channels,
af.bitrate,
af.file_size
FROM release_group_recordings rgr
JOIN recordings r ON rgr.recording_id = r.id
JOIN audio_files af ON af.recording_id = r.id
LEFT JOIN artist_credit ac ON r.artist_credit_id = ac.id
LEFT JOIN release_groups rg ON rgr.release_group_id = rg.id
LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE rgr.release_group_id = ? AND af.library_id = ?
ORDER BY rgr.disc_number, rgr.track_number
`
type GetAudioFilesByReleaseGroupByLibraryParams struct {
ReleaseGroupID int64
LibraryID int64
}
type GetAudioFilesByReleaseGroupByLibraryRow struct {
FilePath string
LengthMilliseconds int64
Title string
ArtistName string
TrackNumber sql.NullInt64
DiscNumber sql.NullInt64
Album string
Genre string
Year int64
Composer string
FileType string
SampleRate int64
BitDepth int64
Channels int64
Bitrate int64
FileSize int64
}
func (q *Queries) GetAudioFilesByReleaseGroupByLibrary(ctx context.Context, arg GetAudioFilesByReleaseGroupByLibraryParams) ([]GetAudioFilesByReleaseGroupByLibraryRow, error) {
rows, err := q.db.QueryContext(ctx, getAudioFilesByReleaseGroupByLibrary, arg.ReleaseGroupID, arg.LibraryID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetAudioFilesByReleaseGroupByLibraryRow
for rows.Next() {
var i GetAudioFilesByReleaseGroupByLibraryRow
if err := rows.Scan(
&i.FilePath,
&i.LengthMilliseconds,
&i.Title,
&i.ArtistName,
&i.TrackNumber,
&i.DiscNumber,
&i.Album,
&i.Genre,
&i.Year,
&i.Composer,
&i.FileType,
&i.SampleRate,
&i.BitDepth,
&i.Channels,
&i.Bitrate,
&i.FileSize,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getAudioFilesNeedingMetadata = `-- name: GetAudioFilesNeedingMetadata :many const getAudioFilesNeedingMetadata = `-- name: GetAudioFilesNeedingMetadata :many
SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id FROM audio_files SELECT id, file_path, length_milliseconds, file_type_id, recording_id, sample_rate, bit_depth, channels, bitrate, file_size, basename, library_id FROM audio_files
WHERE recording_id = 0 WHERE recording_id = 0
+144
View File
@@ -89,6 +89,45 @@ func (q *Queries) GetAllGenresWithCounts(ctx context.Context) ([]GetAllGenresWit
return items, nil return items, nil
} }
const getAllGenresWithCountsByLibrary = `-- name: GetAllGenresWithCountsByLibrary :many
SELECT g.name, COUNT(rg.recording_id) AS track_count
FROM genres g
JOIN recording_genres rg ON g.id = rg.genre_id
JOIN recordings r ON rg.recording_id = r.id
JOIN audio_files af ON af.recording_id = r.id
WHERE af.library_id = ?
GROUP BY g.id, g.name
ORDER BY g.name
`
type GetAllGenresWithCountsByLibraryRow struct {
Name string
TrackCount int64
}
func (q *Queries) GetAllGenresWithCountsByLibrary(ctx context.Context, libraryID int64) ([]GetAllGenresWithCountsByLibraryRow, error) {
rows, err := q.db.QueryContext(ctx, getAllGenresWithCountsByLibrary, libraryID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetAllGenresWithCountsByLibraryRow
for rows.Next() {
var i GetAllGenresWithCountsByLibraryRow
if err := rows.Scan(&i.Name, &i.TrackCount); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getGenresByRecordingID = `-- name: GetGenresByRecordingID :many const getGenresByRecordingID = `-- name: GetGenresByRecordingID :many
SELECT g.id, g.name SELECT g.id, g.name
FROM genres g FROM genres g
@@ -219,6 +258,111 @@ func (q *Queries) GetTracksByGenre(ctx context.Context, name string) ([]GetTrack
return items, nil return items, nil
} }
const getTracksByGenreByLibrary = `-- name: GetTracksByGenreByLibrary :many
SELECT
af.file_path,
af.length_milliseconds,
COALESCE(r.name, '') AS title,
COALESCE(ac.text, '') AS artist_name,
r.track_number,
r.disc_number,
COALESCE(rlg.name, '') AS album,
CAST(COALESCE(
(SELECT GROUP_CONCAT(g2.name, '||')
FROM recording_genres rg2
JOIN genres g2 ON rg2.genre_id = g2.id
WHERE rg2.recording_id = r.id),
''
) AS TEXT) AS genre,
COALESCE(r.year, 0) AS year,
COALESCE(r.composer, '') AS composer,
COALESCE(ft.extension, '') AS file_type,
af.sample_rate,
af.bit_depth,
af.channels,
af.bitrate,
af.file_size
FROM genres g
JOIN recording_genres rg ON g.id = rg.genre_id
JOIN recordings r ON rg.recording_id = r.id
JOIN audio_files af ON af.recording_id = r.id
JOIN artist_credit ac ON r.artist_credit_id = ac.id
LEFT JOIN (
SELECT recording_id,
MIN(release_group_id) AS release_group_id
FROM release_group_recordings
GROUP BY recording_id
) rgr ON r.id = rgr.recording_id
LEFT JOIN release_groups rlg ON rgr.release_group_id = rlg.id
LEFT JOIN file_types ft ON af.file_type_id = ft.id
WHERE g.name = ? AND af.library_id = ?
ORDER BY r.name
`
type GetTracksByGenreByLibraryParams struct {
Name string
LibraryID int64
}
type GetTracksByGenreByLibraryRow struct {
FilePath string
LengthMilliseconds int64
Title string
ArtistName string
TrackNumber sql.NullInt64
DiscNumber sql.NullInt64
Album string
Genre string
Year int64
Composer string
FileType string
SampleRate int64
BitDepth int64
Channels int64
Bitrate int64
FileSize int64
}
func (q *Queries) GetTracksByGenreByLibrary(ctx context.Context, arg GetTracksByGenreByLibraryParams) ([]GetTracksByGenreByLibraryRow, error) {
rows, err := q.db.QueryContext(ctx, getTracksByGenreByLibrary, arg.Name, arg.LibraryID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetTracksByGenreByLibraryRow
for rows.Next() {
var i GetTracksByGenreByLibraryRow
if err := rows.Scan(
&i.FilePath,
&i.LengthMilliseconds,
&i.Title,
&i.ArtistName,
&i.TrackNumber,
&i.DiscNumber,
&i.Album,
&i.Genre,
&i.Year,
&i.Composer,
&i.FileType,
&i.SampleRate,
&i.BitDepth,
&i.Channels,
&i.Bitrate,
&i.FileSize,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const upsertGenre = `-- name: UpsertGenre :one const upsertGenre = `-- name: UpsertGenre :one
INSERT INTO genres (name) VALUES (?) INSERT INTO genres (name) VALUES (?)
ON CONFLICT(name) DO UPDATE SET name = name ON CONFLICT(name) DO UPDATE SET name = name
@@ -146,6 +146,77 @@ func (q *Queries) GetAlbumsByArtist(ctx context.Context, artistID int64) ([]GetA
return items, nil return items, nil
} }
const getAlbumsByArtistByLibrary = `-- name: GetAlbumsByArtistByLibrary :many
SELECT
rg.id,
rg.name,
rg.year,
COALESCE(ac.text, fallback_ac.text, '') as artist_name,
COALESCE(ca.file_path, '') as cover_art_path
FROM release_groups rg
JOIN artist_credit ac ON rg.album_artist_credit_id = ac.id
JOIN artist_credit_artist aca ON aca.credit_id = ac.id
LEFT JOIN cover_art ca ON rg.cover_art_id = ca.id
LEFT JOIN (
SELECT rgr.release_group_id, ac2.text
FROM release_group_recordings rgr
JOIN recordings rec ON rec.id = rgr.recording_id
JOIN artist_credit ac2 ON ac2.id = rec.artist_credit_id
GROUP BY rgr.release_group_id
) fallback_ac ON fallback_ac.release_group_id = rg.id
WHERE aca.artist_id = ?
AND rg.id IN (
SELECT DISTINCT rgr2.release_group_id
FROM release_group_recordings rgr2
JOIN recordings r2 ON r2.id = rgr2.recording_id
JOIN audio_files af2 ON af2.recording_id = r2.id
WHERE af2.library_id = ?
)
ORDER BY rg.name
`
type GetAlbumsByArtistByLibraryParams struct {
ArtistID int64
LibraryID int64
}
type GetAlbumsByArtistByLibraryRow struct {
ID int64
Name string
Year sql.NullInt64
ArtistName string
CoverArtPath string
}
func (q *Queries) GetAlbumsByArtistByLibrary(ctx context.Context, arg GetAlbumsByArtistByLibraryParams) ([]GetAlbumsByArtistByLibraryRow, error) {
rows, err := q.db.QueryContext(ctx, getAlbumsByArtistByLibrary, arg.ArtistID, arg.LibraryID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetAlbumsByArtistByLibraryRow
for rows.Next() {
var i GetAlbumsByArtistByLibraryRow
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Year,
&i.ArtistName,
&i.CoverArtPath,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getAllAlbumsWithDetails = `-- name: GetAllAlbumsWithDetails :many const getAllAlbumsWithDetails = `-- name: GetAllAlbumsWithDetails :many
SELECT SELECT
rg.id, rg.id,
@@ -203,6 +274,70 @@ func (q *Queries) GetAllAlbumsWithDetails(ctx context.Context) ([]GetAllAlbumsWi
return items, nil return items, nil
} }
const getAllAlbumsWithDetailsByLibrary = `-- name: GetAllAlbumsWithDetailsByLibrary :many
SELECT
rg.id,
rg.name,
rg.year,
COALESCE(ac.text, fallback_ac.text, '') as artist_name,
COALESCE(ca.file_path, '') as cover_art_path
FROM release_groups rg
LEFT JOIN artist_credit ac ON rg.album_artist_credit_id = ac.id
LEFT JOIN cover_art ca ON rg.cover_art_id = ca.id
LEFT JOIN (
SELECT rgr.release_group_id, ac2.text
FROM release_group_recordings rgr
JOIN recordings rec ON rec.id = rgr.recording_id
JOIN artist_credit ac2 ON ac2.id = rec.artist_credit_id
GROUP BY rgr.release_group_id
) fallback_ac ON fallback_ac.release_group_id = rg.id
WHERE rg.id IN (
SELECT DISTINCT rgr2.release_group_id
FROM release_group_recordings rgr2
JOIN recordings r2 ON r2.id = rgr2.recording_id
JOIN audio_files af2 ON af2.recording_id = r2.id
WHERE af2.library_id = ?
)
ORDER BY rg.name
`
type GetAllAlbumsWithDetailsByLibraryRow struct {
ID int64
Name string
Year sql.NullInt64
ArtistName string
CoverArtPath string
}
func (q *Queries) GetAllAlbumsWithDetailsByLibrary(ctx context.Context, libraryID int64) ([]GetAllAlbumsWithDetailsByLibraryRow, error) {
rows, err := q.db.QueryContext(ctx, getAllAlbumsWithDetailsByLibrary, libraryID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetAllAlbumsWithDetailsByLibraryRow
for rows.Next() {
var i GetAllAlbumsWithDetailsByLibraryRow
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Year,
&i.ArtistName,
&i.CoverArtPath,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getAllReleaseGroups = `-- name: GetAllReleaseGroups :many const getAllReleaseGroups = `-- name: GetAllReleaseGroups :many
SELECT id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs FROM release_groups SELECT id, name, cover_art_id, album_artist_credit_id, year, total_tracks, total_discs FROM release_groups
ORDER BY name ORDER BY name