diff options
| author | Daniel Theophanes <kardianos@gmail.com> | 2016-10-06 11:06:21 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2016-10-15 07:13:17 +0000 |
| commit | 86b2f29676c52774d91dda96e0ba5d4d7bcd3b47 (patch) | |
| tree | 7c88e2c500d80a1edab4d4b683aa7f3ca787573f /src/database/sql/sql.go | |
| parent | be48aa3f3a16006ab31c424487af352ca374afed (diff) | |
| download | go-86b2f29676c52774d91dda96e0ba5d4d7bcd3b47.tar.xz | |
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>
Diffstat (limited to 'src/database/sql/sql.go')
| -rw-r--r-- | src/database/sql/sql.go | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index c26d7d3063..970334269d 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -1943,6 +1943,47 @@ func (rs *Rows) Next() bool { } 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 { |
