package
0.4.6
Repository: https://github.com/tkeel-io/core-broker.git
Documentation: pkg.go.dev

# 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
}