clickhouse-activerecord 0.4.11 → 0.5.2

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: d8d1d60f75e0f889dc5d947df77924f1490c0325f097d634048fb25405eeca70
4
- data.tar.gz: 309eda1c3f605682c04525fce8633b85a73a38643e367f33d87588939f7815fe
3
+ metadata.gz: c75ca45e5f91a7d83d79b8583539e66021589fc76c7ce48a68f07f49176a6f5a
4
+ data.tar.gz: 282fba24c4ecacdb11e4d358db15ba88beb0457099f3b9efe22d6c873676ead8
5
5
  SHA512:
6
- metadata.gz: 5727f1a23c48e04db1052bfbf4c56af412338be88f4b985ed6700e9a833436bcde893ba9cb1ed7b89473dae95b31e4b70de26c6885cce10b8fffcdb9c65fbb3d
7
- data.tar.gz: 18fad92b704c1c41b97029facbc020111c3b067cbb825d6e5c4d11d6a4b7a220873b922aea7112ec741f1d87a1a5c2217a11047e764959a2edffb98e0b7f2463
6
+ metadata.gz: 69b20ad39aced0dc3ba4f6883664dabdba45c8c677848010b1dd926e26de36a707839cbc5d806e59f0bc73a786daeee6c3448681313de0f973d93faa16f63a5d
7
+ data.tar.gz: cf195bf822304c31f3cd5121f3ca5ea0f5d5fc1b0211862e1cde9ffae32042960ad512a9c10a3a17d146205308aefdfcc09f5de95b07bab952baa9cffab4b60c
data/README.md CHANGED
@@ -35,6 +35,21 @@ default: &default
35
35
  replica_name: '{replica}' # replica macros name, optional for creating replicated tables
36
36
  ```
37
37
 
38
+ Alternatively if you wish to pass a custom `Net::HTTP` transport (or any other
39
+ object which supports a `.post()` function with the same parameters as
40
+ `Net::HTTP`'s), you can do this directly instead of specifying
41
+ `host`/`port`/`ssl`:
42
+
43
+ ```ruby
44
+ class ActionView < ActiveRecord::Base
45
+ establish_connection(
46
+ adapter: 'clickhouse',
47
+ database: 'database',
48
+ connection: Net::HTTP.start('http://example.org', 8123)
49
+ )
50
+ end
51
+ ```
52
+
38
53
  ## Usage in Rails 5
39
54
 
40
55
  Add your `database.yml` connection information with postfix `_clickhouse` for you environment:
@@ -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
@@ -17,8 +17,15 @@ module ActiveRecord
17
17
  def exec_query(sql, name = nil, binds = [], prepare: false)
18
18
  result = do_execute(sql, name)
19
19
  ActiveRecord::Result.new(result['meta'].map { |m| m['name'] }, result['data'])
20
- rescue StandardError => _e
21
- raise ActiveRecord::ActiveRecordError, "Response: #{result}"
20
+ rescue ActiveRecord::ActiveRecordError => e
21
+ raise e
22
+ rescue StandardError => e
23
+ raise ActiveRecord::ActiveRecordError, "Response: #{e.message}"
24
+ end
25
+
26
+ def exec_insert_all(sql, name)
27
+ do_execute(sql, name, format: nil)
28
+ true
22
29
  end
23
30
 
24
31
  def exec_update(_sql, _name = nil, _binds = [])
@@ -114,8 +121,8 @@ module ActiveRecord
114
121
  Clickhouse::SchemaCreation.new(self)
115
122
  end
116
123
 
117
- def create_table_definition(*args)
118
- Clickhouse::TableDefinition.new(self, *args)
124
+ def create_table_definition(table_name, **options)
125
+ Clickhouse::TableDefinition.new(self, table_name, **options)
119
126
  end
120
127
 
121
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,9 +18,22 @@ 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
20
- host = config[:host] || 'localhost'
21
- port = config[:port] || 8123
22
- ssl = config[:ssl].present? ? config[:ssl] : port == 443
21
+
22
+ if config[:connection]
23
+ connection = {
24
+ connection: config[:connection]
25
+ }
26
+ else
27
+ port = config[:port] || 8123
28
+ connection = {
29
+ host: config[:host] || 'localhost',
30
+ port: port,
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],
35
+ }
36
+ end
23
37
 
24
38
  if config.key?(:database)
25
39
  database = config[:database]
@@ -27,7 +41,7 @@ module ActiveRecord
27
41
  raise ArgumentError, 'No database specified. Missing argument: database.'
28
42
  end
29
43
 
30
- ConnectionAdapters::ClickhouseAdapter.new(logger, [host, port, ssl], { user: config[:username], password: config[:password], database: database }.compact, config)
44
+ ConnectionAdapters::ClickhouseAdapter.new(logger, connection, { user: config[:username], password: config[:password], database: database }.compact, config)
31
45
  end
32
46
  end
33
47
  end
@@ -50,7 +64,11 @@ module ActiveRecord
50
64
  module TypeCaster
51
65
  class Map
52
66
  def is_view
53
- 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
54
72
  end
55
73
  end
56
74
  end
@@ -177,12 +195,16 @@ module ActiveRecord
177
195
  register_class_with_limit m, %r(Int128), Type::Integer
178
196
  register_class_with_limit m, %r(Int256), Type::Integer
179
197
 
180
- register_class_with_limit m, %r(Uint8), Type::UnsignedInteger
198
+ register_class_with_limit m, %r(UInt8), Type::UnsignedInteger
181
199
  register_class_with_limit m, %r(UInt16), Type::UnsignedInteger
182
200
  register_class_with_limit m, %r(UInt32), Type::UnsignedInteger
183
201
  register_class_with_limit m, %r(UInt64), Type::UnsignedInteger
184
202
  #register_class_with_limit m, %r(UInt128), Type::UnsignedInteger #not implemnted in clickhouse
185
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
186
208
  end
187
209
 
188
210
  # Quoting time without microseconds
@@ -310,6 +332,19 @@ module ActiveRecord
310
332
  cluster ? "#{sql} ON CLUSTER #{cluster}" : sql
311
333
  end
312
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
+
313
348
  protected
314
349
 
315
350
  def last_inserted_id(result)
@@ -325,7 +360,13 @@ module ActiveRecord
325
360
  private
326
361
 
327
362
  def connect
328
- @connection = Net::HTTP.start(@connection_parameters[0], @connection_parameters[1], use_ssl: @connection_parameters[2], verify_mode: OpenSSL::SSL::VERIFY_NONE)
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
329
370
  end
330
371
 
331
372
  def apply_replica(table, options)
@@ -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.11'
2
+ VERSION = '0.5.2'
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.11
4
+ version: 0.5.2
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-03-23 00:00:00.000000000 Z
11
+ date: 2021-08-04 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
@@ -134,7 +135,7 @@ homepage: https://github.com/pnixx/clickhouse-activerecord
134
135
  licenses:
135
136
  - MIT
136
137
  metadata: {}
137
- post_install_message:
138
+ post_install_message:
138
139
  rdoc_options: []
139
140
  require_paths:
140
141
  - lib
@@ -149,8 +150,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
150
  - !ruby/object:Gem::Version
150
151
  version: '0'
151
152
  requirements: []
152
- rubygems_version: 3.0.3
153
- signing_key:
153
+ rubygems_version: 3.0.4
154
+ signing_key:
154
155
  specification_version: 4
155
156
  summary: ClickHouse ActiveRecord
156
157
  test_files: []