Add a configuration file for golangci-lint that contains an exclude rule
to ignore warnings about the use of deprecated db methods and
interfaces.
Those warnings are not relevant, sqlmw supports older go versions
therefore those must be implemented.
Add a testcases that ensures the driver.DefaultParameterConverter is
used to convert db args for stmts when neither the stmt nor con
implements any value converter methods.
My change caused that driver.DefaultParameterConverter is not called
anymore sometimes.
For example when the lib/pq driver is used, uint32 args passed to
stmt.Exec() are not converted by driver.DefaultParameterConverter to
int64 anymore.
This causes that the lib/pq driver operation fails because the argument
is passed unconverted, as unsupported type.
I could not reproduce the behavior in a testcase with the fakedb driver.
The driver.DefaultParameterConverter was called and the type was passed
converted to stmt.Exec(), as expected.
I don't understand yet why this happens with the lib/pq driver with my
change.
Revert it for now. That the deprecated ColumnConverter is not called by
sqlmw, is a lesser issue compared to the one that was introduced by my
change.
The testcase verifies:
- that the interceptor forwards the rows.Close() the driver.Rows.Close()
function and
- that the ctx passed to Interceptor.RowsClose() is the one that is
specified in the QueryContext() call.
Add a new RowsClose() method to the interceptor interface to which
rows.Close() calls are forwarded.
Intercepting rows.Close() can be useful in tracing middlewares.
It allows to create a parent span when the db Rows object is
created, create child spans for operations on the Rows and finish the
parent span when rows.Close() is called.
According to the stdlib driver documentation
(https://github.com/golang/go/blob/bc51e930274a5d5835ac8797978afc0864c9e30c/src/database/sql/driver/driver.go#L385)
value checkers should be called in the following order:
> [..] stopping at the first found match: Stmt.NamedValueChecker,
> Conn.NamedValueChecker, Stmt.ColumnConverter,
> DefaultParameterConverter.
sqlmw was not calling Stmt.ColumnConverter when it was implemented.
This commit changes the behavior to call Stmt.ColumnConverter, if it is
implemented and the NamedValueCheckers are not implemented.
This is done by returning ErrSkip in wrappedStmt.CheckNamedValue() if
neither the parent statement nor the conn implements CheckNamedValue.
The sql package will call wrappedStmt.ColumnConverter() if ErrSkip was
returned.
wrappedStmt.CheckNamedValue() can not check only if the stmt
implements CheckNamedValue and return ErrSkip.
It must also call CheckNamedValue() on the connection if it
was not implemented for the stmt. This is because the stdlib sql package
calls wrappedStmt.CheckNamedValue() if is implemented on the stmt OR on
the connection.
The commit also adds a testcase to verify that ColumnConverter is
called.