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:
parent
bfaf71cbc2
commit
c0fb67c0f8
3 changed files with 131 additions and 6 deletions
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue