From 9dc1e04152d38b8baead0bd9766ad7e1150020ae Mon Sep 17 00:00:00 2001 From: Daniel Rivas <1887507+danielrs@users.noreply.github.com> Date: Wed, 18 Jun 2025 14:47:35 -0500 Subject: [PATCH 1/2] Allow wrapping the sql.Connector in addition to sql.Driver Some SQL drivers will provide a configurable connector, this new function should make it compatible with interceptors. --- connector.go | 5 +++++ driver.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/connector.go b/connector.go index 4740a0d..839a5c6 100755 --- a/connector.go +++ b/connector.go @@ -1,3 +1,4 @@ +//go:build go1.10 // +build go1.10 package sqlmw @@ -16,6 +17,10 @@ var ( _ driver.Connector = wrappedConnector{} ) +func Connector(driverRef *wrappedDriver, connector driver.Connector) driver.Connector { + return wrappedConnector{driverRef: driverRef, parent: connector} +} + func (c wrappedConnector) Connect(ctx context.Context) (conn driver.Conn, err error) { conn, err = c.driverRef.intr.ConnectorConnect(ctx, c.parent) if err != nil { diff --git a/driver.go b/driver.go index 254972e..6bf7c3f 100755 --- a/driver.go +++ b/driver.go @@ -23,7 +23,7 @@ var ( // Important note: Seeing as the context passed into the various instrumentation calls this package calls, // Any call without a context passed will not be intercepted. Please be sure to use the ___Context() and BeginTx() // function calls added in Go 1.8 instead of the older calls which do not accept a context. -func Driver(driver driver.Driver, intr Interceptor) driver.Driver { +func Driver(driver driver.Driver, intr Interceptor) wrappedDriver { return wrappedDriver{parent: driver, intr: intr} } From e6c3a0b5ac581fbcb5102597aacc9ed13b6806d5 Mon Sep 17 00:00:00 2001 From: Daniel Rivas <1887507+danielrs@users.noreply.github.com> Date: Mon, 23 Jun 2025 12:43:34 -0500 Subject: [PATCH 2/2] Make sure changes to allow Connector wrapping are backward compatible Basically make sure we don't change the signature of the `.Driver(...)` function. --- conn_go110.go | 1 + conn_go115.go | 1 + conn_go19.go | 1 + connector.go | 4 +++- driver.go | 16 +++++++++++----- driver_go110.go | 9 +++------ 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/conn_go110.go b/conn_go110.go index b980d93..36b41e5 100755 --- a/conn_go110.go +++ b/conn_go110.go @@ -1,3 +1,4 @@ +//go:build go1.10 // +build go1.10 package sqlmw diff --git a/conn_go115.go b/conn_go115.go index f635425..ae14e9c 100755 --- a/conn_go115.go +++ b/conn_go115.go @@ -1,3 +1,4 @@ +//go:build go1.15 // +build go1.15 package sqlmw diff --git a/conn_go19.go b/conn_go19.go index 268cabc..21eb1c0 100755 --- a/conn_go19.go +++ b/conn_go19.go @@ -1,3 +1,4 @@ +//go:build go1.9 // +build go1.9 package sqlmw diff --git a/connector.go b/connector.go index 839a5c6..b74a563 100755 --- a/connector.go +++ b/connector.go @@ -17,7 +17,9 @@ var ( _ driver.Connector = wrappedConnector{} ) -func Connector(driverRef *wrappedDriver, connector driver.Connector) driver.Connector { +// WrapConnector returns the supplied driver.Connector wrapped in a new object that has all of its calls intercepted by +// the Interceptor in the supplied driver. +func WrapConnector(driverRef *wrappedDriver, connector driver.Connector) wrappedConnector { return wrappedConnector{driverRef: driverRef, parent: connector} } diff --git a/driver.go b/driver.go index 6bf7c3f..2dd0849 100755 --- a/driver.go +++ b/driver.go @@ -13,17 +13,23 @@ var ( _ driver.Driver = wrappedDriver{} ) -// WrapDriver will wrap the passed SQL driver and return a new sql driver that uses it and also logs and traces calls using the passed logger and tracer -// The returned driver will still have to be registered with the sql package before it can be used. +// WrapDriver returns the supplied driver.Driver wrapped in a new object that has all of its calls intercepted by the +// supplied Interceptor object. // +// Important note: Seeing as the context passed into the various instrumentation calls this package calls, +// Any call without a context passed will not be intercepted. Please be sure to use the ___Context() and BeginTx() +// function calls added in Go 1.8 instead of the older calls which do not accept a context. +func WrapDriver(driver driver.Driver, intr Interceptor) wrappedDriver { + return wrappedDriver{parent: driver, intr: intr} +} -// Driver returns the supplied driver.Driver with a new object that has all of its calls intercepted by the supplied -// Interceptor object. +// WrapDriver returns the supplied driver.Driver wrapped in a new object that has all of its calls intercepted by the +// supplied Interceptor object. // // Important note: Seeing as the context passed into the various instrumentation calls this package calls, // Any call without a context passed will not be intercepted. Please be sure to use the ___Context() and BeginTx() // function calls added in Go 1.8 instead of the older calls which do not accept a context. -func Driver(driver driver.Driver, intr Interceptor) wrappedDriver { +func Driver(driver driver.Driver, intr Interceptor) driver.Driver { return wrappedDriver{parent: driver, intr: intr} } diff --git a/driver_go110.go b/driver_go110.go index 0a2c0a3..d683211 100755 --- a/driver_go110.go +++ b/driver_go110.go @@ -1,3 +1,4 @@ +//go:build go1.10 // +build go1.10 package sqlmw @@ -9,15 +10,11 @@ var _ driver.DriverContext = wrappedDriver{} func (d wrappedDriver) OpenConnector(name string) (driver.Connector, error) { driver, ok := d.parent.(driver.DriverContext) if !ok { - return wrappedConnector{ - parent: dsnConnector{dsn: name, driver: d.parent}, - driverRef: &d, - }, nil + return WrapConnector(&d, dsnConnector{dsn: name, driver: d.parent}), nil } conn, err := driver.OpenConnector(name) if err != nil { return nil, err } - - return wrappedConnector{parent: conn, driverRef: &d}, nil + return WrapConnector(&d, conn), nil }