Merge pull request #1536 from ywk253100/170307_repo_api

Refactor get repo API
This commit is contained in:
Daniel Jiang 2017-03-08 12:31:05 +08:00 committed by GitHub
commit 282c7f61c4
6 changed files with 189 additions and 26 deletions

View File

@ -658,6 +658,11 @@ paths:
format: int32 format: int32
required: true required: true
description: Relevant project ID. description: Relevant project ID.
- name: detail
in: query
type: boolean
required: false
description: Get detail info or not.
- name: q - name: q
in: query in: query
type: string type: string

View File

@ -184,3 +184,34 @@ func GetTotalOfUserRelevantRepositories(userID int, name string) (int64, error)
err := GetOrmer().Raw(sql, params).QueryRow(&total) err := GetOrmer().Raw(sql, params).QueryRow(&total)
return total, err return total, err
} }
// GetTotalOfRepositoriesByProject ...
func GetTotalOfRepositoriesByProject(projectID int64, name string) (int64, error) {
qs := GetOrmer().QueryTable(&models.RepoRecord{}).
Filter("ProjectID", projectID)
if len(name) != 0 {
qs = qs.Filter("Name__contains", name)
}
return qs.Count()
}
// GetRepositoriesByProject ...
func GetRepositoriesByProject(projectID int64, name string,
limit, offset int64) ([]*models.RepoRecord, error) {
repositories := []*models.RepoRecord{}
qs := GetOrmer().QueryTable(&models.RepoRecord{}).
Filter("ProjectID", projectID)
if len(name) != 0 {
qs = qs.Filter("Name__contains", name)
}
_, err := qs.Limit(limit).
Offset(offset).All(&repositories)
return repositories, err
}

View File

@ -340,6 +340,78 @@ func TestGetTopRepos(t *testing.T) {
}) })
} }
func TestGetTotalOfRepositoriesByProject(t *testing.T) {
var projectID int64 = 1
repoName := "library/total_count"
total, err := GetTotalOfRepositoriesByProject(projectID, repoName)
if err != nil {
t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err)
return
}
if err := addRepository(&models.RepoRecord{
Name: repoName,
OwnerName: "admin",
ProjectName: "library",
}); err != nil {
t.Errorf("failed to add repository %s: %v", repoName, err)
return
}
defer func() {
if err := deleteRepository(repoName); err != nil {
t.Errorf("failed to delete repository %s: %v", name, err)
return
}
}()
n, err := GetTotalOfRepositoriesByProject(projectID, repoName)
if err != nil {
t.Errorf("failed to get total of repositoreis of project %d: %v", projectID, err)
return
}
if n != total+1 {
t.Errorf("unexpected total: %d != %d", n, total+1)
}
}
func TestGetRepositoriesByProject(t *testing.T) {
var projectID int64 = 1
repoName := "library/repository"
if err := addRepository(&models.RepoRecord{
Name: repoName,
OwnerName: "admin",
ProjectName: "library",
}); err != nil {
t.Errorf("failed to add repository %s: %v", repoName, err)
return
}
defer func() {
if err := deleteRepository(repoName); err != nil {
t.Errorf("failed to delete repository %s: %v", name, err)
return
}
}()
repositories, err := GetRepositoriesByProject(projectID, repoName, 10, 0)
if err != nil {
t.Errorf("failed to get repositoreis of project %d: %v", projectID, err)
return
}
t.Log(repositories)
for _, repository := range repositories {
if repository.Name == repoName {
return
}
}
t.Errorf("repository %s not found", repoName)
}
func addRepository(repository *models.RepoRecord) error { func addRepository(repository *models.RepoRecord) error {
return AddRepository(*repository) return AddRepository(*repository)
} }

View File

@ -453,7 +453,7 @@ func (a testapi) PutProjectMember(authInfo usrInfo, projectID string, userID str
//-------------------------Repositories Test---------------------------------------// //-------------------------Repositories Test---------------------------------------//
//Return relevant repos of projectID //Return relevant repos of projectID
func (a testapi) GetRepos(authInfo usrInfo, projectID string) (int, error) { func (a testapi) GetRepos(authInfo usrInfo, projectID, detail string) (int, error) {
_sling := sling.New().Get(a.basePath) _sling := sling.New().Get(a.basePath)
path := "/api/repositories/" path := "/api/repositories/"
@ -462,9 +462,13 @@ func (a testapi) GetRepos(authInfo usrInfo, projectID string) (int, error) {
type QueryParams struct { type QueryParams struct {
ProjectID string `url:"project_id"` ProjectID string `url:"project_id"`
Detail string `url:"detail"`
} }
_sling = _sling.QueryStruct(&QueryParams{ProjectID: projectID}) _sling = _sling.QueryStruct(&QueryParams{
ProjectID: projectID,
Detail: detail,
})
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo) httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err return httpStatusCode, err
} }

View File

@ -22,6 +22,7 @@ import (
"path" "path"
"sort" "sort"
"strings" "strings"
"time"
"github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/manifest/schema2" "github.com/docker/distribution/manifest/schema2"
@ -44,6 +45,19 @@ type RepositoryAPI struct {
api.BaseAPI api.BaseAPI
} }
type repoResp struct {
ID string `json:"id"`
Name string `json:"name"`
OwnerID int64 `json:"owner_id"`
ProjectID int64 `json:"project_id"`
Description string `json:"description"`
PullCount int64 `json:"pull_count"`
StarCount int64 `json:"star_count"`
TagsCount int64 `json:"tags_count"`
CreationTime time.Time `json:"creation_time"`
UpdateTime time.Time `json:"update_time"`
}
// Get ... // Get ...
func (ra *RepositoryAPI) Get() { func (ra *RepositoryAPI) Get() {
projectID, err := ra.GetInt64("project_id") projectID, err := ra.GetInt64("project_id")
@ -51,8 +65,6 @@ func (ra *RepositoryAPI) Get() {
ra.CustomAbort(http.StatusBadRequest, "invalid project_id") ra.CustomAbort(http.StatusBadRequest, "invalid project_id")
} }
page, pageSize := ra.GetPaginationParams()
project, err := dao.GetProjectByID(projectID) project, err := dao.GetProjectByID(projectID)
if err != nil { if err != nil {
log.Errorf("failed to get project %d: %v", projectID, err) log.Errorf("failed to get project %d: %v", projectID, err)
@ -77,30 +89,71 @@ func (ra *RepositoryAPI) Get() {
} }
} }
repositories, err := getReposByProject(project.Name, ra.GetString("q")) keyword := ra.GetString("q")
total, err := dao.GetTotalOfRepositoriesByProject(projectID, keyword)
if err != nil {
log.Errorf("failed to get total of repositories of project %d: %v", projectID, err)
ra.CustomAbort(http.StatusInternalServerError, "")
}
page, pageSize := ra.GetPaginationParams()
detail := ra.GetString("detail") == "1" || ra.GetString("detail") == "true"
repositories, err := getRepositories(projectID,
keyword, pageSize, pageSize*(page-1), detail)
if err != nil { if err != nil {
log.Errorf("failed to get repository: %v", err) log.Errorf("failed to get repository: %v", err)
ra.CustomAbort(http.StatusInternalServerError, "") ra.CustomAbort(http.StatusInternalServerError, "")
} }
total := int64(len(repositories))
if (page-1)*pageSize > total {
repositories = []string{}
} else {
repositories = repositories[(page-1)*pageSize:]
}
if page*pageSize <= total {
repositories = repositories[:pageSize]
}
ra.SetPaginationHeader(total, page, pageSize) ra.SetPaginationHeader(total, page, pageSize)
ra.Data["json"] = repositories ra.Data["json"] = repositories
ra.ServeJSON() ra.ServeJSON()
} }
func getRepositories(projectID int64, keyword string,
limit, offset int64, detail bool) (interface{}, error) {
repositories, err := dao.GetRepositoriesByProject(projectID, keyword, limit, offset)
if err != nil {
return nil, err
}
//keep compatibility with old API
if !detail {
result := []string{}
for _, repository := range repositories {
result = append(result, repository.Name)
}
return result, nil
}
result := []*repoResp{}
for _, repository := range repositories {
repo := &repoResp{
ID: repository.RepositoryID,
Name: repository.Name,
OwnerID: repository.OwnerID,
ProjectID: repository.ProjectID,
Description: repository.Description,
PullCount: repository.PullCount,
StarCount: repository.StarCount,
CreationTime: repository.CreationTime,
UpdateTime: repository.UpdateTime,
}
tags, err := getTags(repository.Name)
if err != nil {
return nil, err
}
repo.TagsCount = int64(len(tags))
result = append(result, repo)
}
return result, nil
}
// Delete ... // Delete ...
func (ra *RepositoryAPI) Delete() { func (ra *RepositoryAPI) Delete() {
repoName := ra.GetString("repo_name") repoName := ra.GetString("repo_name")
@ -119,11 +172,9 @@ func (ra *RepositoryAPI) Delete() {
ra.CustomAbort(http.StatusNotFound, fmt.Sprintf("project %s not found", projectName)) ra.CustomAbort(http.StatusNotFound, fmt.Sprintf("project %s not found", projectName))
} }
if project.Public == 0 { userID := ra.ValidateUser()
userID := ra.ValidateUser() if !hasProjectAdminRole(userID, project.ProjectID) {
if !hasProjectAdminRole(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "")
ra.CustomAbort(http.StatusForbidden, "")
}
} }
rc, err := ra.initRepositoryClient(repoName) rc, err := ra.initRepositoryClient(repoName)

View File

@ -20,7 +20,7 @@ func TestGetRepos(t *testing.T) {
fmt.Println("Testing Repos Get API") fmt.Println("Testing Repos Get API")
//-------------------case 1 : response code = 200------------------------// //-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200") fmt.Println("case 1 : response code = 200")
httpStatusCode, err = apiTest.GetRepos(*admin, projectID) httpStatusCode, err = apiTest.GetRepos(*admin, projectID, "true")
if err != nil { if err != nil {
t.Error("Error whihle get repos by projectID", err.Error()) t.Error("Error whihle get repos by projectID", err.Error())
t.Log(err) t.Log(err)
@ -30,7 +30,7 @@ func TestGetRepos(t *testing.T) {
//-------------------case 2 : response code = 400------------------------// //-------------------case 2 : response code = 400------------------------//
fmt.Println("case 2 : response code = 409,invalid project_id") fmt.Println("case 2 : response code = 409,invalid project_id")
projectID = "ccc" projectID = "ccc"
httpStatusCode, err = apiTest.GetRepos(*admin, projectID) httpStatusCode, err = apiTest.GetRepos(*admin, projectID, "0")
if err != nil { if err != nil {
t.Error("Error whihle get repos by projectID", err.Error()) t.Error("Error whihle get repos by projectID", err.Error())
t.Log(err) t.Log(err)
@ -40,7 +40,7 @@ func TestGetRepos(t *testing.T) {
//-------------------case 3 : response code = 404------------------------// //-------------------case 3 : response code = 404------------------------//
fmt.Println("case 3 : response code = 404:project not found") fmt.Println("case 3 : response code = 404:project not found")
projectID = "111" projectID = "111"
httpStatusCode, err = apiTest.GetRepos(*admin, projectID) httpStatusCode, err = apiTest.GetRepos(*admin, projectID, "0")
if err != nil { if err != nil {
t.Error("Error whihle get repos by projectID", err.Error()) t.Error("Error whihle get repos by projectID", err.Error())
t.Log(err) t.Log(err)