From 4210d6e097dff2fb6e1edeb425363dc4420306c3 Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Mon, 8 Jul 2024 16:53:11 +0200 Subject: [PATCH] misc: Add support of array in map --- .../connection_adapters/clickhouse/oid/map.rb | 29 ++++++++++++++++++- .../connection_adapters/clickhouse_adapter.rb | 4 +++ lib/clickhouse-activerecord/schema_dumper.rb | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/active_record/connection_adapters/clickhouse/oid/map.rb b/lib/active_record/connection_adapters/clickhouse/oid/map.rb index 6c6a1879..ba43fecb 100644 --- a/lib/active_record/connection_adapters/clickhouse/oid/map.rb +++ b/lib/active_record/connection_adapters/clickhouse/oid/map.rb @@ -33,7 +33,8 @@ def deserialize(value) def serialize(value) return '{}' if value.nil? - "{#{value.map { |k, v| "'#{k}': '#{v}'" }.join(', ')}}" + res = value.map { |k, v| "#{quote_with_type(k, key_type)}: #{quote_with_type(v, value_type)}" }.join(', ') + "{#{res}}" end private @@ -48,10 +49,36 @@ def cast_type(type) :datetime when /Date/ :date + when /Array\(*\)/ + type else :string end end + + def quote_with_type(value, type) + case type + when :string + "'#{value}'" + when :integer + value + when :datetime, :date + "'#{value.iso8601}'" + when /Array\(*\)/ + "[#{value.map { |v| quote(v) }.join(', ')}]" + end + end + + def quote(value) + case value + when String, Symbol + "'#{value}'" + when ::Array + "[#{value.map { |v| quote(v) }.join(', ')}]" + else + value + end + end end end end diff --git a/lib/active_record/connection_adapters/clickhouse_adapter.rb b/lib/active_record/connection_adapters/clickhouse_adapter.rb index 8c98cf2c..8e036726 100644 --- a/lib/active_record/connection_adapters/clickhouse_adapter.rb +++ b/lib/active_record/connection_adapters/clickhouse_adapter.rb @@ -112,6 +112,8 @@ def cast_type(type) :datetime when /Date/ :date + when /Array/ + type else :string end @@ -267,6 +269,8 @@ def quote(value) case value when Array '[' + value.map { |v| quote(v) }.join(', ') + ']' + when Hash + '{' + value.map { |k, v| "#{quote(k)}: #{quote(v)}" }.join(', ') + '}' else super end diff --git a/lib/clickhouse-activerecord/schema_dumper.rb b/lib/clickhouse-activerecord/schema_dumper.rb index cbd5a2e6..91ff6039 100644 --- a/lib/clickhouse-activerecord/schema_dumper.rb +++ b/lib/clickhouse-activerecord/schema_dumper.rb @@ -175,6 +175,7 @@ def prepare_column_options(column) if column.type == :map spec[:key_type] = "\"#{column.key_type}\"" spec[:value_type] = "\"#{column.value_type}\"" + spec[:array] = nil end spec.merge(super).compact