AllRowsScanned return instead of break

Previous approach could cause panic in case loop broken by
developer and error occurred on rows.
This commit is contained in:
xobotyi 2025-01-24 20:29:58 +01:00
parent 812c9373f0
commit c89724d9e2

13
rows.go
View File

@ -667,18 +667,21 @@ func RowToAddrOfStructByNameLax[T any](row CollectableRow) (*T, error) {
return &value, err return &value, err
} }
// AllRowsScanned returns iterator that read and scans rows one-by-one. It closes // AllRowsScanned returns an iterator that reads and scans rows one-by-one. It automatically
// the rows automatically on return. // closes the rows when done.
// //
// In case rows.Err() returns non-nil error after all rows are read, it will // If rows.Err() returns a non-nil error after all rows are read, it will trigger an extra
// trigger extra yield with zero value and the error. // yield with a zero value and the error.
//
// If the caller's logic implies the possibility of an early loop break, rows.Err() should
// be checked after the loop.
func AllRowsScanned[T any](rows Rows, fn RowToFunc[T]) iter.Seq2[T, error] { func AllRowsScanned[T any](rows Rows, fn RowToFunc[T]) iter.Seq2[T, error] {
return func(yield func(T, error) bool) { return func(yield func(T, error) bool) {
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
if !yield(fn(rows)) { if !yield(fn(rows)) {
break return
} }
} }