aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/migration.rb
diff options
context:
space:
mode:
authorPiotr Sarnacki <drogus@gmail.com>2010-07-26 14:06:14 +0200
committerPiotr Sarnacki <drogus@gmail.com>2010-09-03 22:59:09 +0200
commit75f8ac6ea71e4b2337f870b91ac05df98f33a8d2 (patch)
treeb3fe95ec53958ce38a2b5fe23e7878dafd675b92 /activerecord/lib/active_record/migration.rb
parent2068b8cb6a8508fae9cd1a7f57e68d938c6403e6 (diff)
downloadrails-75f8ac6ea71e4b2337f870b91ac05df98f33a8d2.tar.gz
rails-75f8ac6ea71e4b2337f870b91ac05df98f33a8d2.tar.bz2
rails-75f8ac6ea71e4b2337f870b91ac05df98f33a8d2.zip
Implemented ActiveRecord::Migrations#copy based on James Adam's idea
ActiveRecord::Migration#copy allows to copy migrations from one place to another, changing migrations versions and adding scope to filename. For example: ActiveRecord::Migration.copy("db/migrate", :blog_engine => "vendor/gems/blog/db/migrate") will copy all migrations from vendor/gems/blog/db/migrate to db/migrate with such format: Versions of copied migrations will be reversioned to be appended after migrations that already exists in db/migrate
Diffstat (limited to 'activerecord/lib/active_record/migration.rb')
-rw-r--r--activerecord/lib/active_record/migration.rb86
1 files changed, 61 insertions, 25 deletions
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 932ded414a..293c9f3c08 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.version + 1).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
@@ -470,6 +501,34 @@ module ActiveRecord
@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)
@@ -548,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