feat(api): add dbq→ref projection helpers
This commit is contained in:
@@ -2,6 +2,8 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
|
||||||
|
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||||
)
|
)
|
||||||
|
|
||||||
// uuidToString renders a pgtype.UUID as a canonical hyphenated string.
|
// uuidToString renders a pgtype.UUID as a canonical hyphenated string.
|
||||||
@@ -65,3 +67,51 @@ func coverURL(albumID pgtype.UUID) string {
|
|||||||
func streamURL(trackID pgtype.UUID) string {
|
func streamURL(trackID pgtype.UUID) string {
|
||||||
return "/api/tracks/" + uuidToString(trackID) + "/stream"
|
return "/api/tracks/" + uuidToString(trackID) + "/stream"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// artistRefFrom projects a dbq.Artist into an ArtistRef. albumCount must be
|
||||||
|
// pre-computed by the caller (one query per artist in lists).
|
||||||
|
func artistRefFrom(a dbq.Artist, albumCount int) ArtistRef {
|
||||||
|
return ArtistRef{
|
||||||
|
ID: uuidToString(a.ID),
|
||||||
|
Name: a.Name,
|
||||||
|
AlbumCount: albumCount,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// albumRefFrom projects a dbq.Album into an AlbumRef. artistName must be
|
||||||
|
// pre-resolved because Album only carries artist_id. trackCount and
|
||||||
|
// durationSec may be 0 when the caller does not compute them.
|
||||||
|
func albumRefFrom(a dbq.Album, artistName string, trackCount, durationSec int) AlbumRef {
|
||||||
|
return AlbumRef{
|
||||||
|
ID: uuidToString(a.ID),
|
||||||
|
Title: a.Title,
|
||||||
|
ArtistID: uuidToString(a.ArtistID),
|
||||||
|
ArtistName: artistName,
|
||||||
|
Year: yearFromDate(a.ReleaseDate),
|
||||||
|
TrackCount: trackCount,
|
||||||
|
DurationSec: durationSec,
|
||||||
|
CoverURL: coverURL(a.ID),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trackRefFrom projects a dbq.Track into a TrackRef. Parent names must be
|
||||||
|
// pre-resolved because Track only carries album_id and artist_id.
|
||||||
|
func trackRefFrom(t dbq.Track, albumTitle, artistName string) TrackRef {
|
||||||
|
ref := TrackRef{
|
||||||
|
ID: uuidToString(t.ID),
|
||||||
|
Title: t.Title,
|
||||||
|
AlbumID: uuidToString(t.AlbumID),
|
||||||
|
AlbumTitle: albumTitle,
|
||||||
|
ArtistID: uuidToString(t.ArtistID),
|
||||||
|
ArtistName: artistName,
|
||||||
|
DurationSec: durationMsToSec(t.DurationMs),
|
||||||
|
StreamURL: streamURL(t.ID),
|
||||||
|
}
|
||||||
|
if t.TrackNumber != nil {
|
||||||
|
ref.TrackNumber = int(*t.TrackNumber)
|
||||||
|
}
|
||||||
|
if t.DiscNumber != nil {
|
||||||
|
ref.DiscNumber = int(*t.DiscNumber)
|
||||||
|
}
|
||||||
|
return ref
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
|
||||||
|
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUUIDToString(t *testing.T) {
|
func TestUUIDToString(t *testing.T) {
|
||||||
@@ -73,3 +75,77 @@ func TestCoverURLAndStreamURL(t *testing.T) {
|
|||||||
t.Errorf("streamURL = %q", got)
|
t.Errorf("streamURL = %q", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArtistRefFrom(t *testing.T) {
|
||||||
|
var id pgtype.UUID
|
||||||
|
_ = id.Scan("00112233-4455-6677-8899-aabbccddeeff")
|
||||||
|
a := dbq.Artist{ID: id, Name: "Beatles", SortName: "Beatles"}
|
||||||
|
got := artistRefFrom(a, 7)
|
||||||
|
if got.ID != "00112233-4455-6677-8899-aabbccddeeff" {
|
||||||
|
t.Errorf("ID = %q", got.ID)
|
||||||
|
}
|
||||||
|
if got.Name != "Beatles" || got.AlbumCount != 7 {
|
||||||
|
t.Errorf("ref = %+v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAlbumRefFrom(t *testing.T) {
|
||||||
|
var aid, artID pgtype.UUID
|
||||||
|
_ = aid.Scan("00000000-0000-0000-0000-000000000001")
|
||||||
|
_ = artID.Scan("00000000-0000-0000-0000-000000000002")
|
||||||
|
var rel pgtype.Date
|
||||||
|
_ = rel.Scan("1969-09-26")
|
||||||
|
a := dbq.Album{ID: aid, Title: "Abbey Road", ArtistID: artID, ReleaseDate: rel}
|
||||||
|
got := albumRefFrom(a, "Beatles", 17, 2820)
|
||||||
|
if got.Title != "Abbey Road" || got.ArtistName != "Beatles" {
|
||||||
|
t.Errorf("ref = %+v", got)
|
||||||
|
}
|
||||||
|
if got.TrackCount != 17 || got.DurationSec != 2820 {
|
||||||
|
t.Errorf("counts = %+v", got)
|
||||||
|
}
|
||||||
|
if got.Year != 1969 {
|
||||||
|
t.Errorf("year = %d", got.Year)
|
||||||
|
}
|
||||||
|
if got.CoverURL != "/api/albums/00000000-0000-0000-0000-000000000001/cover" {
|
||||||
|
t.Errorf("cover_url = %q", got.CoverURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTrackRefFrom(t *testing.T) {
|
||||||
|
var tid, aid, artID pgtype.UUID
|
||||||
|
_ = tid.Scan("00000000-0000-0000-0000-000000000010")
|
||||||
|
_ = aid.Scan("00000000-0000-0000-0000-000000000001")
|
||||||
|
_ = artID.Scan("00000000-0000-0000-0000-000000000002")
|
||||||
|
trackNum := int32(3)
|
||||||
|
discNum := int32(1)
|
||||||
|
t2 := dbq.Track{
|
||||||
|
ID: tid, Title: "Something", AlbumID: aid, ArtistID: artID,
|
||||||
|
TrackNumber: &trackNum, DiscNumber: &discNum,
|
||||||
|
DurationMs: 183_000,
|
||||||
|
}
|
||||||
|
got := trackRefFrom(t2, "Abbey Road", "Beatles")
|
||||||
|
if got.Title != "Something" || got.AlbumTitle != "Abbey Road" || got.ArtistName != "Beatles" {
|
||||||
|
t.Errorf("ref = %+v", got)
|
||||||
|
}
|
||||||
|
if got.TrackNumber != 3 || got.DiscNumber != 1 {
|
||||||
|
t.Errorf("positions = %+v", got)
|
||||||
|
}
|
||||||
|
if got.DurationSec != 183 {
|
||||||
|
t.Errorf("duration = %d, want 183", got.DurationSec)
|
||||||
|
}
|
||||||
|
if got.StreamURL != "/api/tracks/00000000-0000-0000-0000-000000000010/stream" {
|
||||||
|
t.Errorf("stream_url = %q", got.StreamURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTrackRefFromNilPositions(t *testing.T) {
|
||||||
|
var tid, aid, artID pgtype.UUID
|
||||||
|
_ = tid.Scan("00000000-0000-0000-0000-000000000010")
|
||||||
|
_ = aid.Scan("00000000-0000-0000-0000-000000000001")
|
||||||
|
_ = artID.Scan("00000000-0000-0000-0000-000000000002")
|
||||||
|
t2 := dbq.Track{ID: tid, AlbumID: aid, ArtistID: artID, DurationMs: 1000}
|
||||||
|
got := trackRefFrom(t2, "A", "B")
|
||||||
|
if got.TrackNumber != 0 || got.DiscNumber != 0 {
|
||||||
|
t.Errorf("nil positions should be 0, got %+v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user