Skip to content

Commit f93ad2c

Browse files
committed
added NextResultSet implementation
1 parent a62bc60 commit f93ad2c

2 files changed

Lines changed: 117 additions & 0 deletions

File tree

sqlx.go

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

636+
// NextResultSet moves to the next resultset if available and resets the field cache.
637+
func (r *Rows) NextResultSet() bool {
638+
if !r.Rows.NextResultSet() {
639+
return false
640+
}
641+
// reset fields cache
642+
r.started = false
643+
return true
644+
}
645+
636646
// Connect to a database and verify with a ping.
637647
func Connect(driverName, dataSourceName string) (*DB, error) {
638648
db, err := Open(driverName, dataSourceName)

sqlx_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,3 +1892,110 @@ func TestIn130Regression(t *testing.T) {
18921892
}
18931893
})
18941894
}
1895+
1896+
func TestMultiResultSet(t *testing.T) {
1897+
RunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {
1898+
var sp, sql string
1899+
1900+
loadDefaultFixture(db, t)
1901+
1902+
switch db.DriverName() {
1903+
case "mysql":
1904+
sp = `
1905+
CREATE PROCEDURE multiQuery()
1906+
BEGIN
1907+
SELECT first_name, last_name, email FROM person LIMIT 1;
1908+
SELECT country, telcode FROM place LIMIT 1;
1909+
END
1910+
`
1911+
sql = "CALL multiQuery();"
1912+
case "postgres":
1913+
sql = `
1914+
SELECT first_name, last_name, email FROM person LIMIT 1;
1915+
SELECT country, telcode FROM place LIMIT 1;
1916+
`
1917+
default:
1918+
// sqlite3 and postgres do not support multiple result sets with different row layout.
1919+
return
1920+
}
1921+
1922+
type Person struct {
1923+
FirstName string `db:"first_name"`
1924+
LastName string `db:"last_name"`
1925+
Email string `db:"email"`
1926+
}
1927+
type Place struct {
1928+
Country string `db:"country"`
1929+
TelCode string `db:"telcode"`
1930+
}
1931+
1932+
if sp != "" {
1933+
if _, err := db.Exec("DROP PROCEDURE IF EXISTS multiQuery"); err != nil {
1934+
t.Fatal(err)
1935+
}
1936+
1937+
if _, err := db.Exec(sp); err != nil {
1938+
t.Fatal(err)
1939+
}
1940+
}
1941+
1942+
rows, err := db.Queryx(sql)
1943+
if err != nil {
1944+
t.Fatal(err)
1945+
}
1946+
defer rows.Close()
1947+
1948+
var (
1949+
person Person
1950+
place Place
1951+
)
1952+
1953+
var i int
1954+
for rows.Next() {
1955+
i++
1956+
if err = rows.StructScan(&person); err != nil {
1957+
t.Fatal(err)
1958+
}
1959+
}
1960+
if i < 1 {
1961+
t.Errorf("[%s] Expected at least one record, got none", db.DriverName())
1962+
}
1963+
1964+
if !rows.NextResultSet() {
1965+
t.Fatalf("[%s] Expected a second recordset, got one", db.DriverName())
1966+
}
1967+
1968+
i = 0
1969+
for rows.Next() {
1970+
i++
1971+
if err = rows.StructScan(&place); err != nil {
1972+
t.Fatal(err)
1973+
}
1974+
}
1975+
if i < 1 {
1976+
t.Errorf("Expected at least one records, got none")
1977+
}
1978+
1979+
// nest no next
1980+
rows2, err := db.Queryx("SELECT first_name, last_name, email FROM person LIMIT 2;")
1981+
if err != nil {
1982+
t.Fatal(err)
1983+
}
1984+
defer rows2.Close()
1985+
1986+
i = 0
1987+
for rows2.Next() {
1988+
i++
1989+
if err = rows2.StructScan(&person); err != nil {
1990+
t.Fatal(err)
1991+
}
1992+
}
1993+
if i < 2 {
1994+
t.Errorf("[%s] Expected at least 2 records, got %d", db.DriverName(), i)
1995+
}
1996+
if rows.NextResultSet() {
1997+
t.Fatalf("[%s] Did not expected a second recordset", db.DriverName())
1998+
}
1999+
2000+
})
2001+
}

0 commit comments

Comments
 (0)