diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-06-17 16:37:08 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-06-17 17:01:09 -0600 |
commit | c462c2bd07548449131359b8e507ce11a44e6cb5 (patch) | |
tree | 695411cfb1a4dd05f9fb29f4357ec351dd85ea0b /activerecord/lib | |
parent | 838c3d25e7ee904d7a9b084c5900491211eda0e9 (diff) | |
download | rails-c462c2bd07548449131359b8e507ce11a44e6cb5.tar.gz rails-c462c2bd07548449131359b8e507ce11a44e6cb5.tar.bz2 rails-c462c2bd07548449131359b8e507ce11a44e6cb5.zip |
Ensure `OID::Array#type_cast_for_database` matches PG's quoting behavior
Also takes a step towards supporting types which use a character other
than ',' for the delimiter (`box` is the only built in type for which
this is the case)
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb | 26 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb | 2 |
2 files changed, 21 insertions, 7 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 b686e1e5ad..63f3be45de 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb @@ -3,11 +3,12 @@ module ActiveRecord module PostgreSQL module OID # :nodoc: class Array < Type::Value - attr_reader :subtype + attr_reader :subtype, :delimiter delegate :type, to: :subtype - def initialize(subtype) + def initialize(subtype, delimiter = ',') @subtype = subtype + @delimiter = delimiter end def type_cast_from_database(value) @@ -55,7 +56,7 @@ module ActiveRecord def cast_value_for_database(value) if value.is_a?(::Array) casted_values = value.map { |item| cast_value_for_database(item) } - "{#{casted_values.join(',')}}" + "{#{casted_values.join(delimiter)}}" else quote_and_escape(subtype.type_cast_for_database(value)) end @@ -66,13 +67,26 @@ module ActiveRecord def quote_and_escape(value) case value when ::String - value = value.gsub(/\\/, ARRAY_ESCAPE) - value.gsub!(/"/,"\\\"") - %("#{value}") + if string_requires_quoting?(value) + value = value.gsub(/\\/, ARRAY_ESCAPE) + value.gsub!(/"/,"\\\"") + %("#{value}") + else + value + end when nil then "NULL" else value end end + + # See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO + # for a list of all cases in which strings will be quoted. + def string_requires_quoting?(string) + string.empty? || + string == "NULL" || + string =~ /[\{\}"\\\s]/ || + string.include?(delimiter) + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb index 28f7a4eafb..e396ff4a1e 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb @@ -40,7 +40,7 @@ module ActiveRecord def register_array_type(row) if subtype = @store.lookup(row['typelem'].to_i) - register row['oid'], OID::Array.new(subtype) + register row['oid'], OID::Array.new(subtype, row['typdelim']) end end |