func buildIteratorTree(tree *peg.ExpressionTree, ts graph.TripleStore) graph.Iterator { switch tree.Name { case "Start": return buildIteratorTree(tree.Children[0], ts) case "NodeIdentifier": var out graph.Iterator nodeID := getIdentString(tree) if tree.Children[0].Name == "Variable" { allIt := ts.GetNodesAllIterator() allIt.AddTag(nodeID) out = allIt } else { n := nodeID if tree.Children[0].Children[0].Name == "ColonIdentifier" { n = nodeID[1:] } fixed := ts.MakeFixed() fixed.AddValue(ts.GetIdFor(n)) out = fixed } return out case "PredIdentifier": i := 0 if tree.Children[0].Name == "Reverse" { //Taken care of below i++ } it := buildIteratorTree(tree.Children[i], ts) lto := graph.NewLinksToIterator(ts, it, "p") return lto case "RootConstraint": constraintCount := 0 and := graph.NewAndIterator() for _, c := range tree.Children { switch c.Name { case "NodeIdentifier": fallthrough case "Constraint": it := buildIteratorTree(c, ts) and.AddSubIterator(it) constraintCount++ continue default: continue } } return and case "Constraint": var hasa *graph.HasaIterator topLevelDir := "s" subItDir := "o" subAnd := graph.NewAndIterator() isOptional := false for _, c := range tree.Children { switch c.Name { case "PredIdentifier": if c.Children[0].Name == "Reverse" { topLevelDir = "o" subItDir = "s" } it := buildIteratorTree(c, ts) subAnd.AddSubIterator(it) continue case "PredicateKeyword": switch c.Children[0].Name { case "OptionalKeyword": isOptional = true } case "NodeIdentifier": fallthrough case "RootConstraint": it := buildIteratorTree(c, ts) l := graph.NewLinksToIterator(ts, it, subItDir) subAnd.AddSubIterator(l) continue default: continue } } hasa = graph.NewHasaIterator(ts, subAnd, topLevelDir) if isOptional { optional := graph.NewOptionalIterator(hasa) return optional } return hasa default: return &graph.NullIterator{} } panic("Not reached") }
func (q *Query) buildResultIterator(path Path) graph.Iterator { all := q.ses.ts.GetNodesAllIterator() all.AddTag(string(path)) return graph.NewOptionalIterator(all) }
func (q *Query) buildIteratorTreeMapInternal(query map[string]interface{}, path Path) (graph.Iterator, error) { it := graph.NewAndIterator() it.AddSubIterator(q.ses.ts.GetNodesAllIterator()) var err error err = nil outputStructure := make(map[string]interface{}) for key, subquery := range query { optional := false outputStructure[key] = nil reverse := false pred := key if strings.HasPrefix(pred, "@") { i := strings.Index(pred, ":") if i != -1 { pred = pred[(i + 1):] } } if strings.HasPrefix(pred, "!") { reverse = true pred = strings.TrimPrefix(pred, "!") } // Other special constructs here var subit graph.Iterator if key == "id" { subit, optional, err = q.buildIteratorTreeInternal(subquery, path.Follow(key)) if err != nil { return nil, err } } else { var builtIt graph.Iterator builtIt, optional, err = q.buildIteratorTreeInternal(subquery, path.Follow(key)) if err != nil { return nil, err } subAnd := graph.NewAndIterator() predFixed := q.ses.ts.MakeFixed() predFixed.AddValue(q.ses.ts.GetIdFor(pred)) subAnd.AddSubIterator(graph.NewLinksToIterator(q.ses.ts, predFixed, graph.Predicate)) if reverse { lto := graph.NewLinksToIterator(q.ses.ts, builtIt, graph.Subject) subAnd.AddSubIterator(lto) hasa := graph.NewHasaIterator(q.ses.ts, subAnd, graph.Object) subit = hasa } else { lto := graph.NewLinksToIterator(q.ses.ts, builtIt, graph.Object) subAnd.AddSubIterator(lto) hasa := graph.NewHasaIterator(q.ses.ts, subAnd, graph.Subject) subit = hasa } } if optional { it.AddSubIterator(graph.NewOptionalIterator(subit)) } else { it.AddSubIterator(subit) } } if err != nil { return nil, err } q.queryStructure[path] = outputStructure return it, nil }