1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Make migrations verbose

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3760 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jamis Buck 2006-03-04 18:46:51 +00:00
parent bfaf71cbc2
commit c0fb67c0f8
3 changed files with 131 additions and 6 deletions

View file

@ -1,5 +1,7 @@
*SVN* *SVN*
* Make migrations verbose [Jamis Buck]
* Make counter_cache work with polymorphic belongs_to [Jamis Buck] * Make counter_cache work with polymorphic belongs_to [Jamis Buck]
* Fixed that calling HasOneProxy#build_model repeatedly would cause saving to happen #4058 [anna@wota.jp] * Fixed that calling HasOneProxy#build_model repeatedly would cause saving to happen #4058 [anna@wota.jp]

View file

@ -159,18 +159,111 @@ module ActiveRecord
# end # end
# end # end
# end # end
#
# == Controlling verbosity
#
# By default, migrations will describe the actions they are taking, writing
# them to the console as they happen, along with benchmarks describing how
# long each step took.
#
# You can quiet them down by setting ActiveRecord::Migration.verbose = false.
#
# You can also insert your own messages and benchmarks by using the #say_with_time
# method:
#
# def self.up
# ...
# say_with_time "Updating salaries..." do
# Person.find(:all).each do |p|
# p.salary = SalaryCalculator.compute(p)
# end
# end
# ...
# end
#
# The phrase "Updating salaries..." would then be printed, along with the
# benchmark for the block when the block completes.
class Migration class Migration
class << self @@verbose = true
def up() end cattr_accessor :verbose
def down() end
class << self
def up_using_benchmarks #:nodoc:
migrate(:up)
end
def down_using_benchmarks #:nodoc:
migrate(:down)
end
# Execute this migration in the named direction
def migrate(direction)
return unless respond_to?(direction)
case direction
when :up then announce "migrating"
when :down then announce "reverting"
end
result = nil
time = Benchmark.measure { result = send("real_#{direction}") }
case direction
when :up then announce "migrated (%.4fs)" % time.real; write
when :down then announce "reverted (%.4fs)" % time.real; write
end
result
end
# Because the method added may do an alias_method, it can be invoked
# recursively. We use @ignore_new_methods as a guard to indicate whether
# it is safe for the call to proceed.
def singleton_method_added(sym) #:nodoc:
return if @ignore_new_methods
begin
@ignore_new_methods = true
case sym
when :up, :down
klass = (class << self; self; end)
klass.send(:alias_method, "real_#{sym}", sym)
klass.send(:alias_method, sym, "#{sym}_using_benchmarks")
end
ensure
@ignore_new_methods = false
end
end
def write(text="")
puts(text) if verbose
end
def announce(message)
text = "#{name}: #{message}"
write "== %s %s" % [ text, "=" * (75 - text.length) ]
end
def say(message, subitem=false)
write "#{subitem ? " ->" : "--"} #{message}"
end
def say_with_time(message)
say(message)
result = nil
time = Benchmark.measure { result = yield }
say "%.4fs" % time.real, :subitem
result
end
private
def method_missing(method, *arguments, &block) def method_missing(method, *arguments, &block)
say_with_time "#{method}(#{arguments.map { |a| a.inspect }.join(", ")})" do
arguments[0] = Migrator.proper_table_name(arguments.first) unless arguments.empty? arguments[0] = Migrator.proper_table_name(arguments.first) unless arguments.empty?
ActiveRecord::Base.connection.send(method, *arguments, &block) ActiveRecord::Base.connection.send(method, *arguments, &block)
end end
end end
end end
end
class Migrator#:nodoc: class Migrator#:nodoc:
class << self class << self
@ -225,7 +318,7 @@ module ActiveRecord
next if irrelevant_migration?(version) next if irrelevant_migration?(version)
Base.logger.info "Migrating to #{migration_class} (#{version})" Base.logger.info "Migrating to #{migration_class} (#{version})"
migration_class.send(@direction) migration_class.migrate(@direction)
set_schema_version(version) set_schema_version(version)
end end
end end

View file

@ -6,10 +6,22 @@ require File.dirname(__FILE__) + '/fixtures/migrations/2_we_need_reminders'
if ActiveRecord::Base.connection.supports_migrations? if ActiveRecord::Base.connection.supports_migrations?
class Reminder < ActiveRecord::Base; end class Reminder < ActiveRecord::Base; end
class ActiveRecord::Migration
class <<self
attr_accessor :message_count
def puts(text="")
self.message_count ||= 0
self.message_count += 1
end
end
end
class MigrationTest < Test::Unit::TestCase class MigrationTest < Test::Unit::TestCase
self.use_transactional_fixtures = false self.use_transactional_fixtures = false
def setup def setup
ActiveRecord::Migration.verbose = true
PeopleHaveLastNames.message_count = 0
end end
def teardown def teardown
@ -345,6 +357,24 @@ if ActiveRecord::Base.connection.supports_migrations?
assert !Reminder.table_exists? assert !Reminder.table_exists?
end end
def test_migrator_verbosity
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
assert PeopleHaveLastNames.message_count > 0
PeopleHaveLastNames.message_count = 0
ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
assert PeopleHaveLastNames.message_count > 0
PeopleHaveLastNames.message_count = 0
end
def test_migrator_verbosity_off
PeopleHaveLastNames.verbose = false
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
assert PeopleHaveLastNames.message_count.zero?
ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
assert PeopleHaveLastNames.message_count.zero?
end
def test_migrator_going_down_due_to_version_target def test_migrator_going_down_due_to_version_target
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1) ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/', 0) ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/', 0)