departure 8.0.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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +41 -2
- data/.pryrc +6 -6
- data/.standard.yml +9 -0
- data/AGENTS.md +77 -0
- data/Appraisals +11 -8
- data/CHANGELOG.md +16 -0
- data/Gemfile +8 -9
- data/Gemfile.lock +25 -11
- data/README.md +26 -4
- data/RELEASING.md +5 -4
- data/Rakefile +10 -10
- data/configuration.rb +3 -3
- data/departure.gemspec +26 -29
- data/gemfiles/rails_7_2.gemfile +2 -2
- data/gemfiles/rails_7_2.gemfile.lock +28 -11
- data/gemfiles/rails_8_0.gemfile +2 -2
- data/gemfiles/rails_8_0.gemfile.lock +28 -11
- data/gemfiles/rails_8_1.gemfile +3 -3
- data/gemfiles/rails_8_1.gemfile.lock +27 -11
- data/lib/active_record/connection_adapters/departure_adapter_behavior.rb +88 -0
- data/lib/active_record/connection_adapters/for_alter.rb +4 -10
- data/lib/active_record/connection_adapters/patch_connection_handling.rb +7 -6
- data/lib/active_record/connection_adapters/rails_7_2_departure_adapter.rb +17 -58
- data/lib/active_record/connection_adapters/rails_7_2_trilogy_adapter.rb +53 -0
- data/lib/active_record/connection_adapters/rails_8_0_departure_adapter.rb +26 -66
- data/lib/active_record/connection_adapters/rails_8_0_trilogy_adapter.rb +21 -0
- data/lib/active_record/connection_adapters/rails_8_1_mysql2_adapter.rb +23 -0
- data/lib/active_record/connection_adapters/rails_8_1_trilogy_adapter.rb +21 -0
- data/lib/departure/alter_argument.rb +6 -6
- data/lib/departure/cli_generator.rb +12 -12
- data/lib/departure/command.rb +1 -1
- data/lib/departure/configuration.rb +3 -3
- data/lib/departure/connection_details.rb +7 -7
- data/lib/departure/db_client.rb +5 -5
- data/lib/departure/dsn.rb +2 -2
- data/lib/departure/errors.rb +2 -2
- data/lib/departure/log_sanitizers/password_sanitizer.rb +1 -1
- data/lib/departure/logger.rb +2 -2
- data/lib/departure/migration.rb +40 -10
- data/lib/departure/option.rb +4 -4
- data/lib/departure/rails_adapter.rb +145 -85
- data/lib/departure/rails_patches/active_record_migrator_with_advisory_lock_patch.rb +2 -2
- data/lib/departure/railtie.rb +7 -5
- data/lib/departure/runner.rb +3 -3
- data/lib/departure/user_options.rb +1 -1
- data/lib/departure/version.rb +1 -1
- data/lib/departure.rb +21 -23
- data/lib/lhm/adapter.rb +12 -12
- data/lib/lhm/column_with_sql.rb +8 -8
- data/lib/lhm.rb +1 -1
- data/test_database.rb +10 -10
- metadata +12 -4
- data/.rubocop.yml +0 -66
- data/.rubocop_todo.yml +0 -238
- data/lib/active_record/connection_adapters/rails_8_1_departure_adapter.rb +0 -83
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "forwardable"
|
|
4
4
|
|
|
5
5
|
module Departure
|
|
6
6
|
class RailsAdapter
|
|
@@ -9,8 +9,19 @@ 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
|
|
18
|
+
def register_integrations(**args)
|
|
19
|
+
for_current(**args).register_integrations
|
|
20
|
+
end
|
|
21
|
+
|
|
13
22
|
def version_matches?(version_string, compatibility_string = current_version::STRING)
|
|
23
|
+
raise "Invalid Gem Version: '#{version_string}'" unless Gem::Version.correct?(version_string)
|
|
24
|
+
|
|
14
25
|
requirement = Gem::Requirement.new(compatibility_string)
|
|
15
26
|
requirement.satisfied_by?(Gem::Version.new(version_string))
|
|
16
27
|
end
|
|
@@ -19,140 +30,182 @@ module Departure
|
|
|
19
30
|
ActiveRecord::VERSION
|
|
20
31
|
end
|
|
21
32
|
|
|
22
|
-
def for_current
|
|
23
|
-
self.for(current_version)
|
|
33
|
+
def for_current(**args)
|
|
34
|
+
self.for(current_version, **args)
|
|
24
35
|
end
|
|
25
36
|
|
|
26
|
-
def for(ar_version)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
def for(ar_version, db_connection_adapter: nil)
|
|
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}
|
|
45
|
+
else
|
|
46
|
+
raise UnsupportedRailsVersionError, "Unsupported Rails version: #{ar_version}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
(db_connection_adapter == "trilogy") ? adapters[:trilogy] : adapters[:mysql2]
|
|
36
50
|
end
|
|
37
51
|
end
|
|
38
52
|
|
|
39
53
|
class BaseAdapter
|
|
40
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
|
+
|
|
41
70
|
def register_integrations
|
|
42
|
-
|
|
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
|
|
43
85
|
end
|
|
44
86
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
87
|
+
def create_connection_adapter(**config)
|
|
88
|
+
connection_adapter_class.new(config)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def departure_adapter_name
|
|
92
|
+
registration.adapter_name
|
|
48
93
|
end
|
|
49
94
|
|
|
50
95
|
# https://github.com/rails/rails/commit/9ad36e067222478090b36a985090475bb03e398c#diff-de807ece2205a84c0e3de66b0e5ab831325d567893b8b88ce0d6e9d498f923d1
|
|
51
96
|
# Rails Column arity changed to require cast_type in position 2 which required us introducing this indirection
|
|
52
97
|
def new_sql_column(name:,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
98
|
+
default_value:,
|
|
99
|
+
mysql_metadata:,
|
|
100
|
+
null_value:,
|
|
101
|
+
**_kwargs)
|
|
57
102
|
sql_column.new(name, default_value, mysql_metadata, null_value)
|
|
58
103
|
end
|
|
59
104
|
|
|
60
105
|
def sql_column
|
|
61
|
-
::
|
|
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)
|
|
62
115
|
end
|
|
63
116
|
end
|
|
64
117
|
end
|
|
65
118
|
|
|
66
119
|
class V7_2_Adapter < BaseAdapter # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
ActiveRecord::Migrator.prepend Departure::RailsPatches::ActiveRecordMigratorWithAdvisoryLockPatch
|
|
78
|
-
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
|
+
)
|
|
79
130
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
131
|
+
class << self
|
|
132
|
+
def registration
|
|
133
|
+
MYSQL2_REGISTRATION
|
|
83
134
|
end
|
|
84
135
|
|
|
85
|
-
def
|
|
86
|
-
|
|
136
|
+
def registrations
|
|
137
|
+
[MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
|
|
87
138
|
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
88
141
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
|
92
146
|
end
|
|
93
147
|
end
|
|
94
148
|
|
|
95
149
|
class V8_0_Adapter < BaseAdapter # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
ActiveRecord::Migrator.prepend Departure::RailsPatches::ActiveRecordMigratorWithAdvisoryLockPatch
|
|
107
|
-
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
|
+
)
|
|
108
160
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def create_connection_adapter(**config)
|
|
115
|
-
ActiveRecord::ConnectionAdapters::Rails80DepartureAdapter.new(config)
|
|
161
|
+
class << self
|
|
162
|
+
def registration
|
|
163
|
+
MYSQL2_REGISTRATION
|
|
116
164
|
end
|
|
117
165
|
|
|
118
|
-
def
|
|
119
|
-
|
|
166
|
+
def registrations
|
|
167
|
+
[MYSQL2_REGISTRATION, TRILOGY_REGISTRATION]
|
|
120
168
|
end
|
|
121
169
|
end
|
|
122
170
|
end
|
|
123
171
|
|
|
124
|
-
class
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
|
176
|
+
end
|
|
177
|
+
end
|
|
129
178
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
+
)
|
|
134
190
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
ActiveRecord::ConnectionAdapters.register 'percona',
|
|
139
|
-
'ActiveRecord::ConnectionAdapters::Rails81DepartureAdapter',
|
|
140
|
-
'active_record/connection_adapters/rails_8_1_departure_adapter'
|
|
191
|
+
class << self
|
|
192
|
+
def registration
|
|
193
|
+
MYSQL2_REGISTRATION
|
|
141
194
|
end
|
|
142
195
|
|
|
143
|
-
def
|
|
144
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
|
@@ -162,5 +215,12 @@ module Departure
|
|
|
162
215
|
end
|
|
163
216
|
end
|
|
164
217
|
end
|
|
218
|
+
|
|
219
|
+
class V8_1_TrilogyAdapter < V8_1_Mysql2Adapter # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
220
|
+
# def self so TRILOGY_REGISTRATION resolves through the superclass
|
|
221
|
+
def self.registration
|
|
222
|
+
TRILOGY_REGISTRATION
|
|
223
|
+
end
|
|
224
|
+
end
|
|
165
225
|
end
|
|
166
226
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Departure
|
|
2
2
|
module RailsPatches
|
|
3
3
|
module ActiveRecordMigratorWithAdvisoryLockPatch
|
|
4
|
-
RELEASE_LOCK_FAILED_MESSAGE =
|
|
5
|
-
|
|
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
|
data/lib/departure/railtie.rb
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
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
|
|
9
|
+
initializer "departure.configure" do |app|
|
|
10
10
|
Departure.configure do |config|
|
|
11
|
-
config.tmp_path = app.paths[
|
|
11
|
+
config.tmp_path = app.paths["tmp"].first
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
Departure::RailsAdapter.register_integrations
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
config.after_initialize do
|
data/lib/departure/runner.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "open3"
|
|
2
|
+
require "forwardable"
|
|
3
3
|
|
|
4
4
|
# Runner is deprecated and used in rails 8.0 and below
|
|
5
5
|
# We will slowly reduce the responsibility of departure to be delegating
|
|
@@ -11,7 +11,7 @@ module Departure
|
|
|
11
11
|
class Runner
|
|
12
12
|
extend ::Forwardable
|
|
13
13
|
|
|
14
|
-
def_delegators :raw_connection, :
|
|
14
|
+
def_delegators :raw_connection, :escape, :close
|
|
15
15
|
|
|
16
16
|
# Constructor
|
|
17
17
|
#
|
data/lib/departure/version.rb
CHANGED
data/lib/departure.rb
CHANGED
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
12
|
-
require
|
|
13
|
-
require
|
|
14
|
-
require
|
|
15
|
-
require
|
|
16
|
-
require
|
|
17
|
-
require
|
|
18
|
-
require
|
|
19
|
-
require
|
|
20
|
-
|
|
21
|
-
require
|
|
1
|
+
require "active_record"
|
|
2
|
+
require "active_support/all"
|
|
3
|
+
|
|
4
|
+
require "active_record/connection_adapters/for_alter"
|
|
5
|
+
|
|
6
|
+
require "departure/version"
|
|
7
|
+
require "departure/log_sanitizers/password_sanitizer"
|
|
8
|
+
require "departure/db_client"
|
|
9
|
+
require "departure/runner"
|
|
10
|
+
require "departure/cli_generator"
|
|
11
|
+
require "departure/logger"
|
|
12
|
+
require "departure/null_logger"
|
|
13
|
+
require "departure/logger_factory"
|
|
14
|
+
require "departure/configuration"
|
|
15
|
+
require "departure/errors"
|
|
16
|
+
require "departure/command"
|
|
17
|
+
require "departure/connection_base"
|
|
18
|
+
require "departure/migration"
|
|
19
|
+
require "departure/rails_adapter"
|
|
20
|
+
|
|
21
|
+
require "departure/railtie" if defined?(Rails)
|
|
22
22
|
|
|
23
23
|
# We need the OS not to buffer the IO to see pt-osc's output while migrating
|
|
24
24
|
$stdout.sync = true
|
|
25
25
|
|
|
26
|
-
Departure::RailsAdapter.for_current.register_integrations
|
|
27
|
-
|
|
28
26
|
module Departure
|
|
29
27
|
class << self
|
|
30
28
|
attr_accessor :configuration
|
data/lib/lhm/adapter.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "lhm/column_with_sql"
|
|
2
|
+
require "lhm/column_with_type"
|
|
3
3
|
|
|
4
4
|
module Lhm
|
|
5
5
|
# Translates Lhm DSL to ActiveRecord's one, so Lhm migrations will now go
|
|
@@ -37,7 +37,7 @@ module Lhm
|
|
|
37
37
|
# @param columns [Array<String>, Array<Symbol>, String, Symbol]
|
|
38
38
|
# @param index_name [String]
|
|
39
39
|
def add_index(columns, index_name = nil)
|
|
40
|
-
options = {
|
|
40
|
+
options = {name: index_name} if index_name
|
|
41
41
|
migration.add_index(table_name, columns, options || {})
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -47,10 +47,10 @@ module Lhm
|
|
|
47
47
|
# @param index_name [String]
|
|
48
48
|
def remove_index(columns, index_name = nil)
|
|
49
49
|
options = if index_name
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
{name: index_name}
|
|
51
|
+
else
|
|
52
|
+
{column: columns}
|
|
53
|
+
end
|
|
54
54
|
migration.remove_index(table_name, options)
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -76,7 +76,7 @@ module Lhm
|
|
|
76
76
|
# @param columns [Array<String>, Array<Symbol>, String, Symbol]
|
|
77
77
|
# @param index_name [String]
|
|
78
78
|
def add_unique_index(columns, index_name = nil)
|
|
79
|
-
options = {
|
|
79
|
+
options = {unique: true}
|
|
80
80
|
options.merge!(name: index_name) if index_name # rubocop:disable Performance/RedundantMerge
|
|
81
81
|
|
|
82
82
|
migration.add_index(table_name, columns, options)
|
|
@@ -93,10 +93,10 @@ module Lhm
|
|
|
93
93
|
# @param definition [String]
|
|
94
94
|
def column(name, definition)
|
|
95
95
|
@column ||= if definition.is_a?(Symbol)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
ColumnWithType.new(name, definition)
|
|
97
|
+
else
|
|
98
|
+
ColumnWithSql.new(name, definition)
|
|
99
|
+
end
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
def column_attributes(name, definition)
|
data/lib/lhm/column_with_sql.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "forwardable"
|
|
2
2
|
|
|
3
3
|
module Lhm
|
|
4
4
|
# Abstracts the details of a table column definition when specified with a MySQL
|
|
@@ -38,7 +38,7 @@ module Lhm
|
|
|
38
38
|
#
|
|
39
39
|
# @return [Hash]
|
|
40
40
|
def column_options
|
|
41
|
-
{
|
|
41
|
+
{limit: column.limit, default: column.default, null: column.null}
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Returns the column instance with the provided data
|
|
@@ -67,14 +67,14 @@ module Lhm
|
|
|
67
67
|
# @return [String, NilClass]
|
|
68
68
|
def default_value
|
|
69
69
|
match = if definition.match?(/timestamp|datetime/i)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
/default '?(.+[^'])'?/i.match(definition)
|
|
71
|
+
else
|
|
72
|
+
/default '?(\w+)'?/i.match(definition)
|
|
73
|
+
end
|
|
74
74
|
|
|
75
75
|
return unless match
|
|
76
76
|
|
|
77
|
-
match[1].downcase !=
|
|
77
|
+
(match[1].downcase != "null") ? match[1] : nil
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
# Checks whether the column accepts NULL as specified in the definition
|
|
@@ -84,7 +84,7 @@ module Lhm
|
|
|
84
84
|
match = /((NOT)? NULL)/i.match(definition)
|
|
85
85
|
return true unless match
|
|
86
86
|
|
|
87
|
-
match[2]&.downcase ==
|
|
87
|
+
!(match[2]&.downcase == "not")
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
end
|
data/lib/lhm.rb
CHANGED
data/test_database.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
1
|
+
require "active_record"
|
|
2
|
+
require "active_record/connection_adapters/mysql2_adapter"
|
|
3
|
+
require "departure"
|
|
4
4
|
|
|
5
5
|
# Setups the test database with the schema_migrations table that ActiveRecord
|
|
6
6
|
# requires for the migrations, plus a table for the Comment model used throught
|
|
@@ -12,7 +12,7 @@ class TestDatabase
|
|
|
12
12
|
# @param config [Hash]
|
|
13
13
|
def initialize(config)
|
|
14
14
|
@config = config
|
|
15
|
-
@database = config[
|
|
15
|
+
@database = config["database"]
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# Creates the test database, the schema_migrations and the comments tables.
|
|
@@ -34,8 +34,8 @@ class TestDatabase
|
|
|
34
34
|
def drop_and_create_schema_migrations_table
|
|
35
35
|
sql = [
|
|
36
36
|
"USE #{@database}",
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
"DROP TABLE IF EXISTS schema_migrations",
|
|
38
|
+
"CREATE TABLE schema_migrations ( version varchar(255) COLLATE utf8_unicode_ci NOT NULL, UNIQUE KEY unique_schema_migrations (version)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
|
|
39
39
|
]
|
|
40
40
|
|
|
41
41
|
run_commands(sql)
|
|
@@ -57,17 +57,17 @@ class TestDatabase
|
|
|
57
57
|
def drop_and_create_comments_table
|
|
58
58
|
sql = [
|
|
59
59
|
"USE #{@database}",
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
"DROP TABLE IF EXISTS comments",
|
|
61
|
+
"CREATE TABLE comments ( id bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
|
|
62
62
|
]
|
|
63
63
|
|
|
64
64
|
run_commands(sql)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def run_commands(sql)
|
|
68
|
-
conn.execute(
|
|
68
|
+
conn.execute("START TRANSACTION")
|
|
69
69
|
sql.each { |str| conn.execute(str) }
|
|
70
|
-
conn.execute(
|
|
70
|
+
conn.execute("COMMIT")
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def conn
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: departure
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.
|
|
4
|
+
version: 8.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ilya Zayats
|
|
@@ -12,6 +12,8 @@ authors:
|
|
|
12
12
|
- Adrian Serafin
|
|
13
13
|
- Kirk Haines
|
|
14
14
|
- Guillermo Iguaran
|
|
15
|
+
- Austin Story
|
|
16
|
+
- Douglas Soares de Andrade
|
|
15
17
|
bindir: bin
|
|
16
18
|
cert_chain: []
|
|
17
19
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
@@ -164,6 +166,8 @@ email:
|
|
|
164
166
|
- adrian@softmad.pl
|
|
165
167
|
- wyhaines@gmail.com
|
|
166
168
|
- guilleiguaran@gmail.com
|
|
169
|
+
- lonnieastory@gmail.com
|
|
170
|
+
- douglas@51street.dev
|
|
167
171
|
executables: []
|
|
168
172
|
extensions: []
|
|
169
173
|
extra_rdoc_files: []
|
|
@@ -173,8 +177,8 @@ files:
|
|
|
173
177
|
- ".gitignore"
|
|
174
178
|
- ".pryrc"
|
|
175
179
|
- ".rspec"
|
|
176
|
-
- ".
|
|
177
|
-
-
|
|
180
|
+
- ".standard.yml"
|
|
181
|
+
- AGENTS.md
|
|
178
182
|
- Appraisals
|
|
179
183
|
- CHANGELOG.md
|
|
180
184
|
- CODE_OF_CONDUCT.md
|
|
@@ -199,11 +203,15 @@ files:
|
|
|
199
203
|
- gemfiles/rails_8_0.gemfile.lock
|
|
200
204
|
- gemfiles/rails_8_1.gemfile
|
|
201
205
|
- gemfiles/rails_8_1.gemfile.lock
|
|
206
|
+
- lib/active_record/connection_adapters/departure_adapter_behavior.rb
|
|
202
207
|
- lib/active_record/connection_adapters/for_alter.rb
|
|
203
208
|
- lib/active_record/connection_adapters/patch_connection_handling.rb
|
|
204
209
|
- lib/active_record/connection_adapters/rails_7_2_departure_adapter.rb
|
|
210
|
+
- lib/active_record/connection_adapters/rails_7_2_trilogy_adapter.rb
|
|
205
211
|
- lib/active_record/connection_adapters/rails_8_0_departure_adapter.rb
|
|
206
|
-
- lib/active_record/connection_adapters/
|
|
212
|
+
- lib/active_record/connection_adapters/rails_8_0_trilogy_adapter.rb
|
|
213
|
+
- lib/active_record/connection_adapters/rails_8_1_mysql2_adapter.rb
|
|
214
|
+
- lib/active_record/connection_adapters/rails_8_1_trilogy_adapter.rb
|
|
207
215
|
- lib/departure.rb
|
|
208
216
|
- lib/departure/alter_argument.rb
|
|
209
217
|
- lib/departure/cli_generator.rb
|