aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-12-20 13:54:10 -0600
committerAaron Patterson <aaron.patterson@gmail.com>2011-12-20 14:04:51 -0600
commit8daaff5dac0725c5cf62811ac4a67b21f62aca2f (patch)
tree4b1089aae88cabc4d24e7adf7b001f8e830611d7 /activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
parent96838b5192e46caecc73cf45968fd27b78a41404 (diff)
downloadrails-8daaff5dac0725c5cf62811ac4a67b21f62aca2f.tar.gz
rails-8daaff5dac0725c5cf62811ac4a67b21f62aca2f.tar.bz2
rails-8daaff5dac0725c5cf62811ac4a67b21f62aca2f.zip
hstores can cycle
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb35
1 files changed, 31 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 6e169ae5c5..705fc8135d 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -52,12 +52,39 @@ module ActiveRecord
def cast_hstore(object)
if Hash === object
- object.map { |k,v| "#{k}=>#{v}" }.join ', '
+ object.map { |k,v|
+ "#{escape_hstore(k)}=>#{escape_hstore(v)}"
+ }.join ', '
else
- kvs = object.split(', ').map { |kv|
- kv.split('=>').map { |k| k[1...-1] }
+ kvs = object.scan(/(?<!\\)".*?(?<!\\)"/).map { |o|
+ unescape_hstore(o[1...-1])
}
- Hash[kvs]
+ Hash[kvs.each_slice(2).to_a]
+ end
+ end
+
+ private
+ def unescape_hstore(value)
+ escape_values = {
+ '\\ ' => ' ',
+ '\\\\' => '\\',
+ '\\"' => '"',
+ '\\=' => '=',
+ }
+ value.gsub(Regexp.union(escape_values.keys)) do |match|
+ escape_values[match]
+ end
+ end
+
+ def escape_hstore(value)
+ escape_values = {
+ ' ' => '\\ ',
+ '\\' => '\\\\',
+ '"' => '\\"',
+ '=' => '\\=',
+ }
+ value.gsub(Regexp.union(escape_values.keys)) do |match|
+ escape_values[match]
end
end
end