forked from Shiloh/githaven
195 lines
4.6 KiB
Go
195 lines
4.6 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"
|
||
|
)
|
||
|
|
||
|
func (mf *mysqlField) typeDatabaseName() string {
|
||
|
switch mf.fieldType {
|
||
|
case fieldTypeBit:
|
||
|
return "BIT"
|
||
|
case fieldTypeBLOB:
|
||
|
if mf.charSet != collations[binaryCollation] {
|
||
|
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:
|
||
|
return "MEDIUMINT"
|
||
|
case fieldTypeJSON:
|
||
|
return "JSON"
|
||
|
case fieldTypeLong:
|
||
|
return "INT"
|
||
|
case fieldTypeLongBLOB:
|
||
|
if mf.charSet != collations[binaryCollation] {
|
||
|
return "LONGTEXT"
|
||
|
}
|
||
|
return "LONGBLOB"
|
||
|
case fieldTypeLongLong:
|
||
|
return "BIGINT"
|
||
|
case fieldTypeMediumBLOB:
|
||
|
if mf.charSet != collations[binaryCollation] {
|
||
|
return "MEDIUMTEXT"
|
||
|
}
|
||
|
return "MEDIUMBLOB"
|
||
|
case fieldTypeNewDate:
|
||
|
return "DATE"
|
||
|
case fieldTypeNewDecimal:
|
||
|
return "DECIMAL"
|
||
|
case fieldTypeNULL:
|
||
|
return "NULL"
|
||
|
case fieldTypeSet:
|
||
|
return "SET"
|
||
|
case fieldTypeShort:
|
||
|
return "SMALLINT"
|
||
|
case fieldTypeString:
|
||
|
if mf.charSet == collations[binaryCollation] {
|
||
|
return "BINARY"
|
||
|
}
|
||
|
return "CHAR"
|
||
|
case fieldTypeTime:
|
||
|
return "TIME"
|
||
|
case fieldTypeTimestamp:
|
||
|
return "TIMESTAMP"
|
||
|
case fieldTypeTiny:
|
||
|
return "TINYINT"
|
||
|
case fieldTypeTinyBLOB:
|
||
|
if mf.charSet != collations[binaryCollation] {
|
||
|
return "TINYTEXT"
|
||
|
}
|
||
|
return "TINYBLOB"
|
||
|
case fieldTypeVarChar:
|
||
|
if mf.charSet == collations[binaryCollation] {
|
||
|
return "VARBINARY"
|
||
|
}
|
||
|
return "VARCHAR"
|
||
|
case fieldTypeVarString:
|
||
|
if mf.charSet == collations[binaryCollation] {
|
||
|
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(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
|
||
|
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 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
|
||
|
}
|
||
|
}
|