aboutsummaryrefslogtreecommitdiff
path: root/src/database/sql/sql.go
diff options
context:
space:
mode:
authorDaniel Theophanes <kardianos@gmail.com>2016-10-06 11:06:21 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2016-10-15 07:13:17 +0000
commit86b2f29676c52774d91dda96e0ba5d4d7bcd3b47 (patch)
tree7c88e2c500d80a1edab4d4b683aa7f3ca787573f /src/database/sql/sql.go
parentbe48aa3f3a16006ab31c424487af352ca374afed (diff)
downloadgo-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.go44
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 {