@@ -11,7 +11,6 @@ import (
11
11
"regexp"
12
12
"strconv"
13
13
"strings"
14
- "sync"
15
14
"sync/atomic"
16
15
"time"
17
16
@@ -38,18 +37,13 @@ const (
38
37
//PROXY LogonMode = 0x400
39
38
)
40
39
41
- var oracleDriver = & OracleDriver {cusTyp : map [string ]customType {}}
42
-
43
40
// from GODROR
44
41
const wrapResultset = "--WRAP_RESULTSET--"
45
42
46
43
// Querier is the QueryContext of sql.Conn.
47
44
type Querier interface {
48
45
QueryContext (context.Context , string , ... interface {}) (* sql.Rows , error )
49
46
}
50
- type GetDriverInterface interface {
51
- Driver () driver.Driver
52
- }
53
47
54
48
/////
55
49
@@ -113,46 +107,16 @@ type OracleConnector struct {
113
107
connectString string
114
108
dialer network.DialerContext
115
109
}
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
- }
142
110
143
- func NewDriver () * OracleDriver {
144
- return & OracleDriver {cusTyp : map [string ]customType {}}
145
- }
146
111
func NewConnector (connString string ) driver.Connector {
147
112
return & OracleConnector {connectString : connString , drv : NewDriver ()}
148
113
}
149
- func (drv * OracleDriver ) OpenConnector (connString string ) (driver.Connector , error ) {
114
+ func (driver * OracleDriver ) OpenConnector (connString string ) (driver.Connector , error ) {
150
115
// create hash from connection string
151
- return & OracleConnector {drv : drv , connectString : connString }, nil
116
+ return & OracleConnector {drv : driver , connectString : connString }, nil
152
117
}
153
118
154
119
func (connector * OracleConnector ) Connect (ctx context.Context ) (driver.Conn , error ) {
155
-
156
120
conn , err := NewConnection (connector .connectString )
157
121
if err != nil {
158
122
return nil , err
@@ -169,23 +133,11 @@ func (connector *OracleConnector) Connect(ctx context.Context) (driver.Conn, err
169
133
if err != nil {
170
134
return nil , err
171
135
}
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
188
139
}
140
+ return conn , nil
189
141
}
190
142
191
143
func (connector * OracleConnector ) Driver () driver.Driver {
@@ -197,29 +149,21 @@ func (connector *OracleConnector) Dialer(dialer network.DialerContext) {
197
149
}
198
150
199
151
// 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 ) {
201
153
conn , err := NewConnection (name )
202
- conn .cusTyp = drv .cusTyp
154
+ conn .cusTyp = driver .cusTyp
203
155
if err != nil {
204
156
return nil , err
205
157
}
206
158
err = conn .Open ()
207
159
if err != nil {
208
160
return nil , err
209
161
}
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
222
165
}
166
+ return conn , nil
223
167
}
224
168
225
169
// GetNLS return NLS properties of the connection.
@@ -1302,167 +1246,6 @@ func (conn *Connection) ResetSession(ctx context.Context) error {
1302
1246
return nil
1303
1247
}
1304
1248
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
-
1466
1249
func (conn * Connection ) dataTypeNegotiation () error {
1467
1250
tracer := conn .connOption .Tracer
1468
1251
var err error
0 commit comments