-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathconstructsql_iterator.go
More file actions
53 lines (46 loc) · 1.06 KB
/
constructsql_iterator.go
File metadata and controls
53 lines (46 loc) · 1.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//go:build go1.23
package constructsql
import (
"errors"
"iter"
"log"
)
// IterateRows returns an iterator over the rows of a database query and scans them to T.
// If an error occurred initially, while scanning or closing, it returns a single-use iterator with the error.
// It returns a single-use iterator.
func IterateRows[T any](rows Rows, err error) iter.Seq2[T, error] {
if err != nil {
return func(yield func(T, error) bool) {
var result T
yield(result, err)
}
}
return func(yield func(T, error) bool) {
var err error
var iteratorClosed bool
defer func() {
closeErr := rows.Close()
err = errors.Join(err, closeErr)
if err != nil {
if iteratorClosed {
log.Printf("constructsql: Unhandled error after closing rows and function for loop body returned false: %v", err)
return
}
var result T
yield(result, err)
}
}()
var value T
for rows.Next() {
value, err = scanRow[T](rows)
if err != nil {
return
}
if !yield(value, nil) {
iteratorClosed = true
return
}
}
err = rows.Err()
}
}