diff --git a/sqlite.go b/sqlite.go index 73604d8..c939821 100644 --- a/sqlite.go +++ b/sqlite.go @@ -119,6 +119,10 @@ func (drv) OpenConnector(name string) (driver.Connector, error) { return &connector{name: name}, nil } +// Connector returns a [driver.Connector] for the given connection +// parameters. +// +// The tracer may be nil. func Connector(sqliteURI string, connInitFunc ConnInitFunc, tracer sqliteh.Tracer) driver.Connector { return &connector{ name: sqliteURI, @@ -128,8 +132,10 @@ func Connector(sqliteURI string, connInitFunc ConnInitFunc, tracer sqliteh.Trace } // ConnectorWithLogger returns a [driver.Connector] for the given connection -// parameters. makeLogger is used to create a [ConnLogger] when [Connect] is +// parameters. makeLogger, if non-nil, is used to create a [ConnLogger] when [Connect] is // called. +// +// The tracer may also be nil. func ConnectorWithLogger(sqliteURI string, connInitFunc ConnInitFunc, tracer sqliteh.Tracer, makeLogger func() ConnLogger) driver.Connector { return &connector{ name: sqliteURI, @@ -141,7 +147,7 @@ func ConnectorWithLogger(sqliteURI string, connInitFunc ConnInitFunc, tracer sql type connector struct { name string - tracer sqliteh.Tracer + tracer sqliteh.Tracer // or nil makeLogger func() ConnLogger // or nil connInitFunc ConnInitFunc } @@ -193,7 +199,7 @@ const ( type conn struct { db sqliteh.DB id sqliteh.TraceConnID - tracer sqliteh.Tracer + tracer sqliteh.Tracer // or nil if unused logger ConnLogger stmts map[string]*stmt // persisted statements txState txState @@ -216,6 +222,9 @@ func (c *conn) Close() error { delete(c.stmts, q) } err := reserr(c.db, "Conn.Close", "", c.db.Close()) + if c.tracer != nil { + c.tracer.Close(c.id, err) + } return err } diff --git a/sqlite_test.go b/sqlite_test.go index ef88d1f..f0c3230 100644 --- a/sqlite_test.go +++ b/sqlite_test.go @@ -634,6 +634,7 @@ func (t *queryTracer) Commit(_ sqliteh.TraceConnID, _ error) { } func (t *queryTracer) Rollback(_ sqliteh.TraceConnID, _ error) { } +func (t *queryTracer) Close(_ sqliteh.TraceConnID, _ error) {} func TestTraceQuery(t *testing.T) { tracer := &queryTracer{ diff --git a/sqliteh/sqliteh.go b/sqliteh/sqliteh.go index ab9290e..69b6a79 100644 --- a/sqliteh/sqliteh.go +++ b/sqliteh/sqliteh.go @@ -909,4 +909,7 @@ type Tracer interface { // Rollback is called by the driver to report the end of a Tx. Rollback(id TraceConnID, err error) + + // Close is called when the SQLite connection is closed. + Close(id TraceConnID, err error) } diff --git a/sqlstats/sqlstats.go b/sqlstats/sqlstats.go index a8572af..1f5b7ff 100644 --- a/sqlstats/sqlstats.go +++ b/sqlstats/sqlstats.go @@ -28,6 +28,7 @@ type Tracer struct { TxCommitError *expvar.Map TxRollback *expvar.Map TxTotalSeconds *expvar.Map + ConnCloses *expvar.Int curTxs sync.Map // TraceConnID -> *connStats @@ -58,6 +59,9 @@ func (t *Tracer) Reset() { if t.TxTotalSeconds != nil { t.TxTotalSeconds.Init() } + if t.ConnCloses != nil { + t.ConnCloses.Set(0) + } t.curTxs.Range(func(key, value any) bool { t.curTxs.Delete(key) return true @@ -376,3 +380,9 @@ func (t *Tracer) Handle(w http.ResponseWriter, r *http.Request) { } fmt.Fprintf(w, "") } + +func (t *Tracer) Close(id sqliteh.TraceConnID, err error) { + if t.ConnCloses != nil { + t.ConnCloses.Add(1) + } +}