support "range over function" in Go 1.22

This commit is contained in:
Qishuai Liu 2024-05-30 17:33:24 +09:00
parent 33af7416b4
commit 9acd4ccf7c
No known key found for this signature in database
3 changed files with 59 additions and 0 deletions

View File

@ -8,6 +8,11 @@ import (
"time"
)
// Scanner is the interface that wraps the Scan method.
type Scanner interface {
Scan(dest ...interface{}) error
}
// Cursor is the interface of a row cursor.
type Cursor interface {
Next() bool

View File

@ -136,6 +136,7 @@ type toSelectFinal interface {
FetchExactlyOne(out ...interface{}) error
FetchAll(dest ...interface{}) (rows int, err error)
FetchCursor() (Cursor, error)
FetchSeq() func(yield func(row Scanner) bool) // use with "range over function" in Go 1.22
}
type join struct {
@ -164,6 +165,31 @@ type selectStatus struct {
lock string
}
type errorScanner struct {
err error
}
func (e errorScanner) Scan(dest ...interface{}) error {
return e.err
}
func (s selectStatus) FetchSeq() func(yield func(row Scanner) bool) {
return func(yield func(row Scanner) bool) {
cursor, err := s.FetchCursor()
if err != nil {
yield(errorScanner{err})
return
}
defer cursor.Close()
for cursor.Next() {
if !yield(cursor) {
break
}
}
}
}
type unionSelectStatus struct {
base selectBase
all bool

View File

@ -222,6 +222,34 @@ func TestFetchAll(t *testing.T) {
}
}
func TestRangeFunc(t *testing.T) {
db := newMockDatabase()
oldColumnCount := sharedMockConn.columnCount
sharedMockConn.columnCount = 2
defer func() {
sharedMockConn.columnCount = oldColumnCount
}()
count := 0
seq := db.Select(field1, field2).From(Table1).FetchSeq()
// for row := range db.Select(field1, field2).From(Table1).FetchSeq() {}
seq(func(row Scanner) bool {
var f1 string
var f2 int
if err := row.Scan(&f1, &f2); err != nil {
t.Error(err)
}
count++
return true
})
if count != 10 {
t.Error(count)
}
}
func TestLock(t *testing.T) {
db := newMockDatabase()
table1 := NewTable("table1")