neo4j 6.1.12 → 7.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|