Beispiel #1
0
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")
}
Beispiel #2
0
func (q *Query) buildResultIterator(path Path) graph.Iterator {
	all := q.ses.ts.GetNodesAllIterator()
	all.AddTag(string(path))
	return graph.NewOptionalIterator(all)
}
Beispiel #3
0
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
}