func main() { // To see how most of this works, see hello_world -- this just add in a transaction store, err := cayley.NewMemoryGraph() if err != nil { log.Fatalln(err) } // Create a transaction of work to do // NOTE: the transaction is independent of the storage type, so comes from cayley rather than store t := cayley.NewTransaction() t.AddQuad(quad.Make("food", "is", "good", nil)) t.AddQuad(quad.Make("phrase of the day", "is of course", "Hello World!", nil)) t.AddQuad(quad.Make("cats", "are", "awesome", nil)) t.AddQuad(quad.Make("cats", "are", "scary", nil)) t.AddQuad(quad.Make("cats", "want to", "kill you", nil)) // Apply the transaction err = store.ApplyTransaction(t) if err != nil { log.Fatalln(err) } p := cayley.StartPath(store, quad.String("cats")).Out(quad.String("are")) err = p.Iterate(nil).EachValue(nil, func(v quad.Value) { fmt.Println("cats are", v.Native()) }) if err != nil { log.Fatalln(err) } }
// setupGraph initializes an in-memory Cayley graph and logging for an individual test. func setupGraph(t *testing.T) (*db.DB, *cayley.Handle, []map[string]interface{}) { tests.ResetLog() items, _, _, _, err := wirefix.Get() if err != nil { t.Fatalf("%s\tShould load item records from the fixture file : %v", tests.Failed, err) } t.Logf("%s\tShould load item records from the fixture file.", tests.Success) db, err := db.NewMGO(tests.Context, tests.TestSession) if err != nil { t.Fatalf("%s\tShould be able to get a Mongo session : %v", tests.Failed, err) } store, err := cayley.NewMemoryGraph() if err != nil { t.Fatalf("\t%s\tShould be able to create a new Cayley graph : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a new Cayley graph.", tests.Success) // Convert the items to maps. var itemMaps []map[string]interface{} for _, itm := range items { itemMap := map[string]interface{}{ "type": itm.Type, "item_id": itm.ID, "version": itm.Version, "data": itm.Data, } itemMaps = append(itemMaps, itemMap) } return db, store, itemMaps }
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) }
// NewGraph creates and returns a SerulianGraph rooted at the specified root source file. func NewGraph(rootSourceFilePath string) (*SerulianGraph, error) { // Load the graph database. store, err := cayley.NewMemoryGraph() if err != nil { return nil, fmt.Errorf("Could not load compiler graph: %v", err) } return &SerulianGraph{ RootSourceFilePath: rootSourceFilePath, cayleyStore: store, }, nil }
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 } }
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") }
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 }
func main() { // Create a brand new graph store, err := cayley.NewMemoryGraph() if err != nil { log.Fatalln(err) } store.AddQuad(quad.Make("phrase of the day", "is of course", "Hello World!", nil)) // Now we create the path, to get to our data p := cayley.StartPath(store, quad.String("phrase of the day")).Out(quad.String("is of course")) // Now we iterate over results. Arguments: // 1. Optional context used for cancellation. // 2. Quad store, but we can omit it because we have already built path with it. err = p.Iterate(nil).EachValue(nil, func(value quad.Value) { nativeValue := quad.NativeOf(value) // this converts RDF values to normal Go types fmt.Println(nativeValue) }) if err != nil { log.Fatalln(err) } }
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 } }