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 }