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) }