| // 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 | |
| } | |
| } |