clickhouse-activerecord 0.5.0 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e17583f619debbb02952aa4299fedebbdd0de5ff6ae5c4a604071e42381c33a
4
- data.tar.gz: d9d642a756c2ff7791081f1298917d96758dd5de4f07781dc7c9e587100536b4
3
+ metadata.gz: 79b43575e5eef93daa11e1a2aca2984f696cbef59021f55d1470b2dc0a5d1e3d
4
+ data.tar.gz: b79cccb85d8a07fa4dc533d7b7e9042eeaa2afead26214c075b3131e1843394b
5
5
  SHA512:
6
- metadata.gz: cca1c4ce673a6622855a860e51b85952b0b09e3cbaaafe6b817a5c95ff1bb90d33da4974908acecaed6a658f7574fbaf9f71c1497d1c527006eb36bc3aaefab3
7
- data.tar.gz: 344cc941b595fe40179c8974dfc371dd3732cbf8994999d75976506582d23abbda39340e7b2232cc7b7c25f1c6271d3f26325c409cfd7aa21f1acfc017fb8d32
6
+ metadata.gz: 840b01cc1d5b88eee5e031fada23cfd35f7a8d948a35a767b2f5baf1596af665f28c56778e699960511004367b16ee3130be1f5bd2ee713a9a0d5053a9b58a37
7
+ data.tar.gz: 4e613a19c51b362a05634da06d9528809ed09f01ebec4eac9984656156e9b877bdc4ce321e24bea63ae4e49d85609fa9dda781db60159e60b6d6ee06e8a99a3e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ### Version 0.5.6 (Oct 25, 2021)
2
+
3
+ * Added auto creating service distributed tables and additional options for creating view [@ygreeek](https://github.com/ygreeek)
4
+ * Added default user agent
5
+
6
+ ### Version 0.5.3 (Sep 22, 2021)
7
+
8
+ * Fix replica cluster for a new syntax MergeTree
9
+ * Fix support rails 5.2 on alter table
10
+ * Support array type of column
11
+ * Support Rails 6.1.0 [@bdevel](https://github.com/bdevel)
12
+
1
13
  ### Version 0.4.10 (Mar 10, 2021)
2
14
 
3
15
  * Support ClickHouse 20.9+
data/README.md CHANGED
@@ -196,6 +196,7 @@ false`. The default integer is `UInt32`
196
196
  | UInt32 | 0 to 4,294,967,295 | 3,4 |
197
197
  | UInt64 | 0 to 18446744073709551615 | 5,6,7,8 |
198
198
  | UInt256 | 0 to ... | 8+ |
199
+ | Array | ... | ... |
199
200
 
200
201
  Example:
201
202
 
@@ -0,0 +1,27 @@
1
+ module CoreExtensions
2
+ module ActiveRecord
3
+ module Migration
4
+ module CommandRecorder
5
+ def create_table_with_distributed(*args, &block)
6
+ record(:create_table_with_distributed, args, &block)
7
+ end
8
+
9
+ def create_view(*args, &block)
10
+ record(:create_view, args, &block)
11
+ end
12
+
13
+ private
14
+
15
+ def invert_create_table_with_distributed(args)
16
+ table_name, options = args
17
+ [:drop_table_with_distributed, table_name, options]
18
+ end
19
+
20
+ def invert_create_view(args)
21
+ view_name, options = args
22
+ [:drop_table, view_name, options]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Clickhouse
6
+ module OID # :nodoc:
7
+ class Array < Type::Value # :nodoc:
8
+
9
+ def initialize(sql_type)
10
+ @subtype = case sql_type
11
+ when /U?Int\d+/
12
+ :integer
13
+ when /DateTime/
14
+ :datetime
15
+ when /Date/
16
+ :date
17
+ else
18
+ :string
19
+ end
20
+ end
21
+
22
+ def type
23
+ @subtype
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -22,6 +22,9 @@ module ActiveRecord
22
22
  if options[:null] || options[:null].nil?
23
23
  sql.gsub!(/\s+(.*)/, ' Nullable(\1)')
24
24
  end
25
+ if options[:array]
26
+ sql.gsub!(/\s+(.*)/, ' Array(\1)')
27
+ end
25
28
  sql.gsub!(/(\sString)\(\d+\)/, '\1')
26
29
  sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
27
30
  sql
@@ -33,7 +36,7 @@ module ActiveRecord
33
36
  # rails 6.1
34
37
  opts ||= options.options
35
38
  end
36
-
39
+
37
40
  if opts.present?
38
41
  create_sql << " ENGINE = #{opts}"
39
42
  else
@@ -43,17 +46,48 @@ module ActiveRecord
43
46
  create_sql
44
47
  end
45
48
 
49
+ def add_as_clause!(create_sql, options)
50
+ return unless options.as
51
+
52
+ assign_database_to_subquery!(options.as) if options.view
53
+ create_sql << " AS #{to_sql(options.as)}"
54
+ end
55
+
56
+ def assign_database_to_subquery!(subquery)
57
+ # If you do not specify a database explicitly, ClickHouse will use the "default" database.
58
+ return unless subquery
59
+
60
+ match = subquery.match(/(?<=from)[^.\w]+(?<database>\w+(?=\.))?(?<table_name>[.\w]+)/i)
61
+ return unless match
62
+ return if match[:database]
63
+
64
+ subquery[match.begin(:table_name)...match.end(:table_name)] =
65
+ "#{current_database}.#{match[:table_name].sub('.', '')}"
66
+ end
67
+
68
+ def add_to_clause!(create_sql, options)
69
+ # If you do not specify a database explicitly, ClickHouse will use the "default" database.
70
+ return unless options.to
71
+
72
+ match = options.to.match(/(?<database>.+(?=\.))?(?<table_name>.+)/i)
73
+ return unless match
74
+ return if match[:database]
75
+
76
+ create_sql << "TO #{current_database}.#{options.to.sub('.', '')} "
77
+ end
78
+
46
79
  def visit_TableDefinition(o)
47
80
  create_sql = +"CREATE#{table_modifier_in_create(o)} #{o.view ? "VIEW" : "TABLE"} "
48
81
  create_sql << "IF NOT EXISTS " if o.if_not_exists
49
82
  create_sql << "#{quote_table_name(o.name)} "
83
+ add_to_clause!(create_sql, o) if o.materialized
50
84
 
51
85
  statements = o.columns.map { |c| accept c }
52
86
  statements << accept(o.primary_keys) if o.primary_keys
53
87
  create_sql << "(#{statements.join(', ')})" if statements.present?
54
- # Attach options for only table or materialized view
55
- add_table_options!(create_sql, o) if !o.view || o.view && o.materialized
56
- create_sql << " AS #{to_sql(o.as)}" if o.as
88
+ # Attach options for only table or materialized view without TO section
89
+ add_table_options!(create_sql, o) if !o.view || o.view && o.materialized && !o.to
90
+ add_as_clause!(create_sql, o)
57
91
  create_sql
58
92
  end
59
93
 
@@ -81,6 +115,9 @@ module ActiveRecord
81
115
  change_column_sql
82
116
  end
83
117
 
118
+ def current_database
119
+ ActiveRecord::Base.connection_db_config.database
120
+ end
84
121
  end
85
122
  end
86
123
  end
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  module Clickhouse
6
6
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
7
7
 
8
- attr_reader :view, :materialized, :if_not_exists
8
+ attr_reader :view, :materialized, :if_not_exists, :to
9
9
 
10
10
  def initialize(
11
11
  conn,
@@ -17,6 +17,7 @@ module ActiveRecord
17
17
  comment: nil,
18
18
  view: false,
19
19
  materialized: false,
20
+ to: nil,
20
21
  **
21
22
  )
22
23
  @conn = conn
@@ -32,6 +33,7 @@ module ActiveRecord
32
33
  @comment = comment
33
34
  @view = view || materialized
34
35
  @materialized = materialized
36
+ @to = to
35
37
  end
36
38
 
37
39
  def integer(*args, **options)
@@ -58,7 +60,7 @@ module ActiveRecord
58
60
  kind = :int256 if options[:limit] > 16
59
61
  end
60
62
  end
61
- args.each { |name| column(name, kind, options.except(:limit, :unsigned)) }
63
+ args.each { |name| column(name, kind, **options.except(:limit, :unsigned)) }
62
64
  end
63
65
  end
64
66
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'clickhouse-activerecord/version'
4
+
3
5
  module ActiveRecord
4
6
  module ConnectionAdapters
5
7
  module Clickhouse
@@ -23,6 +25,11 @@ module ActiveRecord
23
25
  raise ActiveRecord::ActiveRecordError, "Response: #{e.message}"
24
26
  end
25
27
 
28
+ def exec_insert_all(sql, name)
29
+ do_execute(sql, name, format: nil)
30
+ true
31
+ end
32
+
26
33
  def exec_update(_sql, _name = nil, _binds = [])
27
34
  raise ActiveRecord::ActiveRecordError, 'Clickhouse update is not supported'
28
35
  end
@@ -53,7 +60,7 @@ module ActiveRecord
53
60
 
54
61
  def do_system_execute(sql, name = nil)
55
62
  log_with_debug(sql, "#{adapter_name} #{name}") do
56
- res = @connection.post("/?#{@config.to_param}", "#{sql} FORMAT JSONCompact")
63
+ res = @connection.post("/?#{@config.to_param}", "#{sql} FORMAT JSONCompact", 'User-Agent' => "Clickhouse ActiveRecord #{ClickhouseActiverecord::VERSION}")
57
64
 
58
65
  process_response(res)
59
66
  end
@@ -63,7 +70,7 @@ module ActiveRecord
63
70
  log(sql, "#{adapter_name} #{name}") do
64
71
  formatted_sql = apply_format(sql, format)
65
72
  request_params = @config || {}
66
- res = @connection.post("/?#{request_params.merge(settings).to_param}", formatted_sql)
73
+ res = @connection.post("/?#{request_params.merge(settings).to_param}", formatted_sql, 'User-Agent' => "Clickhouse ActiveRecord #{ClickhouseActiverecord::VERSION}")
67
74
 
68
75
  process_response(res)
69
76
  end
@@ -116,7 +123,7 @@ module ActiveRecord
116
123
  Clickhouse::SchemaCreation.new(self)
117
124
  end
118
125
 
119
- def create_table_definition(table_name, options)
126
+ def create_table_definition(table_name, **options)
120
127
  Clickhouse::TableDefinition.new(self, table_name, **options)
121
128
  end
122
129
 
@@ -3,6 +3,7 @@
3
3
  require 'clickhouse-activerecord/arel/visitors/to_sql'
4
4
  require 'clickhouse-activerecord/arel/table'
5
5
  require 'clickhouse-activerecord/migration'
6
+ require 'active_record/connection_adapters/clickhouse/oid/array'
6
7
  require 'active_record/connection_adapters/clickhouse/oid/date'
7
8
  require 'active_record/connection_adapters/clickhouse/oid/date_time'
8
9
  require 'active_record/connection_adapters/clickhouse/oid/big_integer'
@@ -17,6 +18,7 @@ module ActiveRecord
17
18
  # Establishes a connection to the database that's used by all Active Record objects
18
19
  def clickhouse_connection(config)
19
20
  config = config.symbolize_keys
21
+
20
22
  if config[:connection]
21
23
  connection = {
22
24
  connection: config[:connection]
@@ -27,6 +29,9 @@ module ActiveRecord
27
29
  host: config[:host] || 'localhost',
28
30
  port: port,
29
31
  ssl: config[:ssl].present? ? config[:ssl] : port == 443,
32
+ sslca: config[:sslca],
33
+ read_timeout: config[:read_timeout],
34
+ write_timeout: config[:write_timeout],
30
35
  }
31
36
  end
32
37
 
@@ -190,12 +195,16 @@ module ActiveRecord
190
195
  register_class_with_limit m, %r(Int128), Type::Integer
191
196
  register_class_with_limit m, %r(Int256), Type::Integer
192
197
 
193
- register_class_with_limit m, %r(Uint8), Type::UnsignedInteger
198
+ register_class_with_limit m, %r(UInt8), Type::UnsignedInteger
194
199
  register_class_with_limit m, %r(UInt16), Type::UnsignedInteger
195
200
  register_class_with_limit m, %r(UInt32), Type::UnsignedInteger
196
201
  register_class_with_limit m, %r(UInt64), Type::UnsignedInteger
197
202
  #register_class_with_limit m, %r(UInt128), Type::UnsignedInteger #not implemnted in clickhouse
198
203
  register_class_with_limit m, %r(UInt256), Type::UnsignedInteger
204
+ # register_class_with_limit m, %r(Array), Clickhouse::OID::Array
205
+ m.register_type(%r(Array)) do |sql_type|
206
+ Clickhouse::OID::Array.new(sql_type)
207
+ end
199
208
  end
200
209
 
201
210
  # Quoting time without microseconds
@@ -253,7 +262,7 @@ module ActiveRecord
253
262
  def create_view(table_name, **options)
254
263
  options.merge!(view: true)
255
264
  options = apply_replica(table_name, options)
256
- td = create_table_definition(apply_cluster(table_name), options)
265
+ td = create_table_definition(apply_cluster(table_name), **options)
257
266
  yield td if block_given?
258
267
 
259
268
  if options[:force]
@@ -263,10 +272,10 @@ module ActiveRecord
263
272
  execute schema_creation.accept td
264
273
  end
265
274
 
266
- def create_table(table_name, **options)
275
+ def create_table(table_name, **options, &block)
267
276
  options = apply_replica(table_name, options)
268
- td = create_table_definition(apply_cluster(table_name), options)
269
- yield td if block_given?
277
+ td = create_table_definition(apply_cluster(table_name), **options)
278
+ block.call td if block_given?
270
279
 
271
280
  if options[:force]
272
281
  drop_table(table_name, options.merge(if_exists: true))
@@ -275,6 +284,19 @@ module ActiveRecord
275
284
  execute schema_creation.accept td
276
285
  end
277
286
 
287
+ def create_table_with_distributed(table_name, **options, &block)
288
+ sharding_key = options.delete(:sharding_key) || 'rand()'
289
+ create_table("#{table_name}_distributed", **options, &block)
290
+ raise 'Set a cluster' unless cluster
291
+
292
+ distributed_options = "Distributed(#{cluster},#{@config[:database]},#{table_name}_distributed,#{sharding_key})"
293
+ create_table(table_name, **options.merge(options: distributed_options), &block)
294
+ end
295
+
296
+ def drop_table_with_distributed(table_name, **options)
297
+ ["#{table_name}_distributed", table_name].each { |name| drop_table(name, **options) }
298
+ end
299
+
278
300
  # Drops a ClickHouse database.
279
301
  def drop_database(name) #:nodoc:
280
302
  sql = apply_cluster "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
@@ -315,14 +337,41 @@ module ActiveRecord
315
337
  @full_config[:replica_name]
316
338
  end
317
339
 
340
+ def use_default_replicated_merge_tree_params?
341
+ database_engine_atomic? && @full_config[:use_default_replicated_merge_tree_params]
342
+ end
343
+
344
+ def use_replica?
345
+ (replica || use_default_replicated_merge_tree_params?) && cluster
346
+ end
347
+
318
348
  def replica_path(table)
319
349
  "/clickhouse/tables/#{cluster}/#{@config[:database]}.#{table}"
320
350
  end
321
351
 
352
+ def database_engine_atomic?
353
+ current_database_engine = "select engine from system.databases where name = '#{@config[:database]}'"
354
+ res = ActiveRecord::Base.connection.select_one(current_database_engine)
355
+ res['engine'] == 'Atomic' if res
356
+ end
357
+
322
358
  def apply_cluster(sql)
323
359
  cluster ? "#{sql} ON CLUSTER #{cluster}" : sql
324
360
  end
325
361
 
362
+ def supports_insert_on_duplicate_skip?
363
+ true
364
+ end
365
+
366
+ def supports_insert_on_duplicate_update?
367
+ true
368
+ end
369
+
370
+ def build_insert_sql(insert) # :nodoc:
371
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
372
+ sql
373
+ end
374
+
326
375
  protected
327
376
 
328
377
  def last_inserted_id(result)
@@ -339,17 +388,35 @@ module ActiveRecord
339
388
 
340
389
  def connect
341
390
  @connection = @connection_parameters[:connection] || Net::HTTP.start(@connection_parameters[:host], @connection_parameters[:port], use_ssl: @connection_parameters[:ssl], verify_mode: OpenSSL::SSL::VERIFY_NONE)
391
+
392
+ @connection.ca_file = @connection_parameters[:ca_file] if @connection_parameters[:ca_file]
393
+ @connection.read_timeout = @connection_parameters[:read_timeout] if @connection_parameters[:read_timeout]
394
+ @connection.write_timeout = @connection_parameters[:write_timeout] if @connection_parameters[:write_timeout]
395
+
396
+ @connection
342
397
  end
343
398
 
344
399
  def apply_replica(table, options)
345
- if replica && cluster && options[:options]
346
- match = options[:options].match(/^(.*?MergeTree)\(([^\)]*)\)(.*?)$/)
347
- if match
348
- options[:options] = "Replicated#{match[1]}(#{([replica_path(table), replica].map{|v| "'#{v}'"} + [match[2].presence]).compact.join(', ')})#{match[3]}"
400
+ if use_replica? && options[:options]
401
+ if options[:options].match(/^Replicated/)
402
+ raise 'Do not try create Replicated table. It will be configured based on the *MergeTree engine.'
349
403
  end
404
+
405
+ options[:options] = configure_replica(table, options[:options])
350
406
  end
351
407
  options
352
408
  end
409
+
410
+ def configure_replica(table, options)
411
+ match = options.match(/^(.*?MergeTree)(?:\(([^\)]*)\))?((?:.|\n)*)/)
412
+ return options unless match
413
+
414
+ if replica
415
+ engine_params = ([replica_path(table), replica].map { |v| "'#{v}'" } + [match[2].presence]).compact.join(', ')
416
+ end
417
+
418
+ "Replicated#{match[1]}(#{engine_params})#{match[3]}"
419
+ end
353
420
  end
354
421
  end
355
422
  end
@@ -6,14 +6,23 @@ module ClickhouseActiverecord
6
6
  class << self
7
7
 
8
8
  def create_table
9
- unless table_exists?
10
- version_options = connection.internal_string_options_for_primary_key
11
-
12
- connection.create_table(table_name, id: false, options: 'ReplacingMergeTree(ver) PARTITION BY version ORDER BY (version)', if_not_exists: true) do |t|
13
- t.string :version, **version_options
14
- t.column :active, 'Int8', null: false, default: '1'
15
- t.datetime :ver, null: false, default: -> { 'now()' }
16
- end
9
+ return if table_exists?
10
+
11
+ version_options = connection.internal_string_options_for_primary_key
12
+ table_options = {
13
+ id: false, options: 'ReplacingMergeTree(ver) PARTITION BY version ORDER BY (version)', if_not_exists: true
14
+ }
15
+ if connection.instance_variable_get(:@full_config)[:distributed_service_tables]
16
+ table_options.merge!(sharding_key: 'cityHash64(version)')
17
+ table_creation_method = 'create_table_with_distributed'
18
+ else
19
+ table_creation_method = 'create_table'
20
+ end
21
+
22
+ connection.public_send(table_creation_method, table_name, **table_options) do |t|
23
+ t.string :version, **version_options
24
+ t.column :active, 'Int8', null: false, default: '1'
25
+ t.datetime :ver, null: false, default: -> { 'now()' }
17
26
  end
18
27
  end
19
28
 
@@ -26,14 +35,25 @@ module ClickhouseActiverecord
26
35
  class InternalMetadata < ::ActiveRecord::InternalMetadata
27
36
  class << self
28
37
  def create_table
29
- unless table_exists?
30
- key_options = connection.internal_string_options_for_primary_key
31
-
32
- connection.create_table(table_name, id: false, options: connection.adapter_name.downcase == 'clickhouse' ? 'MergeTree() PARTITION BY toDate(created_at) ORDER BY (created_at)' : '', if_not_exists: true) do |t|
33
- t.string :key, key_options
34
- t.string :value
35
- t.timestamps
36
- end
38
+ return if table_exists?
39
+
40
+ key_options = connection.internal_string_options_for_primary_key
41
+ table_options = {
42
+ id: false,
43
+ options: connection.adapter_name.downcase == 'clickhouse' ? 'MergeTree() PARTITION BY toDate(created_at) ORDER BY (created_at)' : '',
44
+ if_not_exists: true
45
+ }
46
+ if connection.instance_variable_get(:@full_config).try(:[], :distributed_service_tables)
47
+ table_options.merge!(sharding_key: 'cityHash64(created_at)')
48
+ table_creation_method = 'create_table_with_distributed'
49
+ else
50
+ table_creation_method = 'create_table'
51
+ end
52
+
53
+ connection.public_send(table_creation_method, table_name, **table_options) do |t|
54
+ t.string :key, **key_options
55
+ t.string :value
56
+ t.timestamps
37
57
  end
38
58
  end
39
59
  end
@@ -47,6 +67,16 @@ module ClickhouseActiverecord
47
67
  @schema_migration = schema_migration
48
68
  end
49
69
 
70
+ def up(target_version = nil)
71
+ selected_migrations = if block_given?
72
+ migrations.select { |m| yield m }
73
+ else
74
+ migrations
75
+ end
76
+
77
+ ClickhouseActiverecord::Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
78
+ end
79
+
50
80
  def down(target_version = nil)
51
81
  selected_migrations = if block_given?
52
82
  migrations.select { |m| yield m }
@@ -144,9 +144,14 @@ HEADER
144
144
  (column.sql_type =~ /(Nullable)?\(?UInt\d+\)?/).nil? ? false : nil
145
145
  end
146
146
 
147
+ def schema_array(column)
148
+ (column.sql_type =~ /Array?\(/).nil? ? nil : true
149
+ end
150
+
147
151
  def prepare_column_options(column)
148
152
  spec = {}
149
153
  spec[:unsigned] = schema_unsigned(column)
154
+ spec[:array] = schema_array(column)
150
155
  spec.merge(super).compact
151
156
  end
152
157
  end
@@ -43,7 +43,15 @@ module ClickhouseActiverecord
43
43
  end
44
44
 
45
45
  def structure_load(*args)
46
- File.read(args.first).split(";\n\n").each { |sql| connection.execute(sql) }
46
+ File.read(args.first).split(";\n\n").each do |sql|
47
+ if sql.gsub(/[a-z]/i, '').blank?
48
+ next
49
+ elsif sql =~ /^INSERT INTO/
50
+ connection.do_execute(sql, nil, format: nil)
51
+ else
52
+ connection.execute(sql)
53
+ end
54
+ end
47
55
  end
48
56
 
49
57
  def migrate
@@ -1,3 +1,3 @@
1
1
  module ClickhouseActiverecord
2
- VERSION = '0.5.0'
2
+ VERSION = '0.5.7'
3
3
  end
@@ -2,6 +2,9 @@
2
2
 
3
3
  require 'active_record/connection_adapters/clickhouse_adapter'
4
4
 
5
+ require_relative '../core_extensions/active_record/migration/command_recorder'
6
+ ActiveRecord::Migration::CommandRecorder.include CoreExtensions::ActiveRecord::Migration::CommandRecorder
7
+
5
8
  if defined?(Rails::Railtie)
6
9
  require 'clickhouse-activerecord/railtie'
7
10
  require 'clickhouse-activerecord/schema'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clickhouse-activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Odintsov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-10 00:00:00.000000000 Z
11
+ date: 2021-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -112,6 +112,8 @@ files:
112
112
  - bin/console
113
113
  - bin/setup
114
114
  - clickhouse-activerecord.gemspec
115
+ - core_extensions/active_record/migration/command_recorder.rb
116
+ - lib/active_record/connection_adapters/clickhouse/oid/array.rb
115
117
  - lib/active_record/connection_adapters/clickhouse/oid/big_integer.rb
116
118
  - lib/active_record/connection_adapters/clickhouse/oid/date.rb
117
119
  - lib/active_record/connection_adapters/clickhouse/oid/date_time.rb