pagination

package
v0.4.6 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2022 License: Apache-2.0 Imports: 8 Imported by: 1

README

Usage example

import "github.com/tkeel.io/kit/pagination"


func (s *SubscribeService) ListSubscribeEntities(ctx context.Context, req *pb.ListSubscribeEntitiesRequest) (*pb.ListSubscribeEntitiesResponse, error) {
    page, err := pagination.Parse(req)
    
	// {Num:10 Size:50 OrderBy:test IsDescending:true KeyWords:key SearchKey:search}
    fmt.Println(page)

    // for example query like an ORM operator 
	query := DB.Query()
	
	if page.Requried {
		cond, fields := page.SearchCondition()
    if cond != nil {
		query.Where(cond)
	}
	if fields != nil {
        query.Select(fields...)
    }
	}
		// Do paginate here
        query.Limit(page.Limit())
        query.Offset(page.Offset())

	} else {
		// Query all date here
    }
	// Query data here
	data := query.Find()
	
	// count all after remove Offset and Limit
	count := query.Offset(-1).Limit(-1).Count()
	
	resp := &pb.ListSubscribeEntitiesResponse{}
    resp.Data = data
	
	// Fill Response Page Fields
    page.FillResponse(resp, count)
}

func Required

Used to determine if the paging request passed meets the paging needs

Judgement conditions:

func (p Page) Required() bool {
	return p.Num > 0 && p.Size > 0
}

func Limit

if no limit set this will return the default value.

func (p Page) Limit() uint32 {
	if p.Size != 0 {
		return uint32(p.Size)
	}

	return uint32(p.defaultSize)
}

func Offset

count the offset of the current page

func (p Page) Offset() uint32 {
	if p.Num <= 0 {
		return 0
	}
	return uint32((p.Num - 1) * p.Size)
}

func SearchCondition

return a map[string]string for the search condition and a []string for the search fields.

iIf the search have no condition or fields required, return nil

func (p Page) SearchCondition() (map[string]string, []string) {
    var values []string
    var keys []string
    if len(p.KeyWords) != 0 {
        values = strings.Split(p.KeyWords, p.defaultSeparator)
    }
    if len(p.SearchKey) != 0 {
        keys = strings.Split(p.SearchKey, p.defaultSeparator)
    }

    valLen := len(values)
    cond := make(map[string]string, valLen)
    fields := make([]string, 0, len(keys)-valLen)
    for i := range keys {
        if i < valLen {
            value := strings.TrimSpace(values[i])
            cond[keys[i]] = value
        } else {
            value := strings.TrimSpace(keys[i])
            fields = append(fields, value)
        }
    }

    if len(fields) == 0 {
        fields = nil
    }

    if len(cond) == 0 {
        cond = nil
    }

    return cond, fields
}
Usage

    cond, fields := page.SearchCondition()
    if cond != nil {
        query = query.Where(cond)
    }
    if fields != nil {
        query = query.Select(fields...)
    }

func FillResponse

Automatic padding of paginated data to match paginated responsive design.


func (p Page) FillResponse(resp interface{}) error {
    if p.Total == 0 {
        return ErrNoTotal
    }

    t := reflect.TypeOf(resp)
    v := reflect.ValueOf(resp)
    for t.Kind() != reflect.Struct {
        switch t.Kind() {
        case reflect.Ptr:
            v = v.Elem()
            t = t.Elem()
        default:
            return ErrInvalidResponse
        }
    }

    for i := 0; i < v.NumField(); i++ {
        if v.Field(i).CanInterface() {
            switch t.Field(i).Name {
            case "Total":
                v.Field(i).SetUint(uint64(p.Total))
            case "PageNum":
                v.Field(i).SetUint(uint64(p.Num))
            case "LastPage":
                if p.Size == 0 {
                    v.Field(i).SetUint(uint64(0))
                    continue
                }
                lastPage := p.Total / p.Size
                if p.Total%p.Size == 0 {
                    v.Field(i).SetUint(uint64(lastPage))
                    continue
                }
                v.Field(i).SetUint(uint64(lastPage + 1))
				
            case "PageSize":
                if p.Size == 0 {
                    v.Field(i).SetUint(uint64(p.Total))
                    continue
                }
                v.Field(i).SetUint(uint64(p.Size))
            }
        }
    }
    return nil
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidPageNum      = errors.New("invalid page number")
	ErrInvalidPageSize     = errors.New("invalid page size")
	ErrInvalidOrderBy      = errors.New("invalid order")
	ErrInvalidKeyWords     = errors.New("invalid key words")
	ErrInvalidSearchKey    = errors.New("invalid search key")
	ErrInvalidIsDescending = errors.New("invalid is descending")
	ErrInvalidParseData    = errors.New("invalid data type parsing")
	ErrInvalidResponse     = errors.New("invalid response")
)
View Source
var File_api_subscribe_v1_list_proto protoreflect.FileDescriptor

Functions

This section is empty.

Types

type ListRequest

type ListRequest struct {
	PageNum      uint64 `protobuf:"varint,1,opt,name=page_num,json=pageNum,proto3" json:"page_num,omitempty"`
	PageSize     uint64 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
	OrderBy      string `protobuf:"bytes,3,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
	IsDescending bool   `protobuf:"varint,4,opt,name=is_descending,json=isDescending,proto3" json:"is_descending,omitempty"`
	KeyWords     string `protobuf:"bytes,5,opt,name=key_words,json=keyWords,proto3" json:"key_words,omitempty"`
	SearchKey    string `protobuf:"bytes,6,opt,name=search_key,json=searchKey,proto3" json:"search_key,omitempty"`
	//user define
	PacketId int64 `protobuf:"varint,10,opt,name=packet_id,json=packetId,proto3" json:"packet_id,omitempty"`
	// contains filtered or unexported fields
}

func (*ListRequest) Descriptor deprecated

func (*ListRequest) Descriptor() ([]byte, []int)

Deprecated: Use ListRequest.ProtoReflect.Descriptor instead.

func (*ListRequest) GetIsDescending

func (x *ListRequest) GetIsDescending() bool

func (*ListRequest) GetKeyWords

func (x *ListRequest) GetKeyWords() string

func (*ListRequest) GetOrderBy

func (x *ListRequest) GetOrderBy() string

func (*ListRequest) GetPacketId

func (x *ListRequest) GetPacketId() int64

func (*ListRequest) GetPageNum

func (x *ListRequest) GetPageNum() uint64

func (*ListRequest) GetPageSize

func (x *ListRequest) GetPageSize() uint64

func (*ListRequest) GetSearchKey

func (x *ListRequest) GetSearchKey() string

func (*ListRequest) ProtoMessage

func (*ListRequest) ProtoMessage()

func (*ListRequest) ProtoReflect

func (x *ListRequest) ProtoReflect() protoreflect.Message

func (*ListRequest) Reset

func (x *ListRequest) Reset()

func (*ListRequest) String

func (x *ListRequest) String() string

type ListResponse

type ListResponse struct {
	Total    uint64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
	PageNum  uint64 `protobuf:"varint,2,opt,name=page_num,json=pageNum,proto3" json:"page_num,omitempty"`
	LastPage uint64 `protobuf:"varint,3,opt,name=last_page,json=lastPage,proto3" json:"last_page,omitempty"`
	PageSize uint64 `protobuf:"varint,4,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
	//user define
	PacketId uint64 `protobuf:"varint,10,opt,name=packet_id,json=packetId,proto3" json:"packet_id,omitempty"`
	// contains filtered or unexported fields
}

func (*ListResponse) Descriptor deprecated

func (*ListResponse) Descriptor() ([]byte, []int)

Deprecated: Use ListResponse.ProtoReflect.Descriptor instead.

func (*ListResponse) GetLastPage

func (x *ListResponse) GetLastPage() uint64

func (*ListResponse) GetPacketId

func (x *ListResponse) GetPacketId() uint64

func (*ListResponse) GetPageNum

func (x *ListResponse) GetPageNum() uint64

func (*ListResponse) GetPageSize

func (x *ListResponse) GetPageSize() uint64

func (*ListResponse) GetTotal

func (x *ListResponse) GetTotal() uint64

func (*ListResponse) ProtoMessage

func (*ListResponse) ProtoMessage()

func (*ListResponse) ProtoReflect

func (x *ListResponse) ProtoReflect() protoreflect.Message

func (*ListResponse) Reset

func (x *ListResponse) Reset()

func (*ListResponse) String

func (x *ListResponse) String() string

type Option

type Option func(*Page) error

func WithDefaultSeparator

func WithDefaultSeparator(separator string) Option

func WithDefaultSize

func WithDefaultSize(size uint) Option

type Page

type Page struct {
	Num          uint
	Size         uint
	OrderBy      string
	IsDescending bool
	KeyWords     string
	SearchKey    string
	Total        uint
	// contains filtered or unexported fields
}

func Parse

func Parse(req interface{}, options ...Option) (Page, error)

Parse a struct which have defined Page fields.

func (Page) FillResponse

func (p Page) FillResponse(resp interface{}) error

func (Page) Limit

func (p Page) Limit() uint32

func (Page) Offset

func (p Page) Offset() uint32

func (Page) Required

func (p Page) Required() bool

func (Page) SearchCondition

func (p Page) SearchCondition() (map[string]string, []string)

func (*Page) SetTotal

func (p *Page) SetTotal(total uint)

Jump to

Keyboard shortcuts

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