neo4j 6.0.0.rc.4 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3dc2eaadf6662bef798f4f7eabb1b32c39ded0fe
4
- data.tar.gz: 07eea640b9818e8d77ef95f281be24fdbde658ca
3
+ metadata.gz: 5e75b34e6d901afdd9e426ecdb467541b6d89c28
4
+ data.tar.gz: ddc468292508fcfff1ad7371977503ec7a0274ae
5
5
  SHA512:
6
- metadata.gz: 0bd648f94fd9b1985d715576bd2568c878c3e34a8bfb07506e1dc38ea4a5b2d00a5f69f32f10689754e7263431356532cfb2869a088773209cf8cc970f0aab93
7
- data.tar.gz: 51497e8c6a42bdd565a08ab8ad0dcc540f5fce691199df458db002bba7d2eb7cea2a6b463d40fcfb2aecbf24ae8fc5807c558cefe9d7c6f249849dc0bf9cac4a
6
+ metadata.gz: 9cb421908fc3da97ba84eb9a7c5254a3f5d6568dd1bd9cdeadae15fdea333881113327a7710b1eb1094a2cb32a37330005653c97be07689ea194d64780add3bb
7
+ data.tar.gz: 8542d356502f221d0e054e913608aa1eb4134999495b309c589473f9c6850d4012096ef8c331f61c4c7880925b7634ecf525af1982d5160557b30f6ae07add9a
data/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
3
3
  This file should follow the standards specified on [http://keepachangelog.com/]
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
+ ## [Unreleased]
7
+
8
+ ### Fixed
9
+
10
+ - Refactor unpersisted association logic to store objects directly on the object rather than the association proxy since different association proxies may be created at different times (see #1043)
11
+
6
12
  ## [6.0.0.rc.4] - 11-19-2015
7
13
 
8
14
  ### Fixed
data/lib/neo4j.rb CHANGED
@@ -61,7 +61,6 @@ require 'neo4j/active_node/dependent'
61
61
  require 'neo4j/active_node/dependent/query_proxy_methods'
62
62
  require 'neo4j/active_node/dependent/association_methods'
63
63
  require 'neo4j/active_node/query_methods'
64
- require 'neo4j/active_node/query/query_proxy_unpersisted'
65
64
  require 'neo4j/active_node/query/query_proxy_methods'
66
65
  require 'neo4j/active_node/query/query_proxy_enumerable'
67
66
  require 'neo4j/active_node/query/query_proxy_find_in_batches'
@@ -50,6 +50,16 @@ module Neo4j
50
50
  _persisted_obj || fail('Tried to access native neo4j object on a non persisted object')
51
51
  end
52
52
 
53
+ module ClassMethods
54
+ def nodeify(object)
55
+ if object.is_a?(::Neo4j::ActiveNode) || object.nil?
56
+ object
57
+ else
58
+ self.find(object)
59
+ end
60
+ end
61
+ end
62
+
53
63
  included do
54
64
  include Neo4j::Timestamps if Neo4j::Config[:record_timestamps]
55
65
 
@@ -8,8 +8,10 @@ module Neo4j::ActiveNode
8
8
  # It uses a QueryProxy to get results
9
9
  # But also caches results and can have results cached on it
10
10
  class AssociationProxy
11
- def initialize(query_proxy, cached_result = nil)
11
+ def initialize(query_proxy, deferred_objects = [], cached_result = nil)
12
12
  @query_proxy = query_proxy
13
+ @deferred_objects = deferred_objects
14
+
13
15
  cache_result(cached_result)
14
16
 
15
17
  # Represents the thing which can be enumerated
@@ -48,21 +50,27 @@ module Neo4j::ActiveNode
48
50
  end
49
51
 
50
52
  def result
51
- return @cached_result if @cached_result
53
+ (@deferred_objects || []) + result_without_deferred
54
+ end
52
55
 
53
- cache_query_proxy_result
56
+ def result_without_deferred
57
+ cache_query_proxy_result if !@cached_result
54
58
 
55
59
  @cached_result
56
60
  end
57
61
 
58
62
  def result_nodes
59
- return result if !@query_proxy.model
63
+ return result_objects if !@query_proxy.model
60
64
 
61
- @cached_result = result.map do |object|
65
+ result_objects.map do |object|
62
66
  object.is_a?(Neo4j::ActiveNode) ? object : @query_proxy.model.find(object)
63
67
  end
64
68
  end
65
69
 
70
+ def result_objects
71
+ @deferred_objects + result_without_deferred
72
+ end
73
+
66
74
  def result_ids
67
75
  result.map do |object|
68
76
  object.is_a?(Neo4j::ActiveNode) ? object.id : object
@@ -80,9 +88,7 @@ module Neo4j::ActiveNode
80
88
  end
81
89
 
82
90
  def cache_query_proxy_result
83
- @query_proxy.to_a.tap do |result|
84
- cache_result(result)
85
- end
91
+ @query_proxy.to_a.tap { |result| cache_result(result) }
86
92
  end
87
93
 
88
94
  def clear_cache_result
@@ -93,6 +99,12 @@ module Neo4j::ActiveNode
93
99
  !!@cached_result
94
100
  end
95
101
 
102
+ def replace_with(*args)
103
+ @cached_result = nil
104
+
105
+ @query_proxy.public_send(:replace_with, *args)
106
+ end
107
+
96
108
  QUERY_PROXY_METHODS = [:<<, :delete]
97
109
  CACHED_RESULT_METHODS = []
98
110
 
@@ -177,7 +189,7 @@ module Neo4j::ActiveNode
177
189
  private
178
190
 
179
191
  def fresh_association_proxy(name, options = {}, cached_result = nil)
180
- AssociationProxy.new(association_query_proxy(name, options), cached_result)
192
+ AssociationProxy.new(association_query_proxy(name, options), deferred_nodes_for_association(name), cached_result)
181
193
  end
182
194
 
183
195
  def previous_proxy_results_by_previous_id(result_cache, association_name)
@@ -356,6 +368,8 @@ module Neo4j::ActiveNode
356
368
  define_method("#{name}=") do |other_nodes|
357
369
  association_proxy_cache.clear
358
370
 
371
+ clear_deferred_nodes_for_association(name)
372
+
359
373
  Neo4j::Transaction.run { association_proxy(name).replace_with(other_nodes) }
360
374
  end
361
375
  end
@@ -366,6 +380,7 @@ module Neo4j::ActiveNode
366
380
  end
367
381
 
368
382
  define_method_unless_defined("#{name.to_s.singularize}_ids=") do |ids|
383
+ clear_deferred_nodes_for_association(name)
369
384
  association_proxy(name).replace_with(ids)
370
385
  end
371
386
 
@@ -415,7 +430,13 @@ module Neo4j::ActiveNode
415
430
  if options[:rel_length] && !options[:rel_length].is_a?(Fixnum)
416
431
  association_proxy
417
432
  else
418
- association_proxy.result_nodes.first
433
+ target_class = self.class.send(:association_target_class, name)
434
+ o = association_proxy.result.first
435
+ if target_class
436
+ target_class.send(:nodeify, o)
437
+ else
438
+ o
439
+ end
419
440
  end
420
441
  end
421
442
  end
@@ -428,7 +449,8 @@ module Neo4j::ActiveNode
428
449
  Neo4j::Transaction.run { association_proxy(name).replace_with(other_node) }
429
450
  # handle_non_persisted_node(other_node)
430
451
  else
431
- association_proxy(name).defer_create(other_node)
452
+ defer_create(name, other_node, clear: true)
453
+ other_node
432
454
  end
433
455
  end
434
456
  end
@@ -457,8 +479,7 @@ module Neo4j::ActiveNode
457
479
  end
458
480
 
459
481
  def association_proxy(name, options = {})
460
- query_proxy = association_query_proxy(name, options)
461
- AssociationProxy.new(query_proxy)
482
+ AssociationProxy.new(association_query_proxy(name, options))
462
483
  end
463
484
 
464
485
  def association_target_class(name)
@@ -478,11 +499,8 @@ module Neo4j::ActiveNode
478
499
  end
479
500
 
480
501
  def default_association_query_proxy
481
- Neo4j::ActiveNode::Query::QueryProxy.new("::#{self.name}".constantize,
482
- nil,
483
- session: neo4j_session,
484
- query_proxy: nil,
485
- context: "#{self.name}")
502
+ Neo4j::ActiveNode::Query::QueryProxy.new("::#{self.name}".constantize, nil,
503
+ session: neo4j_session, query_proxy: nil, context: "#{self.name}")
486
504
  end
487
505
 
488
506
  def build_association(macro, direction, name, options)
@@ -85,10 +85,9 @@ module Neo4j::ActiveNode
85
85
  # build the processable hash before it begins. If there are nodes and associations that
86
86
  # need to be created after the node is saved, a new transaction is started.
87
87
  def cascade_save
88
- deferred_nodes = pending_associations_with_nodes
89
- Neo4j::Transaction.run(!deferred_nodes.blank?) do
88
+ Neo4j::Transaction.run(pending_deferred_creations?) do
90
89
  result = yield
91
- process_unpersisted_nodes!(deferred_nodes) if deferred_nodes
90
+ process_unpersisted_nodes!
92
91
  result
93
92
  end
94
93
  end
@@ -6,7 +6,6 @@ module Neo4j
6
6
  include Neo4j::ActiveNode::Query::QueryProxyMethods
7
7
  include Neo4j::ActiveNode::Query::QueryProxyFindInBatches
8
8
  include Neo4j::ActiveNode::Query::QueryProxyEagerLoading
9
- include Neo4j::ActiveNode::Query::QueryProxyUnpersisted
10
9
  include Neo4j::ActiveNode::Dependent::QueryProxyMethods
11
10
 
12
11
  # The most recent node to start a QueryProxy chain.
@@ -164,7 +163,13 @@ module Neo4j
164
163
 
165
164
  # To add a relationship for the node for the association on this QueryProxy
166
165
  def <<(other_node)
167
- @start_object._persisted_obj ? create(other_node, {}) : defer_create(other_node)
166
+ if @start_object._persisted_obj
167
+ create(other_node, {})
168
+ elsif @association
169
+ @start_object.defer_create(@association.name, other_node)
170
+ else
171
+ fail 'Another crazy error!'
172
+ end
168
173
  self
169
174
  end
170
175
 
@@ -1,52 +1,47 @@
1
1
  module Neo4j
2
2
  module ActiveNode
3
3
  module Unpersisted
4
- def pending_associations
5
- @pending_associations ||= []
4
+ # The values in this Hash are returned and used outside by reference
5
+ # so any modifications to the Array should be in-place
6
+ def deferred_create_cache
7
+ @deferred_create_cache ||= {}
6
8
  end
7
9
 
8
- def pending_associations?
9
- !@pending_associations.blank?
10
+ def defer_create(association_name, object, options = {})
11
+ clear_deferred_nodes_for_association(association_name) if options[:clear]
12
+
13
+ deferred_nodes_for_association(association_name) << object
10
14
  end
11
15
 
12
- private
16
+ def deferred_nodes_for_association(association_name)
17
+ deferred_create_cache[association_name.to_sym] ||= []
18
+ end
13
19
 
14
- # TODO: Change this method's name.
15
- # Takes the pending_associations hash, which is in the format { cache_key => [:association_name, :association_operator]},
16
- # and returns them as { association_name => [[nodes_for_persistence], :operator] }
17
- def pending_associations_with_nodes
18
- return unless pending_associations?
19
- {}.tap do |deferred_nodes|
20
- pending_associations.uniq.each do |association_name|
21
- nodes_for_creation = association_proxy(association_name)
22
- nodes_for_creation = nodes_for_creation.reject(&:persisted?) if self.persisted?
23
-
24
- deferred_nodes[association_name] = nodes_for_creation
25
- end
26
- end
20
+ def pending_deferred_creations?
21
+ !deferred_create_cache.values.all?(&:empty?)
27
22
  end
28
23
 
29
- # @param [Hash] deferred_nodes A hash created by :pending_associations_with_nodes
30
- def process_unpersisted_nodes!(deferred_nodes)
31
- deferred_nodes.each_pair do |k, v|
32
- save_and_associate_queue(k, v)
33
- end
24
+ def clear_deferred_nodes_for_association(association_name)
25
+ deferred_nodes_for_association(association_name.to_sym).clear
34
26
  end
35
27
 
28
+ private
36
29
 
37
- def save_and_associate_queue(association_name, node_queue)
38
- association_proc = proc { |node| save_and_associate_node(association_name, node) }
39
- node_queue.each do |element|
40
- element.is_a?(Array) ? element.each { |node| association_proc.call(node) } : association_proc.call(element)
41
- end
42
- end
30
+ def process_unpersisted_nodes!
31
+ deferred_create_cache.each do |association_name, nodes|
32
+ association_proxy = association_proxy(association_name)
33
+
34
+ nodes.each do |node|
35
+ if node.respond_to?(:changed?)
36
+ node.save if node.changed? || !node.persisted?
37
+ fail "Unable to defer node persistence, could not save #{node.inspect}" unless node.persisted?
38
+ end
39
+
40
+ association_proxy << node
41
+ end
43
42
 
44
- def save_and_associate_node(association_name, node)
45
- if node.respond_to?(:changed?)
46
- node.save if node.changed? || !node.persisted?
47
- fail "Unable to defer node persistence, could not save #{node.inspect}" unless node.persisted?
43
+ @deferred_create_cache = {}
48
44
  end
49
- association_proxy(association_name) << node
50
45
  end
51
46
  end
52
47
  end
data/lib/neo4j/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Neo4j
2
- VERSION = '6.0.0.rc.4'
2
+ VERSION = '6.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neo4j
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.rc.4
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Ronge, Brian Underwood, Chris Grigg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-19 00:00:00.000000000 Z
11
+ date: 2015-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: orm_adapter
@@ -251,7 +251,6 @@ files:
251
251
  - lib/neo4j/active_node/query/query_proxy_find_in_batches.rb
252
252
  - lib/neo4j/active_node/query/query_proxy_link.rb
253
253
  - lib/neo4j/active_node/query/query_proxy_methods.rb
254
- - lib/neo4j/active_node/query/query_proxy_unpersisted.rb
255
254
  - lib/neo4j/active_node/query_methods.rb
256
255
  - lib/neo4j/active_node/reflection.rb
257
256
  - lib/neo4j/active_node/rels.rb
@@ -327,9 +326,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
327
326
  version: 1.9.3
328
327
  required_rubygems_version: !ruby/object:Gem::Requirement
329
328
  requirements:
330
- - - ">"
329
+ - - ">="
331
330
  - !ruby/object:Gem::Version
332
- version: 1.3.1
331
+ version: '0'
333
332
  requirements: []
334
333
  rubyforge_project: neo4j
335
334
  rubygems_version: 2.4.5.1
@@ -1,13 +0,0 @@
1
- module Neo4j
2
- module ActiveNode
3
- module Query
4
- module QueryProxyUnpersisted
5
- def defer_create(other_node)
6
- @start_object.pending_associations << @association.name
7
-
8
- @start_object.association_proxy(@association.name).add_to_cache(other_node)
9
- end
10
- end
11
- end
12
- end
13
- end