Skip to content

Instantly share code, notes, and snippets.

@sadjow
Forked from brennovich/migrate_sql.rake
Last active August 29, 2015 14:17
Show Gist options
  • Save sadjow/50570b7feb7ec2faac81 to your computer and use it in GitHub Desktop.
Save sadjow/50570b7feb7ec2faac81 to your computer and use it in GitHub Desktop.
# Generates SQL from migrations
#
# Usage:
# rake db:[migrate,rollback]:with_sql
#
# The previous rake task will run migrations and create a file in `db/migrate_sql`
# Depending on migrate or rollback a file will be created with the respective
# sufix.
#
# Drawbacks:
# - There is no way to automatically generate migrate and rollback SQL at once
# If we need to generate a SQL from migrations its necessary to rollback:with_sql
# to the desired version and then migrate:with_sql
#
namespace :db do
%i(migrate rollback).each do |n|
namespace n do |migration_task|
desc 'Run migration, and generated SQL'
task with_sql: :environment do
# Fetch action, migrate or rollback
parent_task = Rake.application.top_level_tasks.first.scan(/\w*\:(\w*)\:/).flatten.first
migrate_sql_path = Pathname "#{Rails.root}/db/migrate_sql"
MIGRATE_SQL_FILE_PATH = Pathname "#{migrate_sql_path}/#{Time.now.strftime('%Y%m%d%H%M')}_#{parent_task}.sql"
Dir.mkdir migrate_sql_path unless migrate_sql_path.exist?
ActiveRecord::Base.connection.class.class_eval do
alias :original_execute :execute
# Define our own execute
def execute(sql, name = nil)
# Check for some DDL and DML statements in order to avoid AR check
# queries like SHOW statements
if /^(create|alter|drop|insert|delete|update)/i.match sql
File.open(MIGRATE_SQL_FILE_PATH, 'a') { |f| f.puts "#{sql};\n" }
end
original_execute sql, name
end
end
migrations = ActiveRecord::Migrator.migrations("#{Rails.root}/db/migrate").map(&:name)
current_position = migrations.index ActiveRecord::Migrator.last_migration.name
# Add migration metainformation
File.open(MIGRATE_SQL_FILE_PATH, 'w') do |f|
f.puts "-- Script created @ #{Time.now}"
f.puts "-- Included Migrations: #{migrations[current_position..-1].to_sentence}"
end
# Invoke the normal migration procedure now
Rake::Task["db:#{parent_task}"].invoke
puts "Ran #{parent_task} and wrote sql to #{MIGRATE_SQL_FILE_PATH}"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment