clickhouse-activerecord 0.5.7 → 0.5.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79b43575e5eef93daa11e1a2aca2984f696cbef59021f55d1470b2dc0a5d1e3d
4
- data.tar.gz: b79cccb85d8a07fa4dc533d7b7e9042eeaa2afead26214c075b3131e1843394b
3
+ metadata.gz: 6534694860bbb41c21789239e0589406bcbef64bc1750645c68485e77acb7310
4
+ data.tar.gz: c6640ccc74004a93bfaa18d93dd1c135411d66f27273eb65848f9843f64fd6d0
5
5
  SHA512:
6
- metadata.gz: 840b01cc1d5b88eee5e031fada23cfd35f7a8d948a35a767b2f5baf1596af665f28c56778e699960511004367b16ee3130be1f5bd2ee713a9a0d5053a9b58a37
7
- data.tar.gz: 4e613a19c51b362a05634da06d9528809ed09f01ebec4eac9984656156e9b877bdc4ce321e24bea63ae4e49d85609fa9dda781db60159e60b6d6ee06e8a99a3e
6
+ metadata.gz: f848ad57f80f061aa85a593a90bff65707e8dbe281caf3f4a41914d93a4723351bf7e5ca12bfdc7c8ed2cbed5df3db39472b8d015645875476b68941d7de6111
7
+ data.tar.gz: 1592560741198e983d43599ff78b145262e0638951a2825dcaac993e0dcc0195bf85980b5eeff80d973e0573aeaa865d6d6c8acdd7ee2b2b1ba6bb6740e734cf
data/CHANGELOG.md CHANGED
@@ -1,10 +1,16 @@
1
+ ### Version 0.5.10 (Jun 22, 2022)
2
+
3
+ * Fixes to create_table method (#70)
4
+ * Added support for rails 7 (#65)
5
+ * Use ClickHouse default KeepAlive timeout of 10 seconds (#67)
6
+
1
7
  ### Version 0.5.6 (Oct 25, 2021)
2
-
8
+
3
9
  * Added auto creating service distributed tables and additional options for creating view [@ygreeek](https://github.com/ygreeek)
4
10
  * Added default user agent
5
11
 
6
12
  ### Version 0.5.3 (Sep 22, 2021)
7
-
13
+
8
14
  * Fix replica cluster for a new syntax MergeTree
9
15
  * Fix support rails 5.2 on alter table
10
16
  * Support array type of column
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_runtime_dependency 'bundler', '>= 1.13.4'
27
27
  spec.add_runtime_dependency 'activerecord', '>= 5.2'
28
28
 
29
- spec.add_development_dependency 'bundler', '~> 1.15'
29
+ spec.add_development_dependency 'bundler', '>= 1.15'
30
30
  spec.add_development_dependency 'rake', '~> 13.0'
31
31
  spec.add_development_dependency 'rspec', '~> 3.4'
32
32
  spec.add_development_dependency 'pry', '~> 0.12'
@@ -2,21 +2,12 @@ module CoreExtensions
2
2
  module ActiveRecord
3
3
  module Migration
4
4
  module CommandRecorder
5
- def create_table_with_distributed(*args, &block)
6
- record(:create_table_with_distributed, args, &block)
7
- end
8
-
9
5
  def create_view(*args, &block)
10
6
  record(:create_view, args, &block)
11
7
  end
12
8
 
13
9
  private
14
10
 
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
11
  def invert_create_view(args)
21
12
  view_name, options = args
22
13
  [:drop_table, view_name, options]
@@ -23,6 +23,42 @@ module ActiveRecord
23
23
  @subtype
24
24
  end
25
25
 
26
+ def deserialize(value)
27
+ if value.is_a?(::Array)
28
+ value.map { |item| deserialize(item) }
29
+ else
30
+ return value if value.nil?
31
+ case @subtype
32
+ when :integer
33
+ value.to_i
34
+ when :datetime
35
+ ::DateTime.parse(value)
36
+ when :date
37
+ ::Date.parse(value)
38
+ else
39
+ super
40
+ end
41
+ end
42
+ end
43
+
44
+ def serialize(value)
45
+ if value.is_a?(::Array)
46
+ value.map { |item| serialize(item) }
47
+ else
48
+ return value if value.nil?
49
+ case @subtype
50
+ when :integer
51
+ value.to_i
52
+ when :datetime
53
+ DateTime.new.serialize(value)
54
+ when :date
55
+ Date.new.serialize(value)
56
+ else
57
+ super
58
+ end
59
+ end
60
+ end
61
+
26
62
  end
27
63
  end
28
64
  end
@@ -9,9 +9,8 @@ module ActiveRecord
9
9
  def serialize(value)
10
10
  value = super
11
11
  return unless value
12
- return value.strftime('%Y-%m-%d %H:%M:%S') unless value.acts_like?(:time)
13
12
 
14
- value.to_time.strftime('%Y-%m-%d %H:%M:%S')
13
+ value.strftime('%Y-%m-%d %H:%M:%S' + (@precision.present? && @precision > 0 ? ".%#{@precision}N" : ''))
15
14
  end
16
15
 
17
16
  def type_cast_from_database(value)
@@ -19,9 +19,18 @@ module ActiveRecord
19
19
  end
20
20
 
21
21
  def add_column_options!(sql, options)
22
+ if options[:value]
23
+ sql.gsub!(/\s+(.*)/, " \\1(#{options[:value]})")
24
+ end
25
+ if options[:fixed_string]
26
+ sql.gsub!(/\s+(.*)/, " FixedString(#{options[:fixed_string]})")
27
+ end
22
28
  if options[:null] || options[:null].nil?
23
29
  sql.gsub!(/\s+(.*)/, ' Nullable(\1)')
24
30
  end
31
+ if options[:low_cardinality]
32
+ sql.gsub!(/\s+(.*)/, ' LowCardinality(\1)')
33
+ end
25
34
  if options[:array]
26
35
  sql.gsub!(/\s+(.*)/, ' Array(\1)')
27
36
  end
@@ -73,7 +82,7 @@ module ActiveRecord
73
82
  return unless match
74
83
  return if match[:database]
75
84
 
76
- create_sql << "TO #{current_database}.#{options.to.sub('.', '')} "
85
+ create_sql << "TO #{current_database}.#{match[:table_name].sub('.', '')}"
77
86
  end
78
87
 
79
88
  def visit_TableDefinition(o)
@@ -116,7 +125,11 @@ module ActiveRecord
116
125
  end
117
126
 
118
127
  def current_database
119
- ActiveRecord::Base.connection_db_config.database
128
+ if ActiveRecord::version >= Gem::Version.new('6')
129
+ ActiveRecord::Base.connection_db_config.database
130
+ else
131
+ ActiveRecord::Base.connection_config[:database]
132
+ end
120
133
  end
121
134
  end
122
135
  end
@@ -62,6 +62,38 @@ module ActiveRecord
62
62
  end
63
63
  args.each { |name| column(name, kind, **options.except(:limit, :unsigned)) }
64
64
  end
65
+
66
+ def datetime(*args, **options)
67
+ kind = :datetime
68
+
69
+ if options[:precision]
70
+ kind = :datetime64
71
+ options[:value] = options[:precision]
72
+ end
73
+
74
+ args.each { |name| column(name, kind, **options.except(:precision)) }
75
+ end
76
+
77
+ def uuid(*args, **options)
78
+ args.each { |name| column(name, :uuid, **options) }
79
+ end
80
+
81
+ def enum(*args, **options)
82
+ kind = :enum8
83
+
84
+ unless options[:value].is_a? Hash
85
+ raise ArgumentError, "Column #{args.first}: option 'value' must be Hash, got: #{options[:value].class}"
86
+ end
87
+
88
+ options[:value] = options[:value].each_with_object([]) { |(k, v), arr| arr.push("'#{k}' = #{v}") }.join(', ')
89
+
90
+ if options[:limit]
91
+ kind = :enum8 if options[:limit] == 1
92
+ kind = :enum16 if options[:limit] == 2
93
+ end
94
+
95
+ args.each { |name| column(name, kind, **options.except(:limit)) }
96
+ end
65
97
  end
66
98
  end
67
99
  end
@@ -6,8 +6,8 @@ module ActiveRecord
6
6
  module ConnectionAdapters
7
7
  module Clickhouse
8
8
  module SchemaStatements
9
- def execute(sql, name = nil)
10
- do_execute(sql, name)
9
+ def execute(sql, name = nil, settings: {})
10
+ do_execute(sql, name, settings: settings)
11
11
  end
12
12
 
13
13
  def exec_insert(sql, name, _binds, _pk = nil, _sequence_name = nil)
@@ -39,7 +39,7 @@ module ActiveRecord
39
39
  end
40
40
 
41
41
  def tables(name = nil)
42
- result = do_system_execute('SHOW TABLES', name)
42
+ result = do_system_execute("SHOW TABLES WHERE name NOT LIKE '.inner_id.%'", name)
43
43
  return [] if result.nil?
44
44
  result['data'].flatten
45
45
  end
@@ -92,7 +92,7 @@ module ActiveRecord
92
92
  if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
93
93
  raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
94
94
  end
95
- execute insert_versions_sql(inserting)
95
+ do_execute(insert_versions_sql(inserting), nil, settings: {max_partitions_per_insert_block: [100, inserting.size].max})
96
96
  end
97
97
  end
98
98
 
@@ -11,6 +11,7 @@ require 'active_record/connection_adapters/clickhouse/schema_definitions'
11
11
  require 'active_record/connection_adapters/clickhouse/schema_creation'
12
12
  require 'active_record/connection_adapters/clickhouse/schema_statements'
13
13
  require 'net/http'
14
+ require 'openssl'
14
15
 
15
16
  module ActiveRecord
16
17
  class Base
@@ -32,6 +33,7 @@ module ActiveRecord
32
33
  sslca: config[:sslca],
33
34
  read_timeout: config[:read_timeout],
34
35
  write_timeout: config[:write_timeout],
36
+ keep_alive_timeout: config[:keep_alive_timeout]
35
37
  }
36
38
  end
37
39
 
@@ -46,21 +48,6 @@ module ActiveRecord
46
48
  end
47
49
  end
48
50
 
49
- class Relation
50
-
51
- # Replace for only ClickhouseAdapter
52
- def reverse_order!
53
- orders = order_values.uniq
54
- orders.reject!(&:blank?)
55
- if self.connection.is_a?(ConnectionAdapters::ClickhouseAdapter) && orders.empty? && !primary_key
56
- self.order_values = %w(date created_at).select {|c| column_names.include?(c) }.map{|c| arel_attribute(c).desc }
57
- else
58
- self.order_values = reverse_sql_order(orders)
59
- end
60
- self
61
- end
62
- end
63
-
64
51
  module TypeCaster
65
52
  class Map
66
53
  def is_view
@@ -74,7 +61,7 @@ module ActiveRecord
74
61
  end
75
62
 
76
63
  module ModelSchema
77
- module ClassMethods
64
+ module ClassMethods
78
65
  def is_view
79
66
  @is_view || false
80
67
  end
@@ -86,9 +73,8 @@ module ActiveRecord
86
73
  def arel_table # :nodoc:
87
74
  @arel_table ||= ClickhouseActiverecord::Arel::Table.new(table_name, type_caster: type_caster)
88
75
  end
89
-
90
76
  end
91
- end
77
+ end
92
78
 
93
79
  module ConnectionAdapters
94
80
  class ClickhouseColumn < Column
@@ -104,8 +90,13 @@ module ActiveRecord
104
90
  float: { name: 'Float32' },
105
91
  decimal: { name: 'Decimal' },
106
92
  datetime: { name: 'DateTime' },
93
+ datetime64: { name: 'DateTime64' },
107
94
  date: { name: 'Date' },
108
95
  boolean: { name: 'UInt8' },
96
+ uuid: { name: 'UUID' },
97
+
98
+ enum8: { name: 'Enum8' },
99
+ enum16: { name: 'Enum16' },
109
100
 
110
101
  int8: { name: 'Int8' },
111
102
  int16: { name: 'Int16' },
@@ -182,11 +173,25 @@ module ActiveRecord
182
173
  end
183
174
  end
184
175
 
176
+ # `extract_scale` and `extract_precision` are the same as in the Rails abstract base class,
177
+ # except this permits a space after the comma
178
+
179
+ def extract_scale(sql_type)
180
+ case sql_type
181
+ when /\((\d+)\)/ then 0
182
+ when /\((\d+)(,\s?(\d+))\)/ then $3.to_i
183
+ end
184
+ end
185
+
186
+ def extract_precision(sql_type)
187
+ $1.to_i if sql_type =~ /\((\d+)(,\s?\d+)?\)/
188
+ end
189
+
185
190
  def initialize_type_map(m) # :nodoc:
186
191
  super
187
192
  register_class_with_limit m, %r(String), Type::String
188
193
  register_class_with_limit m, 'Date', Clickhouse::OID::Date
189
- register_class_with_limit m, 'DateTime', Clickhouse::OID::DateTime
194
+ register_class_with_precision m, %r(datetime)i, Clickhouse::OID::DateTime
190
195
 
191
196
  register_class_with_limit m, %r(Int8), Type::Integer
192
197
  register_class_with_limit m, %r(Int16), Type::Integer
@@ -207,17 +212,34 @@ module ActiveRecord
207
212
  end
208
213
  end
209
214
 
215
+ def _quote(value)
216
+ case value
217
+ when Array
218
+ '[' + value.map { |v| _quote(v) }.join(', ') + ']'
219
+ else
220
+ super
221
+ end
222
+ end
223
+
210
224
  # Quoting time without microseconds
211
225
  def quoted_date(value)
212
226
  if value.acts_like?(:time)
213
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
227
+ if ActiveRecord::version >= Gem::Version.new('7')
228
+ zone_conversion_method = ActiveRecord.default_timezone == :utc ? :getutc : :getlocal
229
+ else
230
+ zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
231
+ end
214
232
 
215
233
  if value.respond_to?(zone_conversion_method)
216
234
  value = value.send(zone_conversion_method)
217
235
  end
218
236
  end
219
237
 
220
- value.to_s(:db)
238
+ if ActiveRecord::version >= Gem::Version.new('7')
239
+ value.to_fs(:db)
240
+ else
241
+ value.to_s(:db)
242
+ end
221
243
  end
222
244
 
223
245
  def column_name_for_operation(operation, node) # :nodoc:
@@ -269,32 +291,30 @@ module ActiveRecord
269
291
  drop_table(table_name, options.merge(if_exists: true))
270
292
  end
271
293
 
272
- execute schema_creation.accept td
294
+ do_execute(schema_creation.accept(td), format: nil)
273
295
  end
274
296
 
275
297
  def create_table(table_name, **options, &block)
276
298
  options = apply_replica(table_name, options)
277
299
  td = create_table_definition(apply_cluster(table_name), **options)
278
300
  block.call td if block_given?
301
+ td.column(:id, options[:id], null: false) if options[:id].present? && td[:id].blank?
279
302
 
280
303
  if options[:force]
281
304
  drop_table(table_name, options.merge(if_exists: true))
282
305
  end
283
306
 
284
- execute schema_creation.accept td
285
- end
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
307
+ do_execute(schema_creation.accept(td), format: nil)
291
308
 
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
309
+ if options[:with_distributed]
310
+ distributed_table_name = options.delete(:with_distributed)
311
+ sharding_key = options.delete(:sharding_key) || 'rand()'
312
+ raise 'Set a cluster' unless cluster
295
313
 
296
- def drop_table_with_distributed(table_name, **options)
297
- ["#{table_name}_distributed", table_name].each { |name| drop_table(name, **options) }
314
+ distributed_options =
315
+ "Distributed(#{cluster}, #{@config[:database]}, #{table_name}, #{sharding_key})"
316
+ create_table(distributed_table_name, **options.merge(options: distributed_options), &block)
317
+ end
298
318
  end
299
319
 
300
320
  # Drops a ClickHouse database.
@@ -312,10 +332,29 @@ module ActiveRecord
312
332
 
313
333
  def drop_table(table_name, options = {}) # :nodoc:
314
334
  do_execute apply_cluster "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
335
+
336
+ if options[:with_distributed]
337
+ distributed_table_name = options.delete(:with_distributed)
338
+ drop_table(distributed_table_name, **options)
339
+ end
340
+ end
341
+
342
+ def add_column(table_name, column_name, type, **options)
343
+ return if options[:if_not_exists] == true && column_exists?(table_name, column_name, type)
344
+
345
+ at = create_alter_table table_name
346
+ at.add_column(column_name, type, **options)
347
+ execute(schema_creation.accept(at), nil, settings: {wait_end_of_query: 1, send_progress_in_http_headers: 1})
348
+ end
349
+
350
+ def remove_column(table_name, column_name, type = nil, **options)
351
+ return if options[:if_exists] == true && !column_exists?(table_name, column_name)
352
+
353
+ execute("ALTER TABLE #{quote_table_name(table_name)} #{remove_column_for_alter(table_name, column_name, type, **options)}", nil, settings: {wait_end_of_query: 1, send_progress_in_http_headers: 1})
315
354
  end
316
355
 
317
356
  def change_column(table_name, column_name, type, options = {})
318
- result = do_execute "ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, options)}"
357
+ result = do_execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, options)}", nil, settings: {wait_end_of_query: 1, send_progress_in_http_headers: 1})
319
358
  raise "Error parse json response: #{result}" if result.presence && !result.is_a?(Hash)
320
359
  end
321
360
 
@@ -351,12 +390,18 @@ module ActiveRecord
351
390
 
352
391
  def database_engine_atomic?
353
392
  current_database_engine = "select engine from system.databases where name = '#{@config[:database]}'"
354
- res = ActiveRecord::Base.connection.select_one(current_database_engine)
393
+ res = select_one(current_database_engine)
355
394
  res['engine'] == 'Atomic' if res
356
395
  end
357
396
 
358
397
  def apply_cluster(sql)
359
- cluster ? "#{sql} ON CLUSTER #{cluster}" : sql
398
+ if cluster
399
+ normalized_cluster_name = cluster.start_with?('{') ? "'#{cluster}'" : cluster
400
+
401
+ "#{sql} ON CLUSTER #{normalized_cluster_name}"
402
+ else
403
+ sql
404
+ end
360
405
  end
361
406
 
362
407
  def supports_insert_on_duplicate_skip?
@@ -393,6 +438,9 @@ module ActiveRecord
393
438
  @connection.read_timeout = @connection_parameters[:read_timeout] if @connection_parameters[:read_timeout]
394
439
  @connection.write_timeout = @connection_parameters[:write_timeout] if @connection_parameters[:write_timeout]
395
440
 
441
+ # Use clickhouse default keep_alive_timeout value of 10, rather than Net::HTTP's default of 2
442
+ @connection.keep_alive_timeout = @connection_parameters[:keep_alive_timeout] || 10
443
+
396
444
  @connection
397
445
  end
398
446
 
@@ -10,16 +10,17 @@ module ClickhouseActiverecord
10
10
 
11
11
  version_options = connection.internal_string_options_for_primary_key
12
12
  table_options = {
13
- id: false, options: 'ReplacingMergeTree(ver) PARTITION BY version ORDER BY (version)', if_not_exists: true
13
+ id: false, options: 'ReplacingMergeTree(ver) ORDER BY (version)', if_not_exists: true
14
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'
15
+ full_config = connection.instance_variable_get(:@full_config) || {}
16
+
17
+ if full_config[:distributed_service_tables]
18
+ table_options.merge!(with_distributed: table_name, sharding_key: 'cityHash64(version)')
19
+
20
+ distributed_suffix = "_#{full_config[:distributed_service_tables_suffix] || 'distributed'}"
20
21
  end
21
22
 
22
- connection.public_send(table_creation_method, table_name, **table_options) do |t|
23
+ connection.create_table(table_name + distributed_suffix.to_s, **table_options) do |t|
23
24
  t.string :version, **version_options
24
25
  t.column :active, 'Int8', null: false, default: '1'
25
26
  t.datetime :ver, null: false, default: -> { 'now()' }
@@ -43,14 +44,15 @@ module ClickhouseActiverecord
43
44
  options: connection.adapter_name.downcase == 'clickhouse' ? 'MergeTree() PARTITION BY toDate(created_at) ORDER BY (created_at)' : '',
44
45
  if_not_exists: true
45
46
  }
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'
47
+ full_config = connection.instance_variable_get(:@full_config) || {}
48
+
49
+ if full_config[:distributed_service_tables]
50
+ table_options.merge!(with_distributed: table_name, sharding_key: 'cityHash64(created_at)')
51
+
52
+ distributed_suffix = "_#{full_config[:distributed_service_tables_suffix] || 'distributed'}"
51
53
  end
52
54
 
53
- connection.public_send(table_creation_method, table_name, **table_options) do |t|
55
+ connection.create_table(table_name + distributed_suffix.to_s, **table_options) do |t|
54
56
  t.string :key, **key_options
55
57
  t.string :value
56
58
  t.timestamps
@@ -4,6 +4,12 @@ module ClickhouseActiverecord
4
4
  require 'rails'
5
5
 
6
6
  class Railtie < Rails::Railtie
7
+ initializer "clickhouse.load" do
8
+ ActiveSupport.on_load :active_record do
9
+ ClickhouseActiverecord.load
10
+ end
11
+ end
12
+
7
13
  rake_tasks { load 'tasks/clickhouse.rake' }
8
14
  end
9
15
  end
@@ -14,7 +14,7 @@ module ClickhouseActiverecord
14
14
  connection.create_database @configuration["database"]
15
15
  rescue ActiveRecord::StatementInvalid => e
16
16
  if e.cause.to_s.include?('already exists')
17
- raise ActiveRecord::Tasks::DatabaseAlreadyExists
17
+ raise ActiveRecord::DatabaseAlreadyExists
18
18
  else
19
19
  raise
20
20
  end
@@ -1,3 +1,3 @@
1
1
  module ClickhouseActiverecord
2
- VERSION = '0.5.7'
2
+ VERSION = '0.5.15'
3
3
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'active_record/connection_adapters/clickhouse_adapter'
4
4
 
5
+ require 'core_extensions/active_record/relation'
6
+
5
7
  require_relative '../core_extensions/active_record/migration/command_recorder'
6
8
  ActiveRecord::Migration::CommandRecorder.include CoreExtensions::ActiveRecord::Migration::CommandRecorder
7
9
 
@@ -14,5 +16,7 @@ if defined?(Rails::Railtie)
14
16
  end
15
17
 
16
18
  module ClickhouseActiverecord
17
-
19
+ def self.load
20
+ ActiveRecord::Relation.prepend(CoreExtensions::ActiveRecord::Relation)
21
+ end
18
22
  end
@@ -0,0 +1,15 @@
1
+ module CoreExtensions
2
+ module ActiveRecord
3
+ module Relation
4
+ def reverse_order!
5
+ return super unless connection.is_a?(::ActiveRecord::ConnectionAdapters::ClickhouseAdapter)
6
+
7
+ orders = order_values.uniq.reject(&:blank?)
8
+ return super unless orders.empty? && !primary_key
9
+
10
+ self.order_values = (column_names & %w[date created_at]).map { |c| arel_table[c].desc }
11
+ self
12
+ end
13
+ end
14
+ end
15
+ end
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.7
4
+ version: 0.5.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Odintsov
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-25 00:00:00.000000000 Z
11
+ date: 2023-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.15'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.15'
55
55
  - !ruby/object:Gem::Dependency
@@ -130,13 +130,14 @@ files:
130
130
  - lib/clickhouse-activerecord/schema_dumper.rb
131
131
  - lib/clickhouse-activerecord/tasks.rb
132
132
  - lib/clickhouse-activerecord/version.rb
133
+ - lib/core_extensions/active_record/relation.rb
133
134
  - lib/generators/clickhouse_migration_generator.rb
134
135
  - lib/tasks/clickhouse.rake
135
136
  homepage: https://github.com/pnixx/clickhouse-activerecord
136
137
  licenses:
137
138
  - MIT
138
139
  metadata: {}
139
- post_install_message:
140
+ post_install_message:
140
141
  rdoc_options: []
141
142
  require_paths:
142
143
  - lib
@@ -151,8 +152,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
152
  - !ruby/object:Gem::Version
152
153
  version: '0'
153
154
  requirements: []
154
- rubygems_version: 3.0.3
155
- signing_key:
155
+ rubygems_version: 3.0.4
156
+ signing_key:
156
157
  specification_version: 4
157
158
  summary: ClickHouse ActiveRecord
158
159
  test_files: []