From 19932b77ccf3707f76733dc16fad715a03db7663 Mon Sep 17 00:00:00 2001 From: Denys Smirnov Date: Sat, 14 Apr 2018 18:06:00 +0200 Subject: [PATCH] gizmo: expose SaveOptional; resolves #702 --- docs/GizmoAPI.md | 10 ++++++++++ query/gizmo/gizmo_test.go | 8 ++++++++ query/gizmo/traversals.go | 30 ++++++++++++++++++++++++------ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/docs/GizmoAPI.md b/docs/GizmoAPI.md index 3fe878804..70c95cf24 100644 --- a/docs/GizmoAPI.md +++ b/docs/GizmoAPI.md @@ -513,6 +513,16 @@ g.V("").SaveInPredicates("pred").All() ``` +### `path.SaveOpt(*)` + +SaveOpt is the same as Save, but returns empty tags if predicate does not exists. + + +### `path.SaveOptR(*)` + +SaveOptR is the same as SaveOpt, but tags values via reverse predicate. + + ### `path.SaveOutPredicates(tag)` SaveOutPredicates tags the list of predicates that are pointing out from a node. diff --git a/query/gizmo/gizmo_test.go b/query/gizmo/gizmo_test.go index b087e592b..d60041cba 100644 --- a/query/gizmo/gizmo_test.go +++ b/query/gizmo/gizmo_test.go @@ -381,6 +381,14 @@ var testQueries = []struct { tag: "somecool", expect: []string{"cool_person", "cool_person", "cool_person", "smart_person", "smart_person"}, }, + { + message: "show a simple save optional", + query: ` + g.V("","").Out("").SaveOpt("", "somecool").All() + `, + tag: "somecool", + expect: []string{"cool_person", "cool_person"}, + }, { message: "show a simple saveR", query: ` diff --git a/query/gizmo/traversals.go b/query/gizmo/traversals.go index 4fe96352a..b487d870a 100644 --- a/query/gizmo/traversals.go +++ b/query/gizmo/traversals.go @@ -437,7 +437,7 @@ func (p *pathObject) has(call goja.FunctionCall, rev bool) goja.Value { } return p.newVal(np) } -func (p *pathObject) save(call goja.FunctionCall, rev bool) goja.Value { +func (p *pathObject) save(call goja.FunctionCall, rev, opt bool) goja.Value { args := exportArgs(call.Arguments) if len(args) > 2 || len(args) == 0 { return throwErr(p.s.vm, errArgCount{Got: len(args)}) @@ -461,10 +461,18 @@ func (p *pathObject) save(call goja.FunctionCall, rev bool) goja.Value { } } np := p.clonePath() - if rev { - np = np.SaveReverse(via, tag) + if opt { + if rev { + np = np.SaveOptionalReverse(via, tag) + } else { + np = np.SaveOptional(via, tag) + } } else { - np = np.Save(via, tag) + if rev { + np = np.SaveReverse(via, tag) + } else { + np = np.Save(via, tag) + } } return p.newVal(np) } @@ -486,12 +494,22 @@ func (p *pathObject) save(call goja.FunctionCall, rev bool) goja.Value { // // {"id" : "", "target": "" } // g.V("", "").Save("", "target").All() func (p *pathObject) Save(call goja.FunctionCall) goja.Value { - return p.save(call, false) + return p.save(call, false, false) } // SaveR is the same as Save, but tags values via reverse predicate. func (p *pathObject) SaveR(call goja.FunctionCall) goja.Value { - return p.save(call, true) + return p.save(call, true, false) +} + +// SaveOpt is the same as Save, but returns empty tags if predicate does not exists. +func (p *pathObject) SaveOpt(call goja.FunctionCall) goja.Value { + return p.save(call, false, true) +} + +// SaveOptR is the same as SaveOpt, but tags values via reverse predicate. +func (p *pathObject) SaveOptR(call goja.FunctionCall) goja.Value { + return p.save(call, true, true) } // Except removes all paths which match query from current path.