data_migrate 9.2.0 → 9.4.1

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.
@@ -5,87 +5,142 @@ 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(_format = nil)
13
- File.join(db_dir, "data_schema.rb")
14
- end
15
-
16
- def schema_file_type(_format = nil)
17
- "data_schema.rb"
18
- end
19
-
20
- # This method is removed in Rails 7.0
21
- def dump_filename(spec_name, format = ActiveRecord::Base.schema_format)
22
- filename = if spec_name == "primary"
23
- schema_file_type(format)
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)
24
18
  else
25
- "#{spec_name}_#{schema_file_type(format)}"
19
+ ActiveRecord::Base.configurations.configs_for(env_name: env, name: name).each do |db_config|
20
+ with_temporary_connection(db_config, &block)
21
+ end
26
22
  end
27
-
28
- ENV["DATA_SCHEMA"] || File.join(db_dir, filename)
29
23
  end
30
24
 
31
- def check_schema_file(filename)
32
- unless File.exist?(filename)
33
- message = +%{#{filename} doesn't exist yet. Run `rake data:migrate` to create it, then try again.}
34
- Kernel.abort message
25
+ def with_temporary_connection(db_config) # :nodoc:
26
+ with_temporary_pool(db_config) do |pool|
27
+ yield pool.connection
35
28
  end
36
29
  end
37
30
 
38
- def pending_migrations
39
- sort_migrations(
40
- pending_schema_migrations,
41
- pending_data_migrations
42
- )
31
+ def migration_class # :nodoc:
32
+ ActiveRecord::Base
43
33
  end
44
34
 
45
- def sort_migrations(*migrations)
46
- migrations.flatten.sort { |a, b| sort_string(a) <=> sort_string(b) }
35
+ def migration_connection # :nodoc:
36
+ migration_class.connection
47
37
  end
48
38
 
49
- def sort_string migration
50
- "#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
51
- end
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)
52
42
 
53
- def data_migrations_path
54
- ::DataMigrate.config.data_migrations_path
43
+ yield pool
44
+ ensure
45
+ migration_class.connection_handler.establish_connection(original_db_config)
55
46
  end
47
+ end
56
48
 
57
- def run_migration(migration, direction)
58
- if migration[:kind] == :data
59
- ::ActiveRecord::Migration.write("== %s %s" % ['Data', "=" * 71])
60
- ::DataMigrate::DataMigrator.run(direction, data_migrations_path, migration[:version])
61
- else
62
- ::ActiveRecord::Migration.write("== %s %s" % ['Schema', "=" * 69])
63
- ::DataMigrate::SchemaMigration.run(
64
- direction,
65
- ::DataMigrate::SchemaMigration.migrations_paths,
66
- migration[:version]
67
- )
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
57
+
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
68
62
  end
69
63
  end
70
64
 
71
- def schema_dump_path(db_config, format = ActiveRecord.schema_format)
72
- return ENV["DATA_SCHEMA"] if ENV["DATA_SCHEMA"]
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)}"
82
+ end
73
83
 
74
- # We only require a schema.rb file for the primary database
75
- return unless db_config.primary?
84
+ ENV["DATA_SCHEMA"] || File.join(db_dir, filename)
85
+ end
76
86
 
77
- File.join(File.dirname(ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(db_config, format)), schema_file_type)
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
78
91
  end
92
+ end
93
+
94
+ def pending_migrations
95
+ sort_migrations(
96
+ pending_schema_migrations,
97
+ pending_data_migrations
98
+ )
99
+ end
79
100
 
80
- # Override this method from `ActiveRecord::Tasks::DatabaseTasks`
81
- # to ensure that the sha saved in ar_internal_metadata table
82
- # is from the original schema.rb file
83
- def schema_sha1(file)
84
- ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: "primary"))
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
+ )
85
124
  end
86
125
  end
87
126
 
88
- def self.forward(step = 1)
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)
89
144
  DataMigrate::DataMigrator.create_data_schema_table
90
145
  migrations = pending_migrations.reverse.pop(step).reverse
91
146
  migrations.each do | pending_migration |
@@ -99,7 +154,7 @@ module DataMigrate
99
154
  end
100
155
  end
101
156
 
102
- def self.pending_data_migrations
157
+ def pending_data_migrations
103
158
  data_migrations = DataMigrate::DataMigrator.migrations(data_migrations_path)
104
159
  data_migrator = DataMigrate::RailsHelper.data_migrator(:up, data_migrations)
105
160
  sort_migrations(
@@ -107,16 +162,47 @@ module DataMigrate
107
162
  )
108
163
  end
109
164
 
110
- def self.pending_schema_migrations
165
+ def pending_schema_migrations
111
166
  ::DataMigrate::SchemaMigration.pending_schema_migrations
112
167
  end
113
168
 
114
- def self.past_migrations(sort = nil)
169
+ def past_migrations(sort = nil)
115
170
  data_versions = DataMigrate::RailsHelper.data_schema_migration.table_exists? ? DataMigrate::RailsHelper.data_schema_migration.normalized_versions : []
116
171
  schema_versions = DataMigrate::RailsHelper.schema_migration.normalized_versions
117
172
  migrations = data_versions.map { |v| { version: v.to_i, kind: :data } } + schema_versions.map { |v| { version: v.to_i, kind: :schema } }
118
173
 
119
174
  sort&.downcase == "asc" ? sort_migrations(migrations) : sort_migrations(migrations).reverse
120
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
121
207
  end
122
208
  end
@@ -0,0 +1,14 @@
1
+ module Base
2
+ extend self
3
+
4
+ def foo
5
+ puts "Base#foo called"
6
+ end
7
+ end
8
+
9
+ module Child
10
+ extend Base
11
+ extend self
12
+
13
+ puts "foo: #{respond_to?(:foo)}"
14
+ end
@@ -1,3 +1,3 @@
1
1
  module DataMigrate
2
- VERSION = "9.2.0".freeze
2
+ VERSION = "9.4.1".freeze
3
3
  end
data/lib/data_migrate.rb CHANGED
@@ -12,6 +12,7 @@ require File.join(File.dirname(__FILE__), "data_migrate", "railtie")
12
12
  require File.join(File.dirname(__FILE__), "data_migrate", "tasks/data_migrate_tasks")
13
13
  require File.join(File.dirname(__FILE__), "data_migrate", "config")
14
14
  require File.join(File.dirname(__FILE__), "data_migrate", "schema_migration")
15
+ require File.join(File.dirname(__FILE__), "data_migrate", "database_configurations_wrapper")
15
16
 
16
17
  module DataMigrate
17
18
  def self.root
data/tasks/databases.rake CHANGED
@@ -5,52 +5,8 @@ require 'data_migrate/tasks/data_migrate_tasks'
5
5
  namespace :db do
6
6
  namespace :migrate do
7
7
  desc "Migrate the database data and schema (options: VERSION=x, VERBOSE=false)."
8
- task :with_data => :environment do
9
- DataMigrate::DataMigrator.create_data_schema_table
10
-
11
- ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
12
- target_version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
13
- migrations = []
14
-
15
- if target_version.nil?
16
- migrations = DataMigrate::DatabaseTasks.pending_migrations.map{ |m| m.merge(:direction =>:up) }
17
- else
18
- current_schema_version = ActiveRecord::Migrator.current_version
19
- schema_migrations = if target_version > current_schema_version
20
- DataMigrate::DatabaseTasks.pending_schema_migrations.keep_if{ |m| m[:version] <= target_version }.map{ |m| m.merge(:direction =>:up) }
21
- elsif target_version < current_schema_version
22
- DataMigrate::DatabaseTasks.past_migrations.keep_if{ |m| m[:version] > target_version }.map{ |m| m.merge(:direction =>:down) }
23
- else # ==
24
- []
25
- end
26
-
27
- current_data_version = DataMigrate::DataMigrator.current_version
28
- data_migrations = if target_version > current_data_version
29
- DataMigrate::DatabaseTasks.pending_data_migrations.keep_if{ |m| m[:version] <= target_version }.map{ |m| m.merge(:direction =>:up) }
30
- elsif target_version < current_data_version
31
- DataMigrate::DatabaseTasks.past_migrations.keep_if{ |m| m[:version] > target_version }.map{ |m| m.merge(:direction =>:down) }
32
- else # ==
33
- []
34
- end
35
- migrations = if schema_migrations.empty?
36
- data_migrations
37
- elsif data_migrations.empty?
38
- schema_migrations
39
- elsif target_version > current_data_version && target_version > current_schema_version
40
- DataMigrate::DatabaseTasks.sort_migrations data_migrations, schema_migrations
41
- elsif target_version < current_data_version && target_version < current_schema_version
42
- DataMigrate::DatabaseTasks.sort_migrations(data_migrations, schema_migrations).reverse
43
- elsif target_version > current_data_version && target_version < current_schema_version
44
- schema_migrations + data_migrations
45
- elsif target_version < current_data_version && target_version > current_schema_version
46
- schema_migrations + data_migrations
47
- end
48
- end
49
-
50
- migrations.each do |migration|
51
- DataMigrate::DatabaseTasks.run_migration(migration, migration[:direction])
52
- end
53
-
8
+ task :with_data => :load_config do
9
+ DataMigrate::DatabaseTasks.migrate_with_data
54
10
  Rake::Task["db:_dump"].invoke
55
11
  Rake::Task["data:dump"].invoke
56
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_migrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.2.0
4
+ version: 9.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew J Vargo
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-10-05 00:00:00.000000000 Z
13
+ date: 2024-08-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -128,16 +128,16 @@ dependencies:
128
128
  name: sqlite3
129
129
  requirement: !ruby/object:Gem::Requirement
130
130
  requirements:
131
- - - "~>"
131
+ - - ">="
132
132
  - !ruby/object:Gem::Version
133
- version: 1.3.6
133
+ version: '0'
134
134
  type: :development
135
135
  prerelease: false
136
136
  version_requirements: !ruby/object:Gem::Requirement
137
137
  requirements:
138
- - - "~>"
138
+ - - ">="
139
139
  - !ruby/object:Gem::Version
140
- version: 1.3.6
140
+ version: '0'
141
141
  - !ruby/object:Gem::Dependency
142
142
  name: timecop
143
143
  requirement: !ruby/object:Gem::Requirement
@@ -202,7 +202,6 @@ files:
202
202
  - Changelog.md
203
203
  - Gemfile
204
204
  - Gemfile.lock
205
- - Gemfile.rails6.1
206
205
  - LICENSE
207
206
  - README.md
208
207
  - Rakefile
@@ -220,6 +219,7 @@ files:
220
219
  - lib/data_migrate/data_migrator.rb
221
220
  - lib/data_migrate/data_schema.rb
222
221
  - lib/data_migrate/data_schema_migration.rb
222
+ - lib/data_migrate/database_configurations_wrapper.rb
223
223
  - lib/data_migrate/database_tasks.rb
224
224
  - lib/data_migrate/migration_context.rb
225
225
  - lib/data_migrate/rails_helper.rb
@@ -228,6 +228,7 @@ files:
228
228
  - lib/data_migrate/schema_migration.rb
229
229
  - lib/data_migrate/status_service.rb
230
230
  - lib/data_migrate/tasks/data_migrate_tasks.rb
231
+ - lib/data_migrate/test.rb
231
232
  - lib/data_migrate/version.rb
232
233
  - lib/generators/data_migrate.rb
233
234
  - lib/generators/data_migration/data_migration_generator.rb
@@ -277,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
277
278
  - !ruby/object:Gem::Version
278
279
  version: '0'
279
280
  requirements: []
280
- rubygems_version: 3.4.10
281
+ rubygems_version: 3.4.19
281
282
  signing_key:
282
283
  specification_version: 4
283
284
  summary: Rake tasks to migrate data alongside schema changes.
data/Gemfile.rails6.1 DELETED
@@ -1,11 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in data_migrate.gemspec
4
- %w[
5
- activerecord
6
- railties
7
- ].each do |rails_gem|
8
- gem rails_gem, '~> 6.1.0'
9
- end
10
- gem 'sqlite3', "~> 1.4"
11
- gemspec