Feature: Support multiple action status per release (#69)

* feat: move release actions to separate table

* chore: update sqlite driver
This commit is contained in:
Ludvig Lundgren 2022-01-08 15:40:31 +01:00 committed by GitHub
parent 2ea2293745
commit e03eac24ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 284 additions and 91 deletions

View file

@ -23,8 +23,8 @@ func NewReleaseRepo(db *sql.DB) domain.ReleaseRepo {
func (repo *ReleaseRepo) Store(ctx context.Context, r *domain.Release) (*domain.Release, error) {
query, args, err := sq.
Insert("release").
Columns("filter_status", "push_status", "rejections", "indexer", "filter", "protocol", "implementation", "timestamp", "group_id", "torrent_id", "torrent_name", "size", "raw", "title", "category", "season", "episode", "year", "resolution", "source", "codec", "container", "hdr", "audio", "release_group", "region", "language", "edition", "unrated", "hybrid", "proper", "repack", "website", "artists", "type", "format", "bitrate", "log_score", "has_log", "has_cue", "is_scene", "origin", "tags", "freeleech", "freeleech_percent", "uploader", "pre_time").
Values(r.FilterStatus, r.PushStatus, pq.Array(r.Rejections), r.Indexer, r.FilterName, r.Protocol, r.Implementation, r.Timestamp, r.GroupID, r.TorrentID, r.TorrentName, r.Size, r.Raw, r.Title, r.Category, r.Season, r.Episode, r.Year, r.Resolution, r.Source, r.Codec, r.Container, r.HDR, r.Audio, r.Group, r.Region, r.Language, r.Edition, r.Unrated, r.Hybrid, r.Proper, r.Repack, r.Website, pq.Array(r.Artists), r.Type, r.Format, r.Bitrate, r.LogScore, r.HasLog, r.HasCue, r.IsScene, r.Origin, pq.Array(r.Tags), r.Freeleech, r.FreeleechPercent, r.Uploader, r.PreTime).
Columns("filter_status", "rejections", "indexer", "filter", "protocol", "implementation", "timestamp", "group_id", "torrent_id", "torrent_name", "size", "raw", "title", "category", "season", "episode", "year", "resolution", "source", "codec", "container", "hdr", "audio", "release_group", "region", "language", "edition", "unrated", "hybrid", "proper", "repack", "website", "artists", "type", "format", "bitrate", "log_score", "has_log", "has_cue", "is_scene", "origin", "tags", "freeleech", "freeleech_percent", "uploader", "pre_time").
Values(r.FilterStatus, pq.Array(r.Rejections), r.Indexer, r.FilterName, r.Protocol, r.Implementation, r.Timestamp, r.GroupID, r.TorrentID, r.TorrentName, r.Size, r.Raw, r.Title, r.Category, r.Season, r.Episode, r.Year, r.Resolution, r.Source, r.Codec, r.Container, r.HDR, r.Audio, r.Group, r.Region, r.Language, r.Edition, r.Unrated, r.Hybrid, r.Proper, r.Repack, r.Website, pq.Array(r.Artists), r.Type, r.Format, r.Bitrate, r.LogScore, r.HasLog, r.HasCue, r.IsScene, r.Origin, pq.Array(r.Tags), r.Freeleech, r.FreeleechPercent, r.Uploader, r.PreTime).
ToSql()
res, err := repo.db.ExecContext(ctx, query, args...)
@ -41,37 +41,42 @@ func (repo *ReleaseRepo) Store(ctx context.Context, r *domain.Release) (*domain.
return r, nil
}
func (repo *ReleaseRepo) UpdatePushStatus(ctx context.Context, id int64, status domain.ReleasePushStatus) error {
query, args, err := sq.Update("release").Set("push_status", status).Where("id = ?", id).ToSql()
func (repo *ReleaseRepo) StoreReleaseActionStatus(ctx context.Context, a *domain.ReleaseActionStatus) error {
_, err = repo.db.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error updating status of release")
return err
if a.ID != 0 {
query, args, err := sq.
Update("release_action_status").
Set("status", a.Status).
Set("rejections", pq.Array(a.Rejections)).
Set("timestamp", time.Now().Format(time.RFC3339)).
Where("id = ?", a.ID).
Where("release_id = ?", a.ReleaseID).
ToSql()
_, err = repo.db.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error updating status of release")
return err
}
} else {
query, args, err := sq.
Insert("release_action_status").
Columns("status", "action", "type", "rejections", "timestamp", "release_id").
Values(a.Status, a.Action, a.Type, pq.Array(a.Rejections), a.Timestamp, a.ReleaseID).
ToSql()
res, err := repo.db.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error inserting status of release")
return err
}
resId, _ := res.LastInsertId()
a.ID = resId
}
log.Trace().Msgf("release.update_push_status: id %+v", id)
return nil
}
func (repo *ReleaseRepo) UpdatePushStatusRejected(ctx context.Context, id int64, rejections string) error {
r := []string{rejections}
query, args, err := sq.
Update("release").
Set("push_status", domain.ReleasePushStatusRejected).
Set("rejections", pq.Array(r)).
Where("id = ?", id).
ToSql()
_, err = repo.db.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error updating status of release")
return err
}
log.Trace().Msgf("release.update_push_status_rejected: id %+v", id)
log.Trace().Msgf("release.store_release_action_status: %+v", a)
return nil
}
@ -79,7 +84,7 @@ func (repo *ReleaseRepo) UpdatePushStatusRejected(ctx context.Context, id int64,
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", "COUNT() OVER() AS total_count").
Select("id", "filter_status", "rejections", "indexer", "filter", "protocol", "title", "torrent_name", "size", "timestamp", "COUNT() OVER() AS total_count").
From("release").
OrderBy("timestamp DESC")
@ -132,7 +137,7 @@ func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([
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, &countItems); err != nil {
if err := rows.Scan(&rls.ID, &rls.FilterStatus, 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, 0, err
}
@ -143,6 +148,15 @@ func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([
ca, _ := time.Parse(time.RFC3339, timestamp)
rls.Timestamp = ca
// get action status
actionStatus, err := repo.GetActionStatusByReleaseID(ctx, rls.ID)
if err != nil {
log.Error().Stack().Err(err).Msg("release.find: error getting action status")
return res, 0, 0, err
}
rls.ActionStatus = actionStatus
res = append(res, rls)
}
@ -156,13 +170,57 @@ func (repo *ReleaseRepo) Find(ctx context.Context, params domain.QueryParams) ([
return res, nextCursor, countItems, nil
}
func (repo *ReleaseRepo) GetActionStatusByReleaseID(ctx context.Context, releaseID int64) ([]domain.ReleaseActionStatus, error) {
queryBuilder := sq.
Select("id", "status", "action", "type", "rejections", "timestamp").
From("release_action_status").
Where("release_id = ?", releaseID)
query, args, err := queryBuilder.ToSql()
res := make([]domain.ReleaseActionStatus, 0)
rows, err := repo.db.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error fetching releases")
return res, nil
}
defer rows.Close()
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err)
return res, err
}
for rows.Next() {
var rls domain.ReleaseActionStatus
var timestamp string
if err := rows.Scan(&rls.ID, &rls.Status, &rls.Action, &rls.Type, pq.Array(&rls.Rejections), &timestamp); err != nil {
log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
return res, err
}
ca, _ := time.Parse(time.RFC3339, timestamp)
rls.Timestamp = ca
res = append(res, rls)
}
return res, nil
}
func (repo *ReleaseRepo) Stats(ctx context.Context) (*domain.ReleaseStats, error) {
query := `SELECT
COUNT(*) total,
IFNULL(SUM(CASE WHEN push_status = 'PUSH_APPROVED' THEN 1 ELSE 0 END), 0) push_approved_count,
IFNULL(SUM(CASE WHEN push_status = 'PUSH_REJECTED' THEN 1 ELSE 0 END), 0) push_rejected_count,
IFNULL(SUM(CASE WHEN filter_status = 'FILTER_APPROVED' THEN 1 ELSE 0 END), 0) filtered_count,
IFNULL(SUM(CASE WHEN filter_status = 'FILTER_REJECTED' THEN 1 ELSE 0 END), 0) filter_rejected_count
query := `SELECT COUNT(*) total,
IFNULL(SUM(CASE WHEN filter_status = 'FILTER_APPROVED' THEN 1 ELSE 0 END), 0) filtered_count,
IFNULL(SUM(CASE WHEN filter_status = 'FILTER_REJECTED' THEN 1 ELSE 0 END), 0) filter_rejected_count,
(SELECT IFNULL(SUM(CASE WHEN status = 'PUSH_APPROVED' THEN 1 ELSE 0 END), 0)
FROM "release_action_status") AS push_approved_count,
(SELECT IFNULL(SUM(CASE WHEN status = 'PUSH_REJECTED' THEN 1 ELSE 0 END), 0)
FROM "release_action_status") AS push_rejected_count
FROM "release";`
row := repo.db.QueryRowContext(ctx, query)