mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
database/sql: allow OpenConnector in a driver.Driver interface
While driver.Connector was previously added to allow non-string connection arguments and access to the context, most users of the sql package will continue to rely on a string DSN. Allow drivers to implement a string DSN to Connector interface that both allows a single parsing of the string DSN and uses the Connector interface which passes available context to the driver dialer. Fixes #22713 Change-Id: Ia0b862262f4c4670effe2538d0d6d43733fea18d Reviewed-on: https://go-review.googlesource.com/77550 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
096b195df5
commit
b44b2feb91
4 changed files with 42 additions and 0 deletions
|
|
@ -55,6 +55,17 @@ type Driver interface {
|
||||||
Open(name string) (Conn, error)
|
Open(name string) (Conn, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DriverContext enhances the Driver interface by returning a Connector
|
||||||
|
// rather then a single Conn.
|
||||||
|
// It separates out the name parsing step from actually connecting to the
|
||||||
|
// database. It also gives dialers access to the context by using the
|
||||||
|
// Connector.
|
||||||
|
type DriverContext interface {
|
||||||
|
// OpenConnector must parse the name in the same format that Driver.Open
|
||||||
|
// parses the name parameter.
|
||||||
|
OpenConnector(name string) (Connector, error)
|
||||||
|
}
|
||||||
|
|
||||||
// Connector is an optional interface that drivers can implement.
|
// Connector is an optional interface that drivers can implement.
|
||||||
// It allows drivers to provide more flexible methods to open
|
// It allows drivers to provide more flexible methods to open
|
||||||
// database connections without requiring the use of a DSN string.
|
// database connections without requiring the use of a DSN string.
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,16 @@ func (c *fakeConnector) Driver() driver.Driver {
|
||||||
return fdriver
|
return fdriver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fakeDriverCtx struct {
|
||||||
|
fakeDriver
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ driver.DriverContext = &fakeDriverCtx{}
|
||||||
|
|
||||||
|
func (cc *fakeDriverCtx) OpenConnector(name string) (driver.Connector, error) {
|
||||||
|
return &fakeConnector{name: name}, nil
|
||||||
|
}
|
||||||
|
|
||||||
type fakeDB struct {
|
type fakeDB struct {
|
||||||
name string
|
name string
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -662,6 +662,14 @@ func Open(driverName, dataSourceName string) (*DB, error) {
|
||||||
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
|
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if driverCtx, ok := driveri.(driver.DriverContext); ok {
|
||||||
|
connector, err := driverCtx.OpenConnector(dataSourceName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return OpenDB(connector), nil
|
||||||
|
}
|
||||||
|
|
||||||
return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
|
return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3523,6 +3523,19 @@ func TestNamedValueCheckerSkip(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOpenConnector(t *testing.T) {
|
||||||
|
Register("testctx", &fakeDriverCtx{})
|
||||||
|
db, err := Open("testctx", "people")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
if _, is := db.connector.(*fakeConnector); !is {
|
||||||
|
t.Fatal("not using *fakeConnector")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ctxOnlyDriver struct {
|
type ctxOnlyDriver struct {
|
||||||
fakeDriver
|
fakeDriver
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue