Skip to content

Commit 194b636

Browse files
tieodeke-em
authored andcommitted
database/sql: close driver.Connector if it implements 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 Fixes #41790 Change-Id: Idbd19763134438ed38288b9d44f16608e4e97fd7 GitHub-Last-Rev: 962c785 GitHub-Pull-Request: #41710 Reviewed-on: https://go-review.googlesource.com/c/go/+/258360 Reviewed-by: Emmanuel Odeke <[email protected]> Reviewed-by: Daniel Theophanes <[email protected]> Trust: Emmanuel Odeke <[email protected]> Run-TryBot: Emmanuel Odeke <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent 4ebb6f5 commit 194b636

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-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+
// If a Connector implements io.Closer, the sql package's DB.Close
120+
// method will call Close and return error (if any).
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

+6
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,12 @@ func (db *DB) Close() error {
850850
}
851851
}
852852
db.stop()
853+
if c, ok := db.connector.(io.Closer); ok {
854+
err1 := c.Close()
855+
if err1 != nil {
856+
err = err1
857+
}
858+
}
853859
return err
854860
}
855861

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)