diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-06-17 12:19:27 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-06-17 16:00:48 -0600 |
commit | d5d734939864fa871daf8cef72b638aebf3b0f37 (patch) | |
tree | 2139341a41e21021b5f28b5c396c0dd792439bae /activerecord/lib/active_record/connection_adapters/postgresql/oid | |
parent | 63b347df427ed2189fac7e75e36a3a4b9f6c2a68 (diff) | |
download | rails-d5d734939864fa871daf8cef72b638aebf3b0f37.tar.gz rails-d5d734939864fa871daf8cef72b638aebf3b0f37.tar.bz2 rails-d5d734939864fa871daf8cef72b638aebf3b0f37.zip |
Move array database type casting to the Array type
The case where we have a column object, but don't have a type cast
method involves type casting the default value when changing the schema.
We get one of the column definition structs instead. That is a case that
I'm trying to remove overall, but in the short term, we can achieve the
same behavior without needing to pass the adapter to the array type by
creating a fake type that proxies to the adapter.
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/postgresql/oid')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb index 4e7d472d97..b686e1e5ad 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb @@ -22,6 +22,14 @@ module ActiveRecord type_cast_array(value, :type_cast_from_user) end + def type_cast_for_database(value) + if value.is_a?(::Array) + cast_value_for_database(value) + else + super + end + end + # Loads pg_array_parser if available. String parsing can be # performed quicker by a native extension, which will not create # a large amount of Ruby objects that will need to be garbage @@ -43,6 +51,28 @@ module ActiveRecord @subtype.public_send(method, value) end end + + def cast_value_for_database(value) + if value.is_a?(::Array) + casted_values = value.map { |item| cast_value_for_database(item) } + "{#{casted_values.join(',')}}" + else + quote_and_escape(subtype.type_cast_for_database(value)) + end + end + + ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays + + def quote_and_escape(value) + case value + when ::String + value = value.gsub(/\\/, ARRAY_ESCAPE) + value.gsub!(/"/,"\\\"") + %("#{value}") + when nil then "NULL" + else value + end + end end end end |