Closed
Description
sometimes drivers expose functionality that doesn't make sense to handle via the DSN and would be painful/impossible to setup, using PGX as an example:
- has a logger you can set. can't pass a structure through the DSN. can't set it on the driver returned by DB.Driver() because its a singleton.
- tls.Config. same as above.
- libraries perform various hacks to get around it.
splitting sql.Open into two methods solves the above issues with minimal changes to the runtime.
func Open(driverName, dataSourceName string) (*DB, error) {
driversMu.RLock()
driveri, ok := drivers[driverName]
driversMu.RUnlock()
if !ok {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
}
return NewFromDriver(driveri, dataSourceName), nil
}
func NewFromDriver(driveri driver.Driver, dataSourceName string) *DB {
db := &DB{
driver: driveri,
dsn: dataSourceName,
openerCh: make(chan struct{}, connectionRequestQueueSize),
lastPut: make(map[*driverConn]string),
connRequests: make(map[uint64]chan connRequest),
}
go db.connectionOpener()
return db
}
for reference here is the current open code:
func Open(driverName, dataSourceName string) (*DB, error) {
driversMu.RLock()
driveri, ok := drivers[driverName]
driversMu.RUnlock()
if !ok {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
}
db := &DB{
driver: driveri,
dsn: dataSourceName,
openerCh: make(chan struct{}, connectionRequestQueueSize),
lastPut: make(map[*driverConn]string),
connRequests: make(map[uint64]chan connRequest),
}
go db.connectionOpener()
return db, nil
}