3
0

Generate additional IDs for reports

This commit is contained in:
Tomaž Jerman
2022-02-17 11:08:06 +01:00
committed by Jože Fortun
parent 87d3b68df6
commit 330a332fdd
4 changed files with 141 additions and 4 deletions

View File

@@ -0,0 +1,68 @@
package provision
import (
"context"
"strconv"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/store"
sysTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/spf13/cast"
"go.uber.org/zap"
)
// Migrates existing reports to include the newly added resource identifiers
func migrateReportIdentifiers(ctx context.Context, log *zap.Logger, s store.Storer) (err error) {
log.Info("migrating report identifiers")
set, _, err := store.SearchReports(ctx, s, sysTypes.ReportFilter{Deleted: filter.StateInclusive})
if err != nil {
return err
}
return s.Tx(ctx, func(ctx context.Context, s store.Storer) error {
return set.Walk(func(r *sysTypes.Report) (err error) {
r = setIDs(r)
return store.UpdateReport(ctx, s, r)
})
})
}
// duplicate from the report service
func setIDs(r *sysTypes.Report) *sysTypes.Report {
// scenarios
for _, s := range r.Scenarios {
if s.ScenarioID == 0 {
s.ScenarioID = id.Next()
}
}
// blocks
for _, b := range r.Blocks {
if b.BlockID == 0 {
b.BlockID = id.Next()
}
// elements
for _, elRaw := range b.Elements {
el, ok := elRaw.(map[string]interface{})
if !ok {
continue
}
elID, ok := el["elementID"]
sElID := cast.ToString(elID)
if sElID != "" && sElID != "0" {
continue
}
if cast.ToUint64(elID) != 0 {
continue
}
el["elementID"] = strconv.FormatUint(id.Next(), 10)
}
}
return r
}

View File

@@ -32,6 +32,7 @@ func Run(ctx context.Context, log *zap.Logger, s store.Storer, provisionOpt opti
func() error { return migratePre202109RbacRules(ctx, log.Named("pre-202109-rbac-rules"), s) },
func() error { return cleanupPre202109Settings(ctx, log.Named("pre-202109-settings"), s) },
func() error { return migrateResourceTranslations(ctx, log.Named("resource-translations"), s) },
func() error { return migrateReportIdentifiers(ctx, log.Named("report-identifiers"), s) },
// Config (full & partial)
func() error { return importConfig(ctx, log.Named("config"), s, provisionOpt.Path) },

View File

@@ -3,12 +3,14 @@ package service
import (
"context"
"fmt"
"strconv"
"github.com/cortezaproject/corteza-server/pkg/actionlog"
"github.com/cortezaproject/corteza-server/pkg/label"
rep "github.com/cortezaproject/corteza-server/pkg/report"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/spf13/cast"
)
type (
@@ -140,6 +142,8 @@ func (svc *report) Create(ctx context.Context, new *types.Report) (report *types
new.Meta = &types.ReportMeta{}
}
new = svc.setIDs(new)
if err = store.CreateReport(ctx, svc.store, new); err != nil {
return
}
@@ -193,6 +197,8 @@ func (svc *report) Update(ctx context.Context, upd *types.Report) (report *types
report.Meta = upd.Meta
}
report = svc.setIDs(report)
if err = store.UpdateReport(ctx, svc.store, report); err != nil {
return err
}
@@ -426,6 +432,43 @@ func (svc *report) Run(ctx context.Context, reportID uint64, dd rep.FrameDefinit
return out, svc.recordAction(ctx, aaProps, ReportActionRun, err)
}
func (svc *report) setIDs(r *types.Report) *types.Report {
// scenarios
for _, s := range r.Scenarios {
if s.ScenarioID == 0 {
s.ScenarioID = nextID()
}
}
// blocks
for _, b := range r.Blocks {
if b.BlockID == 0 {
b.BlockID = nextID()
}
// elements
for _, elRaw := range b.Elements {
el, ok := elRaw.(map[string]interface{})
if !ok {
continue
}
elID, ok := el["elementID"]
sElID := cast.ToString(elID)
if sElID != "" && sElID != "0" {
continue
}
if cast.ToUint64(elID) != 0 {
continue
}
el["elementID"] = strconv.FormatUint(nextID(), 10)
}
}
return r
}
// toLabeledReports converts to []label.LabeledResource
//
// This function is auto-generated.

View File

@@ -8,6 +8,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/report"
"github.com/spf13/cast"
)
type (
@@ -35,9 +36,9 @@ type (
ReportScenarioSet []*ReportScenario
ScenarioFilterMap map[string]*report.Filter
ReportScenario struct {
// ScenarioID uint64 `json:"scenarioID,string,omitempty"`
Label string `json:"label"`
Filters ScenarioFilterMap `json:"filters,omitempty"`
ScenarioID uint64 `json:"scenarioID,string,omitempty"`
Label string `json:"label"`
Filters ScenarioFilterMap `json:"filters,omitempty"`
}
ReportDataSource struct {
@@ -52,7 +53,7 @@ type (
}
ReportBlock struct {
BlockID uint64 `json:"blockID"`
BlockID uint64 `json:"blockID,string"`
Title string `json:"title"`
Description string `json:"description"`
Key string `json:"key"`
@@ -87,6 +88,30 @@ type (
}
)
// Initial ReportBlock struct definition omitted string casting for the BlockID (sorry)
// so we need to handle that edge case when reading from DB.
func (b *ReportBlock) UnmarshalJSON(data []byte) (err error) {
type internalReportBlock ReportBlock
i := struct {
internalReportBlock
BlockID interface{} `json:"blockID"`
}{}
if err = json.Unmarshal(data, &i); err != nil {
return
}
bID, err := cast.ToUint64E(i.BlockID)
if err != nil {
return
}
*b = ReportBlock(i.internalReportBlock)
b.BlockID = bID
return nil
}
func (ss ReportDataSourceSet) ModelSteps() report.StepDefinitionSet {
out := make(report.StepDefinitionSet, 0, 124)