neo4j-core 5.0.1 → 5.1.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.
- checksums.yaml +4 -4
- data/Gemfile +0 -3
- data/README.md +32 -6
- data/lib/neo4j/ansi.rb +14 -0
- data/lib/neo4j/label.rb +0 -1
- data/lib/neo4j/node.rb +6 -1
- data/lib/neo4j-core/helpers.rb +2 -7
- data/lib/neo4j-core/query.rb +38 -7
- data/lib/neo4j-core/query_clauses.rb +186 -57
- data/lib/neo4j-core/version.rb +1 -1
- data/lib/neo4j-core.rb +1 -1
- data/lib/neo4j-embedded/embedded_session.rb +18 -10
- data/lib/neo4j-embedded.rb +1 -1
- data/lib/neo4j-server/cypher_node.rb +8 -6
- data/lib/neo4j-server/cypher_relationship.rb +11 -5
- data/lib/neo4j-server/cypher_response.rb +9 -6
- data/lib/neo4j-server/cypher_session.rb +29 -25
- data/lib/neo4j-server/cypher_transaction.rb +0 -1
- data/lib/neo4j-server.rb +0 -1
- data/neo4j-core.gemspec +1 -2
- metadata +7 -25
- data/lib/neo4j/tasks/config_server.rb +0 -36
- data/lib/neo4j/tasks/neo4j_server.rake +0 -245
- data/lib/neo4j-core/cypher_translator.rb +0 -76
- data/lib/neo4j-core/hash_with_indifferent_access.rb +0 -174
- data/lib/neo4j-server/cypher_node_uncommited.rb +0 -14
|
@@ -11,12 +11,12 @@ module Neo4j
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class Clause
|
|
14
|
-
include CypherTranslator
|
|
15
14
|
UNDERSCORE = '_'
|
|
16
15
|
COMMA_SPACE = ', '
|
|
17
16
|
AND = ' AND '
|
|
18
17
|
|
|
19
18
|
attr_accessor :params, :arg
|
|
19
|
+
attr_reader :options
|
|
20
20
|
|
|
21
21
|
def initialize(arg, options = {})
|
|
22
22
|
@arg = arg
|
|
@@ -25,7 +25,7 @@ module Neo4j
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def value
|
|
28
|
-
[String, Symbol, Integer, Hash].each do |arg_class|
|
|
28
|
+
[String, Symbol, Integer, Hash, NilClass].each do |arg_class|
|
|
29
29
|
from_method = "from_#{arg_class.name.downcase}"
|
|
30
30
|
return send(from_method, @arg) if @arg.is_a?(arg_class) && self.respond_to?(from_method)
|
|
31
31
|
end
|
|
@@ -53,8 +53,10 @@ module Neo4j
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def node_from_key_and_value(key, value, options = {})
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
prefer = options[:prefer] || :var
|
|
57
|
+
var = var_from_key_and_value(key, value, prefer)
|
|
58
|
+
label = label_from_key_and_value(key, value, prefer)
|
|
59
|
+
|
|
58
60
|
attributes = attributes_from_key_and_value(key, value)
|
|
59
61
|
|
|
60
62
|
prefix_value = value
|
|
@@ -131,30 +133,73 @@ module Neo4j
|
|
|
131
133
|
new(arg, options) if !arg.respond_to?(:empty?) || !arg.empty?
|
|
132
134
|
end
|
|
133
135
|
|
|
134
|
-
def to_cypher(clauses)
|
|
136
|
+
def to_cypher(clauses, options = {})
|
|
135
137
|
@question_mark_param_index = 1
|
|
136
138
|
|
|
137
|
-
string = clause_string(clauses)
|
|
138
|
-
|
|
139
|
+
string = clause_string(clauses, options)
|
|
140
|
+
|
|
141
|
+
final_keyword = if options[:pretty]
|
|
142
|
+
"#{clause_color}#{keyword}#{ANSI::CLEAR}"
|
|
143
|
+
else
|
|
144
|
+
keyword
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
"#{final_keyword} #{string}" if string.size > 0
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def clause_string(clauses, options = {})
|
|
151
|
+
join_string = clause_join + (options[:pretty] ? "\n " : '')
|
|
152
|
+
|
|
153
|
+
strings = clause_strings(clauses)
|
|
154
|
+
string = ((options[:pretty] && strings.size > 1) ? "\n " : '')
|
|
155
|
+
string + strings.join(join_string).strip
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def clause_join
|
|
159
|
+
''
|
|
160
|
+
end
|
|
139
161
|
|
|
140
|
-
|
|
162
|
+
def clause_color
|
|
163
|
+
ANSI::CYAN
|
|
141
164
|
end
|
|
142
165
|
end
|
|
143
166
|
|
|
167
|
+
def self.paramaterize_key!(key)
|
|
168
|
+
key.tr_s!('^a-zA-Z0-9', UNDERSCORE)
|
|
169
|
+
key.gsub!(/^_+|_+$/, '')
|
|
170
|
+
end
|
|
171
|
+
|
|
144
172
|
private
|
|
145
173
|
|
|
146
174
|
def key_value_string(key, value, previous_keys = [], is_set = false)
|
|
147
175
|
param = (previous_keys << key).join(UNDERSCORE)
|
|
148
|
-
|
|
149
|
-
param.gsub!(/^_+|_+$/, '')
|
|
176
|
+
self.class.paramaterize_key!(param)
|
|
150
177
|
|
|
151
|
-
|
|
152
|
-
|
|
178
|
+
if value.is_a?(Range)
|
|
179
|
+
add_params("#{param}_range_min" => value.min, "#{param}_range_max" => value.max)
|
|
153
180
|
|
|
154
|
-
|
|
155
|
-
"#{key} = {#{param}}"
|
|
181
|
+
"#{key} IN RANGE({#{param}_range_min}, {#{param}_range_max})"
|
|
156
182
|
else
|
|
157
|
-
|
|
183
|
+
value = value.first if array_value?(value, is_set) && value.size == 1
|
|
184
|
+
operator = array_value?(value, is_set) ? 'IN' : '='
|
|
185
|
+
|
|
186
|
+
add_param(param, value)
|
|
187
|
+
|
|
188
|
+
"#{key} #{operator} {#{param}}"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def array_value?(value, is_set)
|
|
193
|
+
value.is_a?(Array) && !is_set
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def add_param(key, value)
|
|
197
|
+
@params[key.freeze.to_sym] = value
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def add_params(params)
|
|
201
|
+
params.each do |key, value|
|
|
202
|
+
add_param(key, value)
|
|
158
203
|
end
|
|
159
204
|
end
|
|
160
205
|
|
|
@@ -180,7 +225,7 @@ module Neo4j
|
|
|
180
225
|
"#{key}: #{value}"
|
|
181
226
|
else
|
|
182
227
|
param_key = "#{prefix}#{key}".gsub('::', '_')
|
|
183
|
-
|
|
228
|
+
add_param(param_key, value)
|
|
184
229
|
"#{key}: {#{param_key}}"
|
|
185
230
|
end
|
|
186
231
|
end.join(Clause::COMMA_SPACE)
|
|
@@ -206,8 +251,12 @@ module Neo4j
|
|
|
206
251
|
end
|
|
207
252
|
|
|
208
253
|
class << self
|
|
209
|
-
def
|
|
210
|
-
clauses.map!(&:value)
|
|
254
|
+
def clause_strings(clauses)
|
|
255
|
+
clauses.map!(&:value)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def clause_join
|
|
259
|
+
Clause::COMMA_SPACE
|
|
211
260
|
end
|
|
212
261
|
end
|
|
213
262
|
end
|
|
@@ -219,16 +268,24 @@ module Neo4j
|
|
|
219
268
|
case value
|
|
220
269
|
when Hash then hash_key_value_string(key, value, previous_keys)
|
|
221
270
|
when NilClass then "#{key} IS NULL"
|
|
222
|
-
when Regexp then regexp_key_value_string(key, value)
|
|
223
|
-
when Array then key_value_string(key, value, previous_keys)
|
|
271
|
+
when Regexp then regexp_key_value_string(key, value, previous_keys)
|
|
272
|
+
when Array, Range then key_value_string(key, value, previous_keys)
|
|
224
273
|
else
|
|
225
274
|
key_value_string(key, value, previous_keys)
|
|
226
275
|
end
|
|
227
276
|
end
|
|
228
277
|
|
|
229
278
|
class << self
|
|
230
|
-
def
|
|
231
|
-
clauses.
|
|
279
|
+
def clause_strings(clauses)
|
|
280
|
+
clauses.flat_map do |clause|
|
|
281
|
+
Array(clause.value).map do |v|
|
|
282
|
+
(clause.options[:not] ? 'NOT' : '') + "(#{v})"
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def clause_join
|
|
288
|
+
Clause::AND
|
|
232
289
|
end
|
|
233
290
|
end
|
|
234
291
|
|
|
@@ -245,9 +302,15 @@ module Neo4j
|
|
|
245
302
|
end.join(AND)
|
|
246
303
|
end
|
|
247
304
|
|
|
248
|
-
def regexp_key_value_string(key, value)
|
|
305
|
+
def regexp_key_value_string(key, value, previous_keys)
|
|
249
306
|
pattern = (value.casefold? ? '(?i)' : '') + value.source
|
|
250
|
-
|
|
307
|
+
|
|
308
|
+
param = [previous_keys + [key]].join(UNDERSCORE)
|
|
309
|
+
self.class.paramaterize_key!(param)
|
|
310
|
+
|
|
311
|
+
add_params(param => pattern)
|
|
312
|
+
|
|
313
|
+
"#{key} =~ {#{param}}"
|
|
251
314
|
end
|
|
252
315
|
|
|
253
316
|
class << self
|
|
@@ -274,14 +337,18 @@ module Neo4j
|
|
|
274
337
|
end
|
|
275
338
|
|
|
276
339
|
def question_mark_params_param
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
340
|
+
"question_mark_param#{question_mark_param_index}"
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def question_mark_param_index
|
|
344
|
+
@question_mark_param_index ||= 1
|
|
345
|
+
@question_mark_param_index.tap do
|
|
346
|
+
@question_mark_param_index += 1
|
|
347
|
+
end
|
|
280
348
|
end
|
|
281
349
|
end
|
|
282
350
|
end
|
|
283
351
|
|
|
284
|
-
|
|
285
352
|
class MatchClause < Clause
|
|
286
353
|
KEYWORD = 'MATCH'
|
|
287
354
|
|
|
@@ -294,8 +361,12 @@ module Neo4j
|
|
|
294
361
|
end
|
|
295
362
|
|
|
296
363
|
class << self
|
|
297
|
-
def
|
|
298
|
-
clauses.map!(&:value)
|
|
364
|
+
def clause_strings(clauses)
|
|
365
|
+
clauses.map!(&:value)
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def clause_join
|
|
369
|
+
Clause::COMMA_SPACE
|
|
299
370
|
end
|
|
300
371
|
end
|
|
301
372
|
end
|
|
@@ -316,8 +387,12 @@ module Neo4j
|
|
|
316
387
|
end
|
|
317
388
|
|
|
318
389
|
class << self
|
|
319
|
-
def
|
|
320
|
-
clauses.map!(&:value)
|
|
390
|
+
def clause_strings(clauses)
|
|
391
|
+
clauses.map!(&:value)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def clause_join
|
|
395
|
+
Clause::COMMA_SPACE
|
|
321
396
|
end
|
|
322
397
|
end
|
|
323
398
|
end
|
|
@@ -326,8 +401,12 @@ module Neo4j
|
|
|
326
401
|
KEYWORD = 'USING'
|
|
327
402
|
|
|
328
403
|
class << self
|
|
329
|
-
def
|
|
330
|
-
clauses.map!(&:value)
|
|
404
|
+
def clause_strings(clauses)
|
|
405
|
+
clauses.map!(&:value)
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def clause_join
|
|
409
|
+
" #{keyword} "
|
|
331
410
|
end
|
|
332
411
|
end
|
|
333
412
|
end
|
|
@@ -358,8 +437,16 @@ module Neo4j
|
|
|
358
437
|
end
|
|
359
438
|
|
|
360
439
|
class << self
|
|
361
|
-
def
|
|
362
|
-
clauses.map!(&:value)
|
|
440
|
+
def clause_strings(clauses)
|
|
441
|
+
clauses.map!(&:value)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def clause_join
|
|
445
|
+
', '
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def clause_color
|
|
449
|
+
ANSI::GREEN
|
|
363
450
|
end
|
|
364
451
|
end
|
|
365
452
|
end
|
|
@@ -370,6 +457,12 @@ module Neo4j
|
|
|
370
457
|
|
|
371
458
|
class MergeClause < CreateClause
|
|
372
459
|
KEYWORD = 'MERGE'
|
|
460
|
+
|
|
461
|
+
class << self
|
|
462
|
+
def clause_color
|
|
463
|
+
ANSI::MAGENTA
|
|
464
|
+
end
|
|
465
|
+
end
|
|
373
466
|
end
|
|
374
467
|
|
|
375
468
|
class DeleteClause < Clause
|
|
@@ -380,8 +473,16 @@ module Neo4j
|
|
|
380
473
|
end
|
|
381
474
|
|
|
382
475
|
class << self
|
|
383
|
-
def
|
|
384
|
-
clauses.map!(&:value)
|
|
476
|
+
def clause_strings(clauses)
|
|
477
|
+
clauses.map!(&:value)
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def clause_join
|
|
481
|
+
Clause::COMMA_SPACE
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def clause_color
|
|
485
|
+
ANSI::RED
|
|
385
486
|
end
|
|
386
487
|
end
|
|
387
488
|
end
|
|
@@ -407,8 +508,12 @@ module Neo4j
|
|
|
407
508
|
end
|
|
408
509
|
|
|
409
510
|
class << self
|
|
410
|
-
def
|
|
411
|
-
clauses.map!(&:value)
|
|
511
|
+
def clause_strings(clauses)
|
|
512
|
+
clauses.map!(&:value)
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
def clause_join
|
|
516
|
+
Clause::COMMA_SPACE
|
|
412
517
|
end
|
|
413
518
|
end
|
|
414
519
|
end
|
|
@@ -418,19 +523,23 @@ module Neo4j
|
|
|
418
523
|
|
|
419
524
|
def from_string(value)
|
|
420
525
|
clause_id = "#{self.class.keyword_downcase}_#{value}"
|
|
421
|
-
|
|
526
|
+
add_param(clause_id, value.to_i)
|
|
422
527
|
"{#{clause_id}}"
|
|
423
528
|
end
|
|
424
529
|
|
|
425
530
|
def from_integer(value)
|
|
426
531
|
clause_id = "#{self.class.keyword_downcase}_#{value}"
|
|
427
|
-
|
|
532
|
+
add_param(clause_id, value)
|
|
428
533
|
"{#{clause_id}}"
|
|
429
534
|
end
|
|
430
535
|
|
|
536
|
+
def from_nilclass(value)
|
|
537
|
+
''
|
|
538
|
+
end
|
|
539
|
+
|
|
431
540
|
class << self
|
|
432
|
-
def
|
|
433
|
-
clauses.last.value
|
|
541
|
+
def clause_strings(clauses)
|
|
542
|
+
[clauses.last.value]
|
|
434
543
|
end
|
|
435
544
|
end
|
|
436
545
|
end
|
|
@@ -440,19 +549,19 @@ module Neo4j
|
|
|
440
549
|
|
|
441
550
|
def from_string(value)
|
|
442
551
|
clause_id = "#{self.class.keyword_downcase}_#{value}"
|
|
443
|
-
|
|
552
|
+
add_param(clause_id, value.to_i)
|
|
444
553
|
"{#{clause_id}}"
|
|
445
554
|
end
|
|
446
555
|
|
|
447
556
|
def from_integer(value)
|
|
448
557
|
clause_id = "#{self.class.keyword_downcase}_#{value}"
|
|
449
|
-
|
|
558
|
+
add_param(clause_id, value)
|
|
450
559
|
"{#{clause_id}}"
|
|
451
560
|
end
|
|
452
561
|
|
|
453
562
|
class << self
|
|
454
|
-
def
|
|
455
|
-
clauses.last.value
|
|
563
|
+
def clause_strings(clauses)
|
|
564
|
+
[clauses.last.value]
|
|
456
565
|
end
|
|
457
566
|
end
|
|
458
567
|
end
|
|
@@ -465,7 +574,7 @@ module Neo4j
|
|
|
465
574
|
when String, Symbol then "#{key}:`#{value}`"
|
|
466
575
|
when Hash
|
|
467
576
|
if @options[:set_props]
|
|
468
|
-
|
|
577
|
+
add_param("#{key}_set_props", value)
|
|
469
578
|
"#{key} = {#{key}_set_props}"
|
|
470
579
|
else
|
|
471
580
|
value.map { |k, v| key_value_string("#{key}.`#{k}`", v, ['setter'], true) }
|
|
@@ -478,8 +587,16 @@ module Neo4j
|
|
|
478
587
|
end
|
|
479
588
|
|
|
480
589
|
class << self
|
|
481
|
-
def
|
|
482
|
-
clauses.map!(&:value)
|
|
590
|
+
def clause_strings(clauses)
|
|
591
|
+
clauses.map!(&:value)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def clause_join
|
|
595
|
+
Clause::COMMA_SPACE
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
def clause_color
|
|
599
|
+
ANSI::YELLOW
|
|
483
600
|
end
|
|
484
601
|
end
|
|
485
602
|
end
|
|
@@ -518,8 +635,12 @@ module Neo4j
|
|
|
518
635
|
end
|
|
519
636
|
|
|
520
637
|
class << self
|
|
521
|
-
def
|
|
522
|
-
clauses.map!(&:value)
|
|
638
|
+
def clause_strings(clauses)
|
|
639
|
+
clauses.map!(&:value)
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
def clause_join
|
|
643
|
+
Clause::COMMA_SPACE
|
|
523
644
|
end
|
|
524
645
|
end
|
|
525
646
|
end
|
|
@@ -539,8 +660,12 @@ module Neo4j
|
|
|
539
660
|
end
|
|
540
661
|
|
|
541
662
|
class << self
|
|
542
|
-
def
|
|
543
|
-
clauses.map!(&:value)
|
|
663
|
+
def clause_strings(clauses)
|
|
664
|
+
clauses.map!(&:value)
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
def clause_join
|
|
668
|
+
' UNWIND '
|
|
544
669
|
end
|
|
545
670
|
end
|
|
546
671
|
end
|
|
@@ -570,8 +695,12 @@ module Neo4j
|
|
|
570
695
|
end
|
|
571
696
|
|
|
572
697
|
class << self
|
|
573
|
-
def
|
|
574
|
-
clauses.map!(&:value)
|
|
698
|
+
def clause_strings(clauses)
|
|
699
|
+
clauses.map!(&:value)
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
def clause_join
|
|
703
|
+
Clause::COMMA_SPACE
|
|
575
704
|
end
|
|
576
705
|
end
|
|
577
706
|
end
|
data/lib/neo4j-core/version.rb
CHANGED
data/lib/neo4j-core.rb
CHANGED
|
@@ -9,7 +9,6 @@ require 'neo4j/property_validator'
|
|
|
9
9
|
require 'neo4j/property_container'
|
|
10
10
|
require 'neo4j-core/active_entity'
|
|
11
11
|
require 'neo4j-core/helpers'
|
|
12
|
-
require 'neo4j-core/cypher_translator'
|
|
13
12
|
require 'neo4j-core/query_find_in_batches'
|
|
14
13
|
require 'neo4j-core/query'
|
|
15
14
|
|
|
@@ -17,6 +16,7 @@ require 'neo4j/entity_equality'
|
|
|
17
16
|
require 'neo4j/node'
|
|
18
17
|
require 'neo4j/label'
|
|
19
18
|
require 'neo4j/session'
|
|
19
|
+
require 'neo4j/ansi'
|
|
20
20
|
|
|
21
21
|
require 'neo4j/relationship'
|
|
22
22
|
require 'neo4j/transaction'
|
|
@@ -4,7 +4,6 @@ Neo4j::Session.register_db(:embedded_db) do |*args|
|
|
|
4
4
|
Neo4j::Embedded::EmbeddedSession.new(*args)
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
module Neo4j
|
|
9
8
|
module Embedded
|
|
10
9
|
class EmbeddedSession < Neo4j::Session
|
|
@@ -17,16 +16,22 @@ module Neo4j
|
|
|
17
16
|
def_delegator :@graph_db, :begin_tx
|
|
18
17
|
|
|
19
18
|
def initialize(db_location, config = {})
|
|
19
|
+
@config = config
|
|
20
20
|
@db_location = db_location
|
|
21
|
-
@auto_commit =
|
|
22
|
-
@properties_file = config[:properties_file]
|
|
23
|
-
if config[:properties_map]
|
|
24
|
-
props = config[:properties_map].each_with_object({}) { |(k, v), m| m[k.to_s.to_java] = v.to_s.to_java }
|
|
25
|
-
@properties_map = java.util.HashMap.new(props)
|
|
26
|
-
end
|
|
21
|
+
@auto_commit = !!@config[:auto_commit]
|
|
22
|
+
@properties_file = @config[:properties_file]
|
|
27
23
|
Neo4j::Session.register(self)
|
|
28
24
|
end
|
|
29
25
|
|
|
26
|
+
def properties_map
|
|
27
|
+
return @properties_map if @properties_map
|
|
28
|
+
|
|
29
|
+
props = @config[:properties_map].each_with_object({}) do |(k, v), m|
|
|
30
|
+
m[k.to_s.to_java] = v.to_s.to_java
|
|
31
|
+
end
|
|
32
|
+
@properties_map = java.util.HashMap.new(props)
|
|
33
|
+
end
|
|
34
|
+
|
|
30
35
|
def db_type
|
|
31
36
|
:embedded_db
|
|
32
37
|
end
|
|
@@ -137,9 +142,12 @@ module Neo4j
|
|
|
137
142
|
# Remember that you should close the resource iterator.
|
|
138
143
|
# @param [String] q the cypher query as a String
|
|
139
144
|
# @return (see #query)
|
|
140
|
-
def _query(
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
def _query(query, params = {}, options = {})
|
|
146
|
+
ActiveSupport::Notifications.instrument('neo4j.cypher_query', params: params, context: options[:context],
|
|
147
|
+
cypher: query, pretty_cypher: options[:pretty_cypher], params: params) do
|
|
148
|
+
@engine ||= Java::OrgNeo4jCypherJavacompat::ExecutionEngine.new(@graph_db)
|
|
149
|
+
@engine.execute(query, HashWithIndifferentAccess.new(params))
|
|
150
|
+
end
|
|
143
151
|
rescue StandardError => e
|
|
144
152
|
raise Neo4j::Session::CypherError.new(e.message, e.class, 'cypher error')
|
|
145
153
|
end
|
data/lib/neo4j-embedded.rb
CHANGED
|
@@ -13,4 +13,4 @@ require 'neo4j-embedded/embedded_transaction'
|
|
|
13
13
|
require 'neo4j-embedded/cypher_response'
|
|
14
14
|
|
|
15
15
|
# TODO: replace this with https://github.com/intridea/hashie gem
|
|
16
|
-
require '
|
|
16
|
+
require 'active_support/hash_with_indifferent_access'
|
|
@@ -2,7 +2,6 @@ module Neo4j
|
|
|
2
2
|
module Server
|
|
3
3
|
class CypherNode < Neo4j::Node
|
|
4
4
|
include Neo4j::Server::Resource
|
|
5
|
-
include Neo4j::Core::CypherTranslator
|
|
6
5
|
include Neo4j::Core::ActiveEntity
|
|
7
6
|
|
|
8
7
|
def initialize(session, value)
|
|
@@ -113,8 +112,6 @@ module Neo4j
|
|
|
113
112
|
end
|
|
114
113
|
|
|
115
114
|
def set_label(*label_names)
|
|
116
|
-
q = match_start_query
|
|
117
|
-
|
|
118
115
|
labels_to_add = label_names.map(&:to_sym).uniq
|
|
119
116
|
labels_to_remove = labels - label_names
|
|
120
117
|
|
|
@@ -122,10 +119,15 @@ module Neo4j
|
|
|
122
119
|
labels_to_add -= common_labels
|
|
123
120
|
labels_to_remove -= common_labels
|
|
124
121
|
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
query = _set_label_query(labels_to_add, labels_to_remove)
|
|
123
|
+
@session._query_or_fail(query, false) unless (labels_to_add + labels_to_remove).empty?
|
|
124
|
+
end
|
|
127
125
|
|
|
128
|
-
|
|
126
|
+
def _set_label_query(labels_to_add, labels_to_remove)
|
|
127
|
+
query = match_start_query
|
|
128
|
+
query = query.remove(n: labels_to_remove) unless labels_to_remove.empty?
|
|
129
|
+
query = query.set(n: labels_to_add) unless labels_to_add.empty?
|
|
130
|
+
query
|
|
129
131
|
end
|
|
130
132
|
|
|
131
133
|
# (see Neo4j::Node#del)
|
|
@@ -2,7 +2,6 @@ module Neo4j
|
|
|
2
2
|
module Server
|
|
3
3
|
class CypherRelationship < Neo4j::Relationship
|
|
4
4
|
include Neo4j::Server::Resource
|
|
5
|
-
include Neo4j::Core::CypherTranslator
|
|
6
5
|
include Neo4j::Core::ActiveEntity
|
|
7
6
|
|
|
8
7
|
def initialize(session, value)
|
|
@@ -93,10 +92,17 @@ module Neo4j
|
|
|
93
92
|
# (see Neo4j::Relationship#update_props)
|
|
94
93
|
def update_props(properties)
|
|
95
94
|
return if properties.empty?
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
|
|
96
|
+
params = {}
|
|
97
|
+
q = "#{match_start} SET " + properties.keys.each_with_index.map do |k, _i|
|
|
98
|
+
param = k.to_s.tr_s('^a-zA-Z0-9', '_').gsub(/^_+|_+$/, '')
|
|
99
|
+
params[param] = properties[k]
|
|
100
|
+
|
|
101
|
+
"n.`#{k}`= {#{param}}"
|
|
98
102
|
end.join(',')
|
|
99
|
-
|
|
103
|
+
|
|
104
|
+
@session._query_or_fail(q, false, params.merge(neo_id: neo_id))
|
|
105
|
+
|
|
100
106
|
properties
|
|
101
107
|
end
|
|
102
108
|
|
|
@@ -127,7 +133,7 @@ module Neo4j
|
|
|
127
133
|
end
|
|
128
134
|
|
|
129
135
|
def neo_id_integer(id_or_url)
|
|
130
|
-
id_or_url.is_a?(Integer) ? id_or_url : id_or_url.
|
|
136
|
+
id_or_url.is_a?(Integer) ? id_or_url : id_or_url.split('/').last.to_i
|
|
131
137
|
end
|
|
132
138
|
end
|
|
133
139
|
end
|
|
@@ -13,6 +13,7 @@ module Neo4j
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
class ConstraintViolationError < ResponseError; end
|
|
16
17
|
|
|
17
18
|
class HashEnumeration
|
|
18
19
|
include Enumerable
|
|
@@ -201,9 +202,15 @@ module Neo4j
|
|
|
201
202
|
self
|
|
202
203
|
end
|
|
203
204
|
|
|
205
|
+
CONSTRAINT_ERROR = 'Neo.ClientError.Schema.ConstraintViolation'
|
|
204
206
|
def raise_error
|
|
205
207
|
fail 'Tried to raise error without an error' unless @error
|
|
206
|
-
|
|
208
|
+
error_class = constraint_error? ? ConstraintViolationError : ResponseError
|
|
209
|
+
fail error_class.new(@error_msg, @error_status, @error_code)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def constraint_error?
|
|
213
|
+
@error_code == CONSTRAINT_ERROR || @error_msg.include?('already exists with')
|
|
207
214
|
end
|
|
208
215
|
|
|
209
216
|
def raise_cypher_error
|
|
@@ -228,11 +235,7 @@ module Neo4j
|
|
|
228
235
|
|
|
229
236
|
new(response, true).tap do |cr|
|
|
230
237
|
body = response.body
|
|
231
|
-
|
|
232
|
-
cr.set_data(body[:results].first)
|
|
233
|
-
else
|
|
234
|
-
cr.set_error(body[:errors].first)
|
|
235
|
-
end
|
|
238
|
+
body[:errors].empty? ? cr.set_data(body[:results].first) : cr.set_error(body[:errors].first)
|
|
236
239
|
end
|
|
237
240
|
end
|
|
238
241
|
|