mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-06 10:44:36 +01:00
Merge pull request #721 from ywk253100/page
Add pagination support for listing projects
This commit is contained in:
commit
4977a2c77e
@ -154,13 +154,15 @@ func (p *ProjectAPI) Get() {
|
||||
|
||||
// List ...
|
||||
func (p *ProjectAPI) List() {
|
||||
var projectList []models.Project
|
||||
projectName := p.GetString("project_name")
|
||||
if len(projectName) > 0 {
|
||||
projectName = "%" + projectName + "%"
|
||||
}
|
||||
var total int64
|
||||
var public int
|
||||
var err error
|
||||
|
||||
page, pageSize := p.getPaginationParams()
|
||||
|
||||
var projectList []models.Project
|
||||
projectName := p.GetString("project_name")
|
||||
|
||||
isPublic := p.GetString("is_public")
|
||||
if len(isPublic) > 0 {
|
||||
public, err = strconv.Atoi(isPublic)
|
||||
@ -171,7 +173,16 @@ func (p *ProjectAPI) List() {
|
||||
}
|
||||
isAdmin := false
|
||||
if public == 1 {
|
||||
projectList, err = dao.GetPublicProjects(projectName)
|
||||
total, err = dao.GetTotalOfProjects(projectName, 1)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get total of projects: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "")
|
||||
}
|
||||
projectList, err = dao.GetProjects(projectName, 1, pageSize, pageSize*(page-1))
|
||||
if err != nil {
|
||||
log.Errorf("failed to get projects: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "")
|
||||
}
|
||||
} else {
|
||||
//if the request is not for public projects, user must login or provide credential
|
||||
p.userID = p.ValidateUser()
|
||||
@ -181,15 +192,30 @@ func (p *ProjectAPI) List() {
|
||||
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
if isAdmin {
|
||||
projectList, err = dao.GetAllProjects(projectName)
|
||||
} else {
|
||||
projectList, err = dao.GetUserRelevantProjects(p.userID, projectName)
|
||||
}
|
||||
}
|
||||
total, err = dao.GetTotalOfProjects(projectName)
|
||||
if err != nil {
|
||||
log.Errorf("Error occured in get projects info, error: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
log.Errorf("failed to get total of projects: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "")
|
||||
}
|
||||
projectList, err = dao.GetProjects(projectName, pageSize, pageSize*(page-1))
|
||||
if err != nil {
|
||||
log.Errorf("failed to get projects: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "")
|
||||
}
|
||||
} else {
|
||||
total, err = dao.GetTotalOfUserRelevantProjects(p.userID, projectName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get total of projects: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "")
|
||||
}
|
||||
projectList, err = dao.GetUserRelevantProjects(p.userID, projectName, pageSize, pageSize*(page-1))
|
||||
if err != nil {
|
||||
log.Errorf("failed to get projects: %v", err)
|
||||
p.CustomAbort(http.StatusInternalServerError, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(projectList); i++ {
|
||||
if public != 1 {
|
||||
if isAdmin {
|
||||
@ -201,6 +227,8 @@ func (p *ProjectAPI) List() {
|
||||
}
|
||||
projectList[i].RepoCount = getRepoCountByProject(projectList[i].Name)
|
||||
}
|
||||
|
||||
p.setPaginationHeader(total, page, pageSize)
|
||||
p.Data["json"] = projectList
|
||||
p.ServeJSON()
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ func (s *SearchAPI) Get() {
|
||||
var projects []models.Project
|
||||
|
||||
if isSysAdmin {
|
||||
projects, err = dao.GetAllProjects("")
|
||||
projects, err = dao.GetProjects("")
|
||||
if err != nil {
|
||||
log.Errorf("failed to get all projects: %v", err)
|
||||
s.CustomAbort(http.StatusInternalServerError, "internal error")
|
||||
|
@ -45,7 +45,7 @@ func (s *StatisticAPI) Get() {
|
||||
}
|
||||
var projectList []models.Project
|
||||
if isAdmin {
|
||||
projectList, err = dao.GetAllProjects("")
|
||||
projectList, err = dao.GetProjects("")
|
||||
} else {
|
||||
projectList, err = dao.GetUserRelevantProjects(s.userID, "")
|
||||
}
|
||||
@ -59,7 +59,7 @@ func (s *StatisticAPI) Get() {
|
||||
proMap["public_project_count"] = 0
|
||||
proMap["public_repo_count"] = 0
|
||||
var publicProjects []models.Project
|
||||
publicProjects, err = dao.GetPublicProjects("")
|
||||
publicProjects, err = dao.GetProjects("", 1)
|
||||
if err != nil {
|
||||
log.Errorf("Error occured in QueryPublicProject, error: %v", err)
|
||||
s.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
|
@ -609,6 +609,17 @@ func TestProjectPermission(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTotalOfUserRelevantProjects(t *testing.T) {
|
||||
total, err := GetTotalOfUserRelevantProjects(currentUser.UserID, "")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get total of user relevant projects: %v", err)
|
||||
}
|
||||
|
||||
if total != 1 {
|
||||
t.Errorf("unexpected total: %d != 1", total)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUserRelevantProjects(t *testing.T) {
|
||||
projects, err := GetUserRelevantProjects(currentUser.UserID, "")
|
||||
if err != nil {
|
||||
@ -622,8 +633,19 @@ func TestGetUserRelevantProjects(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllProjects(t *testing.T) {
|
||||
projects, err := GetAllProjects("")
|
||||
func TestGetTotalOfProjects(t *testing.T) {
|
||||
total, err := GetTotalOfProjects("")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get total of projects: %v", err)
|
||||
}
|
||||
|
||||
if total != 2 {
|
||||
t.Errorf("unexpected total: %d != 2", total)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetProjects(t *testing.T) {
|
||||
projects, err := GetProjects("")
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred in GetAllProjects: %v", err)
|
||||
}
|
||||
@ -636,7 +658,7 @@ func TestGetAllProjects(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPublicProjects(t *testing.T) {
|
||||
projects, err := GetPublicProjects("")
|
||||
projects, err := GetProjects("", 1)
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred in getProjects: %v", err)
|
||||
}
|
||||
|
124
dao/project.go
124
dao/project.go
@ -182,66 +182,98 @@ func SearchProjects(userID int) ([]models.Project, error) {
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
// GetUserRelevantProjects returns the projects of the user which are not deleted and name like projectName
|
||||
func GetUserRelevantProjects(userID int, projectName string) ([]models.Project, error) {
|
||||
//GetTotalOfUserRelevantProjects returns the total count of
|
||||
// user relevant projects
|
||||
func GetTotalOfUserRelevantProjects(userID int, projectName string,
|
||||
public ...int) (int64, error) {
|
||||
o := GetOrmer()
|
||||
sql := `select distinct
|
||||
p.project_id, p.owner_id, p.name,p.creation_time, p.update_time, p.public, pm.role role
|
||||
from project p
|
||||
left join project_member pm on p.project_id = pm.project_id
|
||||
sql := `select count(*) from project p
|
||||
left join project_member pm
|
||||
on p.project_id = pm.project_id
|
||||
where p.deleted = 0 and pm.user_id= ?`
|
||||
|
||||
queryParam := make([]interface{}, 1)
|
||||
queryParam := []interface{}{}
|
||||
queryParam = append(queryParam, userID)
|
||||
if projectName != "" {
|
||||
sql += " and p.name like ? "
|
||||
queryParam = append(queryParam, projectName)
|
||||
}
|
||||
sql += " order by p.name "
|
||||
var r []models.Project
|
||||
_, err := o.Raw(sql, queryParam).QueryRows(&r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
queryParam = append(queryParam, "%"+projectName+"%")
|
||||
}
|
||||
|
||||
//GetPublicProjects returns all public projects whose name like projectName
|
||||
func GetPublicProjects(projectName string) ([]models.Project, error) {
|
||||
publicProjects, err := getProjects(1, projectName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return publicProjects, nil
|
||||
var total int64
|
||||
err := o.Raw(sql, queryParam).QueryRow(&total)
|
||||
|
||||
return total, err
|
||||
}
|
||||
|
||||
// GetAllProjects returns all projects which are not deleted and name like projectName
|
||||
func GetAllProjects(projectName string) ([]models.Project, error) {
|
||||
allProjects, err := getProjects(0, projectName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return allProjects, nil
|
||||
// GetUserRelevantProjects returns the user relevant projects
|
||||
// args[0]: public, args[1]: limit, args[2]: offset
|
||||
func GetUserRelevantProjects(userID int, projectName string, args ...int64) ([]models.Project, error) {
|
||||
return getProjects(userID, projectName, args...)
|
||||
}
|
||||
|
||||
func getProjects(public int, projectName string) ([]models.Project, error) {
|
||||
// GetTotalOfProjects returns the total count of projects
|
||||
func GetTotalOfProjects(name string, public ...int) (int64, error) {
|
||||
qs := GetOrmer().
|
||||
QueryTable(new(models.Project)).
|
||||
Filter("Deleted", 0)
|
||||
|
||||
if len(name) > 0 {
|
||||
qs = qs.Filter("Name__icontains", name)
|
||||
}
|
||||
|
||||
if len(public) > 0 {
|
||||
qs = qs.Filter("Public", public[0])
|
||||
}
|
||||
|
||||
return qs.Count()
|
||||
}
|
||||
|
||||
// GetProjects returns project list
|
||||
// args[0]: public, args[1]: limit, args[2]: offset
|
||||
func GetProjects(name string, args ...int64) ([]models.Project, error) {
|
||||
return getProjects(0, name, args...)
|
||||
}
|
||||
|
||||
func getProjects(userID int, name string, args ...int64) ([]models.Project, error) {
|
||||
projects := []models.Project{}
|
||||
|
||||
o := GetOrmer()
|
||||
sql := `select project_id, owner_id, creation_time, update_time, name, public
|
||||
from project
|
||||
where deleted = 0`
|
||||
queryParam := make([]interface{}, 1)
|
||||
if public == 1 {
|
||||
sql += " and public = ? "
|
||||
queryParam = append(queryParam, public)
|
||||
sql := ""
|
||||
queryParam := []interface{}{}
|
||||
|
||||
if userID != 0 { //get user's projects
|
||||
sql = `select distinct p.project_id, p.owner_id, p.name,
|
||||
p.creation_time, p.update_time, p.public, pm.role role
|
||||
from project p
|
||||
left join project_member pm
|
||||
on p.project_id = pm.project_id
|
||||
where p.deleted = 0 and pm.user_id= ?`
|
||||
queryParam = append(queryParam, userID)
|
||||
} else { // get all projects
|
||||
sql = `select * from project p where p.deleted = 0 `
|
||||
}
|
||||
if len(projectName) > 0 {
|
||||
sql += " and name like ? "
|
||||
queryParam = append(queryParam, projectName)
|
||||
|
||||
if name != "" {
|
||||
sql += ` and p.name like ? `
|
||||
queryParam = append(queryParam, "%"+name+"%")
|
||||
}
|
||||
sql += " order by name "
|
||||
var projects []models.Project
|
||||
if _, err := o.Raw(sql, queryParam).QueryRows(&projects); err != nil {
|
||||
return nil, err
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
sql += ` and p.public = ?`
|
||||
queryParam = append(queryParam, args[0])
|
||||
sql += ` order by p.name `
|
||||
case 2:
|
||||
sql += ` order by p.name `
|
||||
sql = paginateForRawSQL(sql, args[0], args[1])
|
||||
case 3:
|
||||
sql += ` and p.public = ?`
|
||||
queryParam = append(queryParam, args[0])
|
||||
sql += ` order by p.name `
|
||||
sql = paginateForRawSQL(sql, args[1], args[2])
|
||||
}
|
||||
return projects, nil
|
||||
|
||||
_, err := o.Raw(sql, queryParam).QueryRows(&projects)
|
||||
|
||||
return projects, err
|
||||
}
|
||||
|
@ -336,13 +336,13 @@ func FilterRepJobs(policyID int64, repository, status string, startTime,
|
||||
qs = qs.Filter("CreationTime__lte", endTime)
|
||||
}
|
||||
|
||||
qs = qs.OrderBy("-UpdateTime")
|
||||
|
||||
total, err := qs.Count()
|
||||
if err != nil {
|
||||
return jobs, 0, err
|
||||
}
|
||||
|
||||
qs = qs.OrderBy("-UpdateTime")
|
||||
|
||||
_, err = qs.Limit(limit).Offset(offset).All(&jobs)
|
||||
if err != nil {
|
||||
return jobs, 0, err
|
||||
|
@ -25,17 +25,17 @@ type Project struct {
|
||||
OwnerID int `orm:"column(owner_id)" json:"owner_id"`
|
||||
Name string `orm:"column(name)" json:"name"`
|
||||
CreationTime time.Time `orm:"column(creation_time)" json:"creation_time"`
|
||||
CreationTimeStr string `json:"creation_time_str"`
|
||||
CreationTimeStr string `orm:"-" json:"creation_time_str"`
|
||||
Deleted int `orm:"column(deleted)" json:"deleted"`
|
||||
//UserID int `json:"UserId"`
|
||||
OwnerName string `json:"owner_name"`
|
||||
OwnerName string `orm:"-" json:"owner_name"`
|
||||
Public int `orm:"column(public)" json:"public"`
|
||||
//This field does not have correspondent column in DB, this is just for UI to disable button
|
||||
Togglable bool
|
||||
Togglable bool `orm:"-"`
|
||||
|
||||
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
||||
Role int `json:"current_user_role_id"`
|
||||
RepoCount int `json:"repo_count"`
|
||||
Role int `orm:"-" json:"current_user_role_id"`
|
||||
RepoCount int `orm:"-" json:"repo_count"`
|
||||
}
|
||||
|
||||
// ProjectSorter holds an array of projects
|
||||
|
Loading…
Reference in New Issue
Block a user