diff options
author | Bo-Yi Wu <appleboy.tw@gmail.com> | 2018-02-21 18:55:34 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-21 18:55:34 +0800 |
commit | 04b3e8cbdc2bb4eafe8feb3fe4882f010e931860 (patch) | |
tree | ca463be266c44aaf52e5106aac77dfd56402057b /models | |
parent | d27d720f05835dfc4633587aec885ab9b93b5f86 (diff) | |
download | gitea-04b3e8cbdc2bb4eafe8feb3fe4882f010e931860.tar.gz gitea-04b3e8cbdc2bb4eafe8feb3fe4882f010e931860.zip |
refactor: reduce sql query in retrieveFeeds (#3547)
Diffstat (limited to 'models')
-rw-r--r-- | models/action.go | 11 | ||||
-rw-r--r-- | models/action_list.go | 98 |
2 files changed, 108 insertions, 1 deletions
diff --git a/models/action.go b/models/action.go index 5333f62772..b551d79bb8 100644 --- a/models/action.go +++ b/models/action.go @@ -742,5 +742,14 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) { } actions := make([]*Action, 0, 20) - return actions, x.Limit(20).Desc("id").Where(cond).Find(&actions) + + if err := x.Limit(20).Desc("id").Where(cond).Find(&actions); err != nil { + return nil, fmt.Errorf("Find: %v", err) + } + + if err := ActionList(actions).LoadAttributes(); err != nil { + return nil, fmt.Errorf("LoadAttributes: %v", err) + } + + return actions, nil } diff --git a/models/action_list.go b/models/action_list.go new file mode 100644 index 0000000000..6f726f4b34 --- /dev/null +++ b/models/action_list.go @@ -0,0 +1,98 @@ +// Copyright 2018 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package models + +import "fmt" + +// ActionList defines a list of actions +type ActionList []*Action + +func (actions ActionList) getUserIDs() []int64 { + userIDs := make(map[int64]struct{}, len(actions)) + for _, action := range actions { + if _, ok := userIDs[action.ActUserID]; !ok { + userIDs[action.ActUserID] = struct{}{} + } + } + return keysInt64(userIDs) +} + +func (actions ActionList) loadUsers(e Engine) ([]*User, error) { + if len(actions) == 0 { + return nil, nil + } + + userIDs := actions.getUserIDs() + userMaps := make(map[int64]*User, len(userIDs)) + err := e. + In("id", userIDs). + Find(&userMaps) + if err != nil { + return nil, fmt.Errorf("find user: %v", err) + } + + for _, action := range actions { + action.ActUser = userMaps[action.ActUserID] + } + return valuesUser(userMaps), nil +} + +// LoadUsers loads actions' all users +func (actions ActionList) LoadUsers() ([]*User, error) { + return actions.loadUsers(x) +} + +func (actions ActionList) getRepoIDs() []int64 { + repoIDs := make(map[int64]struct{}, len(actions)) + for _, action := range actions { + if _, ok := repoIDs[action.RepoID]; !ok { + repoIDs[action.RepoID] = struct{}{} + } + } + return keysInt64(repoIDs) +} + +func (actions ActionList) loadRepositories(e Engine) ([]*Repository, error) { + if len(actions) == 0 { + return nil, nil + } + + repoIDs := actions.getRepoIDs() + repoMaps := make(map[int64]*Repository, len(repoIDs)) + err := e. + In("id", repoIDs). + Find(&repoMaps) + if err != nil { + return nil, fmt.Errorf("find repository: %v", err) + } + + for _, action := range actions { + action.Repo = repoMaps[action.RepoID] + } + return valuesRepository(repoMaps), nil +} + +// LoadRepositories loads actions' all repositories +func (actions ActionList) LoadRepositories() ([]*Repository, error) { + return actions.loadRepositories(x) +} + +// loadAttributes loads all attributes +func (actions ActionList) loadAttributes(e Engine) (err error) { + if _, err = actions.loadUsers(e); err != nil { + return + } + + if _, err = actions.loadRepositories(e); err != nil { + return + } + + return nil +} + +// LoadAttributes loads attributes of the actions +func (actions ActionList) LoadAttributes() error { + return actions.loadAttributes(x) +} |