From c098d27a32a789f49ba9accd6151dd0a073804b0 Mon Sep 17 00:00:00 2001 From: Raffael Schmid Date: Sun, 15 Sep 2024 21:20:38 +0200 Subject: [PATCH] add LOCATION parameter --- v2/configurations/connect_config.go | 102 ++++++++++++++-------------- v2/configurations/database_info.go | 1 + v2/connection.go | 52 +++++++++----- 3 files changed, 87 insertions(+), 68 deletions(-) diff --git a/v2/configurations/connect_config.go b/v2/configurations/connect_config.go index ffe712a..e97ea2b 100644 --- a/v2/configurations/connect_config.go +++ b/v2/configurations/connect_config.go @@ -95,21 +95,21 @@ func ParseConfig(dsn string) (*ConnectionConfig, error) { }, ClientInfo: ClientInfo{Territory: "AMERICA", Language: "AMERICAN"}, } - //ret := &ConnectionString{ - //Port: defaultPort, - //DBAPrivilege: NONE, - //EnList: TRUE, - //IncrPoolSize: 5, - //DecrPoolSize: 5, - //MaxPoolSize: 100, - //MinPoolSize: 1, - //PromotableTransaction: Promotable, - //StmtCacheSize: 20, - //MetadataBooling: true, - //SelfTuning: true, - //PoolRegulator: 100, - //ConnectionPoolTimeout: 15, - //} + // ret := &ConnectionString{ + // Port: defaultPort, + // DBAPrivilege: NONE, + // EnList: TRUE, + // IncrPoolSize: 5, + // DecrPoolSize: 5, + // MaxPoolSize: 100, + // MinPoolSize: 1, + // PromotableTransaction: Promotable, + // StmtCacheSize: 20, + // MetadataBooling: true, + // SelfTuning: true, + // PoolRegulator: 100, + // ConnectionPoolTimeout: 15, + // } config.UserID = u.User.Username() config.DatabaseInfo.Password, _ = u.User.Password() if strings.ToUpper(config.UserID) == "SYS" { @@ -243,16 +243,16 @@ func ParseConfig(dsn string) (*ConnectionConfig, error) { config.SessionInfo.Timeout = time.Second * time.Duration(to) case "TRACE FILE": config.TraceFilePath = val[0] - //if len(val[0]) > 0 { + // if len(val[0]) > 0 { // tf, err := os.Create(val[0]) // if err != nil { // //noinspection GoErrorStringFormat // return nil, fmt.Errorf("Can't open trace file: %w", err) // } // config.Tracer = trace.NewTraceWriter(tf) - //} else { + // } else { // config.Tracer = trace.NilTracer() - //} + // } case "TRACE DIR": fallthrough case "TRACE FOLDER": @@ -276,20 +276,20 @@ func ParseConfig(dsn string) (*ConnectionConfig, error) { config.DatabaseInfo.ProxyClientName = val[0] case "FAILOVER": return nil, errors.New("starting from v2.7.0 this feature (FAILOVER) is not supported and the driver use database/sql package fail over") - //config.Failover, err = strconv.Atoi(val[0]) - //if err != nil { + // config.Failover, err = strconv.Atoi(val[0]) + // if err != nil { // config.Failover = 0 - //} + // } case "RETRYTIME": fallthrough case "RE-TRY TIME": fallthrough case "RETRY TIME": return nil, errors.New("starting from v2.7.0 this feature (RETRY TIME) is not supported and the driver use database/sql package fail over") - //config.RetryTime, err = strconv.Atoi(val[0]) - //if err != nil { + // config.RetryTime, err = strconv.Atoi(val[0]) + // if err != nil { // config.RetryTime = 0 - //} + // } case "LOB FETCH": tempVal := strings.ToUpper(val[0]) if tempVal == "PRE" || tempVal == "INLINE" { @@ -312,86 +312,88 @@ func ParseConfig(dsn string) (*ConnectionConfig, error) { } case "PROGRAM": config.ClientInfo.ProgramName = val[0] + case "SERVER LOCATION": + config.DatabaseInfo.Location = val[0] default: return nil, fmt.Errorf("unknown URL option: %s", key) - //else if tempVal == "IMPLICIT" || tempVal == "AUTO" { + // else if tempVal == "IMPLICIT" || tempVal == "AUTO" { // config.Lob = 1 - //} else if tempVal == "EXPLICIT" || tempVal == "MANUAL" { + // } else if tempVal == "EXPLICIT" || tempVal == "MANUAL" { // config.Lob = 2 - //} else { + // } else { // return nil, errors.New("LOB value should be: Prefetch, Implicit(AUTO) or Explicit(manual)") - //} - //case "ENLIST": + // } + // case "ENLIST": // ret.EnList = EnListFromString(val[0]) - //case "INC POOL SIZE": + // case "INC POOL SIZE": // ret.IncrPoolSize, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("INC POOL SIZE value must be an integer") // } - //case "DECR POOL SIZE": + // case "DECR POOL SIZE": // ret.DecrPoolSize, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("DECR POOL SIZE value must be an integer") // } - //case "MAX POOL SIZE": + // case "MAX POOL SIZE": // ret.MaxPoolSize, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("MAX POOL SIZE value must be an integer") // } - //case "MIN POOL SIZE": + // case "MIN POOL SIZE": // ret.MinPoolSize, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("MIN POOL SIZE value must be an integer") // } - //case "POOL REGULATOR": + // case "POOL REGULATOR": // ret.PoolRegulator, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("POOL REGULATOR value must be an integer") // } - //case "STATEMENT CACHE SIZE": + // case "STATEMENT CACHE SIZE": // ret.StmtCacheSize, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("STATEMENT CACHE SIZE value must be an integer") // } - //case "CONNECTION POOL TIMEOUT": + // case "CONNECTION POOL TIMEOUT": // ret.ConnectionPoolTimeout, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("CONNECTION POOL TIMEOUT value must be an integer") // } - //case "CONNECTION LIFETIME": + // case "CONNECTION LIFETIME": // ret.ConnectionLifeTime, err = strconv.Atoi(val[0]) // if err != nil { // return nil, errors.New("CONNECTION LIFETIME value must be an integer") // } - //case "PERSIST SECURITY INFO": + // case "PERSIST SECURITY INFO": // ret.PasswordSecurityInfo = val[0] == "TRUE" - //case "POOLING": + // case "POOLING": // ret.Pooling = val[0] == "TRUE" - //case "VALIDATE CONNECTION": + // case "VALIDATE CONNECTION": // ret.ValidateConnection = val[0] == "TRUE" - //case "STATEMENT CACHE PURGE": + // case "STATEMENT CACHE PURGE": // ret.StmtCachePurge = val[0] == "TRUE" - //case "HA EVENTS": + // case "HA EVENTS": // ret.HaEvent = val[0] == "TRUE" - //case "LOAD BALANCING": + // case "LOAD BALANCING": // ret.LoadBalance = val[0] == "TRUE" - //case "METADATA POOLING": + // case "METADATA POOLING": // ret.MetadataBooling = val[0] == "TRUE" - //case "SELF TUNING": + // case "SELF TUNING": // ret.SelfTuning = val[0] == "TRUE" - //case "CONTEXT CONNECTION": + // case "CONTEXT CONNECTION": // ret.ContextConnection = val[0] == "TRUE" - //case "PROMOTABLE TRANSACTION": + // case "PROMOTABLE TRANSACTION": // if val[0] == "PROMOTABLE" { // ret.PromotableTransaction = Promotable // } else { // ret.PromotableTransaction = Local // } - //case "APPLICATION EDITION": + // case "APPLICATION EDITION": // ret.ApplicationEdition = val[0] - //case "PROXY USER ID": + // case "PROXY USER ID": // ret.ProxyUserID = val[0] - //case "PROXY PASSWORD": + // case "PROXY PASSWORD": // ret.ProxyPassword = val[0] } } diff --git a/v2/configurations/database_info.go b/v2/configurations/database_info.go index 442c9dc..5e74e8f 100644 --- a/v2/configurations/database_info.go +++ b/v2/configurations/database_info.go @@ -47,6 +47,7 @@ type DatabaseInfo struct { AuthType AuthType Wallet *Wallet connStr string + Location string } func ExtractServers(connStr string) (addresses []ServerAddr, err error) { diff --git a/v2/connection.go b/v2/connection.go index 60372c4..8bcbc29 100755 --- a/v2/connection.go +++ b/v2/connection.go @@ -50,7 +50,7 @@ type Querier interface { QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) } -///// +// /// type NLSData struct { Calender string `db:"p_nls_calendar,,40,out"` @@ -103,9 +103,10 @@ type Connection struct { date int timestamp int } - bad bool - dbTimeZone *time.Location - dbServerTimeZone *time.Location + bad bool + dbTimeZone *time.Location + dbServerTimeZone *time.Location + dbServerTimeZoneExplicit *time.Location } type OracleConnector struct { @@ -213,7 +214,7 @@ func (conn *Connection) GetNLS() (*NLSData, error) { // fmt.Println(stmt.Pars) - //if len(stmt.Pars) >= 10 { + // if len(stmt.Pars) >= 10 { // conn.NLSData.Calender = conn.sStrConv.Decode(stmt.Pars[0].BValue) // conn.NLSData.Comp = conn.sStrConv.Decode(stmt.Pars[1].BValue) // conn.NLSData.LengthSemantics = conn.sStrConv.Decode(stmt.Pars[2].BValue) @@ -227,7 +228,7 @@ func (conn *Connection) GetNLS() (*NLSData, error) { // conn.NLSData.DualCurrency = conn.sStrConv.Decode(stmt.Pars[10].BValue) // conn.NLSData.Timestamp = conn.sStrConv.Decode(stmt.Pars[11].BValue) // conn.NLSData.TimestampTZ = conn.sStrConv.Decode(stmt.Pars[12].BValue) - //} + // } /* for _, par := range stmt.Pars { @@ -315,8 +316,8 @@ func (conn *Connection) Logoff() error { return err } return conn.read() - //loop := true - //for loop { + // loop := true + // for loop { // msg, err := session.GetByte() // if err != nil { // return err @@ -328,8 +329,8 @@ func (conn *Connection) Logoff() error { // if msg == 4 || msg == 9 { // loop = false // } - //} - //return nil + // } + // return nil } func (conn *Connection) read() error { @@ -356,7 +357,7 @@ func (conn *Connection) Open() error { return conn.OpenWithContext(context.Background()) } -//func (conn *Connection) restore() error { +// func (conn *Connection) restore() error { // tracer := conn.tracer // failOver := conn.connOption.Failover // var err error @@ -370,7 +371,7 @@ func (conn *Connection) Open() error { // break // } // return err -//} +// } // OpenWithContext open the connection with timeout context func (conn *Connection) OpenWithContext(ctx context.Context) error { @@ -492,6 +493,21 @@ func (conn *Connection) OpenWithContext(ctx context.Context) error { } func (conn *Connection) getDBServerTimeZone() { + + if conn.connOption.DatabaseInfo.Location != "" { + loc, err := time.LoadLocation(conn.connOption.DatabaseInfo.Location) + if err == nil { + conn.dbServerTimeZone = loc + return + } + conn.tracer.Printf("Unable to configure timezone from LOCATION parameter: %v", err) + } + + if conn.dbServerTimeZoneExplicit != nil { + conn.dbServerTimeZone = conn.dbServerTimeZoneExplicit + return + } + var current time.Time err := conn.QueryRowContext(context.Background(), "SELECT SYSTIMESTAMP FROM DUAL", nil).Scan(¤t) if err != nil { @@ -1131,12 +1147,12 @@ func (conn *Connection) readMsg(msgCode uint8) error { var err error switch msgCode { case 4: - //if conn.session.IsBreak() { + // if conn.session.IsBreak() { // if conn.session.RestoreIndex() { // _, _ = conn.session.GetByte() // } // conn.session.ResetBreak() - //} + // } conn.session.Summary, err = network.NewSummary(session) if err != nil { return err @@ -1156,18 +1172,18 @@ func (conn *Connection) readMsg(msgCode uint8) error { return err } } - //for x := 0; x < 2; x++ { + // for x := 0; x < 2; x++ { // _, err = session.GetInt(4, true, true) // if err != nil { // return err // } - //} - //for x := 2; x < size; x++ { + // } + // for x := 2; x < size; x++ { // _, err = session.GetInt(4, true, true) // if err != nil { // return err // } - //} + // } _, err = session.GetInt(2, true, true) if err != nil { return err