Created
April 1, 2021 05:50
-
-
Save matthewd/fdb5ebf8da1e0a4cc6069bf2839aec06 to your computer and use it in GitHub Desktop.
bin/db-switch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require(Dir.pwd + "/config/environment") | |
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config| | |
ActiveRecord::Base.establish_connection(db_config.config) | |
context = ActiveRecord::Base.connection.migration_context | |
missing_migrations = [] | |
context.migrations_status.each do |status, version, name| | |
# We're only interested in migrations that are currently applied | |
next unless status == "up" | |
# We're only interested in migrations being displayed as "***** NO FILE *****" | |
next unless name.start_with?("*") | |
raise "Unexpected version format: #{version.inspect} is not numeric" unless version =~ /\A[0-9]+\z/ | |
missing_migrations << version | |
end | |
next if missing_migrations.empty? | |
puts | |
puts "Missing migrations in #{db_config.spec_name}:" | |
puts missing_migrations.map { |s| " #{s}" } | |
puts | |
migration_sha = {} | |
missing_migrations.each do |version| | |
migration_sha[version] = nil | |
end | |
puts "% git rev-list --walk-reflogs HEAD" | |
IO.popen("git rev-list --walk-reflogs HEAD") do |sha_list| | |
until migration_sha.values.all? | |
sha = sha_list.gets.chomp | |
newly_found = [] | |
paths = Shellwords.join([*context.migrations_paths].map { |path| "#{path}/" }) | |
puts %(% git ls-tree --name-only #{sha} -- #{paths}) | |
migrate_files = %x(git ls-tree --name-only #{sha} -- #{paths}).lines.map(&:chomp) | |
migrate_files.each do |filename| | |
version = File.basename(filename).split("_", 2).first | |
if migration_sha.key?(version) && migration_sha[version].nil? | |
migration_sha[version] = [sha, filename] | |
newly_found << version | |
end | |
end | |
puts " found #{newly_found.sort.join(", ")}" unless newly_found.empty? | |
end | |
end | |
migration_files = [] | |
missing_migrations.each do |version| | |
next unless migration_sha[version] | |
sha, filename = migration_sha[version] | |
puts %(% git cat-file blob #{sha}:#{Shellwords.escape filename}) | |
migration_script = %x(git cat-file blob #{sha}:#{Shellwords.escape filename}) | |
eval migration_script, nil, filename, 1 | |
$LOADED_FEATURES << File.expand_path(filename) | |
migration_files << filename | |
end | |
puts | |
dummy_context = ActiveRecord::MigrationContext.new(nil, ActiveRecord::Base.connection.migration_context.schema_migration) | |
class << dummy_context | |
attr_accessor :migration_files | |
end | |
dummy_context.migration_files = migration_files | |
dummy_context.down | |
if ActiveRecord::Base.dump_schema_after_migration | |
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment