From 0a5afa229d769bce9e221f34053bb93b60817a5a Mon Sep 17 00:00:00 2001 From: Josh Susser Date: Sat, 1 Dec 2012 18:32:23 -0800 Subject: Add metadata to schema_migrations migrated_at: timestamp when migration run fingerprint: md5 hash of migration source name: filename without version or extension --- .../abstract/schema_statements.rb | 6 ++--- activerecord/lib/active_record/migration.rb | 24 ++++++++++++------ activerecord/lib/active_record/schema_migration.rb | 29 +++++++++++++++++++--- 3 files changed, 45 insertions(+), 14 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index f1e42dfbbe..7802cb02d8 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -490,7 +490,7 @@ module ActiveRecord sm_table = ActiveRecord::Migrator.schema_migrations_table_name ActiveRecord::SchemaMigration.order('version').map { |sm| - "INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');" + "INSERT INTO #{sm_table} (version, migrated_at, name) VALUES ('#{sm.version}',LOCALTIMESTAMP,'#{sm.name}');" }.join "\n\n" end @@ -512,7 +512,7 @@ module ActiveRecord 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 @@ module ActiveRecord 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 diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 22347fcaef..4ce276d4bf 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -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 @@ module ActiveRecord delegate :migrate, :announce, :write, :to => :migration + def fingerprint + @fingerprint ||= Digest::MD5.hexdigest(File.read(filename)) + end + private def migration @@ -724,7 +729,7 @@ module ActiveRecord 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 @@ module ActiveRecord 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 @@ module ActiveRecord 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 diff --git a/activerecord/lib/active_record/schema_migration.rb b/activerecord/lib/active_record/schema_migration.rb index 9830abe7d8..fd226d5eba 100644 --- a/activerecord/lib/active_record/schema_migration.rb +++ b/activerecord/lib/active_record/schema_migration.rb @@ -14,17 +14,38 @@ module ActiveRecord 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 "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 -- cgit v1.2.3