141 lines
3.7 KiB
Go
141 lines
3.7 KiB
Go
// 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"
|
|
)
|
|
|
|
var typeDatabaseName = map[fieldType]string{
|
|
fieldTypeBit: "BIT",
|
|
fieldTypeBLOB: "BLOB",
|
|
fieldTypeDate: "DATE",
|
|
fieldTypeDateTime: "DATETIME",
|
|
fieldTypeDecimal: "DECIMAL",
|
|
fieldTypeDouble: "DOUBLE",
|
|
fieldTypeEnum: "ENUM",
|
|
fieldTypeFloat: "FLOAT",
|
|
fieldTypeGeometry: "GEOMETRY",
|
|
fieldTypeInt24: "MEDIUMINT",
|
|
fieldTypeJSON: "JSON",
|
|
fieldTypeLong: "INT",
|
|
fieldTypeLongBLOB: "LONGBLOB",
|
|
fieldTypeLongLong: "BIGINT",
|
|
fieldTypeMediumBLOB: "MEDIUMBLOB",
|
|
fieldTypeNewDate: "DATE",
|
|
fieldTypeNewDecimal: "DECIMAL",
|
|
fieldTypeNULL: "NULL",
|
|
fieldTypeSet: "SET",
|
|
fieldTypeShort: "SMALLINT",
|
|
fieldTypeString: "CHAR",
|
|
fieldTypeTime: "TIME",
|
|
fieldTypeTimestamp: "TIMESTAMP",
|
|
fieldTypeTiny: "TINYINT",
|
|
fieldTypeTinyBLOB: "TINYBLOB",
|
|
fieldTypeVarChar: "VARCHAR",
|
|
fieldTypeVarString: "VARCHAR",
|
|
fieldTypeYear: "YEAR",
|
|
}
|
|
|
|
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(NullTime{})
|
|
scanTypeUint8 = reflect.TypeOf(uint8(0))
|
|
scanTypeUint16 = reflect.TypeOf(uint16(0))
|
|
scanTypeUint32 = reflect.TypeOf(uint32(0))
|
|
scanTypeUint64 = reflect.TypeOf(uint64(0))
|
|
scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
|
|
scanTypeUnknown = reflect.TypeOf(new(interface{}))
|
|
)
|
|
|
|
type mysqlField struct {
|
|
tableName string
|
|
name string
|
|
length uint32
|
|
flags fieldFlag
|
|
fieldType fieldType
|
|
decimals byte
|
|
}
|
|
|
|
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 fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
|
|
fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
|
|
fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
|
|
fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON,
|
|
fieldTypeTime:
|
|
return scanTypeRawBytes
|
|
|
|
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
|
|
}
|
|
}
|