<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,12 @@
 = EDGE
 
+* Samuel Williams (http://www.oriontransfer.co.nz/):
+	Thanks to Tekin for his patches.
+	Updated migrations system to tie in more closely with the current rails mechanism.
+	Rake task for updating database schema info
+		rake db:migrate:upgrade_plugin_migrations
+	Please see http://engines.lighthouseapp.com/projects/10178-engines-plugin/tickets/17 for more information.
+
 * Refactored the view loading to work with changes in Edge Rails
 
 * Fixed integration of plugin migrations with the new, default timestamped migrations in Edge Rails</diff>
      <filename>CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -5,8 +5,7 @@ class PluginMigrationGenerator &lt; Rails::Generator::Base
   def initialize(runtime_args, runtime_options={})
     super
     @options = {:assigns =&gt; {}}
-    
-    ensure_plugin_schema_table_exists
+    ensure_schema_table_exists    
     get_plugins_to_migrate(runtime_args)
     
     if @plugins_to_migrate.empty?
@@ -25,10 +24,9 @@ class PluginMigrationGenerator &lt; Rails::Generator::Base
   end
   
   protected
-  
-    # Create the plugin schema table if it doesn't already exist. See
-    # Engines::RailsExtensions::Migrations#initialize_schema_migrations_table_with_engine_additions
-    def ensure_plugin_schema_table_exists
+
+    # Create the schema table if it doesn't already exist.
+    def ensure_schema_table_exists
       ActiveRecord::Base.connection.initialize_schema_migrations_table
     end
 
@@ -70,10 +68,11 @@ class PluginMigrationGenerator &lt; Rails::Generator::Base
     end
 
     # Construct a unique migration name based on the plugins involved and the
-    # versions they should reach after this migration is run.
+    # versions they should reach after this migration is run. The name constructed
+    # needs to be lowercase
     def build_migration_name
       @plugins_to_migrate.map do |plugin| 
         &quot;#{plugin.name}_to_version_#{@new_versions[plugin.name]}&quot; 
-      end.join(&quot;_and_&quot;)
+      end.join(&quot;_and_&quot;).downcase
     end  
 end
\ No newline at end of file</diff>
      <filename>generators/plugin_migration/plugin_migration_generator.rb</filename>
    </modified>
    <modified>
      <diff>@@ -111,11 +111,15 @@ module Engines
     # Returns the version number of the latest migration for this plugin. Returns
     # nil if this plugin has no migrations.
     def latest_migration
+      migrations.last
+    end
+    
+    # Returns the version numbers of all migrations for this plugin.
+    def migrations
       migrations = Dir[migration_directory+&quot;/*.rb&quot;]
-      return nil if migrations.empty?
-      migrations.map { |p| File.basename(p) }.sort.last.match(/0*(\d+)\_/)[1].to_i
+      migrations.map { |p| File.basename(p).match(/0*(\d+)\_/)[1].to_i }.sort
     end
-  
+    
     # Migrate this plugin to the given version. See Engines::Plugin::Migrator for more
     # information.   
     def migrate(version = nil)</diff>
      <filename>lib/engines/plugin.rb</filename>
    </modified>
    <modified>
      <diff>@@ -12,63 +12,30 @@ class Engines::Plugin::Migrator &lt; ActiveRecord::Migrator
   # We need to be able to set the 'current' engine being migrated.
   cattr_accessor :current_plugin
 
-  # Runs the migrations from a plugin, up (or down) to the version given
-  def self.migrate_plugin(plugin, version)
-    self.current_plugin = plugin
-    # There seems to be a bug in Rails' own migrations, where migrating
-    # to the existing version causes all migrations to be run where that
-    # migration number doesn't exist (i.e. zero). We could fix this by
-    # removing the line if the version hits zero...?
-    return if current_version(plugin) == version
-    migrate(plugin.migration_directory, version)
-  end
-  
-  # Returns the name of the table used to store schema information about
-  # installed plugins.
-  #
-  # See Engines.schema_info_table for more details.
-  def self.schema_info_table_name
-    proper_table_name Engines.schema_info_table
-  end
-
-  # Returns the current version of the given plugin
-  def self.current_version(plugin=current_plugin)
-    result = ActiveRecord::Base.connection.select_one(&lt;&lt;-ESQL
-      SELECT version FROM #{schema_info_table_name} 
-      WHERE plugin_name = '#{plugin.name}'
-    ESQL
-    )
-    if result
-      result[&quot;version&quot;].to_i
-    else
-      # There probably isn't an entry for this engine in the migration info table.
-      # We need to create that entry, and set the version to 0
-      ActiveRecord::Base.connection.execute(&lt;&lt;-ESQL
-        INSERT INTO #{schema_info_table_name} (version, plugin_name) 
-        VALUES (0,'#{plugin.name}')
-      ESQL
-      )      
-      0
+  class &lt;&lt; self
+    # Runs the migrations from a plugin, up (or down) to the version given
+    def migrate_plugin(plugin, version)
+      self.current_plugin = plugin
+      return if current_version(plugin) == version
+      migrate(plugin.migration_directory, version)
+    end
+    
+    def current_version(plugin=current_plugin)
+      # Delete migrations that don't match .. to_i will work because the number comes first
+      ::ActiveRecord::Base.connection.select_values(
+        &quot;SELECT version FROM #{schema_migrations_table_name}&quot;
+      ).delete_if{ |v| v.match(/-#{plugin.name}/) == nil }.map(&amp;:to_i).max || 0
     end
   end
-  
-  def migrated(plugin=current_plugin)
-    current = ActiveRecord::Base.connection.select_value(&lt;&lt;-ESQL
-      SELECT version FROM #{self.class.schema_info_table_name}
-      WHERE plugin_name = '#{plugin.name}'
-    ESQL
-    ).to_i
-    current ? (1..current).to_a : []
+       
+  def migrated
+    sm_table = self.class.schema_migrations_table_name
+    ::ActiveRecord::Base.connection.select_values(
+      &quot;SELECT version FROM #{sm_table}&quot;
+    ).delete_if{ |v| v.match(/-#{current_plugin.name}/) == nil }.map(&amp;:to_i).sort
   end
   
-  # Sets the version of the plugin in Engines::Plugin::Migrator.current_plugin to
-  # the given version.
   def record_version_state_after_migrating(version)
-    ActiveRecord::Base.connection.update(&lt;&lt;-ESQL
-      UPDATE #{self.class.schema_info_table_name} 
-      SET version = #{down? ? version.to_i - 1 : version.to_i} 
-      WHERE plugin_name = '#{self.current_plugin.name}'
-    ESQL
-    )
+    super(version.to_s + &quot;-&quot; + current_plugin.name)
   end
 end</diff>
      <filename>lib/engines/plugin/migrator.rb</filename>
    </modified>
    <modified>
      <diff>@@ -120,42 +120,4 @@ require &quot;engines/plugin/migrator&quot;
 #
 # ---
 #
-# The Engines::RailsExtensions::Migrations module defines extensions for Rails' 
-# migration systems. Specifically:
-#
-# * Adding a hook to initialize_schema_migrations_table to create the plugin schema
-#   info table.
-#
-module Engines::RailsExtensions::Migrations
-  def self.included(base) # :nodoc:
-    base.class_eval { alias_method_chain :initialize_schema_migrations_table, :engine_additions }
-  end
-
-  # Create the schema tables, and ensure that the plugin schema table
-  # is also initialized. The plugin schema info table is defined by
-  # Engines::Plugin::Migrator.schema_info_table_name.
-  def initialize_schema_migrations_table_with_engine_additions
-    initialize_schema_migrations_table_without_engine_additions
-
-    # create the plugin schema stuff.    
-    begin
-      execute &lt;&lt;-ESQL
-        CREATE TABLE #{Engines::Plugin::Migrator.schema_info_table_name} 
-          (plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})
-      ESQL
-    rescue ActiveRecord::StatementInvalid
-      # Schema has been initialized
-    end
-  end
-end
-
-module ::ActiveRecord #:nodoc:
-  module ConnectionAdapters #:nodoc:
-    module SchemaStatements #:nodoc:
-      include Engines::RailsExtensions::Migrations
-    end
-  end
-end
-
-# Set ActiveRecord to ignore the plugin schema table by default
-::ActiveRecord::SchemaDumper.ignore_tables &lt;&lt; Engines.schema_info_table
\ No newline at end of file
+# We no longer need Engines::RailsExtensions::Migrations as we are now relying on the migration mechanism in Rails 2.1
\ No newline at end of file</diff>
      <filename>lib/engines/rails_extensions/migrations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -43,6 +43,77 @@ namespace :db do
       end
     end
 
+    desc 'For engines coming from Rails version &lt; 2.0, you need to upgrade the schema info table'
+    task :upgrade_plugin_migrations =&gt; :environment do
+      # This task will upgrade Rails &lt; 2.0, and also databases previously updated with
+      # db:migrate:fix_engines_migrations
+      
+      # Old table name
+      old_sm_table = ActiveRecord::Migrator.proper_table_name(Engines.schema_info_table)
+      
+      unless ActiveRecord::Base.connection.table_exists?(old_sm_table)
+        abort &quot;Cannot find old migration table - assuming nothing needs to be done&quot;
+      end
+      
+      # There are two forms of the engines schema info - pre-fix_plugin_migrations and post
+      # We need to figure this out before we continue.
+      
+      results = ActiveRecord::Base.connection.select_rows(
+        &quot;SELECT version, plugin_name FROM #{old_sm_table}&quot;
+      ).uniq
+      
+      def insert_new_version(plugin_name, version)
+        version_string = &quot;#{version}-#{plugin_name}&quot;
+        new_sm_table = ActiveRecord::Migrator.schema_migrations_table_name
+        
+        # Check if the row already exists for some reason - maybe run this task more than once.
+        return if ActiveRecord::Base.connection.select_rows(&quot;SELECT * FROM #{new_sm_table} WHERE version = #{version_string.dump}&quot;).size &gt; 0
+        
+        puts &quot;Inserting new version #{version} for plugin #{plugin_name}..&quot;
+        ActiveRecord::Base.connection.insert(&quot;INSERT INTO #{new_sm_table} (version) VALUES (#{version_string.dump})&quot;)
+      end
+      
+      # We need to figure out if they already used &quot;fix_plugin_migrations&quot;
+      versions = {}
+      results.each do |r|
+        versions[r[1]] ||= []
+        versions[r[1]] &lt;&lt; r[0].to_i
+      end
+      
+      if versions.values.find{ |v| v.size &gt; 1 } == nil
+        puts &quot;Fixing migration info&quot;
+        # We only have one listed migration per plugin - this is pre-fix_plugin_migrations,
+        # so we build all versions required. In this case, all migrations should 
+        versions.each do |plugin_name, version|
+          version = version[0] # There is only one version
+          
+          # We have to make an assumption that numeric migrations won't get this long..
+          # I'm not sure if there is a better assumption, it should work in all
+          # current cases.. (touch wood..)
+          if version.to_s.size &lt; &quot;YYYYMMDDHHMMSS&quot;.size
+            # Insert version records for each migration
+            (1..version).each do |v|
+             insert_new_version(plugin_name, v)
+            end
+          else
+            # If the plugin is new-format &quot;YYYYMMDDHHMMSS&quot;, we just copy it across... 
+            # The case in which this occurs is very rare..
+            insert_new_version(plugin_name, version)
+          end
+        end
+      else
+        puts &quot;Moving migration info&quot;
+        # We have multiple migrations listed per plugin - thus we can assume they have
+        # already applied fix_plugin_migrations - we just copy it across verbatim
+        versions.each do |plugin_name, version|
+          version.each { |v| insert_new_version(plugin_name, v) }
+        end
+      end
+      
+      puts &quot;Migration info successfully migrated - removing old schema info table&quot;
+      ActiveRecord::Base.connection.drop_table(old_sm_table)
+    end
+    
     desc 'Migrate a specified plugin.'
     task({:plugin =&gt; :environment}, :name, :version) do |task, args|
       name = args[:name] || ENV['NAME']
@@ -53,7 +124,7 @@ namespace :db do
       else
         puts &quot;Plugin #{name} does not exist.&quot;
       end
-    end    
+    end
   end
 end
 
@@ -174,5 +245,5 @@ Report any issues on http://dev.rails-engines.org. Thanks!
     
     # Patch the default plugin testing task to have setup_plugin_fixtures as a prerequisite
     Rake::Task[&quot;test:plugins&quot;].prerequisites &lt;&lt; &quot;test:plugins:setup_plugin_fixtures&quot;
-  end  
-end
\ No newline at end of file
+  end
+end</diff>
      <filename>tasks/engines.rake</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>55b9489bd1d8c62a0ad13f2fc8b4f5dc9869100a</id>
    </parent>
  </parents>
  <author>
    <name>James Adam</name>
    <email>james@lazyatom.com</email>
  </author>
  <url>http://github.com/lazyatom/engines/commit/e659294b73ededec7d367c523dd7c77a7d282e6c</url>
  <id>e659294b73ededec7d367c523dd7c77a7d282e6c</id>
  <committed-date>2008-10-24T06:04:00-07:00</committed-date>
  <authored-date>2008-10-24T06:04:00-07:00</authored-date>
  <message>Samuel Williams' patch for using Rails' own migration mechanism.</message>
  <tree>5c1be2dc93a0c232aabcd1efc7d1567e81ae9297</tree>
  <committer>
    <name>James Adam</name>
    <email>james@lazyatom.com</email>
  </committer>
</commit>
