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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
4 changes: 2 additions & 2 deletions 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 Expand Up @@ -2749,7 +2749,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
}
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
4 changes: 2 additions & 2 deletions templates/repo/issue/view_content/sidebar.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@
</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>
Expand Down