public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Added MigrationProxy to defer loading of Migration classes until they are 
actually required by the migrator

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#747 state:resolved]
Fri Aug 01 22:44:02 -0700 2008
NZKoz (committer)
Wed Aug 06 03:46:52 -0700 2008
commit  080974784582e1e289c2948227b446bc56d404a1
tree    99f7a9679a1dadddfda338db67ef311bafdb902c
parent  29a06f10e8600bbda333c30bf294e7896f35b8d5
...
349
350
351
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
353
354
...
437
438
439
440
 
441
442
443
...
470
471
472
473
474
475
476
477
 
 
 
 
478
479
480
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
...
458
459
460
 
461
462
463
464
...
491
492
493
 
 
 
 
 
494
495
496
497
498
499
500
0
@@ -349,6 +349,27 @@ module ActiveRecord
0
     end
0
   end
0
 
0
+  # MigrationProxy is used to defer loading of the actual migration classes
0
+  # until they are needed
0
+  class MigrationProxy
0
+
0
+    attr_accessor :name, :version, :filename
0
+
0
+    delegate :migrate, :announce, :write, :to=>:migration
0
+
0
+    private
0
+
0
+      def migration
0
+        @migration ||= load_migration
0
+      end
0
+
0
+      def load_migration
0
+        load(filename)
0
+        name.constantize
0
+      end
0
+
0
+  end
0
+
0
   class Migrator#:nodoc:
0
     class << self
0
       def migrate(migrations_path, target_version = nil)
0
@@ -437,7 +458,7 @@ module ActiveRecord
0
       runnable.pop if down? && !target.nil?
0
       
0
       runnable.each do |migration|
0
-        Base.logger.info "Migrating to #{migration} (#{migration.version})"
0
+        Base.logger.info "Migrating to #{migration.name} (#{migration.version})"
0
 
0
         # On our way up, we skip migrating the ones we've already migrated
0
         # On our way down, we skip reverting the ones we've never migrated
0
@@ -470,11 +491,10 @@ module ActiveRecord
0
             raise DuplicateMigrationNameError.new(name.camelize) 
0
           end
0
           
0
-          load(file)
0
-          
0
-          klasses << returning(name.camelize.constantize) do |klass|
0
-            class << klass; attr_accessor :version end
0
-            klass.version = version
0
+          klasses << returning(MigrationProxy.new) do |migration|
0
+            migration.name     = name.camelize
0
+            migration.version  = version
0
+            migration.filename = file
0
           end
0
         end
0
         
...
922
923
924
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
925
926
927
...
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
0
@@ -922,6 +922,26 @@ if ActiveRecord::Base.connection.supports_migrations?
0
       migrations[0].name    == 'innocent_jointable'
0
     end
0
 
0
+    def test_only_loads_pending_migrations
0
+      # migrate up to 1
0
+      ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
0
+
0
+      # now unload the migrations that have been defined
0
+      PeopleHaveLastNames.unloadable
0
+      ActiveSupport::Dependencies.remove_unloadable_constants!
0
+
0
+      ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)
0
+
0
+      assert !defined? PeopleHaveLastNames
0
+
0
+      %w(WeNeedReminders, InnocentJointable).each do |migration|
0
+        assert defined? migration
0
+      end
0
+
0
+    ensure
0
+      load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
0
+    end
0
+
0
     def test_migrator_interleaved_migrations
0
       ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1")
0
 

Comments