Newer
Older
pokemon-go-trade / vendor / github.com / go-pg / pg / urlvalues / pager.go
package urlvalues

import (
	"github.com/go-pg/pg/orm"
)

type Pager struct {
	Limit  int
	Offset int

	// Default max limit is 1000.
	MaxLimit int
	// Default max offset is 1000000.
	MaxOffset int

	stickyErr error
}

func NewPager(values Values) *Pager {
	p := new(Pager)
	p.stickyErr = p.FromValues(values)
	return p
}

func (p *Pager) FromURLValues(values Values) error {
	return p.FromValues(Values(values))
}

func (p *Pager) FromValues(values Values) error {
	limit, err := values.Int("limit")
	if err != nil {
		return err
	}
	p.Limit = int(limit)

	page, err := values.Int("page")
	if err != nil {
		return err
	}
	p.SetPage(int(page))

	return nil
}

func (p *Pager) maxLimit() int {
	if p.MaxLimit > 0 {
		return p.MaxLimit
	}
	return 1000
}

func (p *Pager) maxOffset() int {
	if p.MaxOffset > 0 {
		return p.MaxOffset
	}
	return 1000000
}

func (p *Pager) GetLimit() int {
	const defaultLimit = 100

	if p == nil {
		return defaultLimit
	}
	if p.Limit < 0 {
		return p.Limit
	}
	if p.Limit == 0 {
		return defaultLimit
	}
	if p.Limit > p.maxLimit() {
		return p.maxLimit()
	}
	return p.Limit
}

func (p *Pager) GetOffset() int {
	if p == nil {
		return 0
	}
	if p.Offset > p.maxOffset() {
		return p.maxOffset()
	}
	return p.Offset
}

func (p *Pager) SetPage(page int) {
	if page < 1 {
		page = 1
	}
	p.Offset = (page - 1) * p.GetLimit()
}

func (p *Pager) GetPage() int {
	return (p.GetOffset() / p.GetLimit()) + 1
}

func (p *Pager) Pagination(q *orm.Query) (*orm.Query, error) {
	if p == nil {
		return q, nil
	}
	if p.stickyErr != nil {
		return nil, p.stickyErr
	}

	q = q.Limit(p.GetLimit()).Offset(p.GetOffset())
	return q, nil
}

// Pagination is used with Query.Apply to set LIMIT and OFFSET from the URL values:
//   - ?limit=10 - sets q.Limit(10), max limit is 1000.
//   - ?page=5 - sets q.Offset((page - 1) * limit), max offset is 1000000.
func Pagination(values Values) func(*orm.Query) (*orm.Query, error) {
	return NewPager(values).Pagination
}