21
0
Fork 0
goext/sq/list.go

49 lines
1.4 KiB
Go

package sq
import (
"context"
"fmt"
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
)
func Iterate[TData any](ctx context.Context, q Queryable, table string, filter PaginateFilter, scanMode StructScanMode, scanSec StructScanSafety, page int, limit *int, consumer func(ctx context.Context, v TData) error) (int, error) {
if filter == nil {
filter = NewEmptyPaginateFilter()
}
prepParams := PP{}
sortOrder := filter.Sort()
sortCond := ""
if len(sortOrder) > 0 {
sortCond = "ORDER BY "
for i, v := range sortOrder {
if i > 0 {
sortCond += ", "
}
sortCond += v.Field + " " + string(v.Direction)
}
}
pageCond := ""
if limit != nil {
pageCond += fmt.Sprintf("LIMIT :%s OFFSET :%s", prepParams.Add(*limit+1), prepParams.Add(*limit*(page-1)))
}
filterCond, joinCond, joinTables := filter.SQL(prepParams)
selectCond := table + ".*"
for _, v := range joinTables {
selectCond += ", " + v + ".*"
}
sqlQueryData := "SELECT " + selectCond + " FROM " + table + " " + joinCond + " WHERE ( " + filterCond + " ) " + sortCond + " " + pageCond
rows, err := q.Query(ctx, sqlQueryData, prepParams)
if err != nil {
return 0, exerr.Wrap(err, "failed to list paginated entries from DB").Str("table", table).Any("filter", filter).Int("page", page).Any("limit", limit).Build()
}
return IterateAll[TData](ctx, q, rows, scanMode, scanSec, true, consumer)
}