aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/migration.rb96
-rw-r--r--activerecord/lib/active_record/railties/databases.rake35
-rw-r--r--activerecord/lib/rails/generators/active_record.rb6
3 files changed, 102 insertions, 35 deletions
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 198f0a18cb..e708b3fbcf 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -383,6 +383,37 @@ module ActiveRecord
connection.send(method, *arguments, &block)
end
end
+
+ def copy(destination, sources)
+ copied = []
+
+ sources.each do |scope, path|
+ destination_migrations = ActiveRecord::Migrator.migrations(destination)
+ source_migrations = ActiveRecord::Migrator.migrations(path)
+ last = destination_migrations.last
+
+ source_migrations.each do |migration|
+ next if destination_migrations.any? { |m| m.name == migration.name && m.scope == scope.to_s }
+
+ migration.version = next_migration_number(last ? last.version + 1 : 0).to_i
+ last = migration
+
+ new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.#{scope}.rb")
+ FileUtils.cp(migration.filename, new_path)
+ copied << new_path
+ end
+ end
+
+ copied
+ end
+
+ def next_migration_number(number)
+ if ActiveRecord::Base.timestamped_migrations
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
+ else
+ "%.3d" % number
+ end
+ end
end
end
@@ -390,7 +421,7 @@ module ActiveRecord
# until they are needed
class MigrationProxy
- attr_accessor :name, :version, :filename
+ attr_accessor :name, :version, :filename, :scope
delegate :migrate, :announce, :write, :to=>:migration
@@ -409,6 +440,8 @@ module ActiveRecord
class Migrator#:nodoc:
class << self
+ attr_writer :migrations_path
+
def migrate(migrations_path, target_version = nil)
case
when target_version.nil?
@@ -441,10 +474,6 @@ module ActiveRecord
self.new(direction, migrations_path, target_version).run
end
- def migrations_path
- 'db/migrate'
- end
-
def schema_migrations_table_name
Base.table_name_prefix + 'schema_migrations' + Base.table_name_suffix
end
@@ -468,6 +497,38 @@ module ActiveRecord
name.table_name rescue "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}"
end
+ def migrations_path
+ @migrations_path ||= 'db/migrate'
+ end
+
+ def migrations(path)
+ files = Dir["#{path}/[0-9]*_*.rb"]
+
+ migrations = files.inject([]) do |klasses, file|
+ version, name, scope = file.scan(/([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?.rb/).first
+
+ raise IllegalMigrationNameError.new(file) unless version
+ version = version.to_i
+
+ if klasses.detect { |m| m.version == version }
+ raise DuplicateMigrationVersionError.new(version)
+ end
+
+ if klasses.detect { |m| m.name == name.camelize && m.scope == scope }
+ raise DuplicateMigrationNameError.new(name.camelize)
+ end
+
+ migration = MigrationProxy.new
+ migration.name = name.camelize
+ migration.version = version
+ migration.filename = file
+ migration.scope = scope
+ klasses << migration
+ end
+
+ migrations.sort_by(&:version)
+ end
+
private
def move(direction, migrations_path, steps)
@@ -546,30 +607,7 @@ module ActiveRecord
def migrations
@migrations ||= begin
- files = Dir["#{@migrations_path}/[0-9]*_*.rb"]
-
- migrations = files.inject([]) do |klasses, file|
- version, name = file.scan(/([0-9]+)_([_a-z0-9]*).rb/).first
-
- raise IllegalMigrationNameError.new(file) unless version
- version = version.to_i
-
- if klasses.detect { |m| m.version == version }
- raise DuplicateMigrationVersionError.new(version)
- end
-
- if klasses.detect { |m| m.name == name.camelize }
- raise DuplicateMigrationNameError.new(name.camelize)
- end
-
- migration = MigrationProxy.new
- migration.name = name.camelize
- migration.version = version
- migration.filename = file
- klasses << migration
- end
-
- migrations = migrations.sort_by { |m| m.version }
+ migrations = self.class.migrations(@migrations_path)
down? ? migrations.reverse : migrations
end
end
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index b1aad0d496..aedda26ba5 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -2,6 +2,29 @@ namespace :db do
task :load_config => :rails_env do
require 'active_record'
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
+ ActiveRecord::Migrator.migrations_path = Rails.application.config.paths.db.migrate.to_a.first
+ end
+
+ desc "Copies missing migrations from Railties (e.g. plugins, engines). You can specify Railties to use with FROM=railtie1,railtie2"
+ task :copy_migrations => :load_config do
+ to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map {|n| n.strip }
+ railties = {}
+ Rails.application.railties.all do |railtie|
+ next unless to_load == :all || to_load.include?(railtie.railtie_name)
+
+ if railtie.config.respond_to?(:paths) && railtie.config.paths.db
+ railties[railtie.railtie_name] = railtie.config.paths.db.migrate.to_a.first
+ end
+ end
+
+ copied = ActiveRecord::Migration.copy(ActiveRecord::Migrator.migrations_path, railties)
+
+ if copied.blank?
+ puts "No migrations were copied, project is up to date."
+ else
+ puts "The following migrations were copied:"
+ puts copied.map{ |path| File.basename(path) }.join("\n")
+ end
end
namespace :create do
@@ -139,7 +162,7 @@ namespace :db do
desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
task :migrate => :environment do
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
- ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
+ ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_path, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end
@@ -162,7 +185,7 @@ namespace :db do
task :up => :environment do
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
raise "VERSION is required" unless version
- ActiveRecord::Migrator.run(:up, "db/migrate/", version)
+ ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_path, version)
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end
@@ -170,7 +193,7 @@ namespace :db do
task :down => :environment do
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
raise "VERSION is required" unless version
- ActiveRecord::Migrator.run(:down, "db/migrate/", version)
+ ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_path, version)
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end
@@ -208,14 +231,14 @@ namespace :db do
desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
task :rollback => :environment do
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
- ActiveRecord::Migrator.rollback('db/migrate/', step)
+ ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_path, step)
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end
# desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
task :forward => :environment do
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
- ActiveRecord::Migrator.forward('db/migrate/', step)
+ ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_path, step)
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end
@@ -260,7 +283,7 @@ namespace :db do
# desc "Raises an error if there are pending migrations"
task :abort_if_pending_migrations => :environment do
if defined? ActiveRecord
- pending_migrations = ActiveRecord::Migrator.new(:up, 'db/migrate').pending_migrations
+ pending_migrations = ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations_path).pending_migrations
if pending_migrations.any?
puts "You have #{pending_migrations.size} pending migrations:"
diff --git a/activerecord/lib/rails/generators/active_record.rb b/activerecord/lib/rails/generators/active_record.rb
index 26bc977e19..4b3d1db216 100644
--- a/activerecord/lib/rails/generators/active_record.rb
+++ b/activerecord/lib/rails/generators/active_record.rb
@@ -14,6 +14,12 @@ module ActiveRecord
def self.base_root
File.dirname(__FILE__)
end
+
+ # Implement the required interface for Rails::Generators::Migration.
+ def self.next_migration_number(dirname) #:nodoc:
+ next_migration_number = current_migration_number(dirname) + 1
+ ActiveRecord::Migration.next_migration_number(next_migration_number)
+ end
end
end
end