From 1d0bb9af2234d375d4d10c722e0781a2292db576 Mon Sep 17 00:00:00 2001 From: Sylvain UTARD Date: Tue, 28 Jan 2025 20:58:42 +0100 Subject: [PATCH] Support JSON type --- .docker/clickhouse/users.xml | 3 ++- README.md | 1 + .../connection_adapters/clickhouse_adapter.rb | 4 ++++ .../add_sample_data/1_create_sample_table.rb | 1 + spec/single/model_spec.rb | 22 +++++++++++++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/.docker/clickhouse/users.xml b/.docker/clickhouse/users.xml index 61188536..b327fb76 100644 --- a/.docker/clickhouse/users.xml +++ b/.docker/clickhouse/users.xml @@ -4,6 +4,7 @@ random + 1 @@ -31,4 +32,4 @@ - + \ No newline at end of file diff --git a/README.md b/README.md index b5b21a13..3475d375 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,7 @@ false`. The default integer is `UInt32` | UInt256 | 0 to ... | 8+ | | Array | ... | ... | | Map | ... | ... | +| JSON | ... | ... | Example: diff --git a/lib/active_record/connection_adapters/clickhouse_adapter.rb b/lib/active_record/connection_adapters/clickhouse_adapter.rb index d59f646d..00c2760e 100644 --- a/lib/active_record/connection_adapters/clickhouse_adapter.rb +++ b/lib/active_record/connection_adapters/clickhouse_adapter.rb @@ -110,6 +110,8 @@ class ClickhouseAdapter < AbstractAdapter uint64: { name: 'UInt64' }, # uint128: { name: 'UInt128' }, not yet implemented in clickhouse uint256: { name: 'UInt256' }, + + json: { name: 'JSON' }, }.freeze include Clickhouse::SchemaStatements @@ -242,6 +244,8 @@ def initialize_type_map(m) # :nodoc: m.register_type(%r(Map)) do |sql_type| Clickhouse::OID::Map.new(sql_type) end + + m.register_type %r(JSON)i, Type::Json.new end end diff --git a/spec/fixtures/migrations/add_sample_data/1_create_sample_table.rb b/spec/fixtures/migrations/add_sample_data/1_create_sample_table.rb index 7fc41814..35c49190 100644 --- a/spec/fixtures/migrations/add_sample_data/1_create_sample_table.rb +++ b/spec/fixtures/migrations/add_sample_data/1_create_sample_table.rb @@ -12,6 +12,7 @@ def up t.string :byte_array t.uuid :relation_uuid t.decimal :decimal_value, precision: 38, scale: 16 + t.json :json_value, null: false, default: {} end end end diff --git a/spec/single/model_spec.rb b/spec/single/model_spec.rb index d32b3320..f4df2b4a 100644 --- a/spec/single/model_spec.rb +++ b/spec/single/model_spec.rb @@ -158,6 +158,28 @@ class ModelPk < ActiveRecord::Base end end + describe 'JSON column type' do + let(:json) { { 'key' => 'value' } } + let!(:record1) { Model.create!(event_name: 'some event', json_value: json) } + + it 'is mapped to :json' do + type = Model.columns_hash['json_value'].type + expect(type).to eq(:json) + end + + it 'keeps JSON value' do + expect(Model.first.json_value).to eq(json) + end + + context 'when the JSON column is complex' do + let(:json) { { 'key' => { 'nested_key' => 'value', 'another_key' => ['something'] } } } + + it 'keeps JSON value' do + expect(Model.first.json_value).to eq(json) + end + end + end + describe 'boolean column type' do let!(:record1) { Model.create!(event_name: 'some event', event_value: 1, date: date) }