Skip to content

Commit 0cf218e

Browse files
committed
database/sql: close driver.Connector if it implements an io.Closer
This change allows driver implementations to manage resources in driver.Connector, e.g. to share the same underlying database handle between multiple connections. That is, it allows embedded databases with in-memory backends like SQLite and Genji to safely release the resources once the sql.DB is closed. This makes it possible to address oddities with in-memory stores in SQLite and Genji drivers without introducing too much complexity in the driver implementations. See also: - mattn/go-sqlite3#204 - mattn/go-sqlite3#511 - chaisql/chai#210
1 parent 9fe8ebf commit 0cf218e

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

src/database/sql/driver/driver.go

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ type DriverContext interface {
115115
// DriverContext's OpenConnector method, to allow drivers
116116
// access to context and to avoid repeated parsing of driver
117117
// configuration.
118+
//
119+
// A Connector may optionally implement io.Closer interface
120+
// to release the resources when sql.DB is closed.
118121
type Connector interface {
119122
// Connect returns a connection to the database.
120123
// Connect may return a cached connection (one previously

src/database/sql/fakedb_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type fakeConnector struct {
5656
name string
5757

5858
waiter func(context.Context)
59+
closed bool
5960
}
6061

6162
func (c *fakeConnector) Connect(context.Context) (driver.Conn, error) {
@@ -68,6 +69,14 @@ func (c *fakeConnector) Driver() driver.Driver {
6869
return fdriver
6970
}
7071

72+
func (c *fakeConnector) Close() error {
73+
if c.closed {
74+
return errors.New("fakedb: connector is closed")
75+
}
76+
c.closed = true
77+
return nil
78+
}
79+
7180
type fakeDriverCtx struct {
7281
fakeDriver
7382
}

src/database/sql/sql.go

+3
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,9 @@ func (db *DB) Close() error {
850850
}
851851
}
852852
db.stop()
853+
if c, ok := db.connector.(io.Closer); ok {
854+
err = c.Close()
855+
}
853856
return err
854857
}
855858

src/database/sql/sql_test.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -4059,9 +4059,18 @@ func TestOpenConnector(t *testing.T) {
40594059
}
40604060
defer db.Close()
40614061

4062-
if _, is := db.connector.(*fakeConnector); !is {
4062+
c, ok := db.connector.(*fakeConnector)
4063+
if !ok {
40634064
t.Fatal("not using *fakeConnector")
40644065
}
4066+
4067+
if err := db.Close(); err != nil {
4068+
t.Fatal(err)
4069+
}
4070+
4071+
if !c.closed {
4072+
t.Fatal("connector is not closed")
4073+
}
40654074
}
40664075

40674076
type ctxOnlyDriver struct {

0 commit comments

Comments
 (0)