Class: Surus::Hstore::Serializer
- Inherits:
-
Object
- Object
- Surus::Hstore::Serializer
- Defined in:
- lib/surus/hstore/serializer.rb
Instance Method Summary collapse
- #dump(hash) ⇒ Object
-
#escape(value) ⇒ Object
Escape a value for use as a key or value in an hstore.
- #format_key(key) ⇒ Object
- #format_value(value) ⇒ Object
- #load(stringified_hash) ⇒ Object
-
#stringify(value) ⇒ Object
Returns an array of value as a string and value type.
- #typecast(value, type) ⇒ Object
-
#unescape(value) ⇒ Object
Unescape a value from a key or value in an hstore.
Instance Method Details
#dump(hash) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/surus/hstore/serializer.rb', line 33 def dump(hash) return unless hash key_types = {} value_types = {} stringified_hash = hash.each_with_object({}) do |key_value, stringified_hash| key_string, key_type = stringify(key_value[0]) value_string, value_type = stringify(key_value[1]) stringified_hash[key_string] = value_string key_types[key_string] = key_type unless key_type == "String" value_types[key_string] = value_type unless value_type == "String" end # Use YAML for recording types as it is much simpler than trying to # handle all the special characters that could be in a key or value # and encoding them again to fit into one string. Let YAML handle all # the mess for us. stringified_hash["__key_types"] = YAML.dump(key_types) if key_types.present? stringified_hash["__value_types"] = YAML.dump(value_types) if value_types.present? stringified_hash.map do |key, value| "#{format_key(key)}=>#{format_value(value)}" end.join(", ") end |
#escape(value) ⇒ Object
Escape a value for use as a key or value in an hstore
70 71 72 73 74 |
# File 'lib/surus/hstore/serializer.rb', line 70 def escape(value) value .gsub('\\', '\\\\\\') .gsub('"', '\\"') end |
#format_key(key) ⇒ Object
61 62 63 |
# File 'lib/surus/hstore/serializer.rb', line 61 def format_key(key) %Q("#{escape(key)}") end |
#format_value(value) ⇒ Object
65 66 67 |
# File 'lib/surus/hstore/serializer.rb', line 65 def format_value(value) value ? %Q("#{escape(value)}") : "NULL" end |
#load(stringified_hash) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/surus/hstore/serializer.rb', line 4 def load(stringified_hash) return unless stringified_hash key_types = stringified_hash.delete "__key_types" key_types = YAML.load key_types if key_types value_types = stringified_hash.delete "__value_types" value_types = YAML.load value_types if value_types return stringified_hash unless key_types || value_types stringified_hash.each_with_object({}) do |key_value, hash| string_key, string_value = key_value key = if key_types && key_types.key?(string_key) typecast(string_key, key_types[string_key]) else string_key end value = if value_types && value_types.key?(string_key) typecast(string_value, value_types[string_key]) else string_value end hash[key] = value end end |
#stringify(value) ⇒ Object
Returns an array of value as a string and value type
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/surus/hstore/serializer.rb', line 84 def stringify(value) if value.kind_of?(String) [value, "String"] elsif value.kind_of?(Symbol) [value.to_s, "Symbol"] elsif value.kind_of?(Integer) [value.to_s, "Integer"] elsif value.kind_of?(Float) [value.to_s, "Float"] elsif value.kind_of?(BigDecimal) [value.to_s, "BigDecimal"] elsif value.kind_of?(Date) [value.to_s(:db), "Date"] elsif value.kind_of?(TrueClass) [value.to_s, "TrueClass"] elsif value.kind_of?(FalseClass) [value.to_s, "FalseClass"] elsif value == nil [nil, "String"] # we don't actually stringify nil because format_value special cases nil else [YAML.dump(value), "YAML"] end end |
#typecast(value, type) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/surus/hstore/serializer.rb', line 108 def typecast(value, type) case type when "Symbol" value.to_sym when "Integer" Integer(value) when "Float" Float(value) when "BigDecimal" BigDecimal(value) when "Date" Date.parse(value) when "TrueClass" true when "FalseClass" false when "YAML" YAML.load(value) else raise ArgumentError, "Can't typecast: #{type}" end end |
#unescape(value) ⇒ Object
Unescape a value from a key or value in an hstore
77 78 79 80 81 |
# File 'lib/surus/hstore/serializer.rb', line 77 def unescape(value) value .gsub('\\\\', '\\') .gsub('\\"', '"') end |