neo4j 5.1.5 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -9
- data/lib/neo4j/active_node/has_n.rb +0 -4
- data/lib/neo4j/active_node/labels.rb +8 -1
- data/lib/neo4j/active_node/persistence.rb +20 -14
- data/lib/neo4j/active_node/query/query_proxy_methods.rb +0 -1
- data/lib/neo4j/active_node/unpersisted.rb +2 -4
- data/lib/neo4j/active_node.rb +2 -0
- data/lib/neo4j/active_rel/persistence.rb +2 -13
- data/lib/neo4j/active_rel.rb +2 -0
- data/lib/neo4j/config.rb +16 -2
- data/lib/neo4j/railtie.rb +0 -6
- data/lib/neo4j/shared/declared_property.rb +5 -1
- data/lib/neo4j/shared/persistence.rb +47 -9
- data/lib/neo4j/timestamps/created.rb +1 -3
- data/lib/neo4j/timestamps/updated.rb +1 -3
- data/lib/neo4j/version.rb +1 -1
- data/lib/neo4j.rb +0 -1
- metadata +3 -4
- data/lib/neo4j/active_node/labels/reloading.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cdc33103cf05e1ec6a124c615303f0fcb7ff0760
|
4
|
+
data.tar.gz: 679ae2889ebbe49d6083fe9d471508996a2e6750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b770454c98281fded4132b80fd9c3b7e6fc42b9450fa6dbc97d5b6eefd77b98a9c909183cfe05637ce2e7cef3d368d72d5abd06d2dbe690d8b203f527ee0885
|
7
|
+
data.tar.gz: 4b46fbd5003efb1421a0fdc5f99fe0511c0c89ed6ff7a9c8d08822d7cb03bd156cb82e526ea44c1608476f4ad4c5c9fc5ed1b1d918a2f8a4988e8b741c874b19
|
data/CHANGELOG.md
CHANGED
@@ -5,17 +5,16 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
5
5
|
|
6
6
|
## [Unreleased][unreleased]
|
7
7
|
|
8
|
-
## [5.
|
8
|
+
## [5.2.0] - 08-30-2015
|
9
9
|
|
10
|
-
###
|
11
|
-
-
|
12
|
-
-
|
13
|
-
-
|
14
|
-
|
15
|
-
## [5.1.4] - 08-24-2015
|
10
|
+
### Added
|
11
|
+
- `props_for_persistence`, `props_for_create`, `props_for_update` instance methods for all nodes and rels. Each returns a hash with properties appropriate for sending to the database in a Cypher query to create or update an object.
|
12
|
+
- Added `record_timestamps` configuration do default all `ActiveNode` and `ActiveRel` models to have `created_at` and `updated_at` timestamps (from #939, thanks @rebecca-eakins)
|
13
|
+
- Added `timestamp_type` configuration to specify how timestamps should be stored (from #939, thanks @rebecca-eakins)
|
16
14
|
|
17
|
-
###
|
18
|
-
-
|
15
|
+
### Changed
|
16
|
+
- Methods related to basic node and rel persistence (`save`, `create_model`, `_create_node`, others) were refactored to make the processes simpler, clearer, and slightly faster.
|
17
|
+
- Unit test directory structure was rearranged to mirror the `lib` directory.
|
19
18
|
|
20
19
|
## [5.1.3] - 08-23-2015
|
21
20
|
|
@@ -23,6 +22,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
23
22
|
- `has_one` associations are now properly cached (like `has_many` associations)
|
24
23
|
- `QueryProxy` now responds to `#to_ary`. Fixes integration with ActiveModelSerializer gem
|
25
24
|
|
25
|
+
|
26
26
|
## [5.1.2] - 08-20-2015
|
27
27
|
|
28
28
|
### Fixed
|
@@ -3,7 +3,6 @@ module Neo4j
|
|
3
3
|
# Provides a mapping between neo4j labels and Ruby classes
|
4
4
|
module Labels
|
5
5
|
extend ActiveSupport::Concern
|
6
|
-
include Neo4j::ActiveNode::Labels::Reloading
|
7
6
|
|
8
7
|
WRAPPED_CLASSES = []
|
9
8
|
MODELS_FOR_LABELS_CACHE = {}
|
@@ -76,9 +75,17 @@ module Neo4j
|
|
76
75
|
WRAPPED_CLASSES.clear
|
77
76
|
end
|
78
77
|
|
78
|
+
protected
|
79
|
+
|
79
80
|
module ClassMethods
|
80
81
|
include Neo4j::ActiveNode::QueryMethods
|
81
82
|
|
83
|
+
def before_remove_const
|
84
|
+
associations.each_value(&:queue_model_refresh!)
|
85
|
+
MODELS_FOR_LABELS_CACHE.clear
|
86
|
+
WRAPPED_CLASSES.clear
|
87
|
+
end
|
88
|
+
|
82
89
|
# Returns the object with the specified neo4j id.
|
83
90
|
# @param [String,Integer] id of node to find
|
84
91
|
def find(id)
|
@@ -23,7 +23,6 @@ module Neo4j::ActiveNode
|
|
23
23
|
# There's a series of callbacks associated with save.
|
24
24
|
# If any of the before_* callbacks return false the action is cancelled and save returns false.
|
25
25
|
def save(*)
|
26
|
-
update_magic_properties
|
27
26
|
cascade_save do
|
28
27
|
association_proxy_cache.clear
|
29
28
|
create_or_update
|
@@ -47,25 +46,32 @@ module Neo4j::ActiveNode
|
|
47
46
|
# Creates a model with values matching those of the instance attributes and returns its id.
|
48
47
|
# @private
|
49
48
|
# @return true
|
50
|
-
def create_model
|
51
|
-
|
52
|
-
set_timestamps
|
53
|
-
create_magic_properties
|
54
|
-
properties = self.class.declared_property_manager.convert_properties_to(self, :db, props)
|
55
|
-
node = _create_node(properties)
|
49
|
+
def create_model
|
50
|
+
node = _create_node(props_for_create)
|
56
51
|
init_on_load(node, node.props)
|
57
52
|
send_props(@relationship_props) if @relationship_props
|
58
53
|
@relationship_props = @deferred_nodes = nil
|
59
54
|
true
|
60
55
|
end
|
61
56
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
57
|
+
# TODO: This does not seem like it should be the responsibility of the node.
|
58
|
+
# Creates an unwrapped node in the database.
|
59
|
+
# @param [Hash] node_props The type-converted properties to be added to the new node.
|
60
|
+
# @param [Array] labels The labels to use for creating the new node.
|
61
|
+
# @return [Neo4j::Node] A CypherNode or EmbeddedNode
|
62
|
+
def _create_node(node_props, labels = labels_for_create)
|
63
|
+
self.class.neo4j_session.create_node(node_props, labels)
|
64
|
+
end
|
65
|
+
|
66
|
+
def inject_primary_key!(converted_props)
|
67
|
+
self.class.default_property_values(self).tap do |destination_props|
|
68
|
+
destination_props.merge!(converted_props) if converted_props.is_a?(Hash)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Array] Labels to be set on the node during a create event
|
73
|
+
def labels_for_create
|
74
|
+
self.class.mapped_label_names
|
69
75
|
end
|
70
76
|
|
71
77
|
private
|
@@ -164,7 +164,6 @@ module Neo4j
|
|
164
164
|
|
165
165
|
# Deletes the relationships between all nodes for the last step in the QueryProxy chain. Executed in the database, callbacks will not be run.
|
166
166
|
def delete_all_rels
|
167
|
-
return unless start_object && start_object._persisted_obj
|
168
167
|
self.query.delete(rel_var).exec
|
169
168
|
end
|
170
169
|
|
@@ -40,10 +40,8 @@ module Neo4j
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def save_and_associate_node(association_name, node, operator)
|
43
|
-
if node.
|
44
|
-
|
45
|
-
fail "Unable to defer node persistence, could not save #{node.inspect}" unless node.persisted?
|
46
|
-
end
|
43
|
+
node.save if node.changed? || !node.persisted?
|
44
|
+
fail "Unable to defer node persistence, could not save #{node.inspect}" unless node.persisted?
|
47
45
|
operator == :<< ? send(association_name).send(operator, node) : send(:"#{association_name}=", node)
|
48
46
|
end
|
49
47
|
end
|
data/lib/neo4j/active_node.rb
CHANGED
@@ -7,13 +7,7 @@ module Neo4j::ActiveRel
|
|
7
7
|
class ModelClassInvalidError < RuntimeError; end
|
8
8
|
class RelCreateFailedError < RuntimeError; end
|
9
9
|
|
10
|
-
# Should probably find a way to not need this
|
11
|
-
def association_proxy_cache
|
12
|
-
{}
|
13
|
-
end
|
14
|
-
|
15
10
|
def save(*)
|
16
|
-
update_magic_properties
|
17
11
|
create_or_update
|
18
12
|
end
|
19
13
|
|
@@ -21,12 +15,9 @@ module Neo4j::ActiveRel
|
|
21
15
|
fail RelInvalidError, self unless save(*args)
|
22
16
|
end
|
23
17
|
|
24
|
-
def create_model
|
18
|
+
def create_model
|
25
19
|
validate_node_classes!
|
26
|
-
|
27
|
-
set_timestamps
|
28
|
-
properties = self.class.declared_property_manager.convert_properties_to(self, :db, props)
|
29
|
-
rel = _create_rel(from_node, to_node, properties)
|
20
|
+
rel = _create_rel(from_node, to_node, props_for_create)
|
30
21
|
return self unless rel.respond_to?(:_persisted_obj)
|
31
22
|
init_on_load(rel._persisted_obj, from_node, to_node, @rel_type)
|
32
23
|
true
|
@@ -82,8 +73,6 @@ module Neo4j::ActiveRel
|
|
82
73
|
end
|
83
74
|
|
84
75
|
def _create_rel(from_node, to_node, props = {})
|
85
|
-
set_classname(props, true)
|
86
|
-
|
87
76
|
if from_node.id.nil? || to_node.id.nil?
|
88
77
|
fail RelCreateFailedError, "Unable to create relationship (id is nil). from_node: #{from_node}, to_node: #{to_node}"
|
89
78
|
end
|
data/lib/neo4j/active_rel.rb
CHANGED
data/lib/neo4j/config.rb
CHANGED
@@ -2,19 +2,22 @@ module Neo4j
|
|
2
2
|
# == Keeps configuration for neo4j
|
3
3
|
#
|
4
4
|
# == Configurations keys
|
5
|
-
#
|
6
5
|
class Config
|
7
6
|
DEFAULT_FILE = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config', 'neo4j', 'config.yml'))
|
8
7
|
CLASS_NAME_PROPERTY_KEY = 'class_name_property'
|
9
8
|
|
10
9
|
class << self
|
10
|
+
# In keeping with the Rails convention, this class writer lets you globally configure
|
11
|
+
# the incluse of timestamps on your nodes and rels. It defaults to false, requiring manual
|
12
|
+
# timestamp inclusion.
|
13
|
+
# @return [Boolean] the true/false value specified.
|
14
|
+
attr_writer :record_timestamps
|
11
15
|
# @return [Fixnum] The location of the default configuration file.
|
12
16
|
def default_file
|
13
17
|
@default_file ||= DEFAULT_FILE
|
14
18
|
end
|
15
19
|
|
16
20
|
# Sets the location of the configuration YAML file and old deletes configurations.
|
17
|
-
#
|
18
21
|
# @param [String] file_path represent the path to the file.
|
19
22
|
def default_file=(file_path)
|
20
23
|
delete_all
|
@@ -93,6 +96,12 @@ module Neo4j
|
|
93
96
|
configuration.to_yaml
|
94
97
|
end
|
95
98
|
|
99
|
+
# @return [Boolean] The value of the config variable for including
|
100
|
+
# timestamps on all models.
|
101
|
+
def record_timestamps
|
102
|
+
@record_timestamps ||= false
|
103
|
+
end
|
104
|
+
|
96
105
|
def class_name_property
|
97
106
|
@_class_name_property = Neo4j::Config[CLASS_NAME_PROPERTY_KEY] || :_classname
|
98
107
|
end
|
@@ -106,6 +115,11 @@ module Neo4j
|
|
106
115
|
Neo4j::Config[:module_handling] || :none
|
107
116
|
end
|
108
117
|
|
118
|
+
# @return [Class] The configured timestamps type (e.g. Integer) or the default DateTime.
|
119
|
+
def timestamp_type
|
120
|
+
Neo4j::Config[:timestamp_type] || DateTime
|
121
|
+
end
|
122
|
+
|
109
123
|
def association_model_namespace
|
110
124
|
Neo4j::Config[:association_model_namespace] || nil
|
111
125
|
end
|
data/lib/neo4j/railtie.rb
CHANGED
@@ -5,12 +5,6 @@ module Neo4j
|
|
5
5
|
class Railtie < ::Rails::Railtie
|
6
6
|
config.neo4j = ActiveSupport::OrderedOptions.new
|
7
7
|
|
8
|
-
if const_defined?(:ActionDispatch)
|
9
|
-
ActionDispatch::Reloader.to_prepare do
|
10
|
-
Neo4j::ActiveNode::Labels::Reloading.reload_models!
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
8
|
# Add ActiveModel translations to the I18n load_path
|
15
9
|
initializer 'i18n' do
|
16
10
|
config.i18n.load_path += Dir[File.join(File.dirname(__FILE__), '..', '..', '..', 'config', 'locales', '*.{rb,yml}')]
|
@@ -33,12 +33,16 @@ module Neo4j::Shared
|
|
33
33
|
|
34
34
|
# Tweaks properties
|
35
35
|
def register_magic_properties
|
36
|
-
options[:type] ||=
|
36
|
+
options[:type] ||= Neo4j::Config.timestamp_type if timestamp_prop?
|
37
37
|
|
38
38
|
register_magic_typecaster
|
39
39
|
register_type_converter
|
40
40
|
end
|
41
41
|
|
42
|
+
def timestamp_prop?
|
43
|
+
name.to_sym == :created_at || name.to_sym == :updated_at
|
44
|
+
end
|
45
|
+
|
42
46
|
def register_magic_typecaster
|
43
47
|
found_typecaster = Neo4j::Shared::TypeConverters.typecaster_for(options[:type])
|
44
48
|
return unless found_typecaster && found_typecaster.respond_to?(:primitive_type)
|
@@ -4,13 +4,38 @@ module Neo4j::Shared
|
|
4
4
|
|
5
5
|
USES_CLASSNAME = []
|
6
6
|
|
7
|
+
# @return [Hash] Given a node's state, will call the appropriate `props_for_{action}` method.
|
8
|
+
def props_for_persistence
|
9
|
+
_persisted_obj ? props_for_update : props_for_create
|
10
|
+
end
|
11
|
+
|
7
12
|
def update_model
|
8
13
|
return if !changed_attributes || changed_attributes.empty?
|
14
|
+
_persisted_obj.update_props(props_for_update)
|
15
|
+
changed_attributes.clear
|
16
|
+
end
|
9
17
|
|
18
|
+
# Returns a hash containing:
|
19
|
+
# * All properties and values for insertion in the database
|
20
|
+
# * A `uuid` (or equivalent) key and value
|
21
|
+
# * A `_classname` property, if one is to be set
|
22
|
+
# * Timestamps, if the class is set to include them.
|
23
|
+
# Note that the UUID is added to the hash but is not set on the node.
|
24
|
+
# The timestamps, by comparison, are set on the node prior to addition in this hash.
|
25
|
+
# @return [Hash]
|
26
|
+
def props_for_create
|
27
|
+
inject_timestamps!
|
28
|
+
converted_props = props_for_db(props)
|
29
|
+
inject_classname!(converted_props)
|
30
|
+
return converted_props unless self.class.respond_to?(:default_property_values)
|
31
|
+
inject_primary_key!(converted_props)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Hash] Properties and values, type-converted and timestamped for the database.
|
35
|
+
def props_for_update
|
36
|
+
update_magic_properties
|
10
37
|
changed_props = attributes.select { |k, _| changed_attributes.include?(k) }
|
11
|
-
|
12
|
-
_persisted_obj.update_props(changed_props)
|
13
|
-
changed_attributes.clear
|
38
|
+
props_for_db(changed_props)
|
14
39
|
end
|
15
40
|
|
16
41
|
# Convenience method to set attribute and #save at the same time
|
@@ -115,7 +140,7 @@ module Neo4j::Shared
|
|
115
140
|
|
116
141
|
def reload
|
117
142
|
return self if new_record?
|
118
|
-
association_proxy_cache.clear
|
143
|
+
association_proxy_cache.clear if respond_to?(:association_proxy_cache)
|
119
144
|
changed_attributes && changed_attributes.clear
|
120
145
|
unless reload_from_database
|
121
146
|
@_deleted = true
|
@@ -159,11 +184,12 @@ module Neo4j::Shared
|
|
159
184
|
|
160
185
|
private
|
161
186
|
|
162
|
-
def
|
163
|
-
self.class.
|
187
|
+
def props_for_db(props_hash)
|
188
|
+
self.class.declared_property_manager.convert_properties_to(self, :db, props_hash)
|
164
189
|
end
|
165
190
|
|
166
|
-
def
|
191
|
+
def model_cache_key
|
192
|
+
self.class.model_name.cache_key
|
167
193
|
end
|
168
194
|
|
169
195
|
def update_magic_properties
|
@@ -171,16 +197,28 @@ module Neo4j::Shared
|
|
171
197
|
end
|
172
198
|
|
173
199
|
# Inserts the _classname property into an object's properties during object creation.
|
174
|
-
def
|
200
|
+
def inject_classname!(props, check_version = true)
|
175
201
|
props[:_classname] = self.class.name if self.class.cached_class?(check_version)
|
176
202
|
end
|
177
203
|
|
178
|
-
def
|
204
|
+
def set_classname(props, check_version = true)
|
205
|
+
warning = 'This method has been replaced with `inject_classname!` and will be removed in a future version'.freeze
|
206
|
+
ActiveSupport::Deprecation.warn warning, caller
|
207
|
+
inject_classname!(props, check_version)
|
208
|
+
end
|
209
|
+
|
210
|
+
def inject_timestamps!
|
179
211
|
now = DateTime.now
|
180
212
|
self.created_at ||= now if respond_to?(:created_at=)
|
181
213
|
self.updated_at ||= now if respond_to?(:updated_at=)
|
182
214
|
end
|
183
215
|
|
216
|
+
def set_timestamps
|
217
|
+
warning = 'This method has been replaced with `inject_timestamps!` and will be removed in a future version'.freeze
|
218
|
+
ActiveSupport::Deprecation.warn warning, caller
|
219
|
+
inject_timestamps!
|
220
|
+
end
|
221
|
+
|
184
222
|
module ClassMethods
|
185
223
|
# Determines whether a model should insert a _classname property. This can be used to override the automatic matching of returned
|
186
224
|
# objects to models.
|
data/lib/neo4j/version.rb
CHANGED
data/lib/neo4j.rb
CHANGED
@@ -60,7 +60,6 @@ require 'neo4j/active_node/query/query_proxy_enumerable'
|
|
60
60
|
require 'neo4j/active_node/query/query_proxy_find_in_batches'
|
61
61
|
require 'neo4j/active_node/query/query_proxy_eager_loading'
|
62
62
|
require 'neo4j/active_node/query/query_proxy_link'
|
63
|
-
require 'neo4j/active_node/labels/reloading'
|
64
63
|
require 'neo4j/active_node/labels'
|
65
64
|
require 'neo4j/active_node/id_property/accessor'
|
66
65
|
require 'neo4j/active_node/id_property'
|
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: 5.
|
4
|
+
version: 5.2.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-08-
|
11
|
+
date: 2015-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: orm_adapter
|
@@ -236,7 +236,6 @@ files:
|
|
236
236
|
- lib/neo4j/active_node/id_property/accessor.rb
|
237
237
|
- lib/neo4j/active_node/initialize.rb
|
238
238
|
- lib/neo4j/active_node/labels.rb
|
239
|
-
- lib/neo4j/active_node/labels/reloading.rb
|
240
239
|
- lib/neo4j/active_node/node_wrapper.rb
|
241
240
|
- lib/neo4j/active_node/orm_adapter.rb
|
242
241
|
- lib/neo4j/active_node/persistence.rb
|
@@ -323,7 +322,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
323
322
|
version: '0'
|
324
323
|
requirements: []
|
325
324
|
rubyforge_project: neo4j
|
326
|
-
rubygems_version: 2.4.
|
325
|
+
rubygems_version: 2.4.5
|
327
326
|
signing_key:
|
328
327
|
specification_version: 4
|
329
328
|
summary: A graph database for Ruby
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Neo4j::ActiveNode::Labels
|
2
|
-
module Reloading
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
MODELS_TO_RELOAD = []
|
6
|
-
|
7
|
-
def self.reload_models!
|
8
|
-
MODELS_TO_RELOAD.each(&:constantize)
|
9
|
-
MODELS_TO_RELOAD.clear
|
10
|
-
end
|
11
|
-
|
12
|
-
module ClassMethods
|
13
|
-
def before_remove_const
|
14
|
-
associations.each_value(&:queue_model_refresh!)
|
15
|
-
MODELS_FOR_LABELS_CACHE.clear
|
16
|
-
WRAPPED_CLASSES.each { |c| MODELS_TO_RELOAD << c.name }
|
17
|
-
WRAPPED_CLASSES.clear
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|