Merge pull request #9654 from heww/fix-qutoa-order-by

fix(quota): order by quotas only on support resources
This commit is contained in:
Wenkai Yin(尹文开) 2019-10-30 17:20:17 +08:00 committed by GitHub
commit 5d6cbe9aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 9 deletions

View File

@ -220,12 +220,15 @@ func quotaOrderBy(query ...*models.QuotaQuery) string {
sort = sort[1:] sort = sort[1:]
} }
prefix := []string{"hard.", "used."} prefixes := []string{"hard.", "used."}
for _, p := range prefix { for _, prefix := range prefixes {
if strings.HasPrefix(sort, p) { if strings.HasPrefix(sort, prefix) {
field := fmt.Sprintf("%s->>'%s'", strings.TrimSuffix(p, "."), strings.TrimPrefix(sort, p)) resource := strings.TrimPrefix(sort, prefix)
orderBy = fmt.Sprintf("(%s) %s", castQuantity(field), order) if types.IsValidResource(types.ResourceName(resource)) {
break field := fmt.Sprintf("%s->>'%s'", strings.TrimSuffix(prefix, "."), resource)
orderBy = fmt.Sprintf("(%s) %s", castQuantity(field), order)
break
}
} }
} }
} }

View File

@ -141,3 +141,36 @@ func (suite *QuotaDaoSuite) TestListQuotas() {
func TestRunQuotaDaoSuite(t *testing.T) { func TestRunQuotaDaoSuite(t *testing.T) {
suite.Run(t, new(QuotaDaoSuite)) suite.Run(t, new(QuotaDaoSuite))
} }
func Test_quotaOrderBy(t *testing.T) {
query := func(sort string) []*models.QuotaQuery {
return []*models.QuotaQuery{
{Sorting: models.Sorting{Sort: sort}},
}
}
type args struct {
query []*models.QuotaQuery
}
tests := []struct {
name string
args args
want string
}{
{"no query", args{nil}, "b.creation_time DESC"},
{"order by unsupport field", args{query("unknow")}, "b.creation_time DESC"},
{"order by count of hard", args{query("hard.count")}, "(CAST( (CASE WHEN (hard->>'count') IS NULL THEN '0' WHEN (hard->>'count') = '-1' THEN '9223372036854775807' ELSE (hard->>'count') END) AS BIGINT )) ASC"},
{"order by storage of hard", args{query("hard.storage")}, "(CAST( (CASE WHEN (hard->>'storage') IS NULL THEN '0' WHEN (hard->>'storage') = '-1' THEN '9223372036854775807' ELSE (hard->>'storage') END) AS BIGINT )) ASC"},
{"order by unsupport hard resource", args{query("hard.unknow")}, "b.creation_time DESC"},
{"order by count of used", args{query("used.count")}, "(CAST( (CASE WHEN (used->>'count') IS NULL THEN '0' WHEN (used->>'count') = '-1' THEN '9223372036854775807' ELSE (used->>'count') END) AS BIGINT )) ASC"},
{"order by storage of used", args{query("used.storage")}, "(CAST( (CASE WHEN (used->>'storage') IS NULL THEN '0' WHEN (used->>'storage') = '-1' THEN '9223372036854775807' ELSE (used->>'storage') END) AS BIGINT )) ASC"},
{"order by unsupport used resource", args{query("used.unknow")}, "b.creation_time DESC"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := quotaOrderBy(tt.args.query...); got != tt.want {
t.Errorf("quotaOrderBy() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -21,6 +21,7 @@ import (
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/pkg/types"
) )
var ( var (
@ -127,15 +128,19 @@ func quotaUsageOrderBy(query ...*models.QuotaUsageQuery) string {
} else { } else {
sort := query[0].Sort sort := query[0].Sort
order := "asc" order := "ASC"
if sort[0] == '-' { if sort[0] == '-' {
order = "desc" order = "DESC"
sort = sort[1:] sort = sort[1:]
} }
prefix := "used." prefix := "used."
if strings.HasPrefix(sort, prefix) { if strings.HasPrefix(sort, prefix) {
orderBy = fmt.Sprintf("used->>'%s' %s", strings.TrimPrefix(sort, prefix), order) resource := strings.TrimPrefix(sort, prefix)
if types.IsValidResource(types.ResourceName(resource)) {
field := fmt.Sprintf("%s->>'%s'", strings.TrimSuffix(prefix, "."), resource)
orderBy = fmt.Sprintf("(%s) %s", castQuantity(field), order)
}
} }
} }
} }

View File

@ -133,3 +133,33 @@ func (suite *QuotaUsageDaoSuite) TestListQuotaUsages() {
func TestRunQuotaUsageDaoSuite(t *testing.T) { func TestRunQuotaUsageDaoSuite(t *testing.T) {
suite.Run(t, new(QuotaUsageDaoSuite)) suite.Run(t, new(QuotaUsageDaoSuite))
} }
func Test_quotaUsageOrderBy(t *testing.T) {
query := func(sort string) []*models.QuotaUsageQuery {
return []*models.QuotaUsageQuery{
{Sorting: models.Sorting{Sort: sort}},
}
}
type args struct {
query []*models.QuotaUsageQuery
}
tests := []struct {
name string
args args
want string
}{
{"no query", args{nil}, ""},
{"order by unsupport field", args{query("unknow")}, ""},
{"order by count of used", args{query("used.count")}, "(CAST( (CASE WHEN (used->>'count') IS NULL THEN '0' WHEN (used->>'count') = '-1' THEN '9223372036854775807' ELSE (used->>'count') END) AS BIGINT )) ASC"},
{"order by storage of used", args{query("used.storage")}, "(CAST( (CASE WHEN (used->>'storage') IS NULL THEN '0' WHEN (used->>'storage') = '-1' THEN '9223372036854775807' ELSE (used->>'storage') END) AS BIGINT )) ASC"},
{"order by unsupport used resource", args{query("used.unknow")}, ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := quotaUsageOrderBy(tt.args.query...); got != tt.want {
t.Errorf("quotaUsageOrderBy() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -135,3 +135,13 @@ func IsNegative(a ResourceList) []ResourceName {
} }
return results return results
} }
// IsValidResource returns true when resource was supported
func IsValidResource(resource ResourceName) bool {
switch resource {
case ResourceCount, ResourceStorage:
return true
default:
return false
}
}