gitee.com/curryzheng/dm@v0.0.1/v.go (about) 1 /* 2 * Copyright (c) 2000-2018, 达梦数据库有限公司. 3 * All rights reserved. 4 */ 5 package dm 6 7 import ( 8 "container/list" 9 "context" 10 "database/sql" 11 "database/sql/driver" 12 "fmt" 13 "gitee.com/curryzheng/dm/util" 14 "io" 15 "math/big" 16 "reflect" 17 "strconv" 18 "strings" 19 "time" 20 ) 21 22 const ( 23 BIND_IN byte = 0x01 24 25 BIND_OUT byte = 0x10 26 ) 27 28 var rp = newRsPool() 29 30 type DmStatement struct { 31 filterable 32 33 dmConn *DmConnection 34 rsMap map[int16]*innerRows 35 inUse bool 36 innerUsed bool 37 38 innerExec bool 39 40 id int32 41 42 cursorName string 43 44 readBaseColName bool 45 46 execInfo *execRetInfo 47 48 resultSetType int 49 50 resultSetConcurrency int 51 52 resultSetHoldability int 53 54 nativeSql string 55 56 maxFieldSize int 57 58 maxRows int64 59 60 escapeProcessing bool 61 62 queryTimeout int32 63 64 fetchDirection int 65 66 fetchSize int 67 68 cursorUpdateRow int64 69 70 closeOnCompletion bool 71 72 isBatch bool 73 74 closed bool 75 76 columns []column 77 78 params []parameter 79 80 paramCount int32 81 82 curRowBindIndicator []byte 83 84 preExec bool 85 } 86 87 type stmtPoolInfo struct { 88 id int32 89 90 cursorName string 91 92 readBaseColName bool 93 } 94 95 type rsPoolKey struct { 96 dbGuid string 97 currentSchema string 98 sql string 99 paramCount int 100 } 101 102 func newRsPoolKey(stmt *DmStatement, sql string) rsPoolKey { 103 rpk := new(rsPoolKey) 104 rpk.dbGuid = stmt.dmConn.Guid 105 rpk.currentSchema = stmt.dmConn.Schema 106 rpk.paramCount = int(stmt.paramCount) 107 108 rpk.sql = sql 109 return *rpk 110 } 111 112 func (key rsPoolKey) equals(destKey rsPoolKey) bool { 113 return key.dbGuid == destKey.dbGuid && 114 key.currentSchema == destKey.currentSchema && 115 key.sql == destKey.sql && 116 key.paramCount == destKey.paramCount 117 118 } 119 120 type rsPoolValue struct { 121 m_lastChkTime int 122 m_TbIds []int32 123 m_TbTss []int64 124 execInfo *execRetInfo 125 } 126 127 func newRsPoolValue(execInfo *execRetInfo) rsPoolValue { 128 rpv := new(rsPoolValue) 129 rpv.execInfo = execInfo 130 rpv.m_lastChkTime = time.Now().Nanosecond() 131 copy(rpv.m_TbIds, execInfo.tbIds) 132 copy(rpv.m_TbTss, execInfo.tbTss) 133 return *rpv 134 } 135 136 func (rpv rsPoolValue) refreshed(conn *DmConnection) (bool, error) { 137 138 if conn.dmConnector.rsRefreshFreq == 0 { 139 return false, nil 140 } 141 142 if rpv.m_lastChkTime+conn.dmConnector.rsRefreshFreq*int(time.Second) > time.Now().Nanosecond() { 143 return false, nil 144 } 145 146 tss, err := conn.Access.Dm_build_840(interface{}(rpv.m_TbIds).([]uint32)) 147 if err != nil { 148 return false, err 149 } 150 rpv.m_lastChkTime = time.Now().Nanosecond() 151 152 var tbCount int 153 if tss != nil { 154 tbCount = len(tss) 155 } 156 157 if tbCount != len(rpv.m_TbTss) { 158 return true, nil 159 } 160 161 for i := 0; i < tbCount; i++ { 162 if rpv.m_TbTss[i] != tss[i] { 163 return true, nil 164 } 165 166 } 167 return false, nil 168 } 169 170 func (rpv rsPoolValue) getResultSet(stmt *DmStatement) *innerRows { 171 destDatas := rpv.execInfo.rsDatas 172 var totalRows int 173 if rpv.execInfo.rsDatas != nil { 174 totalRows = len(rpv.execInfo.rsDatas) 175 } 176 177 if stmt.maxRows > 0 && stmt.maxRows < int64(totalRows) { 178 destDatas = make([][][]byte, stmt.maxRows) 179 copy(destDatas[:len(destDatas)], rpv.execInfo.rsDatas[:len(destDatas)]) 180 } 181 182 rs := newLocalInnerRows(stmt, stmt.columns, destDatas) 183 rs.id = 1 184 return rs 185 } 186 187 func (rpv rsPoolValue) getDataLen() int { 188 return rpv.execInfo.rsSizeof 189 } 190 191 type rsPool struct { 192 rsMap map[rsPoolKey]rsPoolValue 193 rsList *list.List 194 totalDataLen int 195 } 196 197 func newRsPool() *rsPool { 198 rp := new(rsPool) 199 rp.rsMap = make(map[rsPoolKey]rsPoolValue, 100) 200 rp.rsList = list.New() 201 return rp 202 } 203 204 func (rp *rsPool) removeInList(key rsPoolKey) { 205 for e := rp.rsList.Front(); e != nil && e.Value.(rsPoolKey).equals(key); e = e.Next() { 206 rp.rsList.Remove(e) 207 } 208 } 209 210 func (rp *rsPool) put(stmt *DmStatement, sql string, execInfo *execRetInfo) { 211 var dataLen int 212 if execInfo != nil { 213 dataLen = execInfo.rsSizeof 214 } 215 216 cacheSize := stmt.dmConn.dmConnector.rsCacheSize * 1024 * 1024 217 218 for rp.totalDataLen+dataLen > cacheSize { 219 if rp.totalDataLen == 0 { 220 return 221 } 222 223 lk := rp.rsList.Back().Value.(rsPoolKey) 224 rp.totalDataLen -= rp.rsMap[lk].getDataLen() 225 rp.rsList.Remove(rp.rsList.Back()) 226 delete(rp.rsMap, rp.rsList.Back().Value.(rsPoolKey)) 227 } 228 229 key := newRsPoolKey(stmt, sql) 230 value := newRsPoolValue(execInfo) 231 232 if _, ok := rp.rsMap[key]; !ok { 233 rp.rsList.PushFront(key) 234 } else { 235 rp.removeInList(key) 236 rp.rsList.PushFront(key) 237 } 238 239 rp.rsMap[key] = value 240 rp.totalDataLen += dataLen 241 } 242 243 func (rp *rsPool) get(stmt *DmStatement, sql string) (*rsPoolValue, error) { 244 key := newRsPoolKey(stmt, sql) 245 246 v, ok := rp.rsMap[key] 247 if ok { 248 b, err := v.refreshed(stmt.dmConn) 249 if err != nil { 250 return nil, err 251 } 252 253 if b { 254 rp.removeInList(key) 255 delete(rp.rsMap, key) 256 return nil, nil 257 } 258 259 rp.removeInList(key) 260 rp.rsList.PushFront(key) 261 return &v, nil 262 } else { 263 return nil, nil 264 } 265 } 266 267 func (s *DmStatement) Close() error { 268 if s.closed { 269 return nil 270 } 271 if len(s.filterChain.filters) == 0 { 272 return s.close() 273 } 274 return s.filterChain.reset().DmStatementClose(s) 275 } 276 277 func (s *DmStatement) NumInput() int { 278 if err := s.checkClosed(); err != nil { 279 return 0 280 } 281 if len(s.filterChain.filters) == 0 { 282 return s.numInput() 283 } 284 return s.filterChain.reset().DmStatementNumInput(s) 285 } 286 287 func (s *DmStatement) Exec(args []driver.Value) (driver.Result, error) { 288 if err := s.checkClosed(); err != nil { 289 return nil, err 290 } 291 if len(s.filterChain.filters) == 0 { 292 return s.exec(args) 293 } 294 return s.filterChain.reset().DmStatementExec(s, args) 295 } 296 297 func (s *DmStatement) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { 298 if err := s.checkClosed(); err != nil { 299 return nil, err 300 } 301 if len(s.filterChain.filters) == 0 { 302 return s.execContext(ctx, args) 303 } 304 return s.filterChain.reset().DmStatementExecContext(s, ctx, args) 305 } 306 307 func (s *DmStatement) Query(args []driver.Value) (driver.Rows, error) { 308 if err := s.checkClosed(); err != nil { 309 return nil, err 310 } 311 if len(s.filterChain.filters) == 0 { 312 return s.query(args) 313 } 314 return s.filterChain.reset().DmStatementQuery(s, args) 315 } 316 317 func (s *DmStatement) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { 318 if err := s.checkClosed(); err != nil { 319 return nil, err 320 } 321 if len(s.filterChain.filters) == 0 { 322 return s.queryContext(ctx, args) 323 } 324 return s.filterChain.reset().DmStatementQueryContext(s, ctx, args) 325 } 326 327 func (s *DmStatement) CheckNamedValue(nv *driver.NamedValue) error { 328 if len(s.filterChain.filters) == 0 { 329 return s.checkNamedValue(nv) 330 } 331 return s.filterChain.reset().DmStatementCheckNamedValue(s, nv) 332 } 333 334 func (st *DmStatement) prepare() error { 335 var err error 336 if st.dmConn.dmConnector.escapeProcess { 337 st.nativeSql, err = st.dmConn.escape(st.nativeSql, st.dmConn.dmConnector.keyWords) 338 if err != nil { 339 return err 340 } 341 } 342 343 st.execInfo, err = st.dmConn.Access.Dm_build_765(st, Dm_build_1043) 344 if err != nil { 345 return err 346 } 347 st.curRowBindIndicator = make([]byte, st.paramCount) 348 return nil 349 } 350 351 func (stmt *DmStatement) close() error { 352 if stmt.closed { 353 return nil 354 } 355 stmt.inUse = true 356 if stmt.dmConn.stmtPool != nil && len(stmt.dmConn.stmtPool) < stmt.dmConn.dmConnector.stmtPoolMaxSize { 357 stmt.pool() 358 return nil 359 } else { 360 return stmt.free() 361 } 362 } 363 364 func (stmt *DmStatement) numInput() int { 365 return int(stmt.paramCount) 366 } 367 368 func (stmt *DmStatement) checkNamedValue(nv *driver.NamedValue) error { 369 var err error 370 var cvt = converter{stmt.dmConn, false} 371 nv.Value, err = cvt.ConvertValue(nv.Value) 372 stmt.isBatch = cvt.isBatch 373 return err 374 } 375 376 func (stmt *DmStatement) exec(args []driver.Value) (*DmResult, error) { 377 var err error 378 379 stmt.inUse = true 380 if stmt.isBatch && len(args) > 0 { 381 var tmpArg []driver.Value 382 var arg driver.Value 383 for i := len(args) - 1; i >= 0; i-- { 384 if args[i] != nil { 385 arg = args[i] 386 break 387 } 388 } 389 for _, row := range arg.([][]interface{}) { 390 tmpArg = append(tmpArg, row) 391 } 392 err = stmt.executeBatch(tmpArg) 393 } else { 394 err = stmt.executeInner(args, Dm_build_1045) 395 } 396 if err != nil { 397 return nil, err 398 } 399 return newDmResult(stmt, stmt.execInfo), nil 400 } 401 402 func (stmt *DmStatement) execContext(ctx context.Context, args []driver.NamedValue) (*DmResult, error) { 403 stmt.inUse = true 404 dargs, err := namedValueToValue(stmt, args) 405 if err != nil { 406 return nil, err 407 } 408 409 if err := stmt.dmConn.watchCancel(ctx); err != nil { 410 return nil, err 411 } 412 defer stmt.dmConn.finish() 413 414 return stmt.exec(dargs) 415 } 416 417 func (stmt *DmStatement) query(args []driver.Value) (*DmRows, error) { 418 var err error 419 stmt.inUse = true 420 err = stmt.executeInner(args, Dm_build_1044) 421 if err != nil { 422 return nil, err 423 } 424 425 return newDmRows(newInnerRows(0, stmt, stmt.execInfo)), nil 426 } 427 428 func (stmt *DmStatement) queryContext(ctx context.Context, args []driver.NamedValue) (*DmRows, error) { 429 stmt.inUse = true 430 dargs, err := namedValueToValue(stmt, args) 431 if err != nil { 432 return nil, err 433 } 434 435 if err := stmt.dmConn.watchCancel(ctx); err != nil { 436 return nil, err 437 } 438 439 rows, err := stmt.query(dargs) 440 if err != nil { 441 stmt.dmConn.finish() 442 return nil, err 443 } 444 rows.finish = stmt.dmConn.finish 445 return rows, err 446 } 447 448 func NewDmStmt(conn *DmConnection, sql string) (*DmStatement, error) { 449 var s *DmStatement 450 451 if s == nil { 452 s = new(DmStatement) 453 s.resetFilterable(&conn.filterable) 454 s.objId = -1 455 s.idGenerator = dmStmtIDGenerator 456 s.dmConn = conn 457 s.maxRows = int64(conn.dmConnector.maxRows) 458 s.nativeSql = sql 459 s.rsMap = make(map[int16]*innerRows) 460 s.inUse = true 461 s.isBatch = conn.isBatch 462 463 if conn.stmtPool != nil && len(conn.stmtPool) > 0 { 464 len := len(conn.stmtPool) 465 spi := conn.stmtPool[0] 466 copy(conn.stmtPool, conn.stmtPool[1:]) 467 conn.stmtPool = conn.stmtPool[:len-1] 468 s.id = spi.id 469 s.cursorName = spi.cursorName 470 s.readBaseColName = spi.readBaseColName 471 } else { 472 err := conn.Access.Dm_build_747(s) 473 if err != nil { 474 return nil, err 475 } 476 } 477 478 } 479 480 return s, nil 481 482 } 483 484 func (stmt *DmStatement) checkClosed() error { 485 if stmt.dmConn.closed.IsSet() { 486 return driver.ErrBadConn 487 } else if stmt.closed { 488 return ECGO_STATEMENT_HANDLE_CLOSED.throw() 489 } 490 491 return nil 492 } 493 494 func (stmt *DmStatement) pool() { 495 for _, rs := range stmt.rsMap { 496 rs.Close() 497 } 498 499 stmt.dmConn.stmtPool = append(stmt.dmConn.stmtPool, stmtPoolInfo{stmt.id, stmt.cursorName, stmt.readBaseColName}) 500 delete(stmt.dmConn.stmtMap, stmt.id) 501 stmt.inUse = false 502 stmt.closed = true 503 } 504 505 func (stmt *DmStatement) free() error { 506 for _, rs := range stmt.rsMap { 507 rs.Close() 508 } 509 510 err := stmt.dmConn.Access.Dm_build_752(int32(stmt.id)) 511 if err != nil { 512 return err 513 } 514 delete(stmt.dmConn.stmtMap, stmt.id) 515 stmt.inUse = false 516 stmt.closed = true 517 return nil 518 } 519 520 func encodeArgs(stmt *DmStatement, args []driver.Value) ([]interface{}, error) { 521 bytes := make([]interface{}, len(args), len(args)) 522 523 var err error 524 525 for i, arg := range args { 526 nextSwitch: 527 if stmt.params[i].colType == CURSOR { 528 if stmt.params[i].cursorStmt == nil { 529 stmt.params[i].cursorStmt = &DmStatement{dmConn: stmt.dmConn} 530 stmt.params[i].cursorStmt.resetFilterable(&stmt.dmConn.filterable) 531 err = stmt.params[i].cursorStmt.dmConn.Access.Dm_build_747(stmt.params[i].cursorStmt) 532 } 533 stmt.curRowBindIndicator[i] |= BIND_OUT 534 continue 535 } 536 if arg == nil { 537 if resetColType(stmt, i, NULL) { 538 bytes[i] = ParamDataEnum_Null 539 } 540 continue 541 } 542 543 switch v := arg.(type) { 544 case bool: 545 if resetColType(stmt, i, TINYINT) { 546 bytes[i], err = G2DB.fromBool(v, stmt.params[i], stmt.dmConn) 547 } 548 case int8: 549 if resetColType(stmt, i, TINYINT) { 550 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 551 } 552 case int16: 553 if resetColType(stmt, i, SMALLINT) { 554 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 555 } 556 case int32: 557 if resetColType(stmt, i, INT) { 558 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 559 } 560 case int64: 561 if resetColType(stmt, i, BIGINT) { 562 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 563 } 564 case int: 565 if resetColType(stmt, i, BIGINT) { 566 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 567 } 568 case uint8: 569 if resetColType(stmt, i, SMALLINT) { 570 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 571 } 572 case uint16: 573 if resetColType(stmt, i, INT) { 574 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 575 } 576 case uint32: 577 if resetColType(stmt, i, BIGINT) { 578 bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn) 579 } 580 581 case float32: 582 if resetColType(stmt, i, REAL) { 583 bytes[i], err = G2DB.fromFloat32(v, stmt.params[i], stmt.dmConn) 584 } 585 case float64: 586 if resetColType(stmt, i, DOUBLE) { 587 bytes[i], err = G2DB.fromFloat64(float64(v), stmt.params[i], stmt.dmConn) 588 } 589 case []byte: 590 if v == nil { 591 if resetColType(stmt, i, NULL) { 592 bytes[i] = ParamDataEnum_Null 593 } 594 } else if resetColType(stmt, i, VARBINARY) { 595 bytes[i], err = G2DB.fromBytes(v, stmt.params[i], stmt.dmConn) 596 } 597 case string: 598 599 if v == "" && emptyStringToNil(stmt.params[i].colType) { 600 arg = nil 601 goto nextSwitch 602 } 603 if resetColType(stmt, i, VARCHAR) { 604 bytes[i], err = G2DB.fromString(v, stmt.params[i], stmt.dmConn) 605 } 606 case time.Time: 607 if resetColType(stmt, i, DATETIME_TZ) { 608 bytes[i], err = G2DB.fromTime(v, stmt.params[i], stmt.dmConn) 609 } 610 case DmTimestamp: 611 if resetColType(stmt, i, DATETIME_TZ) { 612 bytes[i], err = G2DB.fromTime(v.ToTime(), stmt.params[i], stmt.dmConn) 613 } 614 case DmIntervalDT: 615 if resetColType(stmt, i, INTERVAL_DT) { 616 bytes[i], err = G2DB.fromDmIntervalDT(v, stmt.params[i], stmt.dmConn) 617 } 618 case DmIntervalYM: 619 if resetColType(stmt, i, INTERVAL_YM) { 620 bytes[i], err = G2DB.fromDmdbIntervalYM(v, stmt.params[i], stmt.dmConn) 621 } 622 case DmDecimal: 623 if resetColType(stmt, i, DECIMAL) { 624 bytes[i], err = G2DB.fromDecimal(v, stmt.params[i], stmt.dmConn) 625 } 626 627 case DmBlob: 628 if resetColType(stmt, i, BLOB) { 629 bytes[i], err = G2DB.fromBlob(DmBlob(v), stmt.params[i], stmt.dmConn) 630 if err != nil { 631 return nil, err 632 } 633 } 634 case DmClob: 635 if resetColType(stmt, i, CLOB) { 636 bytes[i], err = G2DB.fromClob(DmClob(v), stmt.params[i], stmt.dmConn) 637 if err != nil { 638 return nil, err 639 } 640 } 641 case DmArray: 642 if resetColType(stmt, i, ARRAY) { 643 da := &v 644 da, err = da.create(stmt.dmConn) 645 if err != nil { 646 return nil, err 647 } 648 649 bytes[i], err = G2DB.fromArray(da, stmt.params[i], stmt.dmConn) 650 } 651 case DmStruct: 652 if resetColType(stmt, i, RECORD) { 653 ds := &v 654 ds, err = ds.create(stmt.dmConn) 655 if err != nil { 656 return nil, err 657 } 658 659 bytes[i], err = G2DB.fromStruct(ds, stmt.params[i], stmt.dmConn) 660 } 661 case sql.Out: 662 var cvt = converter{stmt.dmConn, false} 663 if arg, err = cvt.ConvertValue(v.Dest); err != nil { 664 return nil, err 665 } 666 goto nextSwitch 667 668 case *DmTimestamp: 669 if resetColType(stmt, i, DATETIME_TZ) { 670 bytes[i], err = G2DB.fromTime(v.ToTime(), stmt.params[i], stmt.dmConn) 671 } 672 case *DmIntervalDT: 673 if resetColType(stmt, i, INTERVAL_DT) { 674 bytes[i], err = G2DB.fromDmIntervalDT(*v, stmt.params[i], stmt.dmConn) 675 } 676 case *DmIntervalYM: 677 if resetColType(stmt, i, INTERVAL_YM) { 678 bytes[i], err = G2DB.fromDmdbIntervalYM(*v, stmt.params[i], stmt.dmConn) 679 } 680 case *DmDecimal: 681 if resetColType(stmt, i, DECIMAL) { 682 bytes[i], err = G2DB.fromDecimal(*v, stmt.params[i], stmt.dmConn) 683 } 684 case *DmBlob: 685 if resetColType(stmt, i, BLOB) { 686 bytes[i], err = G2DB.fromBlob(DmBlob(*v), stmt.params[i], stmt.dmConn) 687 } 688 case *DmClob: 689 if resetColType(stmt, i, CLOB) { 690 bytes[i], err = G2DB.fromClob(DmClob(*v), stmt.params[i], stmt.dmConn) 691 } 692 case *DmArray: 693 if resetColType(stmt, i, ARRAY) { 694 v, err = v.create(stmt.dmConn) 695 if err != nil { 696 return nil, err 697 } 698 699 bytes[i], err = G2DB.fromArray(v, stmt.params[i], stmt.dmConn) 700 } 701 case *DmStruct: 702 if resetColType(stmt, i, RECORD) { 703 v, err = v.create(stmt.dmConn) 704 if err != nil { 705 return nil, err 706 } 707 708 bytes[i], err = G2DB.fromStruct(v, stmt.params[i], stmt.dmConn) 709 } 710 case *driver.Rows: 711 if stmt.params[i].colType == CURSOR && !resetColType(stmt, i, CURSOR) && stmt.params[i].cursorStmt == nil { 712 stmt.params[i].cursorStmt = &DmStatement{dmConn: stmt.dmConn} 713 stmt.params[i].cursorStmt.resetFilterable(&stmt.dmConn.filterable) 714 err = stmt.params[i].cursorStmt.dmConn.Access.Dm_build_747(stmt.params[i].cursorStmt) 715 } 716 case io.Reader: 717 bytes[i], err = G2DB.fromReader(io.Reader(v), stmt.params[i], stmt.dmConn) 718 if err != nil { 719 return nil, err 720 } 721 default: 722 err = ECGO_UNSUPPORTED_INPARAM_TYPE.throw() 723 } 724 725 if err != nil { 726 return nil, err 727 } 728 729 } 730 731 return bytes, nil 732 } 733 734 type converter struct { 735 conn *DmConnection 736 isBatch bool 737 } 738 type decimalDecompose interface { 739 Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) 740 } 741 742 func (c *converter) ConvertValue(v interface{}) (driver.Value, error) { 743 if driver.IsValue(v) { 744 return v, nil 745 } 746 747 switch vr := v.(type) { 748 case driver.Valuer: 749 sv, err := callValuerValue(vr) 750 if err != nil { 751 return nil, err 752 } 753 754 return sv, nil 755 756 case decimalDecompose, DmDecimal, *DmDecimal, DmTimestamp, *DmTimestamp, DmIntervalDT, *DmIntervalDT, 757 DmIntervalYM, *DmIntervalYM, driver.Rows, *driver.Rows, DmArray, *DmArray, DmStruct, *DmStruct, sql.Out: 758 return vr, nil 759 case big.Int: 760 return NewDecimalFromBigInt(&vr) 761 case big.Float: 762 return NewDecimalFromBigFloat(&vr) 763 case DmClob: 764 765 if vr.connection == nil { 766 vr.connection = c.conn 767 } 768 return vr, nil 769 case *DmClob: 770 771 if vr.connection == nil { 772 vr.connection = c.conn 773 } 774 return vr, nil 775 case DmBlob: 776 777 if vr.connection == nil { 778 vr.connection = c.conn 779 } 780 return vr, nil 781 case *DmBlob: 782 783 if vr.connection == nil { 784 vr.connection = c.conn 785 } 786 return vr, nil 787 case io.Reader: 788 return vr, nil 789 } 790 791 rv := reflect.ValueOf(v) 792 switch rv.Kind() { 793 case reflect.Ptr: 794 if rv.IsNil() { 795 return nil, nil 796 } else { 797 return c.ConvertValue(rv.Elem().Interface()) 798 } 799 case reflect.Int: 800 return rv.Int(), nil 801 case reflect.Int8: 802 return int8(rv.Int()), nil 803 case reflect.Int16: 804 return int16(rv.Int()), nil 805 case reflect.Int32: 806 return int32(rv.Int()), nil 807 case reflect.Int64: 808 return int64(rv.Int()), nil 809 case reflect.Uint8: 810 return uint8(rv.Uint()), nil 811 case reflect.Uint16: 812 return uint16(rv.Uint()), nil 813 case reflect.Uint32: 814 return uint32(rv.Uint()), nil 815 case reflect.Uint64, reflect.Uint: 816 u64 := rv.Uint() 817 if u64 >= 1<<63 { 818 bigInt := &big.Int{} 819 bigInt.SetString(strconv.FormatUint(u64, 10), 10) 820 return NewDecimalFromBigInt(bigInt) 821 } 822 return int64(u64), nil 823 case reflect.Float32: 824 return float32(rv.Float()), nil 825 case reflect.Float64: 826 return float64(rv.Float()), nil 827 case reflect.Bool: 828 return rv.Bool(), nil 829 case reflect.Slice: 830 ek := rv.Type().Elem().Kind() 831 if ek == reflect.Uint8 { 832 return rv.Bytes(), nil 833 } else if ek == reflect.Slice { 834 c.isBatch = true 835 return v, nil 836 } 837 return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek) 838 case reflect.String: 839 return rv.String(), nil 840 } 841 return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) 842 } 843 844 var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() 845 846 func callValuerValue(vr driver.Valuer) (v driver.Value, err error) { 847 if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr && 848 rv.IsNil() && 849 rv.Type().Elem().Implements(valuerReflectType) { 850 return nil, nil 851 } 852 return vr.Value() 853 } 854 855 func namedValueToValue(stmt *DmStatement, named []driver.NamedValue) ([]driver.Value, error) { 856 857 dargs := make([]driver.Value, stmt.paramCount) 858 for i, _ := range dargs { 859 found := false 860 for _, nv := range named { 861 if nv.Name != "" && strings.ToUpper(nv.Name) == strings.ToUpper(stmt.params[i].name) { 862 dargs[i] = nv.Value 863 found = true 864 break 865 } 866 } 867 868 if !found && i < len(named) { 869 dargs[i] = named[i].Value 870 } 871 872 } 873 return dargs, nil 874 } 875 876 func (stmt *DmStatement) executeInner(args []driver.Value, executeType int16) (err error) { 877 878 var bytes []interface{} 879 880 if stmt.paramCount > 0 { 881 bytes, err = encodeArgs(stmt, args) 882 if err != nil { 883 return err 884 } 885 } 886 stmt.execInfo, err = stmt.dmConn.Access.Dm_build_797(stmt, bytes, false) 887 if err != nil { 888 return err 889 } 890 if stmt.execInfo.outParamDatas != nil { 891 for i, outParamData := range stmt.execInfo.outParamDatas { 892 if stmt.curRowBindIndicator[i]&BIND_OUT == BIND_OUT { 893 if arg, ok := args[i].(*driver.Rows); ok && stmt.params[i].colType == CURSOR && outParamData == nil { 894 var tmpExecInfo *execRetInfo 895 if tmpExecInfo, err = stmt.dmConn.Access.Dm_build_807(stmt.params[i].cursorStmt, 1); err != nil { 896 return err 897 } 898 if tmpExecInfo.hasResultSet { 899 *arg = newDmRows(newInnerRows(0, stmt.params[i].cursorStmt, tmpExecInfo)) 900 } else { 901 *arg = nil 902 } 903 continue 904 } 905 if args[i] == nil { 906 if outParamData == nil { 907 continue 908 } 909 910 switch stmt.params[i].colType { 911 case BOOLEAN: 912 args[i], err = DB2G.toBool(outParamData, &stmt.params[i].column, stmt.dmConn) 913 case BIT: 914 if strings.ToLower(stmt.params[i].typeName) == "boolean" { 915 args[i], err = DB2G.toBool(outParamData, &stmt.params[i].column, stmt.dmConn) 916 } 917 918 args[i], err = DB2G.toInt8(outParamData, &stmt.params[i].column, stmt.dmConn) 919 case TINYINT: 920 args[i], err = DB2G.toInt8(outParamData, &stmt.params[i].column, stmt.dmConn) 921 case SMALLINT: 922 args[i], err = DB2G.toInt16(outParamData, &stmt.params[i].column, stmt.dmConn) 923 case INT: 924 args[i], err = DB2G.toInt32(outParamData, &stmt.params[i].column, stmt.dmConn) 925 case BIGINT: 926 args[i], err = DB2G.toInt64(outParamData, &stmt.params[i].column, stmt.dmConn) 927 case REAL: 928 args[i], err = DB2G.toFloat32(outParamData, &stmt.params[i].column, stmt.dmConn) 929 case DOUBLE: 930 args[i], err = DB2G.toFloat64(outParamData, &stmt.params[i].column, stmt.dmConn) 931 case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ: 932 args[i], err = DB2G.toTime(outParamData, &stmt.params[i].column, stmt.dmConn) 933 case INTERVAL_DT: 934 args[i] = newDmIntervalDTByBytes(outParamData) 935 case INTERVAL_YM: 936 args[i] = newDmIntervalYMByBytes(outParamData) 937 case DECIMAL: 938 args[i], err = DB2G.toDmDecimal(outParamData, &stmt.params[i].column, stmt.dmConn) 939 case BINARY, VARBINARY: 940 args[i] = util.StringUtil.BytesToHexString(outParamData, false) 941 case BLOB: 942 args[i] = DB2G.toDmBlob(outParamData, &stmt.params[i].column, stmt.dmConn) 943 case CHAR, VARCHAR2, VARCHAR: 944 args[i] = DB2G.toString(outParamData, &stmt.params[i].column, stmt.dmConn) 945 case CLOB: 946 args[i] = DB2G.toDmClob(outParamData, stmt.dmConn, &stmt.params[i].column) 947 default: 948 err = ECGO_UNSUPPORTED_OUTPARAM_TYPE.throw() 949 } 950 } else { 951 nextSwitch: 952 switch v := args[i].(type) { 953 case sql.Out: 954 args[i] = v.Dest 955 goto nextSwitch 956 case *string: 957 if outParamData == nil { 958 *v = "" 959 } else { 960 *v = DB2G.toString(outParamData, &stmt.params[i].column, stmt.dmConn) 961 } 962 case *sql.NullString: 963 if outParamData == nil { 964 v.String = "" 965 v.Valid = false 966 } else { 967 v.String = DB2G.toString(outParamData, &stmt.params[i].column, stmt.dmConn) 968 v.Valid = true 969 } 970 case *[]byte: 971 if outParamData == nil { 972 *v = nil 973 } else { 974 var val []byte 975 if val, err = DB2G.toBytes(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 976 return err 977 } 978 *v = val 979 } 980 case *bool: 981 if outParamData == nil { 982 *v = false 983 } else { 984 var val bool 985 if val, err = DB2G.toBool(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 986 return err 987 } 988 *v = val 989 } 990 case *sql.NullBool: 991 if outParamData == nil { 992 v.Bool = false 993 v.Valid = false 994 } else { 995 var val bool 996 if val, err = DB2G.toBool(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 997 return err 998 } 999 v.Bool = val 1000 v.Valid = true 1001 } 1002 case *int8: 1003 if outParamData == nil { 1004 *v = 0 1005 } else { 1006 var val int8 1007 if val, err = DB2G.toInt8(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1008 return err 1009 } 1010 *v = val 1011 } 1012 case *int16: 1013 if outParamData == nil { 1014 *v = 0 1015 } else { 1016 var val int16 1017 if val, err = DB2G.toInt16(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1018 return err 1019 } 1020 *v = val 1021 } 1022 case *int32: 1023 if outParamData == nil { 1024 *v = 0 1025 } else { 1026 var val int32 1027 if val, err = DB2G.toInt32(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1028 return err 1029 } 1030 *v = val 1031 } 1032 case *sql.NullInt32: 1033 if outParamData == nil { 1034 v.Int32 = 0 1035 v.Valid = false 1036 } else { 1037 var val int32 1038 if val, err = DB2G.toInt32(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1039 return err 1040 } 1041 v.Int32 = val 1042 v.Valid = true 1043 } 1044 case *int64: 1045 if outParamData == nil { 1046 *v = 0 1047 } else { 1048 var val int64 1049 if val, err = DB2G.toInt64(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1050 return err 1051 } 1052 *v = val 1053 } 1054 case *sql.NullInt64: 1055 if outParamData == nil { 1056 v.Int64 = 0 1057 v.Valid = false 1058 } else { 1059 var val int64 1060 if val, err = DB2G.toInt64(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1061 return err 1062 } 1063 v.Int64 = val 1064 v.Valid = true 1065 } 1066 case *uint8: 1067 if outParamData == nil { 1068 *v = 0 1069 } else { 1070 var val uint8 1071 if val, err = DB2G.toByte(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1072 return err 1073 } 1074 *v = val 1075 } 1076 case *uint16: 1077 if outParamData == nil { 1078 *v = 0 1079 } else { 1080 var val uint16 1081 if val, err = DB2G.toUInt16(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1082 return err 1083 } 1084 *v = val 1085 } 1086 case *uint32: 1087 if outParamData == nil { 1088 *v = 0 1089 } else { 1090 var val uint32 1091 if val, err = DB2G.toUInt32(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1092 return err 1093 } 1094 *v = val 1095 } 1096 case *uint64: 1097 if outParamData == nil { 1098 *v = 0 1099 } else { 1100 var val uint64 1101 if val, err = DB2G.toUInt64(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1102 return err 1103 } 1104 *v = val 1105 } 1106 case *int: 1107 if outParamData == nil { 1108 *v = 0 1109 } else { 1110 var val int 1111 if val, err = DB2G.toInt(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1112 return err 1113 } 1114 *v = val 1115 } 1116 case *uint: 1117 if outParamData == nil { 1118 *v = 0 1119 } else { 1120 var val uint 1121 if val, err = DB2G.toUInt(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1122 return err 1123 } 1124 *v = val 1125 } 1126 case *float32: 1127 if outParamData == nil { 1128 *v = 0.0 1129 } else { 1130 var val float32 1131 if val, err = DB2G.toFloat32(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1132 return err 1133 } 1134 *v = val 1135 } 1136 case *float64: 1137 if outParamData == nil { 1138 *v = 0.0 1139 } else { 1140 var val float64 1141 if val, err = DB2G.toFloat64(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1142 return err 1143 } 1144 *v = val 1145 } 1146 case *sql.NullFloat64: 1147 if outParamData == nil { 1148 v.Float64 = 0.0 1149 v.Valid = false 1150 } else { 1151 var val float64 1152 if val, err = DB2G.toFloat64(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1153 return err 1154 } 1155 v.Float64 = val 1156 v.Valid = true 1157 } 1158 case *time.Time: 1159 if outParamData == nil { 1160 *v = time.Time{} 1161 } else { 1162 var val time.Time 1163 if val, err = DB2G.toTime(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1164 return err 1165 } 1166 *v = val 1167 } 1168 case *sql.NullTime: 1169 if outParamData == nil { 1170 v.Time = time.Time{} 1171 v.Valid = false 1172 } else { 1173 var val time.Time 1174 if val, err = DB2G.toTime(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1175 return err 1176 } 1177 v.Time = val 1178 v.Valid = true 1179 } 1180 case *DmTimestamp: 1181 if outParamData == nil { 1182 *v = DmTimestamp{} 1183 } else { 1184 *v = *newDmTimestampFromBytes(outParamData, stmt.params[i].column, stmt.dmConn) 1185 } 1186 case *DmIntervalDT: 1187 if outParamData == nil { 1188 *v = DmIntervalDT{} 1189 } else { 1190 *v = *newDmIntervalDTByBytes(outParamData) 1191 } 1192 case *DmIntervalYM: 1193 if outParamData == nil { 1194 *v = DmIntervalYM{} 1195 } else { 1196 *v = *newDmIntervalYMByBytes(outParamData) 1197 } 1198 case *DmDecimal: 1199 if outParamData == nil { 1200 *v = DmDecimal{} 1201 } else { 1202 var val *DmDecimal 1203 if val, err = DB2G.toDmDecimal(outParamData, &stmt.params[i].column, stmt.dmConn); err != nil { 1204 return err 1205 } 1206 *v = *val 1207 } 1208 case *DmBlob: 1209 if outParamData == nil { 1210 *v = DmBlob{} 1211 } else { 1212 *v = *DB2G.toDmBlob(outParamData, &stmt.params[i].column, stmt.dmConn) 1213 } 1214 case *DmClob: 1215 if outParamData == nil { 1216 *v = DmClob{} 1217 } else { 1218 *v = *DB2G.toDmClob(outParamData, stmt.dmConn, &stmt.params[i].column) 1219 } 1220 case *driver.Rows: 1221 if stmt.params[i].colType == CURSOR { 1222 var tmpExecInfo *execRetInfo 1223 tmpExecInfo, err = stmt.dmConn.Access.Dm_build_807(stmt.params[i].cursorStmt, 1) 1224 if err != nil { 1225 return err 1226 } 1227 1228 if tmpExecInfo.hasResultSet { 1229 *v = newDmRows(newInnerRows(0, stmt.params[i].cursorStmt, tmpExecInfo)) 1230 } else { 1231 *v = nil 1232 } 1233 } 1234 case *DmArray: 1235 if outParamData == nil { 1236 *v = DmArray{} 1237 } else { 1238 var val *DmArray 1239 if val, err = TypeDataSV.bytesToArray(outParamData, nil, stmt.params[i].typeDescriptor); err != nil { 1240 return err 1241 } 1242 *v = *val 1243 } 1244 case *DmStruct: 1245 if outParamData == nil { 1246 *v = DmStruct{} 1247 } else { 1248 var val *DmStruct 1249 if val, err = TypeDataSV.bytesToRecord(outParamData, nil, stmt.params[i].typeDescriptor); err != nil { 1250 return err 1251 } 1252 *v = *val 1253 } 1254 default: 1255 err = ECGO_UNSUPPORTED_OUTPARAM_TYPE.throw() 1256 } 1257 } 1258 } 1259 } 1260 } 1261 1262 return err 1263 } 1264 1265 func (stmt *DmStatement) executeBatch(args []driver.Value) (err error) { 1266 1267 var bytes [][]interface{} 1268 1269 if stmt.execInfo.retSqlType == Dm_build_1058 || stmt.execInfo.retSqlType == Dm_build_1063 { 1270 return ECGO_INVALID_SQL_TYPE.throw() 1271 } 1272 1273 if stmt.paramCount > 0 && args != nil && len(args) > 0 { 1274 1275 if len(args) == 1 || stmt.dmConn.dmConnector.batchType == 2 || 1276 (stmt.dmConn.dmConnector.batchNotOnCall && stmt.execInfo.retSqlType == Dm_build_1059) { 1277 return stmt.executeBatchByRow(args) 1278 } else { 1279 for _, arg := range args { 1280 var newArg []driver.Value 1281 for _, a := range arg.([]interface{}) { 1282 newArg = append(newArg, a) 1283 } 1284 tmpBytes, err := encodeArgs(stmt, newArg) 1285 if err != nil { 1286 return err 1287 } 1288 bytes = append(bytes, tmpBytes) 1289 } 1290 stmt.execInfo, err = stmt.dmConn.Access.Dm_build_786(stmt, bytes, stmt.preExec) 1291 } 1292 } 1293 return err 1294 } 1295 1296 func (stmt *DmStatement) executeBatchByRow(args []driver.Value) (err error) { 1297 count := len(args) 1298 stmt.execInfo = NewExceInfo() 1299 stmt.execInfo.updateCounts = make([]int64, count) 1300 var sqlErrBuilder strings.Builder 1301 for i := 0; i < count; i++ { 1302 tmpExecInfo, err := stmt.dmConn.Access.Dm_build_797(stmt, args[i].([]interface{}), stmt.preExec || i != 0) 1303 if err == nil { 1304 stmt.execInfo.union(tmpExecInfo, i, 1) 1305 } else { 1306 stmt.execInfo.updateCounts[i] = -1 1307 if stmt.dmConn.dmConnector.continueBatchOnError { 1308 sqlErrBuilder.WriteString("row[" + strconv.Itoa(i) + "]:" + err.Error() + util.LINE_SEPARATOR) 1309 } else { 1310 return ECGO_BATCH_ERROR.addDetailln(err.Error()).throw() 1311 } 1312 } 1313 } 1314 if sqlErrBuilder.Len() > 0 { 1315 return EC_BP_WITH_ERROR.addDetail(sqlErrBuilder.String()).throw() 1316 } 1317 return nil 1318 }