Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6999: rename_column_migration_in_mysql_keeps_default_and_null_state_and_auto_increment.diff

File rename_column_migration_in_mysql_keeps_default_and_null_state_and_auto_increment.diff, 6.0 kB (added by two, 1 year ago)
  • activerecord/test/migration_test.rb

    old new  
    421421      end 
    422422    end 
    423423 
     424    def test_rename_column_preserves_default_and_not_null_state 
     425      begin 
     426        Person.connection.add_column "people", "contibutions", :integer, :default => 10, :null => false 
     427        Person.reset_column_information 
     428        columns = Person.connection.columns(:people) 
     429        column = columns.detect { |c| c.name == "contibutions" } 
     430        assert_equal 10, column.default 
     431        assert !column.null 
     432 
     433        Person.connection.rename_column("people", "contibutions", "contributions") 
     434        Person.reset_column_information 
     435        columns = Person.connection.columns(:people) 
     436        column = columns.detect { |c| c.name == "contributions" } 
     437        assert_equal 10, column.default 
     438        assert !column.null 
     439      ensure 
     440        Person.connection.remove_column("people", "contibutions") rescue ActiveRecord::StatementInvalid 
     441        Person.connection.remove_column("people", "contributions") rescue ActiveRecord::StatementInvalid 
     442      end 
     443    end 
     444 
     445    if current_adapter?(:MysqlAdapter) 
     446      def test_rename_column_preserves_auto_increment 
     447        begin 
     448          ActiveRecord::Base.connection.create_table(:legacy) {} # We just need the id column 
     449          legacy = Class.new(ActiveRecord::Base) 
     450          legacy.send(:define_attr_method, :table_name, "legacy") 
     451          options = legacy.connection.select_one("SHOW COLUMNS FROM legacy LIKE 'id'") 
     452          assert_equal 'auto_increment', options['Extra']  
     453 
     454          legacy.connection.rename_column("legacy", "id", "orig_id") 
     455          options = legacy.connection.select_one("SHOW COLUMNS FROM legacy LIKE 'orig_id'") 
     456          assert_equal 'auto_increment', options['Extra']  
     457        ensure 
     458          ActiveRecord::Base.connection.drop_table :legacy rescue nil 
     459        end 
     460      end 
     461       
     462      def test_rename_column_does_handle_mysql_misreport_of_not_null_column_default 
     463        begin 
     464          Person.connection.add_column "people", "contibutions", :integer, :null => false 
     465          Person.reset_column_information 
     466          columns = Person.connection.columns(:people) 
     467          column = columns.detect { |c| c.name == "contibutions" } 
     468          assert_equal nil, column.default 
     469          assert !column.null 
     470 
     471          Person.connection.rename_column("people", "contibutions", "contributions") 
     472          Person.reset_column_information 
     473          columns = Person.connection.columns(:people) 
     474          column = columns.detect { |c| c.name == "contributions" } 
     475          assert_equal nil, column.default 
     476          assert !column.null 
     477        ensure 
     478          Person.connection.remove_column("people", "contibutions") rescue ActiveRecord::StatementInvalid 
     479          Person.connection.remove_column("people", "contributions") rescue ActiveRecord::StatementInvalid 
     480        end 
     481      end 
     482       
     483      def test_rename_column_keeps_empty_default 
     484        begin 
     485          Person.connection.add_column "people", "state", :string, :default => "" 
     486          Person.reset_column_information 
     487          columns = Person.connection.columns(:people) 
     488          column = columns.detect { |c| c.name == "state" } 
     489          assert_equal '', column.default 
     490          assert column.null 
     491 
     492          Person.connection.rename_column("people", "state", "mood") 
     493          Person.reset_column_information 
     494          columns = Person.connection.columns(:people) 
     495          column = columns.detect { |c| c.name == "mood" } 
     496          assert_equal '', column.default 
     497          assert column.null 
     498        ensure 
     499          Person.connection.remove_column("people", "state") rescue ActiveRecord::StatementInvalid 
     500          Person.connection.remove_column("people", "mood") rescue ActiveRecord::StatementInvalid 
     501        end 
     502      end 
     503    end 
     504 
    424505    def test_rename_table 
    425506      begin 
    426507        ActiveRecord::Base.connection.create_table :octopuses do |t| 
  • activerecord/lib/active_record/connection_adapters/mysql_adapter.rb

    old new  
    8888      TYPES_DISALLOWING_DEFAULT = Set.new([:binary, :text]) 
    8989      TYPES_ALLOWING_EMPTY_STRING_DEFAULT = Set.new([:string]) 
    9090 
    91       def initialize(name, default, sql_type = nil, null = true) 
     91      attr_accessor :extra 
     92 
     93      def initialize(name, default, sql_type = nil, null = true, extra = '') 
    9294        @original_default = default 
    93         super 
     95        super(name, default, sql_type, null) 
    9496        @default = nil if no_default_allowed? || missing_default_forged_as_empty_string? 
    9597        @default = '' if @original_default == '' && no_default_allowed? 
     98        @extra = extra 
    9699      end 
    97100 
    98101      private 
     
    412415      end 
    413416 
    414417      def rename_column(table_name, column_name, new_column_name) #:nodoc: 
    415         current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"] 
    416         execute "ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}" 
     418        options = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'") 
     419        col = MysqlColumn.new(column_name, options["Default"], options["Type"], options["Null"] == "YES", options["Extra"]) 
     420        rename_column_sql = "ALTER TABLE #{table_name} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{col.sql_type}" 
     421        add_column_options!(rename_column_sql, :default => col.default, :null => col.null, :extra => col.extra) 
     422        execute(rename_column_sql) 
    417423      end 
    418424 
     425      def add_column_options!(sql, options) #:nodoc: 
     426        super 
     427        sql << " #{options[:extra]}" unless options[:extra].blank? 
     428      end 
    419429 
    420430      # SHOW VARIABLES LIKE 'name' 
    421431      def show_variable(name)