n.go 23 KB

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