gitee.com/curryzheng/dm@v0.0.1/o.go (about) 1 /* 2 * Copyright (c) 2000-2018, 达梦数据库有限公司. 3 * All rights reserved. 4 */ 5 package dm 6 7 import ( 8 "bytes" 9 "context" 10 "database/sql/driver" 11 "gitee.com/curryzheng/dm/util" 12 "net" 13 "net/url" 14 "os" 15 "path/filepath" 16 "regexp" 17 "runtime" 18 "strconv" 19 "strings" 20 ) 21 22 const ( 23 TimeZoneKey = "timeZone" 24 EnRsCacheKey = "enRsCache" 25 RsCacheSizeKey = "rsCacheSize" 26 RsRefreshFreqKey = "rsRefreshFreq" 27 LoginPrimary = "loginPrimary" 28 LoginModeKey = "loginMode" 29 LoginStatusKey = "loginStatus" 30 LoginDscCtrlKey = "loginDscCtrl" 31 SwitchTimesKey = "switchTimes" 32 SwitchIntervalKey = "switchInterval" 33 EpSelectorKey = "epSelector" 34 PrimaryKey = "primaryKey" 35 KeywordsKey = "keywords" 36 CompressKey = "compress" 37 CompressIdKey = "compressId" 38 LoginEncryptKey = "loginEncrypt" 39 CommunicationEncryptKey = "communicationEncrypt" 40 DirectKey = "direct" 41 Dec2DoubleKey = "dec2double" 42 RwSeparateKey = "rwSeparate" 43 RwPercentKey = "rwPercent" 44 RwAutoDistributeKey = "rwAutoDistribute" 45 CompatibleModeKey = "compatibleMode" 46 CompatibleOraKey = "comOra" 47 CipherPathKey = "cipherPath" 48 DoSwitchKey = "doSwitch" 49 ClusterKey = "cluster" 50 LanguageKey = "language" 51 DbAliveCheckFreqKey = "dbAliveCheckFreq" 52 RwStandbyRecoverTimeKey = "rwStandbyRecoverTime" 53 LogLevelKey = "logLevel" 54 LogDirKey = "logDir" 55 LogBufferPoolSizeKey = "logBufferPoolSize" 56 LogBufferSizeKey = "logBufferSize" 57 LogFlusherQueueSizeKey = "logFlusherQueueSize" 58 LogFlushFreqKey = "logFlushFreq" 59 StatEnableKey = "statEnable" 60 StatDirKey = "statDir" 61 StatFlushFreqKey = "statFlushFreq" 62 StatHighFreqSqlCountKey = "statHighFreqSqlCount" 63 StatSlowSqlCountKey = "statSlowSqlCount" 64 StatSqlMaxCountKey = "statSqlMaxCount" 65 StatSqlRemoveModeKey = "statSqlRemoveMode" 66 AddressRemapKey = "addressRemap" 67 UserRemapKey = "userRemap" 68 ConnectTimeoutKey = "connectTimeout" 69 LoginCertificateKey = "loginCertificate" 70 UrlKey = "url" 71 HostKey = "host" 72 PortKey = "port" 73 UserKey = "user" 74 PasswordKey = "password" 75 RwStandbyKey = "rwStandby" 76 IsCompressKey = "isCompress" 77 RwHAKey = "rwHA" 78 RwIgnoreSqlKey = "rwIgnoreSql" 79 AppNameKey = "appName" 80 OsNameKey = "osName" 81 MppLocalKey = "mppLocal" 82 SocketTimeoutKey = "socketTimeout" 83 SessionTimeoutKey = "sessionTimeout" 84 ContinueBatchOnErrorKey = "continueBatchOnError" 85 BatchAllowMaxErrorsKey = "batchAllowMaxErrors" 86 EscapeProcessKey = "escapeProcess" 87 AutoCommitKey = "autoCommit" 88 MaxRowsKey = "maxRows" 89 RowPrefetchKey = "rowPrefetch" 90 BufPrefetchKey = "bufPrefetch" 91 LobModeKey = "LobMode" 92 StmtPoolSizeKey = "StmtPoolSize" 93 IgnoreCaseKey = "ignoreCase" 94 AlwayseAllowCommitKey = "AlwayseAllowCommit" 95 BatchTypeKey = "batchType" 96 BatchNotOnCallKey = "batchNotOnCall" 97 IsBdtaRSKey = "isBdtaRS" 98 ClobAsStringKey = "clobAsString" 99 SslCertPathKey = "sslCertPath" 100 SslKeyPathKey = "sslKeyPath" 101 SslFilesPathKey = "sslFilesPath" 102 KerberosLoginConfPathKey = "kerberosLoginConfPath" 103 UKeyNameKey = "uKeyName" 104 UKeyPinKey = "uKeyPin" 105 ColumnNameUpperCaseKey = "columnNameUpperCase" 106 ColumnNameCaseKey = "columnNameCase" 107 DatabaseProductNameKey = "databaseProductName" 108 OsAuthTypeKey = "osAuthType" 109 SchemaKey = "schema" 110 111 TIME_ZONE_DEFAULT int16 = 480 112 113 DO_SWITCH_OFF int32 = 0 114 DO_SWITCH_WHEN_CONN_ERROR int32 = 1 115 DO_SWITCH_WHEN_EP_RECOVER int32 = 2 116 117 CLUSTER_TYPE_NORMAL int32 = 0 118 CLUSTER_TYPE_RW int32 = 1 119 CLUSTER_TYPE_DW int32 = 2 120 CLUSTER_TYPE_DSC int32 = 3 121 CLUSTER_TYPE_MPP int32 = 4 122 123 EP_STATUS_OK int32 = 1 124 EP_STATUS_ERROR int32 = 2 125 126 LOGIN_MODE_PRIMARY_FIRST int32 = 0 127 128 LOGIN_MODE_PRIMARY_ONLY int32 = 1 129 130 LOGIN_MODE_STANDBY_ONLY int32 = 2 131 132 LOGIN_MODE_STANDBY_FIRST int32 = 3 133 134 LOGIN_MODE_NORMAL_FIRST int32 = 4 135 136 SERVER_MODE_NORMAL int32 = 0 137 138 SERVER_MODE_PRIMARY int32 = 1 139 140 SERVER_MODE_STANDBY int32 = 2 141 142 SERVER_STATUS_MOUNT int32 = 3 143 144 SERVER_STATUS_OPEN int32 = 4 145 146 SERVER_STATUS_SUSPEND int32 = 5 147 148 COMPATIBLE_MODE_ORACLE int = 1 149 150 COMPATIBLE_MODE_MYSQL int = 2 151 152 LANGUAGE_CN int = 0 153 154 LANGUAGE_EN int = 1 155 156 COLUMN_NAME_NATURAL_CASE = 0 157 158 COLUMN_NAME_UPPER_CASE = 1 159 160 COLUMN_NAME_LOWER_CASE = 2 161 162 compressDef = Dm_build_1039 163 compressIDDef = Dm_build_1040 164 165 charCodeDef = "" 166 167 enRsCacheDef = false 168 169 rsCacheSizeDef = 20 170 171 rsRefreshFreqDef = 10 172 173 loginModeDef = LOGIN_MODE_NORMAL_FIRST 174 175 loginStatusDef = 0 176 177 loginEncryptDef = true 178 179 loginCertificateDef = "" 180 181 dec2DoubleDef = false 182 183 rwHADef = false 184 185 rwStandbyDef = false 186 187 rwSeparateDef = false 188 189 rwPercentDef = 25 190 191 rwAutoDistributeDef = true 192 193 rwStandbyRecoverTimeDef = 1000 194 195 cipherPathDef = "" 196 197 urlDef = "" 198 199 userDef = "SYSDBA" 200 201 passwordDef = "SYSDBA" 202 203 hostDef = "localhost" 204 205 portDef = DEFAULT_PORT 206 207 appNameDef = "" 208 209 mppLocalDef = false 210 211 socketTimeoutDef = 0 212 213 connectTimeoutDef = 5000 214 215 sessionTimeoutDef = 0 216 217 osAuthTypeDef = Dm_build_1022 218 219 continueBatchOnErrorDef = false 220 221 escapeProcessDef = false 222 223 autoCommitDef = true 224 225 maxRowsDef = 0 226 227 rowPrefetchDef = Dm_build_1023 228 229 bufPrefetchDef = 0 230 231 lobModeDef = 1 232 233 stmtPoolMaxSizeDef = 15 234 235 ignoreCaseDef = true 236 237 alwayseAllowCommitDef = true 238 239 isBdtaRSDef = false 240 241 kerberosLoginConfPathDef = "" 242 243 uKeyNameDef = "" 244 245 uKeyPinDef = "" 246 247 databaseProductNameDef = "" 248 249 caseSensitiveDef = true 250 251 compatibleModeDef = 0 252 253 localTimezoneDef = TIME_ZONE_DEFAULT 254 ) 255 256 type DmConnector struct { 257 filterable 258 259 dmDriver *DmDriver 260 261 compress int 262 263 compressID int8 264 265 newClientType bool 266 267 charCode string 268 269 enRsCache bool 270 271 rsCacheSize int 272 273 rsRefreshFreq int 274 275 loginMode int32 276 277 loginStatus int 278 279 loginDscCtrl bool 280 281 switchTimes int32 282 283 switchInterval int 284 285 epSelector int32 286 287 keyWords []string 288 289 loginEncrypt bool 290 291 loginCertificate string 292 293 dec2Double bool 294 295 rwHA bool 296 297 rwStandby bool 298 299 rwSeparate bool 300 301 rwPercent int32 302 303 rwAutoDistribute bool 304 305 rwStandbyRecoverTime int 306 307 rwIgnoreSql bool 308 309 doSwitch int32 310 311 cluster int32 312 313 cipherPath string 314 315 url string 316 317 user string 318 319 password string 320 321 host string 322 323 group *epGroup 324 325 port int32 326 327 appName string 328 329 osName string 330 331 mppLocal bool 332 333 socketTimeout int 334 335 connectTimeout int 336 337 sessionTimeout int 338 339 osAuthType byte 340 341 continueBatchOnError bool 342 343 batchAllowMaxErrors int32 344 345 escapeProcess bool 346 347 autoCommit bool 348 349 maxRows int 350 351 rowPrefetch int 352 353 bufPrefetch int 354 355 lobMode int 356 357 stmtPoolMaxSize int 358 359 ignoreCase bool 360 361 alwayseAllowCommit bool 362 363 batchType int 364 365 batchNotOnCall bool 366 367 isBdtaRS bool 368 369 sslCertPath string 370 371 sslKeyPath string 372 373 sslFilesPath string 374 375 kerberosLoginConfPath string 376 377 uKeyName string 378 379 uKeyPin string 380 381 svcConfPath string 382 383 columnNameCase int 384 385 caseSensitive bool 386 387 compatibleMode int 388 389 localTimezone int16 390 391 schema string 392 393 reConnection *DmConnection 394 395 logLevel int 396 397 logDir string 398 399 logFlushFreq int 400 401 logFlushQueueSize int 402 403 logBufferSize int 404 405 statEnable bool 406 407 statDir string 408 409 statFlushFreq int 410 411 statSlowSqlCount int 412 413 statHighFreqSqlCount int 414 415 statSqlMaxCount int 416 417 statSqlRemoveMode int 418 } 419 420 func (c *DmConnector) init() *DmConnector { 421 c.compress = compressDef 422 c.compressID = compressIDDef 423 c.charCode = charCodeDef 424 c.enRsCache = enRsCacheDef 425 c.rsCacheSize = rsCacheSizeDef 426 c.rsRefreshFreq = rsRefreshFreqDef 427 c.loginMode = loginModeDef 428 c.loginStatus = loginStatusDef 429 c.loginDscCtrl = false 430 c.switchTimes = 1 431 c.switchInterval = 1000 432 c.epSelector = 0 433 c.keyWords = nil 434 c.loginEncrypt = loginEncryptDef 435 c.loginCertificate = loginCertificateDef 436 c.dec2Double = dec2DoubleDef 437 c.rwHA = rwHADef 438 c.rwStandby = rwStandbyDef 439 c.rwSeparate = rwSeparateDef 440 c.rwPercent = rwPercentDef 441 c.rwAutoDistribute = rwAutoDistributeDef 442 c.rwStandbyRecoverTime = rwStandbyRecoverTimeDef 443 c.rwIgnoreSql = false 444 c.doSwitch = DO_SWITCH_OFF 445 c.cluster = CLUSTER_TYPE_NORMAL 446 c.cipherPath = cipherPathDef 447 c.url = urlDef 448 c.user = userDef 449 c.password = passwordDef 450 c.host = hostDef 451 c.port = portDef 452 c.appName = appNameDef 453 c.osName = runtime.GOOS 454 c.mppLocal = mppLocalDef 455 c.socketTimeout = socketTimeoutDef 456 c.connectTimeout = connectTimeoutDef 457 c.sessionTimeout = sessionTimeoutDef 458 c.osAuthType = osAuthTypeDef 459 c.continueBatchOnError = continueBatchOnErrorDef 460 c.batchAllowMaxErrors = 0 461 c.escapeProcess = escapeProcessDef 462 c.autoCommit = autoCommitDef 463 c.maxRows = maxRowsDef 464 c.rowPrefetch = rowPrefetchDef 465 c.bufPrefetch = bufPrefetchDef 466 c.lobMode = lobModeDef 467 c.stmtPoolMaxSize = stmtPoolMaxSizeDef 468 c.ignoreCase = ignoreCaseDef 469 c.alwayseAllowCommit = alwayseAllowCommitDef 470 c.batchType = 1 471 c.batchNotOnCall = false 472 c.isBdtaRS = isBdtaRSDef 473 c.kerberosLoginConfPath = kerberosLoginConfPathDef 474 c.uKeyName = uKeyNameDef 475 c.uKeyPin = uKeyPinDef 476 c.columnNameCase = COLUMN_NAME_NATURAL_CASE 477 c.caseSensitive = caseSensitiveDef 478 c.compatibleMode = compatibleModeDef 479 c.localTimezone = localTimezoneDef 480 c.idGenerator = dmConntorIDGenerator 481 482 c.logDir = LogDirDef 483 c.logFlushFreq = LogFlushFreqDef 484 c.logFlushQueueSize = LogFlushQueueSizeDef 485 c.logBufferSize = LogBufferSizeDef 486 c.statEnable = StatEnableDef 487 c.statDir = StatDirDef 488 c.statFlushFreq = StatFlushFreqDef 489 c.statSlowSqlCount = StatSlowSqlCountDef 490 c.statHighFreqSqlCount = StatHighFreqSqlCountDef 491 c.statSqlMaxCount = StatSqlMaxCountDef 492 c.statSqlRemoveMode = StatSqlRemoveModeDef 493 return c 494 } 495 496 func (c *DmConnector) setAttributes(props *Properties) error { 497 if props == nil || props.Len() == 0 { 498 return nil 499 } 500 501 c.url = props.GetTrimString(UrlKey, c.url) 502 c.host = props.GetTrimString(HostKey, c.host) 503 c.port = int32(props.GetInt(PortKey, int(c.port), 0, 65535)) 504 c.user = props.GetString(UserKey, c.user) 505 c.password = props.GetString(PasswordKey, c.password) 506 c.rwStandby = props.GetBool(RwStandbyKey, c.rwStandby) 507 508 if b := props.GetBool(IsCompressKey, false); b { 509 c.compress = Dm_build_1038 510 } 511 512 c.compress = props.GetInt(CompressKey, c.compress, 0, 2) 513 c.compressID = int8(props.GetInt(CompressIdKey, int(c.compressID), 0, 1)) 514 c.enRsCache = props.GetBool(EnRsCacheKey, c.enRsCache) 515 c.localTimezone = int16(props.GetInt(TimeZoneKey, int(c.localTimezone), -720, 720)) 516 c.rsCacheSize = props.GetInt(RsCacheSizeKey, c.rsCacheSize, 0, int(INT32_MAX)) 517 c.rsRefreshFreq = props.GetInt(RsRefreshFreqKey, c.rsRefreshFreq, 0, int(INT32_MAX)) 518 c.loginMode = int32(props.GetInt(LoginModeKey, int(c.loginMode), 0, 4)) 519 c.loginStatus = props.GetInt(LoginStatusKey, c.loginStatus, 0, int(INT32_MAX)) 520 c.loginDscCtrl = props.GetBool(LoginDscCtrlKey, c.loginDscCtrl) 521 c.switchTimes = int32(props.GetInt(SwitchTimesKey, int(c.switchTimes), 0, int(INT32_MAX))) 522 c.switchInterval = props.GetInt(SwitchIntervalKey, c.switchInterval, 0, int(INT32_MAX)) 523 c.epSelector = int32(props.GetInt(EpSelectorKey, int(c.epSelector), 0, 1)) 524 c.loginEncrypt = props.GetBool(LoginEncryptKey, c.loginEncrypt) 525 c.loginCertificate = props.GetTrimString(LoginCertificateKey, c.loginCertificate) 526 c.dec2Double = props.GetBool(Dec2DoubleKey, c.dec2Double) 527 528 c.rwSeparate = props.GetBool(RwSeparateKey, c.rwSeparate) 529 c.rwAutoDistribute = props.GetBool(RwAutoDistributeKey, c.rwAutoDistribute) 530 c.rwPercent = int32(props.GetInt(RwPercentKey, int(c.rwPercent), 0, 100)) 531 c.rwHA = props.GetBool(RwHAKey, c.rwHA) 532 c.rwStandbyRecoverTime = props.GetInt(RwStandbyRecoverTimeKey, c.rwStandbyRecoverTime, 0, int(INT32_MAX)) 533 c.rwIgnoreSql = props.GetBool(RwIgnoreSqlKey, c.rwIgnoreSql) 534 c.doSwitch = int32(props.GetInt(DoSwitchKey, int(c.doSwitch), 0, 2)) 535 c.parseCluster(props) 536 c.cipherPath = props.GetTrimString(CipherPathKey, c.cipherPath) 537 538 if props.GetBool(CompatibleOraKey, false) { 539 c.compatibleMode = int(COMPATIBLE_MODE_ORACLE) 540 } 541 c.parseCompatibleMode(props) 542 c.keyWords = props.GetStringArray(KeywordsKey, c.keyWords) 543 544 c.appName = props.GetTrimString(AppNameKey, c.appName) 545 c.osName = props.GetTrimString(OsNameKey, c.osName) 546 c.mppLocal = props.GetBool(MppLocalKey, c.mppLocal) 547 c.socketTimeout = props.GetInt(SocketTimeoutKey, c.socketTimeout, 0, int(INT32_MAX)) 548 c.connectTimeout = props.GetInt(ConnectTimeoutKey, c.connectTimeout, 0, int(INT32_MAX)) 549 c.sessionTimeout = props.GetInt(SessionTimeoutKey, c.sessionTimeout, 0, int(INT32_MAX)) 550 551 err := c.parseOsAuthType(props) 552 if err != nil { 553 return err 554 } 555 c.continueBatchOnError = props.GetBool(ContinueBatchOnErrorKey, c.continueBatchOnError) 556 c.batchAllowMaxErrors = int32(props.GetInt(BatchAllowMaxErrorsKey, int(c.batchAllowMaxErrors), 0, int(INT32_MAX))) 557 c.escapeProcess = props.GetBool(EscapeProcessKey, c.escapeProcess) 558 c.autoCommit = props.GetBool(AutoCommitKey, c.autoCommit) 559 c.maxRows = props.GetInt(MaxRowsKey, c.maxRows, 0, int(INT32_MAX)) 560 c.rowPrefetch = props.GetInt(RowPrefetchKey, c.rowPrefetch, 0, int(INT32_MAX)) 561 c.bufPrefetch = props.GetInt(BufPrefetchKey, c.bufPrefetch, int(Dm_build_1024), int(Dm_build_1025)) 562 c.lobMode = props.GetInt(LobModeKey, c.lobMode, 1, 2) 563 c.stmtPoolMaxSize = props.GetInt(StmtPoolSizeKey, c.stmtPoolMaxSize, 0, int(INT32_MAX)) 564 c.ignoreCase = props.GetBool(IgnoreCaseKey, c.ignoreCase) 565 c.alwayseAllowCommit = props.GetBool(AlwayseAllowCommitKey, c.alwayseAllowCommit) 566 c.batchType = props.GetInt(BatchTypeKey, c.batchType, 1, 2) 567 c.batchNotOnCall = props.GetBool(BatchNotOnCallKey, c.batchNotOnCall) 568 c.isBdtaRS = props.GetBool(IsBdtaRSKey, c.isBdtaRS) 569 c.sslFilesPath = props.GetTrimString(SslFilesPathKey, c.sslFilesPath) 570 c.sslCertPath = props.GetTrimString(SslCertPathKey, c.sslCertPath) 571 if c.sslCertPath == "" && c.sslFilesPath != "" { 572 c.sslCertPath = filepath.Join(c.sslFilesPath, "client-cert.pem") 573 } 574 c.sslKeyPath = props.GetTrimString(SslKeyPathKey, c.sslKeyPath) 575 if c.sslKeyPath == "" && c.sslFilesPath != "" { 576 c.sslKeyPath = filepath.Join(c.sslKeyPath, "client-key.pem") 577 } 578 579 c.kerberosLoginConfPath = props.GetTrimString(KerberosLoginConfPathKey, c.kerberosLoginConfPath) 580 581 c.uKeyName = props.GetTrimString(UKeyNameKey, c.uKeyName) 582 c.uKeyPin = props.GetTrimString(UKeyPinKey, c.uKeyPin) 583 584 c.svcConfPath = props.GetString("confPath", "") 585 586 if props.GetBool(ColumnNameUpperCaseKey, false) { 587 c.columnNameCase = COLUMN_NAME_UPPER_CASE 588 } 589 590 v := props.GetTrimString(ColumnNameCaseKey, "") 591 if util.StringUtil.EqualsIgnoreCase(v, "upper") { 592 c.columnNameCase = COLUMN_NAME_UPPER_CASE 593 } else if util.StringUtil.EqualsIgnoreCase(v, "lower") { 594 c.columnNameCase = COLUMN_NAME_LOWER_CASE 595 } 596 597 c.schema = props.GetTrimString(SchemaKey, c.schema) 598 599 c.logLevel = ParseLogLevel(props) 600 LogLevel = c.logLevel 601 c.logDir = util.StringUtil.FormatDir(props.GetTrimString(LogDirKey, LogDirDef)) 602 LogDir = c.logDir 603 c.logBufferSize = props.GetInt(LogBufferSizeKey, LogBufferSizeDef, 1, int(INT32_MAX)) 604 LogBufferSize = c.logBufferSize 605 c.logFlushFreq = props.GetInt(LogFlushFreqKey, LogFlushFreqDef, 1, int(INT32_MAX)) 606 LogFlushFreq = c.logFlushFreq 607 c.logFlushQueueSize = props.GetInt(LogFlusherQueueSizeKey, LogFlushQueueSizeDef, 1, int(INT32_MAX)) 608 LogFlushQueueSize = c.logFlushQueueSize 609 610 c.statEnable = props.GetBool(StatEnableKey, StatEnableDef) 611 StatEnable = c.statEnable 612 c.statDir = util.StringUtil.FormatDir(props.GetTrimString(StatDirKey, StatDirDef)) 613 StatDir = c.statDir 614 c.statFlushFreq = props.GetInt(StatFlushFreqKey, StatFlushFreqDef, 1, int(INT32_MAX)) 615 StatFlushFreq = c.statFlushFreq 616 c.statHighFreqSqlCount = props.GetInt(StatHighFreqSqlCountKey, StatHighFreqSqlCountDef, 0, 1000) 617 StatHighFreqSqlCount = c.statHighFreqSqlCount 618 c.statSlowSqlCount = props.GetInt(StatSlowSqlCountKey, StatSlowSqlCountDef, 0, 1000) 619 StatSlowSqlCount = c.statSlowSqlCount 620 c.statSqlMaxCount = props.GetInt(StatSqlMaxCountKey, StatSqlMaxCountDef, 0, 100000) 621 StatSqlMaxCount = c.statSqlMaxCount 622 c.parseStatSqlRemoveMode(props) 623 return nil 624 } 625 626 func (c *DmConnector) parseOsAuthType(props *Properties) error { 627 value := props.GetString(OsAuthTypeKey, "") 628 if value != "" && !util.StringUtil.IsDigit(value) { 629 if util.StringUtil.EqualsIgnoreCase(value, "ON") { 630 c.osAuthType = Dm_build_1022 631 } else if util.StringUtil.EqualsIgnoreCase(value, "SYSDBA") { 632 c.osAuthType = Dm_build_1018 633 } else if util.StringUtil.EqualsIgnoreCase(value, "SYSAUDITOR") { 634 c.osAuthType = Dm_build_1020 635 } else if util.StringUtil.EqualsIgnoreCase(value, "SYSSSO") { 636 c.osAuthType = Dm_build_1019 637 } else if util.StringUtil.EqualsIgnoreCase(value, "AUTO") { 638 c.osAuthType = Dm_build_1021 639 } else if util.StringUtil.EqualsIgnoreCase(value, "OFF") { 640 c.osAuthType = Dm_build_1017 641 } 642 } else { 643 c.osAuthType = byte(props.GetInt(OsAuthTypeKey, int(c.osAuthType), 0, 4)) 644 } 645 if c.user == "" && c.osAuthType == Dm_build_1017 { 646 c.user = "SYSDBA" 647 } else if c.osAuthType != Dm_build_1017 && c.user != "" { 648 return ECGO_OSAUTH_ERROR.throw() 649 } else if c.osAuthType != Dm_build_1017 { 650 c.user = os.Getenv("user") 651 c.password = "" 652 } 653 return nil 654 } 655 656 func (c *DmConnector) parseCompatibleMode(props *Properties) { 657 value := props.GetString(CompatibleModeKey, "") 658 if value != "" && !util.StringUtil.IsDigit(value) { 659 if util.StringUtil.EqualsIgnoreCase(value, "oracle") { 660 c.compatibleMode = COMPATIBLE_MODE_ORACLE 661 } else if util.StringUtil.EqualsIgnoreCase(value, "mysql") { 662 c.compatibleMode = COMPATIBLE_MODE_MYSQL 663 } 664 } else { 665 c.compatibleMode = props.GetInt(CompatibleModeKey, c.compatibleMode, 0, 2) 666 } 667 } 668 669 func (c *DmConnector) parseStatSqlRemoveMode(props *Properties) { 670 value := props.GetString(StatSqlRemoveModeKey, "") 671 if value != "" && !util.StringUtil.IsDigit(value) { 672 if util.StringUtil.EqualsIgnoreCase("oldest", value) || util.StringUtil.EqualsIgnoreCase("eldest", value) { 673 c.statSqlRemoveMode = STAT_SQL_REMOVE_OLDEST 674 } else if util.StringUtil.EqualsIgnoreCase("latest", value) { 675 c.statSqlRemoveMode = STAT_SQL_REMOVE_LATEST 676 } 677 } else { 678 c.statSqlRemoveMode = props.GetInt(StatSqlRemoveModeKey, StatSqlRemoveModeDef, 1, 2) 679 } 680 } 681 682 func (c *DmConnector) parseCluster(props *Properties) { 683 value := props.GetTrimString(ClusterKey, "") 684 if util.StringUtil.EqualsIgnoreCase(value, "DSC") { 685 c.cluster = CLUSTER_TYPE_DSC 686 } else if util.StringUtil.EqualsIgnoreCase(value, "RW") { 687 c.cluster = CLUSTER_TYPE_RW 688 } else if util.StringUtil.EqualsIgnoreCase(value, "DW") { 689 c.cluster = CLUSTER_TYPE_DW 690 } else if util.StringUtil.EqualsIgnoreCase(value, "MPP") { 691 c.cluster = CLUSTER_TYPE_MPP 692 } else { 693 c.cluster = CLUSTER_TYPE_NORMAL 694 } 695 } 696 697 func (c *DmConnector) parseDSN(dsn string) (*Properties, string, error) { 698 var dsnProps = NewProperties() 699 url, err := url.Parse(dsn) 700 if err != nil { 701 return nil, "", err 702 } 703 if url.Scheme != "dm" { 704 return nil, "", DSN_INVALID_SCHEMA 705 } 706 707 if url.User != nil { 708 c.user = url.User.Username() 709 c.password, _ = url.User.Password() 710 } 711 712 q := url.Query() 713 for k := range q { 714 dsnProps.Set(k, q.Get(k)) 715 } 716 717 return dsnProps, url.Host, nil 718 } 719 720 func (c *DmConnector) BuildDSN() string { 721 var buf bytes.Buffer 722 723 buf.WriteString("dm://") 724 725 if len(c.user) > 0 { 726 buf.WriteString(url.QueryEscape(c.user)) 727 if len(c.password) > 0 { 728 buf.WriteByte(':') 729 buf.WriteString(url.QueryEscape(c.password)) 730 } 731 buf.WriteByte('@') 732 } 733 734 if len(c.host) > 0 { 735 buf.WriteString(c.host) 736 if c.port > 0 { 737 buf.WriteByte(':') 738 buf.WriteString(strconv.Itoa(int(c.port))) 739 } 740 } 741 742 hasParam := false 743 if c.connectTimeout > 0 { 744 if hasParam { 745 buf.WriteString("&timeout=") 746 } else { 747 buf.WriteString("?timeout=") 748 hasParam = true 749 } 750 buf.WriteString(strconv.Itoa(c.connectTimeout)) 751 } 752 return buf.String() 753 } 754 755 func (c *DmConnector) mergeConfigs(dsn string) error { 756 props, host, err := c.parseDSN(dsn) 757 if err != nil { 758 return err 759 } 760 761 driverInit(props.GetString("svcConfPath", "")) 762 763 addressRemapStr := props.GetTrimString(AddressRemapKey, "") 764 userRemapStr := props.GetTrimString(UserRemapKey, "") 765 if addressRemapStr == "" { 766 addressRemapStr = GlobalProperties.GetTrimString(AddressRemapKey, "") 767 } 768 if userRemapStr == "" { 769 userRemapStr = GlobalProperties.GetTrimString(UserRemapKey, "") 770 } 771 772 host = c.remap(host, addressRemapStr) 773 774 c.user = c.remap(c.user, userRemapStr) 775 776 if group, ok := ServerGroupMap[strings.ToLower(host)]; ok { 777 c.group = group 778 } else { 779 host, port, err := net.SplitHostPort(host) 780 if err != nil || net.ParseIP(host) == nil { 781 c.host = hostDef 782 } else { 783 c.host = host 784 } 785 tmpPort, err := strconv.Atoi(port) 786 if err != nil { 787 c.port = portDef 788 } else { 789 c.port = int32(tmpPort) 790 } 791 792 c.group = newEPGroup(c.host+":"+strconv.Itoa(int(c.port)), []*ep{newEP(c.host, c.port)}) 793 } 794 795 props.SetDiffProperties(c.group.props) 796 797 props.SetDiffProperties(GlobalProperties) 798 799 if props.GetBool(RwSeparateKey, false) { 800 props.SetIfNotExist(LoginModeKey, strconv.Itoa(int(LOGIN_MODE_PRIMARY_ONLY))) 801 props.SetIfNotExist(LoginStatusKey, strconv.Itoa(int(SERVER_STATUS_OPEN))) 802 803 props.SetIfNotExist(DoSwitchKey, "true") 804 } 805 806 if err = c.setAttributes(props); err != nil { 807 return err 808 } 809 return nil 810 } 811 812 func (c *DmConnector) remap(origin string, cfgStr string) string { 813 if cfgStr == "" || origin == "" { 814 return origin 815 } 816 817 maps := regexp.MustCompile("\\(.*?,.*?\\)").FindAllString(cfgStr, -1) 818 for _, kvStr := range maps { 819 kv := strings.Split(strings.TrimSpace(kvStr[1:len(kvStr)-1]), ",") 820 if util.StringUtil.Equals(strings.TrimSpace(kv[0]), origin) { 821 return strings.TrimSpace(kv[1]) 822 } 823 } 824 return origin 825 } 826 827 func (c *DmConnector) Connect(ctx context.Context) (driver.Conn, error) { 828 return c.filterChain.reset().DmConnectorConnect(c, ctx) 829 } 830 831 func (c *DmConnector) Driver() driver.Driver { 832 return c.filterChain.reset().DmConnectorDriver(c) 833 } 834 835 func (c *DmConnector) connect(ctx context.Context) (*DmConnection, error) { 836 if c.group != nil && len(c.group.epList) > 0 { 837 return c.group.connect(c) 838 } else { 839 return c.connectSingle(ctx) 840 } 841 } 842 843 func (c *DmConnector) driver() *DmDriver { 844 return c.dmDriver 845 } 846 847 func (c *DmConnector) connectSingle(ctx context.Context) (*DmConnection, error) { 848 var err error 849 var dc *DmConnection 850 if c.reConnection == nil { 851 dc = &DmConnection{ 852 closech: make(chan struct{}), 853 } 854 dc.dmConnector = c 855 dc.autoCommit = c.autoCommit 856 dc.createFilterChain(c, nil) 857 858 dc.objId = -1 859 dc.init() 860 } else { 861 dc = c.reConnection 862 dc.reset() 863 } 864 865 dc.Access, err = dm_build_702(dc) 866 if err != nil { 867 return nil, err 868 } 869 870 dc.startWatcher() 871 if err = dc.watchCancel(ctx); err != nil { 872 return nil, err 873 } 874 defer dc.finish() 875 876 if err = dc.Access.dm_build_743(); err != nil { 877 878 if !dc.closed.IsSet() { 879 close(dc.closech) 880 if dc.Access != nil { 881 dc.Access.Close() 882 } 883 dc.closed.Set(true) 884 } 885 return nil, err 886 } 887 888 if c.schema != "" { 889 _, err = dc.exec("set schema "+c.schema, nil) 890 if err != nil { 891 return nil, err 892 } 893 } 894 895 return dc, nil 896 }