Module: ActiveRecord::ConnectionAdapters::Clickhouse::SchemaStatements

Included in:
ActiveRecord::ConnectionAdapters::ClickhouseAdapter
Defined in:
lib/active_record/connection_adapters/clickhouse/schema_statements.rb

Constant Summary collapse

DEFAULT_RESPONSE_FORMAT =
'JSONCompactEachRowWithNamesAndTypes'.freeze

Instance Method Summary collapse

Instance Method Details

#add_index_options(table_name, expression, **options) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 93

def add_index_options(table_name, expression, **options)
  options.assert_valid_keys(:name, :type, :granularity, :first, :after, :if_not_exists, :if_exists)

  validate_index_length!(table_name, options[:name])

  IndexDefinition.new(table_name, options[:name], expression, options[:type], options[:granularity], first: options[:first], after: options[:after], if_not_exists: options[:if_not_exists], if_exists: options[:if_exists])
end

#assume_migrated_upto_version(version, migrations_paths = nil) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 133

def assume_migrated_upto_version(version, migrations_paths = nil)
  version = version.to_i
  sm_table = quote_table_name(schema_migration.table_name)

  migrated = migration_context.get_all_versions
  versions = migration_context.migrations.map(&:version)

  unless migrated.include?(version)
    exec_insert "INSERT INTO #{sm_table} (version) VALUES (#{quote(version.to_s)})", nil, nil
  end

  inserting = (versions - migrated).select { |v| v < version }
  if inserting.any?
    if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
      raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
    end
    do_execute(insert_versions_sql(inserting), nil, format: nil, settings: {max_partitions_per_insert_block: [100, inserting.size].max})
  end
end

#data_sourcesObject



101
102
103
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 101

def data_sources
  tables
end

#do_execute(sql, name = nil, format: DEFAULT_RESPONSE_FORMAT, settings: {}) ⇒ Object



112
113
114
115
116
117
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 112

def do_execute(sql, name = nil, format: DEFAULT_RESPONSE_FORMAT, settings: {})
  log(sql, "#{adapter_name} #{name}") do
    res = request(sql, format, settings)
    process_response(res, format, sql)
  end
end

#do_system_execute(sql, name = nil) ⇒ Object



105
106
107
108
109
110
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 105

def do_system_execute(sql, name = nil)
  log_with_debug(sql, "#{adapter_name} #{name}") do
    res = request(sql, DEFAULT_RESPONSE_FORMAT)
    process_response(res, DEFAULT_RESPONSE_FORMAT, sql)
  end
end

#exec_delete(_sql, _name = nil, _binds = []) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 49

def exec_delete(_sql, _name = nil, _binds = [])
  log(_sql, "#{adapter_name} #{_name}") do
    res = request(_sql)
    begin
      data = JSON.parse(res.header['x-clickhouse-summary'])
      data['result_rows'].to_i
    rescue JSONError
      0
    end
  end
end

#exec_insert(sql, name, _binds, _pk = nil, _sequence_name = nil, returning: nil) ⇒ Object



15
16
17
18
19
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 15

def exec_insert(sql, name, _binds, _pk = nil, _sequence_name = nil, returning: nil)
  new_sql = sql.dup.sub(/ (DEFAULT )?VALUES/, " VALUES")
  do_execute(new_sql, name, format: nil)
  true
end

#exec_insert_all(sql, name) ⇒ Object



37
38
39
40
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 37

def exec_insert_all(sql, name)
  do_execute(sql, name, format: nil)
  true
end

#exec_update(_sql, _name = nil, _binds = []) ⇒ Object



43
44
45
46
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 43

def exec_update(_sql, _name = nil, _binds = [])
  do_execute(_sql, _name, format: nil)
  0
end

#execute(sql, name = nil, settings: {}) ⇒ Object



11
12
13
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 11

def execute(sql, name = nil, settings: {})
  do_execute(sql, name, settings: settings)
end

#functionsObject



73
74
75
76
77
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 73

def functions
  result = do_system_execute("SELECT name FROM system.functions WHERE origin = 'SQLUserDefined'")
  return [] if result.nil?
  result['data'].flatten
end

#indexes(table_name, name = nil) ⇒ Object

Not indexes on clickhouse



89
90
91
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 89

def indexes(table_name, name = nil)
  []
end

#internal_exec_query(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 21

def internal_exec_query(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false)
  result = do_execute(sql, name)
  columns = result['meta'].map { |m| m['name'] }
  types = {}
  result['meta'].each_with_index do |m, i|
    # need use column name and index after commit in 7.2:
    # https://github.com/rails/rails/commit/24dbf7637b1d5cd6eb3d7100b8d0f6872c3fee3c
    types[m['name']] = types[i] = type_map.lookup(m['type'])
  end
  ActiveRecord::Result.new(columns, result['data'], types)
rescue ActiveRecord::ActiveRecordError => e
  raise e
rescue StandardError => e
  raise ActiveRecord::ActiveRecordError, "Response: #{e.message}"
end

#internal_metadataObject



128
129
130
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 128

def 
  pool.
end

#migration_contextObject



124
125
126
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 124

def migration_context
  pool.migration_context
end

#schema_migrationObject



120
121
122
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 120

def schema_migration
  pool.schema_migration
end

#show_create_function(function) ⇒ Object



79
80
81
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 79

def show_create_function(function)
  do_execute("SELECT create_query FROM system.functions WHERE origin = 'SQLUserDefined' AND name = '#{function}'", format: nil)
end

#table_options(table) ⇒ Object



83
84
85
86
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 83

def table_options(table)
  sql = show_create_table(table)
  { options: sql.gsub(/^(?:.*?)(?:ENGINE = (.*?))?( AS SELECT .*?)?$/, '\\1').presence, as: sql.match(/^CREATE (?:.*?) AS (SELECT .*?)$/).try(:[], 1) }.compact
end

#tables(name = nil) ⇒ Object



61
62
63
64
65
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 61

def tables(name = nil)
  result = do_system_execute("SHOW TABLES WHERE name NOT LIKE '.inner_id.%'", name)
  return [] if result.nil?
  result['data'].flatten
end

#views(name = nil) ⇒ Object



67
68
69
70
71
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 67

def views(name = nil)
  result = do_system_execute("SHOW TABLES WHERE engine = 'View'", name)
  return [] if result.nil?
  result['data'].flatten
end

#with_yaml_fallback(value) ⇒ Object



155
156
157
158
159
160
161
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 155

def with_yaml_fallback(value) # :nodoc:
  if value.is_a?(Array) || value.is_a?(Hash)
    value
  else
    super
  end
end