neography-down 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.project +12 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +4 -0
  6. data/CHANGELOG.md +939 -0
  7. data/CONTRIBUTORS +18 -0
  8. data/Gemfile +4 -0
  9. data/Guardfile +14 -0
  10. data/LICENSE +19 -0
  11. data/README.md +281 -0
  12. data/Rakefile +14 -0
  13. data/examples/facebook.rb +40 -0
  14. data/examples/facebook_v2.rb +25 -0
  15. data/examples/greatest.rb +43 -0
  16. data/examples/linkedin.rb +39 -0
  17. data/examples/linkedin_v2.rb +22 -0
  18. data/examples/traversal_example1.rb +65 -0
  19. data/examples/traversal_example2.rb +54 -0
  20. data/lib/neography.rb +45 -0
  21. data/lib/neography/config.rb +64 -0
  22. data/lib/neography/connection.rb +263 -0
  23. data/lib/neography/equal.rb +21 -0
  24. data/lib/neography/errors.rb +60 -0
  25. data/lib/neography/index.rb +52 -0
  26. data/lib/neography/multi_json_parser.rb +28 -0
  27. data/lib/neography/neography.rb +10 -0
  28. data/lib/neography/node.rb +63 -0
  29. data/lib/neography/node_path.rb +29 -0
  30. data/lib/neography/node_relationship.rb +37 -0
  31. data/lib/neography/node_traverser.rb +146 -0
  32. data/lib/neography/path_traverser.rb +100 -0
  33. data/lib/neography/property.rb +110 -0
  34. data/lib/neography/property_container.rb +28 -0
  35. data/lib/neography/railtie.rb +19 -0
  36. data/lib/neography/relationship.rb +78 -0
  37. data/lib/neography/relationship_traverser.rb +80 -0
  38. data/lib/neography/rest.rb +99 -0
  39. data/lib/neography/rest/batch.rb +414 -0
  40. data/lib/neography/rest/clean.rb +17 -0
  41. data/lib/neography/rest/constraints.rb +38 -0
  42. data/lib/neography/rest/cypher.rb +29 -0
  43. data/lib/neography/rest/extensions.rb +21 -0
  44. data/lib/neography/rest/gremlin.rb +20 -0
  45. data/lib/neography/rest/helpers.rb +96 -0
  46. data/lib/neography/rest/node_auto_indexes.rb +60 -0
  47. data/lib/neography/rest/node_indexes.rb +139 -0
  48. data/lib/neography/rest/node_labels.rb +49 -0
  49. data/lib/neography/rest/node_paths.rb +49 -0
  50. data/lib/neography/rest/node_properties.rb +52 -0
  51. data/lib/neography/rest/node_relationships.rb +33 -0
  52. data/lib/neography/rest/node_traversal.rb +25 -0
  53. data/lib/neography/rest/nodes.rb +94 -0
  54. data/lib/neography/rest/other_node_relationships.rb +38 -0
  55. data/lib/neography/rest/relationship_auto_indexes.rb +60 -0
  56. data/lib/neography/rest/relationship_indexes.rb +142 -0
  57. data/lib/neography/rest/relationship_properties.rb +52 -0
  58. data/lib/neography/rest/relationship_types.rb +11 -0
  59. data/lib/neography/rest/relationships.rb +16 -0
  60. data/lib/neography/rest/schema_indexes.rb +26 -0
  61. data/lib/neography/rest/spatial.rb +137 -0
  62. data/lib/neography/rest/transactions.rb +101 -0
  63. data/lib/neography/tasks.rb +207 -0
  64. data/lib/neography/version.rb +3 -0
  65. data/neography.gemspec +39 -0
  66. data/spec/integration/authorization_spec.rb +40 -0
  67. data/spec/integration/broken_spatial_spec.rb +28 -0
  68. data/spec/integration/index_spec.rb +71 -0
  69. data/spec/integration/neography_spec.rb +10 -0
  70. data/spec/integration/node_encoding_spec.rb +71 -0
  71. data/spec/integration/node_path_spec.rb +222 -0
  72. data/spec/integration/node_relationship_spec.rb +381 -0
  73. data/spec/integration/node_spec.rb +260 -0
  74. data/spec/integration/parsing_spec.rb +13 -0
  75. data/spec/integration/performance_spec.rb +17 -0
  76. data/spec/integration/relationship_spec.rb +37 -0
  77. data/spec/integration/rest_batch_no_streaming_spec.rb +41 -0
  78. data/spec/integration/rest_batch_spec.rb +604 -0
  79. data/spec/integration/rest_batch_streaming_spec.rb +51 -0
  80. data/spec/integration/rest_bulk_spec.rb +106 -0
  81. data/spec/integration/rest_constraints_spec.rb +72 -0
  82. data/spec/integration/rest_experimental_spec.rb +22 -0
  83. data/spec/integration/rest_gremlin_fail_spec.rb +46 -0
  84. data/spec/integration/rest_header_spec.rb +15 -0
  85. data/spec/integration/rest_index_spec.rb +481 -0
  86. data/spec/integration/rest_labels_spec.rb +128 -0
  87. data/spec/integration/rest_node_spec.rb +274 -0
  88. data/spec/integration/rest_other_node_relationship_spec.rb +137 -0
  89. data/spec/integration/rest_path_spec.rb +231 -0
  90. data/spec/integration/rest_plugin_spec.rb +177 -0
  91. data/spec/integration/rest_relationship_spec.rb +354 -0
  92. data/spec/integration/rest_relationship_types_spec.rb +18 -0
  93. data/spec/integration/rest_schema_index_spec.rb +32 -0
  94. data/spec/integration/rest_spatial_spec.rb +166 -0
  95. data/spec/integration/rest_transaction_spec.rb +166 -0
  96. data/spec/integration/rest_traverse_spec.rb +149 -0
  97. data/spec/integration/unmanaged_spec.rb +27 -0
  98. data/spec/matchers.rb +33 -0
  99. data/spec/neography_spec.rb +23 -0
  100. data/spec/spec_helper.rb +44 -0
  101. data/spec/unit/config_spec.rb +135 -0
  102. data/spec/unit/connection_spec.rb +284 -0
  103. data/spec/unit/node_spec.rb +100 -0
  104. data/spec/unit/properties_spec.rb +285 -0
  105. data/spec/unit/relationship_spec.rb +118 -0
  106. data/spec/unit/rest/batch_spec.rb +262 -0
  107. data/spec/unit/rest/clean_spec.rb +16 -0
  108. data/spec/unit/rest/constraints_spec.rb +45 -0
  109. data/spec/unit/rest/cypher_spec.rb +20 -0
  110. data/spec/unit/rest/extensions_spec.rb +28 -0
  111. data/spec/unit/rest/gremlin_spec.rb +25 -0
  112. data/spec/unit/rest/helpers_spec.rb +124 -0
  113. data/spec/unit/rest/labels_spec.rb +77 -0
  114. data/spec/unit/rest/node_auto_indexes_spec.rb +70 -0
  115. data/spec/unit/rest/node_indexes_spec.rb +140 -0
  116. data/spec/unit/rest/node_paths_spec.rb +77 -0
  117. data/spec/unit/rest/node_properties_spec.rb +79 -0
  118. data/spec/unit/rest/node_relationships_spec.rb +57 -0
  119. data/spec/unit/rest/node_traversal_spec.rb +35 -0
  120. data/spec/unit/rest/nodes_spec.rb +187 -0
  121. data/spec/unit/rest/relationship_auto_indexes_spec.rb +66 -0
  122. data/spec/unit/rest/relationship_indexes_spec.rb +132 -0
  123. data/spec/unit/rest/relationship_properties_spec.rb +79 -0
  124. data/spec/unit/rest/relationship_types_spec.rb +15 -0
  125. data/spec/unit/rest/relationships_spec.rb +21 -0
  126. data/spec/unit/rest/schema_index_spec.rb +30 -0
  127. data/spec/unit/rest/transactions_spec.rb +43 -0
  128. metadata +372 -0
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Neography do
4
+ subject { Neography::Rest.new }
5
+ describe 'create_node' do
6
+ it 'should not convert strings to symbol' do
7
+ node = subject.create_node({:text => ':1456'})
8
+
9
+ expect(node['data']['text'].class).to eq(String) # fails! expected: String got: Symbol (using ==)
10
+ expect(node['data']['text']).to eq(':1456')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Neography::Rest, :slow => true do
4
+ before(:each) do
5
+ @neo = Neography::Rest.new
6
+ end
7
+
8
+ describe "can perform" do
9
+ it "is fast" do
10
+ Benchmark.bm do |x|
11
+ x.report(" 100 Times") { 100.times { @neo.create_node } }
12
+ x.report(" 500 Times") { 500.times { @neo.create_node } }
13
+ x.report("1000 Times") { 1000.times { @neo.create_node } }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Neography::Relationship do
4
+ describe "create relationship" do
5
+ it "#new(:family, p1, p2) creates a new relationship between to nodes of given type" do
6
+ p1 = Neography::Node.create
7
+ p2 = Neography::Node.create
8
+
9
+ Neography::Relationship.create(:family, p1, p2)
10
+ expect(p1.outgoing(:family)).to include(p2)
11
+ expect(p2.incoming(:family)).to include(p1)
12
+ end
13
+
14
+ it "#new(:family, p1, p2, :since => '1998', :colour => 'blue') creates relationship and sets its properties" do
15
+ p1 = Neography::Node.create
16
+ p2 = Neography::Node.create
17
+ rel = Neography::Relationship.create(:family, p1, p2, :since => 1998, :colour => 'blue')
18
+
19
+ expect(rel[:since]).to eq(1998)
20
+ expect(rel[:colour]).to eq('blue')
21
+ expect(rel.since).to eq(1998)
22
+ expect(rel.colour).to eq('blue')
23
+ end
24
+
25
+ it "#outgoing(:friends).create(other) creates a new relationship between self and other node" do
26
+ p1 = Neography::Node.create
27
+ p2 = Neography::Node.create
28
+ rel = p1.outgoing(:foo).create(p2)
29
+
30
+ expect(rel).to be_kind_of(Neography::Relationship)
31
+ expect(p1.outgoing(:foo).first).to eq(p2)
32
+ expect(p1.outgoing(:foo)).to include(p2)
33
+ expect(p2.incoming(:foo)).to include(p1)
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Neography::Rest do
4
+ before(:each) do
5
+ @neo = Neography::Rest.new
6
+ end
7
+
8
+ describe "no streaming" do
9
+
10
+ it "can send a 1000 item batch" do
11
+ commands = []
12
+ 1000.times do |x|
13
+ commands << [:create_node, {"name" => "Max " + x.to_s}]
14
+ end
15
+ batch_result = @neo.batch_no_streaming *commands
16
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max 0")
17
+ expect(batch_result.last["body"]["data"]["name"]).to eq("Max 999")
18
+ end
19
+
20
+ it "can send a 5000 item batch" do
21
+ commands = []
22
+ 5000.times do |x|
23
+ commands << [:get_node, 0]
24
+ end
25
+ batch_result = @neo.batch_no_streaming *commands
26
+ expect(batch_result.first["body"]["self"].split('/').last).to eq("0")
27
+ expect(batch_result.last["body"]["self"].split('/').last).to eq("0")
28
+ end
29
+
30
+ it "can send a 20000 item batch" do
31
+ commands = []
32
+ 20000.times do |x|
33
+ commands << [:create_node, {"name" => "Max " + x.to_s}]
34
+ end
35
+ batch_result = @neo.batch_no_streaming *commands
36
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max 0")
37
+ expect(batch_result.last["body"]["data"]["name"]).to eq("Max 19999")
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,604 @@
1
+ require 'spec_helper'
2
+
3
+ describe Neography::Rest do
4
+ before(:each) do
5
+ @neo = Neography::Rest.new
6
+ end
7
+
8
+ describe "simple batch" do
9
+ it "can get a single node" do
10
+ new_node = @neo.create_node
11
+ new_node[:id] = new_node["self"].split('/').last
12
+ batch_result = @neo.batch [:get_node, new_node]
13
+ expect(batch_result.first).not_to be_nil
14
+ expect(batch_result.first).to have_key("id")
15
+ expect(batch_result.first).to have_key("body")
16
+ expect(batch_result.first).to have_key("from")
17
+ expect(batch_result.first["body"]["self"].split('/').last).to eq(new_node[:id])
18
+ end
19
+
20
+ it "can get multiple nodes" do
21
+ node1 = @neo.create_node
22
+ node1[:id] = node1["self"].split('/').last
23
+ node2 = @neo.create_node
24
+ node2[:id] = node2["self"].split('/').last
25
+
26
+ batch_result = @neo.batch [:get_node, node1], [:get_node, node2]
27
+ expect(batch_result.first).not_to be_nil
28
+ expect(batch_result.first).to have_key("id")
29
+ expect(batch_result.first).to have_key("body")
30
+ expect(batch_result.first).to have_key("from")
31
+ expect(batch_result.first["body"]["self"].split('/').last).to eq(node1[:id])
32
+ expect(batch_result.last).to have_key("id")
33
+ expect(batch_result.last).to have_key("body")
34
+ expect(batch_result.last).to have_key("from")
35
+ expect(batch_result.last["body"]["self"].split('/').last).to eq(node2[:id])
36
+
37
+ end
38
+
39
+ it "can create a single node" do
40
+ batch_result = @neo.batch [:create_node, {"name" => "Max"}]
41
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max")
42
+ end
43
+
44
+ it "can create multiple nodes" do
45
+ batch_result = @neo.batch [:create_node, {"name" => "Max"}], [:create_node, {"name" => "Marc"}]
46
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max")
47
+ expect(batch_result.last["body"]["data"]["name"]).to eq("Marc")
48
+ end
49
+
50
+ it "can create multiple nodes given an *array" do
51
+ batch_result = @neo.batch *[[:create_node, {"name" => "Max"}], [:create_node, {"name" => "Marc"}]]
52
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max")
53
+ expect(batch_result.last["body"]["data"]["name"]).to eq("Marc")
54
+ end
55
+
56
+ it "can create a unique node" do
57
+ index_name = generate_text(6)
58
+ key = generate_text(6)
59
+ value = generate_text
60
+ @neo.create_node_index(index_name)
61
+ batch_result = @neo.batch [:create_unique_node, index_name, key, value, {"age" => 31, "name" => "Max"}]
62
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max")
63
+ expect(batch_result.first["body"]["data"]["age"]).to eq(31)
64
+ new_node_id = batch_result.first["body"]["self"].split('/').last
65
+ batch_result = @neo.batch [:create_unique_node, index_name, key, value, {"age" => 31, "name" => "Max"}]
66
+ expect(batch_result.first["body"]["self"].split('/').last).to eq(new_node_id)
67
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max")
68
+ expect(batch_result.first["body"]["data"]["age"]).to eq(31)
69
+
70
+ #Sanity Check
71
+ existing_node = @neo.create_unique_node(index_name, key, value, {"age" => 31, "name" => "Max"})
72
+ expect(existing_node["self"].split('/').last).to eq(new_node_id)
73
+ expect(existing_node["data"]["name"]).to eq("Max")
74
+ expect(existing_node["data"]["age"]).to eq(31)
75
+ end
76
+
77
+ it "can create or fail a unique node" do
78
+ index_name = generate_text(6)
79
+ key = generate_text(6)
80
+ value = generate_text
81
+ @neo.create_node_index(index_name)
82
+ batch_result = @neo.batch [:create_or_fail_unique_node, index_name, key, value, {"age" => 31, "name" => "Max"}]
83
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max")
84
+ expect(batch_result.first["body"]["data"]["age"]).to eq(31)
85
+ new_node_id = batch_result.first["body"]["self"].split('/').last
86
+ expect {
87
+ batch_result = @neo.batch [:create_or_fail_unique_node, index_name, key, value, {"age" => 31, "name" => "Max"}]
88
+ }.to raise_error Neography::OperationFailureException
89
+
90
+ end
91
+ it "can update a property of a node" do
92
+ new_node = @neo.create_node("name" => "Max")
93
+ batch_result = @neo.batch [:set_node_property, new_node, {"name" => "Marc"}]
94
+ expect(batch_result.first).to have_key("id")
95
+ expect(batch_result.first).to have_key("from")
96
+ existing_node = @neo.get_node(new_node)
97
+ expect(existing_node["data"]["name"]).to eq("Marc")
98
+ end
99
+
100
+ it "can update a property of multiple nodes" do
101
+ node1 = @neo.create_node("name" => "Max")
102
+ node2 = @neo.create_node("name" => "Marc")
103
+ batch_result = @neo.batch [:set_node_property, node1, {"name" => "Tom"}], [:set_node_property, node2, {"name" => "Jerry"}]
104
+ expect(batch_result.first).to have_key("id")
105
+ expect(batch_result.first).to have_key("from")
106
+ expect(batch_result.last).to have_key("id")
107
+ expect(batch_result.last).to have_key("from")
108
+ existing_node = @neo.get_node(node1)
109
+ expect(existing_node["data"]["name"]).to eq("Tom")
110
+ existing_node = @neo.get_node(node2)
111
+ expect(existing_node["data"]["name"]).to eq("Jerry")
112
+ end
113
+
114
+ it "can reset the properties of a node" do
115
+ new_node = @neo.create_node("name" => "Max", "weight" => 200)
116
+ batch_result = @neo.batch [:reset_node_properties, new_node, {"name" => "Marc"}]
117
+ expect(batch_result.first).to have_key("id")
118
+ expect(batch_result.first).to have_key("from")
119
+ existing_node = @neo.get_node(new_node)
120
+ expect(existing_node["data"]["name"]).to eq("Marc")
121
+ expect(existing_node["data"]["weight"]).to be_nil
122
+ end
123
+
124
+ it "can reset the properties of multiple nodes" do
125
+ node1 = @neo.create_node("name" => "Max", "weight" => 200)
126
+ node2 = @neo.create_node("name" => "Marc", "weight" => 180)
127
+ batch_result = @neo.batch [:reset_node_properties, node1, {"name" => "Tom"}], [:reset_node_properties, node2, {"name" => "Jerry"}]
128
+ expect(batch_result.first).to have_key("id")
129
+ expect(batch_result.first).to have_key("from")
130
+ expect(batch_result.last).to have_key("id")
131
+ expect(batch_result.last).to have_key("from")
132
+ existing_node = @neo.get_node(node1)
133
+ expect(existing_node["data"]["name"]).to eq("Tom")
134
+ expect(existing_node["data"]["weight"]).to be_nil
135
+ existing_node = @neo.get_node(node2)
136
+ expect(existing_node["data"]["name"]).to eq("Jerry")
137
+ expect(existing_node["data"]["weight"]).to be_nil
138
+ end
139
+
140
+ it "can remove a property of a node" do
141
+ new_node = @neo.create_node("name" => "Max", "weight" => 200)
142
+ batch_result = @neo.batch [:remove_node_property, new_node, "weight"]
143
+ expect(batch_result.first).to have_key("id")
144
+ expect(batch_result.first).to have_key("from")
145
+ existing_node = @neo.get_node(new_node)
146
+ expect(existing_node["data"]["name"]).to eq("Max")
147
+ expect(existing_node["data"]["weight"]).to be_nil
148
+ end
149
+
150
+ it "can remove a property of multiple nodes" do
151
+ node1 = @neo.create_node("name" => "Max", "weight" => 200)
152
+ node2 = @neo.create_node("name" => "Marc", "weight" => 180)
153
+ batch_result = @neo.batch [:remove_node_property, node1, "name"], [:remove_node_property, node2, "name"]
154
+ expect(batch_result.first).to have_key("id")
155
+ expect(batch_result.first).to have_key("from")
156
+ expect(batch_result.last).to have_key("id")
157
+ expect(batch_result.last).to have_key("from")
158
+ existing_node = @neo.get_node(node1)
159
+ expect(existing_node["data"]["name"]).to be_nil
160
+ expect(existing_node["data"]["weight"]).to eq(200)
161
+ existing_node = @neo.get_node(node2)
162
+ expect(existing_node["data"]["name"]).to be_nil
163
+ expect(existing_node["data"]["weight"]).to eq(180)
164
+ end
165
+
166
+ it "can get a single relationship" do
167
+ node1 = @neo.create_node
168
+ node2 = @neo.create_node
169
+ new_relationship = @neo.create_relationship("friends", node1, node2)
170
+ batch_result = @neo.batch [:get_relationship, new_relationship]
171
+ expect(batch_result.first["body"]["type"]).to eq("friends")
172
+ expect(batch_result.first["body"]["start"].split('/').last).to eq(node1["self"].split('/').last)
173
+ expect(batch_result.first["body"]["end"].split('/').last).to eq(node2["self"].split('/').last)
174
+ expect(batch_result.first["body"]["self"]).to eq(new_relationship["self"])
175
+ end
176
+
177
+ it "can create a single relationship without properties" do
178
+ node1 = @neo.create_node
179
+ node2 = @neo.create_node
180
+ batch_result = @neo.batch [:create_relationship, "friends", node1, node2]
181
+ expect(batch_result.first["body"]["type"]).to eq("friends")
182
+ expect(batch_result.first["body"]["data"]["since"]).to be_nil
183
+ expect(batch_result.first["body"]["start"].split('/').last).to eq(node1["self"].split('/').last)
184
+ expect(batch_result.first["body"]["end"].split('/').last).to eq(node2["self"].split('/').last)
185
+ end
186
+
187
+ it "can create a single relationship" do
188
+ node1 = @neo.create_node
189
+ node2 = @neo.create_node
190
+ batch_result = @neo.batch [:create_relationship, "friends", node1, node2, {:since => "high school"}]
191
+ expect(batch_result.first["body"]["type"]).to eq("friends")
192
+ expect(batch_result.first["body"]["data"]["since"]).to eq("high school")
193
+ expect(batch_result.first["body"]["start"].split('/').last).to eq(node1["self"].split('/').last)
194
+ expect(batch_result.first["body"]["end"].split('/').last).to eq(node2["self"].split('/').last)
195
+ end
196
+
197
+ it "can delete a single relationship" do
198
+ node1 = @neo.create_node
199
+ node2 = @neo.create_node
200
+ batch_result = @neo.batch [:create_relationship, "friends", node1, node2, {:since => "time immemorial"}]
201
+ expect(batch_result).not_to be_nil
202
+ expect(batch_result[0]["status"]).to eq(201)
203
+ id = batch_result.first["body"]["self"].split("/").last
204
+ batch_result = @neo.batch [:delete_relationship, id]
205
+ expect(batch_result[0]["status"]).to eq(204)
206
+ expect(batch_result[0]["from"]).to eq("/relationship/#{id}")
207
+ end
208
+
209
+ it "can create a unique relationship" do
210
+ index_name = generate_text(6)
211
+ key = generate_text(6)
212
+ value = generate_text
213
+ @neo.create_relationship_index(index_name)
214
+ node1 = @neo.create_node
215
+ node2 = @neo.create_node
216
+ batch_result = @neo.batch [:create_unique_relationship, index_name, key, value, "friends", node1, node2]
217
+ expect(batch_result.first["body"]["type"]).to eq("friends")
218
+ expect(batch_result.first["body"]["start"].split('/').last).to eq(node1["self"].split('/').last)
219
+ expect(batch_result.first["body"]["end"].split('/').last).to eq(node2["self"].split('/').last)
220
+ end
221
+
222
+ it "can update a single relationship" do
223
+ node1 = @neo.create_node
224
+ node2 = @neo.create_node
225
+ new_relationship = @neo.create_relationship("friends", node1, node2, {:since => "high school"})
226
+ batch_result = @neo.batch [:set_relationship_property, new_relationship, {:since => "college"}]
227
+ expect(batch_result.first).to have_key("id")
228
+ expect(batch_result.first).to have_key("from")
229
+ existing_relationship = @neo.get_relationship(new_relationship)
230
+ expect(existing_relationship["type"]).to eq("friends")
231
+ expect(existing_relationship["data"]["since"]).to eq("college")
232
+ expect(existing_relationship["start"].split('/').last).to eq(node1["self"].split('/').last)
233
+ expect(existing_relationship["end"].split('/').last).to eq(node2["self"].split('/').last)
234
+ expect(existing_relationship["self"]).to eq(new_relationship["self"])
235
+ end
236
+
237
+ it "can reset the properties of a relationship" do
238
+ node1 = @neo.create_node
239
+ node2 = @neo.create_node
240
+ new_relationship = @neo.create_relationship("friends", node1, node2, {:since => "high school"})
241
+ batch_result = @neo.batch [:reset_relationship_properties, new_relationship, {"since" => "college", "dated" => "yes"}]
242
+ expect(batch_result.first).to have_key("id")
243
+ expect(batch_result.first).to have_key("from")
244
+ existing_relationship = @neo.get_relationship(batch_result.first["from"].split('/')[2])
245
+ expect(existing_relationship["type"]).to eq("friends")
246
+ expect(existing_relationship["data"]["since"]).to eq("college")
247
+ expect(existing_relationship["data"]["dated"]).to eq("yes")
248
+ expect(existing_relationship["start"].split('/').last).to eq(node1["self"].split('/').last)
249
+ expect(existing_relationship["end"].split('/').last).to eq(node2["self"].split('/').last)
250
+ expect(existing_relationship["self"]).to eq(new_relationship["self"])
251
+ end
252
+
253
+ it "can drop a node index" do
254
+ index_name = generate_text(6)
255
+ @neo.create_node_index(index_name)
256
+ @neo.batch [:drop_node_index, index_name]
257
+ expect(@neo.list_node_indexes[index_name]).to be_nil
258
+ end
259
+
260
+ it "can create a node index" do
261
+ index_name = generate_text(6)
262
+ @neo.batch [:create_node_index, index_name, "fulltext", "lucene"]
263
+ indexes = @neo.list_node_indexes
264
+ index = indexes[index_name]
265
+ expect(index).not_to be_nil
266
+ expect(index["provider"]).to eq("lucene")
267
+ expect(index["type"]).to eq("fulltext")
268
+ end
269
+
270
+ it "can add a node to an index" do
271
+ index_name = generate_text(6)
272
+ new_node = @neo.create_node
273
+ key = generate_text(6)
274
+ value = generate_text
275
+ batch_result = @neo.batch [:add_node_to_index, index_name, key, value, new_node]
276
+ expect(batch_result.first).to have_key("id")
277
+ expect(batch_result.first).to have_key("from")
278
+ existing_index = @neo.find_node_index(index_name, key, value)
279
+ expect(existing_index).not_to be_nil
280
+ expect(existing_index.first["self"]).to eq(new_node["self"])
281
+ @neo.remove_node_from_index(index_name, key, value, new_node)
282
+ end
283
+
284
+ it "can get a node index" do
285
+ index_name = generate_text(6)
286
+ key = generate_text(6)
287
+ value = generate_text
288
+ @neo.create_node_index(index_name)
289
+ new_node = @neo.create_node
290
+ @neo.add_node_to_index(index_name, key, value, new_node)
291
+ batch_result = @neo.batch [:get_node_index, index_name, key, value]
292
+ expect(batch_result.first).to have_key("id")
293
+ expect(batch_result.first).to have_key("from")
294
+ expect(batch_result.first["body"].first["self"]).to eq(new_node["self"])
295
+ @neo.remove_node_from_index(index_name, key, value, new_node)
296
+ end
297
+
298
+ it "can get a relationship index" do
299
+ index_name = generate_text(6)
300
+ key = generate_text(6)
301
+ value = generate_text
302
+ @neo.create_relationship_index(index_name)
303
+ node1 = @neo.create_node
304
+ node2 = @neo.create_node
305
+ new_relationship = @neo.create_relationship("friends", node1, node2, {:since => "high school"})
306
+ @neo.add_relationship_to_index(index_name, key, value, new_relationship)
307
+ batch_result = @neo.batch [:get_relationship_index, index_name, key, value]
308
+ expect(batch_result.first).to have_key("id")
309
+ expect(batch_result.first).to have_key("from")
310
+ expect(batch_result.first["body"].first["type"]).to eq("friends")
311
+ expect(batch_result.first["body"].first["start"].split('/').last).to eq(node1["self"].split('/').last)
312
+ expect(batch_result.first["body"].first["end"].split('/').last).to eq(node2["self"].split('/').last)
313
+ end
314
+
315
+ it "can batch gremlin", :gremlin => true do
316
+ batch_result = @neo.batch [:execute_script, "g.v(0)"]
317
+ expect(batch_result.first).to have_key("id")
318
+ expect(batch_result.first).to have_key("from")
319
+ expect(batch_result.first["body"]["self"].split('/').last).to eq("0")
320
+ end
321
+
322
+ it "can batch gremlin with parameters", :gremlin => true do
323
+ new_node = @neo.create_node
324
+ id = new_node["self"].split('/').last
325
+ batch_result = @neo.batch [:execute_script, "g.v(id)", {:id => id.to_i}]
326
+ expect(batch_result.first).to have_key("id")
327
+ expect(batch_result.first).to have_key("from")
328
+ expect(batch_result.first["body"]["self"].split('/').last).to eq(id)
329
+ end
330
+
331
+ it "can batch cypher" do
332
+ batch_result = @neo.batch [:execute_query, "start n=node(0) return n"]
333
+ expect(batch_result.first).to have_key("id")
334
+ expect(batch_result.first).to have_key("from")
335
+ expect(batch_result.first["body"]["data"][0][0]["self"].split('/').last).to eq("0")
336
+ end
337
+
338
+ it "can batch cypher with parameters" do
339
+ new_node = @neo.create_node
340
+ id = new_node["self"].split('/').last
341
+ batch_result = @neo.batch [:execute_query, "start n=node({id}) return n", {:id => id.to_i}]
342
+ expect(batch_result.first).to have_key("id")
343
+ expect(batch_result.first).to have_key("from")
344
+ expect(batch_result.first["body"]["data"][0][0]["self"].split('/').last).to eq(id)
345
+ end
346
+
347
+ it "raises ParameterNotFoundException when a cypher parameter is missing and ORDER BY is used" do
348
+ q = "MATCH n WHERE n.x>{missing_parameter} RETURN n ORDER BY n"
349
+ expect{
350
+ @neo.batch [:execute_query, q, {}]
351
+ }.to raise_error Neography::ParameterNotFoundException
352
+ end
353
+
354
+ it "can delete a node in batch" do
355
+ node1 = @neo.create_node
356
+ node2 = @neo.create_node
357
+ id1 = node1['self'].split('/').last
358
+ id2 = node2['self'].split('/').last
359
+ batch_result = @neo.batch [:delete_node, id1 ], [:delete_node, id2]
360
+ expect {
361
+ expect(@neo.get_node(node1)).to be_nil
362
+ }.to raise_error Neography::NodeNotFoundException
363
+ expect {
364
+ expect(@neo.get_node(node2)).to be_nil
365
+ }.to raise_error Neography::NodeNotFoundException
366
+ end
367
+
368
+ it "can remove a node from an index in batch " do
369
+ index = generate_text(6)
370
+ key = generate_text(6)
371
+ value1 = generate_text
372
+ value2 = generate_text
373
+ value3 = generate_text
374
+
375
+ node1 = @neo.create_unique_node(index, key, value1, { "name" => "Max" })
376
+ node2 = @neo.create_unique_node(index, key, value2, { "name" => "Neo" })
377
+ node3 = @neo.create_unique_node(index, key, value3, { "name" => "Samir"})
378
+
379
+ batch_result = @neo.batch [:remove_node_from_index, index, key, value1, node1 ],
380
+ [:remove_node_from_index, index, key, node2 ],
381
+ [:remove_node_from_index, index, node3 ]
382
+
383
+ expect(@neo.get_node_index(index, key, value1)).to be_nil
384
+ expect(@neo.get_node_index(index, key, value2)).to be_nil
385
+ expect(@neo.get_node_index(index, key, value3)).to be_nil
386
+ end
387
+
388
+ it "can remove a relationship from an index in batch" do
389
+ index = generate_text(6)
390
+ key = generate_text(6)
391
+ value1 = generate_text
392
+ value2 = generate_text
393
+
394
+ node1 = @neo.create_node
395
+ node2 = @neo.create_node
396
+ relationship1 = @neo.create_unique_relationship(index, key, value1, "friends", node1, node2)
397
+ relationship2 = @neo.create_unique_relationship(index, key, value2, "friends", node2, node1)
398
+
399
+ batch_result = @neo.batch [:remove_relationship_from_index, index, key, relationship1],
400
+ [:remove_relationship_from_index, index, key, relationship2]
401
+
402
+ expect(@neo.get_relationship_index(index, key, value1)).to be_nil
403
+ expect(@neo.get_relationship_index(index, key, value2)).to be_nil
404
+ end
405
+
406
+ it "can do spatial via Cypher in batch" do
407
+ properties = {:lat => 60.1, :lon => 15.2}
408
+ node = @neo.create_node(properties)
409
+ batch_result = @neo.batch [:create_spatial_index, "geobatchcypher", "point", "lat", "lon"],
410
+ [:add_node_to_spatial_index, "geobatchcypher", node],
411
+ [:execute_query, "start n = node:geobatchcypher({withinDistance}) return n", {:withinDistance => "withinDistance:[60.0,15.0,100.0]"}],
412
+ [:execute_query, "start n = node:geobatchcypher({bbox}) return n", {:bbox => "bbox:[15.0,15.3,60.0,60.2]"}]
413
+
414
+ expect(batch_result[0]["body"]["provider"]).to eq("spatial")
415
+ expect(batch_result[0]["body"]["geometry_type"]).to eq("point")
416
+ expect(batch_result[0]["body"]["lat"]).to eq("lat")
417
+ expect(batch_result[0]["body"]["lon"]).to eq("lon")
418
+ expect(batch_result[1]["from"]).to eq("/index/node/geobatchcypher")
419
+ expect(batch_result[1]["body"]["data"]).to eq({"lat" => 60.1, "lon" => 15.2})
420
+ expect(batch_result[2]["body"]["data"]).not_to be_empty
421
+ expect(batch_result[3]["body"]["data"]).not_to be_empty
422
+ end
423
+ end
424
+
425
+ describe "referenced batch" do
426
+ it "can create a relationship from two newly created nodes" do
427
+ batch_result = @neo.batch [:create_node, {"name" => "Max"}], [:create_node, {"name" => "Marc"}], [:create_relationship, "friends", "{0}", "{1}", {:since => "high school"}]
428
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Max")
429
+ expect(batch_result[1]["body"]["data"]["name"]).to eq("Marc")
430
+ expect(batch_result.last["body"]["type"]).to eq("friends")
431
+ expect(batch_result.last["body"]["data"]["since"]).to eq("high school")
432
+ expect(batch_result.last["body"]["start"].split('/').last).to eq(batch_result.first["body"]["self"].split('/').last)
433
+ expect(batch_result.last["body"]["end"].split('/').last).to eq(batch_result[1]["body"]["self"].split('/').last)
434
+ end
435
+
436
+ it "can create a relationship from an existing node and a newly created node" do
437
+ node1 = @neo.create_node("name" => "Max", "weight" => 200)
438
+ batch_result = @neo.batch [:create_node, {"name" => "Marc"}], [:create_relationship, "friends", "{0}", node1, {:since => "high school"}]
439
+ expect(batch_result.first["body"]["data"]["name"]).to eq("Marc")
440
+ expect(batch_result.last["body"]["type"]).to eq("friends")
441
+ expect(batch_result.last["body"]["data"]["since"]).to eq("high school")
442
+ expect(batch_result.last["body"]["start"].split('/').last).to eq(batch_result.first["body"]["self"].split('/').last)
443
+ expect(batch_result.last["body"]["end"].split('/').last).to eq(node1["self"].split('/').last)
444
+ end
445
+
446
+ it "can add a newly created node to an index" do
447
+ key = generate_text(6)
448
+ value = generate_text
449
+ batch_result = @neo.batch [:create_node, {"name" => "Max"}], [:add_node_to_index, "test_node_index", key, value, "{0}"]
450
+ expect(batch_result.first).to have_key("id")
451
+ expect(batch_result.first).to have_key("from")
452
+ existing_index = @neo.find_node_index("test_node_index", key, value)
453
+ expect(existing_index).not_to be_nil
454
+ expect(existing_index.first["self"]).to eq(batch_result.first["body"]["self"])
455
+ @neo.remove_node_from_index("test_node_index", key, value, batch_result.first["body"]["self"].split('/').last)
456
+ end
457
+
458
+ it "can add a newly created relationship to an index" do
459
+ key = generate_text(6)
460
+ value = generate_text
461
+ node1 = @neo.create_node
462
+ node2 = @neo.create_node
463
+ batch_result = @neo.batch [:create_relationship, "friends", node1, node2, {:since => "high school"}], [:add_relationship_to_index, "test_relationship_index", key, value, "{0}"]
464
+ expect(batch_result.first["body"]["type"]).to eq("friends")
465
+ expect(batch_result.first["body"]["data"]["since"]).to eq("high school")
466
+ expect(batch_result.first["body"]["start"].split('/').last).to eq(node1["self"].split('/').last)
467
+ expect(batch_result.first["body"]["end"].split('/').last).to eq(node2["self"].split('/').last)
468
+ existing_index = @neo.find_relationship_index("test_relationship_index", key, value)
469
+ expect(existing_index).not_to be_nil
470
+ expect(existing_index.first["self"]).to eq(batch_result.first["body"]["self"])
471
+ end
472
+
473
+ it "can reset the properties of a newly created relationship" do
474
+ node1 = @neo.create_node
475
+ node2 = @neo.create_node
476
+ batch_result = @neo.batch [:create_relationship, "friends", node1, node2, {:since => "high school"}], [:reset_relationship_properties, "{0}", {"since" => "college", "dated" => "yes"}]
477
+ expect(batch_result.first).to have_key("id")
478
+ expect(batch_result.first).to have_key("from")
479
+ existing_relationship = @neo.get_relationship(batch_result.first["body"]["self"].split('/').last)
480
+ expect(existing_relationship["type"]).to eq("friends")
481
+ expect(existing_relationship["data"]["since"]).to eq("college")
482
+ expect(existing_relationship["data"]["dated"]).to eq("yes")
483
+ expect(existing_relationship["start"].split('/').last).to eq(node1["self"].split('/').last)
484
+ expect(existing_relationship["end"].split('/').last).to eq(node2["self"].split('/').last)
485
+ expect(existing_relationship["self"]).to eq(batch_result.first["body"]["self"])
486
+ end
487
+
488
+ it "can kitchen sink" do
489
+ key = generate_text(6)
490
+ value = generate_text
491
+
492
+ batch_result = @neo.batch [:create_node, {"name" => "Max"}],
493
+ [:create_node, {"name" => "Marc"}],
494
+ [:add_node_to_index, "test_node_index", key, value, "{0}"]
495
+ [:add_node_to_index, "test_node_index", key, value, "{1}"]
496
+ [:create_relationship, "friends", "{0}", "{1}", {:since => "college"}]
497
+ [:add_relationship_to_index, "test_relationship_index", key, value, "{4}"]
498
+ expect(batch_result).not_to be_nil
499
+ end
500
+
501
+ it "can get multiple relationships" do
502
+ node1 = @neo.create_node
503
+ node2 = @neo.create_node
504
+ node3 = @neo.create_node
505
+ new_relationship1 = @neo.create_relationship("friends", node1, node2)
506
+ new_relationship2 = @neo.create_relationship("brothers", node1, node3)
507
+ batch_result = @neo.batch [:get_node_relationships, node1]
508
+ expect(batch_result.first["body"].length).to be(2)
509
+ expect(batch_result.first["body"][0]["type"]).to eq("friends")
510
+ expect(batch_result.first["body"][0]["start"].split('/').last).to eq(node1["self"].split('/').last)
511
+ expect(batch_result.first["body"][0]["end"].split('/').last).to eq(node2["self"].split('/').last)
512
+ expect(batch_result.first["body"][0]["self"]).to eq(new_relationship1["self"])
513
+ expect(batch_result.first["body"][1]["type"]).to eq("brothers")
514
+ expect(batch_result.first["body"][1]["start"].split('/').last).to eq(node1["self"].split('/').last)
515
+ expect(batch_result.first["body"][1]["end"].split('/').last).to eq(node3["self"].split('/').last)
516
+ expect(batch_result.first["body"][1]["self"]).to eq(new_relationship2["self"])
517
+ end
518
+
519
+ it "can get relationships of specific type" do
520
+ node1 = @neo.create_node
521
+ node2 = @neo.create_node
522
+ node3 = @neo.create_node
523
+ new_relationship1 = @neo.create_relationship("friends", node1, node2)
524
+ new_relationship2 = @neo.create_relationship("brothers", node1, node3)
525
+ batch_result = @neo.batch [:get_node_relationships, node1, "out", "friends"]
526
+ expect(batch_result.first["body"].length).to be(1)
527
+ expect(batch_result.first["body"][0]["type"]).to eq("friends")
528
+ expect(batch_result.first["body"][0]["start"].split('/').last).to eq(node1["self"].split('/').last)
529
+ expect(batch_result.first["body"][0]["end"].split('/').last).to eq(node2["self"].split('/').last)
530
+ expect(batch_result.first["body"][0]["self"]).to eq(new_relationship1["self"])
531
+ end
532
+
533
+ it "can create a relationship from a unique node" do
534
+ batch_result = @neo.batch [:create_node, {:street1=>"94437 Kemmer Crossing", :street2=>"Apt. 333", :city=>"Abshireton", :state=>"AA", :zip=>"65820", :_type=>"Address", :created_at=>1335269478}],
535
+ [:add_node_to_index, "person_ssn", "ssn", "000-00-0001", "{0}"],
536
+ [:create_unique_node, "person", "ssn", "000-00-0001", {:first_name=>"Jane", :last_name=>"Doe", :ssn=>"000-00-0001", :_type=>"Person", :created_at=>1335269478}],
537
+ [:create_relationship, "has", "{0}", "{2}", {}]
538
+ expect(batch_result).not_to be_nil
539
+
540
+ # create_unique_node is returning an index result, not a node, so we can't do this yet.
541
+ # See https://github.com/neo4j/community/issues/697
542
+
543
+ expect {
544
+ batch_result = @neo.batch [:create_unique_node, "person", "ssn", "000-00-0001", {:first_name=>"Jane", :last_name=>"Doe", :ssn=>"000-00-0001", :_type=>"Person", :created_at=>1335269478}],
545
+ [:add_node_to_index, "person_ssn", "ssn", "000-00-0001", "{0}"],
546
+ [:create_node, {:street1=>"94437 Kemmer Crossing", :street2=>"Apt. 333", :city=>"Abshireton", :state=>"AA", :zip=>"65820", :_type=>"Address", :created_at=>1335269478}],
547
+ [:create_relationship, "has", "{0}", "{2}", {}]
548
+ }.to raise_error(Neography::NeographyError)
549
+
550
+ begin
551
+ batch_result = @neo.batch [:create_unique_node, "person", "ssn", "000-00-0001", {:first_name=>"Jane", :last_name=>"Doe", :ssn=>"000-00-0001", :_type=>"Person", :created_at=>1335269478}],
552
+ [:add_node_to_index, "person_ssn", "ssn", "000-00-0001", "{0}"],
553
+ [:create_node, {:street1=>"94437 Kemmer Crossing", :street2=>"Apt. 333", :city=>"Abshireton", :state=>"AA", :zip=>"65820", :_type=>"Address", :created_at=>1335269478}],
554
+ [:create_relationship, "has", "{0}", "{2}", {}]
555
+ rescue Neography::NeographyError => e
556
+ expect(e.message).to eq("Not Found")
557
+ expect(e.code).to eq(404)
558
+ expect(e.stacktrace).to be_nil
559
+ expect(e.request[:path]).to eq("/db/data/batch")
560
+ expect(e.request[:body]).not_to be_nil
561
+ expect(e.index).to eq(3)
562
+ end
563
+ end
564
+
565
+ end
566
+
567
+ describe "broken queries" do
568
+ it "should return errors when bad syntax is passed in batch" do
569
+ batch_commands = []
570
+
571
+ batch_commands << [ :execute_query, "start person_n=node:person(ssn = '000-00-0002')
572
+ set bar1 = {foo}",
573
+ { :other => "what" }
574
+ ]
575
+
576
+ expect {
577
+ batch_result = @neo.batch *batch_commands
578
+ }.to raise_exception Neography::SyntaxException
579
+
580
+ expect {
581
+ @neo.execute_query("start person_n=node:person(ssn = '000-00-0001')
582
+ set bar = {foo}",
583
+ { :other => "what" })
584
+ }.to raise_exception Neography::SyntaxException
585
+
586
+
587
+ end
588
+ end
589
+
590
+ describe "batch unknown option" do
591
+ it "should raise Neography::UnknownBatchOptionException when bad option is passed in batch" do
592
+ batch_commands = []
593
+
594
+ batch_commands << [ :bad_option, "start person_n=node:person(ssn = '000-00-0002')
595
+ set bar1 = {foo}"]
596
+
597
+ expect {
598
+ batch_result = @neo.batch *batch_commands
599
+ }.to raise_exception Neography::UnknownBatchOptionException
600
+
601
+ end
602
+ end
603
+
604
+ end