Skip to content

Commit 6981405

Browse files
committed
chore(song): readd to the tui
1 parent 8b72bd7 commit 6981405

10 files changed

Lines changed: 1250 additions & 48 deletions

File tree

db/queries/song.sql

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,86 @@
1+
-- name: SongGetLastPopulated :many
2+
SELECT sqlc.embed(h), sqlc.embed(s), sqlc.embed(a)
3+
FROM song_history h
4+
JOIN song s ON s.id = h.song_id
5+
LEFT JOIN song_artist_song sa ON sa.song_id = s.id
6+
LEFT JOIN song_artist a ON a.id = sa.artist_id
7+
WHERE h.created_at = (SELECT MAX(created_at) FROM song_history)
8+
ORDER BY a.name;
9+
10+
-- name: SongGetLast50 :many
11+
SELECT sqlc.embed(s), play_count
12+
FROM (
13+
SELECT sh.song_id, MAX(sh.created_at) AS created_at, COUNT(sh.song_id) AS play_count
14+
FROM song_history sh
15+
GROUP BY sh.song_id
16+
) aggregated
17+
JOIN song s ON s.id = aggregated.song_id
18+
ORDER BY aggregated.created_at DESC
19+
LIMIT 50;
20+
21+
-- name: SongGetTop50 :many
22+
SELECT sqlc.embed(s), COUNT(sh.id) AS play_count
23+
FROM song_history sh
24+
JOIN song s ON sh.song_id = s.id
25+
GROUP BY s.id, s.title
26+
ORDER BY play_count DESC
27+
LIMIT 50;
28+
29+
-- name: SongGetTop50Monthly :many
30+
SELECT sqlc.embed(s), COUNT(sh.id) AS play_count
31+
FROM song_history sh
32+
JOIN song s ON sh.song_id = s.id
33+
WHERE sh.created_at > CURRENT_TIMESTAMP - INTERVAL '1 month'
34+
GROUP BY s.id, s.title
35+
ORDER BY play_count DESC
36+
LIMIT 50;
37+
38+
-- name: SongArtistGetTop50 :many
39+
SELECT sqlc.embed(a), COUNT(sh.id) AS play_count
40+
FROM song_history sh
41+
JOIN song s ON sh.song_id = s.id
42+
JOIN song_artist_song sas ON s.id = sas.song_id
43+
JOIN song_artist a ON sas.artist_id = a.id
44+
GROUP BY a.id, a.name
45+
ORDER BY play_count DESC
46+
LIMIT 50;
47+
48+
-- name: SongArtistGetTop50Monthly :many
49+
SELECT sqlc.embed(a), COUNT(sh.id) AS play_count
50+
FROM song_history sh
51+
JOIN song s ON sh.song_id = s.id
52+
JOIN song_artist_song sas ON s.id = sas.song_id
53+
JOIN song_artist a ON sas.artist_id = a.id
54+
WHERE sh.created_at > CURRENT_TIMESTAMP - INTERVAL '1 month'
55+
GROUP BY a.id, a.name
56+
ORDER BY play_count DESC
57+
LIMIT 50;
58+
59+
-- name: SongGenreGetTop50 :many
60+
SELECT sqlc.embed(g), COUNT(sh.id) AS play_count
61+
FROM song_history sh
62+
JOIN song s ON sh.song_id = s.id
63+
JOIN song_artist_song sas ON s.id = sas.song_id
64+
JOIN song_artist sa ON sas.artist_id = sa.id
65+
JOIN song_artist_genre sag ON sa.id = sag.artist_id
66+
JOIN song_genre g ON sag.genre_id = g.id
67+
GROUP BY g.genre, g.id
68+
ORDER BY play_count DESC
69+
LIMIT 50;
70+
71+
-- name: SongGenreGetTop50Monthly :many
72+
SELECT sqlc.embed(g), COUNT(sh.id) AS play_count
73+
FROM song_history sh
74+
JOIN song s ON sh.song_id = s.id
75+
JOIN song_artist_song sas ON s.id = sas.song_id
76+
JOIN song_artist sa ON sas.artist_id = sa.id
77+
JOIN song_artist_genre sag ON sa.id = sag.artist_id
78+
JOIN song_genre g ON sag.genre_id = g.id
79+
WHERE sh.created_at > CURRENT_TIMESTAMP - INTERVAL '1 month'
80+
GROUP BY g.genre, g.id
81+
ORDER BY play_count DESC
82+
LIMIT 50;
83+
184
-- name: SongGetBySpotify :one
285
SELECT *
386
FROM song

internal/database/model/song.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,29 @@ type Song struct {
2323
DurationMS int
2424
LyricsType LyricsType
2525
Lyrics string
26-
PlayedAt time.Time
2726
Artists []Artist
27+
28+
// History fields
29+
PlayedAt time.Time
30+
PlayCount int
2831
}
2932

3033
type Artist struct {
3134
ID int
3235
Name string
3336
SpotifyID string
3437
Genres []Genre
38+
39+
// History fields
40+
PlayCount int
3541
}
3642

3743
type Genre struct {
3844
ID int
3945
Genre string
46+
47+
// History fields
48+
PlayCount int
4049
}
4150

4251
func SongModel(s sqlc.Song) *Song {

internal/database/repository/song.go

Lines changed: 159 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/jackc/pgx/v5/pgtype"
1010
"github.com/zeusWPI/scc/internal/database/model"
1111
"github.com/zeusWPI/scc/internal/database/sqlc"
12-
"github.com/zeusWPI/scc/pkg/utils"
1312
)
1413

1514
type Song struct {
@@ -22,63 +21,199 @@ func (r *Repository) NewSong() *Song {
2221
}
2322
}
2423

25-
func (s *Song) GetBySpotify(ctx context.Context, spotifyID string) (*model.Song, error) {
26-
song, err := s.repo.queries(ctx).SongGetBySpotify(ctx, spotifyID)
24+
func (s *Song) GetLastPopulated(ctx context.Context) (*model.Song, error) {
25+
last, err := s.repo.queries(ctx).SongGetLastPopulated(ctx)
2726
if err != nil {
2827
if errors.Is(err, sql.ErrNoRows) {
2928
return nil, nil
3029
}
31-
return nil, fmt.Errorf("get song by spotify id %s | %w", spotifyID, err)
30+
return nil, fmt.Errorf("get last song populated %w", err)
3231
}
3332

34-
return model.SongModel(song), nil
33+
song := model.SongModel(last[0].Song)
34+
song.PlayedAt = last[0].SongHistory.CreatedAt.Time
35+
36+
for _, s := range last {
37+
song.Artists = append(song.Artists, *model.ArtistModel(s.SongArtist))
38+
}
39+
40+
return song, nil
3541
}
3642

37-
func (s *Song) GetArtistBySpotify(ctx context.Context, spotifyID string) (*model.Artist, error) {
38-
artist, err := s.repo.queries(ctx).SongArtistGetBySpotify(ctx, spotifyID)
43+
func (s *Song) GetLast50(ctx context.Context) ([]*model.Song, error) {
44+
lasts, err := s.repo.queries(ctx).SongGetLast50(ctx)
3945
if err != nil {
4046
if errors.Is(err, sql.ErrNoRows) {
4147
return nil, nil
4248
}
43-
return nil, fmt.Errorf("get song artist by spotify id %s | %w", spotifyID, err)
49+
return nil, fmt.Errorf("get last 50 songs %w", err)
4450
}
4551

46-
return model.ArtistModel(artist), nil
52+
songs := make([]*model.Song, 0, len(lasts))
53+
for _, last := range lasts {
54+
song := model.SongModel(last.Song)
55+
song.PlayCount = int(last.PlayCount)
56+
57+
songs = append(songs, song)
58+
}
59+
60+
return songs, nil
4761
}
4862

49-
func (s *Song) GetGenreByGenre(ctx context.Context, genre string) (*model.Genre, error) {
50-
genreDB, err := s.repo.queries(ctx).SongGenreGetByGenre(ctx, genre)
63+
func (s *Song) GetTopSongs(ctx context.Context) ([]*model.Song, error) {
64+
tops, err := s.repo.queries(ctx).SongGetTop50(ctx)
5165
if err != nil {
5266
if errors.Is(err, sql.ErrNoRows) {
5367
return nil, nil
5468
}
55-
return nil, fmt.Errorf("get song genre by genre %s | %w", genre, err)
69+
return nil, fmt.Errorf("get top songs %w", err)
5670
}
5771

58-
return model.GenreModel(genreDB), nil
72+
songs := make([]*model.Song, 0, len(tops))
73+
for _, top := range tops {
74+
song := model.SongModel(top.Song)
75+
song.PlayCount = int(top.PlayCount)
76+
77+
songs = append(songs, song)
78+
}
79+
80+
return songs, nil
81+
}
82+
83+
func (s *Song) GetTopArtists(ctx context.Context) ([]*model.Artist, error) {
84+
tops, err := s.repo.queries(ctx).SongArtistGetTop50(ctx)
85+
if err != nil {
86+
if errors.Is(err, sql.ErrNoRows) {
87+
return nil, nil
88+
}
89+
return nil, fmt.Errorf("get top artists %w", err)
90+
}
91+
92+
artists := make([]*model.Artist, 0, len(tops))
93+
for _, top := range tops {
94+
artist := model.ArtistModel(top.SongArtist)
95+
artist.PlayCount = int(top.PlayCount)
96+
97+
artists = append(artists, artist)
98+
}
99+
100+
return artists, nil
101+
}
102+
103+
func (s *Song) GetTopGenres(ctx context.Context) ([]*model.Genre, error) {
104+
tops, err := s.repo.queries(ctx).SongGenreGetTop50(ctx)
105+
if err != nil {
106+
if errors.Is(err, sql.ErrNoRows) {
107+
return nil, nil
108+
}
109+
return nil, fmt.Errorf("get top genres %w", err)
110+
}
111+
112+
genres := make([]*model.Genre, 0, len(tops))
113+
for _, top := range tops {
114+
genre := model.GenreModel(top.SongGenre)
115+
genre.PlayCount = int(top.PlayCount)
116+
117+
genres = append(genres, genre)
118+
}
119+
120+
return genres, nil
121+
}
122+
123+
func (s *Song) GetTopSongsMonthly(ctx context.Context) ([]*model.Song, error) {
124+
tops, err := s.repo.queries(ctx).SongGetTop50Monthly(ctx)
125+
if err != nil {
126+
if errors.Is(err, sql.ErrNoRows) {
127+
return nil, nil
128+
}
129+
return nil, fmt.Errorf("get top songs monthly %w", err)
130+
}
131+
132+
songs := make([]*model.Song, 0, len(tops))
133+
for _, top := range tops {
134+
song := model.SongModel(top.Song)
135+
song.PlayCount = int(top.PlayCount)
136+
137+
songs = append(songs, song)
138+
}
139+
140+
return songs, nil
141+
}
142+
143+
func (s *Song) GetTopArtistsMonthly(ctx context.Context) ([]*model.Artist, error) {
144+
tops, err := s.repo.queries(ctx).SongArtistGetTop50Monthly(ctx)
145+
if err != nil {
146+
if errors.Is(err, sql.ErrNoRows) {
147+
return nil, nil
148+
}
149+
return nil, fmt.Errorf("get top artists montlhy %w", err)
150+
}
151+
152+
artists := make([]*model.Artist, 0, len(tops))
153+
for _, top := range tops {
154+
artist := model.ArtistModel(top.SongArtist)
155+
artist.PlayCount = int(top.PlayCount)
156+
157+
artists = append(artists, artist)
158+
}
159+
160+
return artists, nil
161+
}
162+
163+
func (s *Song) GetTopGenresMonthly(ctx context.Context) ([]*model.Genre, error) {
164+
tops, err := s.repo.queries(ctx).SongGenreGetTop50Monthly(ctx)
165+
if err != nil {
166+
if errors.Is(err, sql.ErrNoRows) {
167+
return nil, nil
168+
}
169+
return nil, fmt.Errorf("get top genres monthly %w", err)
170+
}
171+
172+
genres := make([]*model.Genre, 0, len(tops))
173+
for _, top := range tops {
174+
genre := model.GenreModel(top.SongGenre)
175+
genre.PlayCount = int(top.PlayCount)
176+
177+
genres = append(genres, genre)
178+
}
179+
180+
return genres, nil
59181
}
60182

61-
func (s *Song) GetArtistsBySpotify(ctx context.Context, artists []model.Artist) ([]*model.Artist, error) {
62-
artistsDB, err := s.repo.queries(ctx).SongArtistGetBySpotifyIds(ctx, utils.SliceMap(artists, func(a model.Artist) string { return a.SpotifyID }))
183+
func (s *Song) GetBySpotify(ctx context.Context, spotifyID string) (*model.Song, error) {
184+
song, err := s.repo.queries(ctx).SongGetBySpotify(ctx, spotifyID)
63185
if err != nil {
64186
if errors.Is(err, sql.ErrNoRows) {
65187
return nil, nil
66188
}
67-
return nil, fmt.Errorf("get artists by ids %+v | %w", artists, err)
189+
return nil, fmt.Errorf("get song by spotify id %s | %w", spotifyID, err)
68190
}
69191

70-
artistMap := make(map[int]*model.Artist)
71-
for _, artist := range artistsDB {
72-
a, ok := artistMap[int(artist.SongArtist.ID)]
73-
if !ok {
74-
a = model.ArtistModel(artist.SongArtist)
75-
artistMap[a.ID] = a
192+
return model.SongModel(song), nil
193+
}
194+
195+
func (s *Song) GetArtistBySpotify(ctx context.Context, spotifyID string) (*model.Artist, error) {
196+
artist, err := s.repo.queries(ctx).SongArtistGetBySpotify(ctx, spotifyID)
197+
if err != nil {
198+
if errors.Is(err, sql.ErrNoRows) {
199+
return nil, nil
76200
}
201+
return nil, fmt.Errorf("get song artist by spotify id %s | %w", spotifyID, err)
202+
}
203+
204+
return model.ArtistModel(artist), nil
205+
}
77206

78-
a.Genres = append(a.Genres, *model.GenreModel(artist.SongGenre))
207+
func (s *Song) GetGenreByGenre(ctx context.Context, genre string) (*model.Genre, error) {
208+
genreDB, err := s.repo.queries(ctx).SongGenreGetByGenre(ctx, genre)
209+
if err != nil {
210+
if errors.Is(err, sql.ErrNoRows) {
211+
return nil, nil
212+
}
213+
return nil, fmt.Errorf("get song genre by genre %s | %w", genre, err)
79214
}
80215

81-
return utils.MapValues(artistMap), nil
216+
return model.GenreModel(genreDB), nil
82217
}
83218

84219
func (s *Song) Create(ctx context.Context, song *model.Song) error {

0 commit comments

Comments
 (0)