gitee.com/chunanyong/dm@v1.8.12/zzn.go (about)

     1  /*
     2   * Copyright (c) 2000-2018, 达梦数据库有限公司.
     3   * All rights reserved.
     4   */
     5  package dm
     6  
     7  import (
     8  	"database/sql"
     9  	"database/sql/driver"
    10  	"math"
    11  	"reflect"
    12  	"strings"
    13  	"time"
    14  )
    15  
    16  const (
    17  	INT8_MAX int8 = math.MaxInt8
    18  
    19  	INT8_MIN int8 = math.MinInt8
    20  
    21  	BYTE_MAX byte = math.MaxUint8
    22  
    23  	BYTE_MIN byte = 0
    24  
    25  	INT16_MAX int16 = math.MaxInt16
    26  
    27  	INT16_MIN int16 = math.MinInt16
    28  
    29  	UINT16_MAX uint16 = math.MaxUint16
    30  
    31  	UINT16_MIN uint16 = 0
    32  
    33  	INT32_MAX int32 = math.MaxInt32
    34  
    35  	INT32_MIN int32 = math.MinInt32
    36  
    37  	UINT32_MAX uint32 = math.MaxUint32
    38  
    39  	UINT32_MIN uint32 = 0
    40  
    41  	INT64_MAX int64 = math.MaxInt64
    42  
    43  	INT64_MIN int64 = math.MinInt64
    44  
    45  	UINT64_MAX uint64 = math.MaxUint64
    46  
    47  	UINT64_MIN uint64 = 0
    48  
    49  	FLOAT32_MAX float32 = 3.4e+38
    50  
    51  	FLOAT32_MIN float32 = -3.4e+38
    52  
    53  	BYTE_SIZE = 1
    54  
    55  	USINT_SIZE = 2
    56  
    57  	ULINT_SIZE = 4
    58  
    59  	DDWORD_SIZE = 8
    60  
    61  	LINT64_SIZE = 8
    62  
    63  	CHAR = 0
    64  
    65  	VARCHAR2 = 1
    66  
    67  	VARCHAR = 2
    68  
    69  	BIT = 3
    70  
    71  	TINYINT = 5
    72  
    73  	SMALLINT = 6
    74  
    75  	INT = 7
    76  
    77  	BIGINT = 8
    78  
    79  	DECIMAL = 9
    80  
    81  	REAL = 10
    82  
    83  	DOUBLE = 11
    84  
    85  	BLOB = 12
    86  
    87  	BOOLEAN = 13
    88  
    89  	DATE = 14
    90  
    91  	TIME = 15
    92  
    93  	DATETIME = 16
    94  
    95  	BINARY = 17
    96  
    97  	VARBINARY = 18
    98  
    99  	CLOB = 19
   100  
   101  	INTERVAL_YM = 20
   102  
   103  	INTERVAL_DT = 21
   104  
   105  	TIME_TZ = 22
   106  
   107  	DATETIME_TZ = 23
   108  
   109  	XDEC_INT32 = 24
   110  
   111  	XDEC_INT64 = 25
   112  
   113  	DATETIME2 = 26
   114  
   115  	DATETIME2_TZ = 27
   116  
   117  	NULL = 28
   118  
   119  	ANY = 31
   120  
   121  	STAR_ALL = 32
   122  
   123  	STAR = 33
   124  
   125  	RECORD = 40
   126  
   127  	TYPE = 41
   128  
   129  	TYPE_REF = 42
   130  
   131  	UNKNOWN = 54
   132  
   133  	ARRAY = 117
   134  
   135  	CLASS = 119
   136  
   137  	CURSOR = 120
   138  
   139  	PLTYPE_RECORD = 121
   140  
   141  	SARRAY = 122
   142  
   143  	CURSOR_ORACLE = -10
   144  
   145  	BIT_PREC = BYTE_SIZE
   146  
   147  	TINYINT_PREC = BYTE_SIZE
   148  
   149  	SMALLINT_PREC = USINT_SIZE
   150  
   151  	INT_PREC = ULINT_SIZE
   152  
   153  	BIGINT_PREC = LINT64_SIZE
   154  
   155  	REAL_PREC = 4
   156  
   157  	DOUBLE_PREC = 8
   158  
   159  	DATE_PREC = 3
   160  
   161  	TIME_PREC = 5
   162  
   163  	DATETIME_PREC = 8
   164  
   165  	DATETIME2_PREC = 9
   166  
   167  	TIME_TZ_PREC = TIME_PREC + 2
   168  
   169  	DATETIME_TZ_PREC = DATETIME_PREC + 2
   170  
   171  	DATETIME2_TZ_PREC = DATETIME2_PREC + 2
   172  
   173  	INTERVAL_YM_PREC = 3 * ULINT_SIZE
   174  
   175  	INTERVAL_DT_PREC = 6 * ULINT_SIZE
   176  
   177  	VARCHAR_PREC = 8188
   178  
   179  	VARBINARY_PREC = 8188
   180  
   181  	BLOB_PREC int32 = INT32_MAX
   182  
   183  	CLOB_PREC int32 = INT32_MAX
   184  
   185  	NULL_PREC = 0
   186  
   187  	LOCAL_TIME_ZONE_SCALE_MASK = 0x00001000
   188  
   189  	BFILE_PREC = 512
   190  
   191  	BFILE_SCALE = 6
   192  
   193  	COMPLEX_SCALE = 5
   194  
   195  	CURRENCY_PREC = 19
   196  
   197  	CURRENCY_SCALE = 4
   198  
   199  	LOCAL_DATETIME_SCALE_MASK int32 = 0x00001000
   200  
   201  	ORACLE_FLOAT_SCALE_MASK int32 = 0x81
   202  
   203  	ORACLE_DATE_SCALE_MASK int32 = 0x00002000
   204  )
   205  
   206  func isComplexType(colType int, scale int) bool {
   207  	return (colType == BLOB && scale == COMPLEX_SCALE) || colType == ARRAY || colType == SARRAY || colType == CLASS || colType == PLTYPE_RECORD
   208  }
   209  
   210  func isLocalTimeZone(colType int, scale int) bool {
   211  	return (colType == DATETIME || colType == DATETIME2) && (scale&LOCAL_TIME_ZONE_SCALE_MASK) != 0
   212  }
   213  
   214  func getLocalTimeZoneScale(colType int, scale int) int {
   215  	return scale & (^LOCAL_TIME_ZONE_SCALE_MASK)
   216  }
   217  
   218  func isFloat(colType int, scale int) bool {
   219  	return colType == DECIMAL && scale == int(ORACLE_FLOAT_SCALE_MASK)
   220  }
   221  
   222  func getFloatPrec(prec int) int {
   223  	return int(math.Round(float64(prec)*0.30103)) + 1
   224  }
   225  
   226  func getFloatScale(scale int) int {
   227  	return scale & (^int(ORACLE_FLOAT_SCALE_MASK))
   228  }
   229  
   230  var (
   231  	scanTypeFloat32    = reflect.TypeOf(float32(0))
   232  	scanTypeFloat64    = reflect.TypeOf(float64(0))
   233  	scanTypeBool       = reflect.TypeOf(false)
   234  	scanTypeInt8       = reflect.TypeOf(int8(0))
   235  	scanTypeInt16      = reflect.TypeOf(int16(0))
   236  	scanTypeInt32      = reflect.TypeOf(int32(0))
   237  	scanTypeInt64      = reflect.TypeOf(int64(0))
   238  	scanTypeNullBool   = reflect.TypeOf(sql.NullBool{})
   239  	scanTypeNullFloat  = reflect.TypeOf(sql.NullFloat64{})
   240  	scanTypeNullInt    = reflect.TypeOf(sql.NullInt64{})
   241  	scanTypeNullString = reflect.TypeOf(sql.NullString{})
   242  	scanTypeNullTime   = reflect.TypeOf(sql.NullTime{})
   243  	scanTypeRawBytes   = reflect.TypeOf(sql.RawBytes{})
   244  	scanTypeString     = reflect.TypeOf("")
   245  	scanTypeTime       = reflect.TypeOf(time.Now())
   246  	scanTypeUnknown    = reflect.TypeOf(new(interface{}))
   247  )
   248  
   249  func (column *column) ScanType() reflect.Type {
   250  
   251  	switch column.colType {
   252  	case BOOLEAN:
   253  		if column.nullable {
   254  			return scanTypeNullBool
   255  		}
   256  
   257  		return scanTypeBool
   258  
   259  	case BIT:
   260  		if strings.ToLower(column.typeName) == "boolean" {
   261  
   262  			if column.nullable {
   263  				return scanTypeNullBool
   264  			}
   265  
   266  			return scanTypeBool
   267  		} else {
   268  
   269  			if column.nullable {
   270  				return scanTypeNullInt
   271  			}
   272  			return scanTypeInt8
   273  		}
   274  
   275  	case TINYINT:
   276  		if column.nullable {
   277  			return scanTypeNullInt
   278  		}
   279  		return scanTypeInt8
   280  
   281  	case SMALLINT:
   282  		if column.nullable {
   283  			return scanTypeNullInt
   284  		}
   285  		return scanTypeInt16
   286  
   287  	case INT:
   288  		if column.nullable {
   289  			return scanTypeNullInt
   290  		}
   291  
   292  		return scanTypeInt32
   293  
   294  	case BIGINT:
   295  		if column.nullable {
   296  			return scanTypeNullInt
   297  		}
   298  		return scanTypeInt64
   299  
   300  	case REAL:
   301  		if column.nullable {
   302  			return scanTypeNullFloat
   303  		}
   304  
   305  		return scanTypeFloat32
   306  
   307  	case DOUBLE:
   308  
   309  		if strings.ToLower(column.typeName) == "float" {
   310  			if column.nullable {
   311  				return scanTypeNullFloat
   312  			}
   313  
   314  			return scanTypeFloat32
   315  		}
   316  
   317  		if column.nullable {
   318  			return scanTypeNullFloat
   319  		}
   320  
   321  		return scanTypeFloat64
   322  	case DATE, TIME, TIME_TZ, DATETIME, DATETIME_TZ, DATETIME2, DATETIME2_TZ:
   323  		if column.nullable {
   324  			return scanTypeNullTime
   325  		}
   326  
   327  		return scanTypeTime
   328  
   329  	case DECIMAL, BINARY, VARBINARY, BLOB:
   330  		return scanTypeRawBytes
   331  
   332  	case CHAR, VARCHAR2, VARCHAR, CLOB:
   333  		if column.nullable {
   334  			return scanTypeNullString
   335  		}
   336  		return scanTypeString
   337  	}
   338  
   339  	return scanTypeUnknown
   340  }
   341  
   342  func (column *column) Length() (length int64, ok bool) {
   343  	switch column.colType {
   344  	case BINARY, VARBINARY, BLOB, CHAR, VARCHAR2, VARCHAR, CLOB:
   345  		return int64(column.prec), true
   346  	}
   347  
   348  	return int64(0), false
   349  }
   350  
   351  func (column *column) PrecisionScale() (precision, scale int64, ok bool) {
   352  	switch column.colType {
   353  	case DECIMAL:
   354  		if column.prec == 0 {
   355  			return 38, int64(column.scale), true
   356  		} else {
   357  			return int64(column.prec), int64(column.scale), true
   358  		}
   359  	}
   360  
   361  	return int64(0), int64(0), false
   362  }
   363  
   364  func (column *column) getColumnData(bytes []byte, conn *DmConnection) (driver.Value, error) {
   365  	if bytes == nil {
   366  		return nil, nil
   367  	}
   368  
   369  	switch column.colType {
   370  	case BOOLEAN:
   371  		return bytes[0] != 0, nil
   372  	case BIT:
   373  		if strings.ToLower(column.typeName) == "boolean" {
   374  			return bytes[0] != 0, nil
   375  		}
   376  
   377  		return int8(bytes[0]), nil
   378  	case TINYINT:
   379  		return int8(bytes[0]), nil
   380  	case SMALLINT:
   381  		return Dm_build_649.Dm_build_746(bytes, 0), nil
   382  	case INT:
   383  		return Dm_build_649.Dm_build_751(bytes, 0), nil
   384  	case BIGINT:
   385  		return Dm_build_649.Dm_build_756(bytes, 0), nil
   386  	case REAL:
   387  		return Dm_build_649.Dm_build_761(bytes, 0), nil
   388  	case DOUBLE:
   389  
   390  		return Dm_build_649.Dm_build_765(bytes, 0), nil
   391  	case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_TZ:
   392  		return DB2G.toTime(bytes, column, conn)
   393  	case INTERVAL_DT:
   394  		return newDmIntervalDTByBytes(bytes).String(), nil
   395  	case INTERVAL_YM:
   396  		return newDmIntervalYMByBytes(bytes).String(), nil
   397  	case DECIMAL:
   398  		tmp, err := DB2G.toDmDecimal(bytes, column, conn)
   399  		if err != nil {
   400  			return nil, err
   401  		}
   402  		return tmp.String(), nil
   403  
   404  	case BINARY, VARBINARY:
   405  		return bytes, nil
   406  	case BLOB:
   407  		if isComplexType(int(column.colType), int(column.scale)) {
   408  			return DB2G.toComplexType(bytes, column, conn)
   409  		}
   410  		blob := DB2G.toDmBlob(bytes, column, conn)
   411  
   412  		l, err := blob.GetLength()
   413  		if err != nil {
   414  			return nil, err
   415  		}
   416  		return blob.getBytes(1, int32(l))
   417  
   418  	case CHAR, VARCHAR2, VARCHAR:
   419  		return Dm_build_649.Dm_build_806(bytes, 0, len(bytes), conn.getServerEncoding(), conn), nil
   420  	case CLOB:
   421  		clob := DB2G.toDmClob(bytes, conn, column)
   422  
   423  		l, err := clob.GetLength()
   424  		if err != nil {
   425  			return nil, err
   426  		}
   427  		return clob.getSubString(1, int32(l))
   428  
   429  	}
   430  
   431  	return string(bytes), nil
   432  }
   433  
   434  func emptyStringToNil(t int32) bool {
   435  	switch t {
   436  	case BOOLEAN, BIT, TINYINT, SMALLINT, INT, BIGINT, REAL, DOUBLE, DECIMAL, DATE, TIME,
   437  		DATETIME, INTERVAL_DT, INTERVAL_YM, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_TZ:
   438  		return true
   439  	default:
   440  		return false
   441  	}
   442  }