paging

package module
v0.0.0-...-ad05c56 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2018 License: MIT Imports: 10 Imported by: 0

README

paging

A small set of utilities to paginate your data in Go.

Installation

$ go get github.com/ulule/paging

Usage

First, import the package:

import "github.com/ulule/paging"

Now, you can access the package through paging namespace.

There are two types of paginators:

  • OffsetPaginator: uses a database offset. Returns the total of elements.
  • CursorPaginator: uses a database condition like ID > ? or creation_date < ?. Does not return the total number of items but increases performances.

It works in four steps:

  • Create a store (which is basically where your entities are stored)
  • Create paginator options (or use default ones)
  • Create an OffsetPaginator or a CursorPaginator instance with: your store, the HTTP request, and options
  • Call the paginator.Page() method to process the pagination
  • Call the paginator.Previous() method to get the previous paginator instance. (Previous page isn't available for cursor pagination system)
  • Call the paginator.Next() method to get the next paginator instance

Example with OffsetPaginator and GORM:

// Before anything... create a slice for your GORM models.
// Let's assume we have 100 users in our database.
users := []User{}

// Step 1: create the store. It takes your database connection pointer, a
// pointer to models and the GORM "ORDER BY" string.
store, err := paging.NewGORMStore(&db, &users)
if err != nil {
        log.Fatal(err)
}

// Step 2: create options. Here, we use the default ones (see below).
options := paging.NewOptions()

// Step 3: create a paginator instance and pass your store, your current HTTP
// request and your options as arguments.
request, _ := http.NewRequest("GET", "http://example.com?limit=20&offset=0", nil)
paginator := paging.NewOffsetPaginator(store, request, options)

// Step 4: call the paginator.Page() method to get the page instance.
err := paginator.Page()
if err != nil {
        log.Fatal(err)
}

// Your paginator instance contains everything you need.
assert.True(int64(20), paginator.Limit)
assert.True(int64(0), paginator.Offset)
assert.True(int64(100), paginator.Count)
assert.False(paginator.PreviousURI.Valid) // It's a null string because no previous page
assert.True(paginator.NextURI.Valid)
assert.Equal( "?limit=20&offset=20", paginator.NextURI.String)

// And our "users" slice is now populated with 20 users ordered by name.
assert.Equal(20, len(users))

// Now get the next page.
nextPaginator, err := paginator.Next()
if err != nil {
        log.Fatal(err)
}

// Or the previous page.
previousPaginator, err := paginator.Previous()
if err != nil {
        log.Fatal(err)
}

Paginator options are:

  • DefaultLimit (int64): the number of items per page (defaults to 20)
  • MaxLimit (int64): the maximum limit that can be set (defaults to 20)
  • LimitKeyName (string): the query string key name for limit (defaults to limit)
  • OffsetKeyName (string): the query string key name for offset (defaults to offset)
  • CursorOptions.Mode (string): set type of cursor, an idCursor or a dateCursor (time.Time) (defaults to idCursor)
  • CursorOptions.KeyName (string): the query string key name for the cursor (defaults to since)
  • CursorOptions.DBName (string): the cursor's database column name (defaults to id)
  • CursorOptions.StructName (string): the cursor struct field name (defaults to ID)
  • CursorOptions.Reverse (bool): if true, order is reversed (DESC) (defaults to false)

Contributing

Documentation

Index

Constants

View Source
const (
	OffsetType = "offset"

	CursorType = "cursor"
)

pagination system type

View Source
const (
	DateModeCursor = "dateCursor"

	IDModeCursor = "idCursor"
)

cursor mode, date or id

View Source
const (
	// DefaultLimit is the default number of items per page.
	DefaultLimit = 20

	// DefaultLimitKeyName is the request key name.
	DefaultLimitKeyName = "limit"

	// DefaultOffsetKeyName is the request offset key name.
	DefaultOffsetKeyName = "offset"

	// DefaultCursorKeyName is the request cursor key name.
	DefaultCursorKeyName = "since"

	// DefaultCursorDBName is the default cursor db field name
	DefaultCursorDBName = "id"

	// DefaultCursorStructName is the default cursor struct field name
	DefaultCursorStructName = "ID"
)

Variables

View Source
var ErrInvalidLimitOrOffset = errors.New("invalid limit or offset")

ErrInvalidLimitOrOffset is returned by the OffsetPaginator's Page method to indicate that the limit or the offset is invalid

Functions

func GenerateCursorURI

func GenerateCursorURI(limit int64, cursor interface{}, options *Options) string

GenerateCursorURI generates the pagination URI for cursor system.

func GenerateOffsetURI

func GenerateOffsetURI(limit int64, offset int64, options *Options) string

GenerateOffsetURI generates the pagination URI.

func GetCursorFromRequest

func GetCursorFromRequest(request *http.Request, options *Options) int64

GetCursorFromRequest returns current cursor.

func GetLimitFromRequest

func GetLimitFromRequest(request *http.Request, options *Options) int64

GetLimitFromRequest returns current limit.

func GetOffsetFromRequest

func GetOffsetFromRequest(request *http.Request, options *Options) int64

GetOffsetFromRequest returns current offset.

func GetPaginationType

func GetPaginationType(request *http.Request, options *Options) string

GetPaginationType returns the pagination type "offeset|cursor" (use constant CursorType or OffsetType) return OffsetType by default

func Last

func Last(arr interface{}, field string) interface{}

Last gets the last element ID value of array.

func ValidateLimitOffset

func ValidateLimitOffset(limit int64, offset int64) bool

ValidateLimitOffset returns true if limit and offset values are valid

Types

type CursorOptions

type CursorOptions struct {
	// Mode set type of cursor, an ID or a Date (time.Time)
	Mode string
	// KeyName is the query string key name for the cursor
	KeyName string
	// DBName is the cursor's database column name
	DBName string
	// StructName is the cursor struct field name
	StructName string
	// Reverse turn true to work with DESC request
	Reverse bool
}

CursorOptions group all options about cursor pagination

type CursorPaginator

type CursorPaginator struct {
	Cursor      interface{} `json:"-"`
	PreviousURI null.String `json:"-"`
	// contains filtered or unexported fields
}

CursorPaginator is the paginator with cursor pagination system.

func NewCursorPaginator

func NewCursorPaginator(store Store, request *http.Request, options *Options) (*CursorPaginator, error)

NewCursorPaginator returns a new CursorPaginator instance.

func (CursorPaginator) HasNext

func (CursorPaginator) HasNext() bool

HasNext returns true if has next page.

func (CursorPaginator) HasPrevious

func (CursorPaginator) HasPrevious() bool

HasPrevious returns false, previous page is not available on cursor system

func (*CursorPaginator) MakeNextURI

func (p *CursorPaginator) MakeNextURI() null.String

MakeNextURI returns the next page URI.

func (CursorPaginator) MakePreviousURI

func (CursorPaginator) MakePreviousURI() null.String

MakePreviousURI returns an empty URI.

func (*CursorPaginator) Next

func (p *CursorPaginator) Next() (Paginator, error)

Next returns next items

func (*CursorPaginator) Page

func (p *CursorPaginator) Page() error

Page searches and returns the items

func (*CursorPaginator) Previous

func (p *CursorPaginator) Previous() (Paginator, error)

Previous is not available on cursor system

type GORMStore

type GORMStore struct {
	// contains filtered or unexported fields
}

GORMStore is the store for GORM ORM.

func NewGORMStore

func NewGORMStore(db *gorm.DB, items interface{}) (*GORMStore, error)

NewGORMStore returns a new GORM store instance.

func (*GORMStore) GetItems

func (s *GORMStore) GetItems() interface{}

GetItems return the current result

func (*GORMStore) PaginateCursor

func (s *GORMStore) PaginateCursor(limit int64, cursor interface{}, fieldName string, reverse bool) error

PaginateCursor paginates items from the store and update page instance for cursor pagination system. cursor can be an ID or a date (time.Time)

func (*GORMStore) PaginateOffset

func (s *GORMStore) PaginateOffset(limit, offset int64) (int64, error)

PaginateOffset paginates items from the store and update page instance.

type MGOStore

type MGOStore struct {
	// contains filtered or unexported fields
}

MGOStore is the store for mongodb

func NewMGOStore

func NewMGOStore(collection *mgo.Collection, items interface{}, filter bson.M) (*MGOStore, error)

NewMGOStore returns a new mongo store

func (*MGOStore) GetItems

func (m *MGOStore) GetItems() interface{}

GetItems return the current result

func (*MGOStore) PaginateCursor

func (m *MGOStore) PaginateCursor(limit int64, cursor interface{}, fieldName string, reverse bool) error

PaginateCursor paginates items from the store and update page instance for cursor pagination system. cursor can be an ID or a date (time.Time)

func (*MGOStore) PaginateOffset

func (m *MGOStore) PaginateOffset(limit, offset int64) (int64, error)

PaginateOffset paginates items from the store and update page instance.

type OffsetPaginator

type OffsetPaginator struct {
	Offset      int64       `json:"offset"`
	Count       int64       `json:"total_count"`
	PreviousURI null.String `json:"previous"`
	// contains filtered or unexported fields
}

OffsetPaginator is the paginator with offset pagination system.

func NewOffsetPaginator

func NewOffsetPaginator(store Store, request *http.Request, options *Options) (*OffsetPaginator, error)

NewOffsetPaginator returns a new OffsetPaginator instance.

func (*OffsetPaginator) HasNext

func (p *OffsetPaginator) HasNext() bool

HasNext returns true if has next page.

func (*OffsetPaginator) HasPrevious

func (p *OffsetPaginator) HasPrevious() bool

HasPrevious returns true if there is a previous page.

func (*OffsetPaginator) MakeNextURI

func (p *OffsetPaginator) MakeNextURI() null.String

MakeNextURI returns the next page URI.

func (*OffsetPaginator) MakePreviousURI

func (p *OffsetPaginator) MakePreviousURI() null.String

MakePreviousURI returns the previous page URI.

func (*OffsetPaginator) Next

func (p *OffsetPaginator) Next() (Paginator, error)

Next returns next items

func (*OffsetPaginator) Page

func (p *OffsetPaginator) Page() error

Page searches and returns the items

func (*OffsetPaginator) Previous

func (p *OffsetPaginator) Previous() (Paginator, error)

Previous returns previous items

type Options

type Options struct {
	// DefaultLimit is the default number of items per page
	DefaultLimit int64
	// MaxLimit is the maximum limit that can be set
	MaxLimit int64
	// LimitKeyName is the query string key name for the limit
	LimitKeyName string
	// OffsetKeyName is the query string key name for the offset
	OffsetKeyName string
	// CursorOptions
	CursorOptions *CursorOptions
}

Options are paginator options

func NewOptions

func NewOptions() *Options

NewOptions returns defaults options

type Paginator

type Paginator interface {
	Page() error
	Previous() (Paginator, error)
	Next() (Paginator, error)
	HasPrevious() bool
	HasNext() bool
	MakePreviousURI() null.String
	MakeNextURI() null.String
}

Paginator is a paginator interface.

type Store

type Store interface {
	PaginateOffset(limit, offset int64) (int64, error)
	PaginateCursor(limit int64, cursor interface{}, fieldName string, reverse bool) error
	GetItems() interface{}
}

Store is a store.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL