aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-09-04 00:31:35 +0200
committerJosé Valim <jose.valim@gmail.com>2010-09-04 00:31:43 +0200
commit23a9455962f0362cf242ffa96db7a9e7fdb0804b (patch)
treec046d1285d078649db6833fa1b73a6c23f7f16ea /activerecord/lib
parent63032c1162e96d3380168ca63ac42aa044dbebd6 (diff)
parentc3c1a1e14859e6716970283caeab0c4c3720862e (diff)
downloadrails-23a9455962f0362cf242ffa96db7a9e7fdb0804b.tar.gz
rails-23a9455962f0362cf242ffa96db7a9e7fdb0804b.tar.bz2
rails-23a9455962f0362cf242ffa96db7a9e7fdb0804b.zip
This commit merges most of the work done by Piotr Sarnacki in his Ruby Summer of Code project.
His work brings several capabilities from app to engines, as routes, middleware stack, asset handling and much more. Please check Rails::Engine documentation for more refenrences. Merge remote branch 'drogus/engines'
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