Files
MusicServer/internal/db/queries/statistics.sql
T
SansanandClaude Opus 5.5 f79f51ea4c
CI / integration (push) Failing after 14s
CI / docker (push) Failing after 20s
CI / test (push) Successful in 1m10s
CI / publish (push) Skipped
Expose Prometheus metrics on a separate port
Metrics are served on METRICS_PORT (default 2112, "off" to disable), never on
the public port. Besides the Go runtime and process metrics this adds:

- http_requests_total and http_request_duration_seconds per route pattern,
  from an Echo middleware.
- musicserver_songs_requested_total and musicserver_songs_played_total by
  pick mode (random, low, classic). The mode is now stored with each queued
  song (migration 000006, not released yet).
- Library size, sync duration, last successful sync, broken songs from the
  last full sync, and the database connection pool.

Refs #35, #36, #37

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:57:58 +02:00

216 lines
6.7 KiB
SQL

-- Most played soundtracks with their songs
-- name: GetMostPlayedSoundtracksWithSongs :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played,
'file_name', s.file_name
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played DESC, g.soundtrack_name
LIMIT $1;
-- Least played soundtracks with their songs
-- name: GetLeastPlayedSoundtracksWithSongs :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played,
'file_name', s.file_name
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.times_played ASC, g.soundtrack_name
LIMIT $1;
-- Most played songs with their soundtrack info
-- name: GetMostPlayedSongsWithSoundtrack :many
SELECT
s.soundtrack_id as soundtrack_id,
g.uuid as soundtrack_uuid,
s.uuid as song_uuid,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played DESC, s.song_name
LIMIT $1;
-- Least played songs with their soundtrack info
-- name: GetLeastPlayedSongsWithSoundtrack :many
SELECT
s.soundtrack_id as soundtrack_id,
g.uuid as soundtrack_uuid,
s.uuid as song_uuid,
g.soundtrack_name,
s.song_name,
s.path,
s.times_played,
s.file_name
FROM song s
JOIN soundtrack g ON s.soundtrack_id = g.id
WHERE g.deleted IS NULL
ORDER BY s.times_played ASC, s.song_name
LIMIT $1;
-- Soundtracks that have never been played (times_played = 0)
-- name: GetNeverPlayedSoundtracks :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.added,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.times_played = 0
GROUP BY g.id, g.soundtrack_name, g.times_played, g.added
ORDER BY g.soundtrack_name;
-- Last played soundtracks (most recently played)
-- name: GetLastPlayedSoundtracks :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played DESC
LIMIT $1;
-- Oldest played soundtracks (least recently played, but has been played at least once)
-- name: GetOldestPlayedSoundtracks :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL AND g.last_played IS NOT NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.last_played ASC
LIMIT $1;
-- Get statistics summary
-- name: GetStatisticsSummary :one
SELECT
COUNT(*) as total_soundtracks,
COALESCE(SUM(CASE WHEN times_played > 0 THEN 1 ELSE 0 END), 0)::bigint as played_soundtracks,
COALESCE(SUM(CASE WHEN times_played = 0 THEN 1 ELSE 0 END), 0)::bigint as never_played_soundtracks,
COALESCE(SUM(times_played), 0)::bigint as total_soundtrack_plays,
COALESCE(AVG(times_played), 0)::float as avg_soundtrack_plays,
COALESCE(MAX(times_played), 0)::bigint as max_soundtrack_plays,
COALESCE(MIN(times_played), 0)::bigint as min_soundtrack_plays
FROM soundtrack
WHERE deleted IS NULL;
-- Every soundtrack with its songs, by name
-- name: GetAllSoundtracksWithSongs :many
SELECT
g.id as soundtrack_id,
g.uuid as soundtrack_uuid,
g.soundtrack_name,
g.times_played as soundtrack_played,
g.last_played as soundtrack_last_played,
COALESCE(
json_agg(
json_build_object(
'song_uuid', s.uuid,
'soundtrack_uuid', g.uuid,
'song_name', s.song_name,
'path', s.path,
'times_played', s.times_played,
'file_name', s.file_name
)
) FILTER (WHERE s.uuid IS NOT NULL),
'[]'
)::json as songs
FROM soundtrack g
LEFT JOIN song s ON g.id = s.soundtrack_id
WHERE g.deleted IS NULL
GROUP BY g.id, g.soundtrack_name, g.times_played, g.last_played
ORDER BY g.soundtrack_name;
-- name: CountLibrary :one
-- Soundtracks and songs in the library, without deleted soundtracks.
SELECT
(SELECT COUNT(*) FROM soundtrack WHERE deleted IS NULL) AS soundtracks,
(SELECT COUNT(*) FROM song s JOIN soundtrack st ON st.id = s.soundtrack_id WHERE st.deleted IS NULL) AS songs;