Support repo list sorting

Signed-off-by: 陈德 <chende@caicloud.io>
This commit is contained in:
陈德 2018-08-28 18:11:03 +08:00
parent 8b6a17e395
commit 666bd692fe
5 changed files with 61 additions and 9 deletions

View File

@ -894,8 +894,9 @@ paths:
get: get:
summary: Get repositories accompany with relevant project and repo name. summary: Get repositories accompany with relevant project and repo name.
description: > description: >
This endpoint let user search repositories accompanying with relevant This endpoint lets user search repositories accompanying with relevant
project ID and repo name. project ID and repo name. Repositories can be sorted by repo name, creation_time,
update_time in either ascending or descending order.
parameters: parameters:
- name: project_id - name: project_id
in: query in: query
@ -908,6 +909,13 @@ paths:
type: string type: string
required: false required: false
description: Repo name for filtering results. description: Repo name for filtering results.
- name: sort
in: query
type: string
required: false
description: >
Sort method, valid values include: 'name', '-name', 'creation_time', '-creation_time',
'update_time', '-update_time'. Here '-' stands for descending order.
- name: label_id - name: label_id
in: query in: query
type: integer type: integer

View File

@ -22,6 +22,18 @@ import (
"github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/models"
) )
var orderMap = map[string]string {
"name": "name asc",
"+name": "name asc",
"-name": "name desc",
"creation_time": "creation_time asc",
"+creation_time": "creation_time asc",
"-creation_time": "creation_time desc",
"update_time": "update_time asc",
"+update_time": "update_time asc",
"-update_time": "update_time desc",
}
// AddRepository adds a repo to the database. // AddRepository adds a repo to the database.
func AddRepository(repo models.RepoRecord) error { func AddRepository(repo models.RepoRecord) error {
if repo.ProjectID == 0 { if repo.ProjectID == 0 {
@ -116,10 +128,16 @@ func GetTotalOfRepositories(query ...*models.RepositoryQuery) (int64, error) {
// GetRepositories ... // GetRepositories ...
func GetRepositories(query ...*models.RepositoryQuery) ([]*models.RepoRecord, error) { func GetRepositories(query ...*models.RepositoryQuery) ([]*models.RepoRecord, error) {
repositories := []*models.RepoRecord{} repositories := []*models.RepoRecord{}
order := "name asc"
if len(query) > 0 && query[0] != nil {
if s, ok := orderMap[query[0].Sort]; ok {
order = s
}
}
sql, params := repositoryQueryConditions(query...) condition, params := repositoryQueryConditions(query...)
sql = `select r.repository_id, r.name, r.project_id, r.description, r.pull_count, sql := fmt.Sprintf(`select r.repository_id, r.name, r.project_id, r.description, r.pull_count,
r.star_count, r.creation_time, r.update_time ` + sql + `order by r.name ` r.star_count, r.creation_time, r.update_time %s order by r.%s `, condition, order)
if len(query) > 0 && query[0] != nil { if len(query) > 0 && query[0] != nil {
page, size := query[0].Page, query[0].Size page, size := query[0].Page, query[0].Size
if size > 0 { if size > 0 {

View File

@ -125,7 +125,7 @@ type ProjectQueryParam struct {
ProjectIDs []int64 // project ID list ProjectIDs []int64 // project ID list
} }
// MemberQuery fitler by member's username and role // MemberQuery filter by member's username and role
type MemberQuery struct { type MemberQuery struct {
Name string // the username of member Name string // the username of member
Role int // the role of the member has to the project Role int // the role of the member has to the project
@ -138,6 +138,11 @@ type Pagination struct {
Size int64 Size int64
} }
// Sorting sort by given field, ascending or descending
type Sorting struct {
Sort string // in format [+-]?<FIELD_NAME>, e.g. '+creation_time', '-creation_time'
}
// BaseProjectCollection contains the query conditions which can be used // BaseProjectCollection contains the query conditions which can be used
// to get a project collection. The collection can be used as the base to // to get a project collection. The collection can be used as the base to
// do other filter // do other filter

View File

@ -45,4 +45,5 @@ type RepositoryQuery struct {
ProjectName string ProjectName string
LabelID int64 LabelID int64
Pagination Pagination
Sorting
} }

View File

@ -19,6 +19,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -49,6 +50,7 @@ type RepositoryAPI struct {
type repoResp struct { type repoResp struct {
ID int64 `json:"id"` ID int64 `json:"id"`
Index int `json:"-"`
Name string `json:"name"` Name string `json:"name"`
ProjectID int64 `json:"project_id"` ProjectID int64 `json:"project_id"`
Description string `json:"description"` Description string `json:"description"`
@ -60,6 +62,20 @@ type repoResp struct {
UpdateTime time.Time `json:"update_time"` UpdateTime time.Time `json:"update_time"`
} }
type reposSorter []*repoResp
func (r reposSorter) Len() int {
return len(r)
}
func (r reposSorter) Swap(i, j int) {
r[i], r[j] = r[j], r[i]
}
func (r reposSorter) Less(i, j int) bool {
return r[i].Index < r[j].Index
}
type tagDetail struct { type tagDetail struct {
Digest string `json:"digest"` Digest string `json:"digest"`
Name string `json:"name"` Name string `json:"name"`
@ -129,6 +145,7 @@ func (ra *RepositoryAPI) Get() {
LabelID: labelID, LabelID: labelID,
} }
query.Page, query.Size = ra.GetPaginationParams() query.Page, query.Size = ra.GetPaginationParams()
query.Sort = ra.GetString("sort")
total, err := dao.GetTotalOfRepositories(query) total, err := dao.GetTotalOfRepositories(query)
if err != nil { if err != nil {
@ -159,8 +176,8 @@ func getRepositories(query *models.RepositoryQuery) ([]*repoResp, error) {
func assembleReposInParallel(repositories []*models.RepoRecord) []*repoResp { func assembleReposInParallel(repositories []*models.RepoRecord) []*repoResp {
c := make(chan *repoResp) c := make(chan *repoResp)
for _, repository := range repositories { for i, repository := range repositories {
go assembleRepo(c, repository) go assembleRepo(c, i, repository)
} }
result := []*repoResp{} result := []*repoResp{}
var item *repoResp var item *repoResp
@ -171,11 +188,14 @@ func assembleReposInParallel(repositories []*models.RepoRecord) []*repoResp {
} }
result = append(result, item) result = append(result, item)
} }
sort.Sort(reposSorter(result))
return result return result
} }
func assembleRepo(c chan *repoResp, repository *models.RepoRecord) { func assembleRepo(c chan *repoResp, index int, repository *models.RepoRecord) {
repo := &repoResp{ repo := &repoResp{
Index: index,
ID: repository.RepositoryID, ID: repository.RepositoryID,
Name: repository.Name, Name: repository.Name,
ProjectID: repository.ProjectID, ProjectID: repository.ProjectID,