diff options
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb | 25 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb | 29 |
2 files changed, 41 insertions, 13 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 8ccdd69b1d..e1a75f8e5e 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb @@ -5,6 +5,8 @@ module ActiveRecord class Array < Type::Value # :nodoc: include Type::Helpers::Mutable + Data = Struct.new(:encoder, :values) # :nodoc: + attr_reader :subtype, :delimiter delegate :type, :user_input_in_time_zone, :limit, :precision, :scale, to: :subtype @@ -17,8 +19,11 @@ module ActiveRecord end def deserialize(value) - if value.is_a?(::String) + case value + when ::String type_cast_array(@pg_decoder.decode(value), :deserialize) + when Data + deserialize(value.values) else super end @@ -33,11 +38,8 @@ module ActiveRecord def serialize(value) if value.is_a?(::Array) - result = @pg_encoder.encode(type_cast_array(value, :serialize)) - if encoding = determine_encoding_of_strings(value) - result.force_encoding(encoding) - end - result + casted_values = type_cast_array(value, :serialize) + Data.new(@pg_encoder, casted_values) else super end @@ -58,6 +60,10 @@ module ActiveRecord value.map(&block) end + def changed_in_place?(raw_old_value, new_value) + deserialize(raw_old_value) != new_value + end + private def type_cast_array(value, method) @@ -67,13 +73,6 @@ module ActiveRecord @subtype.public_send(method, value) end end - - def determine_encoding_of_strings(value) - case value - when ::Array then determine_encoding_of_strings(value.first) - when ::String then value.encoding - end - end end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index b5031d890f..3783925954 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -92,6 +92,8 @@ module ActiveRecord else super end + when OID::Array::Data + _quote(encode_array(value)) else super end @@ -106,10 +108,37 @@ module ActiveRecord { value: value.to_s, format: 1 } when OID::Xml::Data, OID::Bit::Data value.to_s + when OID::Array::Data + encode_array(value) else super end end + + def encode_array(array_data) + encoder = array_data.encoder + values = type_cast_array(array_data.values) + + result = encoder.encode(values) + if encoding = determine_encoding_of_strings_in_array(values) + result.force_encoding(encoding) + end + result + end + + def determine_encoding_of_strings_in_array(value) + case value + when ::Array then determine_encoding_of_strings_in_array(value.first) + when ::String then value.encoding + end + end + + def type_cast_array(values) + case values + when ::Array then values.map { |item| type_cast_array(item) } + else _type_cast(values) + end + end end end end |