Merge pull request #2372 from ywk253100/170524_statistics

Refactor statistics API
This commit is contained in:
Yan 2017-06-04 20:28:48 -07:00 committed by GitHub
commit b1d09cdccb
4 changed files with 46 additions and 153 deletions

View File

@ -125,50 +125,10 @@ func GetTotalOfRepositories(name string) (int64, error) {
return qs.Count() return qs.Count()
} }
// GetTotalOfPublicRepositories ...
func GetTotalOfPublicRepositories(name string) (int64, error) {
params := []interface{}{}
sql := `select count(*) from repository r
join project p
on r.project_id = p.project_id and p.public = 1 `
if len(name) != 0 {
sql += ` where r.name like ?`
params = append(params, "%"+escape(name)+"%")
}
var total int64
err := GetOrmer().Raw(sql, params).QueryRow(&total)
return total, err
}
// GetTotalOfUserRelevantRepositories ...
func GetTotalOfUserRelevantRepositories(userID int, name string) (int64, error) {
params := []interface{}{}
sql := `select count(*)
from repository r
join (
select p.project_id, p.public
from project p
join project_member pm
on p.project_id = pm.project_id
where pm.user_id = ?
) as pp
on r.project_id = pp.project_id `
params = append(params, userID)
if len(name) != 0 {
sql += ` where r.name like ?`
params = append(params, "%"+escape(name)+"%")
}
var total int64
err := GetOrmer().Raw(sql, params).QueryRow(&total)
return total, err
}
// GetTotalOfRepositoriesByProject ... // GetTotalOfRepositoriesByProject ...
func GetTotalOfRepositoriesByProject(projectID int64, name string) (int64, error) { func GetTotalOfRepositoriesByProject(projectIDs []int64, name string) (int64, error) {
qs := GetOrmer().QueryTable(&models.RepoRecord{}). qs := GetOrmer().QueryTable(&models.RepoRecord{}).
Filter("ProjectID", projectID) Filter("project_id__in", projectIDs)
if len(name) != 0 { if len(name) != 0 {
qs = qs.Filter("Name__contains", name) qs = qs.Filter("Name__contains", name)

View File

@ -88,78 +88,6 @@ func TestGetTotalOfRepositories(t *testing.T) {
} }
} }
func TestGetTotalOfPublicRepositories(t *testing.T) {
total, err := GetTotalOfPublicRepositories("")
if err != nil {
t.Fatalf("failed to get total of public repositoreis: %v", err)
}
if err := addRepository(repository); err != nil {
t.Fatalf("failed to add repository %s: %v", name, err)
}
defer func() {
if err := deleteRepository(name); err != nil {
t.Fatalf("failed to delete repository %s: %v", name, err)
}
}()
n, err := GetTotalOfPublicRepositories("")
if err != nil {
t.Fatalf("failed to get total of public repositoreis: %v", err)
}
if n != total+1 {
t.Errorf("unexpected total: %d != %d", n, total+1)
}
}
func TestGetTotalOfUserRelevantRepositories(t *testing.T) {
total, err := GetTotalOfUserRelevantRepositories(1, "")
if err != nil {
t.Fatalf("failed to get total of repositoreis for user %d: %v", 1, err)
}
if err := addRepository(repository); err != nil {
t.Fatalf("failed to add repository %s: %v", name, err)
}
defer func() {
if err := deleteRepository(name); err != nil {
t.Fatalf("failed to delete repository %s: %v", name, err)
}
}()
users, err := GetUserByProject(1, models.User{})
if err != nil {
t.Fatalf("failed to list members of project %d: %v", 1, err)
}
exist := false
for _, user := range users {
if user.UserID == 1 {
exist = true
break
}
}
if !exist {
if err = AddProjectMember(1, 1, models.DEVELOPER); err != nil {
t.Fatalf("failed to add user %d to be member of project %d: %v", 1, 1, err)
}
defer func() {
if err = DeleteProjectMember(1, 1); err != nil {
t.Fatalf("failed to delete user %d from member of project %d: %v", 1, 1, err)
}
}()
}
n, err := GetTotalOfUserRelevantRepositories(1, "")
if err != nil {
t.Fatalf("failed to get total of public repositoreis for user %d: %v", 1, err)
}
if n != total+1 {
t.Errorf("unexpected total: %d != %d", n, total+1)
}
}
func TestGetTopRepos(t *testing.T) { func TestGetTopRepos(t *testing.T) {
var err error var err error
require := require.New(t) require := require.New(t)
@ -226,7 +154,7 @@ func TestGetTotalOfRepositoriesByProject(t *testing.T) {
var projectID int64 = 1 var projectID int64 = 1
repoName := "library/total_count" repoName := "library/total_count"
total, err := GetTotalOfRepositoriesByProject(projectID, repoName) total, err := GetTotalOfRepositoriesByProject([]int64{projectID}, repoName)
if err != nil { if err != nil {
t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err) t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err)
return return
@ -246,7 +174,7 @@ func TestGetTotalOfRepositoriesByProject(t *testing.T) {
} }
}() }()
n, err := GetTotalOfRepositoriesByProject(projectID, repoName) n, err := GetTotalOfRepositoriesByProject([]int64{projectID}, repoName)
if err != nil { if err != nil {
t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err) t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err)
return return

View File

@ -103,7 +103,8 @@ func (ra *RepositoryAPI) Get() {
keyword := ra.GetString("q") keyword := ra.GetString("q")
total, err := dao.GetTotalOfRepositoriesByProject(projectID, keyword) total, err := dao.GetTotalOfRepositoriesByProject(
[]int64{projectID}, keyword)
if err != nil { if err != nil {
ra.HandleInternalServerError(fmt.Sprintf("failed to get total of repositories of project %d: %v", ra.HandleInternalServerError(fmt.Sprintf("failed to get total of repositories of project %d: %v",
projectID, err)) projectID, err))

View File

@ -15,9 +15,9 @@
package api package api
import ( import (
"fmt"
"net/http" "net/http"
"github.com/vmware/harbor/src/common/api"
"github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/common/utils/log"
@ -40,42 +40,45 @@ const (
// StatisticAPI handles request to /api/statistics/ // StatisticAPI handles request to /api/statistics/
type StatisticAPI struct { type StatisticAPI struct {
api.BaseAPI BaseController
userID int username string
} }
//Prepare validates the URL and the user //Prepare validates the URL and the user
func (s *StatisticAPI) Prepare() { func (s *StatisticAPI) Prepare() {
s.userID = s.ValidateUser() s.BaseController.Prepare()
if !s.SecurityCtx.IsAuthenticated() {
s.HandleUnauthorized()
return
}
s.username = s.SecurityCtx.GetUsername()
} }
// Get total projects and repos of the user // Get total projects and repos of the user
func (s *StatisticAPI) Get() { func (s *StatisticAPI) Get() {
statistic := map[string]int64{} statistic := map[string]int64{}
t := true
n, err := dao.GetTotalOfProjects(&models.QueryParam{
Public: &t,
})
if err != nil {
log.Errorf("failed to get total of public projects: %v", err)
s.CustomAbort(http.StatusInternalServerError, "")
}
statistic[PPC] = n
n, err = dao.GetTotalOfPublicRepositories("") projects, err := s.ProjectMgr.GetPublic()
if err != nil {
s.HandleInternalServerError(fmt.Sprintf(
"failed to get public projects: %v", err))
return
}
statistic[PPC] = (int64)(len(projects))
ids := []int64{}
for _, p := range projects {
ids = append(ids, p.ProjectID)
}
n, err := dao.GetTotalOfRepositoriesByProject(ids, "")
if err != nil { if err != nil {
log.Errorf("failed to get total of public repositories: %v", err) log.Errorf("failed to get total of public repositories: %v", err)
s.CustomAbort(http.StatusInternalServerError, "") s.CustomAbort(http.StatusInternalServerError, "")
} }
statistic[PRC] = n statistic[PRC] = n
isAdmin, err := dao.IsAdminRole(s.userID) if s.SecurityCtx.IsSysAdmin() {
if err != nil {
log.Errorf("Error occured in check admin, error: %v", err)
s.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if isAdmin {
n, err := dao.GetTotalOfProjects(nil) n, err := dao.GetTotalOfProjects(nil)
if err != nil { if err != nil {
log.Errorf("failed to get total of projects: %v", err) log.Errorf("failed to get total of projects: %v", err)
@ -92,28 +95,29 @@ func (s *StatisticAPI) Get() {
statistic[MRC] = n statistic[MRC] = n
statistic[TRC] = n statistic[TRC] = n
} else { } else {
user, err := dao.GetUser(models.User{ projects, err := s.ProjectMgr.GetAll(&models.QueryParam{
UserID: s.userID,
})
if err != nil {
log.Errorf("failed to get user %d: %v", s.userID, err)
s.CustomAbort(http.StatusInternalServerError, "")
}
n, err := dao.GetTotalOfProjects(&models.QueryParam{
Member: &models.Member{ Member: &models.Member{
Name: user.Username, Name: s.username,
}, },
}) })
if err != nil { if err != nil {
log.Errorf("failed to get total of projects for user %d: %v", s.userID, err) s.HandleInternalServerError(fmt.Sprintf(
s.CustomAbort(http.StatusInternalServerError, "") "failed to get projects of user %s: %v", s.username, err))
return
} }
statistic[MPC] = n statistic[MPC] = (int64)(len(projects))
n, err = dao.GetTotalOfUserRelevantRepositories(s.userID, "") ids := []int64{}
for _, p := range projects {
ids = append(ids, p.ProjectID)
}
n, err = dao.GetTotalOfRepositoriesByProject(ids, "")
if err != nil { if err != nil {
log.Errorf("failed to get total of repositories for user %d: %v", s.userID, err) s.HandleInternalServerError(fmt.Sprintf(
s.CustomAbort(http.StatusInternalServerError, "") "failed to get total of repositories for user %s: %v",
s.username, err))
return
} }
statistic[MRC] = n statistic[MRC] = n
} }