// 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" "strconv" "xorm.io/builder" ) // 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)) if len(userIDs) == 0 { return make([]*User, 0), nil } 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)) if len(repoIDs) == 0 { return make([]*Repository, 0), nil } 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) } func (actions ActionList) getCommentIDs() []int64 { commentIDs := make(map[int64]struct{}, len(actions)) for _, action := range actions { if action.CommentID == 0 { continue } if _, ok := commentIDs[action.CommentID]; !ok { commentIDs[action.CommentID] = struct{}{} } } return keysInt64(commentIDs) } func (actions ActionList) loadComments(e Engine) ([]*Comment, error) { if len(actions) == 0 { return nil, nil } commentIDs := actions.getCommentIDs() commentMaps := make(map[int64]*Comment, len(commentIDs)) if len(commentIDs) == 0 { return make([]*Comment, 0), nil } err := e. In("id", commentIDs). Find(&commentMaps) if err != nil { return nil, fmt.Errorf("find comment: %v", err) } for _, action := range actions { if action.CommentID > 0 { action.Comment = commentMaps[action.CommentID] } } return valuesComment(commentMaps), nil } // LoadComments loads actions' all comments func (actions ActionList) LoadComments() ([]*Comment, error) { return actions.loadComments(x) } func (actions ActionList) getCloudbrainIDs() []int64 { cloudbrainIDs := make(map[int64]struct{}, 0) for _, action := range actions { if !action.IsCloudbrainAction() { continue } cloudbrainId, _ := strconv.ParseInt(action.Content, 10, 64) if _, ok := cloudbrainIDs[cloudbrainId]; !ok { cloudbrainIDs[cloudbrainId] = struct{}{} } } return keysInt64(cloudbrainIDs) } func (actions ActionList) getCloudbrainJobIDs() []string { cloudbrainJobIDs := make(map[string]struct{}, 0) for _, action := range actions { if !action.IsCloudbrainAction() { continue } if _, ok := cloudbrainJobIDs[action.Content]; !ok { cloudbrainJobIDs[action.Content] = struct{}{} } } return keysString(cloudbrainJobIDs) } func (actions ActionList) loadCloudbrains(e Engine) ([]*Cloudbrain, error) { if len(actions) == 0 { return nil, nil } cloudbrainIDs := actions.getCloudbrainIDs() cloudbrainJobIDs := actions.getCloudbrainJobIDs() cloudbrainMaps := make(map[int64]*Cloudbrain, len(cloudbrainIDs)) if len(cloudbrainIDs) == 0 { return make([]*Cloudbrain, 0), nil } //由于各个类型的云脑任务在发布action的时候,content字段保存的ID含义不同,部分取的是ID,部分取的是jobId //所以在查询action对应的cloudbrain对象时,以这两个字段做为条件查询 cond := builder.Or(builder.In("id", cloudbrainIDs)).Or(builder.In("job_id", cloudbrainJobIDs)) err := e. Where(cond).Unscoped(). Find(&cloudbrainMaps) if err != nil { return nil, fmt.Errorf("find cloudbrain: %v", err) } cloudBrainJobIdMap := make(map[string]*Cloudbrain, len(cloudbrainIDs)) for _, v := range cloudbrainMaps { cloudBrainJobIdMap[v.JobID] = v } for _, action := range actions { if !action.IsCloudbrainAction() { continue } cloudbrainId, _ := strconv.ParseInt(action.Content, 10, 64) if cloudbrainId > 0 { if c, ok := cloudbrainMaps[cloudbrainId]; ok { if c.DisplayJobName == action.RefName || c.JobName == action.RefName { action.Cloudbrain = c continue } } } if c, ok := cloudBrainJobIdMap[action.Content]; ok { if c.DisplayJobName == action.RefName || c.JobName == action.RefName { action.Cloudbrain = c continue } } } return valuesCloudbrain(cloudbrainMaps), nil } // LoadComments loads actions' all comments func (actions ActionList) LoadCloudbrains() ([]*Comment, error) { return actions.loadComments(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) } // LoadAllAttributes loads all attributes of the actions // compare with LoadAttributes() ,LoadAllAttributes() loads Comment and Cloudbrain attribute func (actions ActionList) LoadAllAttributes() error { return actions.loadAllAttributes(x) } // loadAllAttributes func (actions ActionList) loadAllAttributes(e Engine) (err error) { if _, err = actions.loadUsers(e); err != nil { return } if _, err = actions.loadRepositories(e); err != nil { return } if _, err = actions.loadComments(e); err != nil { return } if _, err = actions.loadCloudbrains(e); err != nil { return } return nil }