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