data_migrate 10.0.3.rc → 11.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +4 -4
  3. data/.github/workflows/gempush.yml +6 -8
  4. data/.gitignore +0 -1
  5. data/Appraisals +10 -5
  6. data/Changelog.md +32 -6
  7. data/Gemfile +0 -1
  8. data/Gemfile.lock +188 -0
  9. data/README.md +13 -4
  10. data/data_migrate.gemspec +2 -2
  11. data/gemfiles/rails_6.1.gemfile +0 -1
  12. data/gemfiles/rails_6.1.gemfile.lock +233 -0
  13. data/gemfiles/rails_7.0.gemfile +1 -2
  14. data/gemfiles/rails_7.0.gemfile.lock +234 -0
  15. data/gemfiles/{rails_6.0.gemfile → rails_7.1.gemfile} +1 -2
  16. data/gemfiles/rails_7.1.gemfile.lock +266 -0
  17. data/gemfiles/rails_7.2.gemfile +7 -0
  18. data/gemfiles/rails_7.2.gemfile.lock +265 -0
  19. data/lib/data_migrate/data_migrator.rb +15 -23
  20. data/lib/data_migrate/data_schema.rb +2 -2
  21. data/lib/data_migrate/data_schema_migration.rb +24 -7
  22. data/lib/data_migrate/database_configurations_wrapper.rb +11 -0
  23. data/lib/data_migrate/database_tasks.rb +194 -48
  24. data/lib/data_migrate/migration_context.rb +11 -8
  25. data/lib/data_migrate/rails_helper.rb +90 -0
  26. data/lib/data_migrate/schema_dumper.rb +1 -1
  27. data/lib/data_migrate/schema_migration.rb +5 -4
  28. data/lib/data_migrate/status_service.rb +3 -3
  29. data/lib/data_migrate/tasks/data_migrate_tasks.rb +13 -14
  30. data/lib/data_migrate/test.rb +14 -0
  31. data/lib/data_migrate/version.rb +1 -1
  32. data/lib/data_migrate.rb +2 -1
  33. data/spec/data_migrate/data_migrator_spec.rb +17 -14
  34. data/spec/data_migrate/data_schema_migration_spec.rb +25 -8
  35. data/spec/data_migrate/data_spec.rb +1 -1
  36. data/spec/data_migrate/database_tasks_spec.rb +34 -19
  37. data/spec/data_migrate/migration_context_spec.rb +25 -9
  38. data/spec/data_migrate/schema_dumper_spec.rb +6 -3
  39. data/spec/data_migrate/schema_migration_spec.rb +13 -6
  40. data/spec/data_migrate/status_service_spec.rb +6 -3
  41. data/spec/data_migrate/tasks/data_migrate_tasks_spec.rb +13 -14
  42. data/spec/db/data/20091231235959_some_name.rb +1 -1
  43. data/spec/db/data/20171231235959_super_update.rb +1 -1
  44. data/spec/db/migrate/20131111111111_late_migration.rb +1 -1
  45. data/spec/db/migrate/20202020202011_db_migration.rb +1 -1
  46. data/tasks/databases.rake +25 -93
  47. metadata +21 -15
  48. data/Gemfile.rails6.1 +0 -11
  49. data/lib/data_migrate/legacy_migrator.rb +0 -22
  50. 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::DataSchemaMigration.normalized_versions.map(&:to_i).sort
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::DataSchemaMigration.where(version: version.to_s).delete_all
74
+ DataMigrate::RailsHelper.data_schema_delete_version(version.to_s)
83
75
  else
84
76
  migrated << version
85
- DataMigrate::DataSchemaMigration.create!(version: version.to_s)
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.assure_data_schema_table
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::DataSchemaMigration.table_name
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
- class << self
4
- delegate :table_name, :primary_key, :create_table, :normalized_versions, :create, :create!, :table_exists?, :exists?, :where, to: :instance
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
- def instance
7
- @instance ||= Class.new(::ActiveRecord::SchemaMigration) do
8
- define_singleton_method(:table_name) { ActiveRecord::Base.table_name_prefix + 'data_migrations' + ActiveRecord::Base.table_name_suffix }
9
- define_singleton_method(:primary_key) { "version" }
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
- class DatabaseTasks
8
+ module DatabaseTasks
9
9
  extend ActiveRecord::Tasks::DatabaseTasks
10
-
11
- class << self
12
- def schema_file_type(_format = nil)
13
- "data_schema.rb"
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 dump_filename(spec_name, format = ActiveRecord::Base.schema_format)
17
- filename = if spec_name == "primary"
18
- schema_file_type(format)
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
- ENV["DATA_SCHEMA"] || File.join(db_dir, filename)
31
+ def migration_class # :nodoc:
32
+ ActiveRecord::Base
24
33
  end
25
34
 
26
- def check_schema_file(filename)
27
- unless File.exist?(filename)
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 pending_migrations
34
- sort_migrations(
35
- pending_schema_migrations,
36
- pending_data_migrations
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
- def sort_migrations(*migrations)
41
- migrations.flatten.sort { |a, b| sort_string(a) <=> sort_string(b) }
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
- def sort_string migration
45
- "#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
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
- def data_migrations_path
49
- ::DataMigrate.config.data_migrations_path
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
- def run_migration(migration, direction)
53
- if migration[:kind] == :data
54
- ::ActiveRecord::Migration.write("== %s %s" % ['Data', "=" * 71])
55
- ::DataMigrate::DataMigrator.run(direction, data_migrations_path, migration[:version])
56
- else
57
- ::ActiveRecord::Migration.write("== %s %s" % ['Schema', "=" * 69])
58
- ::DataMigrate::SchemaMigration.run(
59
- direction,
60
- ::DataMigrate::SchemaMigration.migrations_paths,
61
- migration[:version]
62
- )
63
- end
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 self.forward(step = 1)
68
- DataMigrate::DataMigrator.assure_data_schema_table
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 self.pending_data_migrations
157
+ def pending_data_migrations
82
158
  data_migrations = DataMigrate::DataMigrator.migrations(data_migrations_path)
83
- sort_migrations(DataMigrate::DataMigrator.new(:up, data_migrations ).
84
- pending_migrations.map {|m| { version: m.version, name: m.name, kind: :data }})
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 self.pending_schema_migrations
165
+ def pending_schema_migrations
88
166
  ::DataMigrate::SchemaMigration.pending_schema_migrations
89
167
  end
90
168
 
91
- def self.past_migrations(sort = nil)
92
- data_versions = DataMigrate::DataSchemaMigration.table_exists? ? DataMigrate::DataSchemaMigration.normalized_versions : []
93
- schema_versions = ActiveRecord::SchemaMigration.normalized_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