Skip to content

Instantly share code, notes, and snippets.

@alvinsj
Created October 3, 2011 16:28
Show Gist options
  • Save alvinsj/1259521 to your computer and use it in GitHub Desktop.
Save alvinsj/1259521 to your computer and use it in GitHub Desktop.
Create migration files from existing ActiveRecord models
# ActiveRecord migration by @bridgeutopia (http://www.blog.bridgeutopiaweb.com/post/activerecord-migrations-for-sinatra/)
# Added "rake reverse_migrate" to do reverse migration
require 'rake'
require 'active_record'
require 'logger'
require 'yaml'
desc "Import DB"
task :import => :environment do
url = ENV['URL'] or raise "No url specified, use URL="
require 'rest_client'
posts = YAML.load RestClient.get(url)
posts.each do |post|
DB[:posts] << post
end
end
task :default => :dbsetup
task :loadconfig do
DBconfig = YAML::load( File.open('db/mysql.yml') )['development']
end
desc "Setup db"
task :dbsetup => :loadconfig do
create(DBconfig)
migrate(DBconfig)
end
desc "Do migrations"
task :migrate => :loadconfig do
migrate(DBconfig)
end
desc "Do reverse migrations"
task :reverse_migrate => :loadconfig do
reverse_migrate(DBconfig)
end
def create( config )
begin
if config['adapter'] =~ /sqlite/
if File.exist?(config['database'])
$stderr.puts "#{config['database']} already exists"
else
begin
# Create the SQLite database
ActiveRecord::Base.establish_connection(config)
ActiveRecord::Base.connection
rescue
$stderr.puts $!, *($!.backtrace)
$stderr.puts "Couldn't create database for #{config.inspect}"
end
end
return # Skip the else clause of begin/rescue
else
ActiveRecord::Base.establish_connection(config)
ActiveRecord::Base.connection
end
rescue
case config['adapter']
when 'mysql'
@charset = ENV['CHARSET'] || 'utf8'
@collation = ENV['COLLATION'] || 'utf8_general_ci'
begin
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
ActiveRecord::Base.connection.create_database(config['database'], :charset => (config['charset'] || @charset),
:collation => (config['collation'] || @collation))
ActiveRecord::Base.establish_connection(config)
rescue
$stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset},
collation: #{config['collation'] || @collation}"
end
when 'postgresql'
@encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
begin
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
ActiveRecord::Base.establish_connection(config)
rescue
$stderr.puts $!, *($!.backtrace)
$stderr.puts "Couldn't create database for #{config.inspect}"
end
end
else
$stderr.puts "#{config['database']} already exists"
end
end
def migrate( config )
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection(config)
ActiveRecord::Migrator.migrate "db/migrate/"
end
def reverse_migrate( config )
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection(config)
# load model classes from directory
Dir["./app/models/*.rb"].each do |file|
require file
end
i = 0
tables = Hash[ActiveRecord::Base.send(:descendants).collect{|c| [c.table_name, c.name]}]
tables.each do |table_name, class_name|
m_name = table_name
m_name = table_name.gsub("_","") if table_name.include?"_"
filename = "db/migrate/#{"%04d"%i}_create_table_#{m_name}.rb"
puts "creating migration #{filename}..."
File.open(filename, 'w') do |f|
f.write("class CreateTable#{m_name.capitalize} < ActiveRecord::Migration\n")
f.write(" def up\n")
f.write(" create_table :#{table_name} do |t|\n")
columns = ActiveRecord::Base.connection.columns(table_name)
columns.each do |col|
f.write(" t.#{col.type} :#{col.name}\n") unless ['id','created_at','updated_at'].include?(col.name)
end
names = columns.collect{|c| c.name }
f.write("\n t.timestamps\n") if names.include?('created_at') && names.include?('updated_at')
f.write(" end\n")
f.write(" end\n")
f.write(" def down\n")
f.write(" drop_table :#{table_name}\n")
f.write(" end\n")
f.write("end")
end
i+=1
end
puts "#{i.to_s} files created."
puts "WARNING! change the database config if you are going to do \"rake migrate\" next, otherwise existing database(if any) will be overwritten"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment