Description
I am trying to build up an ontology of a service, its endpoint and a TLS configuration and trying to persist it into Cayley and then load it again. If I try to load it again into objects, there seems to be some kind of type confusion between objects on depth 0 and depth 1, resulting into the crash below.
package main
import (
"context"
"fmt"
"log"
"math/rand"
"github.com/cayleygraph/cayley"
"github.com/cayleygraph/cayley/graph"
"github.com/cayleygraph/cayley/schema"
"github.com/cayleygraph/quad"
"github.com/cayleygraph/quad/voc"
)
type TlsConfiguration struct {
rdfType struct{} `quad:"@type > ex:TlsConfig"`
Version string `quad:"ex:version"`
}
type HttpEndpoint struct {
rdfType struct{} `quad:"@type > ex:Http"`
URL string `quad:"ex:url"`
TlsConfig TlsConfiguration `quad:"ex:tls"`
}
type Category struct {
Name string `quad:"ex:name"`
}
type Service struct {
rdfType struct{} `quad:"@type > ex:Service"`
ID quad.IRI `json:"@id"`
HttpEndpoint HttpEndpoint `quad:"ex:http"`
Category Category `quad:"ex:category"`
}
func main() {
store, err := cayley.NewMemoryGraph()
if err != nil {
log.Fatalln(err)
}
voc.RegisterPrefix("ex:", "https://example.io")
sch := schema.NewConfig()
// Override a function to generate IDs. Can be changed to generate UUIDs, for example.
sch.GenerateID = func(_ interface{}) quad.Value {
return quad.BNode(fmt.Sprintf("node%d", rand.Intn(1000)))
}
qw := graph.NewWriter(store)
s1 := &Service{
ID: quad.IRI("s1"),
HttpEndpoint: HttpEndpoint{
URL: "https://example.io",
TlsConfig: TlsConfiguration{
Version: "1.2",
},
},
Category: Category{Name: "An example service"},
}
sch.WriteAsQuads(qw, s1)
s2 := &Service{
ID: quad.IRI("s2"),
HttpEndpoint: HttpEndpoint{
URL: "https://cayley.io",
TlsConfig: TlsConfiguration{
Version: "1.3",
},
},
Category: Category{Name: "A graph service"},
}
sch.WriteAsQuads(qw, s2)
qw.Close()
// Print quads
fmt.Println("\nquads:")
it := store.QuadsAllIterator().Iterate()
defer it.Close()
for it.Next(context.TODO()) {
fmt.Println(store.Quad(it.Result()))
}
var services []Service
sch.LoadToDepth(context.TODO(), store, &services, 1) // depth=0 will work, 1 will crash
for _, v := range services {
fmt.Printf("%+v\n", v)
}
}
Steps to reproduce the issue:
- Build up a schema with objects on depth 0 and depth 1
- Store it
- Load it
Received results:
<s1> -- <rdf:type> -> <ex:Actor>
_:node81 -- <rdf:type> -> <ex:Http>
_:node81 -- <ex:url> -> "https://example.io"
_:node887 -- <rdf:type> -> <ex:TlsConfig>
_:node887 -- <ex:version> -> "1.2"
_:node81 -- <ex:tls> -> _:node887
<s1> -- <ex:http> -> _:node81
_:node847 -- <ex:name> -> "An example service"
<s1> -- <ex:category> -> _:node847
<s2> -- <rdf:type> -> <ex:Actor>
_:node59 -- <rdf:type> -> <ex:Http>
_:node59 -- <ex:url> -> "https://cayley.io"
_:node81 -- <rdf:type> -> <ex:TlsConfig>
_:node81 -- <ex:version> -> "1.3"
_:node59 -- <ex:tls> -> _:node81
<s2> -- <ex:http> -> _:node59
_:node318 -- <ex:name> -> "A graph service"
<s2> -- <ex:category> -> _:node318
panic: reflect.Set: value of type main.HttpEndpoint is not assignable to type main.TlsConfiguration
goroutine 1 [running]:
reflect.Value.assignTo(0x100505fc0, 0x140001468a0, 0x199, 0x1004ce012, 0xb, 0x100500a60, 0x0, 0x0, 0x0, 0x0)
/opt/homebrew/Cellar/go/1.16.3/libexec/src/reflect/value.go:2451 +0x3f0
reflect.Value.Set(0x100500a60, 0x140001055d0, 0x199, 0x100505fc0, 0x140001468a0, 0x199)
/opt/homebrew/Cellar/go/1.16.3/libexec/src/reflect/value.go:1564 +0xa4
github.com/cayleygraph/cayley/schema.(*loader).loadIteratorToDepth(0x14000108a20, 0x100520230, 0x14000181b30, 0x100500a60, 0x140001055d0, 0x199, 0x0, 0x100520770, 0x140001217e8, 0x0, ...)
/Users/oxisto/go/pkg/mod/github.com/cayleygraph/[email protected]/schema/loader.go:470 +0x790
github.com/cayleygraph/cayley/schema.(*loader).loadToValue(0x14000108a20, 0x100520230, 0x14000181800, 0x100505fc0, 0x14000147320, 0x199, 0x1, 0x1400018ac48, 0x0, 0x0, ...)
/Users/oxisto/go/pkg/mod/github.com/cayleygraph/[email protected]/schema/loader.go:372 +0xe08
github.com/cayleygraph/cayley/schema.(*loader).loadIteratorToDepth(0x14000108a20, 0x100520230, 0x14000181800, 0x100505fc0, 0x14000147320, 0x199, 0x1, 0x100520770, 0x140001213f8, 0x0, ...)
/Users/oxisto/go/pkg/mod/github.com/cayleygraph/[email protected]/schema/loader.go:511 +0xd58
github.com/cayleygraph/cayley/schema.(*loader).loadToValue(0x14000108a20, 0x100520230, 0x140001096e0, 0x10050b840, 0x14000182780, 0x199, 0x2, 0x1400018b848, 0x0, 0x0, ...)
/Users/oxisto/go/pkg/mod/github.com/cayleygraph/[email protected]/schema/loader.go:372 +0xe08
github.com/cayleygraph/cayley/schema.(*loader).loadIteratorToDepth(0x14000108a20, 0x100520230, 0x140001096e0, 0x1004ef100, 0x140001203f0, 0x197, 0x2, 0x0, 0x0, 0x0, ...)
/Users/oxisto/go/pkg/mod/github.com/cayleygraph/[email protected]/schema/loader.go:511 +0xd58
github.com/cayleygraph/cayley/schema.(*Config).LoadIteratorToDepth(0x1400012c0c0, 0x1005201f8, 0x1400010e008, 0x100521398, 0x14000146000, 0x1004ea340, 0x140001203f0, 0x16, 0x2, 0x0, ...)
/Users/oxisto/go/pkg/mod/github.com/cayleygraph/[email protected]/schema/loader.go:142 +0xa8
github.com/cayleygraph/cayley/schema.(*Config).LoadToDepth(0x1400012c0c0, 0x1005201f8, 0x1400010e008, 0x100521398, 0x14000146000, 0x1004ea340, 0x140001203f0, 0x1, 0x0, 0x0, ...)
/Users/oxisto/go/pkg/mod/github.com/cayleygraph/[email protected]/schema/loader.go:116 +0x240
main.main()
/Users/oxisto/Downloads/cayley-test/main.go:95 +0x750
Expected results:
I expect it to work - or at least give me a proper error message why it does not.
Output of cayley version
or commit hash:
github.com/cayleygraph/cayley v0.7.7-0.20210518204410-08381efb7f81
Environment details:
Backend database: in-memory