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

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