departure 8.1.0 → 8.2.0

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +3 -1
  3. data/.pryrc +6 -6
  4. data/.standard.yml +9 -0
  5. data/AGENTS.md +9 -7
  6. data/Appraisals +11 -9
  7. data/CHANGELOG.md +4 -0
  8. data/Gemfile +8 -9
  9. data/Gemfile.lock +25 -11
  10. data/README.md +1 -1
  11. data/RELEASING.md +5 -4
  12. data/Rakefile +10 -10
  13. data/configuration.rb +3 -3
  14. data/departure.gemspec +22 -24
  15. data/gemfiles/rails_7_2.gemfile +12 -12
  16. data/gemfiles/rails_7_2.gemfile.lock +28 -11
  17. data/gemfiles/rails_8_0.gemfile +12 -12
  18. data/gemfiles/rails_8_0.gemfile.lock +28 -11
  19. data/gemfiles/rails_8_1.gemfile +11 -12
  20. data/gemfiles/rails_8_1.gemfile.lock +25 -11
  21. data/lib/active_record/connection_adapters/departure_adapter_behavior.rb +88 -0
  22. data/lib/active_record/connection_adapters/for_alter.rb +4 -4
  23. data/lib/active_record/connection_adapters/patch_connection_handling.rb +2 -2
  24. data/lib/active_record/connection_adapters/rails_7_2_departure_adapter.rb +17 -58
  25. data/lib/active_record/connection_adapters/rails_7_2_trilogy_adapter.rb +53 -0
  26. data/lib/active_record/connection_adapters/rails_8_0_departure_adapter.rb +26 -66
  27. data/lib/active_record/connection_adapters/rails_8_0_trilogy_adapter.rb +21 -0
  28. data/lib/active_record/connection_adapters/rails_8_1_mysql2_adapter.rb +7 -7
  29. data/lib/active_record/connection_adapters/rails_8_1_trilogy_adapter.rb +7 -7
  30. data/lib/departure/alter_argument.rb +6 -6
  31. data/lib/departure/cli_generator.rb +12 -12
  32. data/lib/departure/command.rb +1 -1
  33. data/lib/departure/configuration.rb +3 -3
  34. data/lib/departure/connection_details.rb +7 -7
  35. data/lib/departure/db_client.rb +5 -5
  36. data/lib/departure/dsn.rb +2 -2
  37. data/lib/departure/errors.rb +2 -2
  38. data/lib/departure/log_sanitizers/password_sanitizer.rb +1 -1
  39. data/lib/departure/logger.rb +2 -2
  40. data/lib/departure/option.rb +4 -4
  41. data/lib/departure/rails_adapter.rb +126 -102
  42. data/lib/departure/rails_patches/active_record_migrator_with_advisory_lock_patch.rb +2 -2
  43. data/lib/departure/railtie.rb +5 -5
  44. data/lib/departure/runner.rb +3 -3
  45. data/lib/departure/user_options.rb +1 -1
  46. data/lib/departure/version.rb +1 -1
  47. data/lib/departure.rb +18 -18
  48. data/lib/lhm/adapter.rb +12 -12
  49. data/lib/lhm/column_with_sql.rb +8 -8
  50. data/lib/lhm.rb +1 -1
  51. data/test_database.rb +10 -10
  52. metadata +5 -4
  53. data/.rubocop.yml +0 -66
  54. data/.rubocop_todo.yml +0 -238
  55. data/lib/active_record/connection_adapters/rails_8_1_adapter_behavior.rb +0 -64
@@ -1,16 +1,15 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source 'https://rubygems.org'
3
+ source "https://rubygems.org"
4
4
 
5
- gem 'base64'
6
- gem 'codeclimate-test-reporter', '~> 1.0.3', group: :test, require: nil
7
- gem 'lhm'
8
- gem 'logger'
9
- gem 'mutex_m', require: false
10
- gem 'rails', '8.1.1'
11
- gem 'rubocop', '~> 1.74.0', require: false
12
- gem 'rubocop-performance', '~> 1.20.2', require: false
13
- gem 'trilogy'
14
- gem 'zeitwerk', '< 2.7.0'
5
+ gem "base64"
6
+ gem "codeclimate-test-reporter", "~> 1.0.3", group: :test, require: nil
7
+ gem "lhm"
8
+ gem "logger"
9
+ gem "mutex_m", require: false
10
+ gem "rails", "8.1.1"
11
+ gem "standardrb", require: false
12
+ gem "trilogy"
13
+ gem "zeitwerk", "< 2.7.0"
15
14
 
16
- gemspec path: '../'
15
+ gemspec path: "../"
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- departure (8.1.0)
4
+ departure (8.2.0)
5
5
  activerecord (>= 7.2.0)
6
6
  mysql2 (>= 0.4.0, < 0.6.0)
7
7
  railties (>= 7.2.0)
@@ -169,7 +169,7 @@ GEM
169
169
  pp (0.6.3)
170
170
  prettyprint
171
171
  prettyprint (0.2.0)
172
- prism (1.6.0)
172
+ prism (1.9.0)
173
173
  pry (0.15.2)
174
174
  coderay (~> 1.1)
175
175
  method_source (~> 1.0)
@@ -243,7 +243,7 @@ GEM
243
243
  diff-lcs (>= 1.2.0, < 2.0)
244
244
  rspec-support (~> 3.13.0)
245
245
  rspec-support (3.13.6)
246
- rubocop (1.74.0)
246
+ rubocop (1.84.2)
247
247
  json (~> 2.3)
248
248
  language_server-protocol (~> 3.17.0.2)
249
249
  lint_roller (~> 1.1.0)
@@ -251,15 +251,16 @@ GEM
251
251
  parser (>= 3.3.0.2)
252
252
  rainbow (>= 2.2.2, < 4.0)
253
253
  regexp_parser (>= 2.9.3, < 3.0)
254
- rubocop-ast (>= 1.38.0, < 2.0)
254
+ rubocop-ast (>= 1.49.0, < 2.0)
255
255
  ruby-progressbar (~> 1.7)
256
256
  unicode-display_width (>= 2.4.0, < 4.0)
257
- rubocop-ast (1.47.1)
257
+ rubocop-ast (1.49.1)
258
258
  parser (>= 3.3.7.2)
259
- prism (~> 1.4)
260
- rubocop-performance (1.20.2)
261
- rubocop (>= 1.48.1, < 2.0)
262
- rubocop-ast (>= 1.30.0, < 2.0)
259
+ prism (~> 1.7)
260
+ rubocop-performance (1.26.1)
261
+ lint_roller (~> 1.1)
262
+ rubocop (>= 1.75.0, < 2.0)
263
+ rubocop-ast (>= 1.47.1, < 2.0)
263
264
  ruby-progressbar (1.13.0)
264
265
  securerandom (0.4.1)
265
266
  simplecov (0.13.0)
@@ -267,6 +268,20 @@ GEM
267
268
  json (>= 1.8, < 3)
268
269
  simplecov-html (~> 0.10.0)
269
270
  simplecov-html (0.10.2)
271
+ standard (1.54.0)
272
+ language_server-protocol (~> 3.17.0.2)
273
+ lint_roller (~> 1.0)
274
+ rubocop (~> 1.84.0)
275
+ standard-custom (~> 1.0.0)
276
+ standard-performance (~> 1.8)
277
+ standard-custom (1.0.2)
278
+ lint_roller (~> 1.0)
279
+ rubocop (~> 1.50)
280
+ standard-performance (1.9.0)
281
+ lint_roller (~> 1.1)
282
+ rubocop-performance (~> 1.26.0)
283
+ standardrb (1.0.1)
284
+ standard
270
285
  stringio (3.1.7)
271
286
  thor (1.4.0)
272
287
  timeout (0.4.4)
@@ -309,8 +324,7 @@ DEPENDENCIES
309
324
  rake (>= 10.0)
310
325
  rspec (~> 3.4, >= 3.4.0)
311
326
  rspec-its (~> 1.2)
312
- rubocop (~> 1.74.0)
313
- rubocop-performance (~> 1.20.2)
327
+ standardrb
314
328
  trilogy
315
329
  zeitwerk (< 2.7.0)
316
330
 
@@ -0,0 +1,88 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ # Behavior shared between the per-Rails-version Departure adapters.
4
+ # Adapters compose the pieces they need:
5
+ #
6
+ # - SchemaStatements: ALTER TABLE-friendly schema statements, so every DDL
7
+ # change goes through a statement pt-online-schema-change understands.
8
+ # - DbClientConnection: wraps the raw database client in a
9
+ # Departure::DbClient, which routes ALTER TABLE statements to
10
+ # pt-online-schema-change.
11
+ # - PerformQuery: intercepts ALTER TABLE statements through the
12
+ # perform_query hook available on Rails >= 8.0.
13
+ # - Rails8: the composition used by Rails >= 8.0 adapters.
14
+ module DepartureAdapterBehavior
15
+ module SchemaStatements
16
+ class SchemaCreation < ActiveRecord::ConnectionAdapters::MySQL::SchemaCreation
17
+ def visit_DropForeignKey(name) # standard:disable Naming/MethodName
18
+ fk_name =
19
+ if name =~ /^__(.+)/
20
+ Regexp.last_match(1)
21
+ else
22
+ "_#{name}"
23
+ end
24
+
25
+ "DROP FOREIGN KEY #{fk_name}"
26
+ end
27
+ end
28
+
29
+ def self.included(adapter_class)
30
+ adapter_class.const_set(:SchemaCreation, SchemaCreation)
31
+ adapter_class.include ForAlterStatements unless adapter_class.method_defined?(:change_column_for_alter)
32
+ end
33
+
34
+ # add_index is modified from the underlying mysql adapter implementation to ensure we add ALTER TABLE to it
35
+ def add_index(table_name, column_name, options = {})
36
+ index_definition, = add_index_options(table_name, column_name, **options)
37
+ execute <<-SQL.squish
38
+ ALTER TABLE #{quote_table_name(index_definition.table)}
39
+ ADD #{schema_creation.accept(index_definition)}
40
+ SQL
41
+ end
42
+
43
+ # remove_index is modified from the underlying mysql adapter implementation to ensure we add ALTER TABLE to it
44
+ def remove_index(table_name, column_name = nil, **options)
45
+ return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
46
+
47
+ index_name = index_name_for_remove(table_name, column_name, options)
48
+
49
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP INDEX #{quote_column_name(index_name)}"
50
+ end
51
+
52
+ def schema_creation
53
+ self.class::SchemaCreation.new(self)
54
+ end
55
+ end
56
+
57
+ # Meant to be used with `extend`, so new_client can call super up to the
58
+ # underlying adapter's implementation.
59
+ module DbClientConnection
60
+ def new_client(config)
61
+ original_client = super
62
+
63
+ Departure::DbClient.new(config, original_client)
64
+ end
65
+ end
66
+
67
+ module PerformQuery
68
+ private
69
+
70
+ # rubocop:disable Metrics/ParameterLists
71
+ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch: false)
72
+ return raw_connection.send_to_pt_online_schema_change(sql) if raw_connection.alter_statement?(sql)
73
+
74
+ super
75
+ end
76
+ # rubocop:enable Metrics/ParameterLists
77
+ end
78
+
79
+ module Rails8
80
+ def self.included(adapter_class)
81
+ adapter_class.include SchemaStatements
82
+ adapter_class.extend DbClientConnection
83
+ adapter_class.include PerformQuery
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -1,4 +1,4 @@
1
- require 'active_record/connection_adapters/mysql/schema_statements'
1
+ require "active_record/connection_adapters/mysql/schema_statements"
2
2
 
3
3
  module ForAlterStatements
4
4
  def bulk_change_table(table_name, operations) #:nodoc:
@@ -10,7 +10,7 @@ module ForAlterStatements
10
10
 
11
11
  raise "Unknown method called : #{method}(#{arguments.inspect})" unless respond_to?(method, true)
12
12
  public_send(method, table, *arguments)
13
- end.join(', ')
13
+ end.join(", ")
14
14
 
15
15
  execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls}")
16
16
  end
@@ -31,7 +31,7 @@ module ForAlterStatements
31
31
  end
32
32
 
33
33
  def rename_column_for_alter(table_name, column_name, new_column_name)
34
- column = column_for(table_name, column_name)
34
+ column = column_for(table_name, column_name)
35
35
  options = {
36
36
  default: column.default,
37
37
  null: column.null,
@@ -39,7 +39,7 @@ module ForAlterStatements
39
39
  }
40
40
 
41
41
  columns_sql = "SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE #{quote(column_name)}"
42
- current_type = exec_query(columns_sql, 'SCHEMA').first['Type']
42
+ current_type = exec_query(columns_sql, "SCHEMA").first["Type"]
43
43
  td = create_table_definition(table_name)
44
44
  cd = td.new_column_definition(new_column_name, current_type, **options)
45
45
  schema_creation.accept(ActiveRecord::ConnectionAdapters::ChangeColumnDefinition.new(cd, column.name))
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_record/connection_handling'
3
+ require "active_record/connection_handling"
4
4
 
5
5
  module ActiveRecord
6
6
  module ConnectionHandling
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
  def percona_connection(config)
10
10
  config = config.dup
11
11
  original_adapter = config.delete(:departure_original_adapter)
12
- config[:username] ||= 'root'
12
+ config[:username] ||= "root"
13
13
 
14
14
  Departure::RailsAdapter
15
15
  .for_current(db_connection_adapter: original_adapter)
@@ -1,10 +1,11 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
2
- require 'active_record/connection_adapters/statement_pool'
3
- require 'active_record/connection_adapters/mysql2_adapter'
4
- require 'active_record/connection_adapters/patch_connection_handling'
5
- require 'active_support/core_ext/string/filters'
6
- require 'departure'
7
- require 'forwardable'
1
+ require "active_record/connection_adapters/abstract_mysql_adapter"
2
+ require "active_record/connection_adapters/statement_pool"
3
+ require "active_record/connection_adapters/mysql2_adapter"
4
+ require "active_record/connection_adapters/patch_connection_handling"
5
+ require "active_support/core_ext/string/filters"
6
+ require "departure"
7
+ require "forwardable"
8
+ require "active_record/connection_adapters/departure_adapter_behavior"
8
9
 
9
10
  module ActiveRecord
10
11
  module ConnectionAdapters
@@ -17,24 +18,11 @@ module ActiveRecord
17
18
  end
18
19
  end
19
20
 
20
- class SchemaCreation < ActiveRecord::ConnectionAdapters::MySQL::SchemaCreation
21
- def visit_DropForeignKey(name) # rubocop:disable Style/MethodName
22
- fk_name =
23
- if name =~ /^__(.+)/
24
- Regexp.last_match(1)
25
- else
26
- "_#{name}"
27
- end
28
-
29
- "DROP FOREIGN KEY #{fk_name}"
30
- end
31
- end
32
-
33
21
  extend Forwardable
34
22
 
35
- include ForAlterStatements unless method_defined?(:change_column_for_alter)
23
+ include DepartureAdapterBehavior::SchemaStatements
36
24
 
37
- ADAPTER_NAME = 'Percona'.freeze
25
+ ADAPTER_NAME = "Percona".freeze
38
26
 
39
27
  def self.new_client(config)
40
28
  connection_details = Departure::ConnectionDetails.new(config)
@@ -45,7 +33,7 @@ module ActiveRecord
45
33
  percona_logger = Departure::LoggerFactory.build(sanitizers: sanitizers, verbose: verbose)
46
34
  cli_generator = Departure::CliGenerator.new(connection_details)
47
35
 
48
- mysql_adapter = ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(config.merge(adapter: 'mysql2'))
36
+ mysql_adapter = ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(config.merge(adapter: "mysql2"))
49
37
 
50
38
  Departure::Runner.new(
51
39
  percona_logger,
@@ -60,7 +48,7 @@ module ActiveRecord
60
48
  @config[:flags] ||= 0
61
49
 
62
50
  if @config[:flags].is_a? Array
63
- @config[:flags].push 'FOUND_ROWS'
51
+ @config[:flags].push "FOUND_ROWS"
64
52
  else
65
53
  @config[:flags] |= ::Mysql2::Client::FOUND_ROWS
66
54
  end
@@ -79,18 +67,18 @@ module ActiveRecord
79
67
 
80
68
  @raw_connection.affected_rows
81
69
  end
82
- alias exec_update exec_delete
70
+ alias_method :exec_update, :exec_delete
83
71
 
84
- def exec_insert(sql, name, binds, pky = nil, sequence_name = nil, returning: nil) # rubocop:disable Lint/UnusedMethodArgument, Metrics/Metrics/ParameterLists
72
+ def exec_insert(sql, name, binds, pky = nil, sequence_name = nil, returning: nil) # standard:disable Lint/UnusedMethodArgument
85
73
  execute(to_sql(sql, binds), name)
86
74
  end
87
75
 
88
- def internal_exec_query(sql, name = 'SQL', _binds = [], **_kwargs) # :nodoc:
76
+ def internal_exec_query(sql, name = "SQL", _binds = [], **_kwargs) # :nodoc:
89
77
  result = execute(sql, name)
90
78
  fields = result.fields if defined?(result.fields)
91
79
  ActiveRecord::Result.new(fields || [], result.to_a)
92
80
  end
93
- alias exec_query internal_exec_query
81
+ alias_method :exec_query, :internal_exec_query
94
82
 
95
83
  # Executes a SELECT query and returns an array of rows. Each row is an
96
84
  # array of field values.
@@ -114,35 +102,6 @@ module ActiveRecord
114
102
  Column.new(...)
115
103
  end
116
104
 
117
- # Adds a new index to the table
118
- #
119
- # @param table_name [String, Symbol]
120
- # @param column_name [String, Symbol]
121
- # @param options [Hash] optional
122
- def add_index(table_name, column_name, options = {})
123
- index_definition, = add_index_options(table_name, column_name, **options)
124
- execute <<-SQL.squish
125
- ALTER TABLE #{quote_table_name(index_definition.table)}
126
- ADD #{schema_creation.accept(index_definition)}
127
- SQL
128
- end
129
-
130
- # Remove the given index from the table.
131
- #
132
- # @param table_name [String, Symbol]
133
- # @param options [Hash] optional
134
- def remove_index(table_name, column_name = nil, **options)
135
- return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
136
-
137
- index_name = index_name_for_remove(table_name, column_name, options)
138
-
139
- execute "ALTER TABLE #{quote_table_name(table_name)} DROP INDEX #{quote_column_name(index_name)}"
140
- end
141
-
142
- def schema_creation
143
- SchemaCreation.new(self)
144
- end
145
-
146
105
  def change_table(table_name, _options = {})
147
106
  recorder = ActiveRecord::Migration::CommandRecorder.new(self)
148
107
  yield update_table_definition(table_name, recorder)
@@ -153,7 +112,7 @@ module ActiveRecord
153
112
  get_full_version
154
113
  end
155
114
 
156
- def get_full_version # rubocop:disable Style/AccessorMethodName
115
+ def get_full_version # standard:disable Naming/AccessorMethodName
157
116
  return @get_full_version if defined? @get_full_version
158
117
 
159
118
  with_raw_connection do |conn|
@@ -0,0 +1,53 @@
1
+ require "active_record/connection_adapters/abstract_mysql_adapter"
2
+ require "active_record/connection_adapters/trilogy_adapter"
3
+ require "active_record/connection_adapters/patch_connection_handling"
4
+ require "departure"
5
+ require "active_record/connection_adapters/departure_adapter_behavior"
6
+
7
+ module ActiveRecord
8
+ module ConnectionAdapters
9
+ class Rails72TrilogyAdapter < ActiveRecord::ConnectionAdapters::TrilogyAdapter
10
+ class Column < ActiveRecord::ConnectionAdapters::MySQL::Column
11
+ def adapter
12
+ Rails72TrilogyAdapter
13
+ end
14
+ end
15
+
16
+ ADAPTER_NAME = "Percona".freeze
17
+
18
+ include DepartureAdapterBehavior::SchemaStatements
19
+ extend DepartureAdapterBehavior::DbClientConnection
20
+
21
+ def new_column(...)
22
+ Column.new(...)
23
+ end
24
+
25
+ private
26
+
27
+ # Rails 7.2 has no perform_query hook, so the interception happens here:
28
+ # the DbClient wrapper routes ALTER TABLE statements to
29
+ # pt-online-schema-change, which yields a Process::Status instead of a
30
+ # Trilogy::Result.
31
+ def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
32
+ log(sql, name, async: async) do |notification_payload|
33
+ with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
34
+ sync_timezone_changes(conn)
35
+ result = conn.query(sql)
36
+ while conn.more_results_exist?
37
+ conn.next_result
38
+ end
39
+ verified!
40
+ handle_warnings(sql)
41
+ if result.is_a?(Process::Status)
42
+ notification_payload[:exit_code] = result.exitstatus
43
+ notification_payload[:exit_pid] = result.pid
44
+ elsif result.respond_to?(:count)
45
+ notification_payload[:row_count] = result.count
46
+ end
47
+ result
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,16 +1,18 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
2
- require 'active_record/connection_adapters/statement_pool'
3
- require 'active_record/connection_adapters/mysql2_adapter'
4
- require 'active_record/connection_adapters/mysql2/database_statements'
5
- require 'active_record/connection_adapters/patch_connection_handling'
6
- require 'active_support/core_ext/string/filters'
7
- require 'departure'
8
- require 'forwardable'
1
+ require "active_record/connection_adapters/abstract_mysql_adapter"
2
+ require "active_record/connection_adapters/statement_pool"
3
+ require "active_record/connection_adapters/mysql2_adapter"
4
+ require "active_record/connection_adapters/mysql2/database_statements"
5
+ require "active_record/connection_adapters/patch_connection_handling"
6
+ require "active_support/core_ext/string/filters"
7
+ require "departure"
8
+ require "forwardable"
9
+ require "active_record/connection_adapters/departure_adapter_behavior"
9
10
 
10
11
  module ActiveRecord
11
12
  module ConnectionAdapters
12
13
  class Rails80DepartureAdapter < AbstractMysqlAdapter
13
14
  include ActiveRecord::ConnectionAdapters::Mysql2::DatabaseStatements
15
+
14
16
  TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) } if defined?(initialize_type_map)
15
17
 
16
18
  class Column < ActiveRecord::ConnectionAdapters::MySQL::Column
@@ -19,24 +21,11 @@ module ActiveRecord
19
21
  end
20
22
  end
21
23
 
22
- class SchemaCreation < ActiveRecord::ConnectionAdapters::MySQL::SchemaCreation
23
- def visit_DropForeignKey(name) # rubocop:disable Naming/MethodName
24
- fk_name =
25
- if name =~ /^__(.+)/
26
- Regexp.last_match(1)
27
- else
28
- "_#{name}"
29
- end
30
-
31
- "DROP FOREIGN KEY #{fk_name}"
32
- end
33
- end
34
-
35
24
  extend Forwardable
36
25
 
37
- include ForAlterStatements unless method_defined?(:change_column_for_alter)
26
+ include DepartureAdapterBehavior::SchemaStatements
38
27
 
39
- ADAPTER_NAME = 'Percona'.freeze
28
+ ADAPTER_NAME = "Percona".freeze
40
29
 
41
30
  def self.new_client(config)
42
31
  connection_details = Departure::ConnectionDetails.new(config)
@@ -47,7 +36,7 @@ module ActiveRecord
47
36
  percona_logger = Departure::LoggerFactory.build(sanitizers: sanitizers, verbose: verbose)
48
37
  cli_generator = Departure::CliGenerator.new(connection_details)
49
38
 
50
- mysql_adapter = ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(config.merge(adapter: 'mysql2'))
39
+ mysql_adapter = ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(config.merge(adapter: "mysql2"))
51
40
 
52
41
  Departure::Runner.new(
53
42
  percona_logger,
@@ -62,7 +51,7 @@ module ActiveRecord
62
51
  @config[:flags] ||= 0
63
52
 
64
53
  if @config[:flags].is_a? Array
65
- @config[:flags].push 'FOUND_ROWS'
54
+ @config[:flags].push "FOUND_ROWS"
66
55
  else
67
56
  @config[:flags] |= ::Mysql2::Client::FOUND_ROWS
68
57
  end
@@ -81,18 +70,18 @@ module ActiveRecord
81
70
 
82
71
  @raw_connection.affected_rows
83
72
  end
84
- alias exec_update exec_delete
73
+ alias_method :exec_update, :exec_delete
85
74
 
86
75
  def exec_insert(sql, name, binds, pky = nil, sequence_name = nil, returning: nil) # rubocop:disable Lint/UnusedMethodArgument, Metrics/ParameterLists
87
76
  execute(to_sql(sql, binds), name)
88
77
  end
89
78
 
90
- def internal_exec_query(sql, name = 'SQL', _binds = [], **_kwargs) # :nodoc:
79
+ def internal_exec_query(sql, name = "SQL", _binds = [], **_kwargs) # :nodoc:
91
80
  result = execute(sql, name)
92
81
  fields = result.fields if defined?(result.fields)
93
82
  ActiveRecord::Result.new(fields || [], result.to_a)
94
83
  end
95
- alias exec_query internal_exec_query
84
+ alias_method :exec_query, :internal_exec_query
96
85
 
97
86
  # Executes a SELECT query and returns an array of rows. Each row is an
98
87
  # array of field values.
@@ -116,35 +105,6 @@ module ActiveRecord
116
105
  Column.new(...)
117
106
  end
118
107
 
119
- # Adds a new index to the table
120
- #
121
- # @param table_name [String, Symbol]
122
- # @param column_name [String, Symbol]
123
- # @param options [Hash] optional
124
- def add_index(table_name, column_name, options = {})
125
- index_definition, = add_index_options(table_name, column_name, **options)
126
- execute <<-SQL.squish
127
- ALTER TABLE #{quote_table_name(index_definition.table)}
128
- ADD #{schema_creation.accept(index_definition)}
129
- SQL
130
- end
131
-
132
- # Remove the given index from the table.
133
- #
134
- # @param table_name [String, Symbol]
135
- # @param options [Hash] optional
136
- def remove_index(table_name, column_name = nil, **options)
137
- return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
138
-
139
- index_name = index_name_for_remove(table_name, column_name, options)
140
-
141
- execute "ALTER TABLE #{quote_table_name(table_name)} DROP INDEX #{quote_column_name(index_name)}"
142
- end
143
-
144
- def schema_creation
145
- SchemaCreation.new(self)
146
- end
147
-
148
108
  def change_table(table_name, _options = {})
149
109
  recorder = ActiveRecord::Migration::CommandRecorder.new(self)
150
110
  yield update_table_definition(table_name, recorder)
@@ -183,21 +143,21 @@ module ActiveRecord
183
143
 
184
144
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/ParameterLists
185
145
  def raw_execute(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false,
186
- materialize_transactions: true, batch: false)
146
+ materialize_transactions: true, batch: false)
187
147
  type_casted_binds = type_casted_binds(binds)
188
148
  log(sql, name, binds, type_casted_binds, async: async) do |notification_payload|
189
149
  with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
190
150
  perform_query(conn, sql, binds, type_casted_binds, prepare: prepare,
191
- notification_payload: notification_payload, batch: batch)
151
+ notification_payload: notification_payload, batch: batch)
192
152
  end
193
153
  end
194
154
  end
195
155
 
196
156
  def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch: false)
197
157
  reset_multi_statement = if batch && !multi_statements_enabled?
198
- raw_connection.set_server_option(::Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)
199
- true
200
- end
158
+ raw_connection.set_server_option(::Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)
159
+ true
160
+ end
201
161
 
202
162
  # Make sure we carry over any changes to ActiveRecord.default_timezone that have been
203
163
  # made since we established the connection
@@ -216,10 +176,10 @@ module ActiveRecord
216
176
  # THIS IS THE CORE CHANGES 1 related to size
217
177
  # We will sometimes have a process exit code instead of a result from executing
218
178
  @affected_rows_before_warnings = if result.is_a? Process::Status
219
- result.try(:size) || 0
220
- else
221
- result.try(:size) || raw_connection.affected_rows
222
- end
179
+ result.try(:size) || 0
180
+ else
181
+ result.try(:size) || raw_connection.affected_rows
182
+ end
223
183
  end
224
184
  elsif prepare
225
185
 
@@ -0,0 +1,21 @@
1
+ require "active_record/connection_adapters/abstract_mysql_adapter"
2
+ require "active_record/connection_adapters/trilogy_adapter"
3
+ require "active_record/connection_adapters/patch_connection_handling"
4
+ require "departure"
5
+ require "active_record/connection_adapters/departure_adapter_behavior"
6
+
7
+ module ActiveRecord
8
+ module ConnectionAdapters
9
+ class Rails80TrilogyAdapter < ActiveRecord::ConnectionAdapters::TrilogyAdapter
10
+ class Column < ActiveRecord::ConnectionAdapters::MySQL::Column
11
+ def adapter
12
+ Rails80TrilogyAdapter
13
+ end
14
+ end
15
+
16
+ ADAPTER_NAME = "Percona".freeze
17
+
18
+ include DepartureAdapterBehavior::Rails8
19
+ end
20
+ end
21
+ end
@@ -1,8 +1,8 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
2
- require 'active_record/connection_adapters/mysql2_adapter'
3
- require 'active_record/connection_adapters/patch_connection_handling'
4
- require 'departure'
5
- require 'active_record/connection_adapters/rails_8_1_adapter_behavior'
1
+ require "active_record/connection_adapters/abstract_mysql_adapter"
2
+ require "active_record/connection_adapters/mysql2_adapter"
3
+ require "active_record/connection_adapters/patch_connection_handling"
4
+ require "departure"
5
+ require "active_record/connection_adapters/departure_adapter_behavior"
6
6
 
7
7
  module ActiveRecord
8
8
  module ConnectionAdapters
@@ -15,9 +15,9 @@ module ActiveRecord
15
15
  end
16
16
  end
17
17
 
18
- ADAPTER_NAME = 'Percona'.freeze
18
+ ADAPTER_NAME = "Percona".freeze
19
19
 
20
- include Rails81AdapterBehavior
20
+ include DepartureAdapterBehavior::Rails8
21
21
  end
22
22
  end
23
23
  end