Feature: List releases (#52)

* feat: list releases

* feat: find releases and count
This commit is contained in:
Ludvig Lundgren 2021-12-25 21:44:52 +01:00 committed by GitHub
parent c83ebdc1a4
commit b75c40f6a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 506 additions and 20 deletions

View file

@ -76,9 +76,12 @@ func (repo *ReleaseRepo) UpdatePushStatusRejected(ctx context.Context, id int64,
return nil
}
func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([]domain.Release, int64, error) {
func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([]domain.Release, int64, int64, error) {
queryBuilder := sq.Select("id", "filter_status", "push_status", "rejections", "indexer", "filter", "protocol", "title", "torrent_name", "size", "timestamp").From("release").OrderBy("timestamp DESC")
queryBuilder := sq.
Select("id", "filter_status", "push_status", "rejections", "indexer", "filter", "protocol", "title", "torrent_name", "size", "timestamp", "COUNT() OVER() AS total_count").
From("release").
OrderBy("timestamp DESC")
if params.Limit > 0 {
queryBuilder = queryBuilder.Limit(params.Limit)
@ -86,8 +89,11 @@ func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([
queryBuilder = queryBuilder.Limit(20)
}
if params.Offset > 0 {
queryBuilder = queryBuilder.Offset(params.Offset)
}
if params.Cursor > 0 {
//queryBuilder = queryBuilder.Where(sq.Gt{"id": params.Cursor})
queryBuilder = queryBuilder.Where(sq.Lt{"id": params.Cursor})
}
@ -108,26 +114,27 @@ func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([
rows, err := repo.db.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error fetching releases")
//return
return res, 0, nil
return res, 0, 0, nil
}
defer rows.Close()
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err)
return res, 0, err
return res, 0, 0, err
}
var countItems int64 = 0
for rows.Next() {
var rls domain.Release
var indexer, filter sql.NullString
var timestamp string
if err := rows.Scan(&rls.ID, &rls.FilterStatus, &rls.PushStatus, pq.Array(&rls.Rejections), &indexer, &filter, &rls.Protocol, &rls.Title, &rls.TorrentName, &rls.Size, &timestamp); err != nil {
if err := rows.Scan(&rls.ID, &rls.FilterStatus, &rls.PushStatus, pq.Array(&rls.Rejections), &indexer, &filter, &rls.Protocol, &rls.Title, &rls.TorrentName, &rls.Size, &timestamp, &countItems); err != nil {
log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
return res, 0, err
return res, 0, 0, err
}
rls.Indexer = indexer.String
@ -146,7 +153,7 @@ func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([
//nextCursor, _ = strconv.ParseInt(lastID, 10, 64)
}
return res, nextCursor, nil
return res, nextCursor, countItems, nil
}
func (repo *ReleaseRepo) Stats(ctx context.Context) (*domain.ReleaseStats, error) {

View file

@ -18,7 +18,7 @@ import (
type ReleaseRepo interface {
Store(ctx context.Context, release *Release) (*Release, error)
Find(ctx context.Context, params QueryParams) (res []Release, nextCursor int64, err error)
Find(ctx context.Context, params QueryParams) (res []Release, nextCursor int64, count int64, err error)
Stats(ctx context.Context) (*ReleaseStats, error)
UpdatePushStatus(ctx context.Context, id int64, status ReleasePushStatus) error
UpdatePushStatusRejected(ctx context.Context, id int64, rejections string) error
@ -913,6 +913,7 @@ const (
type QueryParams struct {
Limit uint64
Offset uint64
Cursor uint64
Sort map[string]string
Filter map[string]string

View file

@ -10,7 +10,7 @@ import (
)
type releaseService interface {
Find(ctx context.Context, query domain.QueryParams) (res []domain.Release, nextCursor int64, err error)
Find(ctx context.Context, query domain.QueryParams) (res []domain.Release, nextCursor int64, count int64, err error)
Stats(ctx context.Context) (*domain.ReleaseStats, error)
}
@ -45,6 +45,15 @@ func (h releaseHandler) findReleases(w http.ResponseWriter, r *http.Request) {
limit = 20
}
offsetP := r.URL.Query().Get("offset")
offset, err := strconv.Atoi(offsetP)
if err != nil && offsetP != "" {
h.encoder.StatusResponse(r.Context(), w, map[string]interface{}{
"code": "BAD_REQUEST_PARAMS",
"message": "offset parameter is invalid",
}, http.StatusBadRequest)
}
cursorP := r.URL.Query().Get("cursor")
cursor, err := strconv.Atoi(cursorP)
if err != nil && cursorP != "" {
@ -56,12 +65,13 @@ func (h releaseHandler) findReleases(w http.ResponseWriter, r *http.Request) {
query := domain.QueryParams{
Limit: uint64(limit),
Offset: uint64(offset),
Cursor: uint64(cursor),
Sort: nil,
//Filter: "",
}
releases, nextCursor, err := h.service.Find(r.Context(), query)
releases, nextCursor, count, err := h.service.Find(r.Context(), query)
if err != nil {
h.encoder.StatusNotFound(r.Context(), w)
return
@ -70,9 +80,11 @@ func (h releaseHandler) findReleases(w http.ResponseWriter, r *http.Request) {
ret := struct {
Data []domain.Release `json:"data"`
NextCursor int64 `json:"next_cursor"`
Count int64 `json:"count"`
}{
Data: releases,
NextCursor: nextCursor,
Count: count,
}
h.encoder.StatusResponse(r.Context(), w, ret, http.StatusOK)

View file

@ -11,7 +11,7 @@ import (
)
type Service interface {
Find(ctx context.Context, query domain.QueryParams) (res []domain.Release, nextCursor int64, err error)
Find(ctx context.Context, query domain.QueryParams) (res []domain.Release, nextCursor int64, count int64, err error)
Stats(ctx context.Context) (*domain.ReleaseStats, error)
Store(ctx context.Context, release *domain.Release) error
UpdatePushStatus(ctx context.Context, id int64, status domain.ReleasePushStatus) error
@ -31,16 +31,12 @@ func NewService(repo domain.ReleaseRepo, actionService action.Service) Service {
}
}
func (s *service) Find(ctx context.Context, query domain.QueryParams) (res []domain.Release, nextCursor int64, err error) {
//releases, err := s.repo.Find(ctx, query)
res, nextCursor, err = s.repo.Find(ctx, query)
func (s *service) Find(ctx context.Context, query domain.QueryParams) (res []domain.Release, nextCursor int64, count int64, err error) {
res, nextCursor, count, err = s.repo.Find(ctx, query)
if err != nil {
//return nil, err
return
}
return
//return releases, nil
}
func (s *service) Stats(ctx context.Context) (*domain.ReleaseStats, error) {