neo4j-core 3.1.1 → 4.0.0

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 (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
-