Permalink
Browse files

string_to_hstore / hstore_to_string, serializing

  • Loading branch information...
Joel
Joel committed Feb 6, 2012
1 parent 2967aec commit b04880cecc6fdc452aeea5d64d078d90dfa2693a
@@ -98,7 +98,7 @@ def type_cast(value)
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 @@ def type_cast_code(var_name)
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
@@ -52,25 +52,31 @@ def string_to_time(string)
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 @@ def type_cast(value, column)
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
@@ -12,7 +12,7 @@ def setup
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 @@ def test_type_cast_hstore
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 @@ def test_type_cast_hstore
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

0 comments on commit b04880c

Please sign in to comment.