From d5d734939864fa871daf8cef72b638aebf3b0f37 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 17 Jun 2014 12:19:27 -0600 Subject: 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. --- .../connection_adapters/postgresql/oid/array.rb | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql/oid') 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 -- cgit v1.2.3