clickhouse-activerecord 0.4.12 → 0.5.3

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: ad0ad1c7545498f275ff975d35ee9dde7d2f644516932ee33ab65796360426a0
4
- data.tar.gz: 15b32b155c596c8cdd9e187681a128a4806ca7e2c457e0f833ffc66ba9c994af
3
+ metadata.gz: 41dd800df06e6269f91b1a39d3c9df2e1e903068b5f13913cd2aad863063685f
4
+ data.tar.gz: 50252db6e694467f48669a3c7c52c89e6b1633f08586714db300b8eee59ebbbc
5
5
  SHA512:
6
- metadata.gz: 8f80ffc1c70dbbdd489ea59627e85a72f538276c80adc0fe5ee4319c222a61da2acd1680ea42bd8c4c4b713fb354f7498a3469cc3cfd17f9003c8dbd607719b2
7
- data.tar.gz: 9c91108f18bb9b133708a682ee3dfec238cc54afac480fcada95e876bb051843a7269e3d81c6298299b1bbffbc5a8a47975add7919144d220845fd87c710122b
6
+ metadata.gz: 539e7dfb17998dd1bcc95ee2c15c6111229775ec29837d8f102291bf5da64db2dcf74ef0f01087443c8c1b1d9902cfdf4a586357508d3d8ed97fa099b1545770
7
+ data.tar.gz: f5f8acbf806f9bc8497dcd6aa29c6bfd18b651aae78c28cc0f9449effd4ddce965a1978027d91fa57a998fc1ba0bb0027d33917a3ef35379299185bfde06c784
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ### Version 0.5.3 (Sep 22, 2021)
2
+
3
+ * Fix replica cluster for a new syntax MergeTree
4
+ * Fix support rails 5.2 on alter table
5
+ * Support array type of column
6
+ * Support Rails 6.1.0 [@bdevel](https://github.com/bdevel)
7
+
1
8
  ### Version 0.4.10 (Mar 10, 2021)
2
9
 
3
10
  * Support ClickHouse 20.9+
@@ -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
@@ -1,9 +1,16 @@
1
1
  # frozen_string_literal: true
2
+ begin
3
+ require "active_record/connection_adapters/deduplicable"
4
+ rescue LoadError => e
5
+ # Rails < 6.1 does not have this file in this location, ignore
6
+ end
7
+
8
+ require "active_record/connection_adapters/abstract/schema_creation"
2
9
 
3
10
  module ActiveRecord
4
11
  module ConnectionAdapters
5
12
  module Clickhouse
6
- class SchemaCreation < AbstractAdapter::SchemaCreation# :nodoc:
13
+ class SchemaCreation < ConnectionAdapters::SchemaCreation# :nodoc:
7
14
 
8
15
  def visit_AddColumnDefinition(o)
9
16
  sql = +"ADD COLUMN #{accept(o.column)}"
@@ -15,14 +22,23 @@ module ActiveRecord
15
22
  if options[:null] || options[:null].nil?
16
23
  sql.gsub!(/\s+(.*)/, ' Nullable(\1)')
17
24
  end
25
+ if options[:array]
26
+ sql.gsub!(/\s+(.*)/, ' Array(\1)')
27
+ end
18
28
  sql.gsub!(/(\sString)\(\d+\)/, '\1')
19
29
  sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
20
30
  sql
21
31
  end
22
32
 
23
33
  def add_table_options!(create_sql, options)
24
- if options[:options].present?
25
- create_sql << " ENGINE = #{options[:options]}"
34
+ opts = options[:options]
35
+ if options.respond_to?(:options)
36
+ # rails 6.1
37
+ opts ||= options.options
38
+ end
39
+
40
+ if opts.present?
41
+ create_sql << " ENGINE = #{opts}"
26
42
  else
27
43
  create_sql << " ENGINE = Log()"
28
44
  end
@@ -37,11 +53,9 @@ module ActiveRecord
37
53
 
38
54
  statements = o.columns.map { |c| accept c }
39
55
  statements << accept(o.primary_keys) if o.primary_keys
40
-
41
56
  create_sql << "(#{statements.join(', ')})" if statements.present?
42
57
  # Attach options for only table or materialized view
43
- add_table_options!(create_sql, table_options(o)) if !o.view || o.view && o.materialized
44
-
58
+ add_table_options!(create_sql, o) if !o.view || o.view && o.materialized
45
59
  create_sql << " AS #{to_sql(o.as)}" if o.as
46
60
  create_sql
47
61
  end
@@ -23,6 +23,11 @@ module ActiveRecord
23
23
  raise ActiveRecord::ActiveRecordError, "Response: #{e.message}"
24
24
  end
25
25
 
26
+ def exec_insert_all(sql, name)
27
+ do_execute(sql, name, format: nil)
28
+ true
29
+ end
30
+
26
31
  def exec_update(_sql, _name = nil, _binds = [])
27
32
  raise ActiveRecord::ActiveRecordError, 'Clickhouse update is not supported'
28
33
  end
@@ -116,8 +121,8 @@ module ActiveRecord
116
121
  Clickhouse::SchemaCreation.new(self)
117
122
  end
118
123
 
119
- def create_table_definition(*args)
120
- Clickhouse::TableDefinition.new(self, *args)
124
+ def create_table_definition(table_name, **options)
125
+ Clickhouse::TableDefinition.new(self, table_name, **options)
121
126
  end
122
127
 
123
128
  def new_column_from_field(table_name, field)
@@ -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
 
@@ -59,7 +64,11 @@ module ActiveRecord
59
64
  module TypeCaster
60
65
  class Map
61
66
  def is_view
62
- types.is_view
67
+ if @klass.respond_to?(:is_view)
68
+ @klass.is_view # rails 6.1
69
+ else
70
+ types.is_view # less than 6.1
71
+ end
63
72
  end
64
73
  end
65
74
  end
@@ -186,12 +195,16 @@ module ActiveRecord
186
195
  register_class_with_limit m, %r(Int128), Type::Integer
187
196
  register_class_with_limit m, %r(Int256), Type::Integer
188
197
 
189
- register_class_with_limit m, %r(Uint8), Type::UnsignedInteger
198
+ register_class_with_limit m, %r(UInt8), Type::UnsignedInteger
190
199
  register_class_with_limit m, %r(UInt16), Type::UnsignedInteger
191
200
  register_class_with_limit m, %r(UInt32), Type::UnsignedInteger
192
201
  register_class_with_limit m, %r(UInt64), Type::UnsignedInteger
193
202
  #register_class_with_limit m, %r(UInt128), Type::UnsignedInteger #not implemnted in clickhouse
194
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
195
208
  end
196
209
 
197
210
  # Quoting time without microseconds
@@ -319,6 +332,19 @@ module ActiveRecord
319
332
  cluster ? "#{sql} ON CLUSTER #{cluster}" : sql
320
333
  end
321
334
 
335
+ def supports_insert_on_duplicate_skip?
336
+ true
337
+ end
338
+
339
+ def supports_insert_on_duplicate_update?
340
+ true
341
+ end
342
+
343
+ def build_insert_sql(insert) # :nodoc:
344
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
345
+ sql
346
+ end
347
+
322
348
  protected
323
349
 
324
350
  def last_inserted_id(result)
@@ -335,11 +361,17 @@ module ActiveRecord
335
361
 
336
362
  def connect
337
363
  @connection = @connection_parameters[:connection] || Net::HTTP.start(@connection_parameters[:host], @connection_parameters[:port], use_ssl: @connection_parameters[:ssl], verify_mode: OpenSSL::SSL::VERIFY_NONE)
364
+
365
+ @connection.ca_file = @connection_parameters[:ca_file] if @connection_parameters[:ca_file]
366
+ @connection.read_timeout = @connection_parameters[:read_timeout] if @connection_parameters[:read_timeout]
367
+ @connection.write_timeout = @connection_parameters[:write_timeout] if @connection_parameters[:write_timeout]
368
+
369
+ @connection
338
370
  end
339
371
 
340
372
  def apply_replica(table, options)
341
373
  if replica && cluster && options[:options]
342
- match = options[:options].match(/^(.*?MergeTree)\(([^\)]*)\)(.*?)$/)
374
+ match = options[:options].match(/^(.*?MergeTree)(?:\(([^\)]*)\))?(.*?)$/)
343
375
  if match
344
376
  options[:options] = "Replicated#{match[1]}(#{([replica_path(table), replica].map{|v| "'#{v}'"} + [match[2].presence]).compact.join(', ')})#{match[3]}"
345
377
  end
@@ -1,3 +1,5 @@
1
+ require 'active_record/migration'
2
+
1
3
  module ClickhouseActiverecord
2
4
 
3
5
  class SchemaMigration < ::ActiveRecord::SchemaMigration
@@ -8,7 +10,7 @@ module ClickhouseActiverecord
8
10
  version_options = connection.internal_string_options_for_primary_key
9
11
 
10
12
  connection.create_table(table_name, id: false, options: 'ReplacingMergeTree(ver) PARTITION BY version ORDER BY (version)', if_not_exists: true) do |t|
11
- t.string :version, version_options
13
+ t.string :version, **version_options
12
14
  t.column :active, 'Int8', null: false, default: '1'
13
15
  t.datetime :ver, null: false, default: -> { 'now()' }
14
16
  end
@@ -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
@@ -6,7 +6,7 @@ module ClickhouseActiverecord
6
6
  delegate :connection, :establish_connection, :clear_active_connections!, to: ActiveRecord::Base
7
7
 
8
8
  def initialize(configuration)
9
- @configuration = configuration
9
+ @configuration = configuration.with_indifferent_access
10
10
  end
11
11
 
12
12
  def create
@@ -1,3 +1,3 @@
1
1
  module ClickhouseActiverecord
2
- VERSION = '0.4.12'
2
+ VERSION = '0.5.3'
3
3
  end
@@ -13,7 +13,7 @@ class ClickhouseMigrationGenerator < ActiveRecord::Generators::MigrationGenerato
13
13
 
14
14
  def db_migrate_path
15
15
  if defined?(Rails.application) && Rails.application && respond_to?(:configured_migrate_path, true)
16
- configured_migrate_path
16
+ configured_migrate_path || default_migrate_path
17
17
  else
18
18
  default_migrate_path
19
19
  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.4.12
4
+ version: 0.5.3
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-04-02 00:00:00.000000000 Z
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -112,6 +112,7 @@ files:
112
112
  - bin/console
113
113
  - bin/setup
114
114
  - clickhouse-activerecord.gemspec
115
+ - lib/active_record/connection_adapters/clickhouse/oid/array.rb
115
116
  - lib/active_record/connection_adapters/clickhouse/oid/big_integer.rb
116
117
  - lib/active_record/connection_adapters/clickhouse/oid/date.rb
117
118
  - lib/active_record/connection_adapters/clickhouse/oid/date_time.rb