30b0edf97b
DeleteTrack returns album_id + artist_id so the calling service can chain the album-empty / artist-empty cascade. DeleteAlbumIfEmpty and DeleteArtistIfEmpty are no-ops when other rows still reference the parent — the service treats pgx.ErrNoRows as "not orphaned, skip".
99 lines
3.5 KiB
SQL
99 lines
3.5 KiB
SQL
-- name: UpsertAlbum :one
|
|
INSERT INTO albums (title, sort_title, artist_id, release_date, mbid, cover_art_path)
|
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
ON CONFLICT (mbid) WHERE mbid IS NOT NULL
|
|
DO UPDATE SET
|
|
title = EXCLUDED.title,
|
|
sort_title = EXCLUDED.sort_title,
|
|
artist_id = EXCLUDED.artist_id,
|
|
release_date = EXCLUDED.release_date,
|
|
cover_art_path = EXCLUDED.cover_art_path,
|
|
updated_at = now()
|
|
RETURNING *;
|
|
|
|
-- name: GetAlbumByID :one
|
|
SELECT * FROM albums WHERE id = $1;
|
|
|
|
-- name: GetAlbumByArtistAndTitle :one
|
|
-- Scanner uses this for the no-mbid dedupe path: resolve-or-create.
|
|
SELECT * FROM albums WHERE artist_id = $1 AND title = $2 LIMIT 1;
|
|
|
|
-- name: ListAlbumsByArtist :many
|
|
SELECT * FROM albums WHERE artist_id = $1 ORDER BY release_date NULLS LAST, sort_title;
|
|
|
|
-- name: ListAlbumsAlphaByName :many
|
|
SELECT * FROM albums ORDER BY sort_title LIMIT $1 OFFSET $2;
|
|
|
|
-- name: ListAlbumsAlphaByArtist :many
|
|
-- Sorted by the owning artist's sort_name. Needed by Subsonic's
|
|
-- alphabeticalByArtist album list type.
|
|
SELECT sqlc.embed(albums), artists.sort_name AS artist_sort_name
|
|
FROM albums
|
|
JOIN artists ON artists.id = albums.artist_id
|
|
ORDER BY artists.sort_name, albums.sort_title
|
|
LIMIT $1 OFFSET $2;
|
|
|
|
-- name: ListAlbumsNewest :many
|
|
SELECT * FROM albums ORDER BY created_at DESC LIMIT $1 OFFSET $2;
|
|
|
|
-- name: ListAlbumsRandom :many
|
|
SELECT * FROM albums ORDER BY random() LIMIT $1;
|
|
|
|
-- name: ListAlbumsByGenre :many
|
|
-- Album "belongs to" a genre if any of its tracks carry that genre.
|
|
SELECT DISTINCT ON (albums.id) albums.*
|
|
FROM albums
|
|
JOIN tracks ON tracks.album_id = albums.id
|
|
WHERE tracks.genre = $1
|
|
ORDER BY albums.id, albums.sort_title
|
|
LIMIT $2 OFFSET $3;
|
|
|
|
-- name: SearchAlbums :many
|
|
SELECT * FROM albums
|
|
WHERE title ILIKE '%' || $1 || '%'
|
|
ORDER BY sort_title
|
|
LIMIT $2 OFFSET $3;
|
|
|
|
-- name: CountAlbumsMatching :one
|
|
SELECT COUNT(*) FROM albums WHERE title ILIKE '%' || $1::text || '%';
|
|
|
|
-- name: ListRecentlyAddedAlbumsWithArtist :many
|
|
-- M6a: recently-added albums joined with artist_name + artist_id for the
|
|
-- home-page section. created_at is the row-insert timestamp from the
|
|
-- scanner — the closest proxy to "added to library". Stable secondary
|
|
-- ordering by id keeps pagination tie-break deterministic.
|
|
SELECT sqlc.embed(albums), artists.name AS artist_name
|
|
FROM albums
|
|
JOIN artists ON artists.id = albums.artist_id
|
|
ORDER BY albums.created_at DESC, albums.id
|
|
LIMIT $1;
|
|
|
|
-- name: ListAlbumsAlphaWithArtist :many
|
|
-- M6a: alpha-sorted album list joined with artist_name. Used by
|
|
-- /api/library/albums for the wrapping-grid page. Stable id-tiebreak.
|
|
SELECT sqlc.embed(albums), artists.name AS artist_name
|
|
FROM albums
|
|
JOIN artists ON artists.id = albums.artist_id
|
|
ORDER BY albums.sort_title, albums.id
|
|
LIMIT $1 OFFSET $2;
|
|
|
|
-- name: CountAlbums :one
|
|
-- M6a: total album count for the /api/library/albums envelope.
|
|
SELECT COUNT(*) FROM albums;
|
|
|
|
-- name: CountAlbumsByArtist :one
|
|
-- Used by request-progress reporting to count how many albums have been
|
|
-- ingested for a matched artist while a request is still in flight.
|
|
SELECT COUNT(*) FROM albums WHERE artist_id = $1;
|
|
|
|
-- name: DeleteAlbumIfEmpty :one
|
|
-- M7 #372: deletes the album row only when it has no remaining tracks.
|
|
-- Used after a track delete to tidy up orphaned albums. RETURNING gives
|
|
-- us the artist_id so the service can chain into the artist-empty check.
|
|
-- Returns no rows when the album still has tracks; the service treats
|
|
-- pgx.ErrNoRows as "album not orphaned, skip cascade".
|
|
DELETE FROM albums a
|
|
WHERE a.id = $1
|
|
AND NOT EXISTS (SELECT 1 FROM tracks t WHERE t.album_id = a.id)
|
|
RETURNING a.id, a.artist_id;
|