Skip to content
This repository has been archived by the owner on Sep 15, 2024. It is now read-only.

fix: handle referential integrity for lists of references #126

Merged
merged 2 commits into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions content/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import (
"path/filepath"
"strings"

cueError "cuelang.org/go/cue/errors"
"github.com/cueblox/blox"
"github.com/graphql-go/graphql"

"github.com/cueblox/blox/internal/cuedb"
"github.com/cueblox/blox/internal/encoding/markdown"
"github.com/cueblox/blox/internal/repository"
"github.com/goccy/go-yaml"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-plugin"
"github.com/pterm/pterm"
)
Expand Down Expand Up @@ -91,8 +91,6 @@ func NewService(bloxConfig string, referentialIntegrity bool) (*Service, error)
}

func (s *Service) build() error {
var errors error

err := s.parseRemotes()
if err != nil {
return err
Expand All @@ -104,6 +102,8 @@ func (s *Service) build() error {
return err
}

var errors cueError.Error

for _, dataSet := range s.engine.GetDataSets() {
pterm.Debug.Printf("\t\tBuilding Dataset: %s\n", dataSet.ID())

Expand All @@ -113,7 +113,7 @@ func (s *Service) build() error {

err := os.MkdirAll(dataSetDirectory, 0o755)
if err != nil {
errors = multierror.Append(err)
errors = cueError.Append(errors, cueError.Promote(err, "MkdirAll Failed"))
continue
}

Expand All @@ -140,7 +140,7 @@ func (s *Service) build() error {
pterm.Debug.Println(slug)
bytes, err := ioutil.ReadFile(path)
if err != nil {
return multierror.Append(err)
return cueError.Append(errors, cueError.Promote(err, "ReadFile Failed"))
}

// Loaders to get to YAML
Expand All @@ -159,30 +159,35 @@ func (s *Service) build() error {

err = yaml.Unmarshal(bytes, &istruct)
if err != nil {
return multierror.Append(err)
return cueError.Append(errors, cueError.Promote(err, "YAML Unmarshal Failed"))
}

record := make(map[string]interface{})
record[slug] = istruct

err = s.engine.Insert(dataSet, record)
if err != nil {
return multierror.Append(err)
return cueError.Append(errors, cueError.Promote(err, "CueDB Insert Failed"))
}

return err
},
)

if err != nil {
errors = multierror.Append(err)
errors = cueError.Append(errors, cueError.Promote(err, "Data Walk Errors"))
}
}

if s.ri {
err := s.engine.ReferentialIntegrity()
if err != nil {
errors = multierror.Append(err)
errors = cueError.Append(errors, cueError.Promote(err, "Referential Integrity Failed"))
for _, v := range cueError.Errors(errors) {
pterm.Error.ShowLineNumber = false
pterm.Error.Println(v)
pterm.Error.ShowLineNumber = true
}
}
}

Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
github.com/graphql-go/handler v0.2.3
github.com/h2non/filetype v1.1.1
github.com/hashicorp/go-hclog v0.16.2
github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/go-plugin v1.4.2
github.com/heimdalr/dag v1.0.1
github.com/lib/pq v1.9.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,13 @@ github.com/h2non/filetype v1.1.1 h1:xvOwnXKAckvtLWsN398qS9QhlxlnVXBjXBydK2/UFB4=
github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs=
github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-plugin v1.4.2 h1:yFvG3ufXXpqiMiZx9HLcaK3XbIqQ1WJFR/F1a2CuVw0=
github.com/hashicorp/go-plugin v1.4.2/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ=
Expand Down
16 changes: 13 additions & 3 deletions internal/cuedb/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"cuelang.org/go/cue"
"github.com/cueblox/blox"
"github.com/hashicorp/go-multierror"
"github.com/heimdalr/dag"
"github.com/pterm/pterm"
)
Expand Down Expand Up @@ -388,7 +387,17 @@ func (r *Engine) ReferentialIntegrity() error {
optional = "?"
}

value := r.CueContext.CompileString(fmt.Sprintf("{data: _\n%s: %s: %s%s: or([ for k, _ in data.%s {k}])}", dataSet.GetInlinePath(), dataSet.name, fields.Label(), optional, foreignTable.GetDataDirectory()))
var value cue.Value
switch fields.Value().IncompleteKind() {
case cue.StringKind:
value = r.CueContext.CompileString(fmt.Sprintf("{data: _\n%s: %s: %s%s: or([ for k, _ in data.%s {k}])}", dataSet.GetInlinePath(), dataSet.name, fields.Label(), optional, foreignTable.GetDataDirectory()))
case cue.ListKind:
value = r.CueContext.CompileString(fmt.Sprintf("{data: _\n%s: %s: %s%s: [...or([ for k, _ in data.%s {k}])]}", dataSet.GetInlinePath(), dataSet.name, fields.Label(), optional, foreignTable.GetDataDirectory()))
}

// #names: ["Paul", "Marcel", "cueckoo"]
// #validname: or(#names)
// #name: #validname | [#validname]
if value.Err() != nil {
return value.Err()
}
Expand All @@ -397,6 +406,7 @@ func (r *Engine) ReferentialIntegrity() error {
continue
}

// TODO: This behaviour should probably be deprecated soon
if strings.HasSuffix(fields.Label(), "_id") {
foreignTable, err := r.GetDataSet(strings.TrimSuffix(fields.Label(), "_id"))
if err != nil {
Expand All @@ -420,7 +430,7 @@ func (r *Engine) ReferentialIntegrity() error {

err := r.Database.Validate()
if err != nil {
return multierror.Prefix(err, "Referential Integrity Failed")
return err
}

return nil
Expand Down
1 change: 1 addition & 0 deletions internal/cuedb/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ func TestRelationshipParsing(t *testing.T) {
{cueLiteral: "name: string, profile: string", expected: []string{}},
{cueLiteral: "name: string, profile: string @relationship(Person)", expected: []string{"Person"}},
{cueLiteral: "name: string, profile: string, person: string @relationship(Person)", expected: []string{"Person"}},
{cueLiteral: "name: string, profile: string, people: [...string] @relationship(Person)", expected: []string{"Person"}},
}

cueContext := cuecontext.New()
Expand Down
12 changes: 0 additions & 12 deletions internal/cueutils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,9 @@ import (

"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/errors"
"github.com/hashicorp/go-multierror"
"github.com/pterm/pterm"
)

// UsefulError returns an error that is concatenated from
// multiple cue errors
func UsefulError(err error) error {
var usefulError error
for _, err := range errors.Errors(err) {
usefulError = multierror.Append(usefulError, err)
}
return usefulError
}

// GetAcceptedValues returns the values constraints
// for a cue node
func GetAcceptedValues(node ast.Node) ([]string, error) {
Expand Down