Class: ActiveGraph::Shared::DeclaredProperties
- Inherits:
-
Object
- Object
- ActiveGraph::Shared::DeclaredProperties
show all
- Includes:
- TypeConverters
- Defined in:
- lib/active_graph/shared/declared_properties.rb
Overview
The DeclaredPropertyuManager holds details about objects created as a result of calling the #property class method on a class that includes ActiveGraph::Node or ActiveGraph::Relationship. There are many options that are referenced frequently, particularly during load and save, so this provides easy access and a way of separating behavior from the general Activeobj modules.
See ActiveGraph::Shared::DeclaredProperty for definitions of the property objects themselves.
Constant Summary
collapse
- EXCLUDED_TYPES =
[Array, Range, Regexp]
TypeConverters::CONVERTERS
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#[](key) ⇒ Object
-
#attributes_nil_hash ⇒ Object
During object wrap, a hash is needed that contains each declared property with a nil value.
-
#attributes_string_map ⇒ Object
During object wrapping, a props hash is built with string keys but ActiveGraph::Core provides symbols.
-
#constraint_or_fail!(key, id_property_name, type = :unique) ⇒ Object
-
#declared_property_defaults ⇒ Object
The :default option in ActiveGraph::Node#property class method allows for setting a default value instead of nil on declared properties.
-
#index_or_fail!(key, id_property_name, type = :exact) ⇒ Object
-
#indexed_properties ⇒ Object
-
#initialize(klass) ⇒ DeclaredProperties
constructor
Each class that includes ActiveGraph::Node or ActiveGraph::Relationship gets one instance of this class.
-
#inject_defaults!(object, props) ⇒ Object
-
#magic_typecast_properties ⇒ Object
-
#magic_typecast_properties_keys ⇒ Object
-
#property?(key) ⇒ Boolean
-
#register(property) ⇒ Object
#property on an Node or Relationship class.
-
#registered_properties ⇒ Object
-
#serialize(name, coder = JSON) ⇒ Object
-
#serialized_properties ⇒ Object
-
#serialized_properties=(serialize_hash) ⇒ Object
-
#serialized_properties_keys ⇒ Object
-
#string_key(k) ⇒ Object
but when this happens many times while loading many objects, it results in a surprisingly significant slowdown.
-
#unregister(name) ⇒ Object
-
#value_for_db(key, value) ⇒ Object
-
#value_for_ruby(key, value) ⇒ Object
-
#value_for_where(key, value) ⇒ Object
#convert_properties_to, #convert_property, converter_for, formatted_for_db?, included, register_converter, #supports_array?, to_other, #typecast_attribute, typecast_attribute, #typecaster_for, typecaster_for
Constructor Details
Each class that includes ActiveGraph::Node or ActiveGraph::Relationship gets one instance of this class.
[View source]
16
17
18
|
# File 'lib/active_graph/shared/declared_properties.rb', line 16
def initialize(klass)
@klass = klass
end
|
Instance Attribute Details
#klass ⇒ Object
Returns the value of attribute klass.
11
12
13
|
# File 'lib/active_graph/shared/declared_properties.rb', line 11
def klass
@klass
end
|
Instance Method Details
#[](key) ⇒ Object
[View source]
20
21
22
|
# File 'lib/active_graph/shared/declared_properties.rb', line 20
def [](key)
registered_properties[key.to_sym]
end
|
#attributes_nil_hash ⇒ Object
During object wrap, a hash is needed that contains each declared property with a nil value. The active_attr dependency is capable of providing this but it is expensive and calculated on the fly each time it is called. Rather than rely on that, we build this progressively as properties are registered. When the node or rel is loaded, this is used as a template.
[View source]
69
70
71
72
73
74
75
76
|
# File 'lib/active_graph/shared/declared_properties.rb', line 69
def attributes_nil_hash
@_attributes_nil_hash ||= {}.tap do |attr_hash|
registered_properties.each_pair do |k, prop_obj|
val = prop_obj.default_value
attr_hash[k.to_s] = val
end
end.freeze
end
|
#attributes_string_map ⇒ Object
During object wrapping, a props hash is built with string keys but ActiveGraph::Core provides symbols. Rather than a ‘to_s` or `symbolize_keys` during every load, we build a map of symbol-to-string to speed up the process. This increases memory used by the gem but reduces object allocation and GC, so it is faster in practice.
[View source]
82
83
84
85
86
|
# File 'lib/active_graph/shared/declared_properties.rb', line 82
def attributes_string_map
@_attributes_string_map ||= {}.tap do |attr_hash|
attributes_nil_hash.each_key { |k| attr_hash[k.to_sym] = k }
end.freeze
end
|
#constraint_or_fail!(key, id_property_name, type = :unique) ⇒ Object
[View source]
45
46
47
48
49
|
# File 'lib/active_graph/shared/declared_properties.rb', line 45
def constraint_or_fail!(key, id_property_name, type = :unique)
return if key == id_property_name
fail "Cannot constraint undeclared property #{property}" unless property?(key)
registered_properties[key].constraint!(type)
end
|
#declared_property_defaults ⇒ Object
The :default option in ActiveGraph::Node#property class method allows for setting a default value instead of nil on declared properties. This holds those values.
[View source]
53
54
55
|
# File 'lib/active_graph/shared/declared_properties.rb', line 53
def declared_property_defaults
@_default_property_values ||= {}
end
|
#index_or_fail!(key, id_property_name, type = :exact) ⇒ Object
[View source]
39
40
41
42
43
|
# File 'lib/active_graph/shared/declared_properties.rb', line 39
def index_or_fail!(key, id_property_name, type = :exact)
return if key == id_property_name
fail "Cannot index undeclared property #{key}" unless property?(key)
registered_properties[key].index!(type)
end
|
#indexed_properties ⇒ Object
[View source]
61
62
63
|
# File 'lib/active_graph/shared/declared_properties.rb', line 61
def indexed_properties
registered_properties.select { |_, p| p.index_or_constraint? }
end
|
#inject_defaults!(object, props) ⇒ Object
[View source]
157
158
159
160
161
162
|
# File 'lib/active_graph/shared/declared_properties.rb', line 157
def inject_defaults!(object, props)
declared_property_defaults.each_pair do |k, v|
props[k.to_sym] = v.respond_to?(:call) ? v.call : v if object.send(k).nil? && props[k.to_sym].nil?
end
props
end
|
#magic_typecast_properties ⇒ Object
[View source]
131
132
133
|
# File 'lib/active_graph/shared/declared_properties.rb', line 131
def magic_typecast_properties
@magic_typecast_properties ||= {}
end
|
#magic_typecast_properties_keys ⇒ Object
[View source]
127
128
129
|
# File 'lib/active_graph/shared/declared_properties.rb', line 127
def magic_typecast_properties_keys
@magic_typecast_properties_keys ||= magic_typecast_properties.keys
end
|
#property?(key) ⇒ Boolean
[View source]
24
25
26
|
# File 'lib/active_graph/shared/declared_properties.rb', line 24
def property?(key)
registered_properties.key?(key.to_sym)
end
|
#register(property) ⇒ Object
#property on an Node or Relationship class. The DeclaredProperty has specifics about the property, but registration makes the management object aware of it. This is necessary for type conversion, defaults, and inclusion in the nil and string hashes.
[View source]
31
32
33
34
35
36
37
|
# File 'lib/active_graph/shared/declared_properties.rb', line 31
def register(property)
@_attributes_nil_hash = nil
@_attributes_string_map = nil
registered_properties[property.name] = property
register_magic_typecaster(property) if property.magic_typecaster
declared_property_defaults[property.name] = property.default_value if !property.default_value.nil?
end
|
#registered_properties ⇒ Object
[View source]
57
58
59
|
# File 'lib/active_graph/shared/declared_properties.rb', line 57
def registered_properties
@_registered_properties ||= {}
end
|
#serialize(name, coder = JSON) ⇒ Object
[View source]
109
110
111
112
|
# File 'lib/active_graph/shared/declared_properties.rb', line 109
def serialize(name, coder = JSON)
@serialize ||= {}
@serialize[name] = coder
end
|
#serialized_properties ⇒ Object
[View source]
119
120
121
|
# File 'lib/active_graph/shared/declared_properties.rb', line 119
def serialized_properties
@serialize ||= {}
end
|
#serialized_properties=(serialize_hash) ⇒ Object
[View source]
114
115
116
117
|
# File 'lib/active_graph/shared/declared_properties.rb', line 114
def serialized_properties=(serialize_hash)
@serialized_property_keys = nil
@serialize = serialize_hash.clone
end
|
#serialized_properties_keys ⇒ Object
[View source]
123
124
125
|
# File 'lib/active_graph/shared/declared_properties.rb', line 123
def serialized_properties_keys
@serialized_property_keys ||= serialized_properties.keys
end
|
#string_key(k) ⇒ Object
but when this happens many times while loading many objects, it results in a surprisingly significant slowdown. The branching logic handles what happens if a property can’t be found. The first option attempts to find it in the existing hash. The second option checks whether the key is the class’s id property and, if it is, the string hash is rebuilt with it to prevent future lookups. The third calls ‘to_s`. This would happen if undeclared properties are found on the object. We could add them to the string map but that would result in unchecked, un-GCed memory consumption. In the event that someone is adding properties dynamically, maybe through user input, this would be bad.
[View source]
97
98
99
|
# File 'lib/active_graph/shared/declared_properties.rb', line 97
def string_key(k)
attributes_string_map[k] || string_map_id_property(k) || k.to_s
end
|
#unregister(name) ⇒ Object
[View source]
101
102
103
104
105
106
107
|
# File 'lib/active_graph/shared/declared_properties.rb', line 101
def unregister(name)
fail ArgumentError, "Argument `#{name}` not an attribute" if not registered_properties[name]
registered_properties.delete(name)
unregister_magic_typecaster(name)
unregister_property_default(name)
end
|
#value_for_db(key, value) ⇒ Object
[View source]
147
148
149
150
|
# File 'lib/active_graph/shared/declared_properties.rb', line 147
def value_for_db(key, value)
return value unless registered_properties[key]
convert_property(key, value, :to_db)
end
|
#value_for_ruby(key, value) ⇒ Object
[View source]
152
153
154
155
|
# File 'lib/active_graph/shared/declared_properties.rb', line 152
def value_for_ruby(key, value)
return unless registered_properties[key]
convert_property(key, value, :to_ruby)
end
|
#value_for_where(key, value) ⇒ Object
[View source]
136
137
138
139
140
141
142
143
144
145
|
# File 'lib/active_graph/shared/declared_properties.rb', line 136
def value_for_where(key, value)
return value unless prop = registered_properties[key]
return value_for_db(key, value) if prop.typecaster && prop.typecaster.convert_type == value.class
if should_convert_for_where?(key, value)
value_for_db(key, value)
else
value
end
end
|