Skip to content

Instantly share code, notes, and snippets.

@brennovich
Created October 13, 2014 20:02
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save brennovich/37aa0637cea5060f1a8a 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