diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/migration.rb | 79 | ||||
-rw-r--r-- | activerecord/test/cases/migration_test.rb | 18 | ||||
-rw-r--r-- | activerecord/test/cases/migrator_test.rb | 26 |
3 files changed, 67 insertions, 56 deletions
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 0a7a558675..c000b94bc8 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -342,9 +342,9 @@ module ActiveRecord attr_accessor :name, :version - def initialize - @name = self.class.name - @version = nil + def initialize(name = self.class.name, version = nil) + @name = name + @version = version @connection = nil @reverting = false end @@ -619,8 +619,6 @@ module ActiveRecord files = Dir[*paths.map { |p| "#{p}/**/[0-9]*_*.rb" }] - seen = Hash.new false - migrations = files.map do |file| version, name, scope = file.scan(/([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?.rb/).first @@ -628,11 +626,6 @@ module ActiveRecord version = version.to_i name = name.camelize - raise DuplicateMigrationVersionError.new(version) if seen[version] - raise DuplicateMigrationNameError.new(name) if seen[name] - - seen[version] = seen[name] = true - MigrationProxy.new(name, version, file, scope) end @@ -655,9 +648,9 @@ module ActiveRecord def initialize(direction, migrations, target_version = nil) raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations? - Base.connection.initialize_schema_migrations_table @direction = direction + @target_version = target_version if Array(migrations).grep(String).empty? @migrations = migrations @@ -666,7 +659,9 @@ module ActiveRecord @migrations = self.class.migrations(migrations) end - @target_version = target_version + validate(@migrations) + + Base.connection.initialize_schema_migrations_table end def current_version @@ -748,36 +743,44 @@ module ActiveRecord end private - def record_version_state_after_migrating(version) - table = Arel::Table.new(self.class.schema_migrations_table_name) - - @migrated_versions ||= [] - if down? - @migrated_versions.delete(version) - stmt = table.where(table["version"].eq(version.to_s)).compile_delete - Base.connection.delete stmt - else - @migrated_versions.push(version).sort! - stmt = table.compile_insert table["version"] => version.to_s - Base.connection.insert stmt - end - end + def validate(migrations) + name ,= migrations.group_by(&:name).find { |_,v| v.length > 1 } + raise DuplicateMigrationNameError.new(name) if name - def up? - @direction == :up - end + version ,= migrations.group_by(&:version).find { |_,v| v.length > 1 } + raise DuplicateMigrationVersionError.new(version) if version + end + + def record_version_state_after_migrating(version) + table = Arel::Table.new(self.class.schema_migrations_table_name) - def down? - @direction == :down + @migrated_versions ||= [] + if down? + @migrated_versions.delete(version) + stmt = table.where(table["version"].eq(version.to_s)).compile_delete + Base.connection.delete stmt + else + @migrated_versions.push(version).sort! + stmt = table.compile_insert table["version"] => version.to_s + Base.connection.insert stmt end + end - # Wrap the migration in a transaction only if supported by the adapter. - def ddl_transaction(&block) - if Base.connection.supports_ddl_transactions? - Base.transaction { block.call } - else - block.call - end + def up? + @direction == :up + end + + def down? + @direction == :down + end + + # Wrap the migration in a transaction only if supported by the adapter. + def ddl_transaction(&block) + if Base.connection.supports_ddl_transactions? + Base.transaction { block.call } + else + block.call end + end end end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 2573c77405..1d1a9a221a 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -601,24 +601,6 @@ class MigrationTest < ActiveRecord::TestCase Person.connection.drop_table :binary_testings rescue nil end - def test_migrator_with_duplicates - assert_raise(ActiveRecord::DuplicateMigrationVersionError) do - ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate", nil) - end - end - - def test_migrator_with_duplicate_names - assert_raise(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do - ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate_names", nil) - end - end - - def test_migrator_with_missing_version_numbers - assert_raise(ActiveRecord::UnknownMigrationVersionError) do - ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/missing", 500) - end - end - def test_create_table_with_custom_sequence_name skip "not supported" unless current_adapter? :OracleAdapter diff --git a/activerecord/test/cases/migrator_test.rb b/activerecord/test/cases/migrator_test.rb new file mode 100644 index 0000000000..b0d514e50d --- /dev/null +++ b/activerecord/test/cases/migrator_test.rb @@ -0,0 +1,26 @@ +require "cases/helper" + +module ActiveRecord + class MigratorTest < ActiveRecord::TestCase + def test_migrator_with_duplicate_names + assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do + list = [Migration.new('Chunky'), Migration.new('Chunky')] + ActiveRecord::Migrator.new(:up, list) + end + end + + def test_migrator_with_duplicate_versions + assert_raises(ActiveRecord::DuplicateMigrationVersionError) do + list = [Migration.new('Foo', 1), Migration.new('Bar', 1)] + ActiveRecord::Migrator.new(:up, list) + end + end + + def test_migrator_with_missing_version_numbers + assert_raises(ActiveRecord::UnknownMigrationVersionError) do + list = [Migration.new('Foo', 1), Migration.new('Bar', 2)] + ActiveRecord::Migrator.new(:up, list, 3).run + end + end + end +end |