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)
|
GetList(ctx context.Context, id []int64) ([]model.Submission, error)
|
||||||
Create(ctx context.Context, smap model.Submission) (model.Submission, error)
|
Create(ctx context.Context, smap model.Submission) (model.Submission, error)
|
||||||
Update(ctx context.Context, id int64, values OptionalMap) 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
|
Delete(ctx context.Context, id int64) error
|
||||||
List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Submission, error)
|
List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Submission, error)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ package gormstore
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -50,6 +53,24 @@ func (env *Submissions) Update(ctx context.Context, id int64, values datastore.O
|
|||||||
return nil
|
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 {
|
func (env *Submissions) Delete(ctx context.Context, id int64) error {
|
||||||
if err := env.db.Delete(&model.Submission{}, id).Error; err != nil {
|
if err := env.db.Delete(&model.Submission{}, id).Error; err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
@ -144,22 +144,14 @@ func (svc *Service) PatchSubmissionModel(ctx context.Context, params api.PatchSu
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/publish
|
// PATCH /submissions/{SubmissionID}/status/publish
|
||||||
func (svc *Service) ActionSubmissionPublish(ctx context.Context, params api.ActionSubmissionPublishParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if submission.StatusID != model.StatusPublishing{
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusPublished)
|
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.
|
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
||||||
//
|
//
|
||||||
@ -167,22 +159,14 @@ func (svc *Service) ActionSubmissionPublish(ctx context.Context, params api.Acti
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/reject
|
// PATCH /submissions/{SubmissionID}/status/reject
|
||||||
func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.ActionSubmissionRejectParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if submission.StatusID != model.StatusSubmitted{
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusRejected)
|
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.
|
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
||||||
//
|
//
|
||||||
@ -190,22 +174,14 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/request-changes
|
// PATCH /submissions/{SubmissionID}/status/request-changes
|
||||||
func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params api.ActionSubmissionRequestChangesParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if !(submission.StatusID == model.StatusValidated||submission.StatusID == model.StatusAccepted||submission.StatusID == model.StatusSubmitted){
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusChangesRequested)
|
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.
|
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
||||||
//
|
//
|
||||||
@ -213,22 +189,14 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/revoke
|
// PATCH /submissions/{SubmissionID}/status/revoke
|
||||||
func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.ActionSubmissionRevokeParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if !(submission.StatusID == model.StatusSubmitted||submission.StatusID == model.StatusChangesRequested){
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusUnderConstruction)
|
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.
|
// ActionSubmissionSubmit invokes actionSubmissionSubmit operation.
|
||||||
//
|
//
|
||||||
@ -236,22 +204,14 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/submit
|
// PATCH /submissions/{SubmissionID}/status/submit
|
||||||
func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.ActionSubmissionSubmitParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
// if !CALLER_ROLES.INCLUDES(ROLE_Submitter){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if !(submission.StatusID == model.StatusUnderConstruction||submission.StatusID == model.StatusChangesRequested){
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusSubmitted)
|
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.
|
// ActionSubmissionTriggerPublish invokes actionSubmissionTriggerPublish operation.
|
||||||
//
|
//
|
||||||
@ -259,22 +219,14 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/trigger-publish
|
// PATCH /submissions/{SubmissionID}/status/trigger-publish
|
||||||
func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params api.ActionSubmissionTriggerPublishParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_Admin){
|
// if !CALLER_ROLES.INCLUDES(ROLE_Admin){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if !(submission.StatusID == model.StatusValidated){
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusPublishing)
|
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.
|
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
||||||
//
|
//
|
||||||
@ -282,22 +234,14 @@ func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params a
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/trigger-validate
|
// PATCH /submissions/{SubmissionID}/status/trigger-validate
|
||||||
func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params api.ActionSubmissionTriggerValidateParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
// if !CALLER_ROLES.INCLUDES(ROLE_Reviewer){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if !(submission.StatusID == model.StatusSubmitted||submission.StatusID == model.StatusAccepted){
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusValidating)
|
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.
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||||
//
|
//
|
||||||
@ -305,20 +249,12 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
|
|||||||
//
|
//
|
||||||
// PATCH /submissions/{SubmissionID}/status/validate
|
// PATCH /submissions/{SubmissionID}/status/validate
|
||||||
func (svc *Service) ActionSubmissionValidate(ctx context.Context, params api.ActionSubmissionValidateParams) error {
|
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
|
// check if caller has required role
|
||||||
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
// if !CALLER_ROLES.INCLUDES(ROLE_VALIDATOR){
|
||||||
// return ErrPermissionDenied
|
// return ErrPermissionDenied
|
||||||
// }
|
// }
|
||||||
// check source status
|
// transaction
|
||||||
if submission.StatusID != model.StatusValidating{
|
|
||||||
return ErrInvalidSourceStatus
|
|
||||||
}
|
|
||||||
// set status
|
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id",model.StatusValidated)
|
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