Class: Perpetuity::Postgres::Serializer
- Inherits:
-
Object
- Object
- Perpetuity::Postgres::Serializer
- Includes:
- DataInjectable
- Defined in:
- lib/perpetuity/postgres/serializer.rb
Constant Summary collapse
- SERIALIZABLE_CLASSES =
Set[Fixnum, Float, String, Time, Date, TrueClass, FalseClass, NilClass]
Instance Attribute Summary collapse
-
#mapper ⇒ Object
readonly
Returns the value of attribute mapper.
-
#mapper_registry ⇒ Object
readonly
Returns the value of attribute mapper_registry.
Instance Method Summary collapse
- #attribute_for(object, attr_name) ⇒ Object
- #foreign_object?(value) ⇒ Boolean
-
#initialize(mapper) ⇒ Serializer
constructor
A new instance of Serializer.
- #possible_json_value?(value) ⇒ Boolean
- #serialize(object) ⇒ Object
- #serialize_array(object) ⇒ Object
- #serialize_attribute(object) ⇒ Object
- #serialize_changes(modified, original) ⇒ Object
- #serialize_hash(object) ⇒ Object
- #serialize_reference(value) ⇒ Object
- #serialize_to_hash(value) ⇒ Object
- #serialize_with_foreign_mapper(value) ⇒ Object
- #serializer_for(klass) ⇒ Object
- #unserialize(data) ⇒ Object
- #unserialize_attribute(attribute, value) ⇒ Object
- #unserialize_foreign_object(data) ⇒ Object
- #unserialize_reference(klass, id) ⇒ Object
Constructor Details
#initialize(mapper) ⇒ Serializer
Returns a new instance of Serializer.
18 19 20 21 |
# File 'lib/perpetuity/postgres/serializer.rb', line 18 def initialize mapper @mapper = mapper @mapper_registry = mapper.mapper_registry if mapper end |
Instance Attribute Details
#mapper ⇒ Object (readonly)
Returns the value of attribute mapper.
16 17 18 |
# File 'lib/perpetuity/postgres/serializer.rb', line 16 def mapper @mapper end |
#mapper_registry ⇒ Object (readonly)
Returns the value of attribute mapper_registry.
16 17 18 |
# File 'lib/perpetuity/postgres/serializer.rb', line 16 def mapper_registry @mapper_registry end |
Instance Method Details
#attribute_for(object, attr_name) ⇒ Object
104 105 106 |
# File 'lib/perpetuity/postgres/serializer.rb', line 104 def attribute_for object, attr_name object.instance_variable_get("@#{attr_name}") end |
#foreign_object?(value) ⇒ Boolean
80 81 82 |
# File 'lib/perpetuity/postgres/serializer.rb', line 80 def foreign_object? value value.is_a?(Hash) && value.has_key?('__metadata__') end |
#possible_json_value?(value) ⇒ Boolean
76 77 78 |
# File 'lib/perpetuity/postgres/serializer.rb', line 76 def possible_json_value? value value.is_a?(String) && %w([ {).include?(value[0]) end |
#serialize(object) ⇒ Object
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/perpetuity/postgres/serializer.rb', line 23 def serialize object attrs = mapper.attribute_set.map do |attribute| attr_name = attribute.name.to_s value = ValueWithAttribute.new(attribute_for(object, attr_name), attribute) serialize_attribute(value) end column_names = mapper.attributes SerializedData.new(column_names, attrs) end |
#serialize_array(object) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/perpetuity/postgres/serializer.rb', line 124 def serialize_array object value = object.value rescue object array = value.map do |item| if SERIALIZABLE_CLASSES.include? item.class item elsif object. serialize_with_foreign_mapper item else serialize_reference item end end JSONArray.new(array) end |
#serialize_attribute(object) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/perpetuity/postgres/serializer.rb', line 108 def serialize_attribute object value = object.value rescue object if SERIALIZABLE_CLASSES.include? value.class SQLValue.new(value) elsif value.is_a? Array serialize_array(object) elsif value.is_a? Hash serialize_hash(object) elsif !object. serialize_reference(value) elsif object. serialize_with_foreign_mapper(value) end.to_s end |
#serialize_changes(modified, original) ⇒ Object
183 184 185 |
# File 'lib/perpetuity/postgres/serializer.rb', line 183 def serialize_changes modified, original serialize(modified) - serialize(original) end |
#serialize_hash(object) ⇒ Object
139 140 141 |
# File 'lib/perpetuity/postgres/serializer.rb', line 139 def serialize_hash object JSONHash.new(object) end |
#serialize_reference(value) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/perpetuity/postgres/serializer.rb', line 153 def serialize_reference value klass = if value.is_a? Reference value.klass else value.class end unless mapper.persisted? value mapper_registry[value.class].insert value end json = { __metadata__: { class: klass, id: mapper.id_for(value) } } JSONHash.new(json) end |
#serialize_to_hash(value) ⇒ Object
143 144 145 146 147 148 149 150 151 |
# File 'lib/perpetuity/postgres/serializer.rb', line 143 def serialize_to_hash value Hash[ mapper.attribute_set.map do |attribute| attr_name = attribute.name attr_value = attribute_for(value, attr_name) [attr_name, attr_value] end ] end |
#serialize_with_foreign_mapper(value) ⇒ Object
174 175 176 177 178 179 180 181 |
# File 'lib/perpetuity/postgres/serializer.rb', line 174 def serialize_with_foreign_mapper value mapper = mapper_registry[value.class] serializer = Serializer.new(mapper) attr = serializer.serialize_to_hash(value) attr.merge!('__metadata__' => { 'class' => value.class }) JSONHash.new(attr) end |
#serializer_for(klass) ⇒ Object
100 101 102 |
# File 'lib/perpetuity/postgres/serializer.rb', line 100 def serializer_for klass Serializer.new(mapper_registry[klass]) end |
#unserialize(data) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/perpetuity/postgres/serializer.rb', line 34 def unserialize data if data.is_a? Array data.map do |datum| object = mapper.mapped_class.allocate datum.each do |attribute_name, value| attribute = mapper.attribute_set[attribute_name.to_sym] deserialized_value = unserialize_attribute(attribute, value) inject_attribute object, attribute_name, deserialized_value end object end else unserialize([data]).first end end |
#unserialize_attribute(attribute, value) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/perpetuity/postgres/serializer.rb', line 51 def unserialize_attribute attribute, value if value if possible_json_value?(value) value = JSON.parse(value) rescue value if value.is_a? Array value = value.map { |v| unserialize_attribute(attribute, v) } end end if foreign_object? value value = unserialize_foreign_object value end if attribute if [Fixnum, Bignum, Integer].include? attribute.type value = value.to_i elsif attribute.type == Time value = TimestampValue.from_sql(value).to_time elsif [TrueClass, FalseClass].include? attribute.type value = value.downcase.start_with? 't' end end value end end |
#unserialize_foreign_object(data) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/perpetuity/postgres/serializer.rb', line 84 def unserialize_foreign_object data = data.delete('__metadata__') klass = Object.const_get(['class']) if .has_key? 'id' id = ['id'] return unserialize_reference(klass, id) end serializer = serializer_for(klass) serializer.unserialize(data) end |
#unserialize_reference(klass, id) ⇒ Object
96 97 98 |
# File 'lib/perpetuity/postgres/serializer.rb', line 96 def unserialize_reference klass, id Reference.new(klass, id) end |