func()

in pkg/core/resources/store/pagination_store.go [64:132]


func (p *paginationStore) List(ctx context.Context, list model.ResourceList, optionsFunc ...ListOptionsFunc) error {
	opts := NewListOptions(optionsFunc...)

	// At least one of the following options is required to trigger the paginationStore to do work.
	// Otherwise, it delegates the request and returns early.
	if opts.FilterFunc == nil && opts.PageSize == 0 && opts.PageOffset == "" && !opts.Ordered && len(opts.ResourceKeys) == 0 {
		return p.delegate.List(ctx, list, optionsFunc...)
	}

	fullList, err := registry.Global().NewList(list.GetItemType())
	if err != nil {
		return err
	}

	err = p.delegate.List(ctx, fullList, optionsFunc...)
	if err != nil {
		return err
	}

	filteredList, err := registry.Global().NewList(list.GetItemType())
	if err != nil {
		return err
	}

	for _, item := range fullList.GetItems() {
		_, exists := opts.ResourceKeys[model.MetaToResourceKey(item.GetMeta())]
		if len(opts.ResourceKeys) > 0 && !exists {
			continue
		}
		if !opts.Filter(item) {
			continue
		}
		_ = filteredList.AddItem(item)
	}

	filteredItems := filteredList.GetItems()
	lenFilteredItems := len(filteredItems)
	sort.Sort(model.ByMeta(filteredItems))

	offset := 0
	pageSize := lenFilteredItems
	paginationEnabled := opts.PageSize != 0
	if paginationEnabled {
		pageSize = opts.PageSize
		if opts.PageOffset != "" {
			o, err := strconv.Atoi(opts.PageOffset)
			if err != nil {
				return ErrorInvalidOffset
			}
			offset = o
		}
	}

	for i := offset; i < offset+pageSize && i < lenFilteredItems; i++ {
		_ = list.AddItem(filteredItems[i])
	}

	if paginationEnabled {
		nextOffset := ""
		if offset+pageSize < lenFilteredItems { // set new offset only if we did not reach the end of the collection
			nextOffset = strconv.Itoa(offset + opts.PageSize)
		}
		list.GetPagination().SetNextOffset(nextOffset)
	}

	list.GetPagination().SetTotal(uint32(lenFilteredItems))

	return nil
}