Skip to content

Commit

Permalink
refactoring final method
Browse files Browse the repository at this point in the history
  • Loading branch information
PNixx committed Jan 22, 2024
1 parent 0d3ed5c commit c91066a
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 144 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ If you using multiple databases, for example: PostgreSQL, Clickhouse.

Schema dump to `db/clickhouse_schema.rb` file:

$ rake clickhouse:schema:dump
$ rake db:schema:dump:clickhouse

Schema load from `db/clickhouse_schema.rb` file:

$ rake clickhouse:schema:load
$ rake db:schema:load:clickhouse

For export schema to PostgreSQL, you need use:

Expand Down Expand Up @@ -238,6 +238,7 @@ Donations to this project are going directly to [PNixx](https://github.com/PNixx
* BTC address: `1H3rhpf7WEF5JmMZ3PVFMQc7Hm29THgUfN`
* ETH address: `0x6F094365A70fe7836A633d2eE80A1FA9758234d5`
* XMR address: `42gP71qLB5M43RuDnrQ3vSJFFxis9Kw9VMURhpx9NLQRRwNvaZRjm2TFojAMC8Fk1BQhZNKyWhoyJSn5Ak9kppgZPjE17Zh`
* TON address: `UQBt0-s1igIpJoEup0B1yAUkZ56rzbpruuAjNhQ26MVCaNlC`

## Development

Expand Down
17 changes: 2 additions & 15 deletions lib/active_record/connection_adapters/clickhouse_adapter.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# frozen_string_literal: true

require 'arel/visitors/clickhouse'
require 'arel/nodes/final'
require 'arel/nodes/settings'
require 'arel/nodes/using'
require 'clickhouse-activerecord/migration'
require 'active_record/connection_adapters/clickhouse/oid/array'
require 'active_record/connection_adapters/clickhouse/oid/date'
require 'active_record/connection_adapters/clickhouse/oid/date_time'
Expand Down Expand Up @@ -64,7 +64,7 @@ def is_view

module ModelSchema
module ClassMethods
delegate :final, :settings, to: :all
delegate :final, :final!, :settings, :settings!, to: :all

def is_view
@is_view || false
Expand Down Expand Up @@ -132,23 +132,10 @@ def initialize(logger, connection_parameters, config, full_config)
connect
end

# Support SchemaMigration from v5.2.2 to v6+
def schema_migration # :nodoc:
ClickhouseActiverecord::SchemaMigration.new(self)
end

def internal_metadata # :nodoc:
ClickhouseActiverecord::InternalMetadata.new(self)
end

def migrations_paths
@full_config[:migrations_paths] || 'db/migrate_clickhouse'
end

def migration_context # :nodoc:
ClickhouseActiverecord::MigrationContext.new(migrations_paths, schema_migration, internal_metadata)
end

def arel_visitor # :nodoc:
Arel::Visitors::Clickhouse.new(self)
end
Expand Down
7 changes: 7 additions & 0 deletions lib/arel/nodes/final.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Arel # :nodoc: all
module Nodes
class Final < Arel::Nodes::Unary
delegate :empty?, to: :expr
end
end
end
12 changes: 6 additions & 6 deletions lib/arel/visitors/clickhouse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ def aggregate(name, o, collector)
end
end

def visit_Arel_Table o, collector
collector = super
collector << ' FINAL' if o.final
collector
end

def visit_Arel_Nodes_SelectOptions(o, collector)
maybe_visit o.settings, super
end
Expand All @@ -34,6 +28,12 @@ def visit_Arel_Nodes_UpdateStatement(o, collector)
maybe_visit o.limit, collector
end

def visit_Arel_Nodes_Final(o, collector)
visit o.expr, collector
collector << ' FINAL'
collector
end

def visit_Arel_Nodes_Settings(o, collector)
return collector if o.expr.empty?

Expand Down
6 changes: 6 additions & 0 deletions lib/clickhouse-activerecord.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

require 'active_record/connection_adapters/clickhouse_adapter'

require 'core_extensions/active_record/internal_metadata'
require 'core_extensions/active_record/relation'
require 'core_extensions/active_record/schema_migration'

require 'core_extensions/arel/nodes/select_core'
require 'core_extensions/arel/nodes/select_statement'
require 'core_extensions/arel/select_manager'
require 'core_extensions/arel/table'
Expand All @@ -21,8 +24,11 @@

module ClickhouseActiverecord
def self.load
ActiveRecord::InternalMetadata.singleton_class.prepend(CoreExtensions::ActiveRecord::InternalMetadata::ClassMethods)
ActiveRecord::Relation.prepend(CoreExtensions::ActiveRecord::Relation)
ActiveRecord::SchemaMigration.singleton_class.prepend(CoreExtensions::ActiveRecord::SchemaMigration::ClassMethods)

Arel::Nodes::SelectCore.prepend(CoreExtensions::Arel::Nodes::SelectCore)
Arel::Nodes::SelectStatement.prepend(CoreExtensions::Arel::Nodes::SelectStatement)
Arel::SelectManager.prepend(CoreExtensions::Arel::SelectManager)
Arel::Table.prepend(CoreExtensions::Arel::Table)
Expand Down
103 changes: 0 additions & 103 deletions lib/clickhouse-activerecord/migration.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/clickhouse-activerecord/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ClickhouseActiverecord
VERSION = '1.0.2'
VERSION = '1.0.3'
end
46 changes: 46 additions & 0 deletions lib/core_extensions/active_record/internal_metadata.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module CoreExtensions
module ActiveRecord
module InternalMetadata
module ClassMethods

def []=(key, value)
row = final.find_by(key: key)
if row.nil? || row.value != value
create!(key: key, value: value)
end
end

def [](key)
final.where(key: key).pluck(:value).first
end

def create_table
return super unless connection.is_a?(::ActiveRecord::ConnectionAdapters::ClickhouseAdapter)
return if table_exists? || !enabled?

key_options = connection.internal_string_options_for_primary_key
table_options = {
id: false,
options: connection.adapter_name.downcase == 'clickhouse' ? 'ReplacingMergeTree(created_at) PARTITION BY key ORDER BY key' : '',
if_not_exists: true
}
full_config = connection.instance_variable_get(:@full_config) || {}

if full_config[:distributed_service_tables]
table_options.merge!(with_distributed: table_name, sharding_key: 'cityHash64(created_at)')

distributed_suffix = "_#{full_config[:distributed_service_tables_suffix] || 'distributed'}"
else
distributed_suffix = ''
end

connection.create_table(table_name + distributed_suffix.to_s, **table_options) do |t|
t.string :key, **key_options
t.string :value
t.timestamps
end
end
end
end
end
end
12 changes: 5 additions & 7 deletions lib/core_extensions/active_record/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,14 @@ def settings!(**opts)
# # SELECT users.* FROM users FINAL
#
# An <tt>ActiveRecord::ActiveRecordError</tt> will be raised if database not ClickHouse.
# @param [Boolean] final
def final(final = true)
spawn.final!(final)
def final
spawn.final!
end

# @param [Boolean] final
def final!(final = true)
def final!
assert_mutability!
check_command('FINAL')
@table = @table.dup
@table.final = final
@values[:final] = true
self
end

Expand Down Expand Up @@ -79,6 +76,7 @@ def check_command(cmd)
def build_arel(aliases = nil)
arel = super

arel.final! if @values[:final].present?
arel.settings(@values[:settings]) if @values[:settings].present?
arel.using(@values[:using]) if @values[:using].present?

Expand Down
48 changes: 48 additions & 0 deletions lib/core_extensions/active_record/schema_migration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module CoreExtensions
module ActiveRecord
module SchemaMigration
module ClassMethods

def create_table
return super unless connection.is_a?(::ActiveRecord::ConnectionAdapters::ClickhouseAdapter)

return if table_exists?

version_options = connection.internal_string_options_for_primary_key
table_options = {
id: false, options: 'ReplacingMergeTree(ver) ORDER BY (version)', if_not_exists: true
}
full_config = connection.instance_variable_get(:@full_config) || {}

if full_config[:distributed_service_tables]
table_options.merge!(with_distributed: table_name, sharding_key: 'cityHash64(version)')

distributed_suffix = "_#{full_config[:distributed_service_tables_suffix] || 'distributed'}"
else
distributed_suffix = ''
end

connection.create_table(table_name + distributed_suffix.to_s, **table_options) do |t|
t.string :version, **version_options
t.column :active, 'Int8', null: false, default: '1'
t.datetime :ver, null: false, default: -> { 'now()' }
end
end

def delete_version(version)
return super unless connection.is_a?(::ActiveRecord::ConnectionAdapters::ClickhouseAdapter)

im = Arel::InsertManager.new(arel_table)
im.insert(arel_table[primary_key] => version.to_s, arel_table['active'] => 0)
connection.insert(im, "#{self.class} Create Rollback Version", primary_key, version)
end

def all_versions
return super unless connection.is_a?(::ActiveRecord::ConnectionAdapters::ClickhouseAdapter)

final.where(active: 1).order(:version).pluck(:version)
end
end
end
end
end
19 changes: 19 additions & 0 deletions lib/core_extensions/arel/nodes/select_core.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module CoreExtensions
module Arel # :nodoc: all
module Nodes
module SelectCore
attr_accessor :final

def source
return super unless final

::Arel::Nodes::Final.new(super)
end

def eql?(other)
super && final == other.final
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/core_extensions/arel/select_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ module CoreExtensions
module Arel
module SelectManager

def final!
@ctx.final = true
self
end

# @param [Hash] values
def settings(values)
@ast.settings = ::Arel::Nodes::Settings.new(values)
Expand Down
2 changes: 0 additions & 2 deletions lib/core_extensions/arel/table.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
module CoreExtensions
module Arel
module Table
attr_accessor :final

def is_view
type_caster.is_view
end
Expand Down
Loading

0 comments on commit c91066a

Please sign in to comment.