github.com/dkishere/pop@v4.13.1+incompatible/paginator.go (about)

     1  package pop
     2  
     3  import (
     4  	"encoding/json"
     5  	"strconv"
     6  
     7  	"github.com/gobuffalo/pop/internal/defaults"
     8  )
     9  
    10  // PaginatorPerPageDefault is the amount of results per page
    11  var PaginatorPerPageDefault = 20
    12  
    13  // PaginatorPageKey is the query parameter holding the current page index
    14  var PaginatorPageKey = "page"
    15  
    16  // PaginatorPerPageKey is the query parameter holding the amount of results per page
    17  // to override the default one
    18  var PaginatorPerPageKey = "per_page"
    19  
    20  type paginable interface {
    21  	Paginate() string
    22  }
    23  
    24  var _ paginable = Paginator{}
    25  
    26  // Paginator is a type used to represent the pagination of records
    27  // from the database.
    28  type Paginator struct {
    29  	// Current page you're on
    30  	Page int `json:"page"`
    31  	// Number of results you want per page
    32  	PerPage int `json:"per_page"`
    33  	// Page * PerPage (ex: 2 * 20, Offset == 40)
    34  	Offset int `json:"offset"`
    35  	// Total potential records matching the query
    36  	TotalEntriesSize int `json:"total_entries_size"`
    37  	// Total records returns, will be <= PerPage
    38  	CurrentEntriesSize int `json:"current_entries_size"`
    39  	// Total pages
    40  	TotalPages int `json:"total_pages"`
    41  }
    42  
    43  // Paginate implements the paginable interface.
    44  func (p Paginator) Paginate() string {
    45  	b, _ := json.Marshal(p)
    46  	return string(b)
    47  }
    48  
    49  func (p Paginator) String() string {
    50  	return p.Paginate()
    51  }
    52  
    53  // NewPaginator returns a new `Paginator` value with the appropriate
    54  // defaults set.
    55  func NewPaginator(page int, perPage int) *Paginator {
    56  	if page < 1 {
    57  		page = 1
    58  	}
    59  	if perPage < 1 {
    60  		perPage = 20
    61  	}
    62  	p := &Paginator{Page: page, PerPage: perPage}
    63  	p.Offset = (page - 1) * p.PerPage
    64  	return p
    65  }
    66  
    67  // PaginationParams is a parameters provider interface to get the pagination params from
    68  type PaginationParams interface {
    69  	Get(key string) string
    70  }
    71  
    72  // NewPaginatorFromParams takes an interface of type `PaginationParams`,
    73  // the `url.Values` type works great with this interface, and returns
    74  // a new `Paginator` based on the params or `PaginatorPageKey` and
    75  // `PaginatorPerPageKey`. Defaults are `1` for the page and
    76  // PaginatorPerPageDefault for the per page value.
    77  func NewPaginatorFromParams(params PaginationParams) *Paginator {
    78  	page := defaults.String(params.Get("page"), "1")
    79  
    80  	perPage := defaults.String(params.Get("per_page"), strconv.Itoa(PaginatorPerPageDefault))
    81  
    82  	p, err := strconv.Atoi(page)
    83  	if err != nil {
    84  		p = 1
    85  	}
    86  
    87  	pp, err := strconv.Atoi(perPage)
    88  	if err != nil {
    89  		pp = PaginatorPerPageDefault
    90  	}
    91  	return NewPaginator(p, pp)
    92  }
    93  
    94  // Paginate records returned from the database.
    95  //
    96  //	q := c.Paginate(2, 15)
    97  //	q.All(&[]User{})
    98  //	q.Paginator
    99  func (c *Connection) Paginate(page int, perPage int) *Query {
   100  	return Q(c).Paginate(page, perPage)
   101  }
   102  
   103  // Paginate records returned from the database.
   104  //
   105  //	q = q.Paginate(2, 15)
   106  //	q.All(&[]User{})
   107  //	q.Paginator
   108  func (q *Query) Paginate(page int, perPage int) *Query {
   109  	q.Paginator = NewPaginator(page, perPage)
   110  	return q
   111  }
   112  
   113  // PaginateFromParams paginates records returned from the database.
   114  //
   115  //	q := c.PaginateFromParams(req.URL.Query())
   116  //	q.All(&[]User{})
   117  //	q.Paginator
   118  func (c *Connection) PaginateFromParams(params PaginationParams) *Query {
   119  	return Q(c).PaginateFromParams(params)
   120  }
   121  
   122  // PaginateFromParams paginates records returned from the database.
   123  //
   124  //	q = q.PaginateFromParams(req.URL.Query())
   125  //	q.All(&[]User{})
   126  //	q.Paginator
   127  func (q *Query) PaginateFromParams(params PaginationParams) *Query {
   128  	q.Paginator = NewPaginatorFromParams(params)
   129  	return q
   130  }