aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel <joel@renewfund.com>2012-02-05 20:36:22 -0800
committerJoel <joel@renewfund.com>2012-02-08 22:28:51 -0800
commitb04880cecc6fdc452aeea5d64d078d90dfa2693a (patch)
tree68eabc3c1ecb354b0058879446d6b265d824747a
parent2967aecdafb821bafc67745c75f4e95bcc273a49 (diff)
downloadrails-b04880cecc6fdc452aeea5d64d078d90dfa2693a.tar.gz
rails-b04880cecc6fdc452aeea5d64d078d90dfa2693a.tar.bz2
rails-b04880cecc6fdc452aeea5d64d078d90dfa2693a.zip
string_to_hstore / hstore_to_string, serializing
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb27
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb12
3 files changed, 26 insertions, 17 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index 34d88edff3..7ef3218a49 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -98,7 +98,7 @@ module ActiveRecord
when :date then klass.value_to_date(value)
when :binary then klass.binary_to_string(value)
when :boolean then klass.value_to_boolean(value)
- when :hstore then klass.cast_hstore(value)
+ when :hstore then klass.string_to_hstore(value)
else value
end
end
@@ -116,7 +116,7 @@ module ActiveRecord
when :date then "#{klass}.value_to_date(#{var_name})"
when :binary then "#{klass}.binary_to_string(#{var_name})"
when :boolean then "#{klass}.value_to_boolean(#{var_name})"
- when :hstore then "#{klass}.cast_hstore(#{var_name})"
+ when :hstore then "#{klass}.string_to_hstore(#{var_name})"
else var_name
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 52693e19d9..abb0a4adea 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -52,25 +52,31 @@ module ActiveRecord
end
end
- def cast_hstore(object)
+ def hstore_to_string(object)
if Hash === object
object.map { |k,v|
"#{escape_hstore(k)}=>#{escape_hstore(v)}"
}.join ','
else
- hash_from_hstore_string(object)
+ object
end
end
- private
- def hash_from_hstore_string(string)
- Hash[string.scan(HstorePair).map { |k,v|
- v = v.upcase == 'NULL' ? nil : v.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
- k = k.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
- [k,v]
- }]
+ def string_to_hstore(string)
+ if string.nil?
+ nil
+ elsif String === string
+ Hash[string.scan(HstorePair).map { |k,v|
+ v = v.upcase == 'NULL' ? nil : v.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
+ k = k.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
+ [k,v]
+ }]
+ else
+ string
+ end
end
+ private
HstorePair = begin
quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
@@ -501,6 +507,9 @@ module ActiveRecord
when String
return super unless 'bytea' == column.sql_type
{ :value => value, :format => 1 }
+ when Hash
+ return super unless 'hstore' == column.sql_type
+ PostgreSQLColumn.hstore_to_string(value)
else
super
end
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index 28b5a50126..82c52b38a3 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -12,7 +12,7 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
begin
@connection.transaction do
@connection.create_table('hstores') do |t|
- t.hstore 'tags'
+ t.hstore 'tags', :default => ''
end
end
rescue ActiveRecord::StatementInvalid
@@ -33,7 +33,7 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
assert @column
data = "\"1\"=>\"2\""
- hash = @column.class.cast_hstore data
+ hash = @column.class.string_to_hstore data
assert_equal({'1' => '2'}, hash)
assert_equal({'1' => '2'}, @column.type_cast(data))
@@ -43,19 +43,19 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
end
def test_gen1
- assert_equal(%q(" "=>""), @column.type_cast({' '=>''}))
+ assert_equal(%q(" "=>""), @column.class.hstore_to_string({' '=>''}))
end
def test_gen2
- assert_equal(%q(","=>""), @column.type_cast({','=>''}))
+ assert_equal(%q(","=>""), @column.class.hstore_to_string({','=>''}))
end
def test_gen3
- assert_equal(%q("="=>""), @column.type_cast({'='=>''}))
+ assert_equal(%q("="=>""), @column.class.hstore_to_string({'='=>''}))
end
def test_gen4
- assert_equal(%q(">"=>""), @column.type_cast({'>'=>''}))
+ assert_equal(%q(">"=>""), @column.class.hstore_to_string({'>'=>''}))
end
def test_parse1