types.go 3.5 KB
Newer Older
H
hongming 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
Copyright 2020 The KubeSphere Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

Z
zryfish 已提交
17 18 19 20
package query

import (
	"github.com/emicklei/go-restful"
H
hongming 已提交
21 22
	"k8s.io/apimachinery/pkg/labels"
	"kubesphere.io/kubesphere/pkg/utils/sliceutil"
Z
zryfish 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
	"strconv"
)

const (
	ParameterName          = "name"
	ParameterLabelSelector = "labelSelector"
	ParameterFieldSelector = "fieldSelector"
	ParameterPage          = "page"
	ParameterLimit         = "limit"
	ParameterOrderBy       = "sortBy"
	ParameterAscending     = "ascending"
)

// Query represents api search terms
type Query struct {
	Pagination *Pagination

	// sort result in which field, default to FieldCreationTimeStamp
	SortBy Field

	// sort result in ascending or descending order, default to descending
	Ascending bool

	//
H
hongming 已提交
47 48 49
	Filters map[Field]Value

	LabelSelector string
Z
zryfish 已提交
50 51 52 53 54 55
}

type Pagination struct {
	// items per page
	Limit int

H
hongming 已提交
56 57
	// offset
	Offset int
Z
zryfish 已提交
58 59
}

H
hongming 已提交
60
var NoPagination = newPagination(-1, 0)
Z
zryfish 已提交
61

H
hongming 已提交
62 63
// make sure that pagination is valid
func newPagination(limit int, offset int) *Pagination {
Z
zryfish 已提交
64
	return &Pagination{
H
hongming 已提交
65 66
		Limit:  limit,
		Offset: offset,
Z
zryfish 已提交
67 68 69
	}
}

H
hongming 已提交
70 71 72 73 74 75 76 77
func (q *Query) Selector() labels.Selector {
	if selector, err := labels.Parse(q.LabelSelector); err != nil {
		return labels.Everything()
	} else {
		return selector
	}
}

H
hongming 已提交
78
func (p *Pagination) GetValidPagination(total int) (startIndex, endIndex int) {
H
hongming 已提交
79

H
hongming 已提交
80
	// no pagination
H
hongming 已提交
81 82 83
	if p.Limit == NoPagination.Limit {
		return 0, total
	}
Z
zryfish 已提交
84

H
hongming 已提交
85 86
	// out of range
	if p.Limit < 0 || p.Offset < 0 || p.Offset > total {
H
hongming 已提交
87 88
		return 0, 0
	}
Z
zryfish 已提交
89

H
hongming 已提交
90
	startIndex = p.Offset
Z
zryfish 已提交
91 92 93 94 95 96 97 98 99 100 101
	endIndex = startIndex + p.Limit

	if endIndex > total {
		endIndex = total
	}

	return startIndex, endIndex
}

func New() *Query {
	return &Query{
H
hongming 已提交
102 103 104
		Pagination: NoPagination,
		SortBy:     "",
		Ascending:  false,
H
hongming 已提交
105
		Filters:    map[Field]Value{},
Z
zryfish 已提交
106 107 108 109 110
	}
}

type Filter struct {
	Field Field
H
hongming 已提交
111
	Value Value
Z
zryfish 已提交
112 113 114 115 116
}

func ParseQueryParameter(request *restful.Request) *Query {
	query := New()

H
hongming 已提交
117
	limit, err := strconv.Atoi(request.QueryParameter(ParameterLimit))
H
hongming 已提交
118
	// equivalent to undefined, use the default value
Z
zryfish 已提交
119
	if err != nil {
H
hongming 已提交
120
		limit = -1
Z
zryfish 已提交
121
	}
H
hongming 已提交
122
	page, err := strconv.Atoi(request.QueryParameter(ParameterPage))
H
hongming 已提交
123 124 125
	// equivalent to undefined, use the default value
	if err != nil {
		page = 1
Z
zryfish 已提交
126 127
	}

H
hongming 已提交
128
	query.Pagination = newPagination(limit, (page-1)*limit)
H
hongming 已提交
129

H
hongming 已提交
130
	query.SortBy = Field(defaultString(request.QueryParameter(ParameterOrderBy), FieldCreationTimeStamp))
Z
zryfish 已提交
131

H
hongming 已提交
132
	ascending, err := strconv.ParseBool(defaultString(request.QueryParameter(ParameterAscending), "false"))
Z
zryfish 已提交
133 134 135 136 137 138
	if err != nil {
		query.Ascending = false
	} else {
		query.Ascending = ascending
	}

H
hongming 已提交
139 140 141 142 143 144 145 146
	query.LabelSelector = request.QueryParameter(ParameterLabelSelector)

	for key, values := range request.Request.URL.Query() {
		if !sliceutil.HasString([]string{ParameterPage, ParameterLimit, ParameterOrderBy, ParameterAscending, ParameterLabelSelector}, key) {
			// support multiple query condition
			for _, value := range values {
				query.Filters[Field(key)] = Value(value)
			}
Z
zryfish 已提交
147 148 149 150 151 152 153 154 155 156 157 158
		}
	}

	return query
}

func defaultString(value, defaultValue string) string {
	if len(value) == 0 {
		return defaultValue
	}
	return value
}