Monorepo for Tangled
Something went wrong. Try again.
1.3 kB · 74 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475package db
import ( "database/sql" "fmt")
const ( ListDefaultLimit = 50 ListMaxLimit = 1000)
type ListPage struct { Limit int Cursor *int Desc bool}
func (p ListPage) limit() int { switch { case p.Limit <= 0: return ListDefaultLimit case p.Limit > ListMaxLimit: return ListMaxLimit default: return p.Limit }}
func (p ListPage) clause() (string, []any) { dir, cmp := "asc", ">" if p.Desc { dir, cmp = "desc", "<" } if p.Cursor != nil { return fmt.Sprintf("where id %s ? order by id %s limit ?", cmp, dir), []any{*p.Cursor, p.limit() + 1} } return fmt.Sprintf("order by id %s limit ?", dir), []any{p.limit() + 1}}
func listPaged[T any]( q DBTX, query string, args []any, p ListPage, scan func(*sql.Rows) (T, error), idOf func(T) int,) ([]T, *int, error) { clause, pArgs := p.clause() rows, err := q.Query("select * from ("+query+") "+clause, append(args, pArgs...)...) if err != nil { return nil, nil, err } defer rows.Close()
out := []T{} for rows.Next() { v, err := scan(rows) if err != nil { return nil, nil, err } out = append(out, v) } if err := rows.Err(); err != nil { return nil, nil, err }
if limit := p.limit(); len(out) > limit { out = out[:limit] last := idOf(out[len(out)-1]) return out, &last, nil } return out, nil, nil}