Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
158 lines
4.0 KiB
Go
158 lines
4.0 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/cortezaproject/corteza/server/compose/types"
|
|
"github.com/cortezaproject/corteza/server/pkg/auth"
|
|
"github.com/cortezaproject/corteza/server/pkg/dal"
|
|
"github.com/cortezaproject/corteza/server/pkg/filter"
|
|
"github.com/cortezaproject/corteza/server/pkg/revisions"
|
|
)
|
|
|
|
type (
|
|
// wrapper around revision.service
|
|
//
|
|
// handles all module-to-model conversion
|
|
recordRevisions struct {
|
|
r interface {
|
|
Search(ctx context.Context, mf dal.ModelRef, f filter.Filter) (_ dal.Iterator, err error)
|
|
Create(ctx context.Context, mf dal.ModelRef, revision *revisions.Revision) error
|
|
}
|
|
}
|
|
)
|
|
|
|
// constructs DAL model-ref from module
|
|
//
|
|
// Since we're using revisions model resource type needs to be altered.
|
|
func (svc *recordRevisions) modelRef(mod *types.Module) (mf dal.ModelRef) {
|
|
mf = mod.ModelRef()
|
|
|
|
// removing resource ID from model filter
|
|
// this will force DAL service to use FindModelByResourceIdent
|
|
// to find model with same Resource value and RevisionResourceType
|
|
// for ResourceType
|
|
mf.ResourceID = 0
|
|
mf.ResourceType = revisions.RevisionResourceType
|
|
return
|
|
}
|
|
|
|
func (svc *recordRevisions) search(ctx context.Context, rec *types.Record, sorting filter.Sorting) (_ dal.Iterator, err error) {
|
|
var (
|
|
revModRef = svc.modelRef(rec.GetModule())
|
|
sortExpr = sorting.OrderBy()
|
|
)
|
|
|
|
if len(sortExpr) == 0 {
|
|
sortExpr = filter.SortExprSet{
|
|
&filter.SortExpr{Column: "revision", Descending: true},
|
|
}
|
|
}
|
|
|
|
revFilter := filter.Generic(
|
|
filter.WithConstraint("rel_resource", rec.ID),
|
|
filter.WithOrderBy(sortExpr),
|
|
)
|
|
|
|
return svc.r.Search(ctx, revModRef, revFilter)
|
|
}
|
|
|
|
func (svc *recordRevisions) created(ctx context.Context, new *types.Record) (err error) {
|
|
var (
|
|
skipList = svc.skippedField(new.GetModule())
|
|
invokerID = auth.GetIdentityFromContext(ctx).Identity()
|
|
rev *revisions.Revision
|
|
)
|
|
|
|
rev = revisions.Make(revisions.Created, new.Revision, new.ID, invokerID)
|
|
err = rev.CollectChanges(new, nil, skipList...)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return svc.r.Create(ctx, svc.modelRef(new.GetModule()), rev)
|
|
}
|
|
|
|
func (svc *recordRevisions) updated(ctx context.Context, upd, old *types.Record) (err error) {
|
|
var (
|
|
skipList = svc.skippedField(old.GetModule())
|
|
invokerID = auth.GetIdentityFromContext(ctx).Identity()
|
|
rev *revisions.Revision
|
|
)
|
|
|
|
rev = revisions.Make(revisions.Updated, upd.Revision, upd.ID, invokerID)
|
|
err = rev.CollectChanges(upd, old, skipList...)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return svc.r.Create(ctx, svc.modelRef(upd.GetModule()), rev)
|
|
}
|
|
|
|
func (svc *recordRevisions) softDeleted(ctx context.Context, del *types.Record) (err error) {
|
|
var (
|
|
invokerID = auth.GetIdentityFromContext(ctx).Identity()
|
|
rev *revisions.Revision
|
|
)
|
|
|
|
rev = revisions.Make(revisions.SoftDeleted, del.Revision, del.ID, invokerID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return svc.r.Create(ctx, svc.modelRef(del.GetModule()), rev)
|
|
}
|
|
|
|
func (svc *recordRevisions) undeleted(ctx context.Context, undel *types.Record) (err error) {
|
|
var (
|
|
invokerID = auth.GetIdentityFromContext(ctx).Identity()
|
|
rev *revisions.Revision
|
|
)
|
|
|
|
rev = revisions.Make(revisions.Undeleted, undel.Revision, undel.ID, invokerID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return svc.r.Create(ctx, svc.modelRef(undel.GetModule()), rev)
|
|
}
|
|
|
|
func (svc *recordRevisions) skippedField(mod *types.Module) []string {
|
|
list := []string{
|
|
"ID",
|
|
"namespaceID",
|
|
"moduleID",
|
|
"revision",
|
|
"meta",
|
|
"createdBy",
|
|
"createdAt",
|
|
"updatedBy",
|
|
"updatedAt",
|
|
"deletedBy",
|
|
"deletedAt",
|
|
}
|
|
|
|
for _, f := range mod.Fields {
|
|
if f.Config.RecordRevisions.Skip {
|
|
list = append(list, f.Name)
|
|
}
|
|
}
|
|
|
|
return list
|
|
}
|
|
|
|
// @todo uncomment when supported
|
|
//func (svc *recordRevisions) hardDeleted(ctx context.Context, del *types.Record) (err error) {
|
|
// var (
|
|
// invokerID = auth.GetIdentityFromContext(ctx).Identity()
|
|
// rev *revisions.Revision
|
|
// )
|
|
//
|
|
// rev, err = revisions.Make(revisions.HardDeleted, del.Revision, del.ID, invokerID, nil, nil)
|
|
// if err != nil {
|
|
// return
|
|
// }
|
|
//
|
|
// return svc.r.Create(ctx, svc.modelRef(del.GetModule()), rev)
|
|
//}
|