Skip to content
This repository has been archived by the owner on May 5, 2022. It is now read-only.

Fixes bug when blowing away migrations into one file. #7

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
@@ -1 +1,3 @@
pkg/* pkg/*
.swp
*.swp
32 changes: 32 additions & 0 deletions lib/db_migrate_merge.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,32 @@
class DbMigrateMerge
def self.generate_down_indexes lines
indexes = lines.collect do |line|
columns_regex = /add_index "[^"]+", ?(?::column ?=> ?)?(\[[^\]]+\]|"[^"]+")/

index_regex = /add_index "[^"]+", ?(?::name ?=> ?)?"([^"]+)"/
table_regex = /add_index "([^"]+)"/

if line =~ table_regex
table_name = $1
remove = "remove_index :#{table_name},"

columns = line =~ columns_regex
if columns
if $1.index "["
"#{remove} :column => #{$1}"
else
"#{remove} :column => [#{$1}]"
end
elsif line =~ index_regex
"#{remove} :name => \"#{$1}\""
else
raise Exception.new "Expected to find an index name or column names in the db/schema.rb file but none were found:\n #{line}"
end
end

end

indexes.compact.reverse
end

end
47 changes: 24 additions & 23 deletions lib/tasks/db_migrate_merge.rake
Original file line number Original file line Diff line number Diff line change
@@ -1,49 +1,50 @@
require 'fileutils' require 'fileutils'
namespace :db do namespace :db do

namespace :migrate do namespace :migrate do

desc "Uses schema.rb to build a new base migration with the timestamp of the current migration. Other migrations are moved to a backup folder." desc "Uses schema.rb to build a new base migration with the timestamp of the current migration. Other migrations are moved to a backup folder."
task :compact => [:abort_if_pending_migrations, :environment] do task :compact => [:abort_if_pending_migrations, :environment] do

file = File.read("#{RAILS_ROOT}/db/schema.rb") file = File.read("#{RAILS_ROOT}/db/schema.rb")

main_content_regex = /ActiveRecord::Schema.define\(:version => (.*)\) do(.*)^end/m main_content_regex = /ActiveRecord::Schema.define\(:version => (.*)\) do(.*)^end/m
main_content_regex.match file main_content_regex.match file
create_part = $2 # the second group holds what I want. create_part = $2 # the second group holds what I want.


lines = file.split("\n") lines = file.split("\n")


index_regex = /add_index "(.*)", (.*):name => "(.*)"/
table_regex = /create_table (.*),(.*)/ table_regex = /create_table (.*),(.*)/


index_regex = /add_index "(.*)", \[(.*)\], :name => "(.*)"/

tables = lines.collect{|line| " drop_table #{$1}" if line =~ table_regex } tables = lines.collect{|line| " drop_table #{$1}" if line =~ table_regex }
indexes = lines.collect{|line| " remove_index :#{$1}, :name => :#{$3}" if line =~ index_regex}

# hack to correct spacing so it "looks pretty" # hack to correct spacing so it "looks pretty"
create_part.gsub!("\n", "\n ") create_part.gsub!("\n", "\n ")

# reverse the order so the indexes get taken out in the opposite order # reverse the order so the indexes get taken out in the opposite order
# they were added. Also add two spaces to the start of each line # they were added. Also add two spaces to the start of each line
drop_tables = tables.compact.reverse.join("\n ") drop_tables = tables.compact.reverse.join("\n ")
drop_indexes = indexes.compact.reverse.join("\n ") drop_indexes = DbMigrateMerge.generate_down_indexes lines

drop_indexes = drop_indexes.join("\n ")

new_migration = %Q{# Migration created #{Time.now.to_s} by lazy_developer new_migration = %Q{# Migration created #{Time.now.to_s} by lazy_developer
class InitialMigration < ActiveRecord::Migration class InitialMigration < ActiveRecord::Migration
def self.up def self.up
#{create_part} #{create_part}
end end

def self.down def self.down
#{drop_indexes} #{drop_indexes}

#{drop_tables} #{drop_tables}
end end
end end
} }
version = ActiveRecord::Migrator.current_version version = ActiveRecord::Migrator.current_version
backups = RAILS_ROOT+"/db/migrate_#{version}" backups = RAILS_ROOT+"/db/migrate_#{version}"

svn=File.exist?(RAILS_ROOT+"/db/migrate/.svn") svn=File.exist?(RAILS_ROOT+"/db/migrate/.svn")
if svn if svn
`svn mkdir #{backups}` `svn mkdir #{backups}`
Expand All @@ -55,19 +56,19 @@ end
FileUtils.mv(RAILS_ROOT+"/db/migrate", backups) FileUtils.mv(RAILS_ROOT+"/db/migrate", backups)
FileUtils.mkdir(RAILS_ROOT+"/db/migrate") FileUtils.mkdir(RAILS_ROOT+"/db/migrate")
end end

new_file = RAILS_ROOT+"/db/migrate/#{version}_initial_migration.rb" new_file = RAILS_ROOT+"/db/migrate/#{version}_initial_migration.rb"


File.open(new_file, "w") do |f| File.open(new_file, "w") do |f|
f << new_migration f << new_migration
end end


`svn add #{new_file}` if svn `svn add #{new_file}` if svn

puts "Created #{new_file}." puts "Created #{new_file}."
puts "Previous migrations are in #{backups}" puts "Previous migrations are in #{backups}"
end end

end end

end end
92 changes: 92 additions & 0 deletions spec/db_migrate_merge_spec.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,92 @@
current_directory = File.join File.dirname(__FILE__)
require File.join(current_directory, '../lib/db_migrate_merge')

describe DbMigrateMerge do
describe "#remove_index" do
#___________________
it "handles indexes with just a column name" do
line = <<-eof
add_index "versions", "versioned_type"
eof

expected = <<-ex
remove_index :versions, :column => ["versioned_type"]
ex

DbMigrateMerge.generate_down_indexes([line]).should == expected[0..-2]
end





#___________________
it "handles indexes with only one column name and an index name" do

line = <<-eof
add_index "audited", "transaction", :name => "index_audited_on_transaction"
eof

expected_line = <<-eof
remove_index :audited, :column => ["transaction"]
eof

expected = [expected_line].join()[0..-2]
DbMigrateMerge.generate_down_indexes([line]).should == expected

end


#___________________
it "works with an array of column names and an index name" do
line = <<-eof
add_index "versions", ["versioned_type", "versioned_id"], :name => "index_versions_on_versioned_type_and_versioned_id"
eof

expected = <<-ex
remove_index :versions, :column => ["versioned_type", "versioned_id"]
ex
DbMigrateMerge.generate_down_indexes([line]).should == expected[0..-2]
end

it "handles indexes with a column name with the :column => hash rocket syntax" do
line = <<-eof
add_index "versions", :column => ["versioned_type", "versioned_id"], :name => "index_versions_on_versioned_type_and_versioned_id"
eof

expected = <<-ex
remove_index :versions, :column => ["versioned_type", "versioned_id"]
ex

DbMigrateMerge.generate_down_indexes([line]).should == expected[0..-2]

line = <<-eof
add_index "versions", :column => ["versioned_type"], :name => "index_versions_on_versioned_type"
eof

expected = <<-ex
remove_index :versions, :column => ["versioned_type"]
ex

DbMigrateMerge.generate_down_indexes([line]).should == expected[0..-2]


end



it "handles indexes with a column name with the :column => hash rocket syntax" do
line = <<-eof
add_index "versions", :name => "index_versions_on_versioned_type_and_versioned_id"
eof

expected = <<-ex
remove_index :versions, :name => "index_versions_on_versioned_type_and_versioned_id"
ex

DbMigrateMerge.generate_down_indexes([line]).should == expected[0..-2]

end
end

end