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,8 +1,8 @@
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/rails_8_1_adapter_behavior'
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
6
 
7
7
  module ActiveRecord
8
8
  module ConnectionAdapters
@@ -13,9 +13,9 @@ module ActiveRecord
13
13
  end
14
14
  end
15
15
 
16
- ADAPTER_NAME = 'Percona'.freeze
16
+ ADAPTER_NAME = "Percona".freeze
17
17
 
18
- include Rails81AdapterBehavior
18
+ include DepartureAdapterBehavior::Rails8
19
19
  end
20
20
  end
21
21
  end
@@ -4,7 +4,7 @@ module Departure
4
4
  # Represents the '--alter' argument of Percona's pt-online-schema-change
5
5
  # See https://www.percona.com/doc/percona-toolkit/2.0/pt-online-schema-change.html
6
6
  class AlterArgument
7
- ALTER_TABLE_REGEX = /\AALTER TABLE [^\s]*[\n]* /
7
+ ALTER_TABLE_REGEX = /\AALTER TABLE [^\s]*\n* /
8
8
 
9
9
  attr_reader :table_name
10
10
 
@@ -21,8 +21,8 @@ module Departure
21
21
  #
22
22
  # Removes the grave marks, if they are there, so we can get the table_name
23
23
  @table_name = String(match)
24
- .split(' ')[2]
25
- .delete('`')
24
+ .split(" ")[2]
25
+ .delete("`")
26
26
  end
27
27
 
28
28
  # Returns the '--alter' pt-online-schema-change argument as a string. See
@@ -40,9 +40,9 @@ module Departure
40
40
  # @return [String]
41
41
  def parsed_statement
42
42
  @parsed_statement ||= statement
43
- .gsub(ALTER_TABLE_REGEX, '')
44
- .gsub('`', '\\\`')
45
- .gsub(/\\n/, '')
43
+ .gsub(ALTER_TABLE_REGEX, "")
44
+ .gsub("`", '\\\`')
45
+ .gsub("\\n", "")
46
46
  .gsub('"', '\\\"')
47
47
  end
48
48
  end
@@ -1,24 +1,24 @@
1
- require 'departure/dsn'
2
- require 'departure/option'
3
- require 'departure/alter_argument'
4
- require 'departure/connection_details'
5
- require 'departure/user_options'
1
+ require "departure/dsn"
2
+ require "departure/option"
3
+ require "departure/alter_argument"
4
+ require "departure/connection_details"
5
+ require "departure/user_options"
6
6
 
7
7
  module Departure
8
8
  # Generates the equivalent Percona's pt-online-schema-change command to the
9
9
  # given SQL statement
10
10
  #
11
11
  # --no-check-alter is used to allow running CHANGE COLUMN statements. For more details, check:
12
- # www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html#cmdoption-pt-online-schema-change--[no]check-alter # rubocop:disable Metrics/LineLength
12
+ # www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html#cmdoption-pt-online-schema-change--[no]check-alter
13
13
  #
14
14
  class CliGenerator
15
- COMMAND_NAME = 'pt-online-schema-change'.freeze
15
+ COMMAND_NAME = "pt-online-schema-change".freeze
16
16
  DEFAULT_OPTIONS = Set.new(
17
17
  [
18
- Option.new('execute'),
19
- Option.new('statistics'),
20
- Option.new('alter-foreign-keys-method', 'auto'),
21
- Option.new('no-check-alter')
18
+ Option.new("execute"),
19
+ Option.new("statistics"),
20
+ Option.new("alter-foreign-keys-method", "auto"),
21
+ Option.new("no-check-alter")
22
22
  ]
23
23
  ).freeze
24
24
 
@@ -78,7 +78,7 @@ module Departure
78
78
  env_variable_options = UserOptions.new
79
79
  global_configuration_options = UserOptions.new(Departure.configuration.global_percona_args)
80
80
  options = env_variable_options.merge(global_configuration_options).merge(DEFAULT_OPTIONS)
81
- options.to_a.join(' ')
81
+ options.to_a.join(" ")
82
82
  end
83
83
  end
84
84
  end
@@ -86,7 +86,7 @@ module Departure
86
86
  if redirect_stderr
87
87
  File.read(error_log_path)
88
88
  else
89
- ''
89
+ ""
90
90
  end
91
91
  end
92
92
 
@@ -1,11 +1,11 @@
1
1
  module Departure
2
2
  class Configuration
3
3
  attr_accessor :tmp_path, :global_percona_args, :enabled_by_default, :redirect_stderr,
4
- :disable_rails_advisory_lock_patch
4
+ :disable_rails_advisory_lock_patch
5
5
 
6
6
  def initialize
7
- @tmp_path = '.'.freeze
8
- @error_log_filename = 'departure_error.log'.freeze
7
+ @tmp_path = ".".freeze
8
+ @error_log_filename = "departure_error.log".freeze
9
9
  @global_percona_args = nil
10
10
  @enabled_by_default = true
11
11
  @redirect_stderr = true
@@ -1,4 +1,4 @@
1
- require 'shellwords'
1
+ require "shellwords"
2
2
  module Departure
3
3
  # Holds the parameters of the DB connection and formats them to string
4
4
  class ConnectionDetails
@@ -26,7 +26,7 @@ module Departure
26
26
  #
27
27
  # @return [String]
28
28
  def database
29
- ENV.fetch('PERCONA_DB_NAME', connection_data[:database])
29
+ ENV.fetch("PERCONA_DB_NAME", connection_data[:database])
30
30
  end
31
31
 
32
32
  # Returns the password fragment of the details string if a password is passed
@@ -36,7 +36,7 @@ module Departure
36
36
  if password.present?
37
37
  %(--password #{Shellwords.escape(password)} )
38
38
  else
39
- ''
39
+ ""
40
40
  end
41
41
  end
42
42
 
@@ -77,7 +77,7 @@ module Departure
77
77
  #
78
78
  # @return [String]
79
79
  def host
80
- ENV.fetch('PERCONA_DB_HOST', connection_data[:host]) || 'localhost'
80
+ ENV.fetch("PERCONA_DB_HOST", connection_data[:host]) || "localhost"
81
81
  end
82
82
 
83
83
  # Returns the database user. If PERCONA_DB_USER is passed its value will be
@@ -85,7 +85,7 @@ module Departure
85
85
  #
86
86
  # @return [String]
87
87
  def user
88
- ENV.fetch('PERCONA_DB_USER', connection_data[:username])
88
+ ENV.fetch("PERCONA_DB_USER", connection_data[:username])
89
89
  end
90
90
 
91
91
  # Returns the database user's password. If PERCONA_DB_PASSWORD is passed its
@@ -93,7 +93,7 @@ module Departure
93
93
  #
94
94
  # @return [String]
95
95
  def password
96
- ENV.fetch('PERCONA_DB_PASSWORD', connection_data[:password])
96
+ ENV.fetch("PERCONA_DB_PASSWORD", connection_data[:password])
97
97
  end
98
98
 
99
99
  # Returns the database socket path. If PERCONA_DB_SOCKET is passed its value
@@ -101,7 +101,7 @@ module Departure
101
101
  #
102
102
  # @return [String]
103
103
  def socket
104
- ENV.fetch('PERCONA_DB_SOCKET', connection_data[:socket])
104
+ ENV.fetch("PERCONA_DB_SOCKET", connection_data[:socket])
105
105
  end
106
106
 
107
107
  # Returns the database's port.
@@ -1,6 +1,6 @@
1
- require 'open3'
1
+ require "open3"
2
2
 
3
- require 'forwardable'
3
+ require "forwardable"
4
4
 
5
5
  module Departure
6
6
  # It executes pt-online-schema-change commands in a new process and gets its
@@ -40,9 +40,9 @@ module Departure
40
40
  command_line = @cli_generator.parse_statement(raw_sql_string)
41
41
 
42
42
  Command.new(command_line,
43
- Departure.configuration.error_log_path,
44
- @logger,
45
- Departure.configuration.redirect_stderr).run
43
+ Departure.configuration.error_log_path,
44
+ @logger,
45
+ Departure.configuration.redirect_stderr).run
46
46
  end
47
47
 
48
48
  def alter_statement?(raw_sql_string)
data/lib/departure/dsn.rb CHANGED
@@ -9,13 +9,13 @@ module Departure
9
9
  def initialize(database, table_name)
10
10
  @database = database
11
11
  @table_name = table_name
12
- @suffix = ENV.fetch('PERCONA_DSN_SUFFIX', nil)
12
+ @suffix = ENV.fetch("PERCONA_DSN_SUFFIX", nil)
13
13
  end
14
14
 
15
15
  # Returns the pt-online-schema-change DSN string. See
16
16
  # https://www.percona.com/doc/percona-toolkit/2.0/pt-online-schema-change.html#dsn-options
17
17
  def to_s
18
- "D=#{database},t=#{table_name}#{suffix.nil? ? nil : ',' + suffix}"
18
+ "D=#{database},t=#{table_name}#{"," + suffix unless suffix.nil?}"
19
19
  end
20
20
 
21
21
  private
@@ -5,7 +5,7 @@ module Departure
5
5
  # status.
6
6
  class NoStatusError < Error
7
7
  def message
8
- 'Status could not be retrieved'.freeze
8
+ "Status could not be retrieved".freeze
9
9
  end
10
10
  end
11
11
 
@@ -29,7 +29,7 @@ module Departure
29
29
 
30
30
  class CommandNotFoundError < Error
31
31
  def message
32
- 'Please install pt-online-schema-change. Check: https://www.percona.com/doc/percona-toolkit for further details'
32
+ "Please install pt-online-schema-change. Check: https://www.percona.com/doc/percona-toolkit for further details"
33
33
  end
34
34
  end
35
35
 
@@ -1,7 +1,7 @@
1
1
  module Departure
2
2
  module LogSanitizers
3
3
  class PasswordSanitizer
4
- PASSWORD_REPLACEMENT = '[filtered_password]'.freeze
4
+ PASSWORD_REPLACEMENT = "[filtered_password]".freeze
5
5
 
6
6
  delegate :password_argument, to: :connection_details
7
7
 
@@ -14,13 +14,13 @@ module Departure
14
14
  # @param message [String]
15
15
  # @param subitem [Boolean] whether to show message as a nested log item
16
16
  def say(message, subitem = false)
17
- write "#{subitem ? ' ->' : '--'} #{message}"
17
+ write "#{subitem ? " ->" : "--"} #{message}"
18
18
  end
19
19
 
20
20
  # Outputs the text through the stdout adding a new line at the end
21
21
  #
22
22
  # @param text [String]
23
- def write(text = '')
23
+ def write(text = "")
24
24
  puts(sanitize(text))
25
25
  end
26
26
 
@@ -27,7 +27,7 @@ module Departure
27
27
  def ==(other)
28
28
  name == other.name
29
29
  end
30
- alias eql? ==
30
+ alias_method :eql?, :==
31
31
 
32
32
  # Returns the option's hash
33
33
  #
@@ -50,7 +50,7 @@ module Departure
50
50
  #
51
51
  # @return [String]
52
52
  def normalize_option(name)
53
- if name.start_with?('-')
53
+ if name.start_with?("-")
54
54
  name
55
55
  elsif name.length == 1
56
56
  "-#{name}"
@@ -64,8 +64,8 @@ module Departure
64
64
  # @return [String]
65
65
  def value_as_string
66
66
  if value.nil?
67
- ''
68
- elsif value.include?('=')
67
+ ""
68
+ elsif value.include?("=")
69
69
  " #{value}"
70
70
  else
71
71
  "=#{value}"
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
3
+ require "forwardable"
4
4
 
5
5
  module Departure
6
6
  class RailsAdapter
@@ -9,6 +9,11 @@ module Departure
9
9
  class UnsupportedRailsVersionError < StandardError; end
10
10
  class MustImplementError < StandardError; end
11
11
 
12
+ # Describes how a Departure connection adapter is registered with
13
+ # ActiveRecord: the adapter name apps configure, the class implementing it
14
+ # and the file that defines the class.
15
+ Registration = Struct.new(:adapter_name, :class_name, :path)
16
+
12
17
  class << self
13
18
  def register_integrations(**args)
14
19
  for_current(**args).register_integrations
@@ -29,130 +34,178 @@ module Departure
29
34
  self.for(current_version, **args)
30
35
  end
31
36
 
32
- # rubocop:disable Metrics/PerceivedComplexity
33
37
  def for(ar_version, db_connection_adapter: nil)
34
- # rubocop:enable Metrics/PerceivedComplexity
35
- if ar_version::MAJOR == 8 && ar_version::MINOR.positive?
36
- if db_connection_adapter == 'trilogy'
37
- V8_1_TrilogyAdapter
38
+ adapters =
39
+ if ar_version::MAJOR == 8 && ar_version::MINOR.positive?
40
+ {mysql2: V8_1_Mysql2Adapter, trilogy: V8_1_TrilogyAdapter}
41
+ elsif ar_version::MAJOR == 8
42
+ {mysql2: V8_0_Adapter, trilogy: V8_0_TrilogyAdapter}
43
+ elsif ar_version::MAJOR >= 7 && ar_version::MINOR >= 2
44
+ {mysql2: V7_2_Adapter, trilogy: V7_2_TrilogyAdapter}
38
45
  else
39
- V8_1_Mysql2Adapter
46
+ raise UnsupportedRailsVersionError, "Unsupported Rails version: #{ar_version}"
40
47
  end
41
- elsif ar_version::MAJOR == 8
42
- V8_0_Adapter
43
- elsif ar_version::MAJOR >= 7 && ar_version::MINOR >= 2
44
- V7_2_Adapter
45
- else
46
- raise UnsupportedRailsVersionError, "Unsupported Rails version: #{ar_version}"
47
- end
48
+
49
+ (db_connection_adapter == "trilogy") ? adapters[:trilogy] : adapters[:mysql2]
48
50
  end
49
51
  end
50
52
 
51
53
  class BaseAdapter
52
54
  class << self
55
+ # The Registration for the database adapter this class drives.
56
+ # Subclasses must implement it.
57
+ def registration
58
+ raise MustImplementError, "adapter must implement registration"
59
+ end
60
+
61
+ # Every Registration available for this Rails version, so all
62
+ # Departure adapter names resolve regardless of which one the app
63
+ # connects through. Registration is lazy: the adapter files are only
64
+ # loaded when ActiveRecord resolves the adapter name.
65
+ # Subclasses must implement it.
66
+ def registrations
67
+ raise MustImplementError, "adapter must implement registrations"
68
+ end
69
+
53
70
  def register_integrations
54
- raise MustImplementError, 'adapter must implement register_integrations'
71
+ require registration.path
72
+ require "departure/rails_patches/active_record_migrator_with_advisory_lock_patch"
73
+
74
+ ActiveRecord::Migration.class_eval do
75
+ include Departure::Migration
76
+ end
77
+
78
+ ActiveRecord::Migrator.prepend Departure::RailsPatches::ActiveRecordMigratorWithAdvisoryLockPatch
79
+
80
+ registrations.each do |registration|
81
+ ActiveRecord::ConnectionAdapters.register registration.adapter_name,
82
+ registration.class_name,
83
+ registration.path
84
+ end
55
85
  end
56
86
 
57
- # ActiveRecord::ConnectionAdapters::Mysql2Adapter
58
- def create_connection_adapter(**_config)
59
- raise MustImplementError, 'adapter must implement create_connection_adapter'
87
+ def create_connection_adapter(**config)
88
+ connection_adapter_class.new(config)
60
89
  end
61
90
 
62
91
  def departure_adapter_name
63
- 'percona'
92
+ registration.adapter_name
64
93
  end
65
94
 
66
95
  # https://github.com/rails/rails/commit/9ad36e067222478090b36a985090475bb03e398c#diff-de807ece2205a84c0e3de66b0e5ab831325d567893b8b88ce0d6e9d498f923d1
67
96
  # Rails Column arity changed to require cast_type in position 2 which required us introducing this indirection
68
97
  def new_sql_column(name:,
69
- default_value:,
70
- mysql_metadata:,
71
- null_value:,
72
- **_kwargs)
98
+ default_value:,
99
+ mysql_metadata:,
100
+ null_value:,
101
+ **_kwargs)
73
102
  sql_column.new(name, default_value, mysql_metadata, null_value)
74
103
  end
75
104
 
76
105
  def sql_column
77
- ::ActiveRecord::ConnectionAdapters::DepartureAdapter::Column
106
+ connection_adapter_class::Column
107
+ end
108
+
109
+ private
110
+
111
+ def connection_adapter_class
112
+ require registration.path
113
+
114
+ Object.const_get(registration.class_name)
78
115
  end
79
116
  end
80
117
  end
81
118
 
82
119
  class V7_2_Adapter < BaseAdapter # rubocop:disable Naming/ClassAndModuleCamelCase
83
- class << self
84
- def register_integrations
85
- require 'active_record/connection_adapters/rails_7_2_departure_adapter'
86
- require 'departure/rails_patches/active_record_migrator_with_advisory_lock_patch'
87
-
88
- ActiveRecord::Migration.class_eval do
89
- include Departure::Migration
90
- end
120
+ MYSQL2_REGISTRATION = Registration.new(
121
+ "percona",
122
+ "ActiveRecord::ConnectionAdapters::Rails72DepartureAdapter",
123
+ "active_record/connection_adapters/rails_7_2_departure_adapter"
124
+ )
125
+ TRILOGY_REGISTRATION = Registration.new(
126
+ "percona_trilogy",
127
+ "ActiveRecord::ConnectionAdapters::Rails72TrilogyAdapter",
128
+ "active_record/connection_adapters/rails_7_2_trilogy_adapter"
129
+ )
91
130
 
92
- ActiveRecord::Migrator.prepend Departure::RailsPatches::ActiveRecordMigratorWithAdvisoryLockPatch
93
-
94
- ActiveRecord::ConnectionAdapters.register 'percona',
95
- 'ActiveRecord::ConnectionAdapters::Rails72DepartureAdapter',
96
- 'active_record/connection_adapters/rails_7_2_departure_adapter'
131
+ class << self
132
+ def registration
133
+ MYSQL2_REGISTRATION
97
134
  end
98
135
 
99
- def create_connection_adapter(**config)
100
- ActiveRecord::ConnectionAdapters::Rails72DepartureAdapter.new(config)
136
+ def registrations
137
+ [MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
101
138
  end
139
+ end
140
+ end
102
141
 
103
- def sql_column
104
- ::ActiveRecord::ConnectionAdapters::Rails72DepartureAdapter::Column
105
- end
142
+ class V7_2_TrilogyAdapter < V7_2_Adapter # rubocop:disable Naming/ClassAndModuleCamelCase
143
+ # def self so TRILOGY_REGISTRATION resolves through the superclass
144
+ def self.registration
145
+ TRILOGY_REGISTRATION
106
146
  end
107
147
  end
108
148
 
109
149
  class V8_0_Adapter < BaseAdapter # rubocop:disable Naming/ClassAndModuleCamelCase
110
- class << self
111
- def register_integrations
112
- require 'active_record/connection_adapters/rails_8_0_departure_adapter'
113
- require 'departure/rails_patches/active_record_migrator_with_advisory_lock_patch'
114
-
115
- ActiveRecord::Migration.class_eval do
116
- include Departure::Migration
117
- end
150
+ MYSQL2_REGISTRATION = Registration.new(
151
+ "percona",
152
+ "ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter",
153
+ "active_record/connection_adapters/rails_8_0_departure_adapter"
154
+ )
155
+ TRILOGY_REGISTRATION = Registration.new(
156
+ "percona_trilogy",
157
+ "ActiveRecord::ConnectionAdapters::Rails80TrilogyAdapter",
158
+ "active_record/connection_adapters/rails_8_0_trilogy_adapter"
159
+ )
118
160
 
119
- ActiveRecord::Migrator.prepend Departure::RailsPatches::ActiveRecordMigratorWithAdvisoryLockPatch
120
-
121
- ActiveRecord::ConnectionAdapters.register 'percona',
122
- 'ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter',
123
- 'active_record/connection_adapters/rails_8_0_departure_adapter'
161
+ class << self
162
+ def registration
163
+ MYSQL2_REGISTRATION
124
164
  end
125
165
 
126
- def create_connection_adapter(**config)
127
- ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter.new(config)
166
+ def registrations
167
+ [MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
128
168
  end
169
+ end
170
+ end
129
171
 
130
- def sql_column
131
- ::ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter::Column
132
- end
172
+ class V8_0_TrilogyAdapter < V8_0_Adapter # rubocop:disable Naming/ClassAndModuleCamelCase
173
+ # def self so TRILOGY_REGISTRATION resolves through the superclass
174
+ def self.registration
175
+ TRILOGY_REGISTRATION
133
176
  end
134
177
  end
135
178
 
136
179
  class V8_1_Mysql2Adapter < BaseAdapter # rubocop:disable Naming/ClassAndModuleCamelCase
180
+ MYSQL2_REGISTRATION = Registration.new(
181
+ "percona",
182
+ "ActiveRecord::ConnectionAdapters::Rails81Mysql2Adapter",
183
+ "active_record/connection_adapters/rails_8_1_mysql2_adapter"
184
+ )
185
+ TRILOGY_REGISTRATION = Registration.new(
186
+ "percona_trilogy",
187
+ "ActiveRecord::ConnectionAdapters::Rails81TrilogyAdapter",
188
+ "active_record/connection_adapters/rails_8_1_trilogy_adapter"
189
+ )
190
+
137
191
  class << self
138
- def register_integrations
139
- require 'active_record/connection_adapters/rails_8_1_mysql2_adapter'
140
- register_rails_8_1_integrations
192
+ def registration
193
+ MYSQL2_REGISTRATION
141
194
  end
142
195
 
143
- def create_connection_adapter(**config)
144
- ActiveRecord::ConnectionAdapters::Rails81Mysql2Adapter.new(config)
196
+ def registrations
197
+ [MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
145
198
  end
146
199
 
147
200
  # rubocop:disable Metrics/ParameterLists
148
201
  # https://github.com/rails/rails/commit/9ad36e067222478090b36a985090475bb03e398c#diff-de807ece2205a84c0e3de66b0e5ab831325d567893b8b88ce0d6e9d498f923d1
149
202
  # Rails Column arity changed to require cast_type in position 2 which required us introducing this indirection
150
203
  def new_sql_column(name:,
151
- cast_type:,
152
- default_value:,
153
- mysql_metadata:,
154
- null_value:,
155
- **_kwargs)
204
+ cast_type:,
205
+ default_value:,
206
+ mysql_metadata:,
207
+ null_value:,
208
+ **_kwargs)
156
209
  # rubocop:enable Metrics/ParameterLists
157
210
  sql_column.new(name, cast_type, default_value, mysql_metadata, null_value)
158
211
  end
@@ -160,42 +213,13 @@ module Departure
160
213
  def sql_column
161
214
  ::ActiveRecord::ConnectionAdapters::MySQL::Column
162
215
  end
163
-
164
- private
165
-
166
- def register_rails_8_1_integrations
167
- require 'departure/rails_patches/active_record_migrator_with_advisory_lock_patch'
168
-
169
- ActiveRecord::Migration.class_eval do
170
- include Departure::Migration
171
- end
172
-
173
- ActiveRecord::Migrator.prepend Departure::RailsPatches::ActiveRecordMigratorWithAdvisoryLockPatch
174
-
175
- ActiveRecord::ConnectionAdapters.register 'percona',
176
- 'ActiveRecord::ConnectionAdapters::Rails81Mysql2Adapter',
177
- 'active_record/connection_adapters/rails_8_1_mysql2_adapter'
178
- ActiveRecord::ConnectionAdapters.register 'percona_trilogy',
179
- 'ActiveRecord::ConnectionAdapters::Rails81TrilogyAdapter',
180
- 'active_record/connection_adapters/rails_8_1_trilogy_adapter'
181
- end
182
216
  end
183
217
  end
184
218
 
185
219
  class V8_1_TrilogyAdapter < V8_1_Mysql2Adapter # rubocop:disable Naming/ClassAndModuleCamelCase
186
- class << self
187
- def register_integrations
188
- require 'active_record/connection_adapters/rails_8_1_trilogy_adapter'
189
- register_rails_8_1_integrations
190
- end
191
-
192
- def create_connection_adapter(**config)
193
- ActiveRecord::ConnectionAdapters::Rails81TrilogyAdapter.new(config)
194
- end
195
-
196
- def departure_adapter_name
197
- 'percona_trilogy'
198
- end
220
+ # def self so TRILOGY_REGISTRATION resolves through the superclass
221
+ def self.registration
222
+ TRILOGY_REGISTRATION
199
223
  end
200
224
  end
201
225
  end
@@ -1,8 +1,8 @@
1
1
  module Departure
2
2
  module RailsPatches
3
3
  module ActiveRecordMigratorWithAdvisoryLockPatch
4
- RELEASE_LOCK_FAILED_MESSAGE = 'Failed to release advisory lock from ActiveRecordMigratorWithAdvisoryLockPatch'
5
- .freeze
4
+ RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock from ActiveRecordMigratorWithAdvisoryLockPatch"
5
+ .freeze
6
6
 
7
7
  def with_advisory_lock
8
8
  return super if Departure.configuration.disable_rails_advisory_lock_patch
@@ -1,14 +1,14 @@
1
- require 'departure'
2
- require 'lhm' # It's our own Lhm adapter, not the gem
3
- require 'rails'
1
+ require "departure"
2
+ require "lhm" # It's our own Lhm adapter, not the gem
3
+ require "rails"
4
4
 
5
5
  module Departure
6
6
  class Railtie < Rails::Railtie
7
7
  railtie_name :departure
8
8
 
9
- initializer 'departure.configure' do |app|
9
+ initializer "departure.configure" do |app|
10
10
  Departure.configure do |config|
11
- config.tmp_path = app.paths['tmp'].first
11
+ config.tmp_path = app.paths["tmp"].first
12
12
  end
13
13
 
14
14
  Departure::RailsAdapter.register_integrations