summaryrefslogtreecommitdiffstats
path: root/models/access.go
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2016-12-28 09:34:35 +0800
committerGitHub <noreply@github.com>2016-12-28 09:34:35 +0800
commitc463b1b8cb925ff80da1e8c8ec3aed64a7642091 (patch)
tree23b617a69e5393ad843ca4f18f1c1fefb7bfc099 /models/access.go
parent9fae9f0dc21e95209491c96d2e809d8a50a94a21 (diff)
downloadgitea-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.go45
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
}