aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/postgresql/oid
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-06-17 12:19:27 -0600
committerSean Griffin <sean@thoughtbot.com>2014-06-17 16:00:48 -0600
commitd5d734939864fa871daf8cef72b638aebf3b0f37 (patch)
tree2139341a41e21021b5f28b5c396c0dd792439bae /activerecord/lib/active_record/connection_adapters/postgresql/oid
parent63b347df427ed2189fac7e75e36a3a4b9f6c2a68 (diff)
downloadrails-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.rb30
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