Example #1
0
func TestBasicLayer(t *testing.T) {
	store, err := cayley.NewMemoryGraph()
	assert.Nil(t, err, "Could not construct Cayley graph")

	gl := &GraphLayer{
		id:                compilerutil.NewUniqueId(),
		prefix:            "testprefix",
		cayleyStore:       store,
		nodeKindPredicate: "node-kind",
		nodeKindEnum:      TestNodeTypeTagged,
	}

	// Add some nodes and verify we can get them back.
	gm := gl.NewModifier()

	firstNode := gm.CreateNode(TestNodeTypeFirst)
	secondNode := gm.CreateNode(TestNodeTypeSecond)

	firstNodeAgain := gm.CreateNode(TestNodeTypeFirst)

	thirdNode := gm.CreateNode(TestNodeTypeThird)

	// Decorate the nodes with some predicates.
	firstNode.Decorate("coolpredicate", "is cool")
	secondNode.Decorate("coolpredicate", "is hot!")
	secondNode.Decorate("anotherpredicate", "is cool")

	firstNode.DecorateWith("numericpredicate", 1234)

	firstNodeAgain.Connect("thirdpredicate", thirdNode)

	gm.Apply()

	assert.Equal(t, firstNode.NodeId, gl.GetNode(firstNode.NodeId).NodeId)
	assert.Equal(t, secondNode.NodeId, gl.GetNode(secondNode.NodeId).NodeId)
	assert.Equal(t, firstNodeAgain.NodeId, gl.GetNode(firstNodeAgain.NodeId).NodeId)

	assert.Equal(t, "is cool", gl.GetNode(firstNode.NodeId).Get("coolpredicate"))
	assert.Equal(t, "is hot!", gl.GetNode(secondNode.NodeId).Get("coolpredicate"))
	assert.Equal(t, "is cool", gl.GetNode(secondNode.NodeId).Get("anotherpredicate"))

	assert.Equal(t, 1234, gl.GetNode(firstNode.NodeId).GetValue("numericpredicate").Int())

	// Search for some nodes via some simple queries.
	assert.Equal(t, firstNode.NodeId, gl.StartQuery().Has("coolpredicate", "is cool").GetNode().NodeId)
	assert.Equal(t, secondNode.NodeId, gl.StartQuery().Has("coolpredicate", "is hot!").GetNode().NodeId)

	// Search for nodes via kind.
	assert.Equal(t, 2, len(getNodes(gl.FindNodesOfKind(TestNodeTypeFirst).BuildNodeIterator())), "Expected 2 first nodes")
	assert.Equal(t, 1, len(getNodes(gl.FindNodesOfKind(TestNodeTypeSecond).BuildNodeIterator())), "Expected 1 second node")
	assert.Equal(t, 3, len(getNodes(gl.FindNodesOfKind(TestNodeTypeFirst, TestNodeTypeSecond).BuildNodeIterator())), "Expected 3 nodes in total")

	// Search outward from a node.
	firstNodeAgainReal := gl.GetNode(firstNodeAgain.NodeId)
	assert.Equal(t, thirdNode.NodeId, firstNodeAgainReal.StartQuery().Out("thirdpredicate").GetNode().NodeId)
}
Example #2
0
// CreateNode will create a new node in the graph layer.
func (gl *graphLayerModifierStruct) CreateNode(nodeKind TaggedValue) ModifiableGraphNode {
	// Create the new node.
	nodeId := compilerutil.NewUniqueId()

	node := ModifiableGraphNode{
		NodeId:   GraphNodeId(nodeId),
		Kind:     nodeKind,
		modifier: gl,
	}

	// Decorate the node with its kind.
	node.DecorateWithTagged(gl.layer.nodeKindPredicate, nodeKind)
	return node
}
func TestBasicGraph(t *testing.T) {
	store, err := cayley.NewMemoryGraph()
	assert.Nil(t, err, "Could not construct Cayley graph")

	gl := &GraphLayer{
		id:                compilerutil.NewUniqueId(),
		prefix:            "testprefix",
		cayleyStore:       store,
		nodeKindPredicate: "node-kind",
		nodeKindEnum:      TestNodeTypeTagged,
	}

	gm := gl.NewModifier()

	// Add some nodes.
	firstNode := gm.CreateNode(TestNodeTypeFirst)
	secondNode := gm.CreateNode(TestNodeTypeFirst)
	thirdNode := gm.CreateNode(TestNodeTypeFirst)
	fourthNode := gm.CreateNode(TestNodeTypeFirst)

	firstNode.Connect("some-predicate", secondNode)
	firstNode.Connect("another-predicate", thirdNode)

	thirdNode.Connect("some-predicate", fourthNode)

	thirdNode.Decorate("some-other-predicate", "cool-value")
	thirdNode.DecorateWithTagged("some-tagged-value", TestTaggedFirstValue)

	gm.Apply()

	// Walk outward.
	firstFound := getNodes(firstNode.AsNode().OutgoingNodeIterator())
	if !assert.Equal(t, 2, len(firstFound), "Expected 2 nodes found off of the first node") {
		return
	}

	secondFound := getNodes(secondNode.AsNode().OutgoingNodeIterator())
	if !assert.Equal(t, 0, len(secondFound), "Expected 0 nodes found off of the second node") {
		return
	}

	thirdFound := getNodes(thirdNode.AsNode().OutgoingNodeIterator())
	if !assert.Equal(t, 1, len(thirdFound), "Expected 1 node found off of the third node") {
		return
	}
}
Example #4
0
// BuildNodeIterator returns an iterator over the filtered query.
func (fq *FilteredQuery) BuildNodeIterator(predicates ...Predicate) NodeIterator {
	// Build an iterator to collect the IDs matching the inner query.
	it := fq.query.BuildNodeIterator()
	if !it.Next() {
		return EmptyIterator{}
	}

	// Note that it.Next() is called in the check above, so we call it at the
	// *end* of each of the loop iterations. This ensure that we don't allocate
	// the slice unless absolutely necessary.
	var nodeIds = make([]GraphNodeId, 0, 16)
	for {
		nodeIds = append(nodeIds, it.Node().NodeId)
		if !it.Next() {
			break
		}
	}

	// Otherwise, create a new query starting from the nodes found and send it
	// to the filtering function.
	fullKindPredicate := fq.query.layer.getPrefixedPredicate(fq.query.layer.nodeKindPredicate)
	markId := compilerutil.NewUniqueId()
	subQuery := fq.query.layer.StartQueryFromNodes(nodeIds...).mark(markId).save(fullKindPredicate, markId+"-kind")
	filteredQuery := fq.filter(subQuery)

	// Build an iterator over the filtered query.
	fit := filteredQuery.BuildNodeIterator()
	if !fit.Next() {
		return EmptyIterator{}
	}

	// Collect the filtered nodes.
	var filtered = make([]GraphNode, 0, len(nodeIds))
	for {
		nodeId := valueToNodeId(fit.getMarked(markId))
		kindValue := fit.getMarked(markId + "-kind")
		filtered = append(filtered, GraphNode{nodeId, kindValue, fq.query.layer})
		if !fit.Next() {
			break
		}
	}

	return &nodeReturnIterator{fq.query.layer, filtered, -1}
}
Example #5
0
func TestFilteringViaClientQuery(t *testing.T) {
	store, err := cayley.NewMemoryGraph()
	assert.Nil(t, err, "Could not construct Cayley graph")

	gl := &GraphLayer{
		id:                compilerutil.NewUniqueId(),
		prefix:            "testprefix",
		cayleyStore:       store,
		nodeKindPredicate: "node-kind",
		nodeKindEnum:      TestNodeTypeTagged,
	}

	gm := gl.NewModifier()

	// Add some nodes.
	rootNodeOne := gm.CreateNode(TestNodeTypeFirst)
	rootNodeTwo := gm.CreateNode(TestNodeTypeFirst)
	childNodeOne := gm.CreateNode(TestNodeTypeSecond)
	childNodeTwo := gm.CreateNode(TestNodeTypeSecond)

	rootNodeOne.Decorate("is-root", "true")
	rootNodeTwo.Decorate("is-root", "true")

	childNodeOne.DecorateWith("child-id", 1)
	childNodeTwo.DecorateWith("child-id", 2)

	rootNodeOne.Connect("has-child", childNodeOne)
	rootNodeTwo.Connect("has-child", childNodeTwo)

	gm.Apply()

	// Find the root node whose child has an ID of 2.
	filter := func(q GraphQuery) Query {
		return q.Out("has-child").HasWhere("child-id", WhereGTE, 2)
	}

	result, found := gl.StartQuery().Has("is-root", "true").FilterBy(filter).TryGetNode()
	assert.True(t, found, "Expected node")
	assert.Equal(t, rootNodeTwo.NodeId, result.NodeId, "Expected second node")
}
Example #6
0
func createClientQueryTestLayer(t *testing.T) *GraphLayer {
	store, err := cayley.NewMemoryGraph()
	assert.Nil(t, err, "Could not construct Cayley graph")

	gl := &GraphLayer{
		id:                compilerutil.NewUniqueId(),
		prefix:            "testprefix",
		cayleyStore:       store,
		nodeKindPredicate: "node-kind",
		nodeKindEnum:      TestNodeTypeTagged,
	}

	gm := gl.NewModifier()

	// Add some nodes.
	firstNode := gm.CreateNode(TestNodeTypeFirst)
	secondNode := gm.CreateNode(TestNodeTypeFirst)
	thirdNode := gm.CreateNode(TestNodeTypeFirst)
	fourthNode := gm.CreateNode(TestNodeTypeFirst)

	firstNode.Decorate("test-id", "first")
	secondNode.Decorate("test-id", "second")
	thirdNode.Decorate("test-id", "third")
	fourthNode.Decorate("test-id", "fourth")

	firstNode.Decorate("loves", "cake")
	secondNode.Decorate("loves", "cake")
	thirdNode.Decorate("loves", "pie")
	fourthNode.Decorate("loves", "pie")

	firstNode.DecorateWith("calories", 10)
	secondNode.DecorateWith("calories", 100)
	thirdNode.DecorateWith("calories", 120)
	fourthNode.DecorateWith("calories", 200)

	gm.Apply()

	return gl
}
Example #7
0
func TestBasicQuery(t *testing.T) {
	store, err := cayley.NewMemoryGraph()
	assert.Nil(t, err, "Could not construct Cayley graph")

	gl := &GraphLayer{
		id:                compilerutil.NewUniqueId(),
		prefix:            "testprefix",
		cayleyStore:       store,
		nodeKindPredicate: "node-kind",
		nodeKindEnum:      TestNodeTypeTagged,
	}

	// Add some nodes and verify some queries.
	gm := gl.NewModifier()

	firstNode := gm.CreateNode(TestNodeTypeFirst)
	thirdNode := gm.CreateNode(TestNodeTypeThird)

	secondNode1 := gm.CreateNode(TestNodeTypeSecond)
	secondNode2 := gm.CreateNode(TestNodeTypeSecond)

	firstNode.Decorate("name", "first")
	thirdNode.Decorate("name", "third")
	secondNode1.Decorate("name", "second")
	secondNode2.Decorate("name", "second")

	firstNode.Connect("first-to-second", secondNode1)
	firstNode.Connect("first-to-third", thirdNode)
	firstNode.Connect("first-to-second", secondNode2)

	secondNode2.Connect("second-to-third", thirdNode)

	gm.Apply()

	// Second nodes from first (expected 2)
	r := getNodes(gl.StartQuery(firstNode.NodeId).Out("first-to-second").BuildNodeIterator())
	if !assert.Equal(t, 2, len(r), "Expected 2 nodes in iterator") {
		return
	}

	// Third nodes from first (expected 1)
	r = getNodes(gl.StartQuery(firstNode.NodeId).Out("first-to-third").BuildNodeIterator())
	if !assert.Equal(t, 1, len(r), "Expected 1 node in iterator") {
		return
	}

	// Second nodes from first as type third (expected 0)
	r = getNodes(gl.StartQuery(firstNode.NodeId).Out("first-to-second").IsKind(TestNodeTypeThird).BuildNodeIterator())
	if !assert.Equal(t, 0, len(r), "Expected no nodes in iterator") {
		return
	}

	// Second nodes from first (expected 2)
	r = getNodes(gl.StartQuery(firstNode.NodeId).Out("first-to-second").IsKind(TestNodeTypeSecond).BuildNodeIterator())
	if !assert.Equal(t, 2, len(r), "Expected 2 nodes in iterator") {
		return
	}

	// Third node into first.
	r = getNodes(gl.StartQuery(thirdNode.NodeId).In("first-to-third").BuildNodeIterator())
	if !assert.Equal(t, 1, len(r), "Expected 1 node in iterator") {
		return
	}

	// Third node into second into first.
	r = getNodes(gl.StartQuery(thirdNode.NodeId).In("second-to-third").In("first-to-second").BuildNodeIterator())
	if !assert.Equal(t, 1, len(r), "Expected 1 node in iterator") {
		return
	}

	// Second-by-name (expected 2)
	r = getNodes(gl.StartQuery("second").In("name").BuildNodeIterator())
	if !assert.Equal(t, 2, len(r), "Expected 2 nodes in iterator") {
		return
	}

	// Second-by-name to second to first (will return the first node twice).
	r = getNodes(gl.StartQuery("second").In("name").In("first-to-second").BuildNodeIterator())
	if !assert.Equal(t, 2, len(r), "Expected 2 nodes in iterator") {
		return
	}

	// Two outgoing paths.
	r = getNodes(gl.StartQuery("first").In("name").Out("first-to-second", "first-to-third").BuildNodeIterator())
	if !assert.Equal(t, 3, len(r), "Expected 3 nodes in iterator") {
		return
	}

	firstNodeReal := firstNode.AsNode()
	r = getNodes(firstNodeReal.StartQuery().Out("first-to-second", "first-to-third").BuildNodeIterator())
	if !assert.Equal(t, 3, len(r), "Expected 3 nodes in iterator") {
		return
	}

	// Two incoming paths.
	r = getNodes(gl.StartQuery("third").In("name").In("first-to-third", "second-to-third").BuildNodeIterator())
	if !assert.Equal(t, 2, len(r), "Expected 2 nodes in iterator") {
		return
	}

	thirdNodeReal := thirdNode.AsNode()
	r = getNodes(thirdNodeReal.StartQuery().In("first-to-third", "second-to-third").BuildNodeIterator())
	if !assert.Equal(t, 2, len(r), "Expected 2 nodes in iterator") {
		return
	}
}