aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-07-03 07:07:27 -0600
committerSean Griffin <sean@thoughtbot.com>2014-07-03 07:07:27 -0600
commite2763b487ea905c14c0fb8298b6d67d123a046ad (patch)
tree5df6376cf8f3f6ad6fe6b90eb6276fca4e4c292a /activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
parent03c9c0e2fa83e4ccaefb3b06970b9c3efe170be5 (diff)
downloadrails-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.rb36
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