Skip to content

Commit b0dcf41

Browse files
6543lunny
authored andcommitted
Fix milestone num_issues (#8221) (#8400)
* fix milestone num_issues * update missing completeness * only update milestone closed number when closed issue is assigned a new milestone or clear milestone * fix tests * fix update milestone num * fix completeness calculate * make completeness calucation more clear
1 parent 797194d commit b0dcf41

File tree

3 files changed

+44
-41
lines changed

3 files changed

+44
-41
lines changed

models/issue.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ func (issue *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (er
755755
}
756756

757757
// Update issue count of milestone
758-
if err = changeMilestoneIssueStats(e, issue); err != nil {
758+
if err := updateMilestoneClosedNum(e, issue.MilestoneID); err != nil {
759759
return err
760760
}
761761

@@ -1099,7 +1099,7 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
10991099
}
11001100

11011101
if opts.Issue.MilestoneID > 0 {
1102-
if err = changeMilestoneAssign(e, doer, opts.Issue, -1); err != nil {
1102+
if _, err = e.Exec("UPDATE `milestone` SET num_issues=num_issues+1 WHERE id=?", opts.Issue.MilestoneID); err != nil {
11031103
return err
11041104
}
11051105
}

models/issue_milestone.go

+39-36
Original file line numberDiff line numberDiff line change
@@ -311,71 +311,74 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
311311
return sess.Commit()
312312
}
313313

314-
func changeMilestoneIssueStats(e *xorm.Session, issue *Issue) error {
315-
if issue.MilestoneID == 0 {
316-
return nil
314+
func updateMilestoneTotalNum(e Engine, milestoneID int64) (err error) {
315+
if _, err = e.Exec("UPDATE `milestone` SET num_issues=(SELECT count(*) FROM issue WHERE milestone_id=?) WHERE id=?",
316+
milestoneID,
317+
milestoneID,
318+
); err != nil {
319+
return
317320
}
318321

319-
m, err := getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
320-
if err != nil {
321-
return err
322-
}
322+
_, err = e.Exec("UPDATE `milestone` SET completeness=100*num_closed_issues/(CASE WHEN num_issues > 0 THEN num_issues ELSE 1 END) WHERE id=?",
323+
milestoneID,
324+
)
323325

324-
if issue.IsClosed {
325-
m.NumOpenIssues--
326-
m.NumClosedIssues++
327-
} else {
328-
m.NumOpenIssues++
329-
m.NumClosedIssues--
326+
return
327+
}
328+
329+
func updateMilestoneClosedNum(e Engine, milestoneID int64) (err error) {
330+
if _, err = e.Exec("UPDATE `milestone` SET num_closed_issues=(SELECT count(*) FROM issue WHERE milestone_id=? AND is_closed=?) WHERE id=?",
331+
milestoneID,
332+
true,
333+
milestoneID,
334+
); err != nil {
335+
return
330336
}
331337

332-
return updateMilestone(e, m)
338+
_, err = e.Exec("UPDATE `milestone` SET completeness=100*num_closed_issues/(CASE WHEN num_issues > 0 THEN num_issues ELSE 1 END) WHERE id=?",
339+
milestoneID,
340+
)
341+
return
333342
}
334343

335344
func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilestoneID int64) error {
345+
if err := updateIssueCols(e, issue, "milestone_id"); err != nil {
346+
return err
347+
}
348+
336349
if oldMilestoneID > 0 {
337-
m, err := getMilestoneByRepoID(e, issue.RepoID, oldMilestoneID)
338-
if err != nil {
350+
if err := updateMilestoneTotalNum(e, oldMilestoneID); err != nil {
339351
return err
340352
}
341-
342-
m.NumIssues--
343353
if issue.IsClosed {
344-
m.NumClosedIssues--
345-
}
346-
347-
if err = updateMilestone(e, m); err != nil {
348-
return err
354+
if err := updateMilestoneClosedNum(e, oldMilestoneID); err != nil {
355+
return err
356+
}
349357
}
350358
}
351359

352360
if issue.MilestoneID > 0 {
353-
m, err := getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
354-
if err != nil {
361+
if err := updateMilestoneTotalNum(e, issue.MilestoneID); err != nil {
355362
return err
356363
}
357-
358-
m.NumIssues++
359364
if issue.IsClosed {
360-
m.NumClosedIssues++
365+
if err := updateMilestoneClosedNum(e, issue.MilestoneID); err != nil {
366+
return err
367+
}
361368
}
369+
}
362370

363-
if err = updateMilestone(e, m); err != nil {
371+
if oldMilestoneID > 0 || issue.MilestoneID > 0 {
372+
if err := issue.loadRepo(e); err != nil {
364373
return err
365374
}
366-
}
367-
368-
if err := issue.loadRepo(e); err != nil {
369-
return err
370-
}
371375

372-
if oldMilestoneID > 0 || issue.MilestoneID > 0 {
373376
if _, err := createMilestoneComment(e, doer, issue.Repo, issue, oldMilestoneID, issue.MilestoneID); err != nil {
374377
return err
375378
}
376379
}
377380

378-
return updateIssueCols(e, issue, "milestone_id")
381+
return nil
379382
}
380383

381384
// ChangeMilestoneAssign changes assignment of milestone for issue.

models/issue_milestone_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ func TestChangeMilestoneStatus(t *testing.T) {
231231
CheckConsistencyFor(t, &Repository{ID: milestone.RepoID}, &Milestone{})
232232
}
233233

234-
func TestChangeMilestoneIssueStats(t *testing.T) {
234+
func TestUpdateMilestoneClosedNum(t *testing.T) {
235235
assert.NoError(t, PrepareTestDatabase())
236236
issue := AssertExistsAndLoadBean(t, &Issue{MilestoneID: 1},
237237
"is_closed=0").(*Issue)
@@ -240,14 +240,14 @@ func TestChangeMilestoneIssueStats(t *testing.T) {
240240
issue.ClosedUnix = util.TimeStampNow()
241241
_, err := x.Cols("is_closed", "closed_unix").Update(issue)
242242
assert.NoError(t, err)
243-
assert.NoError(t, changeMilestoneIssueStats(x.NewSession(), issue))
243+
assert.NoError(t, updateMilestoneClosedNum(x, issue.MilestoneID))
244244
CheckConsistencyFor(t, &Milestone{})
245245

246246
issue.IsClosed = false
247247
issue.ClosedUnix = 0
248248
_, err = x.Cols("is_closed", "closed_unix").Update(issue)
249249
assert.NoError(t, err)
250-
assert.NoError(t, changeMilestoneIssueStats(x.NewSession(), issue))
250+
assert.NoError(t, updateMilestoneClosedNum(x, issue.MilestoneID))
251251
CheckConsistencyFor(t, &Milestone{})
252252
}
253253

0 commit comments

Comments
 (0)