Added get all shows
This commit is contained in:
parent
0ad8a01564
commit
42eb154479
@ -98,5 +98,14 @@ func NewRouter(svc service.EpisodeService) *gin.Engine {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// GET /v1/shows — list all rows from "current"
|
||||||
|
v1.GET("/shows", func(c *gin.Context) {
|
||||||
|
items, err := svc.ListAll(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "list failed"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, items)
|
||||||
|
})
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,14 @@ func (f *fakeSvc) MoveToArchive(ctx context.Context, ids []int64) (repo.MoveResu
|
|||||||
f.lastMove = append([]int64(nil), ids...)
|
f.lastMove = append([]int64(nil), ids...)
|
||||||
return f.moveRes, f.moveErr
|
return f.moveRes, f.moveErr
|
||||||
}
|
}
|
||||||
|
func (f *fakeSvc) ListAll(ctx context.Context) ([]repo.Episode, error) {
|
||||||
|
if f.moveErr != nil {
|
||||||
|
return nil, f.moveErr
|
||||||
|
}
|
||||||
|
return []repo.Episode{
|
||||||
|
{Id: 10, EpTitle: "X"},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ---- helpers ----
|
// ---- helpers ----
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import (
|
|||||||
var ErrNotFound = errors.New("not found")
|
var ErrNotFound = errors.New("not found")
|
||||||
|
|
||||||
type Episode struct {
|
type Episode struct {
|
||||||
|
Id int `json:"id"`
|
||||||
EpNum int `json:"ep_num"`
|
EpNum int `json:"ep_num"`
|
||||||
EpTitle string `json:"ep_title"`
|
EpTitle string `json:"ep_title"`
|
||||||
SeasonName string `json:"season_name"`
|
SeasonName string `json:"season_name"`
|
||||||
@ -30,6 +31,7 @@ type EpisodeRepository interface {
|
|||||||
GetCurrent(ctx context.Context) (Episode, error)
|
GetCurrent(ctx context.Context) (Episode, error)
|
||||||
SetCurrent(ctx context.Context, id int64, startHHMMSS string) error
|
SetCurrent(ctx context.Context, id int64, startHHMMSS string) error
|
||||||
MoveToArchive(ctx context.Context, ids []int64) (MoveResult, error)
|
MoveToArchive(ctx context.Context, ids []int64) (MoveResult, error)
|
||||||
|
ListAll(ctx context.Context) ([]Episode, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type pgxEpisodeRepo struct {
|
type pgxEpisodeRepo struct {
|
||||||
@ -40,9 +42,40 @@ func NewEpisodeRepo(pool *pgxpool.Pool) EpisodeRepository {
|
|||||||
return &pgxEpisodeRepo{pool: pool}
|
return &pgxEpisodeRepo{pool: pool}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *pgxEpisodeRepo) ListAll(ctx context.Context) ([]Episode, error) {
|
||||||
|
const q = `
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
ep_num,
|
||||||
|
ep_title,
|
||||||
|
season_name,
|
||||||
|
to_char(start_time, 'HH24:MI:SS') AS start_time,
|
||||||
|
to_char(playback_length, 'HH24:MI:SS') AS playback_length,
|
||||||
|
date_created
|
||||||
|
FROM current
|
||||||
|
ORDER BY id DESC;
|
||||||
|
`
|
||||||
|
rows, err := r.pool.Query(ctx, q)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var out []Episode
|
||||||
|
for rows.Next() {
|
||||||
|
var e Episode
|
||||||
|
if err := rows.Scan(&e.Id, &e.EpNum, &e.EpTitle, &e.SeasonName, &e.StartTime, &e.PlaybackLength, &e.DateCreated); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out = append(out, e)
|
||||||
|
}
|
||||||
|
return out, rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
func (r *pgxEpisodeRepo) GetCurrent(ctx context.Context) (Episode, error) {
|
func (r *pgxEpisodeRepo) GetCurrent(ctx context.Context) (Episode, error) {
|
||||||
const q = `
|
const q = `
|
||||||
SELECT
|
SELECT
|
||||||
|
id,
|
||||||
ep_num,
|
ep_num,
|
||||||
ep_title,
|
ep_title,
|
||||||
season_name,
|
season_name,
|
||||||
@ -56,7 +89,7 @@ LIMIT 1;
|
|||||||
`
|
`
|
||||||
var e Episode
|
var e Episode
|
||||||
err := r.pool.QueryRow(ctx, q).Scan(
|
err := r.pool.QueryRow(ctx, q).Scan(
|
||||||
&e.EpNum, &e.EpTitle, &e.SeasonName, &e.StartTime, &e.PlaybackLength, &e.DateCreated,
|
&e.Id, &e.EpNum, &e.EpTitle, &e.SeasonName, &e.StartTime, &e.PlaybackLength, &e.DateCreated,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
if errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ type EpisodeService interface {
|
|||||||
GetCurrent(ctx context.Context) (repo.Episode, error)
|
GetCurrent(ctx context.Context) (repo.Episode, error)
|
||||||
SetCurrent(ctx context.Context, id int64, start string) (repo.Episode, error)
|
SetCurrent(ctx context.Context, id int64, start string) (repo.Episode, error)
|
||||||
MoveToArchive(ctx context.Context, ids []int64) (repo.MoveResult, error)
|
MoveToArchive(ctx context.Context, ids []int64) (repo.MoveResult, error)
|
||||||
|
ListAll(ctx context.Context) ([]repo.Episode, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type episodeService struct {
|
type episodeService struct {
|
||||||
@ -28,6 +29,12 @@ func NewEpisodeService(r repo.EpisodeRepository) EpisodeService {
|
|||||||
return &episodeService{repo: r}
|
return &episodeService{repo: r}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *episodeService) ListAll(ctx context.Context) ([]repo.Episode, error) {
|
||||||
|
c, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
return s.repo.ListAll(c)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *episodeService) GetCurrent(ctx context.Context) (repo.Episode, error) {
|
func (s *episodeService) GetCurrent(ctx context.Context) (repo.Episode, error) {
|
||||||
c, cancel := context.WithTimeout(ctx, 3*time.Second)
|
c, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|||||||
@ -23,6 +23,8 @@ type fakeRepo struct {
|
|||||||
start string
|
start string
|
||||||
}
|
}
|
||||||
moveCalls [][]int64
|
moveCalls [][]int64
|
||||||
|
listRes []repo.Episode
|
||||||
|
listErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeRepo) GetCurrent(ctx context.Context) (repo.Episode, error) {
|
func (f *fakeRepo) GetCurrent(ctx context.Context) (repo.Episode, error) {
|
||||||
@ -39,6 +41,9 @@ func (f *fakeRepo) MoveToArchive(ctx context.Context, ids []int64) (repo.MoveRes
|
|||||||
f.moveCalls = append(f.moveCalls, ids)
|
f.moveCalls = append(f.moveCalls, ids)
|
||||||
return f.moveRes, f.moveErr
|
return f.moveRes, f.moveErr
|
||||||
}
|
}
|
||||||
|
func (f *fakeRepo) ListAll(ctx context.Context) ([]repo.Episode, error) {
|
||||||
|
return f.listRes, f.listErr
|
||||||
|
}
|
||||||
|
|
||||||
// ---- tests ----
|
// ---- tests ----
|
||||||
|
|
||||||
@ -141,3 +146,23 @@ func TestEpisodeService_MoveToArchive_DedupAndOK(t *testing.T) {
|
|||||||
t.Fatalf("unexpected response: %+v", res)
|
t.Fatalf("unexpected response: %+v", res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEpisodeService_ListAll_OK(t *testing.T) {
|
||||||
|
fr := &fakeRepo{listRes: []repo.Episode{{Id: 3}, {Id: 1}}}
|
||||||
|
svc := service.NewEpisodeService(fr)
|
||||||
|
got, err := svc.ListAll(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected: %v", err)
|
||||||
|
}
|
||||||
|
if len(got) != 2 || got[0].Id != 3 {
|
||||||
|
t.Fatalf("bad: %+v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEpisodeService_ListAll_Error(t *testing.T) {
|
||||||
|
fr := &fakeRepo{listErr: errors.New("boom")}
|
||||||
|
svc := service.NewEpisodeService(fr)
|
||||||
|
if _, err := svc.ListAll(context.Background()); err == nil {
|
||||||
|
t.Fatal("expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user