Skip to content

Commit 6bec6f1

Browse files
committed
Merge remote-tracking branch 'kmpm/issue-380' into issue-380
2 parents f83eff2 + 845a9a7 commit 6bec6f1

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

sqlx.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,16 @@ func (r *Rows) StructScan(dest interface{}) error {
666666
return r.Err()
667667
}
668668

669+
// NextResultSet moves to the next resultset if available and resets the field cache.
670+
func (r *Rows) NextResultSet() bool {
671+
if !r.Rows.NextResultSet() {
672+
return false
673+
}
674+
// reset fields cache
675+
r.started = false
676+
return true
677+
}
678+
669679
// Connect to a database and verify with a ping.
670680
func Connect(driverName, dataSourceName string) (*DB, error) {
671681
db, err := Open(driverName, dataSourceName)

sqlx_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,6 +1929,112 @@ func TestIn130Regression(t *testing.T) {
19291929
})
19301930
}
19311931

1932+
func TestMultiResultSet(t *testing.T) {
1933+
RunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {
1934+
var sp, sql string
1935+
1936+
loadDefaultFixture(db, t)
1937+
1938+
switch db.DriverName() {
1939+
case "mysql":
1940+
sp = `
1941+
CREATE PROCEDURE multiQuery()
1942+
BEGIN
1943+
SELECT first_name, last_name, email FROM person LIMIT 1;
1944+
SELECT country, telcode FROM place LIMIT 1;
1945+
END
1946+
`
1947+
sql = "CALL multiQuery();"
1948+
case "postgres":
1949+
sql = `
1950+
SELECT first_name, last_name, email FROM person LIMIT 1;
1951+
SELECT country, telcode FROM place LIMIT 1;
1952+
`
1953+
default:
1954+
// sqlite3 and postgres do not support multiple result sets with different row layout.
1955+
return
1956+
}
1957+
1958+
type Person struct {
1959+
FirstName string `db:"first_name"`
1960+
LastName string `db:"last_name"`
1961+
Email string `db:"email"`
1962+
}
1963+
type Place struct {
1964+
Country string `db:"country"`
1965+
TelCode string `db:"telcode"`
1966+
}
1967+
1968+
if sp != "" {
1969+
if _, err := db.Exec("DROP PROCEDURE IF EXISTS multiQuery"); err != nil {
1970+
t.Fatal(err)
1971+
}
1972+
1973+
if _, err := db.Exec(sp); err != nil {
1974+
t.Fatal(err)
1975+
}
1976+
}
1977+
1978+
rows, err := db.Queryx(sql)
1979+
if err != nil {
1980+
t.Fatal(err)
1981+
}
1982+
defer rows.Close()
1983+
1984+
var (
1985+
person Person
1986+
place Place
1987+
)
1988+
1989+
var i int
1990+
for rows.Next() {
1991+
i++
1992+
if err = rows.StructScan(&person); err != nil {
1993+
t.Fatal(err)
1994+
}
1995+
}
1996+
if i < 1 {
1997+
t.Errorf("[%s] Expected at least one record, got none", db.DriverName())
1998+
}
1999+
2000+
if !rows.NextResultSet() {
2001+
t.Fatalf("[%s] Expected a second recordset, got one", db.DriverName())
2002+
}
2003+
2004+
i = 0
2005+
for rows.Next() {
2006+
i++
2007+
if err = rows.StructScan(&place); err != nil {
2008+
t.Fatal(err)
2009+
}
2010+
}
2011+
if i < 1 {
2012+
t.Errorf("Expected at least one records, got none")
2013+
}
2014+
2015+
// nest no next
2016+
rows2, err := db.Queryx("SELECT first_name, last_name, email FROM person LIMIT 2;")
2017+
if err != nil {
2018+
t.Fatal(err)
2019+
}
2020+
defer rows2.Close()
2021+
2022+
i = 0
2023+
for rows2.Next() {
2024+
i++
2025+
if err = rows2.StructScan(&person); err != nil {
2026+
t.Fatal(err)
2027+
}
2028+
}
2029+
if i < 2 {
2030+
t.Errorf("[%s] Expected at least 2 records, got %d", db.DriverName(), i)
2031+
}
2032+
if rows.NextResultSet() {
2033+
t.Fatalf("[%s] Did not expected a second recordset", db.DriverName())
2034+
}
2035+
})
2036+
}
2037+
19322038
func TestSelectReset(t *testing.T) {
19332039
RunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {
19342040
loadDefaultFixture(db, t)

0 commit comments

Comments
 (0)