Skip to content

Commit 6ba10ae

Browse files
committed
add option to alter session after connection open
1 parent d97857c commit 6ba10ae

File tree

2 files changed

+276
-229
lines changed

2 files changed

+276
-229
lines changed

v2/connection.go

Lines changed: 12 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"regexp"
1212
"strconv"
1313
"strings"
14-
"sync"
1514
"sync/atomic"
1615
"time"
1716

@@ -38,18 +37,13 @@ const (
3837
//PROXY LogonMode = 0x400
3938
)
4039

41-
var oracleDriver = &OracleDriver{cusTyp: map[string]customType{}}
42-
4340
// from GODROR
4441
const wrapResultset = "--WRAP_RESULTSET--"
4542

4643
// Querier is the QueryContext of sql.Conn.
4744
type Querier interface {
4845
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
4946
}
50-
type GetDriverInterface interface {
51-
Driver() driver.Driver
52-
}
5347

5448
/////
5549

@@ -113,46 +107,16 @@ type OracleConnector struct {
113107
connectString string
114108
dialer network.DialerContext
115109
}
116-
type OracleDriver struct {
117-
dataCollected bool
118-
cusTyp map[string]customType
119-
mu sync.Mutex
120-
sStrConv converters.IStringConverter
121-
nStrConv converters.IStringConverter
122-
//serverCharset int
123-
//serverNCharset int
124-
//Conn *Connection
125-
//Server string
126-
//Port int
127-
//Instance string
128-
//Service string
129-
//DBName string
130-
UserId string
131-
//SessionId int
132-
//SerialNum int
133-
}
134-
135-
func init() {
136-
sql.Register("oracle", oracleDriver)
137-
}
138-
139-
func GetDefaultDriver() *OracleDriver {
140-
return oracleDriver
141-
}
142110

143-
func NewDriver() *OracleDriver {
144-
return &OracleDriver{cusTyp: map[string]customType{}}
145-
}
146111
func NewConnector(connString string) driver.Connector {
147112
return &OracleConnector{connectString: connString, drv: NewDriver()}
148113
}
149-
func (drv *OracleDriver) OpenConnector(connString string) (driver.Connector, error) {
114+
func (driver *OracleDriver) OpenConnector(connString string) (driver.Connector, error) {
150115
// create hash from connection string
151-
return &OracleConnector{drv: drv, connectString: connString}, nil
116+
return &OracleConnector{drv: driver, connectString: connString}, nil
152117
}
153118

154119
func (connector *OracleConnector) Connect(ctx context.Context) (driver.Conn, error) {
155-
156120
conn, err := NewConnection(connector.connectString)
157121
if err != nil {
158122
return nil, err
@@ -169,23 +133,11 @@ func (connector *OracleConnector) Connect(ctx context.Context) (driver.Conn, err
169133
if err != nil {
170134
return nil, err
171135
}
172-
connector.drv.collectData(conn)
173-
return conn, nil
174-
}
175-
176-
func (driver *OracleDriver) collectData(conn *Connection) {
177-
if !driver.dataCollected {
178-
driver.mu.Lock()
179-
defer driver.mu.Unlock()
180-
driver.UserId = conn.connOption.UserID
181-
if driver.sStrConv == nil {
182-
driver.sStrConv = conn.sStrConv.Clone()
183-
}
184-
if driver.nStrConv == nil {
185-
driver.nStrConv = conn.nStrConv.Clone()
186-
}
187-
driver.dataCollected = true
136+
err = connector.drv.init(conn)
137+
if err != nil {
138+
return nil, err
188139
}
140+
return conn, nil
189141
}
190142

191143
func (connector *OracleConnector) Driver() driver.Driver {
@@ -197,29 +149,21 @@ func (connector *OracleConnector) Dialer(dialer network.DialerContext) {
197149
}
198150

199151
// Open return a new open connection
200-
func (drv *OracleDriver) Open(name string) (driver.Conn, error) {
152+
func (driver *OracleDriver) Open(name string) (driver.Conn, error) {
201153
conn, err := NewConnection(name)
202-
conn.cusTyp = drv.cusTyp
154+
conn.cusTyp = driver.cusTyp
203155
if err != nil {
204156
return nil, err
205157
}
206158
err = conn.Open()
207159
if err != nil {
208160
return nil, err
209161
}
210-
drv.collectData(conn)
211-
212-
return conn, nil
213-
}
214-
215-
// SetStringConverter this function is used to set a custom string converter interface
216-
// that will be used to encode and decode strings and bytearrays
217-
// passing nil will use driver string converter for supported langs
218-
func SetStringConverter(db GetDriverInterface, charset, nCharset converters.IStringConverter) {
219-
if driver, ok := db.Driver().(*OracleDriver); ok {
220-
driver.sStrConv = charset
221-
driver.nStrConv = nCharset
162+
err = driver.init(conn)
163+
if err != nil {
164+
return nil, err
222165
}
166+
return conn, nil
223167
}
224168

225169
// GetNLS return NLS properties of the connection.
@@ -1302,167 +1246,6 @@ func (conn *Connection) ResetSession(ctx context.Context) error {
13021246
return nil
13031247
}
13041248

1305-
func RegisterType(conn *sql.DB, typeName, arrayTypeName string, typeObj interface{}) error {
1306-
// ping first to avoid error when calling register type after open connection
1307-
err := conn.Ping()
1308-
if err != nil {
1309-
return err
1310-
}
1311-
1312-
if driver, ok := conn.Driver().(*OracleDriver); ok {
1313-
return RegisterTypeWithOwner(conn, driver.UserId, typeName, arrayTypeName, typeObj)
1314-
}
1315-
return errors.New("the driver used is not a go-ora driver type")
1316-
}
1317-
1318-
func RegisterTypeWithOwner(conn *sql.DB, owner, typeName, arrayTypeName string, typeObj interface{}) error {
1319-
if len(owner) == 0 {
1320-
return errors.New("owner can't be empty")
1321-
}
1322-
if driver, ok := conn.Driver().(*OracleDriver); ok {
1323-
1324-
if typeObj == nil {
1325-
return errors.New("type object cannot be nil")
1326-
}
1327-
typ := reflect.TypeOf(typeObj)
1328-
switch typ.Kind() {
1329-
case reflect.Ptr:
1330-
return errors.New("unsupported type object: Ptr")
1331-
case reflect.Array:
1332-
return errors.New("unsupported type object: Array")
1333-
case reflect.Chan:
1334-
return errors.New("unsupported type object: Chan")
1335-
case reflect.Map:
1336-
return errors.New("unsupported type object: Map")
1337-
case reflect.Slice:
1338-
return errors.New("unsupported type object: Slice")
1339-
}
1340-
if typ.Kind() != reflect.Struct {
1341-
return errors.New("type object should be of structure type")
1342-
}
1343-
cust := customType{
1344-
owner: owner,
1345-
name: typeName,
1346-
arrayTypeName: arrayTypeName,
1347-
typ: typ,
1348-
fieldMap: map[string]int{},
1349-
}
1350-
sqlText := `SELECT type_oid FROM ALL_TYPES WHERE UPPER(OWNER)=:1 AND UPPER(TYPE_NAME)=:2`
1351-
err := conn.QueryRow(sqlText, strings.ToUpper(owner), strings.ToUpper(typeName)).Scan(&cust.toid)
1352-
if err != nil {
1353-
return err
1354-
}
1355-
if len(cust.arrayTypeName) > 0 {
1356-
err = conn.QueryRow(sqlText, strings.ToUpper(owner), strings.ToUpper(arrayTypeName)).Scan(&cust.arrayTOID)
1357-
if err != nil {
1358-
return err
1359-
}
1360-
}
1361-
sqlText = `SELECT ATTR_NAME, ATTR_TYPE_NAME, LENGTH, ATTR_NO
1362-
FROM ALL_TYPE_ATTRS
1363-
WHERE UPPER(OWNER)=:1 AND UPPER(TYPE_NAME)=:2`
1364-
rows, err := conn.Query(sqlText, strings.ToUpper(owner), strings.ToUpper(typeName))
1365-
if err != nil {
1366-
return err
1367-
}
1368-
var (
1369-
attName sql.NullString
1370-
attOrder int64
1371-
attTypeName sql.NullString
1372-
length sql.NullInt64
1373-
)
1374-
for rows.Next() {
1375-
err = rows.Scan(&attName, &attTypeName, &length, &attOrder)
1376-
if err != nil {
1377-
return err
1378-
}
1379-
for int(attOrder) > len(cust.attribs) {
1380-
cust.attribs = append(cust.attribs, ParameterInfo{
1381-
Direction: Input,
1382-
Flag: 3,
1383-
})
1384-
}
1385-
param := &cust.attribs[attOrder-1]
1386-
param.Name = attName.String
1387-
param.TypeName = attTypeName.String
1388-
switch strings.ToUpper(attTypeName.String) {
1389-
case "NUMBER":
1390-
param.DataType = NUMBER
1391-
param.MaxLen = converters.MAX_LEN_NUMBER
1392-
case "VARCHAR2":
1393-
param.DataType = NCHAR
1394-
param.CharsetForm = 1
1395-
param.ContFlag = 16
1396-
param.MaxCharLen = int(length.Int64)
1397-
param.CharsetID = driver.sStrConv.GetLangID()
1398-
param.MaxLen = int(length.Int64) * converters.MaxBytePerChar(param.CharsetID)
1399-
case "NVARCHAR2":
1400-
param.DataType = NCHAR
1401-
param.CharsetForm = 2
1402-
param.ContFlag = 16
1403-
param.MaxCharLen = int(length.Int64)
1404-
param.CharsetID = driver.nStrConv.GetLangID()
1405-
param.MaxLen = int(length.Int64) * converters.MaxBytePerChar(param.CharsetID)
1406-
case "TIMESTAMP":
1407-
fallthrough
1408-
case "DATE":
1409-
param.DataType = DATE
1410-
param.MaxLen = 11
1411-
case "RAW":
1412-
param.DataType = RAW
1413-
param.MaxLen = int(length.Int64)
1414-
case "BLOB":
1415-
param.DataType = OCIBlobLocator
1416-
param.MaxLen = int(length.Int64)
1417-
case "CLOB":
1418-
param.DataType = OCIClobLocator
1419-
param.CharsetForm = 1
1420-
param.ContFlag = 16
1421-
param.CharsetID = driver.sStrConv.GetLangID()
1422-
param.MaxCharLen = int(length.Int64)
1423-
param.MaxLen = int(length.Int64) * converters.MaxBytePerChar(param.CharsetID)
1424-
case "NCLOB":
1425-
param.DataType = OCIClobLocator
1426-
param.CharsetForm = 2
1427-
param.ContFlag = 16
1428-
param.CharsetID = driver.nStrConv.GetLangID()
1429-
param.MaxCharLen = int(length.Int64)
1430-
param.MaxLen = int(length.Int64) * converters.MaxBytePerChar(param.CharsetID)
1431-
default:
1432-
found := false
1433-
for name, value := range driver.cusTyp {
1434-
if name == strings.ToUpper(attTypeName.String) {
1435-
found = true
1436-
param.cusType = new(customType)
1437-
*param.cusType = value
1438-
param.ToID = value.toid
1439-
break
1440-
}
1441-
if value.arrayTypeName == strings.ToUpper(attTypeName.String) {
1442-
found = true
1443-
param.cusType = new(customType)
1444-
*param.cusType = value
1445-
param.ToID = value.toid
1446-
break
1447-
}
1448-
}
1449-
if !found {
1450-
return fmt.Errorf("unsupported attribute type: %s", attTypeName.String)
1451-
}
1452-
}
1453-
}
1454-
if len(cust.attribs) == 0 {
1455-
return fmt.Errorf("unknown or empty type: %s", typeName)
1456-
}
1457-
cust.loadFieldMap()
1458-
driver.mu.Lock()
1459-
defer driver.mu.Unlock()
1460-
driver.cusTyp[strings.ToUpper(typeName)] = cust
1461-
return nil
1462-
}
1463-
return errors.New("the driver used is not a go-ora driver type")
1464-
}
1465-
14661249
func (conn *Connection) dataTypeNegotiation() error {
14671250
tracer := conn.connOption.Tracer
14681251
var err error

0 commit comments

Comments
 (0)