Merge branch 'joshsusser-master' into merge
* joshsusser-master: style cleanup Add migration history to schema.rb dump Add metadata to schema_migrations Conflicts: activerecord/CHANGELOG.md activerecord/lib/active_record/schema.rb
This commit is contained in:
commit
0c692f4d12
@ -1,5 +1,23 @@
|
||||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* Add migration history to schema.rb dump.
|
||||
Loading schema.rb with full migration history
|
||||
restores the exact list of migrations that created
|
||||
that schema (including names and fingerprints). This
|
||||
avoids possible mistakes caused by assuming all
|
||||
migrations with a lower version have been run when
|
||||
loading schema.rb. Old schema.rb files without migration
|
||||
history but with the :version setting still work as before.
|
||||
|
||||
*Josh Susser*
|
||||
|
||||
* Add metadata columns to schema_migrations table.
|
||||
New columns are: migrated_at (timestamp),
|
||||
fingerprint (md5 hash of migration source), and
|
||||
name (filename minus version and extension)
|
||||
|
||||
*Josh Susser*
|
||||
|
||||
* Fix performance problem with primary_key method in PostgreSQL adapter when having many schemas.
|
||||
Uses pg_constraint table instead of pg_depend table which has many records in general.
|
||||
Fix #8414
|
||||
|
@ -490,8 +490,8 @@ def dump_schema_information #:nodoc:
|
||||
sm_table = ActiveRecord::Migrator.schema_migrations_table_name
|
||||
|
||||
ActiveRecord::SchemaMigration.order('version').map { |sm|
|
||||
"INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');"
|
||||
}.join "\n\n"
|
||||
"INSERT INTO #{sm_table} (version, migrated_at, fingerprint, name) VALUES ('#{sm.version}',LOCALTIMESTAMP,'#{sm.fingerprint}','#{sm.name}');"
|
||||
}.join("\n\n")
|
||||
end
|
||||
|
||||
# Should not be called normally, but this operation is non-destructive.
|
||||
@ -512,7 +512,7 @@ def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migra
|
||||
end
|
||||
|
||||
unless migrated.include?(version)
|
||||
execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')"
|
||||
ActiveRecord::SchemaMigration.create!(:version => version, :migrated_at => Time.now)
|
||||
end
|
||||
|
||||
inserted = Set.new
|
||||
@ -520,7 +520,7 @@ def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migra
|
||||
if inserted.include?(v)
|
||||
raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict."
|
||||
elsif v < version
|
||||
execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')"
|
||||
ActiveRecord::SchemaMigration.create!(:version => v, :migrated_at => Time.now)
|
||||
inserted << v
|
||||
end
|
||||
end
|
||||
|
@ -1,5 +1,6 @@
|
||||
require "active_support/core_ext/class/attribute_accessors"
|
||||
require 'set'
|
||||
require 'digest/md5'
|
||||
|
||||
module ActiveRecord
|
||||
# Exception that can be raised to stop migrations from going backwards.
|
||||
@ -554,6 +555,10 @@ def basename
|
||||
|
||||
delegate :migrate, :announce, :write, :to => :migration
|
||||
|
||||
def fingerprint
|
||||
@fingerprint ||= Digest::MD5.hexdigest(File.read(filename))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def migration
|
||||
@ -724,7 +729,7 @@ def run
|
||||
raise UnknownMigrationVersionError.new(@target_version) if target.nil?
|
||||
unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i))
|
||||
target.migrate(@direction)
|
||||
record_version_state_after_migrating(target.version)
|
||||
record_version_state_after_migrating(target)
|
||||
end
|
||||
end
|
||||
|
||||
@ -747,7 +752,7 @@ def migrate
|
||||
begin
|
||||
ddl_transaction do
|
||||
migration.migrate(@direction)
|
||||
record_version_state_after_migrating(migration.version)
|
||||
record_version_state_after_migrating(migration)
|
||||
end
|
||||
rescue => e
|
||||
canceled_msg = Base.connection.supports_ddl_transactions? ? "this and " : ""
|
||||
@ -805,13 +810,18 @@ def validate(migrations)
|
||||
raise DuplicateMigrationVersionError.new(version) if version
|
||||
end
|
||||
|
||||
def record_version_state_after_migrating(version)
|
||||
def record_version_state_after_migrating(target)
|
||||
if down?
|
||||
migrated.delete(version)
|
||||
ActiveRecord::SchemaMigration.where(:version => version.to_s).delete_all
|
||||
migrated.delete(target.version)
|
||||
ActiveRecord::SchemaMigration.where(:version => target.version.to_s).delete_all
|
||||
else
|
||||
migrated << version
|
||||
ActiveRecord::SchemaMigration.create!(:version => version.to_s)
|
||||
migrated << target.version
|
||||
ActiveRecord::SchemaMigration.create!(
|
||||
:version => target.version.to_s,
|
||||
:migrated_at => Time.now,
|
||||
:fingerprint => target.fingerprint,
|
||||
:name => File.basename(target.filename,'.rb').gsub(/^\d+_/,'')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -39,27 +39,45 @@ def migrations_paths
|
||||
end
|
||||
|
||||
def define(info, &block) # :nodoc:
|
||||
@using_deprecated_version_setting = info[:version].present?
|
||||
SchemaMigration.drop_table
|
||||
initialize_schema_migrations_table
|
||||
|
||||
instance_eval(&block)
|
||||
|
||||
unless info[:version].blank?
|
||||
initialize_schema_migrations_table
|
||||
assume_migrated_upto_version(info[:version], migrations_paths)
|
||||
end
|
||||
# handle files from pre-4.0 that used :version option instead of dumping migration table
|
||||
assume_migrated_upto_version(info[:version], migrations_paths) if @using_deprecated_version_setting
|
||||
end
|
||||
|
||||
# Eval the given block. All methods available to the current connection
|
||||
# adapter are available within the block, so you can easily use the
|
||||
# database definition DSL to build up your schema (+create_table+,
|
||||
# +add_index+, etc.).
|
||||
#
|
||||
# The +info+ hash is optional, and if given is used to define metadata
|
||||
# about the current schema (currently, only the schema's version):
|
||||
#
|
||||
# ActiveRecord::Schema.define(version: 20380119000001) do
|
||||
# ...
|
||||
# end
|
||||
def self.define(info={}, &block)
|
||||
new.define(info, &block)
|
||||
end
|
||||
|
||||
# Create schema migration history. Include migration statements in a block to this method.
|
||||
#
|
||||
# migrations do
|
||||
# migration 20121128235959, "44f1397e3b92442ca7488a029068a5ad", "add_horn_color_to_unicorns"
|
||||
# migration 20121129235959, "4a1eb3965d94406b00002b370854eae8", "add_magic_power_to_unicorns"
|
||||
# end
|
||||
def migrations
|
||||
raise(ArgumentError, "Can't set migrations while using :version option") if @using_deprecated_version_setting
|
||||
yield
|
||||
end
|
||||
|
||||
# Add a migration to the ActiveRecord::SchemaMigration table.
|
||||
#
|
||||
# The +version+ argument is an integer.
|
||||
# The +fingerprint+ and +name+ arguments are required but may be empty strings.
|
||||
# The migration's +migrated_at+ attribute is set to the current time,
|
||||
# instead of being set explicitly as an argument to the method.
|
||||
#
|
||||
# migration 20121129235959, "4a1eb3965d94406b00002b370854eae8", "add_magic_power_to_unicorns"
|
||||
def migration(version, fingerprint, name)
|
||||
SchemaMigration.create!(version: version, migrated_at: Time.now, fingerprint: fingerprint, name: name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -24,6 +24,7 @@ def self.dump(connection=ActiveRecord::Base.connection, stream=STDOUT)
|
||||
|
||||
def dump(stream)
|
||||
header(stream)
|
||||
migrations(stream)
|
||||
tables(stream)
|
||||
trailer(stream)
|
||||
stream
|
||||
@ -44,7 +45,7 @@ def header(stream)
|
||||
stream.puts "# encoding: #{stream.external_encoding.name}"
|
||||
end
|
||||
|
||||
stream.puts <<HEADER
|
||||
header_text = <<HEADER_RUBY
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
@ -59,13 +60,25 @@ def header(stream)
|
||||
|
||||
ActiveRecord::Schema.define(#{define_params}) do
|
||||
|
||||
HEADER
|
||||
HEADER_RUBY
|
||||
stream.puts header_text
|
||||
end
|
||||
|
||||
def trailer(stream)
|
||||
stream.puts "end"
|
||||
end
|
||||
|
||||
def migrations(stream)
|
||||
all_migrations = ActiveRecord::SchemaMigration.all.to_a
|
||||
if all_migrations.any?
|
||||
stream.puts(" migrations do")
|
||||
all_migrations.each do |migration|
|
||||
stream.puts(migration.schema_line(" "))
|
||||
end
|
||||
stream.puts(" end")
|
||||
end
|
||||
end
|
||||
|
||||
def tables(stream)
|
||||
@connection.tables.sort.each do |tbl|
|
||||
next if ['schema_migrations', ignore_tables].flatten.any? do |ignored|
|
||||
|
@ -14,17 +14,38 @@ def self.index_name
|
||||
end
|
||||
|
||||
def self.create_table
|
||||
unless connection.table_exists?(table_name)
|
||||
if connection.table_exists?(table_name)
|
||||
cols = connection.columns(table_name).collect { |col| col.name }
|
||||
unless cols.include?("migrated_at")
|
||||
connection.add_column(table_name, "migrated_at", :datetime)
|
||||
q_table_name = connection.quote_table_name(table_name)
|
||||
q_timestamp = connection.quoted_date(Time.now)
|
||||
connection.update("UPDATE #{q_table_name} SET migrated_at = '#{q_timestamp}' WHERE migrated_at IS NULL")
|
||||
connection.change_column(table_name, "migrated_at", :datetime, :null => false)
|
||||
end
|
||||
unless cols.include?("fingerprint")
|
||||
connection.add_column(table_name, "fingerprint", :string, :limit => 32)
|
||||
end
|
||||
unless cols.include?("name")
|
||||
connection.add_column(table_name, "name", :string)
|
||||
end
|
||||
else
|
||||
connection.create_table(table_name, :id => false) do |t|
|
||||
t.column :version, :string, :null => false
|
||||
t.column :migrated_at, :datetime, :null => false
|
||||
t.column :fingerprint, :string, :limit => 32
|
||||
t.column :name, :string
|
||||
end
|
||||
connection.add_index table_name, :version, :unique => true, :name => index_name
|
||||
connection.add_index(table_name, "version", :unique => true, :name => index_name)
|
||||
end
|
||||
reset_column_information
|
||||
end
|
||||
|
||||
def self.drop_table
|
||||
if connection.index_exists?(table_name, "version", :unique => true, :name => index_name)
|
||||
connection.remove_index(table_name, :name => index_name)
|
||||
end
|
||||
if connection.table_exists?(table_name)
|
||||
connection.remove_index table_name, :name => index_name
|
||||
connection.drop_table(table_name)
|
||||
end
|
||||
end
|
||||
@ -32,5 +53,17 @@ def self.drop_table
|
||||
def version
|
||||
super.to_i
|
||||
end
|
||||
|
||||
# Construct ruby source to include in schema.rb dump for this migration.
|
||||
# Pass a string of spaces as +indent+ to allow calling code to control how deeply indented the line is.
|
||||
# The generated line includes the migration version, fingerprint, and name. Either fingerprint or name
|
||||
# can be an empty string.
|
||||
#
|
||||
# Example output:
|
||||
#
|
||||
# migration 20121129235959, "ee4be703f9e6e2fc0f4baddebe6eb8f7", "add_magic_power_to_unicorns"
|
||||
def schema_line(indent)
|
||||
%Q(#{indent}migration %s, "%s", "%s") % [version, fingerprint, name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -46,4 +46,55 @@ def test_schema_subclass
|
||||
end
|
||||
end
|
||||
|
||||
class ActiveRecordSchemaMigrationsTest < ActiveRecordSchemaTest
|
||||
def setup
|
||||
super
|
||||
ActiveRecord::SchemaMigration.delete_all
|
||||
end
|
||||
|
||||
def test_migration_adds_row_to_migrations_table
|
||||
schema = ActiveRecord::Schema.new
|
||||
schema.migration(1001, "", "")
|
||||
schema.migration(1002, "123456789012345678901234567890ab", "add_magic_power_to_unicorns")
|
||||
|
||||
migrations = ActiveRecord::SchemaMigration.all.to_a
|
||||
assert_equal 2, migrations.length
|
||||
|
||||
assert_equal 1001, migrations[0].version
|
||||
assert_match %r{^2\d\d\d-}, migrations[0].migrated_at.to_s(:db)
|
||||
assert_equal "", migrations[0].fingerprint
|
||||
assert_equal "", migrations[0].name
|
||||
|
||||
assert_equal 1002, migrations[1].version
|
||||
assert_match %r{^2\d\d\d-}, migrations[1].migrated_at.to_s(:db)
|
||||
assert_equal "123456789012345678901234567890ab", migrations[1].fingerprint
|
||||
assert_equal "add_magic_power_to_unicorns", migrations[1].name
|
||||
end
|
||||
|
||||
def test_define_clears_schema_migrations
|
||||
assert_nothing_raised do
|
||||
ActiveRecord::Schema.define do
|
||||
migrations do
|
||||
migration(123001, "", "")
|
||||
end
|
||||
end
|
||||
ActiveRecord::Schema.define do
|
||||
migrations do
|
||||
migration(123001, "", "")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_define_raises_if_both_version_and_explicit_migrations
|
||||
assert_raise(ArgumentError) do
|
||||
ActiveRecord::Schema.define(version: 123001) do
|
||||
migrations do
|
||||
migration(123001, "", "")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -6,10 +6,12 @@ class LoggerTest < ActiveRecord::TestCase
|
||||
# mysql can't roll back ddl changes
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
Migration = Struct.new(:name, :version) do
|
||||
Migration = Struct.new(:name, :version, :filename, :fingerprint) do
|
||||
def migrate direction
|
||||
# do nothing
|
||||
end
|
||||
def filename; "anon.rb"; end
|
||||
def fingerprint; "123456789012345678901234567890ab"; end
|
||||
end
|
||||
|
||||
def setup
|
||||
|
@ -1,24 +0,0 @@
|
||||
require "cases/helper"
|
||||
|
||||
module ActiveRecord
|
||||
class Migration
|
||||
class TableAndIndexTest < ActiveRecord::TestCase
|
||||
def test_add_schema_info_respects_prefix_and_suffix
|
||||
conn = ActiveRecord::Base.connection
|
||||
|
||||
conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
|
||||
# Use shorter prefix and suffix as in Oracle database identifier cannot be larger than 30 characters
|
||||
ActiveRecord::Base.table_name_prefix = 'p_'
|
||||
ActiveRecord::Base.table_name_suffix = '_s'
|
||||
conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
|
||||
|
||||
conn.initialize_schema_migrations_table
|
||||
|
||||
assert_equal "p_unique_schema_migrations_s", conn.indexes(ActiveRecord::Migrator.schema_migrations_table_name)[0][:name]
|
||||
ensure
|
||||
ActiveRecord::Base.table_name_prefix = ""
|
||||
ActiveRecord::Base.table_name_suffix = ""
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -59,12 +59,21 @@ def teardown
|
||||
def test_migrator_versions
|
||||
migrations_path = MIGRATIONS_ROOT + "/valid"
|
||||
ActiveRecord::Migrator.migrations_paths = migrations_path
|
||||
m0_path = File.join(migrations_path, "1_valid_people_have_last_names.rb")
|
||||
m0_fingerprint = Digest::MD5.hexdigest(File.read(m0_path))
|
||||
|
||||
ActiveRecord::Migrator.up(migrations_path)
|
||||
assert_equal 3, ActiveRecord::Migrator.current_version
|
||||
assert_equal 3, ActiveRecord::Migrator.last_version
|
||||
assert_equal false, ActiveRecord::Migrator.needs_migration?
|
||||
|
||||
rows = connection.select_all("SELECT * FROM #{connection.quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)}")
|
||||
assert_equal m0_fingerprint, rows[0]["fingerprint"]
|
||||
assert_equal "valid_people_have_last_names", rows[0]["name"]
|
||||
rows.each do |row|
|
||||
assert_match(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, row["migrated_at"], "missing migrated_at")
|
||||
end
|
||||
|
||||
ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid")
|
||||
assert_equal 0, ActiveRecord::Migrator.current_version
|
||||
assert_equal 3, ActiveRecord::Migrator.last_version
|
||||
@ -337,7 +346,7 @@ def test_create_table_with_binary_column
|
||||
|
||||
assert_nothing_raised {
|
||||
Person.connection.create_table :binary_testings do |t|
|
||||
t.column "data", :binary, :null => false
|
||||
t.column :data, :binary, :null => false
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,9 @@ def initialize name = self.class.name, version = nil
|
||||
|
||||
def up; @went_up = true; end
|
||||
def down; @went_down = true; end
|
||||
# also used in place of a MigrationProxy
|
||||
def filename; "anon.rb"; end
|
||||
def fingerprint; "123456789012345678901234567890ab"; end
|
||||
end
|
||||
|
||||
def setup
|
||||
@ -102,7 +105,7 @@ def test_relative_migrations
|
||||
end
|
||||
|
||||
def test_finds_pending_migrations
|
||||
ActiveRecord::SchemaMigration.create!(:version => '1')
|
||||
ActiveRecord::SchemaMigration.create!(:version => '1', :name => "anon", :migrated_at => Time.now)
|
||||
migration_list = [ Migration.new('foo', 1), Migration.new('bar', 3) ]
|
||||
migrations = ActiveRecord::Migrator.new(:up, migration_list).pending_migrations
|
||||
|
||||
@ -152,7 +155,7 @@ def test_down_calls_down
|
||||
end
|
||||
|
||||
def test_current_version
|
||||
ActiveRecord::SchemaMigration.create!(:version => '1000')
|
||||
ActiveRecord::SchemaMigration.create!(:version => '1000', :name => "anon", :migrated_at => Time.now)
|
||||
assert_equal 1000, ActiveRecord::Migrator.current_version
|
||||
end
|
||||
|
||||
@ -320,7 +323,7 @@ def test_migrator_forward
|
||||
|
||||
def test_only_loads_pending_migrations
|
||||
# migrate up to 1
|
||||
ActiveRecord::SchemaMigration.create!(:version => '1')
|
||||
ActiveRecord::SchemaMigration.create!(:version => '1', :name => "anon", :migrated_at => Time.now)
|
||||
|
||||
calls, migrator = migrator_class(3)
|
||||
migrator.migrate("valid", nil)
|
||||
|
@ -1,6 +1,5 @@
|
||||
require "cases/helper"
|
||||
|
||||
|
||||
class SchemaDumperTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
super
|
||||
@ -18,11 +17,15 @@ def standard_dump
|
||||
def test_dump_schema_information_outputs_lexically_ordered_versions
|
||||
versions = %w{ 20100101010101 20100201010101 20100301010101 }
|
||||
versions.reverse.each do |v|
|
||||
ActiveRecord::SchemaMigration.create!(:version => v)
|
||||
ActiveRecord::SchemaMigration.create!(
|
||||
:version => v, :migrated_at => Time.now,
|
||||
:fingerprint => "123456789012345678901234567890ab", :name => "anon")
|
||||
end
|
||||
|
||||
schema_info = ActiveRecord::Base.connection.dump_schema_information
|
||||
assert_match(/20100201010101.*20100301010101/m, schema_info)
|
||||
target_line = %q{INSERT INTO schema_migrations (version, migrated_at, fingerprint, name) VALUES ('20100101010101',LOCALTIMESTAMP,'123456789012345678901234567890ab','anon');}
|
||||
assert_match target_line, schema_info
|
||||
end
|
||||
|
||||
def test_magic_comment
|
||||
@ -36,6 +39,16 @@ def test_schema_dump
|
||||
assert_no_match %r{create_table "schema_migrations"}, output
|
||||
end
|
||||
|
||||
def test_schema_dump_includes_migrations
|
||||
ActiveRecord::SchemaMigration.delete_all
|
||||
ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/always_safe")
|
||||
|
||||
output = standard_dump
|
||||
assert_match %r{migrations do}, output, "Missing migrations block"
|
||||
assert_match %r{migration 1001, "[0-9a-f]{32}", "always_safe"}, output, "Missing migration line"
|
||||
assert_match %r{migration 1002, "[0-9a-f]{32}", "still_safe"}, output, "Missing migration line"
|
||||
end
|
||||
|
||||
def test_schema_dump_excludes_sqlite_sequence
|
||||
output = standard_dump
|
||||
assert_no_match %r{create_table "sqlite_sequence"}, output
|
||||
|
54
activerecord/test/cases/schema_migration_test.rb
Normal file
54
activerecord/test/cases/schema_migration_test.rb
Normal file
@ -0,0 +1,54 @@
|
||||
require "cases/helper"
|
||||
|
||||
class SchemaMigrationTest < ActiveRecord::TestCase
|
||||
def sm_table_name
|
||||
ActiveRecord::SchemaMigration.table_name
|
||||
end
|
||||
|
||||
def connection
|
||||
ActiveRecord::Base.connection
|
||||
end
|
||||
|
||||
def test_add_schema_info_respects_prefix_and_suffix
|
||||
connection.drop_table(sm_table_name) if connection.table_exists?(sm_table_name)
|
||||
# Use shorter prefix and suffix as in Oracle database identifier cannot be larger than 30 characters
|
||||
ActiveRecord::Base.table_name_prefix = 'p_'
|
||||
ActiveRecord::Base.table_name_suffix = '_s'
|
||||
connection.drop_table(sm_table_name) if connection.table_exists?(sm_table_name)
|
||||
|
||||
ActiveRecord::SchemaMigration.create_table
|
||||
|
||||
assert_equal "p_unique_schema_migrations_s", connection.indexes(sm_table_name)[0][:name]
|
||||
ensure
|
||||
ActiveRecord::Base.table_name_prefix = ""
|
||||
ActiveRecord::Base.table_name_suffix = ""
|
||||
end
|
||||
|
||||
def test_add_metadata_columns_to_exisiting_schema_migrations
|
||||
# creates the old table schema from pre-Rails4.0, so we can test adding to it below
|
||||
if connection.table_exists?(sm_table_name)
|
||||
connection.drop_table(sm_table_name)
|
||||
end
|
||||
connection.create_table(sm_table_name, :id => false) do |schema_migrations_table|
|
||||
schema_migrations_table.column("version", :string, :null => false)
|
||||
end
|
||||
|
||||
connection.insert "INSERT INTO #{connection.quote_table_name(sm_table_name)} (version) VALUES (100)"
|
||||
connection.insert "INSERT INTO #{connection.quote_table_name(sm_table_name)} (version) VALUES (200)"
|
||||
|
||||
ActiveRecord::SchemaMigration.create_table
|
||||
|
||||
rows = connection.select_all("SELECT * FROM #{connection.quote_table_name(sm_table_name)}")
|
||||
assert rows[0].has_key?("migrated_at"), "missing column `migrated_at`"
|
||||
assert_match(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, rows[0]["migrated_at"])
|
||||
assert rows[0].has_key?("fingerprint"), "missing column `fingerprint`"
|
||||
assert rows[0].has_key?("name"), "missing column `name`"
|
||||
end
|
||||
|
||||
def test_schema_migrations_columns
|
||||
ActiveRecord::SchemaMigration.create_table
|
||||
|
||||
columns = connection.columns(sm_table_name).collect(&:name)
|
||||
%w[version migrated_at fingerprint name].each { |col| assert columns.include?(col), "missing column `#{col}`" }
|
||||
end
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
class AlwaysSafe < ActiveRecord::Migration
|
||||
def change
|
||||
# do nothing to avoid side-effect conflicts from running multiple times
|
||||
end
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
class StillSafe < ActiveRecord::Migration
|
||||
def change
|
||||
# do nothing to avoid side-effect conflicts from running multiple times
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user