query_test.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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 eql
  11. import (
  12. "testing"
  13. "devt.de/krotik/eliasdb/eql/interpreter"
  14. "devt.de/krotik/eliasdb/graph"
  15. "devt.de/krotik/eliasdb/graph/data"
  16. "devt.de/krotik/eliasdb/graph/graphstorage"
  17. )
  18. func TestBugFixes(t *testing.T) {
  19. gm, _ := songGraph()
  20. // Bug 1 - Lookup only giving last AST main child node (show) to runtime instead of first non-value (where)
  21. res, err := RunQuery("test", "main", "lookup Author '000' traverse :::Song end show Song:key with ordering(ascending key)", gm)
  22. if err != nil || res.String() != `
  23. Labels: Song Key
  24. Format: auto
  25. Data: 2:n:key
  26. Aria1
  27. Aria2
  28. Aria3
  29. Aria4
  30. `[1:] {
  31. t.Error("Unexpected result: ", err, res)
  32. return
  33. }
  34. }
  35. func TestQuery(t *testing.T) {
  36. gm, _ := songGraph()
  37. res, _ := RunQuery("test", "main", "get Author with ordering(ascending key)", gm)
  38. if res.String() != `
  39. Labels: Author Key, Author Name
  40. Format: auto, auto
  41. Data: 1:n:key, 1:n:name
  42. 000, John
  43. 123, Mike
  44. 456, Hans
  45. `[1:] {
  46. t.Error("Unexpected result: ", res)
  47. return
  48. }
  49. if res.Rows() == nil {
  50. t.Error("Unexpected result")
  51. return
  52. }
  53. if res.RowSources() == nil {
  54. t.Error("Unexpected result")
  55. return
  56. }
  57. if res.Header().(*interpreter.SearchHeader) != &res.(*queryResult).SearchHeader {
  58. t.Error("Unexpected header result")
  59. return
  60. }
  61. res, _ = RunQuery("test", "main", "lookup Author '000'", gm)
  62. if res.String() != `
  63. Labels: Author Key, Author Name
  64. Format: auto, auto
  65. Data: 1:n:key, 1:n:name
  66. 000, John
  67. `[1:] {
  68. t.Error("Unexpected result: ", res)
  69. return
  70. }
  71. // Test error cases
  72. _, err := RunQuery("test", "main", "boo Author", gm)
  73. if err.Error() != "EQL error in test: Invalid construct (Unknown query type: boo) (Line:1 Pos:1)" {
  74. t.Error(err)
  75. return
  76. }
  77. _, err = RunQuery("test", "main", "get Author where", gm)
  78. if err.Error() != "Parse error in test: Unexpected end" {
  79. t.Error(err)
  80. return
  81. }
  82. _, err = RunQuery("test", "main", "get Author traverse ::", gm)
  83. if err.Error() != "EQL error in test: Invalid traversal spec (::) (Line:1 Pos:12)" {
  84. t.Error(err)
  85. return
  86. }
  87. }
  88. func TestQueryPlainGraph(t *testing.T) {
  89. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  90. gm := graph.NewGraphManager(mgs)
  91. createNode := func(key string) {
  92. node0 := data.NewGraphNode()
  93. node0.SetAttr("key", key)
  94. node0.SetAttr("kind", "test")
  95. gm.StoreNode("main", node0)
  96. }
  97. createNode("123")
  98. createNode("1")
  99. createNode("2")
  100. createNode("3")
  101. node0 := data.NewGraphNode()
  102. node0.SetAttr("key", "4")
  103. node0.SetAttr("kind", "test")
  104. node0.SetAttr("name", "bla")
  105. gm.StoreNode("main", node0)
  106. res, _ := RunQuery("test", "main", "get test", gm)
  107. if res.String() != `
  108. Labels: Test Key, Test Name
  109. Format: auto, auto
  110. Data: 1:n:key, 1:n:name
  111. 123, <not set>
  112. 1, <not set>
  113. 2, <not set>
  114. 3, <not set>
  115. 4, bla
  116. `[1:] {
  117. t.Error("Unexpected result: ", res)
  118. return
  119. }
  120. }
  121. func TestParseQuery(t *testing.T) {
  122. res, _ := ParseQuery("test", "get Author with ordering(ascending key)")
  123. if res.String() != `
  124. get
  125. value: "Author"
  126. with
  127. ordering
  128. asc
  129. value: "key"
  130. `[1:] {
  131. t.Error("Unexpected result: ", res)
  132. return
  133. }
  134. // Test error case
  135. _, err := ParseQuery("test", "get Author where")
  136. if err.Error() != "Parse error in test: Unexpected end" {
  137. t.Error(err)
  138. return
  139. }
  140. }
  141. func songGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
  142. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  143. gm := graph.NewGraphManager(mgs)
  144. constructEdge := func(key string, node1 data.Node, node2 data.Node, number int) data.Edge {
  145. edge := data.NewGraphEdge()
  146. edge.SetAttr("key", key)
  147. edge.SetAttr("kind", "Wrote")
  148. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  149. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  150. edge.SetAttr(data.EdgeEnd1Role, "Author")
  151. edge.SetAttr(data.EdgeEnd1Cascading, true)
  152. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  153. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  154. edge.SetAttr(data.EdgeEnd2Role, "Song")
  155. edge.SetAttr(data.EdgeEnd2Cascading, false)
  156. edge.SetAttr("number", number)
  157. return edge
  158. }
  159. storeSong := func(node data.Node, name string, ranking int, number int) {
  160. node3 := data.NewGraphNode()
  161. node3.SetAttr("key", name)
  162. node3.SetAttr("kind", "Song")
  163. node3.SetAttr("name", name)
  164. node3.SetAttr("ranking", ranking)
  165. gm.StoreNode("main", node3)
  166. gm.StoreEdge("main", constructEdge(name, node, node3, number))
  167. }
  168. node0 := data.NewGraphNode()
  169. node0.SetAttr("key", "000")
  170. node0.SetAttr("kind", "Author")
  171. node0.SetAttr("name", "John")
  172. gm.StoreNode("main", node0)
  173. storeSong(node0, "Aria1", 8, 1)
  174. storeSong(node0, "Aria2", 2, 2)
  175. storeSong(node0, "Aria3", 4, 3)
  176. storeSong(node0, "Aria4", 18, 4)
  177. node1 := data.NewGraphNode()
  178. node1.SetAttr("key", "123")
  179. node1.SetAttr("kind", "Author")
  180. node1.SetAttr("name", "Mike")
  181. gm.StoreNode("main", node1)
  182. storeSong(node1, "LoveSong3", 1, 3)
  183. storeSong(node1, "FightSong4", 3, 4)
  184. storeSong(node1, "DeadSong2", 6, 2)
  185. storeSong(node1, "StrangeSong1", 5, 1)
  186. node2 := data.NewGraphNode()
  187. node2.SetAttr("key", "456")
  188. node2.SetAttr("kind", "Author")
  189. node2.SetAttr("name", "Hans")
  190. gm.StoreNode("main", node2)
  191. storeSong(node2, "MyOnlySong3", 19, 3)
  192. return gm, mgs.(*graphstorage.MemoryGraphStorage)
  193. }
  194. func songGraphGroups() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
  195. gm, mgs := songGraph()
  196. node0 := data.NewGraphNode()
  197. node0.SetAttr("key", "Best")
  198. node0.SetAttr("kind", GroupNodeKind)
  199. gm.StoreNode("main", node0)
  200. constructEdge := func(songkey string) data.Edge {
  201. edge := data.NewGraphEdge()
  202. edge.SetAttr("key", songkey)
  203. edge.SetAttr("kind", "Contains")
  204. edge.SetAttr(data.EdgeEnd1Key, node0.Key())
  205. edge.SetAttr(data.EdgeEnd1Kind, node0.Kind())
  206. edge.SetAttr(data.EdgeEnd1Role, "group")
  207. edge.SetAttr(data.EdgeEnd1Cascading, false)
  208. edge.SetAttr(data.EdgeEnd2Key, songkey)
  209. edge.SetAttr(data.EdgeEnd2Kind, "Song")
  210. edge.SetAttr(data.EdgeEnd2Role, "Song")
  211. edge.SetAttr(data.EdgeEnd2Cascading, false)
  212. return edge
  213. }
  214. gm.StoreEdge("main", constructEdge("LoveSong3"))
  215. gm.StoreEdge("main", constructEdge("Aria3"))
  216. gm.StoreEdge("main", constructEdge("MyOnlySong3"))
  217. gm.StoreEdge("main", constructEdge("StrangeSong1"))
  218. return gm, mgs
  219. }