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.
   
 
  
    
      
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 
  
  
  
  
    
      
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.
   
 
  
  
    
      
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.
   
 
  
  
    
      
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 
  
  
  
  
    
      
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.
   
 
  
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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.
   
 
  
    
      
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 
  
  
  
  
    
      
57
58
59 
     | 
    
      # File 'lib/active_graph/shared/declared_properties.rb', line 57
def registered_properties
  @_registered_properties ||= {}
end
     | 
  
 
    
      
  
  
    #serialize(name, coder = JSON)  ⇒ Object 
  
  
  
  
    
      
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 
  
  
  
  
    
      
119
120
121 
     | 
    
      # File 'lib/active_graph/shared/declared_properties.rb', line 119
def serialized_properties
  @serialize ||= {}
end
     | 
  
 
    
      
  
  
    #serialized_properties=(serialize_hash)  ⇒ Object 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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.
   
 
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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 
  
  
  
  
    
      
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
     |