The sidebar had a Home item that fell through to "Coming soon". What was missing was not another view of the library — four of those exist, sorted and complete — but the opposite: a complete, sorted library is exactly what gives you nothing to play, because every entry point into it is alphabetical and identical every time you open the app. So a shelf is a *reason*, not a filter. Each one answers a different question you might be asking when you do not know what you want (what was I listening to, what is new, what do I keep coming back to, what have I forgotten, what fits, what would I never pick myself) and each says which question it answered — a row of covers with no explanation is just another grid. Two consequences run through it. Shelves are built from what the user actually did — play counts, last played, import order — with random sampling only where there is no signal to use, so randomness is the fallback rather than the design. And a shelf with nothing behind it is omitted instead of rendered empty: a fresh library legitimately gets three, and an empty row labelled "on repeat" would be a lie. The queries return album ids and nothing else, joined back to GetAllAlbumsWithDetails in Go, so the album projection keeps having one definition rather than one per shelf.
120 lines
4.0 KiB
SQL
120 lines
4.0 KiB
SQL
-- Queries behind the home page's "start listening" shelves.
|
|
--
|
|
-- Every one of these returns album ids and nothing else. The display
|
|
-- columns (cover art, artist credit, year) already have exactly one
|
|
-- correct expression of them, in GetAllAlbumsWithDetails, and a second
|
|
-- copy per shelf would be six more places for that to drift. The home
|
|
-- service joins the ids back to that one album list in Go.
|
|
|
|
-- name: HomeRecentlyPlayedAlbums :many
|
|
-- Albums with the most recent play, newest first.
|
|
SELECT rg.id AS album_id
|
|
FROM release_groups rg
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN audio_files af ON af.recording_id = rgr.recording_id
|
|
WHERE af.last_played IS NOT NULL
|
|
GROUP BY rg.id
|
|
ORDER BY MAX(af.last_played) DESC
|
|
LIMIT ?;
|
|
|
|
-- name: HomeRecentlyAddedAlbums :many
|
|
-- Newest albums. audio_files has no import timestamp, so the row id
|
|
-- stands in for one: it is monotonic and assigned at import, which is
|
|
-- the same ordering an added_at column would give.
|
|
SELECT rg.id AS album_id
|
|
FROM release_groups rg
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN audio_files af ON af.recording_id = rgr.recording_id
|
|
GROUP BY rg.id
|
|
ORDER BY MAX(af.id) DESC
|
|
LIMIT ?;
|
|
|
|
-- name: HomeMostPlayedAlbums :many
|
|
-- Albums by total plays across their tracks.
|
|
SELECT rg.id AS album_id
|
|
FROM release_groups rg
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN audio_files af ON af.recording_id = rgr.recording_id
|
|
GROUP BY rg.id
|
|
HAVING SUM(af.play_count) > 0
|
|
ORDER BY SUM(af.play_count) DESC
|
|
LIMIT ?;
|
|
|
|
-- name: HomeUnplayedAlbums :many
|
|
-- Albums nothing on has ever been played, sampled at random so the
|
|
-- shelf is a different suggestion each time rather than the same
|
|
-- alphabetical head of the list forever.
|
|
SELECT rg.id AS album_id
|
|
FROM release_groups rg
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN audio_files af ON af.recording_id = rgr.recording_id
|
|
GROUP BY rg.id
|
|
HAVING SUM(af.play_count) = 0
|
|
ORDER BY RANDOM()
|
|
LIMIT ?;
|
|
|
|
-- name: HomeStaleAlbums :many
|
|
-- Played before, but not for a long while.
|
|
SELECT rg.id AS album_id
|
|
FROM release_groups rg
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN audio_files af ON af.recording_id = rgr.recording_id
|
|
WHERE af.last_played IS NOT NULL
|
|
GROUP BY rg.id
|
|
HAVING MAX(af.last_played) < datetime('now', ?)
|
|
ORDER BY MAX(af.last_played) ASC
|
|
LIMIT ?;
|
|
|
|
-- name: HomeRandomAlbums :many
|
|
SELECT rg.id AS album_id
|
|
FROM release_groups rg
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN audio_files af ON af.recording_id = rgr.recording_id
|
|
GROUP BY rg.id
|
|
ORDER BY RANDOM()
|
|
LIMIT ?;
|
|
|
|
-- name: HomeAlbumsByGenre :many
|
|
-- A random sample of albums carrying a genre, so the same genre shelf
|
|
-- is not the same ten albums every time the page opens.
|
|
SELECT rg.id AS album_id
|
|
FROM release_groups rg
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN recording_genres rgen ON rgen.recording_id = rgr.recording_id
|
|
JOIN genres g ON g.id = rgen.genre_id
|
|
WHERE g.name = ?
|
|
GROUP BY rg.id
|
|
ORDER BY RANDOM()
|
|
LIMIT ?;
|
|
|
|
-- name: HomeTopGenres :many
|
|
-- Genres ranked by how much of the library carries them, restricted to
|
|
-- ones with at least a few albums: a shelf built from a genre one
|
|
-- album carries is a shelf about that one album.
|
|
SELECT
|
|
g.name AS genre,
|
|
COUNT(DISTINCT rgr.release_group_id) AS album_count
|
|
FROM genres g
|
|
JOIN recording_genres rgen ON rgen.genre_id = g.id
|
|
JOIN release_group_recordings rgr ON rgr.recording_id = rgen.recording_id
|
|
GROUP BY g.id
|
|
HAVING album_count >= 3
|
|
ORDER BY album_count DESC
|
|
LIMIT ?;
|
|
|
|
-- name: HomeTopArtists :many
|
|
-- Artists by total plays, as the album-artist credit text the album
|
|
-- list already displays.
|
|
SELECT
|
|
COALESCE(ac.text, '') AS artist_name,
|
|
SUM(af.play_count) AS plays
|
|
FROM release_groups rg
|
|
JOIN artist_credit ac ON ac.id = rg.album_artist_credit_id
|
|
JOIN release_group_recordings rgr ON rgr.release_group_id = rg.id
|
|
JOIN audio_files af ON af.recording_id = rgr.recording_id
|
|
WHERE ac.text <> ''
|
|
GROUP BY ac.text
|
|
HAVING plays > 0
|
|
ORDER BY plays DESC
|
|
LIMIT ?;
|