| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- /*
- * Copyright (c) 2000-2018, 达梦数据库有限公司.
- * All rights reserved.
- */
- package dm
- import (
- "database/sql"
- "database/sql/driver"
- "math"
- "reflect"
- "strings"
- "time"
- )
- const (
- INT8_MAX int8 = math.MaxInt8
- INT8_MIN int8 = math.MinInt8
- BYTE_MAX byte = math.MaxUint8
- BYTE_MIN byte = 0
- INT16_MAX int16 = math.MaxInt16
- INT16_MIN int16 = math.MinInt16
- UINT16_MAX uint16 = math.MaxUint16
- UINT16_MIN uint16 = 0
- INT32_MAX int32 = math.MaxInt32
- INT32_MIN int32 = math.MinInt32
- UINT32_MAX uint32 = math.MaxUint32
- UINT32_MIN uint32 = 0
- INT64_MAX int64 = math.MaxInt64
- INT64_MIN int64 = math.MinInt64
- UINT64_MAX uint64 = math.MaxUint64
- UINT64_MIN uint64 = 0
- FLOAT32_MAX float32 = 3.4e+38
- FLOAT32_MIN float32 = -3.4e+38
- BYTE_SIZE = 1
- USINT_SIZE = 2
- ULINT_SIZE = 4
- DDWORD_SIZE = 8
- LINT64_SIZE = 8
- CHAR = 0
- VARCHAR2 = 1
- VARCHAR = 2
- BIT = 3
- TINYINT = 5
- SMALLINT = 6
- INT = 7
- BIGINT = 8
- DECIMAL = 9
- REAL = 10
- DOUBLE = 11
- BLOB = 12
- BOOLEAN = 13
- DATE = 14
- TIME = 15
- DATETIME = 16
- BINARY = 17
- VARBINARY = 18
- CLOB = 19
- INTERVAL_YM = 20
- INTERVAL_DT = 21
- TIME_TZ = 22
- DATETIME_TZ = 23
- XDEC_INT32 = 24
- XDEC_INT64 = 25
- DATETIME2 = 26
- DATETIME2_TZ = 27
- NULL = 28
- ANY = 31
- STAR_ALL = 32
- STAR = 33
- RECORD = 40
- TYPE = 41
- TYPE_REF = 42
- UNKNOWN = 54
- ARRAY = 117
- CLASS = 119
- CURSOR = 120
- PLTYPE_RECORD = 121
- SARRAY = 122
- CURSOR_ORACLE = -10
- BIT_PREC = BYTE_SIZE
- TINYINT_PREC = BYTE_SIZE
- SMALLINT_PREC = USINT_SIZE
- INT_PREC = ULINT_SIZE
- BIGINT_PREC = LINT64_SIZE
- REAL_PREC = 4
- DOUBLE_PREC = 8
- DATE_PREC = 3
- TIME_PREC = 5
- DATETIME_PREC = 8
- DATETIME2_PREC = 9
- TIME_TZ_PREC = TIME_PREC + 2
- DATETIME_TZ_PREC = DATETIME_PREC + 2
- DATETIME2_TZ_PREC = DATETIME2_PREC + 2
- INTERVAL_YM_PREC = 3 * ULINT_SIZE
- INTERVAL_DT_PREC = 6 * ULINT_SIZE
- VARCHAR_PREC = 8188
- VARBINARY_PREC = 8188
- BLOB_PREC int32 = INT32_MAX
- CLOB_PREC int32 = INT32_MAX
- NULL_PREC = 0
- LOCAL_TIME_ZONE_SCALE_MASK = 0x00001000
- BFILE_PREC = 512
- BFILE_SCALE = 6
- COMPLEX_SCALE = 5
- CURRENCY_PREC = 19
- CURRENCY_SCALE = 4
- LOCAL_DATETIME_SCALE_MASK int32 = 0x00001000
- ORACLE_FLOAT_SCALE_MASK int32 = 0x81
- ORACLE_DATE_SCALE_MASK int32 = 0x00002000
- )
- func isComplexType(colType int, scale int) bool {
- return (colType == BLOB && scale == COMPLEX_SCALE) || colType == ARRAY || colType == SARRAY || colType == CLASS || colType == PLTYPE_RECORD
- }
- func isLocalTimeZone(colType int, scale int) bool {
- return (colType == DATETIME || colType == DATETIME2) && (scale&LOCAL_TIME_ZONE_SCALE_MASK) != 0
- }
- func getLocalTimeZoneScale(colType int, scale int) int {
- return scale & (^LOCAL_TIME_ZONE_SCALE_MASK)
- }
- func isFloat(colType int, scale int) bool {
- return colType == DECIMAL && scale == int(ORACLE_FLOAT_SCALE_MASK)
- }
- func getFloatPrec(prec int) int {
- return int(math.Round(float64(prec)*0.30103)) + 1
- }
- func getFloatScale(scale int) int {
- return scale & (^int(ORACLE_FLOAT_SCALE_MASK))
- }
- var (
- scanTypeFloat32 = reflect.TypeOf(float32(0))
- scanTypeFloat64 = reflect.TypeOf(float64(0))
- scanTypeBool = reflect.TypeOf(false)
- scanTypeInt8 = reflect.TypeOf(int8(0))
- scanTypeInt16 = reflect.TypeOf(int16(0))
- scanTypeInt32 = reflect.TypeOf(int32(0))
- scanTypeInt64 = reflect.TypeOf(int64(0))
- scanTypeNullBool = reflect.TypeOf(sql.NullBool{})
- scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
- scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
- scanTypeNullString = reflect.TypeOf(sql.NullString{})
- scanTypeNullTime = reflect.TypeOf(sql.NullTime{})
- scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
- scanTypeString = reflect.TypeOf("")
- scanTypeTime = reflect.TypeOf(time.Now())
- scanTypeUnknown = reflect.TypeOf(new(interface{}))
- )
- func (column *column) ScanType() reflect.Type {
- switch column.colType {
- case BOOLEAN:
- if column.nullable {
- return scanTypeNullBool
- }
- return scanTypeBool
- case BIT:
- if strings.ToLower(column.typeName) == "boolean" {
- if column.nullable {
- return scanTypeNullBool
- }
- return scanTypeBool
- } else {
- if column.nullable {
- return scanTypeNullInt
- }
- return scanTypeInt8
- }
- case TINYINT:
- if column.nullable {
- return scanTypeNullInt
- }
- return scanTypeInt8
- case SMALLINT:
- if column.nullable {
- return scanTypeNullInt
- }
- return scanTypeInt16
- case INT:
- if column.nullable {
- return scanTypeNullInt
- }
- return scanTypeInt32
- case BIGINT:
- if column.nullable {
- return scanTypeNullInt
- }
- return scanTypeInt64
- case REAL:
- if column.nullable {
- return scanTypeNullFloat
- }
- return scanTypeFloat32
- case DOUBLE:
- if strings.ToLower(column.typeName) == "float" {
- if column.nullable {
- return scanTypeNullFloat
- }
- return scanTypeFloat32
- }
- if column.nullable {
- return scanTypeNullFloat
- }
- return scanTypeFloat64
- case DATE, TIME, DATETIME, DATETIME2:
- if column.nullable {
- return scanTypeNullTime
- }
- return scanTypeTime
- case DECIMAL, BINARY, VARBINARY, BLOB:
- return scanTypeRawBytes
- case CHAR, VARCHAR2, VARCHAR, CLOB:
- if column.nullable {
- return scanTypeNullString
- }
- return scanTypeString
- }
- return scanTypeUnknown
- }
- func (column *column) Length() (length int64, ok bool) {
- switch column.colType {
- case BINARY:
- case VARBINARY:
- case BLOB:
- case CHAR:
- case VARCHAR2:
- case VARCHAR:
- case CLOB:
- return int64(column.prec), true
- }
- return int64(0), false
- }
- func (column *column) PrecisionScale() (precision, scale int64, ok bool) {
- switch column.colType {
- case DECIMAL:
- if column.prec == 0 {
- return 38, int64(column.scale), true
- } else {
- return int64(column.prec), int64(column.scale), true
- }
- }
- return int64(0), int64(0), false
- }
- func (column *column) getColumnData(bytes []byte, conn *DmConnection) (driver.Value, error) {
- if bytes == nil {
- return nil, nil
- }
- switch column.colType {
- case BOOLEAN:
- return bytes[0] != 0, nil
- case BIT:
- if strings.ToLower(column.typeName) == "boolean" {
- return bytes[0] != 0, nil
- }
- return int8(bytes[0]), nil
- case TINYINT:
- return int8(bytes[0]), nil
- case SMALLINT:
- return Dm_build_1.Dm_build_98(bytes, 0), nil
- case INT:
- return Dm_build_1.Dm_build_103(bytes, 0), nil
- case BIGINT:
- return Dm_build_1.Dm_build_108(bytes, 0), nil
- case REAL:
- return Dm_build_1.Dm_build_113(bytes, 0), nil
- case DOUBLE:
- return Dm_build_1.Dm_build_117(bytes, 0), nil
- case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_TZ:
- return DB2G.toTime(bytes, column, conn)
- case INTERVAL_DT:
- return newDmIntervalDTByBytes(bytes).String(), nil
- case INTERVAL_YM:
- return newDmIntervalYMByBytes(bytes).String(), nil
- case DECIMAL:
- tmp, err := DB2G.toDmDecimal(bytes, column, conn)
- if err != nil {
- return nil, err
- }
- return tmp.String(), nil
- case BINARY, VARBINARY:
- return bytes, nil
- case BLOB:
- if isComplexType(int(column.colType), int(column.scale)) {
- return DB2G.toComplexType(bytes, column, conn)
- }
- blob := DB2G.toDmBlob(bytes, column, conn)
- l, err := blob.GetLength()
- if err != nil {
- return nil, err
- }
- return blob.getBytes(1, int32(l))
- case CHAR, VARCHAR2, VARCHAR:
- return Dm_build_1.Dm_build_158(bytes, 0, len(bytes), conn.getServerEncoding(), conn), nil
- case CLOB:
- clob := DB2G.toDmClob(bytes, conn, column)
- l, err := clob.GetLength()
- if err != nil {
- return nil, err
- }
- return clob.getSubString(1, int32(l))
- }
- return string(bytes), nil
- }
- func emptyStringToNil(t int32) bool {
- switch t {
- case BOOLEAN, BIT, TINYINT, SMALLINT, INT, BIGINT, REAL, DOUBLE, DECIMAL, DATE, TIME,
- DATETIME, INTERVAL_DT, INTERVAL_YM, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_TZ:
- return true
- default:
- return false
- }
- }
|