departure 8.1.0 → 8.3.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 +8 -9
  7. data/CHANGELOG.md +7 -1
  8. data/Gemfile +8 -9
  9. data/Gemfile.lock +29 -12
  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 +23 -24
  15. data/gemfiles/rails_7_2.gemfile +11 -12
  16. data/gemfiles/rails_7_2.gemfile.lock +29 -12
  17. data/gemfiles/rails_8_0.gemfile +11 -12
  18. data/gemfiles/rails_8_0.gemfile.lock +29 -12
  19. data/gemfiles/rails_8_1.gemfile +10 -12
  20. data/gemfiles/rails_8_1.gemfile.lock +27 -13
  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 +125 -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 +34 -19
  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,177 @@ 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 "departure/rails_patches/active_record_migrator_with_advisory_lock_patch"
72
+
73
+ ActiveRecord::Migration.class_eval do
74
+ include Departure::Migration
75
+ end
76
+
77
+ ActiveRecord::Migrator.prepend Departure::RailsPatches::ActiveRecordMigratorWithAdvisoryLockPatch
78
+
79
+ registrations.each do |registration|
80
+ ActiveRecord::ConnectionAdapters.register registration.adapter_name,
81
+ registration.class_name,
82
+ registration.path
83
+ end
55
84
  end
56
85
 
57
- # ActiveRecord::ConnectionAdapters::Mysql2Adapter
58
- def create_connection_adapter(**_config)
59
- raise MustImplementError, 'adapter must implement create_connection_adapter'
86
+ def create_connection_adapter(**config)
87
+ connection_adapter_class.new(config)
60
88
  end
61
89
 
62
90
  def departure_adapter_name
63
- 'percona'
91
+ registration.adapter_name
64
92
  end
65
93
 
66
94
  # https://github.com/rails/rails/commit/9ad36e067222478090b36a985090475bb03e398c#diff-de807ece2205a84c0e3de66b0e5ab831325d567893b8b88ce0d6e9d498f923d1
67
95
  # Rails Column arity changed to require cast_type in position 2 which required us introducing this indirection
68
96
  def new_sql_column(name:,
69
- default_value:,
70
- mysql_metadata:,
71
- null_value:,
72
- **_kwargs)
97
+ default_value:,
98
+ mysql_metadata:,
99
+ null_value:,
100
+ **_kwargs)
73
101
  sql_column.new(name, default_value, mysql_metadata, null_value)
74
102
  end
75
103
 
76
104
  def sql_column
77
- ::ActiveRecord::ConnectionAdapters::DepartureAdapter::Column
105
+ connection_adapter_class::Column
106
+ end
107
+
108
+ private
109
+
110
+ def connection_adapter_class
111
+ require registration.path
112
+
113
+ Object.const_get(registration.class_name)
78
114
  end
79
115
  end
80
116
  end
81
117
 
82
118
  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
119
+ MYSQL2_REGISTRATION = Registration.new(
120
+ "percona",
121
+ "ActiveRecord::ConnectionAdapters::Rails72DepartureAdapter",
122
+ "active_record/connection_adapters/rails_7_2_departure_adapter"
123
+ )
124
+ TRILOGY_REGISTRATION = Registration.new(
125
+ "percona_trilogy",
126
+ "ActiveRecord::ConnectionAdapters::Rails72TrilogyAdapter",
127
+ "active_record/connection_adapters/rails_7_2_trilogy_adapter"
128
+ )
91
129
 
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'
130
+ class << self
131
+ def registration
132
+ MYSQL2_REGISTRATION
97
133
  end
98
134
 
99
- def create_connection_adapter(**config)
100
- ActiveRecord::ConnectionAdapters::Rails72DepartureAdapter.new(config)
135
+ def registrations
136
+ [MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
101
137
  end
138
+ end
139
+ end
102
140
 
103
- def sql_column
104
- ::ActiveRecord::ConnectionAdapters::Rails72DepartureAdapter::Column
105
- end
141
+ class V7_2_TrilogyAdapter < V7_2_Adapter # rubocop:disable Naming/ClassAndModuleCamelCase
142
+ # def self so TRILOGY_REGISTRATION resolves through the superclass
143
+ def self.registration
144
+ TRILOGY_REGISTRATION
106
145
  end
107
146
  end
108
147
 
109
148
  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
149
+ MYSQL2_REGISTRATION = Registration.new(
150
+ "percona",
151
+ "ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter",
152
+ "active_record/connection_adapters/rails_8_0_departure_adapter"
153
+ )
154
+ TRILOGY_REGISTRATION = Registration.new(
155
+ "percona_trilogy",
156
+ "ActiveRecord::ConnectionAdapters::Rails80TrilogyAdapter",
157
+ "active_record/connection_adapters/rails_8_0_trilogy_adapter"
158
+ )
118
159
 
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'
160
+ class << self
161
+ def registration
162
+ MYSQL2_REGISTRATION
124
163
  end
125
164
 
126
- def create_connection_adapter(**config)
127
- ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter.new(config)
165
+ def registrations
166
+ [MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
128
167
  end
168
+ end
169
+ end
129
170
 
130
- def sql_column
131
- ::ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter::Column
132
- end
171
+ class V8_0_TrilogyAdapter < V8_0_Adapter # rubocop:disable Naming/ClassAndModuleCamelCase
172
+ # def self so TRILOGY_REGISTRATION resolves through the superclass
173
+ def self.registration
174
+ TRILOGY_REGISTRATION
133
175
  end
134
176
  end
135
177
 
136
178
  class V8_1_Mysql2Adapter < BaseAdapter # rubocop:disable Naming/ClassAndModuleCamelCase
179
+ MYSQL2_REGISTRATION = Registration.new(
180
+ "percona",
181
+ "ActiveRecord::ConnectionAdapters::Rails81Mysql2Adapter",
182
+ "active_record/connection_adapters/rails_8_1_mysql2_adapter"
183
+ )
184
+ TRILOGY_REGISTRATION = Registration.new(
185
+ "percona_trilogy",
186
+ "ActiveRecord::ConnectionAdapters::Rails81TrilogyAdapter",
187
+ "active_record/connection_adapters/rails_8_1_trilogy_adapter"
188
+ )
189
+
137
190
  class << self
138
- def register_integrations
139
- require 'active_record/connection_adapters/rails_8_1_mysql2_adapter'
140
- register_rails_8_1_integrations
191
+ def registration
192
+ MYSQL2_REGISTRATION
141
193
  end
142
194
 
143
- def create_connection_adapter(**config)
144
- ActiveRecord::ConnectionAdapters::Rails81Mysql2Adapter.new(config)
195
+ def registrations
196
+ [MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
145
197
  end
146
198
 
147
199
  # rubocop:disable Metrics/ParameterLists
148
200
  # https://github.com/rails/rails/commit/9ad36e067222478090b36a985090475bb03e398c#diff-de807ece2205a84c0e3de66b0e5ab831325d567893b8b88ce0d6e9d498f923d1
149
201
  # Rails Column arity changed to require cast_type in position 2 which required us introducing this indirection
150
202
  def new_sql_column(name:,
151
- cast_type:,
152
- default_value:,
153
- mysql_metadata:,
154
- null_value:,
155
- **_kwargs)
203
+ cast_type:,
204
+ default_value:,
205
+ mysql_metadata:,
206
+ null_value:,
207
+ **_kwargs)
156
208
  # rubocop:enable Metrics/ParameterLists
157
209
  sql_column.new(name, cast_type, default_value, mysql_metadata, null_value)
158
210
  end
@@ -160,42 +212,13 @@ module Departure
160
212
  def sql_column
161
213
  ::ActiveRecord::ConnectionAdapters::MySQL::Column
162
214
  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
215
  end
183
216
  end
184
217
 
185
218
  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
219
+ # def self so TRILOGY_REGISTRATION resolves through the superclass
220
+ def self.registration
221
+ TRILOGY_REGISTRATION
199
222
  end
200
223
  end
201
224
  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