construct transactional update
This commit is contained in:
parent
f4fea2963d
commit
f5fb895aeb
@ -19,6 +19,7 @@ type Submissions interface {
|
||||
GetList(ctx context.Context, id []int64) ([]model.Submission, error)
|
||||
Create(ctx context.Context, smap model.Submission) (model.Submission, error)
|
||||
Update(ctx context.Context, id int64, values OptionalMap) error
|
||||
IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values OptionalMap) error
|
||||
Delete(ctx context.Context, id int64) error
|
||||
List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Submission, error)
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package gormstore
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||
"gorm.io/gorm"
|
||||
@ -50,6 +53,24 @@ func (env *Submissions) Update(ctx context.Context, id int64, values datastore.O
|
||||
return nil
|
||||
}
|
||||
|
||||
// the update can only occur if the status matches one of the provided values.
|
||||
func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) error {
|
||||
tx := env.db.Model(&model.Submission{}).Where("id = ?", id)
|
||||
expr := make([]string, 0,len(statuses))
|
||||
for i, status := range statuses{
|
||||
expr[i] = fmt.Sprintf("status = %d", int32(status))
|
||||
}
|
||||
tx = tx.Where(strings.Join(expr, " OR "))
|
||||
if err := tx.Updates(values.Map()).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return datastore.ErrNotExist
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (env *Submissions) Delete(ctx context.Context, id int64) error {
|
||||
if err := env.db.Delete(&model.Submission{}, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
|
@ -144,22 +144,14 @@ func (svc *Service) PatchSubmissionModel(ctx context.Context, params api.PatchSu
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/publish
|
||||
func (svc *Service) ActionSubmissionPublish(ctx context.Context, params api.ActionSubmissionPublishParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if submission.StatusID != model.StatusPublishing{
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusPublished)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusPublishing}, smap)
|
||||
}
|
||||
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
||||
//
|
||||
@ -167,22 +159,14 @@ func (svc *Service) ActionSubmissionPublish(ctx context.Context, params api.Acti
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/reject
|
||||
func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.ActionSubmissionRejectParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if submission.StatusID != model.StatusSubmitted{
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusRejected)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted}, smap)
|
||||
}
|
||||
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
||||
//
|
||||
@ -190,22 +174,14 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/request-changes
|
||||
func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params api.ActionSubmissionRequestChangesParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if !(submission.StatusID == model.StatusValidated||submission.StatusID == model.StatusAccepted||submission.StatusID == model.StatusSubmitted){
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusChangesRequested)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidated,model.StatusAccepted,model.StatusSubmitted}, smap)
|
||||
}
|
||||
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
||||
//
|
||||
@ -213,22 +189,14 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/revoke
|
||||
func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.ActionSubmissionRevokeParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if !(submission.StatusID == model.StatusSubmitted||submission.StatusID == model.StatusChangesRequested){
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusUnderConstruction)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted,model.StatusChangesRequested}, smap)
|
||||
}
|
||||
// ActionSubmissionSubmit invokes actionSubmissionSubmit operation.
|
||||
//
|
||||
@ -236,22 +204,14 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/submit
|
||||
func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.ActionSubmissionSubmitParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if !(submission.StatusID == model.StatusUnderConstruction||submission.StatusID == model.StatusChangesRequested){
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusSubmitted)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUnderConstruction,model.StatusChangesRequested}, smap)
|
||||
}
|
||||
// ActionSubmissionTriggerPublish invokes actionSubmissionTriggerPublish operation.
|
||||
//
|
||||
@ -259,22 +219,14 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/trigger-publish
|
||||
func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params api.ActionSubmissionTriggerPublishParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_Admin){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if !(submission.StatusID == model.StatusValidated){
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusPublishing)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap)
|
||||
}
|
||||
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
||||
//
|
||||
@ -282,22 +234,14 @@ func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params a
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/trigger-validate
|
||||
func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params api.ActionSubmissionTriggerValidateParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if !(submission.StatusID == model.StatusSubmitted||submission.StatusID == model.StatusAccepted){
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusValidating)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted,model.StatusAccepted}, smap)
|
||||
}
|
||||
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||
//
|
||||
@ -305,20 +249,12 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
|
||||
//
|
||||
// PATCH /submissions/{SubmissionID}/status/validate
|
||||
func (svc *Service) ActionSubmissionValidate(ctx context.Context, params api.ActionSubmissionValidateParams) error {
|
||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
// check if caller has required role
|
||||
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
||||
// return ErrPermissionDenied
|
||||
// }
|
||||
// check source status
|
||||
if submission.StatusID != model.StatusValidating{
|
||||
return ErrInvalidSourceStatus
|
||||
}
|
||||
// set status
|
||||
// transaction
|
||||
smap := datastore.Optional()
|
||||
smap.Add("status_id",model.StatusValidated)
|
||||
return svc.DB.Submissions().Update(ctx, params.SubmissionID, smap)
|
||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user