123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
- //
- // Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
- // You can obtain one at http://mozilla.org/MPL/2.0/.
- package mysql
- import (
- "database/sql"
- "reflect"
- )
- func (mf *mysqlField) typeDatabaseName() string {
- switch mf.fieldType {
- case fieldTypeBit:
- return "BIT"
- case fieldTypeBLOB:
- if mf.charSet != binaryCollationID {
- return "TEXT"
- }
- return "BLOB"
- case fieldTypeDate:
- return "DATE"
- case fieldTypeDateTime:
- return "DATETIME"
- case fieldTypeDecimal:
- return "DECIMAL"
- case fieldTypeDouble:
- return "DOUBLE"
- case fieldTypeEnum:
- return "ENUM"
- case fieldTypeFloat:
- return "FLOAT"
- case fieldTypeGeometry:
- return "GEOMETRY"
- case fieldTypeInt24:
- if mf.flags&flagUnsigned != 0 {
- return "UNSIGNED MEDIUMINT"
- }
- return "MEDIUMINT"
- case fieldTypeJSON:
- return "JSON"
- case fieldTypeLong:
- if mf.flags&flagUnsigned != 0 {
- return "UNSIGNED INT"
- }
- return "INT"
- case fieldTypeLongBLOB:
- if mf.charSet != binaryCollationID {
- return "LONGTEXT"
- }
- return "LONGBLOB"
- case fieldTypeLongLong:
- if mf.flags&flagUnsigned != 0 {
- return "UNSIGNED BIGINT"
- }
- return "BIGINT"
- case fieldTypeMediumBLOB:
- if mf.charSet != binaryCollationID {
- return "MEDIUMTEXT"
- }
- return "MEDIUMBLOB"
- case fieldTypeNewDate:
- return "DATE"
- case fieldTypeNewDecimal:
- return "DECIMAL"
- case fieldTypeNULL:
- return "NULL"
- case fieldTypeSet:
- return "SET"
- case fieldTypeShort:
- if mf.flags&flagUnsigned != 0 {
- return "UNSIGNED SMALLINT"
- }
- return "SMALLINT"
- case fieldTypeString:
- if mf.flags&flagEnum != 0 {
- return "ENUM"
- } else if mf.flags&flagSet != 0 {
- return "SET"
- }
- if mf.charSet == binaryCollationID {
- return "BINARY"
- }
- return "CHAR"
- case fieldTypeTime:
- return "TIME"
- case fieldTypeTimestamp:
- return "TIMESTAMP"
- case fieldTypeTiny:
- if mf.flags&flagUnsigned != 0 {
- return "UNSIGNED TINYINT"
- }
- return "TINYINT"
- case fieldTypeTinyBLOB:
- if mf.charSet != binaryCollationID {
- return "TINYTEXT"
- }
- return "TINYBLOB"
- case fieldTypeVarChar:
- if mf.charSet == binaryCollationID {
- return "VARBINARY"
- }
- return "VARCHAR"
- case fieldTypeVarString:
- if mf.charSet == binaryCollationID {
- return "VARBINARY"
- }
- return "VARCHAR"
- case fieldTypeYear:
- return "YEAR"
- default:
- return ""
- }
- }
- var (
- scanTypeFloat32 = reflect.TypeOf(float32(0))
- scanTypeFloat64 = reflect.TypeOf(float64(0))
- scanTypeInt8 = reflect.TypeOf(int8(0))
- scanTypeInt16 = reflect.TypeOf(int16(0))
- scanTypeInt32 = reflect.TypeOf(int32(0))
- scanTypeInt64 = reflect.TypeOf(int64(0))
- scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
- scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
- scanTypeNullTime = reflect.TypeOf(sql.NullTime{})
- scanTypeUint8 = reflect.TypeOf(uint8(0))
- scanTypeUint16 = reflect.TypeOf(uint16(0))
- scanTypeUint32 = reflect.TypeOf(uint32(0))
- scanTypeUint64 = reflect.TypeOf(uint64(0))
- scanTypeString = reflect.TypeOf("")
- scanTypeNullString = reflect.TypeOf(sql.NullString{})
- scanTypeBytes = reflect.TypeOf([]byte{})
- scanTypeUnknown = reflect.TypeOf(new(any))
- )
- type mysqlField struct {
- tableName string
- name string
- length uint32
- flags fieldFlag
- fieldType fieldType
- decimals byte
- charSet uint8
- }
- func (mf *mysqlField) scanType() reflect.Type {
- switch mf.fieldType {
- case fieldTypeTiny:
- if mf.flags&flagNotNULL != 0 {
- if mf.flags&flagUnsigned != 0 {
- return scanTypeUint8
- }
- return scanTypeInt8
- }
- return scanTypeNullInt
- case fieldTypeShort, fieldTypeYear:
- if mf.flags&flagNotNULL != 0 {
- if mf.flags&flagUnsigned != 0 {
- return scanTypeUint16
- }
- return scanTypeInt16
- }
- return scanTypeNullInt
- case fieldTypeInt24, fieldTypeLong:
- if mf.flags&flagNotNULL != 0 {
- if mf.flags&flagUnsigned != 0 {
- return scanTypeUint32
- }
- return scanTypeInt32
- }
- return scanTypeNullInt
- case fieldTypeLongLong:
- if mf.flags&flagNotNULL != 0 {
- if mf.flags&flagUnsigned != 0 {
- return scanTypeUint64
- }
- return scanTypeInt64
- }
- return scanTypeNullInt
- case fieldTypeFloat:
- if mf.flags&flagNotNULL != 0 {
- return scanTypeFloat32
- }
- return scanTypeNullFloat
- case fieldTypeDouble:
- if mf.flags&flagNotNULL != 0 {
- return scanTypeFloat64
- }
- return scanTypeNullFloat
- case fieldTypeBit, fieldTypeTinyBLOB, fieldTypeMediumBLOB, fieldTypeLongBLOB,
- fieldTypeBLOB, fieldTypeVarString, fieldTypeString, fieldTypeGeometry:
- if mf.charSet == binaryCollationID {
- return scanTypeBytes
- }
- fallthrough
- case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
- fieldTypeEnum, fieldTypeSet, fieldTypeJSON, fieldTypeTime:
- if mf.flags&flagNotNULL != 0 {
- return scanTypeString
- }
- return scanTypeNullString
- case fieldTypeDate, fieldTypeNewDate,
- fieldTypeTimestamp, fieldTypeDateTime:
- // NullTime is always returned for more consistent behavior as it can
- // handle both cases of parseTime regardless if the field is nullable.
- return scanTypeNullTime
- default:
- return scanTypeUnknown
- }
- }
|