data_migrate 10.0.0.rc1 → 11.0.0.rc
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/build.yml +4 -4
- data/.github/workflows/gempush.yml +6 -8
- data/.gitignore +3 -2
- data/Appraisals +10 -5
- data/Changelog.md +51 -2
- data/Gemfile +0 -1
- data/Gemfile.lock +188 -0
- data/README.md +17 -6
- data/data_migrate.gemspec +2 -2
- data/gemfiles/rails_6.1.gemfile +0 -1
- data/gemfiles/rails_6.1.gemfile.lock +233 -0
- data/gemfiles/rails_7.0.gemfile +1 -2
- data/gemfiles/rails_7.0.gemfile.lock +234 -0
- data/gemfiles/{rails_6.0.gemfile → rails_7.1.gemfile} +1 -2
- data/gemfiles/rails_7.1.gemfile.lock +266 -0
- data/gemfiles/rails_7.2.gemfile +7 -0
- data/gemfiles/rails_7.2.gemfile.lock +265 -0
- data/lib/data_migrate/data_migrator.rb +15 -23
- data/lib/data_migrate/data_schema.rb +2 -2
- data/lib/data_migrate/data_schema_migration.rb +24 -7
- data/lib/data_migrate/database_configurations_wrapper.rb +11 -0
- data/lib/data_migrate/database_tasks.rb +194 -48
- data/lib/data_migrate/migration_context.rb +11 -8
- data/lib/data_migrate/rails_helper.rb +90 -0
- data/lib/data_migrate/schema_dumper.rb +1 -1
- data/lib/data_migrate/schema_migration.rb +5 -4
- data/lib/data_migrate/status_service.rb +4 -4
- data/lib/data_migrate/tasks/data_migrate_tasks.rb +14 -15
- data/lib/data_migrate/test.rb +14 -0
- data/lib/data_migrate/version.rb +1 -1
- data/lib/data_migrate.rb +2 -1
- data/spec/data_migrate/data_migrator_spec.rb +17 -14
- data/spec/data_migrate/data_schema_migration_spec.rb +25 -8
- data/spec/data_migrate/data_spec.rb +1 -1
- data/spec/data_migrate/database_tasks_spec.rb +34 -19
- data/spec/data_migrate/migration_context_spec.rb +25 -9
- data/spec/data_migrate/schema_dumper_spec.rb +6 -3
- data/spec/data_migrate/schema_migration_spec.rb +13 -6
- data/spec/data_migrate/status_service_spec.rb +7 -4
- data/spec/data_migrate/tasks/data_migrate_tasks_spec.rb +13 -14
- data/spec/db/data/20091231235959_some_name.rb +1 -1
- data/spec/db/data/20171231235959_super_update.rb +1 -1
- data/spec/db/migrate/20131111111111_late_migration.rb +1 -1
- data/spec/db/migrate/20202020202011_db_migration.rb +1 -1
- data/tasks/databases.rake +25 -83
- metadata +21 -17
- data/.ruby-version +0 -1
- data/.travis.yml +0 -14
- data/Gemfile.rails6.1 +0 -11
- data/lib/data_migrate/legacy_migrator.rb +0 -22
- data/spec/data_migrate/legacy_migrator_spec.rb +0 -38
@@ -0,0 +1,265 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
data_migrate (11.0.0.rc)
|
5
|
+
activerecord (>= 6.1)
|
6
|
+
railties (>= 6.1)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actioncable (7.2.0)
|
12
|
+
actionpack (= 7.2.0)
|
13
|
+
activesupport (= 7.2.0)
|
14
|
+
nio4r (~> 2.0)
|
15
|
+
websocket-driver (>= 0.6.1)
|
16
|
+
zeitwerk (~> 2.6)
|
17
|
+
actionmailbox (7.2.0)
|
18
|
+
actionpack (= 7.2.0)
|
19
|
+
activejob (= 7.2.0)
|
20
|
+
activerecord (= 7.2.0)
|
21
|
+
activestorage (= 7.2.0)
|
22
|
+
activesupport (= 7.2.0)
|
23
|
+
mail (>= 2.8.0)
|
24
|
+
actionmailer (7.2.0)
|
25
|
+
actionpack (= 7.2.0)
|
26
|
+
actionview (= 7.2.0)
|
27
|
+
activejob (= 7.2.0)
|
28
|
+
activesupport (= 7.2.0)
|
29
|
+
mail (>= 2.8.0)
|
30
|
+
rails-dom-testing (~> 2.2)
|
31
|
+
actionpack (7.2.0)
|
32
|
+
actionview (= 7.2.0)
|
33
|
+
activesupport (= 7.2.0)
|
34
|
+
nokogiri (>= 1.8.5)
|
35
|
+
racc
|
36
|
+
rack (>= 2.2.4, < 3.2)
|
37
|
+
rack-session (>= 1.0.1)
|
38
|
+
rack-test (>= 0.6.3)
|
39
|
+
rails-dom-testing (~> 2.2)
|
40
|
+
rails-html-sanitizer (~> 1.6)
|
41
|
+
useragent (~> 0.16)
|
42
|
+
actiontext (7.2.0)
|
43
|
+
actionpack (= 7.2.0)
|
44
|
+
activerecord (= 7.2.0)
|
45
|
+
activestorage (= 7.2.0)
|
46
|
+
activesupport (= 7.2.0)
|
47
|
+
globalid (>= 0.6.0)
|
48
|
+
nokogiri (>= 1.8.5)
|
49
|
+
actionview (7.2.0)
|
50
|
+
activesupport (= 7.2.0)
|
51
|
+
builder (~> 3.1)
|
52
|
+
erubi (~> 1.11)
|
53
|
+
rails-dom-testing (~> 2.2)
|
54
|
+
rails-html-sanitizer (~> 1.6)
|
55
|
+
activejob (7.2.0)
|
56
|
+
activesupport (= 7.2.0)
|
57
|
+
globalid (>= 0.3.6)
|
58
|
+
activemodel (7.2.0)
|
59
|
+
activesupport (= 7.2.0)
|
60
|
+
activerecord (7.2.0)
|
61
|
+
activemodel (= 7.2.0)
|
62
|
+
activesupport (= 7.2.0)
|
63
|
+
timeout (>= 0.4.0)
|
64
|
+
activestorage (7.2.0)
|
65
|
+
actionpack (= 7.2.0)
|
66
|
+
activejob (= 7.2.0)
|
67
|
+
activerecord (= 7.2.0)
|
68
|
+
activesupport (= 7.2.0)
|
69
|
+
marcel (~> 1.0)
|
70
|
+
activesupport (7.2.0)
|
71
|
+
base64
|
72
|
+
bigdecimal
|
73
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
74
|
+
connection_pool (>= 2.2.5)
|
75
|
+
drb
|
76
|
+
i18n (>= 1.6, < 2)
|
77
|
+
logger (>= 1.4.2)
|
78
|
+
minitest (>= 5.1)
|
79
|
+
securerandom (>= 0.3)
|
80
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
81
|
+
appraisal (2.5.0)
|
82
|
+
bundler
|
83
|
+
rake
|
84
|
+
thor (>= 0.14.0)
|
85
|
+
ast (2.4.2)
|
86
|
+
base64 (0.2.0)
|
87
|
+
bigdecimal (3.1.8)
|
88
|
+
builder (3.3.0)
|
89
|
+
childprocess (5.0.0)
|
90
|
+
coderay (1.1.3)
|
91
|
+
concurrent-ruby (1.3.4)
|
92
|
+
connection_pool (2.4.1)
|
93
|
+
crass (1.0.6)
|
94
|
+
date (3.3.4)
|
95
|
+
diff-lcs (1.5.1)
|
96
|
+
drb (2.2.1)
|
97
|
+
erubi (1.13.0)
|
98
|
+
globalid (1.2.1)
|
99
|
+
activesupport (>= 6.1)
|
100
|
+
i18n (1.14.5)
|
101
|
+
concurrent-ruby (~> 1.0)
|
102
|
+
iniparse (1.5.0)
|
103
|
+
io-console (0.7.2)
|
104
|
+
irb (1.14.0)
|
105
|
+
rdoc (>= 4.0.0)
|
106
|
+
reline (>= 0.4.2)
|
107
|
+
json (2.7.2)
|
108
|
+
language_server-protocol (3.17.0.3)
|
109
|
+
logger (1.6.0)
|
110
|
+
loofah (2.22.0)
|
111
|
+
crass (~> 1.0.2)
|
112
|
+
nokogiri (>= 1.12.0)
|
113
|
+
mail (2.8.1)
|
114
|
+
mini_mime (>= 0.1.1)
|
115
|
+
net-imap
|
116
|
+
net-pop
|
117
|
+
net-smtp
|
118
|
+
marcel (1.0.4)
|
119
|
+
method_source (1.1.0)
|
120
|
+
mini_mime (1.1.5)
|
121
|
+
minitest (5.25.1)
|
122
|
+
net-imap (0.4.14)
|
123
|
+
date
|
124
|
+
net-protocol
|
125
|
+
net-pop (0.1.2)
|
126
|
+
net-protocol
|
127
|
+
net-protocol (0.2.2)
|
128
|
+
timeout
|
129
|
+
net-smtp (0.5.0)
|
130
|
+
net-protocol
|
131
|
+
nio4r (2.7.3)
|
132
|
+
nokogiri (1.16.7-aarch64-linux)
|
133
|
+
racc (~> 1.4)
|
134
|
+
nokogiri (1.16.7-arm64-darwin)
|
135
|
+
racc (~> 1.4)
|
136
|
+
nokogiri (1.16.7-x86_64-linux)
|
137
|
+
racc (~> 1.4)
|
138
|
+
overcommit (0.63.0)
|
139
|
+
childprocess (>= 0.6.3, < 6)
|
140
|
+
iniparse (~> 1.4)
|
141
|
+
rexml (~> 3.2)
|
142
|
+
parallel (1.24.0)
|
143
|
+
parser (3.3.1.0)
|
144
|
+
ast (~> 2.4.1)
|
145
|
+
racc
|
146
|
+
pry (0.14.2)
|
147
|
+
coderay (~> 1.1)
|
148
|
+
method_source (~> 1.0)
|
149
|
+
psych (5.1.2)
|
150
|
+
stringio
|
151
|
+
racc (1.8.1)
|
152
|
+
rack (3.1.7)
|
153
|
+
rack-session (2.0.0)
|
154
|
+
rack (>= 3.0.0)
|
155
|
+
rack-test (2.1.0)
|
156
|
+
rack (>= 1.3)
|
157
|
+
rackup (2.1.0)
|
158
|
+
rack (>= 3)
|
159
|
+
webrick (~> 1.8)
|
160
|
+
rails (7.2.0)
|
161
|
+
actioncable (= 7.2.0)
|
162
|
+
actionmailbox (= 7.2.0)
|
163
|
+
actionmailer (= 7.2.0)
|
164
|
+
actionpack (= 7.2.0)
|
165
|
+
actiontext (= 7.2.0)
|
166
|
+
actionview (= 7.2.0)
|
167
|
+
activejob (= 7.2.0)
|
168
|
+
activemodel (= 7.2.0)
|
169
|
+
activerecord (= 7.2.0)
|
170
|
+
activestorage (= 7.2.0)
|
171
|
+
activesupport (= 7.2.0)
|
172
|
+
bundler (>= 1.15.0)
|
173
|
+
railties (= 7.2.0)
|
174
|
+
rails-dom-testing (2.2.0)
|
175
|
+
activesupport (>= 5.0.0)
|
176
|
+
minitest
|
177
|
+
nokogiri (>= 1.6)
|
178
|
+
rails-html-sanitizer (1.6.0)
|
179
|
+
loofah (~> 2.21)
|
180
|
+
nokogiri (~> 1.14)
|
181
|
+
railties (7.2.0)
|
182
|
+
actionpack (= 7.2.0)
|
183
|
+
activesupport (= 7.2.0)
|
184
|
+
irb (~> 1.13)
|
185
|
+
rackup (>= 1.0.0)
|
186
|
+
rake (>= 12.2)
|
187
|
+
thor (~> 1.0, >= 1.2.2)
|
188
|
+
zeitwerk (~> 2.6)
|
189
|
+
rainbow (3.1.1)
|
190
|
+
rake (13.2.1)
|
191
|
+
rb-readline (0.5.5)
|
192
|
+
rdoc (6.7.0)
|
193
|
+
psych (>= 4.0.0)
|
194
|
+
regexp_parser (2.9.2)
|
195
|
+
reline (0.5.9)
|
196
|
+
io-console (~> 0.5)
|
197
|
+
rexml (3.2.8)
|
198
|
+
strscan (>= 3.0.9)
|
199
|
+
rspec (3.13.0)
|
200
|
+
rspec-core (~> 3.13.0)
|
201
|
+
rspec-expectations (~> 3.13.0)
|
202
|
+
rspec-mocks (~> 3.13.0)
|
203
|
+
rspec-core (3.13.0)
|
204
|
+
rspec-support (~> 3.13.0)
|
205
|
+
rspec-expectations (3.13.0)
|
206
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
207
|
+
rspec-support (~> 3.13.0)
|
208
|
+
rspec-mocks (3.13.1)
|
209
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
210
|
+
rspec-support (~> 3.13.0)
|
211
|
+
rspec-support (3.13.1)
|
212
|
+
rubocop (1.64.0)
|
213
|
+
json (~> 2.3)
|
214
|
+
language_server-protocol (>= 3.17.0)
|
215
|
+
parallel (~> 1.10)
|
216
|
+
parser (>= 3.3.0.2)
|
217
|
+
rainbow (>= 2.2.2, < 4.0)
|
218
|
+
regexp_parser (>= 1.8, < 3.0)
|
219
|
+
rexml (>= 3.2.5, < 4.0)
|
220
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
221
|
+
ruby-progressbar (~> 1.7)
|
222
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
223
|
+
rubocop-ast (1.31.3)
|
224
|
+
parser (>= 3.3.1.0)
|
225
|
+
ruby-progressbar (1.13.0)
|
226
|
+
securerandom (0.3.1)
|
227
|
+
sqlite3 (2.0.2-aarch64-linux-gnu)
|
228
|
+
sqlite3 (2.0.2-arm64-darwin)
|
229
|
+
sqlite3 (2.0.2-x86_64-linux-gnu)
|
230
|
+
stringio (3.1.1)
|
231
|
+
strscan (3.1.0)
|
232
|
+
thor (1.3.1)
|
233
|
+
timecop (0.9.8)
|
234
|
+
timeout (0.4.1)
|
235
|
+
tzinfo (2.0.6)
|
236
|
+
concurrent-ruby (~> 1.0)
|
237
|
+
unicode-display_width (2.5.0)
|
238
|
+
useragent (0.16.10)
|
239
|
+
webrick (1.8.1)
|
240
|
+
websocket-driver (0.7.6)
|
241
|
+
websocket-extensions (>= 0.1.0)
|
242
|
+
websocket-extensions (0.1.5)
|
243
|
+
zeitwerk (2.6.17)
|
244
|
+
|
245
|
+
PLATFORMS
|
246
|
+
aarch64-linux
|
247
|
+
arm64-darwin-23
|
248
|
+
x86_64-linux
|
249
|
+
|
250
|
+
DEPENDENCIES
|
251
|
+
appraisal
|
252
|
+
data_migrate!
|
253
|
+
overcommit
|
254
|
+
pry
|
255
|
+
rails (~> 7.2.0)
|
256
|
+
rake
|
257
|
+
rb-readline
|
258
|
+
rspec
|
259
|
+
rspec-core
|
260
|
+
rubocop
|
261
|
+
sqlite3
|
262
|
+
timecop
|
263
|
+
|
264
|
+
BUNDLED WITH
|
265
|
+
2.4.17
|
@@ -5,32 +5,20 @@ require "data_migrate/config"
|
|
5
5
|
|
6
6
|
module DataMigrate
|
7
7
|
class DataMigrator < ActiveRecord::Migrator
|
8
|
-
def self.migrations_paths
|
9
|
-
[DataMigrate.config.data_migrations_path]
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.assure_data_schema_table
|
13
|
-
DataMigrate::DataSchemaMigration.create_table
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(direction, migrations, target_version = nil)
|
17
|
-
@direction = direction
|
18
|
-
@target_version = target_version
|
19
|
-
@migrated_versions = nil
|
20
|
-
@migrations = migrations
|
21
|
-
|
22
|
-
validate(@migrations)
|
23
|
-
|
24
|
-
DataMigrate::DataSchemaMigration.create_table
|
25
|
-
ActiveRecord::InternalMetadata.create_table
|
26
|
-
end
|
27
|
-
|
28
8
|
def load_migrated
|
29
9
|
@migrated_versions =
|
30
|
-
DataMigrate::
|
10
|
+
DataMigrate::RailsHelper.data_schema_migration.normalized_versions.map(&:to_i).sort
|
31
11
|
end
|
32
12
|
|
33
13
|
class << self
|
14
|
+
def migrations_paths
|
15
|
+
[DataMigrate.config.data_migrations_path]
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_data_schema_table
|
19
|
+
DataMigrate::RailsHelper.data_schema_migration.create_table
|
20
|
+
end
|
21
|
+
|
34
22
|
def current_version
|
35
23
|
DataMigrate::MigrationContext.new(migrations_paths).current_version
|
36
24
|
end
|
@@ -66,6 +54,10 @@ module DataMigrate
|
|
66
54
|
|
67
55
|
#TODO: this was added to be backward compatible, need to re-evaluate
|
68
56
|
def run(direction, migration_paths, version)
|
57
|
+
# Ensure all Active Record model cache is reset for each data migration
|
58
|
+
# As recommended in: https://github.com/rails/rails/blob/da21c2e9812e5eb0698fba4a9aa38632fc004432/activerecord/lib/active_record/migration.rb#L467-L470
|
59
|
+
ActiveRecord::Base.descendants.each(&:reset_column_information)
|
60
|
+
|
69
61
|
DataMigrate::MigrationContext.new(migration_paths).run(direction, version)
|
70
62
|
end
|
71
63
|
|
@@ -79,10 +71,10 @@ module DataMigrate
|
|
79
71
|
def record_version_state_after_migrating(version)
|
80
72
|
if down?
|
81
73
|
migrated.delete(version)
|
82
|
-
DataMigrate::
|
74
|
+
DataMigrate::RailsHelper.data_schema_delete_version(version.to_s)
|
83
75
|
else
|
84
76
|
migrated << version
|
85
|
-
DataMigrate::
|
77
|
+
DataMigrate::RailsHelper.data_schema_migration.create_version(version.to_s)
|
86
78
|
end
|
87
79
|
end
|
88
80
|
end
|
@@ -9,7 +9,7 @@ module DataMigrate
|
|
9
9
|
# ActiveRecord::ConnectionAdapters::SchemaStatements
|
10
10
|
# #assume_migrated_upto_version
|
11
11
|
def define(info)
|
12
|
-
DataMigrate::DataMigrator.
|
12
|
+
DataMigrate::DataMigrator.create_data_schema_table
|
13
13
|
|
14
14
|
return if info[:version].blank?
|
15
15
|
|
@@ -57,7 +57,7 @@ module DataMigrate
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def table_name
|
60
|
-
DataMigrate::
|
60
|
+
DataMigrate::RailsHelper.data_schema_migration.table_name
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -1,12 +1,29 @@
|
|
1
1
|
module DataMigrate
|
2
|
-
class DataSchemaMigration
|
3
|
-
|
4
|
-
|
2
|
+
class DataSchemaMigration < ActiveRecord::SchemaMigration
|
3
|
+
# In Rails 7.1+, ActiveRecord::SchemaMigration methods are instance methods
|
4
|
+
# So we only load the appropriate methods depending on Rails version.
|
5
|
+
if DataMigrate::RailsHelper.rails_version_equal_to_or_higher_than_7_1
|
6
|
+
def table_name
|
7
|
+
ActiveRecord::Base.table_name_prefix + 'data_migrations' + ActiveRecord::Base.table_name_suffix
|
8
|
+
end
|
9
|
+
|
10
|
+
def primary_key
|
11
|
+
"version"
|
12
|
+
end
|
13
|
+
else
|
14
|
+
class << self
|
15
|
+
def table_name
|
16
|
+
ActiveRecord::Base.table_name_prefix + 'data_migrations' + ActiveRecord::Base.table_name_suffix
|
17
|
+
end
|
18
|
+
|
19
|
+
def primary_key
|
20
|
+
"version"
|
21
|
+
end
|
5
22
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
23
|
+
def create_version(version)
|
24
|
+
# Note that SchemaMigration.create_version in Rails 7.1 does not
|
25
|
+
# raise an error if validations fail but we retain this behaviour for now.
|
26
|
+
create!(version: version)
|
10
27
|
end
|
11
28
|
end
|
12
29
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
# This wrapper is used to differentiate between
|
3
|
+
# a data and schema db config when running migrations
|
4
|
+
class DatabaseConfigurationWrapper
|
5
|
+
attr_reader :db_config
|
6
|
+
|
7
|
+
def initialize(db_config)
|
8
|
+
@db_config = db_config
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -5,67 +5,143 @@ require "data_migrate/config"
|
|
5
5
|
module DataMigrate
|
6
6
|
##
|
7
7
|
# This class extends DatabaseTasks to add a schema_file method.
|
8
|
-
|
8
|
+
module DatabaseTasks
|
9
9
|
extend ActiveRecord::Tasks::DatabaseTasks
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# These method are only introduced in Rails 7.1
|
13
|
+
unless respond_to?(:with_temporary_connection_for_each)
|
14
|
+
def with_temporary_connection_for_each(env: ActiveRecord::Tasks::DatabaseTasks.env, name: nil, &block) # :nodoc:
|
15
|
+
if name
|
16
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env, name: name)
|
17
|
+
with_temporary_connection(db_config, &block)
|
18
|
+
else
|
19
|
+
ActiveRecord::Base.configurations.configs_for(env_name: env, name: name).each do |db_config|
|
20
|
+
with_temporary_connection(db_config, &block)
|
21
|
+
end
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
else
|
20
|
-
"#{spec_name}_#{schema_file_type(format)}"
|
25
|
+
def with_temporary_connection(db_config) # :nodoc:
|
26
|
+
with_temporary_pool(db_config) do |pool|
|
27
|
+
yield pool.connection
|
21
28
|
end
|
29
|
+
end
|
22
30
|
|
23
|
-
|
31
|
+
def migration_class # :nodoc:
|
32
|
+
ActiveRecord::Base
|
24
33
|
end
|
25
34
|
|
26
|
-
def
|
27
|
-
|
28
|
-
message = +%{#{filename} doesn't exist yet. Run `rake data:migrate` to create it, then try again.}
|
29
|
-
Kernel.abort message
|
30
|
-
end
|
35
|
+
def migration_connection # :nodoc:
|
36
|
+
migration_class.connection
|
31
37
|
end
|
32
38
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
private def with_temporary_pool(db_config)
|
40
|
+
original_db_config = migration_class.connection_db_config
|
41
|
+
pool = migration_class.connection_handler.establish_connection(db_config)
|
42
|
+
|
43
|
+
yield pool
|
44
|
+
ensure
|
45
|
+
migration_class.connection_handler.establish_connection(original_db_config)
|
38
46
|
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def db_configs_with_versions
|
50
|
+
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
|
51
|
+
|
52
|
+
with_temporary_connection_for_each do |conn|
|
53
|
+
db_config = conn.pool.db_config
|
54
|
+
if db_config.primary?
|
55
|
+
versions_to_run = DataMigrate::DatabaseTasks.pending_data_migrations.map { |m| m[:version] }
|
56
|
+
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
|
39
57
|
|
40
|
-
|
41
|
-
|
58
|
+
versions_to_run.each do |version|
|
59
|
+
next if target_version && target_version != version
|
60
|
+
db_configs_with_versions[version] << DatabaseConfigurationWrapper.new(db_config)
|
61
|
+
end
|
62
|
+
end
|
42
63
|
end
|
43
64
|
|
44
|
-
|
45
|
-
|
65
|
+
db_configs_with_versions
|
66
|
+
end
|
67
|
+
|
68
|
+
def schema_file(_format = nil)
|
69
|
+
File.join(db_dir, "data_schema.rb")
|
70
|
+
end
|
71
|
+
|
72
|
+
def schema_file_type(_format = nil)
|
73
|
+
"data_schema.rb"
|
74
|
+
end
|
75
|
+
|
76
|
+
# This method is removed in Rails 7.0
|
77
|
+
def dump_filename(spec_name, format = ActiveRecord::Base.schema_format)
|
78
|
+
filename = if spec_name == "primary"
|
79
|
+
schema_file_type(format)
|
80
|
+
else
|
81
|
+
"#{spec_name}_#{schema_file_type(format)}"
|
46
82
|
end
|
47
83
|
|
48
|
-
|
49
|
-
|
84
|
+
ENV["DATA_SCHEMA"] || File.join(db_dir, filename)
|
85
|
+
end
|
86
|
+
|
87
|
+
def check_schema_file(filename)
|
88
|
+
unless File.exist?(filename)
|
89
|
+
message = +%{#{filename} doesn't exist yet. Run `rake data:migrate` to create it, then try again.}
|
90
|
+
Kernel.abort message
|
50
91
|
end
|
92
|
+
end
|
51
93
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
94
|
+
def pending_migrations
|
95
|
+
sort_migrations(
|
96
|
+
pending_schema_migrations,
|
97
|
+
pending_data_migrations
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
def sort_migrations(*migrations)
|
102
|
+
migrations.flatten.sort { |a, b| sort_string(a) <=> sort_string(b) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def sort_string migration
|
106
|
+
"#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def data_migrations_path
|
110
|
+
::DataMigrate.config.data_migrations_path
|
111
|
+
end
|
112
|
+
|
113
|
+
def run_migration(migration, direction)
|
114
|
+
if migration[:kind] == :data
|
115
|
+
::ActiveRecord::Migration.write("== %s %s" % ['Data', "=" * 71])
|
116
|
+
::DataMigrate::DataMigrator.run(direction, data_migrations_path, migration[:version])
|
117
|
+
else
|
118
|
+
::ActiveRecord::Migration.write("== %s %s" % ['Schema', "=" * 69])
|
119
|
+
::DataMigrate::SchemaMigration.run(
|
120
|
+
direction,
|
121
|
+
::DataMigrate::SchemaMigration.migrations_paths,
|
122
|
+
migration[:version]
|
123
|
+
)
|
64
124
|
end
|
65
125
|
end
|
66
126
|
|
67
|
-
def
|
68
|
-
|
127
|
+
def schema_dump_path(db_config, format = ActiveRecord.schema_format)
|
128
|
+
return ENV["DATA_SCHEMA"] if ENV["DATA_SCHEMA"]
|
129
|
+
|
130
|
+
# We only require a schema.rb file for the primary database
|
131
|
+
return unless db_config.primary?
|
132
|
+
|
133
|
+
File.join(File.dirname(ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(db_config, format)), schema_file_type)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Override this method from `ActiveRecord::Tasks::DatabaseTasks`
|
137
|
+
# to ensure that the sha saved in ar_internal_metadata table
|
138
|
+
# is from the original schema.rb file
|
139
|
+
def schema_sha1(file)
|
140
|
+
ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: "primary"))
|
141
|
+
end
|
142
|
+
|
143
|
+
def forward(step = 1)
|
144
|
+
DataMigrate::DataMigrator.create_data_schema_table
|
69
145
|
migrations = pending_migrations.reverse.pop(step).reverse
|
70
146
|
migrations.each do | pending_migration |
|
71
147
|
if pending_migration[:kind] == :data
|
@@ -78,22 +154,92 @@ module DataMigrate
|
|
78
154
|
end
|
79
155
|
end
|
80
156
|
|
81
|
-
def
|
157
|
+
def pending_data_migrations
|
82
158
|
data_migrations = DataMigrate::DataMigrator.migrations(data_migrations_path)
|
83
|
-
|
84
|
-
|
159
|
+
data_migrator = DataMigrate::RailsHelper.data_migrator(:up, data_migrations)
|
160
|
+
sort_migrations(
|
161
|
+
data_migrator.pending_migrations.map { |m| { version: m.version, name: m.name, kind: :data } }
|
162
|
+
)
|
85
163
|
end
|
86
164
|
|
87
|
-
def
|
165
|
+
def pending_schema_migrations
|
88
166
|
::DataMigrate::SchemaMigration.pending_schema_migrations
|
89
167
|
end
|
90
168
|
|
91
|
-
def
|
92
|
-
data_versions = DataMigrate::
|
93
|
-
schema_versions =
|
169
|
+
def past_migrations(sort = nil)
|
170
|
+
data_versions = DataMigrate::RailsHelper.data_schema_migration.table_exists? ? DataMigrate::RailsHelper.data_schema_migration.normalized_versions : []
|
171
|
+
schema_versions = DataMigrate::RailsHelper.schema_migration.normalized_versions
|
94
172
|
migrations = data_versions.map { |v| { version: v.to_i, kind: :data } } + schema_versions.map { |v| { version: v.to_i, kind: :schema } }
|
95
173
|
|
96
174
|
sort&.downcase == "asc" ? sort_migrations(migrations) : sort_migrations(migrations).reverse
|
97
175
|
end
|
176
|
+
|
177
|
+
def self.migrate_with_data
|
178
|
+
DataMigrate::DataMigrator.create_data_schema_table
|
179
|
+
|
180
|
+
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
181
|
+
|
182
|
+
db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
|
183
|
+
|
184
|
+
schema_mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions(db_configs)
|
185
|
+
data_mapped_versions = DataMigrate::DatabaseTasks.db_configs_with_versions
|
186
|
+
|
187
|
+
mapped_versions = schema_mapped_versions.merge(data_mapped_versions) do |_key, schema_db_configs, data_db_configs|
|
188
|
+
schema_db_configs + data_db_configs
|
189
|
+
end
|
190
|
+
|
191
|
+
mapped_versions.sort.each do |version, db_configs|
|
192
|
+
db_configs.each do |db_config|
|
193
|
+
if is_data_migration = db_config.is_a?(DataMigrate::DatabaseConfigurationWrapper)
|
194
|
+
db_config = db_config.db_config
|
195
|
+
end
|
196
|
+
|
197
|
+
DataMigrate::DatabaseTasks.with_temporary_connection(db_config) do
|
198
|
+
if is_data_migration
|
199
|
+
DataMigrate::DataMigrator.run(:up, DataMigrate::DatabaseTasks.data_migrations_path, version)
|
200
|
+
else
|
201
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate(version)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.prepare_all_with_data
|
209
|
+
seed = false
|
210
|
+
|
211
|
+
each_current_configuration(env) do |db_config|
|
212
|
+
next unless db_config.primary?
|
213
|
+
|
214
|
+
with_temporary_pool(db_config) do
|
215
|
+
begin
|
216
|
+
database_initialized = migration_connection.schema_migration.table_exists?
|
217
|
+
rescue ActiveRecord::NoDatabaseError
|
218
|
+
create(db_config)
|
219
|
+
retry
|
220
|
+
end
|
221
|
+
|
222
|
+
unless database_initialized
|
223
|
+
if File.exist?(schema_dump_path(db_config))
|
224
|
+
load_schema(db_config, ActiveRecord.schema_format, nil)
|
225
|
+
load_schema_current(
|
226
|
+
:ruby,
|
227
|
+
ENV["DATA_SCHEMA"]
|
228
|
+
)
|
229
|
+
end
|
230
|
+
|
231
|
+
seed = true
|
232
|
+
end
|
233
|
+
|
234
|
+
migrate_with_data
|
235
|
+
if ActiveRecord.dump_schema_after_migration
|
236
|
+
dump_schema(db_config)
|
237
|
+
DataMigrate::Tasks::DataMigrateTasks.dump
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
load_seed if seed
|
243
|
+
end
|
98
244
|
end
|
99
245
|
end
|