Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve loadprojects for issue list #25468

Merged
merged 9 commits into from
Jun 24, 2023
38 changes: 20 additions & 18 deletions models/issues/issue_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
}

Expand Down
4 changes: 4 additions & 0 deletions models/issues/issue_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
5 changes: 0 additions & 5 deletions models/issues/issue_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions routers/web/org/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,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
Expand Down
7 changes: 6 additions & 1 deletion routers/web/repo/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down