The other soundtrack statistics are capped at 100, so a client that shows every soundtrack (the MusicPlayer statistics tab) had no way to get them all. This one has no limit and is sorted by name.
554 lines
16 KiB
Go
554 lines
16 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: statistics.sql
|
|
|
|
package repository
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
const getAllSoundtracksWithSongs = `-- 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
|
|
`
|
|
|
|
type GetAllSoundtracksWithSongsRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SoundtrackPlayed int32 `json:"soundtrack_played"`
|
|
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
|
|
Songs []byte `json:"songs"`
|
|
}
|
|
|
|
// Every soundtrack with its songs, by name
|
|
func (q *Queries) GetAllSoundtracksWithSongs(ctx context.Context) ([]GetAllSoundtracksWithSongsRow, error) {
|
|
rows, err := q.db.Query(ctx, getAllSoundtracksWithSongs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetAllSoundtracksWithSongsRow
|
|
for rows.Next() {
|
|
var i GetAllSoundtracksWithSongsRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SoundtrackName,
|
|
&i.SoundtrackPlayed,
|
|
&i.SoundtrackLastPlayed,
|
|
&i.Songs,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getLastPlayedSoundtracks = `-- 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
|
|
`
|
|
|
|
type GetLastPlayedSoundtracksRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SoundtrackPlayed int32 `json:"soundtrack_played"`
|
|
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
|
|
Songs []byte `json:"songs"`
|
|
}
|
|
|
|
// Last played soundtracks (most recently played)
|
|
func (q *Queries) GetLastPlayedSoundtracks(ctx context.Context, limit int32) ([]GetLastPlayedSoundtracksRow, error) {
|
|
rows, err := q.db.Query(ctx, getLastPlayedSoundtracks, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetLastPlayedSoundtracksRow
|
|
for rows.Next() {
|
|
var i GetLastPlayedSoundtracksRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SoundtrackName,
|
|
&i.SoundtrackPlayed,
|
|
&i.SoundtrackLastPlayed,
|
|
&i.Songs,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getLeastPlayedSongsWithSoundtrack = `-- 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
|
|
`
|
|
|
|
type GetLeastPlayedSongsWithSoundtrackRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SongUuid uuid.UUID `json:"song_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SongName string `json:"song_name"`
|
|
Path string `json:"path"`
|
|
TimesPlayed int32 `json:"times_played"`
|
|
FileName *string `json:"file_name"`
|
|
}
|
|
|
|
// Least played songs with their soundtrack info
|
|
func (q *Queries) GetLeastPlayedSongsWithSoundtrack(ctx context.Context, limit int32) ([]GetLeastPlayedSongsWithSoundtrackRow, error) {
|
|
rows, err := q.db.Query(ctx, getLeastPlayedSongsWithSoundtrack, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetLeastPlayedSongsWithSoundtrackRow
|
|
for rows.Next() {
|
|
var i GetLeastPlayedSongsWithSoundtrackRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SongUuid,
|
|
&i.SoundtrackName,
|
|
&i.SongName,
|
|
&i.Path,
|
|
&i.TimesPlayed,
|
|
&i.FileName,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getLeastPlayedSoundtracksWithSongs = `-- 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
|
|
`
|
|
|
|
type GetLeastPlayedSoundtracksWithSongsRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SoundtrackPlayed int32 `json:"soundtrack_played"`
|
|
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
|
|
Songs []byte `json:"songs"`
|
|
}
|
|
|
|
// Least played soundtracks with their songs
|
|
func (q *Queries) GetLeastPlayedSoundtracksWithSongs(ctx context.Context, limit int32) ([]GetLeastPlayedSoundtracksWithSongsRow, error) {
|
|
rows, err := q.db.Query(ctx, getLeastPlayedSoundtracksWithSongs, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetLeastPlayedSoundtracksWithSongsRow
|
|
for rows.Next() {
|
|
var i GetLeastPlayedSoundtracksWithSongsRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SoundtrackName,
|
|
&i.SoundtrackPlayed,
|
|
&i.SoundtrackLastPlayed,
|
|
&i.Songs,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getMostPlayedSongsWithSoundtrack = `-- 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
|
|
`
|
|
|
|
type GetMostPlayedSongsWithSoundtrackRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SongUuid uuid.UUID `json:"song_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SongName string `json:"song_name"`
|
|
Path string `json:"path"`
|
|
TimesPlayed int32 `json:"times_played"`
|
|
FileName *string `json:"file_name"`
|
|
}
|
|
|
|
// Most played songs with their soundtrack info
|
|
func (q *Queries) GetMostPlayedSongsWithSoundtrack(ctx context.Context, limit int32) ([]GetMostPlayedSongsWithSoundtrackRow, error) {
|
|
rows, err := q.db.Query(ctx, getMostPlayedSongsWithSoundtrack, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetMostPlayedSongsWithSoundtrackRow
|
|
for rows.Next() {
|
|
var i GetMostPlayedSongsWithSoundtrackRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SongUuid,
|
|
&i.SoundtrackName,
|
|
&i.SongName,
|
|
&i.Path,
|
|
&i.TimesPlayed,
|
|
&i.FileName,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getMostPlayedSoundtracksWithSongs = `-- 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
|
|
`
|
|
|
|
type GetMostPlayedSoundtracksWithSongsRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SoundtrackPlayed int32 `json:"soundtrack_played"`
|
|
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
|
|
Songs []byte `json:"songs"`
|
|
}
|
|
|
|
// Most played soundtracks with their songs
|
|
func (q *Queries) GetMostPlayedSoundtracksWithSongs(ctx context.Context, limit int32) ([]GetMostPlayedSoundtracksWithSongsRow, error) {
|
|
rows, err := q.db.Query(ctx, getMostPlayedSoundtracksWithSongs, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetMostPlayedSoundtracksWithSongsRow
|
|
for rows.Next() {
|
|
var i GetMostPlayedSoundtracksWithSongsRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SoundtrackName,
|
|
&i.SoundtrackPlayed,
|
|
&i.SoundtrackLastPlayed,
|
|
&i.Songs,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getNeverPlayedSoundtracks = `-- 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
|
|
`
|
|
|
|
type GetNeverPlayedSoundtracksRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SoundtrackPlayed int32 `json:"soundtrack_played"`
|
|
Added time.Time `json:"added"`
|
|
Songs []byte `json:"songs"`
|
|
}
|
|
|
|
// Soundtracks that have never been played (times_played = 0)
|
|
func (q *Queries) GetNeverPlayedSoundtracks(ctx context.Context) ([]GetNeverPlayedSoundtracksRow, error) {
|
|
rows, err := q.db.Query(ctx, getNeverPlayedSoundtracks)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetNeverPlayedSoundtracksRow
|
|
for rows.Next() {
|
|
var i GetNeverPlayedSoundtracksRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SoundtrackName,
|
|
&i.SoundtrackPlayed,
|
|
&i.Added,
|
|
&i.Songs,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getOldestPlayedSoundtracks = `-- 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
|
|
`
|
|
|
|
type GetOldestPlayedSoundtracksRow struct {
|
|
SoundtrackID int32 `json:"soundtrack_id"`
|
|
SoundtrackUuid uuid.UUID `json:"soundtrack_uuid"`
|
|
SoundtrackName string `json:"soundtrack_name"`
|
|
SoundtrackPlayed int32 `json:"soundtrack_played"`
|
|
SoundtrackLastPlayed *time.Time `json:"soundtrack_last_played"`
|
|
Songs []byte `json:"songs"`
|
|
}
|
|
|
|
// Oldest played soundtracks (least recently played, but has been played at least once)
|
|
func (q *Queries) GetOldestPlayedSoundtracks(ctx context.Context, limit int32) ([]GetOldestPlayedSoundtracksRow, error) {
|
|
rows, err := q.db.Query(ctx, getOldestPlayedSoundtracks, limit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetOldestPlayedSoundtracksRow
|
|
for rows.Next() {
|
|
var i GetOldestPlayedSoundtracksRow
|
|
if err := rows.Scan(
|
|
&i.SoundtrackID,
|
|
&i.SoundtrackUuid,
|
|
&i.SoundtrackName,
|
|
&i.SoundtrackPlayed,
|
|
&i.SoundtrackLastPlayed,
|
|
&i.Songs,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getStatisticsSummary = `-- 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
|
|
`
|
|
|
|
type GetStatisticsSummaryRow struct {
|
|
TotalSoundtracks int64 `json:"total_soundtracks"`
|
|
PlayedSoundtracks int64 `json:"played_soundtracks"`
|
|
NeverPlayedSoundtracks int64 `json:"never_played_soundtracks"`
|
|
TotalSoundtrackPlays int64 `json:"total_soundtrack_plays"`
|
|
AvgSoundtrackPlays float64 `json:"avg_soundtrack_plays"`
|
|
MaxSoundtrackPlays int64 `json:"max_soundtrack_plays"`
|
|
MinSoundtrackPlays int64 `json:"min_soundtrack_plays"`
|
|
}
|
|
|
|
// Get statistics summary
|
|
func (q *Queries) GetStatisticsSummary(ctx context.Context) (GetStatisticsSummaryRow, error) {
|
|
row := q.db.QueryRow(ctx, getStatisticsSummary)
|
|
var i GetStatisticsSummaryRow
|
|
err := row.Scan(
|
|
&i.TotalSoundtracks,
|
|
&i.PlayedSoundtracks,
|
|
&i.NeverPlayedSoundtracks,
|
|
&i.TotalSoundtrackPlays,
|
|
&i.AvgSoundtrackPlays,
|
|
&i.MaxSoundtrackPlays,
|
|
&i.MinSoundtrackPlays,
|
|
)
|
|
return i, err
|
|
}
|