neo4j 6.0.0.alpha.11 → 6.0.0.alpha.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/neo4j/active_node.rb +5 -0
- data/lib/neo4j/active_node/has_n/association.rb +0 -6
- data/lib/neo4j/active_node/node_wrapper.rb +1 -7
- data/lib/neo4j/active_node/persistence.rb +1 -2
- data/lib/neo4j/active_node/query/query_proxy.rb +1 -3
- data/lib/neo4j/active_rel.rb +22 -1
- data/lib/neo4j/active_rel/rel_wrapper.rb +1 -5
- data/lib/neo4j/active_rel/related_node.rb +1 -1
- data/lib/neo4j/active_rel/types.rb +1 -4
- data/lib/neo4j/config.rb +0 -4
- data/lib/neo4j/migration.rb +0 -92
- data/lib/neo4j/shared/persistence.rb +0 -49
- data/lib/neo4j/shared/property.rb +3 -2
- data/lib/neo4j/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88d57fe8f616166912b89e008686fea6190fee43
|
4
|
+
data.tar.gz: 83cbc8c78c8ae3a8571ed0870699f0537b018a84
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/neo4j/active_node.rb
CHANGED
@@ -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
|
-
|
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)
|
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.
|
222
|
+
association.relationship_class.create(properties.merge(node_props))
|
225
223
|
end
|
226
224
|
end
|
227
225
|
|
data/lib/neo4j/active_rel.rb
CHANGED
@@ -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
|
-
|
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 =
|
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
|
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)
|
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]
|
data/lib/neo4j/migration.rb
CHANGED
@@ -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
|
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
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.
|
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-
|
11
|
+
date: 2015-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: orm_adapter
|