Expose LabelContext in gremlin
This commit is contained in:
parent
36d0f48d15
commit
283aca83c2
5 changed files with 28 additions and 4 deletions
|
|
@ -16,6 +16,7 @@ package path
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/google/cayley/graph"
|
"github.com/google/cayley/graph"
|
||||||
"github.com/google/cayley/graph/iterator"
|
"github.com/google/cayley/graph/iterator"
|
||||||
|
|
@ -161,25 +162,27 @@ func bothMorphism(tags []string, via ...interface{}) morphism {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func labelContextMorphism(via ...interface{}) morphism {
|
func labelContextMorphism(tags []string, via ...interface{}) morphism {
|
||||||
var path *Path
|
var path *Path
|
||||||
if len(via) == 0 {
|
if len(via) == 0 {
|
||||||
path = nil
|
path = nil
|
||||||
} else {
|
} else {
|
||||||
path = buildViaPath(nil, via...)
|
path = buildViaPath(nil, via...)
|
||||||
|
path = path.Tag(tags...)
|
||||||
}
|
}
|
||||||
return morphism{
|
return morphism{
|
||||||
Name: "label_context",
|
Name: "label_context",
|
||||||
Reversal: func(ctx *context) (morphism, *context) {
|
Reversal: func(ctx *context) (morphism, *context) {
|
||||||
out := ctx.copy()
|
out := ctx.copy()
|
||||||
ctx.labelSet = path
|
ctx.labelSet = path
|
||||||
return labelContextMorphism(via...), &out
|
return labelContextMorphism(tags, via...), &out
|
||||||
},
|
},
|
||||||
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
|
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
|
||||||
out := ctx.copy()
|
out := ctx.copy()
|
||||||
out.labelSet = path
|
out.labelSet = path
|
||||||
return in, &out
|
return in, &out
|
||||||
},
|
},
|
||||||
|
tags: tags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -364,7 +367,7 @@ func buildViaPath(qs graph.QuadStore, via ...interface{}) *Path {
|
||||||
case string:
|
case string:
|
||||||
return StartPath(qs, p)
|
return StartPath(qs, p)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprint("Invalid type passed to buildViaPath. ", p))
|
panic(fmt.Sprintln("Invalid type passed to buildViaPath.", reflect.TypeOf(v), p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var strings []string
|
var strings []string
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,14 @@ func (p *Path) Has(via interface{}, nodes ...string) *Path {
|
||||||
// LabelContext restricts the following operations (such as In, Out) to only
|
// LabelContext restricts the following operations (such as In, Out) to only
|
||||||
// traverse edges that match the given set of labels.
|
// traverse edges that match the given set of labels.
|
||||||
func (p *Path) LabelContext(via ...interface{}) *Path {
|
func (p *Path) LabelContext(via ...interface{}) *Path {
|
||||||
p.stack = append(p.stack, labelContextMorphism(via...))
|
p.stack = append(p.stack, labelContextMorphism(nil, via...))
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelContextWithTags is exactly like LabelContext, except it tags the value
|
||||||
|
// of the label used in the traversal with the tags provided.
|
||||||
|
func (p *Path) LabelContextWithTags(tags []string, via ...interface{}) *Path {
|
||||||
|
p.stack = append(p.stack, labelContextMorphism(tags, via...))
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,12 @@ func buildPathFromObject(obj *otto.Object) *path.Path {
|
||||||
return p.InPredicates()
|
return p.InPredicates()
|
||||||
case "OutPredicates":
|
case "OutPredicates":
|
||||||
return p.OutPredicates()
|
return p.OutPredicates()
|
||||||
|
case "LabelContext":
|
||||||
|
labels, tags, ok := getViaData(obj)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return p.LabelContextWithTags(tags, labels...)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprint("Unimplemented Gremlin function", gremlinType))
|
panic(fmt.Sprint("Unimplemented Gremlin function", gremlinType))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -278,6 +278,13 @@ var testQueries = []struct {
|
||||||
`,
|
`,
|
||||||
expect: []string{"are", "follows", "status"},
|
expect: []string{"are", "follows", "status"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
message: "traverse using LabelContext",
|
||||||
|
query: `
|
||||||
|
g.V("greg").LabelContext("smart_graph").Out("status").All()
|
||||||
|
`,
|
||||||
|
expect: []string{"smart_person"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func runQueryGetTag(g []quad.Quad, query string, tag string) []string {
|
func runQueryGetTag(g []quad.Quad, query string, tag string) []string {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ var traversals = []string{
|
||||||
"Difference",
|
"Difference",
|
||||||
"InPredicates",
|
"InPredicates",
|
||||||
"OutPredicates",
|
"OutPredicates",
|
||||||
|
"LabelContext",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wk *worker) embedTraversals(env *otto.Otto, obj *otto.Object) {
|
func (wk *worker) embedTraversals(env *otto.Otto, obj *otto.Object) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue