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

Commit

Permalink
fix: handle referential integrity for lists of references
Browse files Browse the repository at this point in the history
  • Loading branch information
rawkode committed Mar 2, 2022
1 parent fb7a205 commit 896dbe4
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 27 deletions.
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
17 changes: 14 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 @@ -419,8 +429,9 @@ 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

0 comments on commit 896dbe4

Please sign in to comment.