diff --git a/models/db/engine.go b/models/db/engine.go index 26abf0b96c..97aa37ed6d 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -57,6 +57,7 @@ type Engine interface { SumInt(bean any, columnName string) (res int64, err error) Sync(...any) error Select(string) *xorm.Session + SetExpr(column string, expression any) *xorm.Session NotIn(string, ...any) *xorm.Session OrderBy(any, ...any) *xorm.Session Exist(...any) (bool, error) diff --git a/models/issues/comment.go b/models/issues/comment.go index 353163ebd6..980b1f374b 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -868,7 +868,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment } fallthrough case CommentTypeComment: - if _, err = db.Exec(ctx, "UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", opts.Issue.ID); err != nil { + if err := UpdateIssueNumComments(ctx, opts.Issue.ID); err != nil { return err } fallthrough @@ -1148,8 +1148,8 @@ func DeleteComment(ctx context.Context, comment *Comment) error { return err } - if comment.Type == CommentTypeComment { - if _, err := e.ID(comment.IssueID).Decr("num_comments").Update(new(Issue)); err != nil { + if comment.Type == CommentTypeComment || comment.Type == CommentTypeReview { + if err := UpdateIssueNumComments(ctx, comment.IssueID); err != nil { return err } } @@ -1266,6 +1266,26 @@ func (c *Comment) HasOriginalAuthor() bool { return c.OriginalAuthor != "" && c.OriginalAuthorID != 0 } +func CountCommentsBuilder(issueID int64) *builder.Builder { + return builder.Select("count(*)").From("comment").Where(builder.Eq{ + "issue_id": issueID, + }.And(builder.Or( + builder.Eq{"type": CommentTypeComment}, + builder.Eq{"type": CommentTypeReview}, + builder.Eq{"type": CommentTypeCode}, + )).And(builder.Neq{ + "invalidated": true, + })) +} + +func UpdateIssueNumComments(ctx context.Context, issueID int64) error { + _, err := db.GetEngine(ctx). + SetExpr("num_comments", CountCommentsBuilder(issueID)). + ID(issueID). + Update(new(Issue)) + return err +} + // InsertIssueComments inserts many comments of issues. func InsertIssueComments(ctx context.Context, comments []*Comment) error { if len(comments) == 0 { @@ -1298,8 +1318,7 @@ func InsertIssueComments(ctx context.Context, comments []*Comment) error { } for _, issueID := range issueIDs { - if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?", - issueID, CommentTypeComment, issueID); err != nil { + if err := UpdateIssueNumComments(ctx, issueID); err != nil { return err } } diff --git a/models/repo.go b/models/repo.go index 0dc8ee5df3..020a414527 100644 --- a/models/repo.go +++ b/models/repo.go @@ -109,7 +109,7 @@ func userStatsCorrectNumRepos(ctx context.Context, id int64) error { } func repoStatsCorrectIssueNumComments(ctx context.Context, id int64) error { - return StatsCorrectSQL(ctx, "UPDATE `issue` SET num_comments=(SELECT COUNT(*) FROM `comment` WHERE issue_id=? AND type=0) WHERE id=?", id) + return StatsCorrectSQL(ctx, "UPDATE `issue` SET num_comments=(SELECT COUNT(*) FROM `comment` WHERE issue_id=? AND (type=0 or type=22)) WHERE id=?", id) } func repoStatsCorrectNumIssues(ctx context.Context, id int64) error { @@ -201,7 +201,7 @@ func CheckRepoStats(ctx context.Context) error { }, // Issue.NumComments { - statsQuery("SELECT `issue`.id FROM `issue` WHERE `issue`.num_comments!=(SELECT COUNT(*) FROM `comment` WHERE issue_id=`issue`.id AND type=0)"), + statsQuery("SELECT `issue`.id FROM `issue` WHERE `issue`.num_comments!=(SELECT COUNT(*) FROM `comment` WHERE issue_id=`issue`.id AND (type=0 OR type=22))"), repoStatsCorrectIssueNumComments, "issue count 'num_comments'", },