Skip to content
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.12

require (
github.com/badgerodon/peg v0.0.0-20130729175151-9e5f7f4d07ca
github.com/cayleygraph/quad v1.1.0
github.com/cayleygraph/quad v1.2.1
github.com/cockroachdb/apd v1.1.0 // indirect
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
github.com/coreos/bbolt v1.3.3 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/cayleygraph/quad v1.1.0 h1:w1nXAmn+nz07+qlw89dke9LwWkYpeX+OcvfTvGQRBpM=
github.com/cayleygraph/quad v1.1.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4=
github.com/cayleygraph/quad v1.2.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4=
github.com/cayleygraph/quad v1.2.1 h1:PqqP+F8BLICaAWoGvSlrx1U11pXEc2BBodmTv30uSLM=
github.com/cayleygraph/quad v1.2.1/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4=
github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
Expand Down
65 changes: 46 additions & 19 deletions internal/linkedql/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,33 @@ import (

"github.com/cayleygraph/cayley/query/linkedql"
"github.com/cayleygraph/quad"
"github.com/cayleygraph/quad/voc/owl"
"github.com/cayleygraph/quad/voc/rdf"
"github.com/cayleygraph/quad/voc/rdfs"
"github.com/cayleygraph/quad/voc/xsd"
)

var (
pathStep = reflect.TypeOf((*linkedql.PathStep)(nil)).Elem()
iteratorStep = reflect.TypeOf((*linkedql.IteratorStep)(nil)).Elem()
value = reflect.TypeOf((*quad.Value)(nil)).Elem()
operator = reflect.TypeOf((*linkedql.Operator)(nil)).Elem()
pathStep = reflect.TypeOf((*linkedql.PathStep)(nil)).Elem()
iteratorStep = reflect.TypeOf((*linkedql.IteratorStep)(nil)).Elem()
entityIdentifier = reflect.TypeOf((*linkedql.EntityIdentifier)(nil)).Elem()
value = reflect.TypeOf((*quad.Value)(nil)).Elem()
operator = reflect.TypeOf((*linkedql.Operator)(nil)).Elem()
propertyPath = reflect.TypeOf((*linkedql.PropertyPath)(nil)).Elem()
)

func typeToRange(t reflect.Type) string {
if t.Kind() == reflect.Slice {
return typeToRange(t.Elem())
}
// TODO: add XSD types to voc package
if t.Kind() == reflect.String {
return "xsd:string"
return xsd.String
}
if t.Kind() == reflect.Bool {
return "xsd:boolean"
return xsd.Boolean
}
if kind := t.Kind(); kind == reflect.Int64 || kind == reflect.Int {
return "xsd:int"
return xsd.Int
}
if t.Implements(pathStep) {
return linkedql.Prefix + "PathStep"
Expand All @@ -39,6 +43,12 @@ func typeToRange(t reflect.Type) string {
if t.Implements(value) {
return rdfs.Resource
}
if t.Implements(entityIdentifier) {
return owl.Thing
}
if t == propertyPath {
return linkedql.Prefix + "PropertyPath"
}
panic("Unexpected type " + t.String())
}

Expand Down Expand Up @@ -68,7 +78,7 @@ func newBlankNodeID() string {
func newSingleCardinalityRestriction(prop string) cardinalityRestriction {
return cardinalityRestriction{
ID: newBlankNodeID(),
Type: "owl:Restriction",
Type: owl.Restriction,
Cardinality: 1,
Property: identified{ID: prop},
}
Expand All @@ -77,9 +87,9 @@ func newSingleCardinalityRestriction(prop string) cardinalityRestriction {
// getOWLPropertyType for given kind of value type returns property OWL type
func getOWLPropertyType(kind reflect.Kind) string {
if kind == reflect.String || kind == reflect.Bool || kind == reflect.Int64 || kind == reflect.Int {
return "owl:DatatypeProperty"
return owl.DatatypeProperty
}
return "owl:ObjectProperty"
return owl.ObjectProperty
}

// property is used to declare a property
Expand Down Expand Up @@ -143,7 +153,7 @@ func newUnionOf(classes []string) unionOf {
}
return unionOf{
ID: newBlankNodeID(),
Type: "owl:Class",
Type: owl.Class,
List: newList(members),
}
}
Expand Down Expand Up @@ -233,7 +243,7 @@ func (g *generator) Generate() []byte {
}
var dom interface{}
if len(domains) == 1 {
dom = domains[0]
dom = identified{domains[0]}
} else {
dom = newUnionOf(domains)
}
Expand All @@ -250,15 +260,32 @@ func (g *generator) Generate() []byte {
Range: rng,
})
}
graph := []interface{}{
map[string]string{
"@id": linkedql.Prefix + "Step",
"@type": owl.Class,
},
map[string]interface{}{
"@id": linkedql.Prefix + "PathStep",
"@type": owl.Class,
rdfs.SubClassOf: identified{ID: linkedql.Prefix + "Step"},
},
map[string]interface{}{
"@id": linkedql.Prefix + "IteratorStep",
"@type": owl.Class,
rdfs.SubClassOf: identified{ID: linkedql.Prefix + "Step"},
},
}
graph = append(graph, g.out...)
data, err := json.Marshal(map[string]interface{}{
"@context": map[string]interface{}{
"rdf": map[string]string{"@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#"},
"rdfs": map[string]string{"@id": "http://www.w3.org/2000/01/rdf-schema#"},
"owl": map[string]string{"@id": "http://www.w3.org/2002/07/owl#"},
"xsd": map[string]string{"@id": "http://www.w3.org/2001/XMLSchema#"},
"linkedql": map[string]string{"@id": "http://cayley.io/linkedql#"},
"rdf": rdf.NS,
"rdfs": rdfs.NS,
"owl": owl.NS,
"xsd": xsd.NS,
"linkedql": linkedql.Namespace,
},
"@graph": g.out,
"@graph": graph,
})
if err != nil {
panic(err)
Expand Down
11 changes: 11 additions & 0 deletions query/linkedql/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package linkedql

import "fmt"

func formatMultiError(errors []error) error {
joinedErr := ""
for _, err := range errors {
joinedErr += "; " + err.Error()
}
return fmt.Errorf("Could not parse PropertyPath: %v", joinedErr)
}
44 changes: 19 additions & 25 deletions query/linkedql/iter_docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,45 @@ package linkedql
import (
"context"

"github.com/cayleygraph/cayley/graph/iterator"
"github.com/cayleygraph/cayley/graph/refs"
"github.com/cayleygraph/cayley/query"
"github.com/cayleygraph/cayley/query/path"
"github.com/cayleygraph/quad"
)

var _ query.Iterator = (*DocumentIterator)(nil)

type document = map[string]interface{}
type properties = map[string][]interface{}
type idToProperties = map[quad.Value]properties

// DocumentIterator is an iterator of documents from the graph
type DocumentIterator struct {
qs refs.Namer
path *path.Path
tagsIt *TagsIterator
ids []quad.Value
scanner iterator.Scanner
properties map[quad.Value]map[string][]quad.Value
properties idToProperties
current int
}

// NewDocumentIterator returns a new DocumentIterator for a QuadStore and Path.
func NewDocumentIterator(qs refs.Namer, p *path.Path) *DocumentIterator {
return &DocumentIterator{qs: qs, path: p, current: -1}
func NewDocumentIterator(valueIt *ValueIterator) *DocumentIterator {
tagsIt := &TagsIterator{valueIt: valueIt, selected: nil}
return &DocumentIterator{tagsIt: tagsIt, current: -1}
}

// Next implements query.Iterator.
func (it *DocumentIterator) Next(ctx context.Context) bool {
if it.properties == nil {
it.properties = make(map[quad.Value]map[string][]quad.Value)
it.scanner = it.path.BuildIterator(ctx).Iterate()
for it.scanner.Next(ctx) {
id := it.qs.NameOf(it.scanner.Result())
it.properties = make(idToProperties)
for it.tagsIt.Next(ctx) {
id := it.tagsIt.valueIt.Value()
tags := it.tagsIt.getTags()
it.ids = append(it.ids, id)

tags := make(map[string]refs.Ref)
it.scanner.TagResults(tags)

for k, ref := range tags {
value := it.qs.NameOf(ref)
for k, v := range tags {
m, ok := it.properties[id]
if !ok {
m = make(map[string][]quad.Value)
m = make(properties)
it.properties[id] = m
}
m[k] = append(m[k], value)
m[k] = append(m[k], v)
}
}
}
Expand All @@ -65,6 +58,7 @@ func (it *DocumentIterator) Result() interface{} {
return nil
}
id := it.ids[it.current]
// FIXME(iddan): don't cast to string when collation is Raw
var sid string
switch val := id.(type) {
case quad.IRI:
Expand All @@ -83,16 +77,16 @@ func (it *DocumentIterator) Result() interface{} {

// Err implements query.Iterator.
func (it *DocumentIterator) Err() error {
if it.scanner == nil {
if it.tagsIt == nil {
return nil
}
return it.scanner.Err()
return it.tagsIt.Err()
}

// Close implements query.Iterator.
func (it *DocumentIterator) Close() error {
if it.scanner == nil {
if it.tagsIt == nil {
return nil
}
return it.scanner.Close()
return it.tagsIt.Close()
}
18 changes: 12 additions & 6 deletions query/linkedql/iter_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/cayleygraph/cayley/graph/refs"
"github.com/cayleygraph/cayley/query"
"github.com/cayleygraph/quad"
"github.com/cayleygraph/quad/jsonld"
)

var _ query.Iterator = (*TagsIterator)(nil)
Expand All @@ -22,24 +22,30 @@ func (it *TagsIterator) Next(ctx context.Context) bool {
return it.valueIt.Next(ctx)
}

// Result implements query.Iterator.
func (it *TagsIterator) Result() interface{} {
func (it *TagsIterator) getTags() map[string]interface{} {
refTags := make(map[string]refs.Ref)
it.valueIt.scanner.TagResults(refTags)

tags := make(map[string]quad.Value)
tags := make(map[string]interface{})
// FIXME(iddan): only convert when collation is JSON/JSON-LD, leave as Ref otherwise
if it.selected != nil {
for _, tag := range it.selected {
tags[tag] = it.valueIt.namer.NameOf(refTags[tag])
tags[tag] = jsonld.FromValue(it.valueIt.getName(refTags[tag]))
}
} else {
for tag, ref := range refTags {
tags[tag] = it.valueIt.namer.NameOf(ref)
tags[tag] = jsonld.FromValue(it.valueIt.getName(ref))
}
}

return tags
}

// Result implements query.Iterator.
func (it *TagsIterator) Result() interface{} {
return it.getTags()
}

// Err implements query.Iterator.
func (it *TagsIterator) Err() error {
return it.valueIt.Err()
Expand Down
19 changes: 16 additions & 3 deletions query/linkedql/iter_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/cayleygraph/cayley/graph/refs"
"github.com/cayleygraph/cayley/query"
"github.com/cayleygraph/cayley/query/path"
"github.com/cayleygraph/quad"
"github.com/cayleygraph/quad/jsonld"
)

var _ query.Iterator = (*ValueIterator)(nil)
Expand Down Expand Up @@ -42,12 +44,23 @@ func (it *ValueIterator) Next(ctx context.Context) bool {
return it.scanner.Next(ctx)
}

// Result implements query.Iterator.
func (it *ValueIterator) Result() interface{} {
func (it *ValueIterator) getName(ref refs.Ref) quad.Value {
name := it.namer.NameOf(ref)
return name
}

// Value returns the current value
func (it *ValueIterator) Value() quad.Value {
if it.scanner == nil {
return nil
}
return it.namer.NameOf(it.scanner.Result())
return it.getName(it.scanner.Result())
}

// Result implements query.Iterator.
func (it *ValueIterator) Result() interface{} {
// FIXME(iddan): only convert when collation is JSON/JSON-LD, leave as Ref otherwise
return jsonld.FromValue(it.Value())
}

// Err implements query.Iterator.
Expand Down
Loading