]> source.dussan.org Git - gitea.git/commitdiff
Improve loadprojects for issue list (#25468) (#25493)
authorGiteabot <teabot@gitea.io>
Mon, 26 Jun 2023 02:06:58 +0000 (22:06 -0400)
committerGitHub <noreply@github.com>
Mon, 26 Jun 2023 02:06:58 +0000 (02:06 +0000)
models/issues/issue_list.go
models/issues/issue_list_test.go
models/issues/issue_project.go
routers/web/org/projects.go
routers/web/repo/issue.go
routers/web/repo/projects.go
templates/repo/issue/view_content/sidebar.tmpl

index dad21c14776f036a0cc1d8743936db7d6aa0d030..9cc41ec6ab37e8701502008dfd171bf82cd88c27 100644 (file)
@@ -229,39 +229,41 @@ func (issues IssueList) loadMilestones(ctx context.Context) error {
        return nil
 }
 
-func (issues IssueList) getProjectIDs() []int64 {
-       ids := make(container.Set[int64], len(issues))
-       for _, issue := range issues {
-               ids.Add(issue.ProjectID())
-       }
-       return ids.Values()
-}
+func (issues IssueList) LoadProjects(ctx context.Context) error {
+       issueIDs := issues.getIssueIDs()
+       projectMaps := make(map[int64]*project_model.Project, len(issues))
+       left := len(issueIDs)
 
-func (issues IssueList) loadProjects(ctx context.Context) error {
-       projectIDs := issues.getProjectIDs()
-       if len(projectIDs) == 0 {
-               return nil
+       type projectWithIssueID struct {
+               *project_model.Project `xorm:"extends"`
+               IssueID                int64
        }
 
-       projectMaps := make(map[int64]*project_model.Project, len(projectIDs))
-       left := len(projectIDs)
        for left > 0 {
                limit := db.DefaultMaxInSize
                if left < limit {
                        limit = left
                }
+
+               projects := make([]*projectWithIssueID, 0, limit)
                err := db.GetEngine(ctx).
-                       In("id", projectIDs[:limit]).
-                       Find(&projectMaps)
+                       Table("project").
+                       Select("project.*, project_issue.issue_id").
+                       Join("INNER", "project_issue", "project.id = project_issue.project_id").
+                       In("project_issue.issue_id", issueIDs[:limit]).
+                       Find(&projects)
                if err != nil {
                        return err
                }
+               for _, project := range projects {
+                       projectMaps[project.IssueID] = project.Project
+               }
                left -= limit
-               projectIDs = projectIDs[limit:]
+               issueIDs = issueIDs[limit:]
        }
 
        for _, issue := range issues {
-               issue.Project = projectMaps[issue.ProjectID()]
+               issue.Project = projectMaps[issue.ID]
        }
        return nil
 }
@@ -541,7 +543,7 @@ func (issues IssueList) loadAttributes(ctx context.Context) error {
                return fmt.Errorf("issue.loadAttributes: loadMilestones: %w", err)
        }
 
-       if err := issues.loadProjects(ctx); err != nil {
+       if err := issues.LoadProjects(ctx); err != nil {
                return fmt.Errorf("issue.loadAttributes: loadProjects: %w", err)
        }
 
index 954a20ffe44edec5b7a2e316c919d186cd431629..97ce9e43b377734cf04e64756609d04b61d6e277 100644 (file)
@@ -66,8 +66,12 @@ func TestIssueList_LoadAttributes(t *testing.T) {
                }
                if issue.ID == int64(1) {
                        assert.Equal(t, int64(400), issue.TotalTrackedTime)
+                       assert.NotNil(t, issue.Project)
                } else if issue.ID == int64(2) {
                        assert.Equal(t, int64(3682), issue.TotalTrackedTime)
+                       assert.Nil(t, issue.Project)
+               } else {
+                       assert.Nil(t, issue.Project)
                }
        }
 }
index 04d12e055cc586f9617528fa76fec11ab3823ca2..b163c683577f0e363f317def6ae235790679fded 100644 (file)
@@ -27,11 +27,6 @@ func (issue *Issue) LoadProject(ctx context.Context) (err error) {
        return err
 }
 
-// ProjectID return project id if issue was assigned to one
-func (issue *Issue) ProjectID() int64 {
-       return issue.projectID(db.DefaultContext)
-}
-
 func (issue *Issue) projectID(ctx context.Context) int64 {
        var ip project_model.ProjectIssue
        has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
index b3f6024b6060658dbf1f52852c8e574a06defdb2..e525f2c43f3ac956fc562f5a55909454635ce7e7 100644 (file)
@@ -383,7 +383,7 @@ func ViewProject(ctx *context.Context) {
        ctx.HTML(http.StatusOK, tplProjectsView)
 }
 
-func getActionIssues(ctx *context.Context) []*issues_model.Issue {
+func getActionIssues(ctx *context.Context) issues_model.IssueList {
        commaSeparatedIssueIDs := ctx.FormString("issue_ids")
        if len(commaSeparatedIssueIDs) == 0 {
                return nil
@@ -429,9 +429,14 @@ func UpdateIssueProject(ctx *context.Context) {
                return
        }
 
+       if err := issues.LoadProjects(ctx); err != nil {
+               ctx.ServerError("LoadProjects", err)
+               return
+       }
+
        projectID := ctx.FormInt64("id")
        for _, issue := range issues {
-               oldProjectID := issue.ProjectID()
+               oldProjectID := issue.Project.ID
                if oldProjectID == projectID {
                        continue
                }
index 5ab8db2e057fe8e7ddca7a656beb83c5aa5ba94c..0756fcd533ef13e1aab0e1a58e0d6b42bac39419 100644 (file)
@@ -1971,7 +1971,7 @@ func checkIssueRights(ctx *context.Context, issue *issues_model.Issue) {
        }
 }
 
-func getActionIssues(ctx *context.Context) []*issues_model.Issue {
+func getActionIssues(ctx *context.Context) issues_model.IssueList {
        commaSeparatedIssueIDs := ctx.FormString("issue_ids")
        if len(commaSeparatedIssueIDs) == 0 {
                return nil
@@ -2722,7 +2722,7 @@ func UpdateIssueStatus(ctx *context.Context) {
                log.Warn("Unrecognized action: %s", action)
        }
 
-       if _, err := issues_model.IssueList(issues).LoadRepositories(ctx); err != nil {
+       if _, err := issues.LoadRepositories(ctx); err != nil {
                ctx.ServerError("LoadRepositories", err)
                return
        }
index 5ee5ead12177b4fe4455ea6b0824c63fd4b6d7fe..6da9edfd0b802faee26f66f619191f92d8cfe2b3 100644 (file)
@@ -378,9 +378,14 @@ func UpdateIssueProject(ctx *context.Context) {
                return
        }
 
+       if err := issues.LoadProjects(ctx); err != nil {
+               ctx.ServerError("LoadProjects", err)
+               return
+       }
+
        projectID := ctx.FormInt64("id")
        for _, issue := range issues {
-               oldProjectID := issue.ProjectID()
+               oldProjectID := issue.Project.ID
                if oldProjectID == projectID {
                        continue
                }
index 901f714e325c10324f7aeaff978051e3d0edac9d..2f32639220b0d98aafae1febde076bac8b7b5026 100644 (file)
                        </div>
                </div>
                <div class="ui select-project list">
-                       <span class="no-select item {{if .Issue.ProjectID}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span>
+                       <span class="no-select item {{if .Issue.Project}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span>
                        <div class="selected">
-                               {{if .Issue.ProjectID}}
+                               {{if .Issue.Project}}
                                        <a class="item muted sidebar-item-link" href="{{.Issue.Project.Link}}">
                                                {{svg .Issue.Project.IconName 18 "gt-mr-3"}}{{.Issue.Project.Title}}
                                        </a>