@@ -678,8 +678,79 @@ def empty_insert_statement_value
678678 "VALUES ()"
679679 end
680680
681+ # @note since AR 4.2
682+ def valid_type? ( type )
683+ ! native_database_types [ type ] . nil?
684+ end
685+
686+ # @private
687+ Type = ActiveRecord ::Type if AR42
688+
681689 protected
682690
691+ # @private
692+ def initialize_type_map ( m )
693+ super
694+
695+ register_class_with_limit m , %r(char)i , MysqlString
696+
697+ m . register_type %r(tinytext)i , Type ::Text . new ( limit : 2 **8 - 1 )
698+ m . register_type %r(tinyblob)i , Type ::Binary . new ( limit : 2 **8 - 1 )
699+ m . register_type %r(text)i , Type ::Text . new ( limit : 2 **16 - 1 )
700+ m . register_type %r(blob)i , Type ::Binary . new ( limit : 2 **16 - 1 )
701+ m . register_type %r(mediumtext)i , Type ::Text . new ( limit : 2 **24 - 1 )
702+ m . register_type %r(mediumblob)i , Type ::Binary . new ( limit : 2 **24 - 1 )
703+ m . register_type %r(longtext)i , Type ::Text . new ( limit : 2 **32 - 1 )
704+ m . register_type %r(longblob)i , Type ::Binary . new ( limit : 2 **32 - 1 )
705+ m . register_type %r(^float)i , Type ::Float . new ( limit : 24 )
706+ m . register_type %r(^double)i , Type ::Float . new ( limit : 53 )
707+
708+ register_integer_type m , %r(^bigint)i , limit : 8
709+ register_integer_type m , %r(^int)i , limit : 4
710+ register_integer_type m , %r(^mediumint)i , limit : 3
711+ register_integer_type m , %r(^smallint)i , limit : 2
712+ register_integer_type m , %r(^tinyint)i , limit : 1
713+
714+ m . alias_type %r(tinyint\( 1\) )i , 'boolean' if emulate_booleans
715+ m . alias_type %r(set)i , 'varchar'
716+ m . alias_type %r(year)i , 'integer'
717+ m . alias_type %r(bit)i , 'binary'
718+
719+ m . register_type ( %r(datetime)i ) do |sql_type |
720+ precision = extract_precision ( sql_type )
721+ MysqlDateTime . new ( precision : precision )
722+ end
723+
724+ m . register_type ( %r(enum)i ) do |sql_type |
725+ limit = sql_type [ /^enum\( (.+)\) /i , 1 ]
726+ . split ( ',' ) . map { |enum | enum . strip . length - 2 } . max
727+ MysqlString . new ( limit : limit )
728+ end
729+ end if AR42
730+
731+ # @private
732+ def register_integer_type ( mapping , key , options )
733+ mapping . register_type ( key ) do |sql_type |
734+ if /unsigned/i =~ sql_type
735+ Type ::UnsignedInteger . new ( options )
736+ else
737+ Type ::Integer . new ( options )
738+ end
739+ end
740+ end if AR42
741+
742+ # MySQL is too stupid to create a temporary table for use subquery, so we have
743+ # to give it some prompting in the form of a subsubquery. Ugh!
744+ # @note since AR 4.2
745+ def subquery_for ( key , select )
746+ subsubselect = select . clone
747+ subsubselect . projections = [ key ]
748+
749+ subselect = Arel ::SelectManager . new ( select . engine )
750+ subselect . project Arel . sql ( key . name )
751+ subselect . from subsubselect . as ( '__active_record_temp' )
752+ end if AR42
753+
683754 def quoted_columns_for_index ( column_names , options = { } )
684755 length = options [ :length ] if options . is_a? ( Hash )
685756
@@ -744,6 +815,39 @@ def full_version
744815 end
745816 end
746817
818+ # @private
819+ def emulate_booleans ; ::ArJdbc ::MySQL . emulate_booleans? ; end # due AR 4.2
820+
821+ # @private
822+ class MysqlDateTime < Type ::DateTime
823+ private
824+
825+ def has_precision?
826+ precision || 0
827+ end
828+ end if AR42
829+
830+ # @private
831+ class MysqlString < Type ::String
832+ def type_cast_for_database ( value )
833+ case value
834+ when true then "1"
835+ when false then "0"
836+ else super
837+ end
838+ end
839+
840+ private
841+
842+ def cast_value ( value )
843+ case value
844+ when true then "1"
845+ when false then "0"
846+ else super
847+ end
848+ end
849+ end if AR42
850+
747851 end
748852end
749853
0 commit comments