123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651 |
- /*
- * EliasDB
- *
- * Copyright 2016 Matthias Ladkau. All rights reserved.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
- package interpreter
- import (
- "errors"
- "fmt"
- "testing"
- "devt.de/krotik/eliasdb/eql/parser"
- "devt.de/krotik/eliasdb/graph"
- "devt.de/krotik/eliasdb/graph/data"
- "devt.de/krotik/eliasdb/graph/graphstorage"
- "devt.de/krotik/eliasdb/storage"
- )
- func TestSources(t *testing.T) {
- gm, _ := filterGraph()
- rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
- res, err := getResult("get filtertest with ordering(ascending key)", `
- Labels: Filtertest Key, Val1, Val2, Val3
- Format: auto, auto, auto, auto
- Data: 1:n:key, 1:n:val1, 1:n:val2, 1:n:val3
- 1, test, Hans, foo
- 2, test1, Hans, foo
- 3, test2, Hans, foo
- 4, test3, Peter, foo
- 5, test4, Peter, foo
- 6, test5, Peter, foo
- 7, test6, Anna, foo
- 8, test7, Anna, foo
- 9, test8, Steve, foo
- 10, test9, Steve, foo
- 11, test10, Franz, foo
- 12, test11, Kevin, foo
- 13, test12, Kevin, foo
- 14, test13, Kevin, foo
- 15, test14, X1, foo
- 16, test15, X2, foo
- 17, test16, X3, foo
- 18, test17, X4, foo
- 19, test17, X5, foo
- `[1:], rt, false)
- if err != nil {
- t.Error(err)
- return
- }
- if q := res.Query(); q != `
- get filtertest
- with
- ordering(ascending key)`[1:] {
- t.Error("Unexpected result: ", q)
- return
- }
- if r := fmt.Sprint(res.Rows()); r != "[[1 test Hans foo] [2 test1 Hans foo] [3 test2 Hans foo] [4 test3 Peter foo] [5 test4 Peter foo] [6 test5 Peter foo] [7 test6 Anna foo] [8 test7 Anna foo] [9 test8 Steve foo] [10 test9 Steve foo] [11 test10 Franz foo] [12 test11 Kevin foo] [13 test12 Kevin foo] [14 test13 Kevin foo] [15 test14 X1 foo] [16 test15 X2 foo] [17 test16 X3 foo] [18 test17 X4 foo] [19 test17 X5 foo]]" {
- t.Error("Unexpected result: ", r)
- }
- if r := fmt.Sprint(res.RowSources()); r != "[[n:filtertest:1 n:filtertest:1 n:filtertest:1 n:filtertest:1] [n:filtertest:2 n:filtertest:2 n:filtertest:2 n:filtertest:2] [n:filtertest:3 n:filtertest:3 n:filtertest:3 n:filtertest:3] [n:filtertest:4 n:filtertest:4 n:filtertest:4 n:filtertest:4] [n:filtertest:5 n:filtertest:5 n:filtertest:5 n:filtertest:5] [n:filtertest:6 n:filtertest:6 n:filtertest:6 n:filtertest:6] [n:filtertest:7 n:filtertest:7 n:filtertest:7 n:filtertest:7] [n:filtertest:8 n:filtertest:8 n:filtertest:8 n:filtertest:8] [n:filtertest:9 n:filtertest:9 n:filtertest:9 n:filtertest:9] [n:filtertest:10 n:filtertest:10 n:filtertest:10 n:filtertest:10] [n:filtertest:11 n:filtertest:11 n:filtertest:11 n:filtertest:11] [n:filtertest:12 n:filtertest:12 n:filtertest:12 n:filtertest:12] [n:filtertest:13 n:filtertest:13 n:filtertest:13 n:filtertest:13] [n:filtertest:14 n:filtertest:14 n:filtertest:14 n:filtertest:14] [n:filtertest:15 n:filtertest:15 n:filtertest:15 n:filtertest:15] [n:filtertest:16 n:filtertest:16 n:filtertest:16 n:filtertest:16] [n:filtertest:17 n:filtertest:17 n:filtertest:17 n:filtertest:17] [n:filtertest:18 n:filtertest:18 n:filtertest:18 n:filtertest:18] [n:filtertest:19 n:filtertest:19 n:filtertest:19 n:filtertest:19]]" {
- t.Error("Unexpected result: ", r)
- }
- if res := res.CSV(); res != `
- Filtertest Key,Val1,Val2,Val3
- 1,test,Hans,foo
- 2,test1,Hans,foo
- 3,test2,Hans,foo
- 4,test3,Peter,foo
- 5,test4,Peter,foo
- 6,test5,Peter,foo
- 7,test6,Anna,foo
- 8,test7,Anna,foo
- 9,test8,Steve,foo
- 10,test9,Steve,foo
- 11,test10,Franz,foo
- 12,test11,Kevin,foo
- 13,test12,Kevin,foo
- 14,test13,Kevin,foo
- 15,test14,X1,foo
- 16,test15,X2,foo
- 17,test16,X3,foo
- 18,test17,X4,foo
- 19,test17,X5,foo
- `[1:] {
- t.Error("Unexpected result: ", res)
- }
- }
- func TestGrouping(t *testing.T) {
- gm, mgs := songGraphGroups()
- rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
- rt2 := NewLookupRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
- res, err := getResult("get group where key = 'Best' traverse :::", `
- Labels: Group Key, Key, Kind, Name
- Format: auto, auto, auto, auto
- Data: 1:n:key, 2:n:key, 2:n:kind, 2:n:name
- Best, Aria3, Song, Aria3
- Best, LoveSong3, Song, LoveSong3
- Best, MyOnlySong3, Song, MyOnlySong3
- Best, StrangeSong1, Song, StrangeSong1
- `[1:], rt, true)
- if err != nil {
- t.Error(err)
- return
- }
- if r := res.Rows(); r == nil || fmt.Sprint(r) != "[[Best Aria3 Song Aria3] [Best LoveSong3 Song LoveSong3] [Best MyOnlySong3 Song MyOnlySong3] [Best StrangeSong1 Song StrangeSong1]]" {
- t.Error("Unexpected result: ", r)
- return
- }
- if r := res.RowSources(); r == nil || fmt.Sprint(r) != "[[n:group:Best n:Song:Aria3 n:Song:Aria3 n:Song:Aria3] [n:group:Best n:Song:LoveSong3 n:Song:LoveSong3 n:Song:LoveSong3] [n:group:Best n:Song:MyOnlySong3 n:Song:MyOnlySong3 n:Song:MyOnlySong3] [n:group:Best n:Song:StrangeSong1 n:Song:StrangeSong1 n:Song:StrangeSong1]]" {
- t.Error("Unexpected result: ", r)
- return
- }
- // Inspect result
- if res.Header() != &res.SearchHeader {
- t.Error("Unexpected result")
- return
- }
- if res.Header().Data()[0] != res.SearchHeader.ColData[0] {
- t.Error("Unexpected result")
- return
- }
- if res.Header().Format()[0] != res.SearchHeader.ColFormat[0] {
- t.Error("Unexpected result")
- return
- }
- if res.Header().Labels()[0] != res.SearchHeader.ColLabels[0] {
- t.Error("Unexpected result")
- return
- }
- if res.Header().PrimaryKind() != res.SearchHeader.ResPrimaryKind {
- t.Error("Unexpected result")
- return
- }
- if res.Header().Partition() != res.SearchHeader.ResPartition {
- t.Error("Unexpected result")
- return
- }
- if res.RowCount() != 4 {
- t.Error("Unexpected result")
- return
- }
- if res.Row(2)[1] != res.Data[2][1] {
- t.Error("Unexpected result")
- return
- }
- if res.RowSource(2)[1] != res.Source[2][1] {
- t.Error("Unexpected result")
- return
- }
- if _, err := getResult("get Song from group Best", `
- Labels: Song Key, Song Name, Ranking
- Format: auto, auto, auto
- Data: 1:n:key, 1:n:name, 1:n:ranking
- Aria3, Aria3, 4
- LoveSong3, LoveSong3, 1
- MyOnlySong3, MyOnlySong3, 19
- StrangeSong1, StrangeSong1, 5
- `[1:], rt, true); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Song from group bbest", `
- Labels: Song Key, Song Name, Ranking
- Format: auto, auto, auto
- Data: 1:n:key, 1:n:name, 1:n:ranking
- `[1:], rt, true); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Song from group Best1", `
- Labels: Song Key, Song Name, Ranking
- Format: auto, auto, auto
- Data: 1:n:key, 1:n:name, 1:n:ranking
- `[1:], rt, true); err != nil {
- t.Error(err)
- return
- }
- // Test special error case with groups
- msm := mgs.StorageManager("main"+"group"+graph.StorageSuffixNodes, false).(*storage.MemoryStorageManager)
- msm.AccessMap[1] = storage.AccessCacheAndFetchError
- if _, err := getResult("get Song from group Best", "", rt, true); err.Error() !=
- "GraphError: Failed to access graph storage component (Slot not found (mystorage/maingroup.nodes - Location:1))" {
- t.Error(err)
- return
- }
- if _, err := getResult("lookup Song '1' from group Best", "", rt2, true); err.Error() !=
- "GraphError: Failed to access graph storage component (Slot not found (mystorage/maingroup.nodes - Location:1))" {
- t.Error(err)
- return
- }
- delete(msm.AccessMap, 1)
- if _, err := getResult("lookup Song 'non', 'Aria1', 'MyOnlySong3' from group Best", `
- Labels: Song Key, Song Name, Ranking
- Format: auto, auto, auto
- Data: 1:n:key, 1:n:name, 1:n:ranking
- MyOnlySong3, MyOnlySong3, 19
- `[1:], rt2, true); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("lookup Song 'non', 'Aria1', 'MyOnlySong3' from group bbest", `
- Labels: Song Key, Song Name, Ranking
- Format: auto, auto, auto
- Data: 1:n:key, 1:n:name, 1:n:ranking
- `[1:], rt2, true); err != nil {
- t.Error(err)
- return
- }
- }
- func TestWithFlags(t *testing.T) {
- gm, _ := songGraph()
- rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
- // Test simple query to get everything
- if _, err := getResult("get Author traverse :::", `
- Labels: Author Key, Author Name, Key, Kind, Name
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:kind, 2:n:name
- 000, John, Aria1, Song, Aria1
- 000, John, Aria2, Song, Aria2
- 000, John, Aria3, Song, Aria3
- 000, John, Aria4, Song, Aria4
- 123, Mike, DeadSong2, Song, DeadSong2
- 123, Mike, FightSong4, Song, FightSong4
- 123, Mike, LoveSong3, Song, LoveSong3
- 123, Mike, StrangeSong1, Song, StrangeSong1
- 456, Hans, MyOnlySong3, Song, MyOnlySong3
- `[1:], rt, true); err != nil {
- t.Error(err)
- return
- }
- // Test ordering
- if _, err := getResult("get Author traverse :::Song end with ordering(ascending Song:name)", `
- Labels: Author Key, Author Name, Song Key, Song Name, Ranking
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
- 000, John, Aria1, Aria1, 8
- 000, John, Aria2, Aria2, 2
- 000, John, Aria3, Aria3, 4
- 000, John, Aria4, Aria4, 18
- 123, Mike, DeadSong2, DeadSong2, 6
- 123, Mike, FightSong4, FightSong4, 3
- 123, Mike, LoveSong3, LoveSong3, 1
- 456, Hans, MyOnlySong3, MyOnlySong3, 19
- 123, Mike, StrangeSong1, StrangeSong1, 5
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse :::Song end with ordering(descending ranking)", `
- Labels: Author Key, Author Name, Song Key, Song Name, Ranking
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
- 456, Hans, MyOnlySong3, MyOnlySong3, 19
- 000, John, Aria4, Aria4, 18
- 000, John, Aria1, Aria1, 8
- 123, Mike, DeadSong2, DeadSong2, 6
- 123, Mike, StrangeSong1, StrangeSong1, 5
- 000, John, Aria3, Aria3, 4
- 123, Mike, FightSong4, FightSong4, 3
- 000, John, Aria2, Aria2, 2
- 123, Mike, LoveSong3, LoveSong3, 1
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse :::Song end with ordering(ascending Song:ranking)", `
- Labels: Author Key, Author Name, Song Key, Song Name, Ranking
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
- 123, Mike, LoveSong3, LoveSong3, 1
- 000, John, Aria2, Aria2, 2
- 123, Mike, FightSong4, FightSong4, 3
- 000, John, Aria3, Aria3, 4
- 123, Mike, StrangeSong1, StrangeSong1, 5
- 123, Mike, DeadSong2, DeadSong2, 6
- 000, John, Aria1, Aria1, 8
- 000, John, Aria4, Aria4, 18
- 456, Hans, MyOnlySong3, MyOnlySong3, 19
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse :::Song end with ordering(ascending 2:n:ranking)", `
- Labels: Author Key, Author Name, Song Key, Song Name, Ranking
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
- 123, Mike, LoveSong3, LoveSong3, 1
- 000, John, Aria2, Aria2, 2
- 123, Mike, FightSong4, FightSong4, 3
- 000, John, Aria3, Aria3, 4
- 123, Mike, StrangeSong1, StrangeSong1, 5
- 123, Mike, DeadSong2, DeadSong2, 6
- 000, John, Aria1, Aria1, 8
- 000, John, Aria4, Aria4, 18
- 456, Hans, MyOnlySong3, MyOnlySong3, 19
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse :Wrote::Song end show 1:n:name, 2:n:name, 2:e:number with ordering(descending Song:name, ascending Wrote:number)", `
- Labels: Name, Name, Number
- Format: auto, auto, auto
- Data: 1:n:name, 2:n:name, 2:e:number
- Mike, StrangeSong1, 1
- John, Aria1, 1
- Mike, DeadSong2, 2
- John, Aria2, 2
- Hans, MyOnlySong3, 3
- Mike, LoveSong3, 3
- John, Aria3, 3
- Mike, FightSong4, 4
- John, Aria4, 4
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- // Test empty traversal flag
- if _, err := getResult("get Author traverse :::Song where name = '123' end with nulltraversal(true)", `
- Labels: Author Key, Author Name, Song Key, Song Name, Ranking
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
- 123, Mike, <not set>, <not set>, <not set>
- 456, Hans, <not set>, <not set>, <not set>
- 000, John, <not set>, <not set>, <not set>
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse :::Song where name = '123' end", `
- Labels: Author Key, Author Name, Song Key, Song Name, Ranking
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- // Test filtering
- if _, err := getResult("get Author traverse :::Song where name = 'DeadSong2' end with nulltraversal(true), filtering(isnotnull Song:name)", `
- Labels: Author Key, Author Name, Song Key, Song Name, Ranking
- Format: auto, auto, auto, auto, auto
- Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
- 123, Mike, DeadSong2, DeadSong2, 6
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse :::Song end show Author:name with filtering(unique Author:name)", `
- Labels: Author Name
- Format: auto
- Data: 1:n:name
- Mike
- Hans
- John
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse :::Song end show Author:name with filtering(uniquecount Author:name)", `
- Labels: Author Name
- Format: auto
- Data: 1:n:name
- Mike (4)
- Hans (1)
- John (4)
- `[1:], rt, false); err != nil {
- t.Error(err)
- return
- }
- }
- func TestWithFlagsErrors(t *testing.T) {
- gm, _ := songGraph()
- rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
- if _, err := getResult("get Author traverse ::: end with filtering(unique 1:p:bla)", "", rt, false); err.Error() !=
- "EQL error in test: Invalid construct (Cannot determine column for with term: 1:p:bla) (Line:1 Pos:44)" {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse ::: end with ordering(ascending p:bla)", "", rt, false); err.Error() !=
- "EQL error in test: Invalid construct (Cannot determine column for with term: p:bla) (Line:1 Pos:43)" {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse ::: end with filtering(ascending p:bla)", "", rt, false); err.Error() !=
- "EQL error in test: Invalid construct (ascending) (Line:1 Pos:44)" {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse ::: end with ordering(unique p:bla)", "", rt, false); err.Error() !=
- "EQL error in test: Invalid construct (unique) (Line:1 Pos:43)" {
- t.Error(err)
- return
- }
- if _, err := getResult("get Author traverse ::: end with ascending(ascending p:bla)", "", rt, false); err.Error() !=
- "EQL error in test: Invalid construct (ascending) (Line:1 Pos:34)" {
- t.Error(err)
- return
- }
- }
- /*
- Helper function to run a search and check against a result.
- */
- func getResult(query string, expectedResult string, rt parser.RuntimeProvider, sort bool) (*SearchResult, error) {
- ast, err := parser.ParseWithRuntime("test", query, rt)
- if err != nil {
- return nil, err
- }
- res, err := ast.Runtime.Eval()
- if err != nil {
- return nil, err
- }
- if sort {
- res.(*SearchResult).StableSort()
- }
- if fmt.Sprint(res) != expectedResult {
- return nil, errors.New(fmt.Sprint("Unexpected search result:", res, err))
- }
- return res.(*SearchResult), nil
- }
- func songGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
- mgs := graphstorage.NewMemoryGraphStorage("mystorage")
- gm := graph.NewGraphManager(mgs)
- constructEdge := func(key string, node1 data.Node, node2 data.Node, number int) data.Edge {
- edge := data.NewGraphEdge()
- edge.SetAttr("key", key)
- edge.SetAttr("kind", "Wrote")
- edge.SetAttr(data.EdgeEnd1Key, node1.Key())
- edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
- edge.SetAttr(data.EdgeEnd1Role, "Author")
- edge.SetAttr(data.EdgeEnd1Cascading, true)
- edge.SetAttr(data.EdgeEnd2Key, node2.Key())
- edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
- edge.SetAttr(data.EdgeEnd2Role, "Song")
- edge.SetAttr(data.EdgeEnd2Cascading, false)
- edge.SetAttr("number", number)
- return edge
- }
- storeSong := func(node data.Node, name string, ranking int, number int) {
- node3 := data.NewGraphNode()
- node3.SetAttr("key", name)
- node3.SetAttr("kind", "Song")
- node3.SetAttr("name", name)
- node3.SetAttr("ranking", ranking)
- gm.StoreNode("main", node3)
- gm.StoreEdge("main", constructEdge(name, node, node3, number))
- }
- node0 := data.NewGraphNode()
- node0.SetAttr("key", "000")
- node0.SetAttr("kind", "Author")
- node0.SetAttr("name", "John")
- gm.StoreNode("main", node0)
- storeSong(node0, "Aria1", 8, 1)
- storeSong(node0, "Aria2", 2, 2)
- storeSong(node0, "Aria3", 4, 3)
- storeSong(node0, "Aria4", 18, 4)
- node1 := data.NewGraphNode()
- node1.SetAttr("key", "123")
- node1.SetAttr("kind", "Author")
- node1.SetAttr("name", "Mike")
- gm.StoreNode("main", node1)
- storeSong(node1, "LoveSong3", 1, 3)
- storeSong(node1, "FightSong4", 3, 4)
- storeSong(node1, "DeadSong2", 6, 2)
- storeSong(node1, "StrangeSong1", 5, 1)
- node2 := data.NewGraphNode()
- node2.SetAttr("key", "456")
- node2.SetAttr("kind", "Author")
- node2.SetAttr("name", "Hans")
- gm.StoreNode("main", node2)
- storeSong(node2, "MyOnlySong3", 19, 3)
- return gm, mgs.(*graphstorage.MemoryGraphStorage)
- }
- func songGraphGroups() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
- gm, mgs := songGraph()
- node0 := data.NewGraphNode()
- node0.SetAttr("key", "Best")
- node0.SetAttr("kind", GroupNodeKind)
- gm.StoreNode("main", node0)
- constructEdge := func(songkey string) data.Edge {
- edge := data.NewGraphEdge()
- edge.SetAttr("key", songkey)
- edge.SetAttr("kind", "Contains")
- edge.SetAttr(data.EdgeEnd1Key, node0.Key())
- edge.SetAttr(data.EdgeEnd1Kind, node0.Kind())
- edge.SetAttr(data.EdgeEnd1Role, "group")
- edge.SetAttr(data.EdgeEnd1Cascading, false)
- edge.SetAttr(data.EdgeEnd2Key, songkey)
- edge.SetAttr(data.EdgeEnd2Kind, "Song")
- edge.SetAttr(data.EdgeEnd2Role, "Song")
- edge.SetAttr(data.EdgeEnd2Cascading, false)
- return edge
- }
- gm.StoreEdge("main", constructEdge("LoveSong3"))
- gm.StoreEdge("main", constructEdge("Aria3"))
- gm.StoreEdge("main", constructEdge("MyOnlySong3"))
- gm.StoreEdge("main", constructEdge("StrangeSong1"))
- return gm, mgs
- }
- func dateGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
- mgs := graphstorage.NewMemoryGraphStorage("mystorage")
- gm := graph.NewGraphManager(mgs)
- node0 := data.NewGraphNode()
- node0.SetAttr("key", "000")
- node0.SetAttr("kind", "datetest")
- node0.SetAttr("name", "date1")
- node0.SetAttr("unix", 1349809255)
- node0.SetAttr("RFC3339_value", "2012-10-09T19:00:55Z")
- node0.SetAttr("naive_value", "2012-10-09")
- gm.StoreNode("main", node0)
- node1 := data.NewGraphNode()
- node1.SetAttr("key", "001")
- node1.SetAttr("kind", "datetest")
- node1.SetAttr("name", "date2")
- node1.SetAttr("unix", 1350061255)
- node1.SetAttr("RFC3339_value", "2012-10-12T19:00:55+02:00")
- node1.SetAttr("naive_value", "2012-10-12")
- gm.StoreNode("main", node1)
- return gm, mgs.(*graphstorage.MemoryGraphStorage)
- }
- func filterGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
- gm, mgs := songGraph()
- constructNode := func(key, val1, val2, val3 string) data.Node {
- node0 := data.NewGraphNode()
- node0.SetAttr("key", key)
- node0.SetAttr("kind", "filtertest")
- node0.SetAttr("val1", val1)
- node0.SetAttr("val2", val2)
- node0.SetAttr("val3", val3)
- return node0
- }
- gm.StoreNode("main", constructNode("1", "test", "Hans", "foo"))
- gm.StoreNode("main", constructNode("2", "test1", "Hans", "foo"))
- gm.StoreNode("main", constructNode("3", "test2", "Hans", "foo"))
- gm.StoreNode("main", constructNode("4", "test3", "Peter", "foo"))
- gm.StoreNode("main", constructNode("5", "test4", "Peter", "foo"))
- gm.StoreNode("main", constructNode("6", "test5", "Peter", "foo"))
- gm.StoreNode("main", constructNode("7", "test6", "Anna", "foo"))
- gm.StoreNode("main", constructNode("8", "test7", "Anna", "foo"))
- gm.StoreNode("main", constructNode("9", "test8", "Steve", "foo"))
- gm.StoreNode("main", constructNode("10", "test9", "Steve", "foo"))
- gm.StoreNode("main", constructNode("11", "test10", "Franz", "foo"))
- gm.StoreNode("main", constructNode("12", "test11", "Kevin", "foo"))
- gm.StoreNode("main", constructNode("13", "test12", "Kevin", "foo"))
- gm.StoreNode("main", constructNode("14", "test13", "Kevin", "foo"))
- gm.StoreNode("main", constructNode("15", "test14", "X1", "foo"))
- gm.StoreNode("main", constructNode("16", "test15", "X2", "foo"))
- gm.StoreNode("main", constructNode("17", "test16", "X3", "foo"))
- gm.StoreNode("main", constructNode("18", "test17", "X4", "foo"))
- gm.StoreNode("main", constructNode("19", "test17", "X5", "foo"))
- return gm, mgs
- }
|