diff --git a/lib/active_record/connection_adapters/clickhouse/oid/map.rb b/lib/active_record/connection_adapters/clickhouse/oid/map.rb index a4629d11..08067a33 100644 --- a/lib/active_record/connection_adapters/clickhouse/oid/map.rb +++ b/lib/active_record/connection_adapters/clickhouse/oid/map.rb @@ -1,76 +1,66 @@ # frozen_string_literal: true -require 'yaml' - module ActiveRecord module ConnectionAdapters module Clickhouse module OID # :nodoc: class Map < Type::Value # :nodoc: - attr_reader :key_type, :value_type def initialize(sql_type) - types = sql_type.match(/Map\((.+),\s?(.+)\)/).captures - - @key_type = cast_type(types.first) - @value_type = cast_type(types.last) + @subtype = case sql_type + when /U?Int\d+/ + :integer + when /DateTime/ + :datetime + when /Date/ + :date + else + :string + end end def type - :map - end - - def cast(value) - value + @subtype end def deserialize(value) - return value if value.is_a?(Hash) - - YAML.safe_load(value) - end - - def serialize(value) - return '{}' if value.nil? - - res = value.map { |k, v| "#{quote(k, key_type)}: #{quote(v, value_type)}" }.join(', ') - "{#{res}}" - end - - private - - def cast_type(type) - return type if type.nil? - - case type - when /U?Int\d+/ - :integer - when /DateTime/ - :datetime - when /Date/ - :date - when /Array\(.*\)/ - type + if value.is_a?(::Hash) + value.map { |k, item| [k.to_s, deserialize(item)] }.to_h else - :string + return value if value.nil? + case @subtype + when :integer + value.to_i + when :datetime + ::DateTime.parse(value) + when :date + ::Date.parse(value) + else + super + end end end - def quote(value, type) - case cast_type(type) - when :string - "'#{value}'" - when :integer - value - when :datetime, :date - "'#{value.iso8601}'" - when /Array\(.*\)/ - sub_type = type.match(/Array\((.+)\)/).captures.first - "[#{value.map { |v| quote(v, sub_type) }.join(', ')}]" + def serialize(value) + if value.is_a?(::Hash) + value.map { |k, item| [k.to_s, serialize(item)] }.to_h else - value + return value if value.nil? + case @subtype + when :integer + value.to_i + when :datetime + DateTime.new.serialize(value) + when :date + Date.new.serialize(value) + when :string + value.to_s + else + super + end end end + end end end