neo4j 6.0.0.alpha.11 → 6.0.0.alpha.12

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: cbd147ccfe5710b9dd99035774e8ccac71f1a2fe
4
- data.tar.gz: 0afb13bbc63f47ce1658313f13541586cdbaca8b
3
+ metadata.gz: 88d57fe8f616166912b89e008686fea6190fee43
4
+ data.tar.gz: 83cbc8c78c8ae3a8571ed0870699f0537b018a84
5
5
  SHA512:
6
- metadata.gz: ba9b1a7bed89c5e0d3be9349a527b496d0cd92a025b0602e68a89b38e4bcae5e45de4a667249abeb23c7fa63be7fcf26f152e48b117108eebcb6f38fe061729c
7
- data.tar.gz: ccb77857f67f3bc4ac45087b10d71ef2117b6170ed437aae1593a77f4ff35549a709b76d9046430dd429419efc6cb829cd76e80e1e790b5faad49a454e6d88dd
6
+ metadata.gz: c13bb99309098ea662883902a7491cec10d32c9beb475a96825622e0a3b9e2f032b6d92eed15524613a796ab00da7407516241f5d655c1fc770ee1e0a321f70e
7
+ data.tar.gz: db933033b16e28f6282dd3e6b46f772587bfa670d125c26e2289f32bba771d93c66c5da3933fe1beb0fab1783495af1604c82ba616179f78179b4f2889a1a55e
data/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@ 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.alpha.12] - 11-5-2015
7
+
8
+ ### Changed
9
+ - `_classname` property has been completely removed, officially dropping support for Neo4j < 2.1.5.
10
+
11
+ ### Added
12
+ - Optional three-argument signature for `ActiveRel#create` and `#create!`, just like `initialize`.
13
+
6
14
  ## [6.0.0.alpha.11] - 11-3-2015
7
15
 
8
16
  ### Fixed
@@ -41,6 +41,11 @@ module Neo4j
41
41
  include Neo4j::ActiveNode::Scope
42
42
  include Neo4j::ActiveNode::Dependent
43
43
 
44
+ def initialize(args = nil)
45
+ symbol_args = args.is_a?(Hash) ? args.symbolize_keys : args
46
+ super(symbol_args)
47
+ end
48
+
44
49
  def neo4j_obj
45
50
  _persisted_obj || fail('Tried to access native neo4j object on a non persisted object')
46
51
  end
@@ -128,12 +128,6 @@ module Neo4j
128
128
  @relationship_class ||= @relationship_class_name && @relationship_class_name.constantize
129
129
  end
130
130
 
131
- def inject_classname(properties)
132
- return properties unless relationship_class
133
- properties[Neo4j::Config.class_name_property] = relationship_class_name if relationship_class.cached_class?(true)
134
- properties
135
- end
136
-
137
131
  def unique?
138
132
  return relationship_class.unique? if rel_class?
139
133
  @origin ? origin_association.unique? : !!@unique
@@ -15,7 +15,7 @@ class Neo4j::Node
15
15
 
16
16
  def class_to_wrap
17
17
  load_classes_from_labels
18
- (named_class || ::Neo4j::ActiveNode::Labels.model_for_labels(labels)).tap do |model_class|
18
+ Neo4j::ActiveNode::Labels.model_for_labels(labels).tap do |model_class|
19
19
  Neo4j::Node::Wrapper.populate_constants_for_labels_cache(model_class, labels)
20
20
  end
21
21
  end
@@ -48,11 +48,5 @@ class Neo4j::Node
48
48
  def self.association_model_namespace
49
49
  Neo4j::Config.association_model_namespace_string
50
50
  end
51
-
52
- def named_class
53
- property = Neo4j::Config.class_name_property
54
-
55
- Neo4j::Node::Wrapper.constant_for_label(self.props[property]) if self.props.is_a?(Hash) && self.props.key?(property)
56
- end
57
51
  end
58
52
  end
@@ -130,9 +130,8 @@ module Neo4j::ActiveNode
130
130
 
131
131
  def find_or_create(find_attributes, set_attributes = {})
132
132
  on_create_attributes = set_attributes.merge(on_create_props(find_attributes))
133
- on_match_attributes = set_attributes.merge(on_match_props)
134
133
  neo4j_session.query.merge(n: {self.mapped_label_names => find_attributes})
135
- .on_create_set(n: on_create_attributes).on_match_set(n: on_match_attributes)
134
+ .on_create_set(n: on_create_attributes)
136
135
  .pluck(:n).first
137
136
  end
138
137
 
@@ -178,8 +178,6 @@ module Neo4j
178
178
  fail 'Can only create relationships on associations' if !@association
179
179
  other_nodes = _nodeify!(*other_nodes)
180
180
 
181
- properties = @association.inject_classname(properties)
182
-
183
181
  Neo4j::Transaction.run do
184
182
  other_nodes.each do |other_node|
185
183
  other_node.save unless other_node.neo_id
@@ -221,7 +219,7 @@ module Neo4j
221
219
  Array(other_node_or_nodes).each do |other_node|
222
220
  node_props = (association.direction == :in) ? {from_node: other_node, to_node: @start_object} : {from_node: @start_object, to_node: other_node}
223
221
 
224
- association.relationship_class.create(properties.except(:_classname).merge(node_props))
222
+ association.relationship_class.create(properties.merge(node_props))
225
223
  end
226
224
  end
227
225
 
@@ -19,7 +19,9 @@ module Neo4j
19
19
 
20
20
  def initialize(from_node = nil, to_node = nil, args = nil)
21
21
  load_nodes(node_or_nil(from_node), node_or_nil(to_node))
22
- super(hash_or_nil(from_node, args))
22
+ resolved_args = hash_or_nil(from_node, args)
23
+ symbol_args = resolved_args.is_a?(Hash) ? resolved_args.symbolize_keys : resolved_args
24
+ super(symbol_args)
23
25
  end
24
26
 
25
27
  def node_cypher_representation(node)
@@ -53,5 +55,24 @@ module Neo4j
53
55
  def hash_or_nil(node_or_hash, hash_or_nil)
54
56
  node_or_hash.is_a?(Hash) ? node_or_hash : hash_or_nil
55
57
  end
58
+
59
+ module ClassMethods
60
+ [:create, :create!].each do |meth|
61
+ define_method(meth) do |from_node_or_args = nil, to_node = nil, args = nil|
62
+ return super(from_node_or_args) if from_node_or_args.is_a?(Hash)
63
+ args_hash = args || {}
64
+ args_with_node!(:from_node, from_node_or_args, args_hash)
65
+ args_with_node!(:to_node, to_node, args_hash)
66
+ super(args_hash)
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def args_with_node!(key, node, args)
73
+ args[key] = node if node.is_a?(Neo4j::ActiveNode)
74
+ args
75
+ end
76
+ end
56
77
  end
57
78
  end
@@ -3,7 +3,7 @@ class Neo4j::Relationship
3
3
  def wrapper
4
4
  props.symbolize_keys!
5
5
  begin
6
- most_concrete_class = sorted_wrapper_classes
6
+ most_concrete_class = class_from_type
7
7
  wrapped_rel = most_concrete_class.constantize.new
8
8
  rescue NameError
9
9
  return self
@@ -15,10 +15,6 @@ class Neo4j::Relationship
15
15
 
16
16
  private
17
17
 
18
- def sorted_wrapper_classes
19
- props[Neo4j::Config.class_name_property] || class_from_type
20
- end
21
-
22
18
  def class_from_type
23
19
  Neo4j::ActiveRel::Types::WRAPPED_CLASSES[rel_type] || Neo4j::ActiveRel::Types::WRAPPED_CLASSES[rel_type] = rel_type.camelize
24
20
  end
@@ -29,7 +29,7 @@ module Neo4j::ActiveRel
29
29
 
30
30
  # Loads a node from the database or returns the node if already laoded
31
31
  def loaded
32
- fail NilRelatedNodeError, 'Node not set, cannot load' if @node.nil?
32
+ fail UnsetRelatedNodeError, 'Node not set, cannot load' if @node.nil?
33
33
  @node = @node.respond_to?(:neo_id) ? @node : Neo4j::Node.load(@node)
34
34
  end
35
35
 
@@ -15,9 +15,6 @@ module Neo4j
15
15
  #
16
16
  # A model is added to WRAPPED_CLASSES when it is initalized AND when the `type` class method is called within a model. This means that
17
17
  # it's possible a model will be added twice: once with the rel_type version of the model name, again with the custom type. deal_with_it.gif.
18
- #
19
- # As an alternative to this, you can call the `set_classname` class method to insert a `_classname` property into your relationship,
20
- # which will completely bypass this whole process.
21
18
  WRAPPED_CLASSES = {}
22
19
 
23
20
  included do
@@ -76,7 +73,7 @@ module Neo4j
76
73
 
77
74
  def assign_type!(given_type, auto)
78
75
  @rel_type = (auto ? decorated_rel_type(given_type) : given_type).tap do |type|
79
- add_wrapped_class(type) unless uses_classname?
76
+ add_wrapped_class(type)
80
77
  end
81
78
  end
82
79
  end
data/lib/neo4j/config.rb CHANGED
@@ -96,10 +96,6 @@ module Neo4j
96
96
  configuration.to_yaml
97
97
  end
98
98
 
99
- def class_name_property
100
- @_class_name_property = Neo4j::Config[CLASS_NAME_PROPERTY_KEY] || :_classname
101
- end
102
-
103
99
  def include_root_in_json
104
100
  # we use ternary because a simple || will always evaluate true
105
101
  Neo4j::Config[:include_root_in_json].nil? ? true : Neo4j::Config[:include_root_in_json]
@@ -123,97 +123,5 @@ MESSAGE
123
123
  end
124
124
  end
125
125
  end
126
-
127
- class AddClassnames < Neo4j::Migration
128
- def initialize(path = default_path)
129
- @classnames_filename = 'add_classnames.yml'
130
- @classnames_filepath = File.join(joined_path(path), classnames_filename)
131
- end
132
-
133
- def migrate
134
- output 'Adding classnames. This make take some time.'
135
- execute(true)
136
- end
137
-
138
- def test
139
- output 'TESTING! No queries will be executed.'
140
- execute(false)
141
- end
142
-
143
- def setup
144
- output "Creating file #{classnames_filepath}. Please use this as the migration guide."
145
- FileUtils.mkdir_p('db/neo4j-migrate')
146
-
147
- return if File.file?(classnames_filepath)
148
-
149
- source = File.join(File.dirname(__FILE__), '..', '..', 'config', 'neo4j', classnames_filename)
150
- FileUtils.copy_file(source, classnames_filepath)
151
- end
152
-
153
- private
154
-
155
- attr_reader :classnames_filename, :classnames_filepath, :model_map
156
-
157
- def execute(migrate = false)
158
- file_init
159
- map = []
160
- map.push :nodes if model_map[:nodes]
161
- map.push :relationships if model_map[:relationships]
162
- map.each do |type|
163
- model_map[type].each do |action, labels|
164
- do_classnames(action, labels, type, migrate)
165
- end
166
- end
167
- end
168
-
169
- def do_classnames(action, labels, type, migrate = false)
170
- method = type == :nodes ? :node_cypher : :rel_cypher
171
- labels.each do |label|
172
- output cypher = self.send(method, label, action)
173
- execute_cypher(cypher) if migrate
174
- end
175
- end
176
-
177
- def file_init
178
- @model_map = ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(classnames_filepath))
179
- end
180
-
181
- def node_cypher(label, action)
182
- where, phrase_start = action_variables(action, 'n')
183
- output "#{phrase_start} _classname '#{label}' on nodes with matching label:"
184
- "MATCH (n:`#{label}`) #{where} SET n._classname = '#{label}' RETURN COUNT(n) as modified"
185
- end
186
-
187
- def rel_cypher(hash, action)
188
- label = hash[0]
189
- value = hash[1]
190
- from = value[:from]
191
- fail "All relationships require a 'type'" unless value[:type]
192
-
193
- from_cypher = from ? "(from:`#{from}`)" : '(from)'
194
- to = value[:to]
195
- to_cypher = to ? "(to:`#{to}`)" : '(to)'
196
- type = "[r:`#{value[:type]}`]"
197
- where, phrase_start = action_variables(action, 'r')
198
- output "#{phrase_start} _classname '#{label}' where type is '#{value[:type]}' using cypher:"
199
- "MATCH #{from_cypher}-#{type}->#{to_cypher} #{where} SET r._classname = '#{label}' return COUNT(r) as modified"
200
- end
201
-
202
- def execute_cypher(query_string)
203
- output "Modified #{Neo4j::Session.query(query_string).first.modified} records"
204
- output ''
205
- end
206
-
207
- def action_variables(action, identifier)
208
- case action
209
- when 'overwrite'
210
- ['', 'Overwriting']
211
- when 'add'
212
- ["WHERE NOT HAS(#{identifier}._classname)", 'Adding']
213
- else
214
- fail "Invalid action #{action} specified"
215
- end
216
- end
217
- end
218
126
  end
219
127
  end
@@ -2,8 +2,6 @@ module Neo4j::Shared
2
2
  module Persistence
3
3
  extend ActiveSupport::Concern
4
4
 
5
- USES_CLASSNAME = []
6
-
7
5
  # @return [Hash] Given a node's state, will call the appropriate `props_for_{action}` method.
8
6
  def props_for_persistence
9
7
  _persisted_obj ? props_for_update : props_for_create
@@ -18,7 +16,6 @@ module Neo4j::Shared
18
16
  # Returns a hash containing:
19
17
  # * All properties and values for insertion in the database
20
18
  # * A `uuid` (or equivalent) key and value
21
- # * A `_classname` property, if one is to be set
22
19
  # * Timestamps, if the class is set to include them.
23
20
  # Note that the UUID is added to the hash but is not set on the node.
24
21
  # The timestamps, by comparison, are set on the node prior to addition in this hash.
@@ -27,7 +24,6 @@ module Neo4j::Shared
27
24
  inject_timestamps!
28
25
  props_with_defaults = inject_defaults!(props)
29
26
  converted_props = props_for_db(props_with_defaults)
30
- inject_classname!(converted_props)
31
27
  return converted_props unless self.class.respond_to?(:default_property_values)
32
28
  inject_primary_key!(converted_props)
33
29
  end
@@ -187,61 +183,16 @@ module Neo4j::Shared
187
183
  self.updated_at = DateTime.now if respond_to?(:updated_at=) && (updated_at.nil? || (changed? && !updated_at_changed?))
188
184
  end
189
185
 
190
- # Inserts the _classname property into an object's properties during object creation.
191
- def inject_classname!(props, check_version = true)
192
- props[:_classname] = self.class.name if self.class.cached_class?(check_version)
193
- end
194
-
195
- def set_classname(props, check_version = true)
196
- warning = 'This method has been replaced with `inject_classname!` and will be removed in a future version'.freeze
197
- ActiveSupport::Deprecation.warn warning, caller
198
- inject_classname!(props, check_version)
199
- end
200
-
201
186
  def inject_timestamps!
202
187
  now = DateTime.now
203
188
  self.created_at ||= now if respond_to?(:created_at=)
204
189
  self.updated_at ||= now if respond_to?(:updated_at=)
205
190
  end
206
191
 
207
-
208
-
209
192
  def set_timestamps
210
193
  warning = 'This method has been replaced with `inject_timestamps!` and will be removed in a future version'.freeze
211
194
  ActiveSupport::Deprecation.warn warning, caller
212
195
  inject_timestamps!
213
196
  end
214
-
215
- module ClassMethods
216
- # Determines whether a model should insert a _classname property. This can be used to override the automatic matching of returned
217
- # objects to models.
218
- def cached_class?(check_version = true)
219
- uses_classname? || (!!Neo4j::Config[:cache_class_names] && (check_version ? neo4j_session.version < '2.1.5' : true))
220
- end
221
-
222
- # @return [Boolean] status of whether this model will add a _classname property
223
- def uses_classname?
224
- Neo4j::Shared::Persistence::USES_CLASSNAME.include?(self.name)
225
- end
226
-
227
- # Adds this model to the USES_CLASSNAME array. When new rels/nodes are created, a _classname property will be added. This will override the
228
- # automatic matching of label/rel type to model.
229
- #
230
- # You'd want to do this if you have multiple models for the same label or relationship type. When it comes to labels, there isn't really any
231
- # reason to do this because you can have multiple labels; on the other hand, an argument can be made for doing this with relationships since
232
- # rel type is a bit more restrictive.
233
- #
234
- # It could also be speculated that there's a slight performance boost to using _classname since the gem immediately knows what model is responsible
235
- # for a returned object. At the same time, it is a bit restrictive and changing it can be a bit of a PITA. Use carefully!
236
- def set_classname
237
- Neo4j::Shared::Persistence::USES_CLASSNAME << self.name
238
- end
239
-
240
- # Removes this model from the USES_CLASSNAME array. When new rels/nodes are create, no _classname property will be injected. Upon returning of
241
- # the object from the database, it will be matched to a model using its relationship type or labels.
242
- def unset_classname
243
- Neo4j::Shared::Persistence::USES_CLASSNAME.delete self.name
244
- end
245
- end
246
197
  end
247
198
  end
@@ -84,13 +84,15 @@ module Neo4j::Shared
84
84
  end
85
85
  end
86
86
 
87
+ DATE_KEY_REGEX = /\A([^\(]+)\((\d+)([if])\)$/
87
88
  # Gives support for Rails date_select, datetime_select, time_select helpers.
88
89
  def process_attributes(attributes = nil)
89
90
  return attributes if attributes.blank?
90
91
  multi_parameter_attributes = {}
91
92
  new_attributes = {}
92
93
  attributes.each_pair do |key, value|
93
- if match = key.match(/\A([^\(]+)\((\d+)([if])\)$/)
94
+ if key.match(DATE_KEY_REGEX)
95
+ match = key.to_s.match(DATE_KEY_REGEX)
94
96
  found_key = match[1]
95
97
  index = match[2].to_i
96
98
  (multi_parameter_attributes[found_key] ||= {})[index] = value.empty? ? nil : value.send("to_#{$3}")
@@ -105,7 +107,6 @@ module Neo4j::Shared
105
107
  def process_multiparameter_attributes(multi_parameter_attributes, new_attributes)
106
108
  multi_parameter_attributes.each_with_object(new_attributes) do |(key, values), attributes|
107
109
  values = (values.keys.min..values.keys.max).map { |i| values[i] }
108
-
109
110
  if (field = self.class.attributes[key.to_sym]).nil?
110
111
  fail MultiparameterAssignmentError, "error on assignment #{values.inspect} to #{key}"
111
112
  end
data/lib/neo4j/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Neo4j
2
- VERSION = '6.0.0.alpha.11'
2
+ VERSION = '6.0.0.alpha.12'
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.alpha.11
4
+ version: 6.0.0.alpha.12
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-03 00:00:00.000000000 Z
11
+ date: 2015-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: orm_adapter