This is a dirty hack to golang's database/sql
package.
Currently only go-sql-driver/mysql is supported, dont apply this patch if you using other databases.
The motivation to create this package, comes from that the standard database/sql
package lacks the support for Multi ResultSet feature. This is not a big issue for common usage, but for users who using stored procedures, they will encounter "Command out of sync" error.
Developers of go-sql-driver/mysql
has confirmed that they cannot support this feature until golang's database API change first. So, it will remain dirty until Golang provide its offical way to support multiResultSet returned by stored procedure (or multi statements).
I named this package to an independent package named databasex
to avoid name conflicts. You can directly patch the source code of database/sql
and using github.com/databasex/mysql
directly.
- Support return multi result sets in text protocol , ex
CALL sp_test(1,2,3)
- Support return multi result sets in prepared statement protocol, ex
CALL sp_test(?,?,?)
- Supoort return out paramater of stored procedure as a new Result Set
- For usage, reference multi_test.go
database/sql/Rows
type added one method.
// Sibling forward the next result set in current context.
//
// To support multi result set feature, append clientMultiResults=true
// to DSN string passed to sql.Open()
//
// Currently only support stored procedure to generate multi resultsets,
// using multi statements also possible , welcome to contribue ;-)
func (rs *Rows) Sibling() (Result, bool)
database/sql/driver/Rows
interface added 2 methods.
// MoreResults returns if there are other result sets exists
//
// After iterate the current result set and Next() returns false,
// then call this method to determine if there are some onther result
// sets exists, if it does, call Sibling to change to that Rows.
MoreResults() bool
// Sibling is called to pululate multi results in one query.
//
// Sibling should return io.EOF when there are no more results
Sibling() (Rows, error)
This hack based on the following code:
- source code of
database/sql
package from golang 1.5- add a Sibling() method for sql.Rows type.
- add MoreResults() / Sibling() method to driver.Rows interface
- source code of
go-sql-driver/mysql
based on commit: 3dd7008ac1529aca1bcd8a9db75228a71ba23cac
- implement the sql.driver.Rows interfaces
All modifications are listed in the orig.diff file in both sql and mysql repo.
go get -u github.com/databasex/sql
go get -u github.com/databasex/mysql
cd $GOROOT/src/database/sql
, then apply the patchpatch -p1 < $GOROOT/src/github.com/databasex/sql/database.patch
rm -rf $GOROOT/pkg/darwin_amd64/database
to purge the compiled binary.darwin_amd64
might be diffrent on linux/windows box.- Replace
_ github.com/go-sql-driver/mysql
imports with_ github.com/databasex/mysql
- When calling sql.Open, append
"&clientMultiResults=true"
to your DSN. - To enable return multi result sets with prepared statement, append
"&clientPSMultiResults=true"
to your DSN. - For detail, reference multi_test.go