diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-07-03 07:07:27 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-07-03 07:07:27 -0600 |
commit | e2763b487ea905c14c0fb8298b6d67d123a046ad (patch) | |
tree | 5df6376cf8f3f6ad6fe6b90eb6276fca4e4c292a /activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb | |
parent | 03c9c0e2fa83e4ccaefb3b06970b9c3efe170be5 (diff) | |
download | rails-e2763b487ea905c14c0fb8298b6d67d123a046ad.tar.gz rails-e2763b487ea905c14c0fb8298b6d67d123a046ad.tar.bz2 rails-e2763b487ea905c14c0fb8298b6d67d123a046ad.zip |
Use the type object for type casting HStore columns
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb index 57b20477df..be4525c94f 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb @@ -10,16 +10,48 @@ module ActiveRecord end def type_cast_from_database(value) - ConnectionAdapters::PostgreSQLColumn.string_to_hstore(value) + if value.is_a?(::String) + ::Hash[value.scan(HstorePair).map { |k, v| + v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') + k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') + [k, v] + }] + else + value + end end def type_cast_for_database(value) - ConnectionAdapters::PostgreSQLColumn.hstore_to_string(value) + if value.is_a?(::Hash) + value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(', ') + else + value + end end def accessor ActiveRecord::Store::StringKeyedHashAccessor end + + private + + HstorePair = begin + quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/ + unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/ + /(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/ + end + + def escape_hstore(value) + if value.nil? + 'NULL' + else + if value == "" + '""' + else + '"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1') + end + end + end end end end |