File: lib/radiant/extension_migrator.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Radiant#1
  class: ExtensionMigrator#2
inherits from
  Migrator ( ActiveRecord )
has properties
class attribute: extension [RW] #4
class method: migrate / 1 #6
class method: migrate_extensions #10
class method: get_all_versions #17
method: initialize / 3 #24
method: quote / 1 #31
method: extension_name #35
method: version_string / 1 #39
method: initialize_extension_schema_migrations #43
method: initialize_received_migrations #51
method: assume_migrated_upto_version / 1 #61
method: record_version_state_after_migrating / 1 #85

Class Hierarchy

Code

   1  module Radiant
   2    class ExtensionMigrator < ActiveRecord::Migrator
   3      class << self
   4        attr_accessor :extension
   5 
   6        def migrate(target_version = nil)
   7          super extension.migrations_path, target_version
   8        end
   9        
  10        def migrate_extensions
  11          Radiant.configuration.enabled_extensions.each do |ext|
  12            to_migrate = Extension.descendants.detect{|descendant| descendant.name == "#{ext.to_s.camelize}Extension" }
  13            to_migrate.migrator.migrate
  14          end
  15        end
  16 
  17        def get_all_versions
  18          ActiveRecord::Base.connection.select_values("SELECT version FROM #{schema_migrations_table_name}").
  19            select { |version| version.starts_with?("#{@extension.extension_name}-")}.
  20            map { |version| version.sub("#{@extension.extension_name}-", '').to_i }.sort
  21        end
  22      end
  23      
  24      def initialize(direction, migrations_path, target_version = nil)
  25        super
  26        initialize_extension_schema_migrations
  27        initialize_received_migrations
  28      end
  29      
  30      private
  31        def quote(s)
  32          ActiveRecord::Base.connection.quote(s)
  33        end
  34        
  35        def extension_name
  36          self.class.extension.extension_name
  37        end
  38        
  39        def version_string(version)
  40          "#{extension_name}-#{version}"
  41        end
  42        
  43        def initialize_extension_schema_migrations
  44          current_version = ActiveRecord::Base.connection.select_value("SELECT schema_version FROM extension_meta WHERE name = #{quote(extension_name)}")
  45          if current_version
  46            assume_migrated_upto_version(current_version.to_i) 
  47            ActiveRecord::Base.connection.delete("DELETE FROM extension_meta WHERE name = #{quote(extension_name)}")
  48          end
  49        end
  50 
  51        def initialize_received_migrations
  52          if donors = self.class.extension.migrates_from
  53            donors.each do |extension_name, until_migration|
  54              replaced = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name} WHERE version LIKE '#{extension_name}-%'").map{|v| v.sub(/^#{extension_name}\-/, '').to_i}
  55              replaced.delete_if{|v| v > until_migration.to_i} if until_migration
  56              assume_migrated_upto_version(replaced.max) if replaced.any?
  57            end
  58          end
  59        end
  60        
  61        def assume_migrated_upto_version(version)
  62          version = version.to_i
  63          sm_table = self.class.schema_migrations_table_name
  64 
  65          migrated = self.class.get_all_versions
  66          versions = Dir["#{@migrations_path}/[0-9]*_*.rb"].map do |filename|
  67            filename.split('/').last.split('_').first.to_i
  68          end
  69 
  70          unless migrated.include?(version)
  71            ActiveRecord::Base.connection.execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version_string(version))})"
  72          end
  73 
  74          inserted = Set.new
  75          (versions - migrated).each do |v|
  76            if inserted.include?(v)
  77              raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict."
  78            elsif v < version
  79              ActiveRecord::Base.connection.execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version_string(v))})"
  80              inserted << v
  81            end
  82          end
  83        end
  84        
  85        def record_version_state_after_migrating(version)
  86          sm_table = self.class.schema_migrations_table_name
  87 
  88          @migrated_versions ||= []
  89          if down?
  90            @migrated_versions.delete(version.to_i)
  91            ActiveRecord::Base.connection.update("DELETE FROM #{sm_table} WHERE version = #{quote(version_string(version))}")
  92          else
  93            @migrated_versions.push(version.to_i).sort!
  94            ActiveRecord::Base.connection.insert("INSERT INTO #{sm_table} (version) VALUES (#{quote(version_string(version))})")
  95          end
  96        end
  97    end
  98  end