mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
database/sql: add support for multiple result sets
Many database systems allow returning multiple result sets in a single query. This can be useful when dealing with many intermediate results on the server and there is a need to return more then one arity of data to the client. Fixes #12382 Change-Id: I480a9ac6dadfc8743e0ba8b6d868ccf8442a9ca1 Reviewed-on: https://go-review.googlesource.com/30592 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
be48aa3f3a
commit
86b2f29676
5 changed files with 335 additions and 88 deletions
|
|
@ -1942,6 +1942,47 @@ func (rs *Rows) Next() bool {
|
|||
rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
|
||||
}
|
||||
rs.lasterr = rs.rowsi.Next(rs.lastcols)
|
||||
if rs.lasterr != nil {
|
||||
// Close the connection if there is a driver error.
|
||||
if rs.lasterr != io.EOF {
|
||||
rs.Close()
|
||||
return false
|
||||
}
|
||||
nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
|
||||
if !ok {
|
||||
rs.Close()
|
||||
return false
|
||||
}
|
||||
// The driver is at the end of the current result set.
|
||||
// Test to see if there is another result set after the current one.
|
||||
// Only close Rows if there is no futher result sets to read.
|
||||
if !nextResultSet.HasNextResultSet() {
|
||||
rs.Close()
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NextResultSet prepares the next result set for reading. It returns true if
|
||||
// there is further result sets, or false if there is no further result set
|
||||
// or if there is an error advancing to it. The Err method should be consulted
|
||||
// to distinguish between the two cases.
|
||||
//
|
||||
// After calling NextResultSet, the Next method should always be called before
|
||||
// scanning. If there are further result sets they may not have rows in the result
|
||||
// set.
|
||||
func (rs *Rows) NextResultSet() bool {
|
||||
if rs.isClosed() {
|
||||
return false
|
||||
}
|
||||
rs.lastcols = nil
|
||||
nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
|
||||
if !ok {
|
||||
rs.Close()
|
||||
return false
|
||||
}
|
||||
rs.lasterr = nextResultSet.NextResultSet()
|
||||
if rs.lasterr != nil {
|
||||
rs.Close()
|
||||
return false
|
||||
|
|
@ -2047,7 +2088,8 @@ func (rs *Rows) isClosed() bool {
|
|||
return atomic.LoadInt32(&rs.closed) != 0
|
||||
}
|
||||
|
||||
// Close closes the Rows, preventing further enumeration. If Next returns
|
||||
// Close closes the Rows, preventing further enumeration. If Next and
|
||||
// NextResultSet both return
|
||||
// false, the Rows are closed automatically and it will suffice to check the
|
||||
// result of Err. Close is idempotent and does not affect the result of Err.
|
||||
func (rs *Rows) Close() error {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue