aboutsummaryrefslogblamecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
blob: eff96e329fffc079537e8fa6e31523f0dc8b6681 (plain) (tree)
1
2
3
4
5
6
7


                           
                                   

                                          
                                                      






                                                                                      








                             
                                          
                                                                
             
 



                                                              
                                 



                                



                   
             
 
                                      
                                                                                                       
             
 


                                                                 
                                                                                                                                           

                                                                                                
             



                                                                      
                                                                                                                                                                       


                                       
                                                     
                                                                                    

                                                               
                                                                
                                                

               



         
module ActiveRecord
  module ConnectionAdapters
    module MySQL
      module ColumnDumper # :nodoc:
        def prepare_column_options(column)
          spec = super
          spec[:unsigned] = "true" if column.unsigned?

          if supports_virtual_columns? && column.virtual?
            spec[:as] = extract_expression_for_virtual_column(column)
            spec[:stored] = "true" if /\b(?:STORED|PERSISTENT)\b/.match?(column.extra)
            spec = { type: schema_type(column).inspect }.merge!(spec)
          end

          spec
        end

        def migration_keys
          super + [:unsigned]
        end

        private

          def default_primary_key?(column)
            super && column.auto_increment? && !column.unsigned?
          end

          def explicit_primary_key_default?(column)
            column.type == :integer && !column.auto_increment?
          end

          def schema_type(column)
            case column.sql_type
            when /\Atimestamp\b/
              :timestamp
            when "tinyblob"
              :blob
            else
              super
            end
          end

          def schema_precision(column)
            super unless /\A(?:date)?time(?:stamp)?\b/.match?(column.sql_type) && column.precision == 0
          end

          def schema_collation(column)
            if column.collation && table_name = column.table_name
              @table_collation_cache ||= {}
              @table_collation_cache[table_name] ||= exec_query("SHOW TABLE STATUS LIKE #{quote(table_name)}", "SCHEMA").first["Collation"]
              column.collation.inspect if column.collation != @table_collation_cache[table_name]
            end
          end

          def extract_expression_for_virtual_column(column)
            if mariadb?
              create_table_info = create_table_info(column.table_name)
              if %r/#{quote_column_name(column.name)} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
                $~[:expression].inspect
              end
            else
              scope = quoted_scope(column.table_name)
              sql = "SELECT generation_expression FROM information_schema.columns" \
                    " WHERE table_schema = #{scope[:schema]}" \
                    "   AND table_name = #{scope[:name]}" \
                    "   AND column_name = #{quote(column.name)}"
              query_value(sql, "SCHEMA").inspect
            end
          end
      end
    end
  end
end