diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2011-12-20 13:54:10 -0600 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2011-12-20 14:04:51 -0600 |
commit | 8daaff5dac0725c5cf62811ac4a67b21f62aca2f (patch) | |
tree | 4b1089aae88cabc4d24e7adf7b001f8e830611d7 /activerecord/lib | |
parent | 96838b5192e46caecc73cf45968fd27b78a41404 (diff) | |
download | rails-8daaff5dac0725c5cf62811ac4a67b21f62aca2f.tar.gz rails-8daaff5dac0725c5cf62811ac4a67b21f62aca2f.tar.bz2 rails-8daaff5dac0725c5cf62811ac4a67b21f62aca2f.zip |
hstores can cycle
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 35 |
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 |