neo4j-core 3.1.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -12
  3. data/README.md +7 -7
  4. data/lib/neo4j-core.rb +3 -2
  5. data/lib/neo4j-core/active_entity.rb +8 -10
  6. data/lib/neo4j-core/cypher_translator.rb +61 -59
  7. data/lib/neo4j-core/hash_with_indifferent_access.rb +31 -22
  8. data/lib/neo4j-core/helpers.rb +15 -17
  9. data/lib/neo4j-core/label.rb +7 -6
  10. data/lib/neo4j-core/query.rb +271 -268
  11. data/lib/neo4j-core/query_clauses.rb +371 -355
  12. data/lib/neo4j-core/query_find_in_batches.rb +26 -26
  13. data/lib/neo4j-core/version.rb +1 -1
  14. data/lib/neo4j-embedded.rb +2 -2
  15. data/lib/neo4j-embedded/cypher_response.rb +40 -41
  16. data/lib/neo4j-embedded/embedded_database.rb +21 -22
  17. data/lib/neo4j-embedded/embedded_ha_session.rb +13 -11
  18. data/lib/neo4j-embedded/embedded_impermanent_session.rb +9 -8
  19. data/lib/neo4j-embedded/embedded_label.rb +64 -70
  20. data/lib/neo4j-embedded/embedded_node.rb +68 -73
  21. data/lib/neo4j-embedded/embedded_relationship.rb +6 -13
  22. data/lib/neo4j-embedded/embedded_session.rb +128 -132
  23. data/lib/neo4j-embedded/embedded_transaction.rb +34 -33
  24. data/lib/neo4j-embedded/property.rb +84 -77
  25. data/lib/neo4j-embedded/to_java.rb +24 -23
  26. data/lib/neo4j-server.rb +1 -1
  27. data/lib/neo4j-server/cypher_authentication.rb +105 -103
  28. data/lib/neo4j-server/cypher_label.rb +25 -23
  29. data/lib/neo4j-server/cypher_node.rb +180 -177
  30. data/lib/neo4j-server/cypher_node_uncommited.rb +11 -9
  31. data/lib/neo4j-server/cypher_relationship.rb +101 -102
  32. data/lib/neo4j-server/cypher_response.rb +171 -170
  33. data/lib/neo4j-server/cypher_session.rb +209 -205
  34. data/lib/neo4j-server/cypher_transaction.rb +66 -48
  35. data/lib/neo4j-server/resource.rb +17 -22
  36. data/lib/neo4j/entity_equality.rb +3 -4
  37. data/lib/neo4j/label.rb +13 -16
  38. data/lib/neo4j/node.rb +30 -34
  39. data/lib/neo4j/property_container.rb +3 -3
  40. data/lib/neo4j/property_validator.rb +4 -5
  41. data/lib/neo4j/relationship.rb +17 -22
  42. data/lib/neo4j/session.rb +19 -21
  43. data/lib/neo4j/tasks/config_server.rb +2 -3
  44. data/lib/neo4j/tasks/neo4j_server.rake +82 -74
  45. data/lib/neo4j/transaction.rb +23 -22
  46. data/neo4j-core.gemspec +21 -16
  47. metadata +72 -2
@@ -1,496 +1,512 @@
1
- module Neo4j::Core
2
- module QueryClauses
3
-
4
- class ArgError < StandardError
5
- attr_reader :arg_part
6
- def initialize(arg_part = nil)
7
- super
8
- @arg_part = arg_part
1
+ module Neo4j
2
+ module Core
3
+ module QueryClauses
4
+ class ArgError < StandardError
5
+ attr_reader :arg_part
6
+ def initialize(arg_part = nil)
7
+ super
8
+ @arg_part = arg_part
9
+ end
9
10
  end
10
- end
11
11
 
12
12
 
13
- class Clause
14
- include CypherTranslator
13
+ class Clause
14
+ include CypherTranslator
15
15
 
16
- attr_reader :params
16
+ attr_reader :params
17
17
 
18
- def initialize(arg, options = {})
19
- @arg = arg
20
- @options = options
21
- @params = {}
22
- end
18
+ def initialize(arg, options = {})
19
+ @arg = arg
20
+ @options = options
21
+ @params = {}
22
+ end
23
23
 
24
- def value
25
- if @arg.is_a?(String)
26
- self.from_string @arg
24
+ def value
25
+ [String, Symbol, Integer, Hash].each do |arg_class|
26
+ from_method = "from_#{arg_class.name.downcase}"
27
+ return send(from_method, @arg) if @arg.is_a?(arg_class) && self.respond_to?(from_method)
28
+ end
27
29
 
28
- elsif @arg.is_a?(Symbol) && self.respond_to?(:from_symbol)
29
- self.from_symbol @arg
30
+ fail ArgError
31
+ rescue ArgError => arg_error
32
+ message = "Invalid argument for #{self.class.keyword}. Full arguments: #{@arg.inspect}"
33
+ message += " | Invalid part: #{arg_error.arg_part.inspect}" if arg_error.arg_part
30
34
 
31
- elsif @arg.is_a?(Integer) && self.respond_to?(:from_integer)
32
- self.from_integer @arg
35
+ raise ArgumentError, message
36
+ end
33
37
 
34
- elsif @arg.is_a?(Hash)
35
- if self.respond_to?(:from_hash)
36
- self.from_hash @arg
37
- elsif self.respond_to?(:from_key_and_value)
38
- @arg.map do |key, value|
39
- self.from_key_and_value key, value
38
+ def from_hash(value)
39
+ if self.respond_to?(:from_key_and_value)
40
+ value.map do |k, v|
41
+ from_key_and_value k, v
40
42
  end
41
43
  else
42
- raise ArgError.new
44
+ fail ArgError
43
45
  end
44
-
45
- else
46
- raise ArgError.new
47
46
  end
48
47
 
49
- rescue ArgError => arg_error
50
- message = "Invalid argument for #{self.class.keyword}. Full arguments: #{@arg.inspect}"
51
- message += " | Invalid part: #{arg_error.arg_part.inspect}" if arg_error.arg_part
48
+ def from_string(value)
49
+ value
50
+ end
52
51
 
53
- raise ArgumentError, message
54
- end
52
+ def node_from_key_and_value(key, value, options = {})
53
+ var = var_from_key_and_value(key, value, options[:prefer] || :var)
54
+ label = label_from_key_and_value(key, value, options[:prefer] || :var)
55
+ attributes = attributes_from_key_and_value(key, value)
55
56
 
56
- def from_string(value)
57
- value
58
- end
57
+ "(#{var}#{format_label(label)}#{attributes_string(attributes)})"
58
+ end
59
59
 
60
- def node_from_key_and_value(key, value, options = {})
61
- prefer = options[:prefer] || :var
62
-
63
- var, label_string, attributes_string = nil
64
-
65
- case value
66
- when String, Symbol
67
- var = key
68
- label_string = value
69
- when Hash
70
- if !value.values.any? {|v| v.is_a?(Hash) }
71
- case prefer
72
- when :var
73
- var = key
74
- when :label
75
- label_string = key
60
+ def var_from_key_and_value(key, value, prefer = :var)
61
+ case value
62
+ when String, Symbol, Class, Module
63
+ key
64
+ when Hash
65
+ if value.values.none? { |v| v.is_a?(Hash) }
66
+ key if prefer == :var
67
+ else
68
+ key
76
69
  end
77
70
  else
78
- var = key
71
+ fail ArgError, value
79
72
  end
73
+ end
80
74
 
81
- if value.size == 1 && value.values.first.is_a?(Hash)
82
- label_string, attributes = value.first
83
- attributes_string = attributes_string(attributes)
75
+ def label_from_key_and_value(key, value, prefer = :var)
76
+ case value
77
+ when String, Symbol
78
+ value
79
+ when Class, Module
80
+ defined?(value::CYPHER_LABEL) ? value::CYPHER_LABEL : value.name
81
+ when Hash
82
+ if value.values.map(&:class) == [Hash]
83
+ value.first.first
84
+ else
85
+ key if value.values.none? { |v| v.is_a?(Hash) } && prefer == :label
86
+ end
84
87
  else
85
- attributes_string = attributes_string(value)
88
+ fail ArgError, value
86
89
  end
87
- when Class, Module
88
- var = key
89
- label_string = defined?(value::CYPHER_LABEL) ? value::CYPHER_LABEL : value.name
90
- else
91
- raise ArgError.new(value)
92
90
  end
93
91
 
94
- "(#{var}#{format_label(label_string)}#{attributes_string})"
95
- end
96
-
97
- class << self
98
- attr_reader :keyword
92
+ def attributes_from_key_and_value(key, value)
93
+ return nil unless value.is_a?(Hash)
99
94
 
100
- def from_args(args, options = {})
101
- args.flatten.map do |arg|
102
- if !arg.respond_to?(:empty?) || !arg.empty?
103
- self.new(arg, options)
104
- end
105
- end.compact
95
+ if value.values.map(&:class) == [Hash]
96
+ value.first[1]
97
+ else
98
+ value
99
+ end
106
100
  end
107
101
 
108
- def to_cypher(clauses)
109
- string = clause_string(clauses)
102
+ class << self
103
+ attr_reader :keyword
104
+
105
+ def from_args(args, options = {})
106
+ args.flatten.map do |arg|
107
+ new(arg, options) if !arg.respond_to?(:empty?) || !arg.empty?
108
+ end.compact
109
+ end
110
+
111
+ def to_cypher(clauses)
112
+ string = clause_string(clauses)
113
+ string.strip!
110
114
 
111
- "#{@keyword} #{string}" if string.to_s.strip.size > 0
115
+ "#{@keyword} #{string}" if string.size > 0
116
+ end
112
117
  end
113
- end
114
118
 
115
- private
119
+ private
116
120
 
117
- def key_value_string(key, value, previous_keys = [], force_equals = false)
118
- param = (previous_keys + [key]).join('_').gsub(/[^a-z0-9]+/i, '_').gsub(/^_+|_+$/, '')
119
- @params[param.to_sym] = value
121
+ def key_value_string(key, value, previous_keys = [], force_equals = false)
122
+ param = (previous_keys << key).join('_')
123
+ param.gsub!(/[^a-z0-9]+/i, '_')
124
+ param.gsub!(/^_+|_+$/, '')
125
+ @params[param.to_sym] = value
120
126
 
121
- if !value.is_a?(Array) || force_equals
122
- "#{key} = {#{param}}"
123
- else
124
- "#{key} IN {#{param}}"
127
+ if !value.is_a?(Array) || force_equals
128
+ "#{key} = {#{param}}"
129
+ else
130
+ "#{key} IN {#{param}}"
131
+ end
125
132
  end
126
- end
127
133
 
128
- def format_label(label_string)
129
- label_string = label_string.to_s.strip
130
- if !label_string.empty? && label_string[0] != ':'
131
- label_string = "`#{label_string}`" unless label_string.match(' ')
132
- label_string = ":#{label_string}"
134
+ def format_label(label_string)
135
+ label_string = label_string.to_s
136
+ label_string.strip!
137
+ if !label_string.empty? && label_string[0] != ':'
138
+ label_string = "`#{label_string}`" unless label_string.match(' ')
139
+ label_string = ":#{label_string}"
140
+ end
141
+ label_string
133
142
  end
134
- label_string
135
- end
136
143
 
137
- def attributes_string(attributes)
138
- attributes_string = attributes.map do |key, value|
139
- v = if value.nil?
140
- 'null'
141
- else
142
- value.to_s.match(/^{.+}$/) ? value : value.inspect
143
- end
144
- "#{key}: #{v}"
145
- end.join(', ')
144
+ def attributes_string(attributes)
145
+ return '' if not attributes
146
146
 
147
- " {#{attributes_string}}"
147
+ attributes_string = attributes.map do |key, value|
148
+ v = if value.nil?
149
+ 'null'
150
+ else
151
+ value.to_s.match(/^{.+}$/) ? value : value.inspect
152
+ end
153
+ "#{key}: #{v}"
154
+ end.join(', ')
155
+
156
+ " {#{attributes_string}}"
157
+ end
148
158
  end
149
- end
150
159
 
151
- class StartClause < Clause
152
- @keyword = 'START'
160
+ class StartClause < Clause
161
+ @keyword = 'START'
153
162
 
154
- def from_symbol(value)
155
- from_string(value.to_s)
156
- end
163
+ def from_symbol(value)
164
+ from_string(value.to_s)
165
+ end
157
166
 
158
- def from_key_and_value(key, value)
159
- case value
160
- when String, Symbol
161
- "#{key} = #{value}"
162
- else
163
- raise ArgError.new(value)
167
+ def from_key_and_value(key, value)
168
+ case value
169
+ when String, Symbol
170
+ "#{key} = #{value}"
171
+ else
172
+ fail ArgError, value
173
+ end
164
174
  end
165
- end
166
175
 
167
- class << self
168
- def clause_string(clauses)
169
- clauses.map(&:value).join(', ')
176
+ class << self
177
+ def clause_string(clauses)
178
+ clauses.map!(&:value).join(', ')
179
+ end
170
180
  end
171
181
  end
172
- end
173
182
 
174
- class WhereClause < Clause
175
- @keyword = 'WHERE'
183
+ class WhereClause < Clause
184
+ @keyword = 'WHERE'
176
185
 
177
- def from_key_and_value(key, value, previous_keys = [])
178
- case value
179
- when Hash
180
- value.map do |k, v|
181
- if k.to_sym == :neo_id
182
- "ID(#{key}) = #{v.to_i}"
183
- else
184
- key.to_s + '.' + from_key_and_value(k, v, previous_keys + [key])
185
- end
186
- end.join(' AND ')
187
- when NilClass
188
- "#{key} IS NULL"
189
- when Regexp
190
- pattern = (value.casefold? ? "(?i)" : "") + value.source
191
- "#{key} =~ #{escape_value(pattern.gsub(/\\/, '\\\\\\'))}"
192
- when Array
193
- key_value_string(key, value, previous_keys)
194
- else
195
- key_value_string(key, value, previous_keys)
186
+ def from_key_and_value(key, value, previous_keys = [])
187
+ case value
188
+ when Hash
189
+ value.map do |k, v|
190
+ if k.to_sym == :neo_id
191
+ clause_id = "neo_id_#{v}"
192
+ @params[clause_id] = v.to_i
193
+ "ID(#{key}) = {#{clause_id}}"
194
+ else
195
+ "#{key}.#{from_key_and_value(k, v, previous_keys + [key])}"
196
+ end
197
+ end.join(' AND ')
198
+ when NilClass
199
+ "#{key} IS NULL"
200
+ when Regexp
201
+ pattern = (value.casefold? ? '(?i)' : '') + value.source
202
+ "#{key} =~ #{escape_value(pattern.gsub(/\\/, '\\\\\\'))}"
203
+ when Array
204
+ key_value_string(key, value, previous_keys)
205
+ else
206
+ key_value_string(key, value, previous_keys)
207
+ end
196
208
  end
197
- end
198
209
 
199
- class << self
200
- def clause_string(clauses)
201
- clauses.map(&:value).join(' AND ')
210
+ class << self
211
+ def clause_string(clauses)
212
+ clauses.map!(&:value).join(' AND ')
213
+ end
202
214
  end
203
215
  end
204
- end
205
216
 
206
217
 
207
- class MatchClause < Clause
208
- @keyword = 'MATCH'
218
+ class MatchClause < Clause
219
+ @keyword = 'MATCH'
209
220
 
210
- def from_symbol(value)
211
- from_string(value.to_s)
212
- end
221
+ def from_symbol(value)
222
+ from_string(value.to_s)
223
+ end
213
224
 
214
- def from_key_and_value(key, value)
215
- self.node_from_key_and_value(key, value)
216
- end
225
+ def from_key_and_value(key, value)
226
+ node_from_key_and_value(key, value)
227
+ end
217
228
 
218
- class << self
219
- def clause_string(clauses)
220
- clauses.map(&:value).join(', ')
229
+ class << self
230
+ def clause_string(clauses)
231
+ clauses.map!(&:value).join(', ')
232
+ end
221
233
  end
222
234
  end
223
- end
224
235
 
225
- class OptionalMatchClause < MatchClause
226
- @keyword = 'OPTIONAL MATCH'
227
- end
236
+ class OptionalMatchClause < MatchClause
237
+ @keyword = 'OPTIONAL MATCH'
238
+ end
228
239
 
229
- class WithClause < Clause
230
- @keyword = 'WITH'
240
+ class WithClause < Clause
241
+ @keyword = 'WITH'
231
242
 
232
- def from_symbol(value)
233
- from_string(value.to_s)
234
- end
243
+ def from_symbol(value)
244
+ from_string(value.to_s)
245
+ end
235
246
 
236
- def from_key_and_value(key, value)
237
- "#{value} AS #{key}"
238
- end
247
+ def from_key_and_value(key, value)
248
+ "#{value} AS #{key}"
249
+ end
239
250
 
240
- class << self
241
- def clause_string(clauses)
242
- clauses.map(&:value).join(', ')
251
+ class << self
252
+ def clause_string(clauses)
253
+ clauses.map!(&:value).join(', ')
254
+ end
243
255
  end
244
256
  end
245
- end
246
257
 
247
- class UsingClause < Clause
248
- @keyword = 'USING'
258
+ class UsingClause < Clause
259
+ @keyword = 'USING'
249
260
 
250
- class << self
251
- def clause_string(clauses)
252
- clauses.map(&:value).join(" #{@keyword} ")
261
+ class << self
262
+ def clause_string(clauses)
263
+ clauses.map!(&:value).join(" #{@keyword} ")
264
+ end
253
265
  end
254
266
  end
255
- end
256
267
 
257
- class CreateClause < Clause
258
- @keyword = 'CREATE'
268
+ class CreateClause < Clause
269
+ @keyword = 'CREATE'
259
270
 
260
- def from_string(value)
261
- value
262
- end
271
+ def from_string(value)
272
+ value
273
+ end
263
274
 
264
- def from_symbol(value)
265
- "(:#{value})"
266
- end
275
+ def from_symbol(value)
276
+ "(:#{value})"
277
+ end
267
278
 
268
- def from_hash(hash)
269
- if hash.values.any? {|value| value.is_a?(Hash) }
270
- hash.map do |key, value|
271
- from_key_and_value(key, value)
279
+ def from_hash(hash)
280
+ if hash.values.any? { |value| value.is_a?(Hash) }
281
+ hash.map do |key, value|
282
+ from_key_and_value(key, value)
283
+ end
284
+ else
285
+ "(#{attributes_string(hash)})"
272
286
  end
273
- else
274
- "(#{attributes_string(hash)})"
275
287
  end
276
- end
277
288
 
278
- def from_key_and_value(key, value)
279
- self.node_from_key_and_value(key, value, prefer: :label)
280
- end
289
+ def from_key_and_value(key, value)
290
+ node_from_key_and_value(key, value, prefer: :label)
291
+ end
281
292
 
282
- class << self
283
- def clause_string(clauses)
284
- clauses.map(&:value).join(', ')
293
+ class << self
294
+ def clause_string(clauses)
295
+ clauses.map!(&:value).join(', ')
296
+ end
285
297
  end
286
298
  end
287
- end
288
299
 
289
- class CreateUniqueClause < CreateClause
290
- @keyword = 'CREATE UNIQUE'
291
- end
300
+ class CreateUniqueClause < CreateClause
301
+ @keyword = 'CREATE UNIQUE'
302
+ end
292
303
 
293
- class MergeClause < CreateClause
294
- @keyword = 'MERGE'
295
- end
304
+ class MergeClause < CreateClause
305
+ @keyword = 'MERGE'
306
+ end
296
307
 
297
- class DeleteClause < Clause
298
- @keyword = 'DELETE'
308
+ class DeleteClause < Clause
309
+ @keyword = 'DELETE'
299
310
 
300
- def from_symbol(value)
301
- from_string(value.to_s)
302
- end
311
+ def from_symbol(value)
312
+ from_string(value.to_s)
313
+ end
303
314
 
304
- class << self
305
- def clause_string(clauses)
306
- clauses.map(&:value).join(', ')
315
+ class << self
316
+ def clause_string(clauses)
317
+ clauses.map!(&:value).join(', ')
318
+ end
307
319
  end
308
320
  end
309
- end
310
321
 
311
- class OrderClause < Clause
312
- @keyword = 'ORDER BY'
322
+ class OrderClause < Clause
323
+ @keyword = 'ORDER BY'
313
324
 
314
- def from_symbol(value)
315
- from_string(value.to_s)
316
- end
325
+ def from_symbol(value)
326
+ from_string(value.to_s)
327
+ end
317
328
 
318
- def from_key_and_value(key, value)
319
- case value
320
- when String, Symbol
321
- "#{key}.#{value}"
322
- when Array
323
- value.map do |v|
324
- if v.is_a?(Hash)
325
- from_key_and_value(key, v)
326
- else
327
- "#{key}.#{v}"
329
+ def from_key_and_value(key, value)
330
+ case value
331
+ when String, Symbol
332
+ "#{key}.#{value}"
333
+ when Array
334
+ value.map do |v|
335
+ if v.is_a?(Hash)
336
+ from_key_and_value(key, v)
337
+ else
338
+ "#{key}.#{v}"
339
+ end
340
+ end
341
+ when Hash
342
+ value.map do |k, v|
343
+ "#{key}.#{k} #{v.upcase}"
328
344
  end
329
- end
330
- when Hash
331
- value.map do |k, v|
332
- "#{key}.#{k} #{v.upcase}"
333
345
  end
334
346
  end
335
- end
336
347
 
337
- class << self
338
- def clause_string(clauses)
339
- clauses.map(&:value).join(', ')
348
+ class << self
349
+ def clause_string(clauses)
350
+ clauses.map!(&:value).join(', ')
351
+ end
340
352
  end
341
353
  end
342
- end
343
354
 
344
- class LimitClause < Clause
345
- @keyword = 'LIMIT'
355
+ class LimitClause < Clause
356
+ @keyword = 'LIMIT'
346
357
 
347
- def from_string(value)
348
- value.to_i
349
- end
358
+ def from_string(value)
359
+ clause_id = "#{self.class.keyword.downcase}_#{value}"
360
+ @params[clause_id] = value.to_i
361
+ "{#{clause_id}}"
362
+ end
350
363
 
351
- def from_integer(value)
352
- value
353
- end
364
+ def from_integer(value)
365
+ clause_id = "#{self.class.keyword.downcase}_#{value}"
366
+ @params[clause_id] = value
367
+ "{#{clause_id}}"
368
+ end
354
369
 
355
- class << self
356
- def clause_string(clauses)
357
- clauses.last.value
370
+ class << self
371
+ def clause_string(clauses)
372
+ clauses.last.value
373
+ end
358
374
  end
359
375
  end
360
- end
361
376
 
362
- class SkipClause < Clause
363
- @keyword = 'SKIP'
377
+ class SkipClause < Clause
378
+ @keyword = 'SKIP'
364
379
 
365
- def from_string(value)
366
- value.to_i
367
- end
380
+ def from_string(value)
381
+ clause_id = "#{self.class.keyword.downcase}_#{value}"
382
+ @params[clause_id] = value.to_i
383
+ "{#{clause_id}}"
384
+ end
368
385
 
369
- def from_integer(value)
370
- value
371
- end
386
+ def from_integer(value)
387
+ clause_id = "#{self.class.keyword.downcase}_#{value}"
388
+ @params[clause_id] = value
389
+ "{#{clause_id}}"
390
+ end
372
391
 
373
- class << self
374
- def clause_string(clauses)
375
- clauses.last.value
392
+ class << self
393
+ def clause_string(clauses)
394
+ clauses.last.value
395
+ end
376
396
  end
377
397
  end
378
- end
379
398
 
380
- class SetClause < Clause
381
- @keyword = 'SET'
382
-
383
- def from_key_and_value(key, value)
384
- case value
385
- when String, Symbol
386
- "#{key} = #{value}"
387
- when Hash
388
- if @options[:set_props]
389
- attribute_string = value.map {|k, v| "#{k}: #{v.inspect}" }.join(', ')
390
- "#{key} = {#{attribute_string}}"
391
- else
392
- value.map do |k, v|
393
- key_value_string("#{key}.`#{k}`", v, ['setter'], true)
399
+ class SetClause < Clause
400
+ @keyword = 'SET'
401
+
402
+ def from_key_and_value(key, value)
403
+ case value
404
+ when String, Symbol
405
+ "#{key} = #{value}"
406
+ when Hash
407
+ if @options[:set_props]
408
+ attribute_string = value.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
409
+ "#{key} = {#{attribute_string}}"
410
+ else
411
+ value.map do |k, v|
412
+ key_value_string("#{key}.`#{k}`", v, ['setter'], true)
413
+ end
394
414
  end
415
+ else
416
+ fail ArgError, value
395
417
  end
396
- else
397
- raise ArgError.new(value)
398
418
  end
399
- end
400
419
 
401
- class << self
402
- def clause_string(clauses)
403
- clauses.map(&:value).join(', ')
420
+ class << self
421
+ def clause_string(clauses)
422
+ clauses.map!(&:value).join(', ')
423
+ end
404
424
  end
405
425
  end
406
- end
407
426
 
408
- class OnCreateSetClause < SetClause
409
- @keyword = 'ON CREATE SET'
427
+ class OnCreateSetClause < SetClause
428
+ @keyword = 'ON CREATE SET'
410
429
 
411
- def initialize(*args)
412
- super
413
- @options[:set_props] = false
430
+ def initialize(*args)
431
+ super
432
+ @options[:set_props] = false
433
+ end
414
434
  end
415
- end
416
435
 
417
- class OnMatchSetClause < OnCreateSetClause
418
- @keyword = 'ON MATCH SET'
419
- end
436
+ class OnMatchSetClause < OnCreateSetClause
437
+ @keyword = 'ON MATCH SET'
438
+ end
420
439
 
421
- class RemoveClause < Clause
422
- @keyword = 'REMOVE'
440
+ class RemoveClause < Clause
441
+ @keyword = 'REMOVE'
423
442
 
424
- def from_key_and_value(key, value)
425
- case value
426
- when /^:/
427
- "#{key}:#{value[1..-1]}"
428
- when String
429
- "#{key}.#{value}"
430
- when Symbol
431
- "#{key}:#{value}"
432
- else
433
- raise ArgError.new(value)
443
+ def from_key_and_value(key, value)
444
+ case value
445
+ when /^:/
446
+ "#{key}:#{value[1..-1]}"
447
+ when String
448
+ "#{key}.#{value}"
449
+ when Symbol
450
+ "#{key}:#{value}"
451
+ else
452
+ fail ArgError, value
453
+ end
434
454
  end
435
455
 
436
- end
437
-
438
- class << self
439
- def clause_string(clauses)
440
- clauses.map(&:value).join(', ')
456
+ class << self
457
+ def clause_string(clauses)
458
+ clauses.map!(&:value).join(', ')
459
+ end
441
460
  end
442
461
  end
443
- end
444
462
 
445
- class UnwindClause < Clause
446
- @keyword = 'UNWIND'
463
+ class UnwindClause < Clause
464
+ @keyword = 'UNWIND'
447
465
 
448
- def from_key_and_value(key, value)
449
- case value
450
- when String, Symbol
451
- "#{value} AS #{key}"
452
- when Array
453
- "#{value.inspect} AS #{key}"
454
- else
455
- raise ArgError.new(value)
466
+ def from_key_and_value(key, value)
467
+ case value
468
+ when String, Symbol
469
+ "#{value} AS #{key}"
470
+ when Array
471
+ "#{value.inspect} AS #{key}"
472
+ else
473
+ fail ArgError, value
474
+ end
456
475
  end
457
- end
458
476
 
459
- class << self
460
- def clause_string(clauses)
461
- clauses.map(&:value).join(' UNWIND ')
477
+ class << self
478
+ def clause_string(clauses)
479
+ clauses.map!(&:value).join(' UNWIND ')
480
+ end
462
481
  end
463
482
  end
464
- end
465
483
 
466
- class ReturnClause < Clause
467
- @keyword = 'RETURN'
484
+ class ReturnClause < Clause
485
+ @keyword = 'RETURN'
468
486
 
469
- def from_symbol(value)
470
- from_string(value.to_s)
471
- end
487
+ def from_symbol(value)
488
+ from_string(value.to_s)
489
+ end
472
490
 
473
- def from_key_and_value(key, value)
474
- case value
475
- when Array
476
- value.map do |v|
477
- from_key_and_value(key, v)
478
- end.join(', ')
479
- when String, Symbol
480
- "#{key}.#{value}"
481
- else
482
- raise ArgError.new(value)
491
+ def from_key_and_value(key, value)
492
+ case value
493
+ when Array
494
+ value.map do |v|
495
+ from_key_and_value(key, v)
496
+ end.join(', ')
497
+ when String, Symbol
498
+ "#{key}.#{value}"
499
+ else
500
+ fail ArgError, value
501
+ end
483
502
  end
484
- end
485
503
 
486
- class << self
487
- def clause_string(clauses)
488
- clauses.map(&:value).join(', ')
504
+ class << self
505
+ def clause_string(clauses)
506
+ clauses.map!(&:value).join(', ')
507
+ end
489
508
  end
490
509
  end
491
510
  end
492
-
493
-
494
511
  end
495
512
  end
496
-