searchresult_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package interpreter
  11. import (
  12. "errors"
  13. "fmt"
  14. "testing"
  15. "devt.de/krotik/eliasdb/eql/parser"
  16. "devt.de/krotik/eliasdb/graph"
  17. "devt.de/krotik/eliasdb/graph/data"
  18. "devt.de/krotik/eliasdb/graph/graphstorage"
  19. "devt.de/krotik/eliasdb/storage"
  20. )
  21. func TestSources(t *testing.T) {
  22. gm, _ := filterGraph()
  23. rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  24. res, err := getResult("get filtertest with ordering(ascending key)", `
  25. Labels: Filtertest Key, Val1, Val2, Val3
  26. Format: auto, auto, auto, auto
  27. Data: 1:n:key, 1:n:val1, 1:n:val2, 1:n:val3
  28. 1, test, Hans, foo
  29. 2, test1, Hans, foo
  30. 3, test2, Hans, foo
  31. 4, test3, Peter, foo
  32. 5, test4, Peter, foo
  33. 6, test5, Peter, foo
  34. 7, test6, Anna, foo
  35. 8, test7, Anna, foo
  36. 9, test8, Steve, foo
  37. 10, test9, Steve, foo
  38. 11, test10, Franz, foo
  39. 12, test11, Kevin, foo
  40. 13, test12, Kevin, foo
  41. 14, test13, Kevin, foo
  42. 15, test14, X1, foo
  43. 16, test15, X2, foo
  44. 17, test16, X3, foo
  45. 18, test17, X4, foo
  46. 19, test17, X5, foo
  47. `[1:], rt, false)
  48. if err != nil {
  49. t.Error(err)
  50. return
  51. }
  52. if q := res.Query(); q != `
  53. get filtertest
  54. with
  55. ordering(ascending key)`[1:] {
  56. t.Error("Unexpected result: ", q)
  57. return
  58. }
  59. 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]]" {
  60. t.Error("Unexpected result: ", r)
  61. }
  62. 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]]" {
  63. t.Error("Unexpected result: ", r)
  64. }
  65. if res := res.CSV(); res != `
  66. Filtertest Key,Val1,Val2,Val3
  67. 1,test,Hans,foo
  68. 2,test1,Hans,foo
  69. 3,test2,Hans,foo
  70. 4,test3,Peter,foo
  71. 5,test4,Peter,foo
  72. 6,test5,Peter,foo
  73. 7,test6,Anna,foo
  74. 8,test7,Anna,foo
  75. 9,test8,Steve,foo
  76. 10,test9,Steve,foo
  77. 11,test10,Franz,foo
  78. 12,test11,Kevin,foo
  79. 13,test12,Kevin,foo
  80. 14,test13,Kevin,foo
  81. 15,test14,X1,foo
  82. 16,test15,X2,foo
  83. 17,test16,X3,foo
  84. 18,test17,X4,foo
  85. 19,test17,X5,foo
  86. `[1:] {
  87. t.Error("Unexpected result: ", res)
  88. }
  89. }
  90. func TestGrouping(t *testing.T) {
  91. gm, mgs := songGraphGroups()
  92. rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  93. rt2 := NewLookupRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  94. res, err := getResult("get group where key = 'Best' traverse :::", `
  95. Labels: Group Key, Key, Kind, Name
  96. Format: auto, auto, auto, auto
  97. Data: 1:n:key, 2:n:key, 2:n:kind, 2:n:name
  98. Best, Aria3, Song, Aria3
  99. Best, LoveSong3, Song, LoveSong3
  100. Best, MyOnlySong3, Song, MyOnlySong3
  101. Best, StrangeSong1, Song, StrangeSong1
  102. `[1:], rt, true)
  103. if err != nil {
  104. t.Error(err)
  105. return
  106. }
  107. 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]]" {
  108. t.Error("Unexpected result: ", r)
  109. return
  110. }
  111. 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]]" {
  112. t.Error("Unexpected result: ", r)
  113. return
  114. }
  115. // Inspect result
  116. if res.Header() != &res.SearchHeader {
  117. t.Error("Unexpected result")
  118. return
  119. }
  120. if res.Header().Data()[0] != res.SearchHeader.ColData[0] {
  121. t.Error("Unexpected result")
  122. return
  123. }
  124. if res.Header().Format()[0] != res.SearchHeader.ColFormat[0] {
  125. t.Error("Unexpected result")
  126. return
  127. }
  128. if res.Header().Labels()[0] != res.SearchHeader.ColLabels[0] {
  129. t.Error("Unexpected result")
  130. return
  131. }
  132. if res.Header().PrimaryKind() != res.SearchHeader.ResPrimaryKind {
  133. t.Error("Unexpected result")
  134. return
  135. }
  136. if res.Header().Partition() != res.SearchHeader.ResPartition {
  137. t.Error("Unexpected result")
  138. return
  139. }
  140. if res.RowCount() != 4 {
  141. t.Error("Unexpected result")
  142. return
  143. }
  144. if res.Row(2)[1] != res.Data[2][1] {
  145. t.Error("Unexpected result")
  146. return
  147. }
  148. if res.RowSource(2)[1] != res.Source[2][1] {
  149. t.Error("Unexpected result")
  150. return
  151. }
  152. if _, err := getResult("get Song from group Best", `
  153. Labels: Song Key, Song Name, Ranking
  154. Format: auto, auto, auto
  155. Data: 1:n:key, 1:n:name, 1:n:ranking
  156. Aria3, Aria3, 4
  157. LoveSong3, LoveSong3, 1
  158. MyOnlySong3, MyOnlySong3, 19
  159. StrangeSong1, StrangeSong1, 5
  160. `[1:], rt, true); err != nil {
  161. t.Error(err)
  162. return
  163. }
  164. if _, err := getResult("get Song from group bbest", `
  165. Labels: Song Key, Song Name, Ranking
  166. Format: auto, auto, auto
  167. Data: 1:n:key, 1:n:name, 1:n:ranking
  168. `[1:], rt, true); err != nil {
  169. t.Error(err)
  170. return
  171. }
  172. if _, err := getResult("get Song from group Best1", `
  173. Labels: Song Key, Song Name, Ranking
  174. Format: auto, auto, auto
  175. Data: 1:n:key, 1:n:name, 1:n:ranking
  176. `[1:], rt, true); err != nil {
  177. t.Error(err)
  178. return
  179. }
  180. // Test special error case with groups
  181. msm := mgs.StorageManager("main"+"group"+graph.StorageSuffixNodes, false).(*storage.MemoryStorageManager)
  182. msm.AccessMap[1] = storage.AccessCacheAndFetchError
  183. if _, err := getResult("get Song from group Best", "", rt, true); err.Error() !=
  184. "GraphError: Failed to access graph storage component (Slot not found (mystorage/maingroup.nodes - Location:1))" {
  185. t.Error(err)
  186. return
  187. }
  188. if _, err := getResult("lookup Song '1' from group Best", "", rt2, true); err.Error() !=
  189. "GraphError: Failed to access graph storage component (Slot not found (mystorage/maingroup.nodes - Location:1))" {
  190. t.Error(err)
  191. return
  192. }
  193. delete(msm.AccessMap, 1)
  194. if _, err := getResult("lookup Song 'non', 'Aria1', 'MyOnlySong3' from group Best", `
  195. Labels: Song Key, Song Name, Ranking
  196. Format: auto, auto, auto
  197. Data: 1:n:key, 1:n:name, 1:n:ranking
  198. MyOnlySong3, MyOnlySong3, 19
  199. `[1:], rt2, true); err != nil {
  200. t.Error(err)
  201. return
  202. }
  203. if _, err := getResult("lookup Song 'non', 'Aria1', 'MyOnlySong3' from group bbest", `
  204. Labels: Song Key, Song Name, Ranking
  205. Format: auto, auto, auto
  206. Data: 1:n:key, 1:n:name, 1:n:ranking
  207. `[1:], rt2, true); err != nil {
  208. t.Error(err)
  209. return
  210. }
  211. }
  212. func TestWithFlags(t *testing.T) {
  213. gm, _ := songGraph()
  214. rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  215. // Test simple query to get everything
  216. if _, err := getResult("get Author traverse :::", `
  217. Labels: Author Key, Author Name, Key, Kind, Name
  218. Format: auto, auto, auto, auto, auto
  219. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:kind, 2:n:name
  220. 000, John, Aria1, Song, Aria1
  221. 000, John, Aria2, Song, Aria2
  222. 000, John, Aria3, Song, Aria3
  223. 000, John, Aria4, Song, Aria4
  224. 123, Mike, DeadSong2, Song, DeadSong2
  225. 123, Mike, FightSong4, Song, FightSong4
  226. 123, Mike, LoveSong3, Song, LoveSong3
  227. 123, Mike, StrangeSong1, Song, StrangeSong1
  228. 456, Hans, MyOnlySong3, Song, MyOnlySong3
  229. `[1:], rt, true); err != nil {
  230. t.Error(err)
  231. return
  232. }
  233. // Test ordering
  234. if _, err := getResult("get Author traverse :::Song end with ordering(ascending Song:name)", `
  235. Labels: Author Key, Author Name, Song Key, Song Name, Ranking
  236. Format: auto, auto, auto, auto, auto
  237. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
  238. 000, John, Aria1, Aria1, 8
  239. 000, John, Aria2, Aria2, 2
  240. 000, John, Aria3, Aria3, 4
  241. 000, John, Aria4, Aria4, 18
  242. 123, Mike, DeadSong2, DeadSong2, 6
  243. 123, Mike, FightSong4, FightSong4, 3
  244. 123, Mike, LoveSong3, LoveSong3, 1
  245. 456, Hans, MyOnlySong3, MyOnlySong3, 19
  246. 123, Mike, StrangeSong1, StrangeSong1, 5
  247. `[1:], rt, false); err != nil {
  248. t.Error(err)
  249. return
  250. }
  251. if _, err := getResult("get Author traverse :::Song end with ordering(descending ranking)", `
  252. Labels: Author Key, Author Name, Song Key, Song Name, Ranking
  253. Format: auto, auto, auto, auto, auto
  254. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
  255. 456, Hans, MyOnlySong3, MyOnlySong3, 19
  256. 000, John, Aria4, Aria4, 18
  257. 000, John, Aria1, Aria1, 8
  258. 123, Mike, DeadSong2, DeadSong2, 6
  259. 123, Mike, StrangeSong1, StrangeSong1, 5
  260. 000, John, Aria3, Aria3, 4
  261. 123, Mike, FightSong4, FightSong4, 3
  262. 000, John, Aria2, Aria2, 2
  263. 123, Mike, LoveSong3, LoveSong3, 1
  264. `[1:], rt, false); err != nil {
  265. t.Error(err)
  266. return
  267. }
  268. if _, err := getResult("get Author traverse :::Song end with ordering(ascending Song:ranking)", `
  269. Labels: Author Key, Author Name, Song Key, Song Name, Ranking
  270. Format: auto, auto, auto, auto, auto
  271. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
  272. 123, Mike, LoveSong3, LoveSong3, 1
  273. 000, John, Aria2, Aria2, 2
  274. 123, Mike, FightSong4, FightSong4, 3
  275. 000, John, Aria3, Aria3, 4
  276. 123, Mike, StrangeSong1, StrangeSong1, 5
  277. 123, Mike, DeadSong2, DeadSong2, 6
  278. 000, John, Aria1, Aria1, 8
  279. 000, John, Aria4, Aria4, 18
  280. 456, Hans, MyOnlySong3, MyOnlySong3, 19
  281. `[1:], rt, false); err != nil {
  282. t.Error(err)
  283. return
  284. }
  285. if _, err := getResult("get Author traverse :::Song end with ordering(ascending 2:n:ranking)", `
  286. Labels: Author Key, Author Name, Song Key, Song Name, Ranking
  287. Format: auto, auto, auto, auto, auto
  288. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
  289. 123, Mike, LoveSong3, LoveSong3, 1
  290. 000, John, Aria2, Aria2, 2
  291. 123, Mike, FightSong4, FightSong4, 3
  292. 000, John, Aria3, Aria3, 4
  293. 123, Mike, StrangeSong1, StrangeSong1, 5
  294. 123, Mike, DeadSong2, DeadSong2, 6
  295. 000, John, Aria1, Aria1, 8
  296. 000, John, Aria4, Aria4, 18
  297. 456, Hans, MyOnlySong3, MyOnlySong3, 19
  298. `[1:], rt, false); err != nil {
  299. t.Error(err)
  300. return
  301. }
  302. 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)", `
  303. Labels: Name, Name, Number
  304. Format: auto, auto, auto
  305. Data: 1:n:name, 2:n:name, 2:e:number
  306. Mike, StrangeSong1, 1
  307. John, Aria1, 1
  308. Mike, DeadSong2, 2
  309. John, Aria2, 2
  310. Hans, MyOnlySong3, 3
  311. Mike, LoveSong3, 3
  312. John, Aria3, 3
  313. Mike, FightSong4, 4
  314. John, Aria4, 4
  315. `[1:], rt, false); err != nil {
  316. t.Error(err)
  317. return
  318. }
  319. // Test empty traversal flag
  320. if _, err := getResult("get Author traverse :::Song where name = '123' end with nulltraversal(true)", `
  321. Labels: Author Key, Author Name, Song Key, Song Name, Ranking
  322. Format: auto, auto, auto, auto, auto
  323. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
  324. 123, Mike, <not set>, <not set>, <not set>
  325. 456, Hans, <not set>, <not set>, <not set>
  326. 000, John, <not set>, <not set>, <not set>
  327. `[1:], rt, false); err != nil {
  328. t.Error(err)
  329. return
  330. }
  331. if _, err := getResult("get Author traverse :::Song where name = '123' end", `
  332. Labels: Author Key, Author Name, Song Key, Song Name, Ranking
  333. Format: auto, auto, auto, auto, auto
  334. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
  335. `[1:], rt, false); err != nil {
  336. t.Error(err)
  337. return
  338. }
  339. // Test filtering
  340. if _, err := getResult("get Author traverse :::Song where name = 'DeadSong2' end with nulltraversal(true), filtering(isnotnull Song:name)", `
  341. Labels: Author Key, Author Name, Song Key, Song Name, Ranking
  342. Format: auto, auto, auto, auto, auto
  343. Data: 1:n:key, 1:n:name, 2:n:key, 2:n:name, 2:n:ranking
  344. 123, Mike, DeadSong2, DeadSong2, 6
  345. `[1:], rt, false); err != nil {
  346. t.Error(err)
  347. return
  348. }
  349. if _, err := getResult("get Author traverse :::Song end show Author:name with filtering(unique Author:name)", `
  350. Labels: Author Name
  351. Format: auto
  352. Data: 1:n:name
  353. Mike
  354. Hans
  355. John
  356. `[1:], rt, false); err != nil {
  357. t.Error(err)
  358. return
  359. }
  360. if _, err := getResult("get Author traverse :::Song end show Author:name with filtering(uniquecount Author:name)", `
  361. Labels: Author Name
  362. Format: auto
  363. Data: 1:n:name
  364. Mike (4)
  365. Hans (1)
  366. John (4)
  367. `[1:], rt, false); err != nil {
  368. t.Error(err)
  369. return
  370. }
  371. }
  372. func TestWithFlagsErrors(t *testing.T) {
  373. gm, _ := songGraph()
  374. rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  375. if _, err := getResult("get Author traverse ::: end with filtering(unique 1:p:bla)", "", rt, false); err.Error() !=
  376. "EQL error in test: Invalid construct (Cannot determine column for with term: 1:p:bla) (Line:1 Pos:44)" {
  377. t.Error(err)
  378. return
  379. }
  380. if _, err := getResult("get Author traverse ::: end with ordering(ascending p:bla)", "", rt, false); err.Error() !=
  381. "EQL error in test: Invalid construct (Cannot determine column for with term: p:bla) (Line:1 Pos:43)" {
  382. t.Error(err)
  383. return
  384. }
  385. if _, err := getResult("get Author traverse ::: end with filtering(ascending p:bla)", "", rt, false); err.Error() !=
  386. "EQL error in test: Invalid construct (ascending) (Line:1 Pos:44)" {
  387. t.Error(err)
  388. return
  389. }
  390. if _, err := getResult("get Author traverse ::: end with ordering(unique p:bla)", "", rt, false); err.Error() !=
  391. "EQL error in test: Invalid construct (unique) (Line:1 Pos:43)" {
  392. t.Error(err)
  393. return
  394. }
  395. if _, err := getResult("get Author traverse ::: end with ascending(ascending p:bla)", "", rt, false); err.Error() !=
  396. "EQL error in test: Invalid construct (ascending) (Line:1 Pos:34)" {
  397. t.Error(err)
  398. return
  399. }
  400. }
  401. /*
  402. Helper function to run a search and check against a result.
  403. */
  404. func getResult(query string, expectedResult string, rt parser.RuntimeProvider, sort bool) (*SearchResult, error) {
  405. ast, err := parser.ParseWithRuntime("test", query, rt)
  406. if err != nil {
  407. return nil, err
  408. }
  409. res, err := ast.Runtime.Eval()
  410. if err != nil {
  411. return nil, err
  412. }
  413. if sort {
  414. res.(*SearchResult).StableSort()
  415. }
  416. if fmt.Sprint(res) != expectedResult {
  417. return nil, errors.New(fmt.Sprint("Unexpected search result:", res, err))
  418. }
  419. return res.(*SearchResult), nil
  420. }
  421. func songGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
  422. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  423. gm := graph.NewGraphManager(mgs)
  424. constructEdge := func(key string, node1 data.Node, node2 data.Node, number int) data.Edge {
  425. edge := data.NewGraphEdge()
  426. edge.SetAttr("key", key)
  427. edge.SetAttr("kind", "Wrote")
  428. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  429. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  430. edge.SetAttr(data.EdgeEnd1Role, "Author")
  431. edge.SetAttr(data.EdgeEnd1Cascading, true)
  432. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  433. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  434. edge.SetAttr(data.EdgeEnd2Role, "Song")
  435. edge.SetAttr(data.EdgeEnd2Cascading, false)
  436. edge.SetAttr("number", number)
  437. return edge
  438. }
  439. storeSong := func(node data.Node, name string, ranking int, number int) {
  440. node3 := data.NewGraphNode()
  441. node3.SetAttr("key", name)
  442. node3.SetAttr("kind", "Song")
  443. node3.SetAttr("name", name)
  444. node3.SetAttr("ranking", ranking)
  445. gm.StoreNode("main", node3)
  446. gm.StoreEdge("main", constructEdge(name, node, node3, number))
  447. }
  448. node0 := data.NewGraphNode()
  449. node0.SetAttr("key", "000")
  450. node0.SetAttr("kind", "Author")
  451. node0.SetAttr("name", "John")
  452. gm.StoreNode("main", node0)
  453. storeSong(node0, "Aria1", 8, 1)
  454. storeSong(node0, "Aria2", 2, 2)
  455. storeSong(node0, "Aria3", 4, 3)
  456. storeSong(node0, "Aria4", 18, 4)
  457. node1 := data.NewGraphNode()
  458. node1.SetAttr("key", "123")
  459. node1.SetAttr("kind", "Author")
  460. node1.SetAttr("name", "Mike")
  461. gm.StoreNode("main", node1)
  462. storeSong(node1, "LoveSong3", 1, 3)
  463. storeSong(node1, "FightSong4", 3, 4)
  464. storeSong(node1, "DeadSong2", 6, 2)
  465. storeSong(node1, "StrangeSong1", 5, 1)
  466. node2 := data.NewGraphNode()
  467. node2.SetAttr("key", "456")
  468. node2.SetAttr("kind", "Author")
  469. node2.SetAttr("name", "Hans")
  470. gm.StoreNode("main", node2)
  471. storeSong(node2, "MyOnlySong3", 19, 3)
  472. return gm, mgs.(*graphstorage.MemoryGraphStorage)
  473. }
  474. func songGraphGroups() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
  475. gm, mgs := songGraph()
  476. node0 := data.NewGraphNode()
  477. node0.SetAttr("key", "Best")
  478. node0.SetAttr("kind", GroupNodeKind)
  479. gm.StoreNode("main", node0)
  480. constructEdge := func(songkey string) data.Edge {
  481. edge := data.NewGraphEdge()
  482. edge.SetAttr("key", songkey)
  483. edge.SetAttr("kind", "Contains")
  484. edge.SetAttr(data.EdgeEnd1Key, node0.Key())
  485. edge.SetAttr(data.EdgeEnd1Kind, node0.Kind())
  486. edge.SetAttr(data.EdgeEnd1Role, "group")
  487. edge.SetAttr(data.EdgeEnd1Cascading, false)
  488. edge.SetAttr(data.EdgeEnd2Key, songkey)
  489. edge.SetAttr(data.EdgeEnd2Kind, "Song")
  490. edge.SetAttr(data.EdgeEnd2Role, "Song")
  491. edge.SetAttr(data.EdgeEnd2Cascading, false)
  492. return edge
  493. }
  494. gm.StoreEdge("main", constructEdge("LoveSong3"))
  495. gm.StoreEdge("main", constructEdge("Aria3"))
  496. gm.StoreEdge("main", constructEdge("MyOnlySong3"))
  497. gm.StoreEdge("main", constructEdge("StrangeSong1"))
  498. return gm, mgs
  499. }
  500. func dateGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
  501. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  502. gm := graph.NewGraphManager(mgs)
  503. node0 := data.NewGraphNode()
  504. node0.SetAttr("key", "000")
  505. node0.SetAttr("kind", "datetest")
  506. node0.SetAttr("name", "date1")
  507. node0.SetAttr("unix", 1349809255)
  508. node0.SetAttr("RFC3339_value", "2012-10-09T19:00:55Z")
  509. node0.SetAttr("naive_value", "2012-10-09")
  510. gm.StoreNode("main", node0)
  511. node1 := data.NewGraphNode()
  512. node1.SetAttr("key", "001")
  513. node1.SetAttr("kind", "datetest")
  514. node1.SetAttr("name", "date2")
  515. node1.SetAttr("unix", 1350061255)
  516. node1.SetAttr("RFC3339_value", "2012-10-12T19:00:55+02:00")
  517. node1.SetAttr("naive_value", "2012-10-12")
  518. gm.StoreNode("main", node1)
  519. return gm, mgs.(*graphstorage.MemoryGraphStorage)
  520. }
  521. func filterGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
  522. gm, mgs := songGraph()
  523. constructNode := func(key, val1, val2, val3 string) data.Node {
  524. node0 := data.NewGraphNode()
  525. node0.SetAttr("key", key)
  526. node0.SetAttr("kind", "filtertest")
  527. node0.SetAttr("val1", val1)
  528. node0.SetAttr("val2", val2)
  529. node0.SetAttr("val3", val3)
  530. return node0
  531. }
  532. gm.StoreNode("main", constructNode("1", "test", "Hans", "foo"))
  533. gm.StoreNode("main", constructNode("2", "test1", "Hans", "foo"))
  534. gm.StoreNode("main", constructNode("3", "test2", "Hans", "foo"))
  535. gm.StoreNode("main", constructNode("4", "test3", "Peter", "foo"))
  536. gm.StoreNode("main", constructNode("5", "test4", "Peter", "foo"))
  537. gm.StoreNode("main", constructNode("6", "test5", "Peter", "foo"))
  538. gm.StoreNode("main", constructNode("7", "test6", "Anna", "foo"))
  539. gm.StoreNode("main", constructNode("8", "test7", "Anna", "foo"))
  540. gm.StoreNode("main", constructNode("9", "test8", "Steve", "foo"))
  541. gm.StoreNode("main", constructNode("10", "test9", "Steve", "foo"))
  542. gm.StoreNode("main", constructNode("11", "test10", "Franz", "foo"))
  543. gm.StoreNode("main", constructNode("12", "test11", "Kevin", "foo"))
  544. gm.StoreNode("main", constructNode("13", "test12", "Kevin", "foo"))
  545. gm.StoreNode("main", constructNode("14", "test13", "Kevin", "foo"))
  546. gm.StoreNode("main", constructNode("15", "test14", "X1", "foo"))
  547. gm.StoreNode("main", constructNode("16", "test15", "X2", "foo"))
  548. gm.StoreNode("main", constructNode("17", "test16", "X3", "foo"))
  549. gm.StoreNode("main", constructNode("18", "test17", "X4", "foo"))
  550. gm.StoreNode("main", constructNode("19", "test17", "X5", "foo"))
  551. return gm, mgs
  552. }