clickhouse-activerecord 0.6.0 → 0.6.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: 182d838abbda9972bdfa59b1e6a76af247bd4e3b275a5e611dfe6cd8ceaaea5c
4
- data.tar.gz: f987ee429692c24518a0ea54d24f52c65f96ddfe1e6d6770fe0c2dd4549c623e
3
+ metadata.gz: 6533de4ab9b2415a4df22e72e7ef551d4fb58c5bdc6713ec355b85dbad1174fd
4
+ data.tar.gz: 1c0a898f494c6dc7511897617ea86c2f12aa42461cf693e28e78124bde3638c6
5
5
  SHA512:
6
- metadata.gz: 90aac52260cd39eaa23dddb9be9290afa8ccb6731f4c84b6403d67fc56ddf1e24d075e9e33d9cc99ffdf29309608b0a8ae78a35db87d673731438dd5db50c57b
7
- data.tar.gz: 505c299c7f657deb7b0685504c0f61754b801d0900238fa9a00a939b49873e379e2d2c84f9ce3661e0c26d405b9e94a31cbeb71c514f644cf4391059df44fa22
6
+ metadata.gz: f6c5c2eba18dce09211cc6b8e5448aaaf2c40ca3eb5cc411aa76874ad6efc00ae257880e5997256808d02771aec7947559edfca941187c219b6724f09b9488f0
7
+ data.tar.gz: 7b7e5f520c4189b4b5a1587789d0ea2ef8b74e86c077611ac18515c45105306c6e17cfd824623ab574420beeb45d205a9f301e2db9f3befd3c3b92c4d303b978
data/README.md CHANGED
@@ -183,6 +183,10 @@ Action.where(date: Date.current).final.limit(10)
183
183
  Action.settings(optimize_read_in_order: 1).where(date: Date.current).limit(10)
184
184
  # Clickhouse Action Load (10.3ms) SELECT actions.* FROM actions FINAL WHERE actions.date = '2017-11-29' LIMIT 10 SETTINGS optimize_read_in_order = 1
185
185
  #=> #<ActiveRecord::Relation [#<Action *** >]>
186
+
187
+ User.joins(:actions).using(:group_id)
188
+ # Clickhouse User Load (10.3ms) SELECT users.* FROM users INNER JOIN actions USING group_id
189
+ #=> #<ActiveRecord::Relation [#<Action *** >]>
186
190
  ```
187
191
 
188
192
 
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ['lib']
25
25
 
26
26
  spec.add_runtime_dependency 'bundler', '>= 1.13.4'
27
- spec.add_runtime_dependency 'activerecord', '>= 5.2'
27
+ spec.add_runtime_dependency 'activerecord', '~> 7.0.0'
28
28
 
29
29
  spec.add_development_dependency 'rake', '~> 13.0'
30
30
  spec.add_development_dependency 'rspec', '~> 3.4'
@@ -125,7 +125,7 @@ module ActiveRecord
125
125
  end
126
126
 
127
127
  def current_database
128
- if ActiveRecord::version >= Gem::Version.new('6')
128
+ if ActiveRecord::version >= Gem::Version.new('6.1')
129
129
  ActiveRecord::Base.connection_db_config.database
130
130
  else
131
131
  ActiveRecord::Base.connection_config[:database]
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'arel/visitors/clickhouse'
4
4
  require 'arel/nodes/settings'
5
+ require 'arel/nodes/using'
5
6
  require 'clickhouse-activerecord/migration'
6
7
  require 'active_record/connection_adapters/clickhouse/oid/array'
7
8
  require 'active_record/connection_adapters/clickhouse/oid/date'
@@ -158,66 +159,73 @@ module ActiveRecord
158
159
  !native_database_types[type].nil?
159
160
  end
160
161
 
161
- def extract_limit(sql_type) # :nodoc:
162
- case sql_type
163
- when /(Nullable)?\(?String\)?/
164
- super('String')
165
- when /(Nullable)?\(?U?Int8\)?/
166
- 1
167
- when /(Nullable)?\(?U?Int16\)?/
168
- 2
169
- when /(Nullable)?\(?U?Int32\)?/
170
- nil
171
- when /(Nullable)?\(?U?Int64\)?/
172
- 8
173
- else
174
- super
162
+ class << self
163
+ def extract_limit(sql_type) # :nodoc:
164
+ case sql_type
165
+ when /(Nullable)?\(?String\)?/
166
+ super('String')
167
+ when /(Nullable)?\(?U?Int8\)?/
168
+ 1
169
+ when /(Nullable)?\(?U?Int16\)?/
170
+ 2
171
+ when /(Nullable)?\(?U?Int32\)?/
172
+ nil
173
+ when /(Nullable)?\(?U?Int64\)?/
174
+ 8
175
+ else
176
+ super
177
+ end
175
178
  end
176
- end
177
179
 
178
- # `extract_scale` and `extract_precision` are the same as in the Rails abstract base class,
179
- # except this permits a space after the comma
180
+ # `extract_scale` and `extract_precision` are the same as in the Rails abstract base class,
181
+ # except this permits a space after the comma
180
182
 
181
- def extract_scale(sql_type)
182
- case sql_type
183
- when /\((\d+)\)/ then 0
184
- when /\((\d+)(,\s?(\d+))\)/ then $3.to_i
183
+ def extract_scale(sql_type)
184
+ case sql_type
185
+ when /\((\d+)\)/ then 0
186
+ when /\((\d+)(,\s?(\d+))\)/ then $3.to_i
187
+ end
188
+ end
189
+
190
+ def extract_precision(sql_type)
191
+ $1.to_i if sql_type =~ /\((\d+)(,\s?\d+)?\)/
185
192
  end
186
- end
187
193
 
188
- def extract_precision(sql_type)
189
- $1.to_i if sql_type =~ /\((\d+)(,\s?\d+)?\)/
190
- end
191
-
192
- def initialize_type_map(m) # :nodoc:
193
- super
194
- register_class_with_limit m, %r(String), Type::String
195
- register_class_with_limit m, 'Date', Clickhouse::OID::Date
196
- register_class_with_precision m, %r(datetime)i, Clickhouse::OID::DateTime
197
-
198
- register_class_with_limit m, %r(Int8), Type::Integer
199
- register_class_with_limit m, %r(Int16), Type::Integer
200
- register_class_with_limit m, %r(Int32), Type::Integer
201
- register_class_with_limit m, %r(Int64), Type::Integer
202
- register_class_with_limit m, %r(Int128), Type::Integer
203
- register_class_with_limit m, %r(Int256), Type::Integer
204
-
205
- register_class_with_limit m, %r(UInt8), Type::UnsignedInteger
206
- register_class_with_limit m, %r(UInt16), Type::UnsignedInteger
207
- register_class_with_limit m, %r(UInt32), Type::UnsignedInteger
208
- register_class_with_limit m, %r(UInt64), Type::UnsignedInteger
209
- #register_class_with_limit m, %r(UInt128), Type::UnsignedInteger #not implemnted in clickhouse
210
- register_class_with_limit m, %r(UInt256), Type::UnsignedInteger
211
- # register_class_with_limit m, %r(Array), Clickhouse::OID::Array
212
- m.register_type(%r(Array)) do |sql_type|
213
- Clickhouse::OID::Array.new(sql_type)
194
+ def initialize_type_map(m) # :nodoc:
195
+ super
196
+ register_class_with_limit m, %r(String), Type::String
197
+ register_class_with_limit m, 'Date', Clickhouse::OID::Date
198
+ register_class_with_precision m, %r(datetime)i, Clickhouse::OID::DateTime
199
+
200
+ register_class_with_limit m, %r(Int8), Type::Integer
201
+ register_class_with_limit m, %r(Int16), Type::Integer
202
+ register_class_with_limit m, %r(Int32), Type::Integer
203
+ register_class_with_limit m, %r(Int64), Type::Integer
204
+ register_class_with_limit m, %r(Int128), Type::Integer
205
+ register_class_with_limit m, %r(Int256), Type::Integer
206
+
207
+ register_class_with_limit m, %r(UInt8), Type::UnsignedInteger
208
+ register_class_with_limit m, %r(UInt16), Type::UnsignedInteger
209
+ register_class_with_limit m, %r(UInt32), Type::UnsignedInteger
210
+ register_class_with_limit m, %r(UInt64), Type::UnsignedInteger
211
+ #register_class_with_limit m, %r(UInt128), Type::UnsignedInteger #not implemnted in clickhouse
212
+ register_class_with_limit m, %r(UInt256), Type::UnsignedInteger
213
+ # register_class_with_limit m, %r(Array), Clickhouse::OID::Array
214
+ m.register_type(%r(Array)) do |sql_type|
215
+ Clickhouse::OID::Array.new(sql_type)
216
+ end
214
217
  end
215
218
  end
216
219
 
217
- def _quote(value)
220
+ # In Rails 7 used constant TYPE_MAP, we need redefine method
221
+ def type_map
222
+ @type_map ||= Type::TypeMap.new.tap { |m| ClickhouseAdapter.initialize_type_map(m) }
223
+ end
224
+
225
+ def quote(value)
218
226
  case value
219
227
  when Array
220
- '[' + value.map { |v| _quote(v) }.join(', ') + ']'
228
+ '[' + value.map { |v| quote(v) }.join(', ') + ']'
221
229
  else
222
230
  super
223
231
  end
@@ -333,7 +341,13 @@ module ActiveRecord
333
341
  end
334
342
 
335
343
  def drop_table(table_name, options = {}) # :nodoc:
336
- do_execute apply_cluster "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
344
+ query = "DROP TABLE"
345
+ query = "#{query} IF EXISTS " if options[:if_exists]
346
+ query = "#{query} #{quote_table_name(table_name)}"
347
+ query = apply_cluster(query)
348
+ query = "#{query} SYNC" if options[:sync]
349
+
350
+ do_execute(query)
337
351
 
338
352
  if options[:with_distributed]
339
353
  distributed_table_name = options.delete(:with_distributed)
@@ -0,0 +1,6 @@
1
+ module Arel # :nodoc: all
2
+ module Nodes
3
+ class Using < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
@@ -36,6 +36,12 @@ module Arel
36
36
  collector
37
37
  end
38
38
 
39
+ def visit_Arel_Nodes_Using o, collector
40
+ collector << "USING "
41
+ visit o.expr, collector
42
+ collector
43
+ end
44
+
39
45
  def sanitize_as_setting_value(value)
40
46
  if value == :default
41
47
  'DEFAULT'
@@ -2,7 +2,6 @@
2
2
 
3
3
  module ClickhouseActiverecord
4
4
  class Tasks
5
-
6
5
  delegate :connection, :establish_connection, :clear_active_connections!, to: ActiveRecord::Base
7
6
 
8
7
  def initialize(configuration)
@@ -11,7 +10,7 @@ module ClickhouseActiverecord
11
10
 
12
11
  def create
13
12
  establish_master_connection
14
- connection.create_database @configuration["database"]
13
+ connection.create_database @configuration['database']
15
14
  rescue ActiveRecord::StatementInvalid => e
16
15
  if e.cause.to_s.include?('already exists')
17
16
  raise ActiveRecord::DatabaseAlreadyExists
@@ -22,7 +21,7 @@ module ClickhouseActiverecord
22
21
 
23
22
  def drop
24
23
  establish_master_connection
25
- connection.drop_database @configuration["database"]
24
+ connection.drop_database @configuration['database']
26
25
  end
27
26
 
28
27
  def purge
@@ -1,3 +1,3 @@
1
1
  module ClickhouseActiverecord
2
- VERSION = '0.6.0'
2
+ VERSION = '0.6.2'
3
3
  end
@@ -4,7 +4,7 @@ module CoreExtensions
4
4
  module SelectStatement
5
5
  attr_accessor :settings
6
6
 
7
- def initialize
7
+ def initialize(relation = nil)
8
8
  super
9
9
  @settings = nil
10
10
  end
@@ -7,6 +7,11 @@ module CoreExtensions
7
7
  @ast.settings = ::Arel::Nodes::Settings.new(values)
8
8
  self
9
9
  end
10
+
11
+ def using(*exprs)
12
+ @ctx.source.right.last.right = ::Arel::Nodes::Using.new(::Arel.sql(exprs.join(',')))
13
+ self
14
+ end
10
15
  end
11
16
  end
12
17
  end
@@ -1,68 +1,70 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :clickhouse do
4
-
5
4
  task prepare_schema_migration_table: :environment do
6
- ClickhouseActiverecord::SchemaMigration.create_table unless ENV['simple'] || ARGV.map{|a| a.include?('--simple') ? true : nil}.compact.any?
5
+ ClickhouseActiverecord::SchemaMigration.create_table unless ENV['simple'] || ARGV.any? { |a| a.include?('--simple') }
7
6
  end
8
7
 
9
8
  task prepare_internal_metadata_table: :environment do
10
- ClickhouseActiverecord::InternalMetadata.create_table unless ENV['simple'] || ARGV.map{|a| a.include?('--simple') ? true : nil}.compact.any?
9
+ ClickhouseActiverecord::InternalMetadata.create_table unless ENV['simple'] || ARGV.any? { |a| a.include?('--simple') }
11
10
  end
12
11
 
13
12
  task load_config: :environment do
14
- ENV['SCHEMA'] = "db/clickhouse_schema.rb"
15
- ActiveRecord::Migrator.migrations_paths = ["db/migrate_clickhouse"]
16
- ActiveRecord::Base.establish_connection(:"#{Rails.env}_clickhouse")
13
+ ENV['SCHEMA'] = 'db/clickhouse_schema.rb'
14
+ ActiveRecord::Migrator.migrations_paths = %w[db/migrate_clickhouse]
15
+ ActiveRecord::Base.establish_connection(:clickhouse)
17
16
  end
18
17
 
19
18
  namespace :schema do
20
-
21
- # todo not testing
19
+ # TODO: not testing
22
20
  desc 'Load database schema'
23
- task load: [:load_config, :prepare_internal_metadata_table] do |t, args|
24
- simple = ENV['simple'] || ARGV.map{|a| a.include?('--simple') ? true : nil}.compact.any? ? '_simple' : nil
21
+ task load: %i[load_config prepare_internal_metadata_table] do
22
+ simple = ENV['simple'] || ARGV.any? { |a| a.include?('--simple') } ? '_simple' : nil
25
23
  ClickhouseActiverecord::SchemaMigration.drop_table
26
- load("#{Rails.root}/db/clickhouse_schema#{simple}.rb")
24
+ load(Rails.root.join("db/clickhouse_schema#{simple}.rb"))
27
25
  end
28
26
 
29
27
  desc 'Dump database schema'
30
- task dump: :environment do |t, args|
31
- simple = ENV['simple'] || args[:simple] || ARGV.map{|a| a.include?('--simple') ? true : nil}.compact.any? ? '_simple' : nil
32
- filename = "#{Rails.root}/db/clickhouse_schema#{simple}.rb"
28
+ task dump: :environment do |_, args|
29
+ simple = ENV['simple'] || args[:simple] || ARGV.any? { |a| a.include?('--simple') } ? '_simple' : nil
30
+ filename = Rails.root.join("db/clickhouse_schema#{simple}.rb")
33
31
  File.open(filename, 'w:utf-8') do |file|
34
- ActiveRecord::Base.establish_connection(:"#{Rails.env}_clickhouse")
35
- ClickhouseActiverecord::SchemaDumper.dump(ActiveRecord::Base.connection, file, ActiveRecord::Base, !!simple)
32
+ ActiveRecord::Base.establish_connection(:clickhouse)
33
+ ClickhouseActiverecord::SchemaDumper.dump(ActiveRecord::Base.connection, file, ActiveRecord::Base, simple.present?)
36
34
  end
37
35
  end
38
-
39
36
  end
40
37
 
41
38
  namespace :structure do
42
39
  desc 'Load database structure'
43
40
  task load: [:load_config, 'db:check_protected_environments'] do
44
- ClickhouseActiverecord::Tasks.new(ActiveRecord::Base.configurations["#{Rails.env}_clickhouse"]).structure_load("#{Rails.root}/db/clickhouse_structure.sql")
41
+ config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'clickhouse')
42
+ ClickhouseActiverecord::Tasks.new(config).structure_load(Rails.root.join('db/clickhouse_structure.sql'))
45
43
  end
46
44
 
47
45
  desc 'Dump database structure'
48
46
  task dump: [:load_config, 'db:check_protected_environments'] do
49
- ClickhouseActiverecord::Tasks.new(ActiveRecord::Base.configurations["#{Rails.env}_clickhouse"]).structure_dump("#{Rails.root}/db/clickhouse_structure.sql")
47
+ config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'clickhouse')
48
+ ClickhouseActiverecord::Tasks.new(config).structure_dump(Rails.root.join('db/clickhouse_structure.sql'))
50
49
  end
51
50
  end
52
51
 
53
52
  desc 'Creates the database from DATABASE_URL or config/database.yml'
54
53
  task create: [:load_config] do
55
- ActiveRecord::Tasks::DatabaseTasks.create(ActiveRecord::Base.configurations["#{Rails.env}_clickhouse"])
54
+ config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'clickhouse')
55
+ ActiveRecord::Tasks::DatabaseTasks.create(config)
56
56
  end
57
57
 
58
58
  desc 'Drops the database from DATABASE_URL or config/database.yml'
59
59
  task drop: [:load_config, 'db:check_protected_environments'] do
60
- ActiveRecord::Tasks::DatabaseTasks.drop(ActiveRecord::Base.configurations["#{Rails.env}_clickhouse"])
60
+ config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'clickhouse')
61
+ ActiveRecord::Tasks::DatabaseTasks.drop(config)
61
62
  end
62
63
 
63
64
  desc 'Empty the database from DATABASE_URL or config/database.yml'
64
65
  task purge: [:load_config, 'db:check_protected_environments'] do
65
- ActiveRecord::Tasks::DatabaseTasks.purge(ActiveRecord::Base.configurations["#{Rails.env}_clickhouse"])
66
+ config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'clickhouse')
67
+ ActiveRecord::Tasks::DatabaseTasks.purge(config)
66
68
  end
67
69
 
68
70
  # desc 'Resets your database using your migrations for the current environment'
@@ -72,7 +74,7 @@ namespace :clickhouse do
72
74
  end
73
75
 
74
76
  desc 'Migrate the clickhouse database'
75
- task migrate: [:load_config, :prepare_schema_migration_table, :prepare_internal_metadata_table] do
77
+ task migrate: %i[load_config prepare_schema_migration_table prepare_internal_metadata_table] do
76
78
  Rake::Task['db:migrate'].execute
77
79
  if File.exists? "#{Rails.root}/db/clickhouse_schema_simple.rb"
78
80
  Rake::Task['clickhouse:schema:dump'].execute(simple: true)
@@ -80,7 +82,7 @@ namespace :clickhouse do
80
82
  end
81
83
 
82
84
  desc 'Rollback the clickhouse database'
83
- task rollback: [:load_config, :prepare_schema_migration_table, :prepare_internal_metadata_table] do
85
+ task rollback: %i[load_config prepare_schema_migration_table prepare_internal_metadata_table] do
84
86
  Rake::Task['db:rollback'].execute
85
87
  end
86
88
  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.6.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Odintsov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-19 00:00:00.000000000 Z
11
+ date: 2023-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.2'
33
+ version: 7.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '5.2'
40
+ version: 7.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,7 @@ files:
108
108
  - lib/active_record/connection_adapters/clickhouse/schema_statements.rb
109
109
  - lib/active_record/connection_adapters/clickhouse_adapter.rb
110
110
  - lib/arel/nodes/settings.rb
111
+ - lib/arel/nodes/using.rb
111
112
  - lib/arel/visitors/clickhouse.rb
112
113
  - lib/clickhouse-activerecord.rb
113
114
  - lib/clickhouse-activerecord/migration.rb