diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2016-12-28 09:34:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-28 09:34:35 +0800 |
commit | c463b1b8cb925ff80da1e8c8ec3aed64a7642091 (patch) | |
tree | 23b617a69e5393ad843ca4f18f1c1fefb7bfc099 /models/access.go | |
parent | 9fae9f0dc21e95209491c96d2e809d8a50a94a21 (diff) | |
download | gitea-c463b1b8cb925ff80da1e8c8ec3aed64a7642091.tar.gz gitea-c463b1b8cb925ff80da1e8c8ec3aed64a7642091.zip |
Optimization for user.GetRepositoryAccesses to reduce db query times (#495)
* optimization for user.GetRepositoryAccesses to reduce db query times
* fix missing cache
Diffstat (limited to 'models/access.go')
-rw-r--r-- | models/access.go | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/models/access.go b/models/access.go index b591e0c9db..c77e7f0a16 100644 --- a/models/access.go +++ b/models/access.go @@ -4,11 +4,7 @@ package models -import ( - "fmt" - - "code.gitea.io/gitea/modules/log" -) +import "fmt" // AccessMode specifies the users access mode type AccessMode int @@ -103,26 +99,39 @@ func HasAccess(user *User, repo *Repository, testMode AccessMode) (bool, error) // GetRepositoryAccesses finds all repositories with their access mode where a user has access but does not own. func (user *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) { accesses := make([]*Access, 0, 10) - if err := x.Find(&accesses, &Access{UserID: user.ID}); err != nil { + type RepoAccess struct { + Access `xorm:"extends"` + Repository `xorm:"extends"` + } + + rows, err := x. + Join("INNER", "repository", "respository.id = access.repo_id"). + Where("access.user_id = ?", user.ID). + And("repository.owner_id <> ?", user.ID). + Rows(new(RepoAccess)) + if err != nil { return nil, err } + defer rows.Close() - repos := make(map[*Repository]AccessMode, len(accesses)) - for _, access := range accesses { - repo, err := GetRepositoryByID(access.RepoID) + var repos = make(map[*Repository]AccessMode, len(accesses)) + var ownerCache = make(map[int64]*User, len(accesses)) + for rows.Next() { + var repo RepoAccess + err = rows.Scan(&repo) if err != nil { - if IsErrRepoNotExist(err) { - log.Error(4, "GetRepositoryByID: %v", err) - continue - } return nil, err } - if err = repo.GetOwner(); err != nil { - return nil, err - } else if repo.OwnerID == user.ID { - continue + + var ok bool + if repo.Owner, ok = ownerCache[repo.OwnerID]; !ok { + if err = repo.GetOwner(); err != nil { + return nil, err + } + ownerCache[repo.OwnerID] = repo.Owner } - repos[repo] = access.Mode + + repos[&repo.Repository] = repo.Access.Mode } return repos, nil } |