Class: ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Hstore

Inherits:
Type::Value
  • Object
show all
Includes:
ActiveModel::Type::Helpers::Mutable
Defined in:
activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb

Overview

:nodoc:

Constant Summary collapse

ERROR =
"Invalid Hstore document: %s"

Instance Method Summary collapse

Methods included from ActiveModel::Type::Helpers::Mutable

#cast

Instance Method Details

#accessorObject


81
82
83
# File 'activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb', line 81

def accessor
  ActiveRecord::Store::StringKeyedHashAccessor
end

#changed_in_place?(raw_old_value, new_value) ⇒ Boolean

Will compare the Hash equivalents of raw_old_value and new_value. By comparing hashes, this avoids an edge case where the order of the keys change between the two hashes, and they would not be marked as equal.

Returns:

  • (Boolean)

89
90
91
# File 'activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb', line 89

def changed_in_place?(raw_old_value, new_value)
  deserialize(raw_old_value) != new_value
end

#deserialize(value) ⇒ Object


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
60
61
62
63
64
65
66
67
68
69
# File 'activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb', line 18

def deserialize(value)
  return value unless value.is_a?(::String)

  scanner = StringScanner.new(value)
  hash = {}

  until scanner.eos?
    unless scanner.skip(/"/)
      raise(ArgumentError, ERROR % scanner.string.inspect)
    end

    unless key = scanner.scan_until(/(?<!\\)(?=")/)
      raise(ArgumentError, ERROR % scanner.string.inspect)
    end

    unless scanner.skip(/"=>?/)
      raise(ArgumentError, ERROR % scanner.string.inspect)
    end

    if scanner.scan(/NULL/)
      value = nil
    else
      unless scanner.skip(/"/)
        raise(ArgumentError, ERROR % scanner.string.inspect)
      end

      unless value = scanner.scan_until(/(?<!\\)(?=")/)
        raise(ArgumentError, ERROR % scanner.string.inspect)
      end

      unless scanner.skip(/"/)
        raise(ArgumentError, ERROR % scanner.string.inspect)
      end
    end

    key.gsub!('\"', '"')
    key.gsub!("\\\\", "\\")

    if value
      value.gsub!('\"', '"')
      value.gsub!("\\\\", "\\")
    end

    hash[key] = value

    unless scanner.skip(/, /) || scanner.eos?
      raise(ArgumentError, ERROR % scanner.string.inspect)
    end
  end

  hash
end

#serialize(value) ⇒ Object


71
72
73
74
75
76
77
78
79
# File 'activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb', line 71

def serialize(value)
  if value.is_a?(::Hash)
    value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(", ")
  elsif value.respond_to?(:to_unsafe_h)
    serialize(value.to_unsafe_h)
  else
    value
  end
end

#typeObject


14
15
16
# File 'activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb', line 14

def type
  :hstore
end