Merge pull request #5748 from cd1989/sort-repos

Support repo list sorting
This commit is contained in:
Wenkai Yin 2018-08-30 16:14:26 +08:00 committed by GitHub
commit d80b9ea471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 9 deletions

View File

@ -894,8 +894,9 @@ paths:
get:
summary: Get repositories accompany with relevant project and repo name.
description: >
This endpoint let user search repositories accompanying with relevant
project ID and repo name.
This endpoint lets user search repositories accompanying with relevant
project ID and repo name. Repositories can be sorted by repo name, creation_time,
update_time in either ascending or descending order.
parameters:
- name: project_id
in: query
@ -908,6 +909,13 @@ paths:
type: string
required: false
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
in: query
type: integer

View File

@ -22,6 +22,18 @@ import (
"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.
func AddRepository(repo models.RepoRecord) error {
if repo.ProjectID == 0 {
@ -116,10 +128,16 @@ func GetTotalOfRepositories(query ...*models.RepositoryQuery) (int64, error) {
// GetRepositories ...
func GetRepositories(query ...*models.RepositoryQuery) ([]*models.RepoRecord, error) {
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...)
sql = `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 `
condition, params := repositoryQueryConditions(query...)
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 %s order by r.%s `, condition, order)
if len(query) > 0 && query[0] != nil {
page, size := query[0].Page, query[0].Size
if size > 0 {

View File

@ -125,7 +125,7 @@ type ProjectQueryParam struct {
ProjectIDs []int64 // project ID list
}
// MemberQuery fitler by member's username and role
// MemberQuery filter by member's username and role
type MemberQuery struct {
Name string // the username of member
Role int // the role of the member has to the project
@ -138,6 +138,11 @@ type Pagination struct {
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
// to get a project collection. The collection can be used as the base to
// do other filter

View File

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

View File

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