Module: Familia::DataType::Serialization
- Included in:
- Familia::DataType
- Defined in:
- lib/familia/data_type/serialization.rb
Instance Method Summary collapse
-
#deserialize_value(val) ⇒ Object?
Deserializes a single value from the database.
-
#deserialize_values(*values) ⇒ Array<Object>
Deserializes multiple values from Valkey/Redis, removing nil values.
-
#deserialize_values_with_nil(*values) ⇒ Array<Object, nil>
Deserializes multiple values from Valkey/Redis, preserving nil values.
-
#serialize_value(val) ⇒ String
Serializes a value for storage in the database.
Instance Method Details
#deserialize_value(val) ⇒ Object?
Deserializes a single value from the database.
Deserialization priority:
- Redis::Future objects → return as-is (transaction handling)
- nil values → return default option value
- Class option specified → use class-based deserialization
- No class option → JSON parse for type preservation
This unifies behavior with Horreum fields (Issue #190), ensuring consistent type preservation. Legacy data stored without JSON encoding is returned as-is.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/familia/data_type/serialization.rb', line 135 def deserialize_value(val) # Handle Redis::Future objects during transactions first return val if val.is_a?(Redis::Future) return @opts[:default] if val.nil? # If a class option is specified, use the existing class-based deserialization if @opts[:class] ret = deserialize_values val return ret&.first # return the object or nil end # No class option: JSON deserialize for type preservation (Issue #190) # This unifies behavior with Horreum fields begin Familia::JsonSerializer.parse(val) rescue Familia::SerializerError # Fallback for legacy data stored without JSON encoding val end end |
#deserialize_values(*values) ⇒ Array<Object>
Deserializes multiple values from Valkey/Redis, removing nil values.
60 61 62 63 64 65 66 |
# File 'lib/familia/data_type/serialization.rb', line 60 def deserialize_values(*values) # Avoid using compact! here. Using compact! as the last expression in the # method can unintentionally return nil if no changes are made, which is # not desirable. Instead, use compact to ensure the method returns the # expected value. deserialize_values_with_nil(*values).compact end |
#deserialize_values_with_nil(*values) ⇒ Array<Object, nil>
This method attempts to deserialize each value using the specified class's from_json method. If deserialization fails for a value, it's replaced with nil.
Deserializes multiple values from Valkey/Redis, preserving nil values.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/familia/data_type/serialization.rb', line 79 def deserialize_values_with_nil(*values) Familia.debug "deserialize_values: (#{@opts}) #{values}" return [] if values.empty? # If a class option is specified, use class-based deserialization if @opts[:class] unless @opts[:class].respond_to?(:from_json) raise Familia::Problem, "No such method: #{@opts[:class]}.from_json" end values.collect! do |obj| next if obj.nil? val = @opts[:class].from_json(obj) Familia.debug "[#{self.class}#deserialize_values] nil returned for #{@opts[:class]}.from_json" if val.nil? val rescue StandardError => e Familia.info obj Familia.info "Parse error for #{dbkey} (from_json): #{e.}" Familia.info e.backtrace nil end return values end # No class option: JSON deserialize each value for type preservation (Issue #190) values.flatten.collect do |obj| next if obj.nil? begin Familia::JsonSerializer.parse(obj) rescue Familia::SerializerError # Fallback for legacy data stored without JSON encoding obj end end end |
#serialize_value(val) ⇒ String
Serializes a value for storage in the database.
Serialization priority:
- Familia objects (Base instances or classes) → extract identifier
- All other values → JSON serialize for type preservation
This unifies behavior with Horreum fields (Issue #190), ensuring consistent type preservation across DataType and Horreum.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/familia/data_type/serialization.rb', line 30 def serialize_value(val) Familia.trace :TOREDIS, nil, "#{val}<#{val.class}|#{opts[:class]}>" if Familia.debug? # Priority 1: Handle Familia object references - extract identifier # This preserves the existing behavior for storing object references if val.is_a?(Familia::Base) || (val.is_a?(Class) && val.ancestors.include?(Familia::Base)) prepared = val.is_a?(Class) ? val.name : val.identifier Familia.debug " Familia object: #{val.class} => #{prepared}" return prepared end # Priority 2: Everything else gets JSON serialized for type preservation # This unifies behavior with Horreum fields (Issue #190) prepared = Familia::JsonSerializer.dump(val) Familia.debug " JSON serialized: #{val.class} => #{prepared}" if Familia.debug? Familia.trace :TOREDIS, nil, "#{val}<#{val.class}> => #{prepared}<#{prepared.class}>" end prepared end |