neo4j 6.1.12 → 7.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 +4 -4
- data/CHANGELOG.md +20 -33
- data/lib/neo4j.rb +6 -10
- data/lib/neo4j/active_node.rb +1 -0
- data/lib/neo4j/active_node/enum.rb +29 -0
- data/lib/neo4j/active_node/has_n.rb +1 -1
- data/lib/neo4j/active_node/has_n/association.rb +1 -1
- data/lib/neo4j/active_node/labels.rb +16 -8
- data/lib/neo4j/active_node/persistence.rb +14 -6
- data/lib/neo4j/active_node/query/query_proxy.rb +20 -0
- data/lib/neo4j/active_node/query/query_proxy_find_in_batches.rb +1 -1
- data/lib/neo4j/active_node/query/query_proxy_methods.rb +21 -66
- data/lib/neo4j/active_node/query/query_proxy_methods_of_mass_updating.rb +83 -0
- data/lib/neo4j/active_node/query_methods.rb +2 -4
- data/lib/neo4j/active_node/scope.rb +5 -9
- data/lib/neo4j/active_rel.rb +2 -1
- data/lib/neo4j/active_rel/related_node.rb +2 -3
- data/lib/neo4j/errors.rb +19 -3
- data/lib/neo4j/railtie.rb +13 -0
- data/lib/neo4j/shared/attributes.rb +207 -0
- data/lib/neo4j/shared/declared_properties.rb +2 -8
- data/lib/neo4j/shared/declared_property.rb +40 -3
- data/lib/neo4j/shared/enum.rb +148 -0
- data/lib/neo4j/shared/filtered_hash.rb +1 -1
- data/lib/neo4j/shared/mass_assignment.rb +58 -0
- data/lib/neo4j/shared/property.rb +41 -45
- data/lib/neo4j/shared/type_converters.rb +76 -17
- data/lib/neo4j/shared/typecasted_attributes.rb +98 -0
- data/lib/neo4j/version.rb +1 -1
- data/neo4j.gemspec +0 -1
- metadata +10 -19
- data/lib/neo4j/shared/property/default_property.rb +0 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module ActiveNode
|
3
|
+
module Query
|
4
|
+
module QueryProxyMethodsOfMassUpdating
|
5
|
+
# Updates some attributes of a group of nodes within a QP chain.
|
6
|
+
# The optional argument makes sense only of `updates` is a string.
|
7
|
+
# @param [Hash,String] updates An hash or a string of parameters to be updated.
|
8
|
+
# @param [Hash] params An hash of parameters for the update string. It's ignored if `updates` is an Hash.
|
9
|
+
def update_all(updates, params = {})
|
10
|
+
# Move this to ActiveNode module?
|
11
|
+
update_all_with_query(identity, updates, params)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Updates some attributes of a group of relationships within a QP chain.
|
15
|
+
# The optional argument makes sense only of `updates` is a string.
|
16
|
+
# @param [Hash,String] updates An hash or a string of parameters to be updated.
|
17
|
+
# @param [Hash] params An hash of parameters for the update string. It's ignored if `updates` is an Hash.
|
18
|
+
def update_all_rels(updates, params = {})
|
19
|
+
fail 'Cannot update rels without a relationship variable.' unless @rel_var
|
20
|
+
update_all_with_query(@rel_var, updates, params)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Deletes a group of nodes and relationships within a QP chain. When identifier is omitted, it will remove the last link in the chain.
|
24
|
+
# The optional argument must be a node identifier. A relationship identifier will result in a Cypher Error
|
25
|
+
# @param identifier [String,Symbol] the optional identifier of the link in the chain to delete.
|
26
|
+
def delete_all(identifier = nil)
|
27
|
+
query_with_target(identifier) do |target|
|
28
|
+
begin
|
29
|
+
self.query.with(target).optional_match("(#{target})-[#{target}_rel]-()").delete("#{target}, #{target}_rel").exec
|
30
|
+
rescue Neo4j::Session::CypherError
|
31
|
+
self.query.delete(target).exec
|
32
|
+
end
|
33
|
+
clear_source_object_cache
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Deletes the relationship between a node and its last link in the QueryProxy chain. Executed in the database, callbacks will not run.
|
38
|
+
def delete(node)
|
39
|
+
self.match_to(node).query.delete(rel_var).exec
|
40
|
+
clear_source_object_cache
|
41
|
+
end
|
42
|
+
|
43
|
+
# Deletes the relationships between all nodes for the last step in the QueryProxy chain. Executed in the database, callbacks will not be run.
|
44
|
+
def delete_all_rels
|
45
|
+
return unless start_object && start_object._persisted_obj
|
46
|
+
self.query.delete(rel_var).exec
|
47
|
+
end
|
48
|
+
|
49
|
+
# Deletes the relationships between all nodes for the last step in the QueryProxy chain and replaces them with relationships to the given nodes.
|
50
|
+
# Executed in the database, callbacks will not be run.
|
51
|
+
def replace_with(node_or_nodes)
|
52
|
+
nodes = Array(node_or_nodes)
|
53
|
+
|
54
|
+
self.delete_all_rels
|
55
|
+
nodes.each { |node| self << node }
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns all relationships between a node and its last link in the QueryProxy chain, destroys them in Ruby. Callbacks will be run.
|
59
|
+
def destroy(node)
|
60
|
+
self.rels_to(node).map!(&:destroy)
|
61
|
+
clear_source_object_cache
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def update_all_with_query(var_name, updates, params)
|
67
|
+
query = all.query
|
68
|
+
|
69
|
+
case updates
|
70
|
+
when Hash then query.set(var_name => updates).pluck("count(#{var_name})").first
|
71
|
+
when String then query.set(updates).params(params).pluck("count(#{var_name})").first
|
72
|
+
else
|
73
|
+
fail ArgumentError, "Invalid parameter type #{updates.class} for `updates`."
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def clear_source_object_cache
|
78
|
+
self.source_object.clear_association_cache if self.source_object.respond_to?(:clear_association_cache)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module ActiveNode
|
3
3
|
module QueryMethods
|
4
|
-
class InvalidParameterError < StandardError; end
|
5
|
-
|
6
4
|
def exists?(node_condition = nil)
|
7
5
|
unless node_condition.is_a?(Integer) || node_condition.is_a?(Hash) || node_condition.nil?
|
8
|
-
fail(InvalidParameterError, ':exists? only accepts ids or conditions')
|
6
|
+
fail(Neo4j::InvalidParameterError, ':exists? only accepts ids or conditions')
|
9
7
|
end
|
10
8
|
query_start = exists_query_start(node_condition)
|
11
9
|
start_q = query_start.respond_to?(:query_as) ? query_start.query_as(:n) : query_start
|
@@ -24,7 +22,7 @@ module Neo4j
|
|
24
22
|
|
25
23
|
# @return [Integer] number of nodes of this class
|
26
24
|
def count(distinct = nil)
|
27
|
-
fail(InvalidParameterError, ':count accepts `distinct` or nil as a parameter') unless distinct.nil? || distinct == :distinct
|
25
|
+
fail(Neo4j::InvalidParameterError, ':count accepts `distinct` or nil as a parameter') unless distinct.nil? || distinct == :distinct
|
28
26
|
q = distinct.nil? ? 'n' : 'DISTINCT n'
|
29
27
|
self.query_as(:n).return("count(#{q}) AS count").first.count
|
30
28
|
end
|
@@ -35,13 +35,13 @@ module Neo4j::ActiveNode
|
|
35
35
|
#
|
36
36
|
# @see http://guides.rubyonrails.org/active_record_querying.html#scopes
|
37
37
|
def scope(name, proc)
|
38
|
-
|
38
|
+
_scope[name.to_sym] = proc
|
39
39
|
|
40
40
|
klass = class << self; self; end
|
41
41
|
klass.instance_eval do
|
42
42
|
define_method(name) do |query_params = nil, _ = nil|
|
43
43
|
eval_context = ScopeEvalContext.new(self, current_scope || self.query_proxy)
|
44
|
-
proc =
|
44
|
+
proc = _scope[name.to_sym]
|
45
45
|
_call_scope_context(eval_context, query_params, proc)
|
46
46
|
end
|
47
47
|
end
|
@@ -56,15 +56,11 @@ module Neo4j::ActiveNode
|
|
56
56
|
# rubocop:enable Style/PredicateName
|
57
57
|
|
58
58
|
def scope?(name)
|
59
|
-
|
59
|
+
_scope.key?(name.to_sym)
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
63
|
-
@
|
64
|
-
end
|
65
|
-
|
66
|
-
def full_scopes
|
67
|
-
scopes.merge(self.superclass.respond_to?(:scopes) ? self.superclass.scopes : {})
|
62
|
+
def _scope
|
63
|
+
@_scope ||= {}
|
68
64
|
end
|
69
65
|
|
70
66
|
def _call_scope_context(eval_context, query_params, proc)
|
data/lib/neo4j/active_rel.rb
CHANGED
@@ -17,8 +17,9 @@ module Neo4j
|
|
17
17
|
include Neo4j::ActiveRel::Callbacks
|
18
18
|
include Neo4j::ActiveRel::Query
|
19
19
|
include Neo4j::ActiveRel::Types
|
20
|
+
include Neo4j::Shared::Enum
|
20
21
|
|
21
|
-
class FrozenRelError <
|
22
|
+
class FrozenRelError < Neo4j::Error; end
|
22
23
|
|
23
24
|
def initialize(from_node = nil, to_node = nil, args = nil)
|
24
25
|
load_nodes(node_or_nil(from_node), node_or_nil(to_node))
|
@@ -3,8 +3,7 @@ module Neo4j::ActiveRel
|
|
3
3
|
# It's important (or maybe not really IMPORTANT, but at least worth mentioning) that calling method_missing
|
4
4
|
# will result in a query to load the node if the node is not already loaded.
|
5
5
|
class RelatedNode
|
6
|
-
class
|
7
|
-
class UnsetRelatedNodeError < StandardError; end
|
6
|
+
class UnsetRelatedNodeError < Neo4j::Error; end
|
8
7
|
|
9
8
|
# ActiveRel's related nodes can be initialized with nothing, an integer, or a fully wrapped node.
|
10
9
|
#
|
@@ -13,7 +12,7 @@ module Neo4j::ActiveRel
|
|
13
12
|
# Initialization with an integer happens when a relationship is loaded from the database. It loads using the ID
|
14
13
|
# because that is provided by the Cypher response and does not require an extra query.
|
15
14
|
def initialize(node = nil)
|
16
|
-
@node = valid_node_param?(node) ? node : (fail InvalidParameterError, 'RelatedNode must be initialized with either a node ID or node')
|
15
|
+
@node = valid_node_param?(node) ? node : (fail Neo4j::InvalidParameterError, 'RelatedNode must be initialized with either a node ID or node')
|
17
16
|
end
|
18
17
|
|
19
18
|
# Loads the node if needed, then conducts comparison.
|
data/lib/neo4j/errors.rb
CHANGED
@@ -1,12 +1,28 @@
|
|
1
1
|
module Neo4j
|
2
2
|
# Neo4j.rb Errors
|
3
3
|
# Generic Neo4j.rb exception class.
|
4
|
-
class
|
4
|
+
class Error < StandardError
|
5
5
|
end
|
6
6
|
|
7
7
|
# Raised when Neo4j.rb cannot find record by given id.
|
8
|
-
class RecordNotFound <
|
8
|
+
class RecordNotFound < Error
|
9
|
+
attr_reader :model, :primary_key, :id
|
10
|
+
|
11
|
+
def initialize(message = nil, model = nil, primary_key = nil, id = nil)
|
12
|
+
@primary_key = primary_key
|
13
|
+
@model = model
|
14
|
+
@id = id
|
15
|
+
|
16
|
+
super(message)
|
17
|
+
end
|
9
18
|
end
|
10
19
|
|
11
|
-
class InvalidPropertyOptionsError <
|
20
|
+
class InvalidPropertyOptionsError < Error; end
|
21
|
+
|
22
|
+
class InvalidParameterError < Error; end
|
23
|
+
|
24
|
+
class UnknownTypeConverterError < Error; end
|
25
|
+
|
26
|
+
class DangerousAttributeError < ScriptError; end
|
27
|
+
class UnknownAttributeError < NoMethodError; end
|
12
28
|
end
|
data/lib/neo4j/railtie.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'active_support/notifications'
|
2
2
|
require 'rails/railtie'
|
3
|
+
# Need the action_dispatch railtie to have action_dispatch.rescue_responses initialized correctly
|
4
|
+
require 'action_dispatch/railtie'
|
3
5
|
|
4
6
|
module Neo4j
|
5
7
|
class Railtie < ::Rails::Railtie
|
@@ -11,6 +13,17 @@ module Neo4j
|
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
16
|
+
# Rescue responses similar to ActiveRecord.
|
17
|
+
# For rails 3.2 and 4.0
|
18
|
+
if config.action_dispatch.respond_to?(:rescue_responses)
|
19
|
+
config.action_dispatch.rescue_responses.merge!(
|
20
|
+
'Neo4j::RecordNotFound' => :not_found
|
21
|
+
)
|
22
|
+
else
|
23
|
+
# For rails 3.0 and 3.1
|
24
|
+
ActionDispatch::ShowExceptions.rescue_responses['Neo4j::RecordNotFound'] = :not_found
|
25
|
+
end
|
26
|
+
|
14
27
|
# Add ActiveModel translations to the I18n load_path
|
15
28
|
initializer 'i18n' do
|
16
29
|
config.i18n.load_path += Dir[File.join(File.dirname(__FILE__), '..', '..', '..', 'config', 'locales', '*.{rb,yml}')]
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module Neo4j::Shared
|
2
|
+
# Attributes provides a set of class methods for defining an attributes
|
3
|
+
# schema and instance methods for reading and writing attributes.
|
4
|
+
#
|
5
|
+
# @example Usage
|
6
|
+
# class Person
|
7
|
+
# include Neo4j::Shared::Attributes
|
8
|
+
# attribute :name
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# person = Person.new
|
12
|
+
# person.name = "Ben Poweski"
|
13
|
+
#
|
14
|
+
# Originally part of ActiveAttr, https://github.com/cgriego/active_attr
|
15
|
+
module Attributes
|
16
|
+
extend ActiveSupport::Concern
|
17
|
+
include ActiveModel::AttributeMethods
|
18
|
+
|
19
|
+
# Methods deprecated on the Object class which can be safely overridden
|
20
|
+
DEPRECATED_OBJECT_METHODS = %w(id type)
|
21
|
+
|
22
|
+
included do
|
23
|
+
attribute_method_suffix '' if attribute_method_matchers.none? { |matcher| matcher.prefix == '' && matcher.suffix == '' }
|
24
|
+
attribute_method_suffix '='
|
25
|
+
end
|
26
|
+
|
27
|
+
# Performs equality checking on the result of attributes and its type.
|
28
|
+
#
|
29
|
+
# @example Compare for equality.
|
30
|
+
# model == other
|
31
|
+
#
|
32
|
+
# @param [ActiveAttr::Attributes, Object] other The other model to compare
|
33
|
+
#
|
34
|
+
# @return [true, false] True if attributes are equal and other is instance
|
35
|
+
# of the same Class, false if not.
|
36
|
+
def ==(other)
|
37
|
+
return false unless other.instance_of? self.class
|
38
|
+
attributes == other.attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a Hash of all attributes
|
42
|
+
#
|
43
|
+
# @example Get attributes
|
44
|
+
# person.attributes # => {"name"=>"Ben Poweski"}
|
45
|
+
#
|
46
|
+
# @return [Hash{String => Object}] The Hash of all attributes
|
47
|
+
def attributes
|
48
|
+
attributes_map { |name| send name }
|
49
|
+
end
|
50
|
+
|
51
|
+
# Write a single attribute to the model's attribute hash.
|
52
|
+
#
|
53
|
+
# @example Write the attribute with write_attribute
|
54
|
+
# person.write_attribute(:name, "Benjamin")
|
55
|
+
# @example Write an attribute with bracket syntax
|
56
|
+
# person[:name] = "Benjamin"
|
57
|
+
#
|
58
|
+
# @param [String, Symbol, #to_s] name The name of the attribute to update.
|
59
|
+
# @param [Object] value The value to set for the attribute.
|
60
|
+
#
|
61
|
+
# @raise [UnknownAttributeError] if the attribute is unknown
|
62
|
+
def write_attribute(name, value)
|
63
|
+
if respond_to? "#{name}="
|
64
|
+
send "#{name}=", value
|
65
|
+
else
|
66
|
+
fail Neo4j::UnknownAttributeError, "unknown attribute: #{name}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
alias_method :[]=, :write_attribute
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
# Read an attribute from the attributes hash
|
74
|
+
def attribute(name)
|
75
|
+
@attributes ||= {}
|
76
|
+
@attributes[name]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Write an attribute to the attributes hash
|
80
|
+
def attribute=(name, value)
|
81
|
+
@attributes ||= {}
|
82
|
+
@attributes[name] = value
|
83
|
+
end
|
84
|
+
|
85
|
+
# Maps all attributes using the given block
|
86
|
+
#
|
87
|
+
# @example Stringify attributes
|
88
|
+
# person.attributes_map { |name| send(name).to_s }
|
89
|
+
#
|
90
|
+
# @yield [name] block called to return hash value
|
91
|
+
# @yieldparam [String] name The name of the attribute to map.
|
92
|
+
#
|
93
|
+
# @return [Hash{String => Object}] The Hash of mapped attributes
|
94
|
+
def attributes_map
|
95
|
+
Hash[self.class.attribute_names.map { |name| [name, yield(name)] }]
|
96
|
+
end
|
97
|
+
|
98
|
+
module ClassMethods
|
99
|
+
# Defines an attribute
|
100
|
+
#
|
101
|
+
# For each attribute that is defined, a getter and setter will be
|
102
|
+
# added as an instance method to the model. An
|
103
|
+
# {AttributeDefinition} instance will be added to result of the
|
104
|
+
# attributes class method.
|
105
|
+
#
|
106
|
+
# @example Define an attribute.
|
107
|
+
# attribute :name
|
108
|
+
#
|
109
|
+
# @param (see AttributeDefinition#initialize)
|
110
|
+
#
|
111
|
+
# @raise [DangerousAttributeError] if the attribute name conflicts with
|
112
|
+
# existing methods
|
113
|
+
#
|
114
|
+
# @return [AttributeDefinition] Attribute's definition
|
115
|
+
def attribute(name)
|
116
|
+
if dangerous_attribute?(name)
|
117
|
+
fail Neo4j::DangerousAttributeError, %(an attribute method named "#{name}" would conflict with an existing method)
|
118
|
+
else
|
119
|
+
attribute!(name)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns an Array of attribute names as Strings
|
124
|
+
#
|
125
|
+
# @example Get attribute names
|
126
|
+
# Person.attribute_names
|
127
|
+
#
|
128
|
+
# @return [Array<String>] The attribute names
|
129
|
+
def attribute_names
|
130
|
+
attributes.keys
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns a Hash of AttributeDefinition instances
|
134
|
+
#
|
135
|
+
# @example Get attribute definitions
|
136
|
+
# Person.attributes
|
137
|
+
#
|
138
|
+
# @return [ActiveSupport::HashWithIndifferentAccess{String => Neo4j::Shared::AttributeDefinition}]
|
139
|
+
# The Hash of AttributeDefinition instances
|
140
|
+
def attributes
|
141
|
+
@attributes ||= ActiveSupport::HashWithIndifferentAccess.new
|
142
|
+
end
|
143
|
+
|
144
|
+
# Determine if a given attribute name is dangerous
|
145
|
+
#
|
146
|
+
# Some attribute names can cause conflicts with existing methods
|
147
|
+
# on an object. For example, an attribute named "timeout" would
|
148
|
+
# conflict with the timeout method that Ruby's Timeout library
|
149
|
+
# mixes into Object.
|
150
|
+
#
|
151
|
+
# @example Testing a harmless attribute
|
152
|
+
# Person.dangerous_attribute? :name #=> false
|
153
|
+
#
|
154
|
+
# @example Testing a dangerous attribute
|
155
|
+
# Person.dangerous_attribute? :nil #=> "nil?"
|
156
|
+
#
|
157
|
+
# @param name Attribute name
|
158
|
+
#
|
159
|
+
# @return [false, String] False or the conflicting method name
|
160
|
+
def dangerous_attribute?(name)
|
161
|
+
attribute_methods(name).detect do |method_name|
|
162
|
+
!DEPRECATED_OBJECT_METHODS.include?(method_name.to_s) && allocate.respond_to?(method_name, true)
|
163
|
+
end unless attribute_names.include? name.to_s
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns the class name plus its attribute names
|
167
|
+
#
|
168
|
+
# @example Inspect the model's definition.
|
169
|
+
# Person.inspect
|
170
|
+
#
|
171
|
+
# @return [String] Human-readable presentation of the attributes
|
172
|
+
def inspect
|
173
|
+
inspected_attributes = attribute_names.sort
|
174
|
+
attributes_list = "(#{inspected_attributes.join(', ')})" unless inspected_attributes.empty?
|
175
|
+
"#{name}#{attributes_list}"
|
176
|
+
end
|
177
|
+
|
178
|
+
protected
|
179
|
+
|
180
|
+
# Assign a set of attribute definitions, used when subclassing models
|
181
|
+
#
|
182
|
+
# @param [Array<Neo4j::Shared::DeclaredProperties>] The Array of
|
183
|
+
# AttributeDefinition instances
|
184
|
+
def attributes=(attributes)
|
185
|
+
@attributes = attributes
|
186
|
+
end
|
187
|
+
|
188
|
+
# Overrides ActiveModel::AttributeMethods to backport 3.2 fix
|
189
|
+
def instance_method_already_implemented?(method_name)
|
190
|
+
generated_attribute_methods.method_defined?(method_name)
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
# Expand an attribute name into its generated methods names
|
196
|
+
def attribute_methods(name)
|
197
|
+
attribute_method_matchers.map { |matcher| matcher.method_name name }
|
198
|
+
end
|
199
|
+
|
200
|
+
# Ruby inherited hook to assign superclass attributes to subclasses
|
201
|
+
def inherited(subclass)
|
202
|
+
super
|
203
|
+
subclass.attributes = attributes.dup
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -101,8 +101,7 @@ module Neo4j::Shared
|
|
101
101
|
def unregister(name)
|
102
102
|
# might need to be include?(name.to_s)
|
103
103
|
fail ArgumentError, "Argument `#{name}` not an attribute" if not registered_properties[name]
|
104
|
-
|
105
|
-
registered_properties.delete(declared_prop)
|
104
|
+
registered_properties.delete(name)
|
106
105
|
unregister_magic_typecaster(name)
|
107
106
|
unregister_property_default(name)
|
108
107
|
end
|
@@ -133,11 +132,6 @@ module Neo4j::Shared
|
|
133
132
|
@magic_typecast_properties ||= {}
|
134
133
|
end
|
135
134
|
|
136
|
-
# The known mappings of declared properties and their primitive types.
|
137
|
-
def upstream_primitives
|
138
|
-
@upstream_primitives ||= {}
|
139
|
-
end
|
140
|
-
|
141
135
|
EXCLUDED_TYPES = [Array, Range, Regexp]
|
142
136
|
def value_for_where(key, value)
|
143
137
|
return value unless prop = registered_properties[key]
|
@@ -166,7 +160,7 @@ module Neo4j::Shared
|
|
166
160
|
|
167
161
|
# Prevents repeated calls to :_attribute_type, which isn't free and never changes.
|
168
162
|
def fetch_upstream_primitive(attr)
|
169
|
-
|
163
|
+
registered_properties[attr].type
|
170
164
|
end
|
171
165
|
|
172
166
|
private
|