neo4j 6.0.0.alpha.12 → 6.0.0.rc.1

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: 88d57fe8f616166912b89e008686fea6190fee43
4
- data.tar.gz: 83cbc8c78c8ae3a8571ed0870699f0537b018a84
3
+ metadata.gz: 79fee58d2b88d542f1af73c6240762f5484fe820
4
+ data.tar.gz: bc525e2a2f3ec67b346a09a89f62dc1ac39f85fc
5
5
  SHA512:
6
- metadata.gz: c13bb99309098ea662883902a7491cec10d32c9beb475a96825622e0a3b9e2f032b6d92eed15524613a796ab00da7407516241f5d655c1fc770ee1e0a321f70e
7
- data.tar.gz: db933033b16e28f6282dd3e6b46f772587bfa670d125c26e2289f32bba771d93c66c5da3933fe1beb0fab1783495af1604c82ba616179f78179b4f2889a1a55e
6
+ metadata.gz: e536923b9a12aee831cefb2bf323c52c616868f1404d1c3e34edb68833c4365ae65afea87872174bd5b227dc857775c0e03bf0577a194df8da01e1e3176da1f5
7
+ data.tar.gz: 33a078d405f0eb7afaa34f079d458920211a2844c743d32faca3ba5f2a2e1fe10d41f4acc89b529177dae8c19ba62c746d6843478162296d3be13fd7236fe7c9
@@ -3,10 +3,59 @@ 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
+ ## [6.0.0.rc.1] - 11-13-2015
7
+
8
+ This release contains no changes since the last alpha. Below are all modifications introduced in alpha releases.
9
+
10
+ ### Changed
11
+
12
+ - `_classname` property has been completely removed, officially dropping support for Neo4j < 2.1.5.
13
+ - `ActiveRel#creates_unique` and the `:unique` Association option take arguments to control how the query is built. See https://github.com/neo4jrb/neo4j/pull/1038.
14
+ - `#<<` and `#create` methods on associations now create with the `rel_class` when available so that validations/callbacks/defaults are all used as expected
15
+ - Allow calling of `#method=` methods via model `new` method `Hash` argument
16
+ - Remove uniqueness validation for `id_property` because we already have Neo4j constraints
17
+ - Improved eager loading when no with_associations is specified (see #905)
18
+ - Change size and length so that they match expected Ruby / ActiveRecord behavior (see http://stackoverflow.com/questions/6083219/activerecord-size-vs-count and #875)
19
+ - Refactoring around indexing and constraints in `Neo4j::ActiveNode`. The public interfaces are unchanged.
20
+ - `Neo4j::Shared::DeclaredPropertyManager` was renamed `Neo4j::Shared::DeclaredProperties`. All methods referencing the old name were updated to reflect this.
21
+ - Methods that were using `Neo4j::Session#on_session_available` were updated to reflect the upstream change to `on_next_session_available`.
22
+ - `rel_where` will now use ActiveRel classes for type conversion, when possible.
23
+ - Converters will look for a `converted?` method to determine whether an object is of the appropriate type for the database. This allows converters to be responsible for multiple types, if required.
24
+ - Removed the ability to set both an exact index and unique constraint on the same property in a model. Unique constraints also provide exact indexes.
25
+ - Deprecated all methods in ActiveRel's Query module except for those that allow finding by id.
26
+ - Return `true` on successful `#save!` calls (Thanks to jmdeldin)
27
+
28
+ ### Added
29
+
30
+ - Optional three-argument signature for `ActiveRel#create` and `#create!`, just like `initialize`.
31
+ - Alternate `ActiveRel` init syntax: `RelClass.new(from_node, to_node, args)`. This is optional, so giving a single hash with props with or without nodes is still possible.
32
+ - `ActiveRel` `create` actions can now handle unpersisted nodes.
33
+ - `rel_order` method for association chaining
34
+ - Support `config/neo4j.yaml`
35
+ - Look for ENV variables for Neo4j URL / path for Rails apps
36
+ - New classes for schema operations, predictably called `Neo4j::Schema::Operation` and subclasses `UniqueConstraintOperation` and `ExactIndexOperation`. These provide methods to aid in the additional, removal, and presence checking of indexes and constraints.
37
+ - A few methods were added to `Neo4j::Shared::DeclaredProperties` to make it easier to work with. In particular, `[key]` acts as a shortcut for `DeclaredProperties#registered_properties`.
38
+ - Type Converters were added for String, Integer, Fixnum, BigDecimal, and Boolean to provide type conversion for these objects in QueryProxy.
39
+ - Support for Array arguments to ActiveRel's `from_class` and `to_class`.
40
+
41
+ ### Fixed
42
+
43
+ - Regression RE: properties being overwritten with their defaults on save in alpha.10.
44
+ - Long properties in `ActiveNode`/`ActiveRel` `#inspect` are truncated
45
+ - Property defaults are set initially when an instance of a model is loaded, then checked again before save to ensure `valid?` works.
46
+ - `QueryProxy` was not converting Boolean properties correctly
47
+ - Certain actions that were intended as once-in-the-app's-lifetime events, notably schema operations, will only occur immediately upon the first session's establishment.
48
+ - Context now set for Model.all QueryProxy so that logs can reflect that it wasn't just a raw Cypher query
49
+
50
+ ### Removed
51
+
52
+ - Railtie was removing username/password and putting them into the session options. This has been unneccessary in `neo4j-core` for a while now
53
+
6
54
  ## [6.0.0.alpha.12] - 11-5-2015
7
55
 
8
56
  ### Changed
9
57
  - `_classname` property has been completely removed, officially dropping support for Neo4j < 2.1.5.
58
+ - `ActiveRel#creates_unique` and the `:unique` Association option take arguments to control how the query is built. See https://github.com/neo4jrb/neo4j/pull/1038.
10
59
 
11
60
  ### Added
12
61
  - Optional three-argument signature for `ActiveRel#create` and `#create!`, just like `initialize`.
@@ -51,7 +100,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
51
100
 
52
101
  ### Added
53
102
 
54
- - Support `config/neo4j.ya?ml`
103
+ - Support `config/neo4j.yaml`
55
104
 
56
105
  ## [6.0.0.alpha.6] - 10-18-2015
57
106
 
@@ -31,6 +31,7 @@ require 'neo4j/schema/operation'
31
31
  require 'neo4j/timestamps'
32
32
 
33
33
  require 'neo4j/shared/callbacks'
34
+ require 'neo4j/shared/filtered_hash'
34
35
  require 'neo4j/shared/declared_property/index'
35
36
  require 'neo4j/shared/declared_property'
36
37
  require 'neo4j/shared/declared_properties'
@@ -42,6 +43,7 @@ require 'neo4j/shared/serialized_properties'
42
43
  require 'neo4j/shared/typecaster'
43
44
  require 'neo4j/shared/initialize'
44
45
  require 'neo4j/shared/query_factory'
46
+ require 'neo4j/shared/cypher'
45
47
  require 'neo4j/shared'
46
48
 
47
49
  require 'neo4j/active_rel/callbacks'
@@ -80,6 +82,8 @@ require 'neo4j/active_node/reflection'
80
82
  require 'neo4j/active_node/unpersisted'
81
83
  require 'neo4j/active_node/has_n'
82
84
  require 'neo4j/active_node/has_n/association_cypher_methods'
85
+ require 'neo4j/active_node/has_n/association/rel_wrapper'
86
+ require 'neo4j/active_node/has_n/association/rel_factory'
83
87
  require 'neo4j/active_node/has_n/association'
84
88
  require 'neo4j/active_node/query/query_proxy'
85
89
  require 'neo4j/active_node/query'
@@ -133,10 +133,18 @@ module Neo4j
133
133
  @origin ? origin_association.unique? : !!@unique
134
134
  end
135
135
 
136
+ def creates_unique_option
137
+ @unique || :none
138
+ end
139
+
136
140
  def create_method
137
141
  unique? ? :create_unique : :create
138
142
  end
139
143
 
144
+ def _create_relationship(start_object, node_or_nodes, properties)
145
+ RelFactory.create(start_object, node_or_nodes, properties, self)
146
+ end
147
+
140
148
  def relationship_class?
141
149
  !!relationship_class
142
150
  end
@@ -0,0 +1,61 @@
1
+ module Neo4j::ActiveNode::HasN
2
+ class Association
3
+ class RelFactory
4
+ [:start_object, :other_node_or_nodes, :properties, :association].tap do |accessors|
5
+ attr_reader(*accessors)
6
+ private(*accessors)
7
+ end
8
+
9
+ def self.create(start_object, other_node_or_nodes, properties, association)
10
+ factory = new(start_object, other_node_or_nodes, properties, association)
11
+ factory._create_relationship
12
+ end
13
+
14
+ def _create_relationship
15
+ creator = association.relationship_class ? :rel_class : :factory
16
+ send(:"_create_relationship_with_#{creator}")
17
+ end
18
+
19
+ private
20
+
21
+ def initialize(start_object, other_node_or_nodes, properties, association)
22
+ @start_object = start_object
23
+ @other_node_or_nodes = other_node_or_nodes
24
+ @properties = properties
25
+ @association = association
26
+ end
27
+
28
+ def _create_relationship_with_rel_class
29
+ Array(other_node_or_nodes).each do |other_node|
30
+ node_props = _nodes_for_create(other_node, :from_node, :to_node)
31
+ association.relationship_class.create(properties.merge(node_props))
32
+ end
33
+ end
34
+
35
+ def _create_relationship_with_factory
36
+ Array(other_node_or_nodes).each do |other_node|
37
+ wrapper = _rel_wrapper(properties)
38
+ base = _match_query(other_node, wrapper)
39
+ factory = Neo4j::Shared::RelQueryFactory.new(wrapper, wrapper.rel_identifier)
40
+ factory.base_query = base
41
+ factory.query.exec
42
+ end
43
+ end
44
+
45
+ def _match_query(other_node, wrapper)
46
+ nodes = _nodes_for_create(other_node, wrapper.from_node_identifier, wrapper.to_node_identifier)
47
+ Neo4j::Session.current.query.match_nodes(nodes)
48
+ end
49
+
50
+ def _nodes_for_create(other_node, from_node_id, to_node_id)
51
+ nodes = [@start_object, other_node]
52
+ nodes.reverse! if association.direction == :in
53
+ {from_node_id => nodes[0], to_node_id => nodes[1]}
54
+ end
55
+
56
+ def _rel_wrapper(properties)
57
+ Neo4j::ActiveNode::HasN::Association::RelWrapper.new(association, properties)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,23 @@
1
+ class Neo4j::ActiveNode::HasN::Association
2
+ # Provides the interface needed to interact with the ActiveRel query factory.
3
+ class RelWrapper
4
+ include Neo4j::Shared::Cypher::RelIdentifiers
5
+ include Neo4j::Shared::Cypher::CreateMethod
6
+
7
+ attr_reader :type, :association
8
+ attr_accessor :properties
9
+ private :association
10
+ alias_method :props_for_create, :properties
11
+
12
+ def initialize(association, properties = {})
13
+ @association = association
14
+ @properties = properties
15
+ @type = association.relationship_type(true)
16
+ creates_unique(association.creates_unique_option) if association.unique?
17
+ end
18
+
19
+ def persisted?
20
+ false
21
+ end
22
+ end
23
+ end
@@ -206,21 +206,7 @@ module Neo4j
206
206
  end
207
207
 
208
208
  def _create_relationship(other_node_or_nodes, properties)
209
- if association.relationship_class
210
- _create_relationship_with_rel_class(other_node_or_nodes, properties)
211
- else
212
- _session.query(context: @options[:context])
213
- .match(:start, :end).match_nodes(start: @start_object, end: other_node_or_nodes)
214
- .send(association.create_method, "start#{_association_arrow(properties, true)}end").exec
215
- end
216
- end
217
-
218
- def _create_relationship_with_rel_class(other_node_or_nodes, properties)
219
- Array(other_node_or_nodes).each do |other_node|
220
- node_props = (association.direction == :in) ? {from_node: other_node, to_node: @start_object} : {from_node: @start_object, to_node: other_node}
221
-
222
- association.relationship_class.create(properties.merge(node_props))
223
- end
209
+ association._create_relationship(@start_object, other_node_or_nodes, properties)
224
210
  end
225
211
 
226
212
  def read_attribute_for_serialization(*args)
@@ -1,10 +1,9 @@
1
1
  module Neo4j::ActiveRel
2
2
  module Persistence
3
3
  extend ActiveSupport::Concern
4
+ include Neo4j::Shared::Cypher::RelIdentifiers
4
5
  include Neo4j::Shared::Persistence
5
6
 
6
- attr_writer :from_node_identifier, :to_node_identifier
7
-
8
7
  class RelInvalidError < RuntimeError; end
9
8
  class ModelClassInvalidError < RuntimeError; end
10
9
  class RelCreateFailedError < RuntimeError; end
@@ -17,6 +16,14 @@ module Neo4j::ActiveRel
17
16
  @to_node_identifier || :to_node
18
17
  end
19
18
 
19
+ def from_node_identifier=(id)
20
+ @from_node_identifier = id.to_sym
21
+ end
22
+
23
+ def to_node_identifier=(id)
24
+ @to_node_identifier = id.to_sym
25
+ end
26
+
20
27
  def cypher_identifier
21
28
  @cypher_identifier || :rel
22
29
  end
@@ -29,7 +29,7 @@ module Neo4j::ActiveRel::Persistence
29
29
  private
30
30
 
31
31
  def rel_id
32
- @rel_id ||= rel.cypher_identifier
32
+ @rel_id ||= rel.rel_identifier
33
33
  end
34
34
 
35
35
  # Node callbacks only need to be executed if the node is not persisted. We let the `conditional_callback` method do the work,
@@ -31,7 +31,13 @@ module Neo4j::ActiveRel
31
31
  send_props(@relationship_props) unless @relationship_props.nil?
32
32
  end
33
33
 
34
+ def creates_unique_option
35
+ self.class.creates_unique_option
36
+ end
37
+
34
38
  module ClassMethods
39
+ include Neo4j::Shared::Cypher::CreateMethod
40
+
35
41
  # Extracts keys from attributes hash which are relationships of the model
36
42
  # TODO: Validate separately that relationships are getting the right values? Perhaps also store the values and persist relationships on save?
37
43
  def extract_association_attributes!(attributes)
@@ -62,26 +68,6 @@ module Neo4j::ActiveRel
62
68
  def load_entity(id)
63
69
  Neo4j::Node.load(id)
64
70
  end
65
-
66
- def creates_unique
67
- @creates_unique = true
68
- end
69
-
70
- def creates_unique_rel
71
- warning = <<-WARNING
72
- creates_unique_rel() is deprecated and will be removed from future releases,
73
- use creates_unique() instead.
74
- WARNING
75
-
76
- ActiveSupport::Deprecation.warn(warning, caller)
77
-
78
- creates_unique
79
- end
80
-
81
- def creates_unique?
82
- !!@creates_unique
83
- end
84
- alias_method :unique?, :creates_unique?
85
71
  end
86
72
 
87
73
  private
@@ -0,0 +1,37 @@
1
+ module Neo4j::Shared
2
+ module Cypher
3
+ module CreateMethod
4
+ def create_method
5
+ creates_unique? ? :create_unique : :create
6
+ end
7
+
8
+ def creates_unique(option = :none)
9
+ option = :none if option == true
10
+ @creates_unique = option
11
+ end
12
+
13
+ def creates_unique_option
14
+ @creates_unique || :none
15
+ end
16
+
17
+ def creates_unique?
18
+ !!@creates_unique
19
+ end
20
+ alias_method :unique?, :creates_unique?
21
+ end
22
+
23
+ module RelIdentifiers
24
+ extend ActiveSupport::Concern
25
+
26
+ [:from_node, :to_node, :rel].each do |element|
27
+ define_method("#{element}_identifier") do
28
+ instance_variable_get(:"@#{element}_identifier") || element
29
+ end
30
+
31
+ define_method("#{element}_identifier=") do |id|
32
+ instance_variable_set(:"@#{element}_identifier", id.to_sym)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,79 @@
1
+ module Neo4j::Shared
2
+ class FilteredHash
3
+ class InvalidHashFilterType < Neo4j::Neo4jrbError; end
4
+ VALID_SYMBOL_INSTRUCTIONS = [:all, :none]
5
+ VALID_HASH_INSTRUCTIONS = [:on]
6
+ VALID_INSTRUCTIONS_TYPES = [Hash, Symbol]
7
+
8
+ attr_reader :base, :instructions, :instructions_type
9
+
10
+ def initialize(base, instructions)
11
+ @base = base
12
+ @instructions = instructions
13
+ @instructions_type = instructions.class
14
+ validate_instructions!(instructions)
15
+ end
16
+
17
+ def filtered_base
18
+ case instructions
19
+ when Symbol
20
+ filtered_base_by_symbol
21
+ when Hash
22
+ filtered_base_by_hash
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def filtered_base_by_symbol
29
+ case instructions
30
+ when :all
31
+ [base, {}]
32
+ when :none
33
+ [{}, base]
34
+ end
35
+ end
36
+
37
+ def filtered_base_by_hash
38
+ behavior_key = instructions.keys.first
39
+ filter_keys = keys_array(behavior_key)
40
+ [filter(filter_keys, :with), filter(filter_keys, :without)]
41
+ end
42
+
43
+ def key?(filter_keys, key)
44
+ filter_keys.include?(key)
45
+ end
46
+
47
+ def filter(filter_keys, key)
48
+ filtering = key == :with
49
+ base.select { |k, _v| key?(filter_keys, k) == filtering }
50
+ end
51
+
52
+ def keys_array(key)
53
+ instructions[key].is_a?(Array) ? instructions[key] : [instructions[key]]
54
+ end
55
+
56
+ def validate_instructions!(instructions)
57
+ fail InvalidHashFilterType, "Filtering instructions #{instructions} are invalid" unless VALID_INSTRUCTIONS_TYPES.include?(instructions.class)
58
+ clazz = instructions_type.name.downcase
59
+ return if send(:"valid_#{clazz}_instructions?", instructions)
60
+ fail InvalidHashFilterType, "Invalid instructions #{instructions}, valid options for #{clazz}: #{send(:"valid_#{clazz}_instructions")}"
61
+ end
62
+
63
+ def valid_symbol_instructions?(instructions)
64
+ valid_symbol_instructions.include?(instructions)
65
+ end
66
+
67
+ def valid_hash_instructions?(instructions)
68
+ valid_hash_instructions.include?(instructions.keys.first)
69
+ end
70
+
71
+ def valid_symbol_instructions
72
+ VALID_SYMBOL_INSTRUCTIONS
73
+ end
74
+
75
+ def valid_hash_instructions
76
+ VALID_HASH_INSTRUCTIONS
77
+ end
78
+ end
79
+ end
@@ -79,13 +79,20 @@ module Neo4j::Shared
79
79
 
80
80
  def create_query
81
81
  return match_query if graph_object.persisted?
82
- base_query.send(graph_object.create_method, query_string).params(identifier_params.to_sym => graph_object.props_for_create)
82
+ create_props, set_props = filtered_props
83
+ base_query.send(graph_object.create_method, query_string).break
84
+ .set(identifier => set_props)
85
+ .params(:"#{identifier}_create_props" => create_props)
83
86
  end
84
87
 
85
88
  private
86
89
 
90
+ def filtered_props
91
+ Neo4j::Shared::FilteredHash.new(graph_object.props_for_create, graph_object.creates_unique_option).filtered_base
92
+ end
93
+
87
94
  def query_string
88
- "#{graph_object.from_node_identifier}-[#{identifier}:#{graph_object.type} {#{identifier_params}}]->#{graph_object.to_node_identifier}"
95
+ "#{graph_object.from_node_identifier}-[#{identifier}:#{graph_object.type} {#{identifier}_create_props}]->#{graph_object.to_node_identifier}"
89
96
  end
90
97
  end
91
98
  end
@@ -1,3 +1,3 @@
1
1
  module Neo4j
2
- VERSION = '6.0.0.alpha.12'
2
+ VERSION = '6.0.0.rc.1'
3
3
  end
@@ -30,7 +30,7 @@ A Neo4j OGM (Object-Graph-Mapper) for use in Ruby on Rails and Rack frameworks h
30
30
  s.add_dependency('activemodel', '~> 4')
31
31
  s.add_dependency('activesupport', '~> 4')
32
32
  s.add_dependency('active_attr', '~> 0.8')
33
- s.add_dependency('neo4j-core', '~> 6.0.0.alpha.6')
33
+ s.add_dependency('neo4j-core', '~> 6.0.0.rc.1')
34
34
  s.add_dependency('neo4j-community', '~> 2.0') if RUBY_PLATFORM =~ /java/
35
35
  s.add_development_dependency('railties', '~> 4')
36
36
  s.add_development_dependency('pry')
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.alpha.12
4
+ version: 6.0.0.rc.1
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-05 00:00:00.000000000 Z
11
+ date: 2015-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: orm_adapter
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 6.0.0.alpha.6
75
+ version: 6.0.0.rc.1
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 6.0.0.alpha.6
82
+ version: 6.0.0.rc.1
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: railties
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -231,6 +231,8 @@ files:
231
231
  - lib/neo4j/active_node/dependent/query_proxy_methods.rb
232
232
  - lib/neo4j/active_node/has_n.rb
233
233
  - lib/neo4j/active_node/has_n/association.rb
234
+ - lib/neo4j/active_node/has_n/association/rel_factory.rb
235
+ - lib/neo4j/active_node/has_n/association/rel_wrapper.rb
234
236
  - lib/neo4j/active_node/has_n/association_cypher_methods.rb
235
237
  - lib/neo4j/active_node/id_property.rb
236
238
  - lib/neo4j/active_node/id_property/accessor.rb
@@ -276,9 +278,11 @@ files:
276
278
  - lib/neo4j/schema/operation.rb
277
279
  - lib/neo4j/shared.rb
278
280
  - lib/neo4j/shared/callbacks.rb
281
+ - lib/neo4j/shared/cypher.rb
279
282
  - lib/neo4j/shared/declared_properties.rb
280
283
  - lib/neo4j/shared/declared_property.rb
281
284
  - lib/neo4j/shared/declared_property/index.rb
285
+ - lib/neo4j/shared/filtered_hash.rb
282
286
  - lib/neo4j/shared/identity.rb
283
287
  - lib/neo4j/shared/initialize.rb
284
288
  - lib/neo4j/shared/persistence.rb