@@ -197,6 +197,20 @@ func (t CommentType) HasMailReplySupport() bool {
197197 return false
198198}
199199
200+ func (t CommentType ) CountedAsConversation () bool {
201+ for _ , ct := range ConversationCountedCommentType () {
202+ if t == ct {
203+ return true
204+ }
205+ }
206+ return false
207+ }
208+
209+ // ConversationCountedCommentType returns the comment types that are counted as a conversation
210+ func ConversationCountedCommentType () []CommentType {
211+ return []CommentType {CommentTypeComment , CommentTypeReview }
212+ }
213+
200214// RoleInRepo presents the user's participation in the repo
201215type RoleInRepo string
202216
@@ -592,26 +606,26 @@ func (c *Comment) LoadAttachments(ctx context.Context) error {
592606 return nil
593607}
594608
595- // UpdateAttachments update attachments by UUIDs for the comment
596- func (c * Comment ) UpdateAttachments (ctx context.Context , uuids []string ) error {
597- ctx , committer , err := db .TxContext (ctx )
598- if err != nil {
599- return err
600- }
601- defer committer .Close ()
602-
603- attachments , err := repo_model .GetAttachmentsByUUIDs (ctx , uuids )
604- if err != nil {
605- return fmt .Errorf ("getAttachmentsByUUIDs [uuids: %v]: %w" , uuids , err )
609+ // UpdateCommentAttachments update attachments by UUIDs for the comment
610+ func UpdateCommentAttachments (ctx context.Context , c * Comment , uuids []string ) error {
611+ if len (uuids ) == 0 {
612+ return nil
606613 }
607- for i := 0 ; i < len (attachments ); i ++ {
608- attachments [i ].IssueID = c .IssueID
609- attachments [i ].CommentID = c .ID
610- if err := repo_model .UpdateAttachment (ctx , attachments [i ]); err != nil {
611- return fmt .Errorf ("update attachment [id: %d]: %w" , attachments [i ].ID , err )
614+ return db .WithTx (ctx , func (ctx context.Context ) error {
615+ attachments , err := repo_model .GetAttachmentsByUUIDs (ctx , uuids )
616+ if err != nil {
617+ return fmt .Errorf ("getAttachmentsByUUIDs [uuids: %v]: %w" , uuids , err )
612618 }
613- }
614- return committer .Commit ()
619+ for i := 0 ; i < len (attachments ); i ++ {
620+ attachments [i ].IssueID = c .IssueID
621+ attachments [i ].CommentID = c .ID
622+ if err := repo_model .UpdateAttachment (ctx , attachments [i ]); err != nil {
623+ return fmt .Errorf ("update attachment [id: %d]: %w" , attachments [i ].ID , err )
624+ }
625+ }
626+ c .Attachments = attachments
627+ return nil
628+ })
615629}
616630
617631// LoadAssigneeUserAndTeam if comment.Type is CommentTypeAssignees, then load assignees
@@ -878,7 +892,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
878892 // Check comment type.
879893 switch opts .Type {
880894 case CommentTypeCode :
881- if err = updateAttachments (ctx , opts , comment ); err != nil {
895+ if err = UpdateCommentAttachments (ctx , comment , opts . Attachments ); err != nil {
882896 return err
883897 }
884898 if comment .ReviewID != 0 {
@@ -893,12 +907,12 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
893907 }
894908 fallthrough
895909 case CommentTypeComment :
896- if _ , err = db . Exec (ctx , "UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?" , opts .Issue .ID ); err != nil {
910+ if err := UpdateIssueNumComments (ctx , opts .Issue .ID ); err != nil {
897911 return err
898912 }
899913 fallthrough
900914 case CommentTypeReview :
901- if err = updateAttachments (ctx , opts , comment ); err != nil {
915+ if err = UpdateCommentAttachments (ctx , comment , opts . Attachments ); err != nil {
902916 return err
903917 }
904918 case CommentTypeReopen , CommentTypeClose :
@@ -910,23 +924,6 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
910924 return UpdateIssueCols (ctx , opts .Issue , "updated_unix" )
911925}
912926
913- func updateAttachments (ctx context.Context , opts * CreateCommentOptions , comment * Comment ) error {
914- attachments , err := repo_model .GetAttachmentsByUUIDs (ctx , opts .Attachments )
915- if err != nil {
916- return fmt .Errorf ("getAttachmentsByUUIDs [uuids: %v]: %w" , opts .Attachments , err )
917- }
918- for i := range attachments {
919- attachments [i ].IssueID = opts .Issue .ID
920- attachments [i ].CommentID = comment .ID
921- // No assign value could be 0, so ignore AllCols().
922- if _ , err = db .GetEngine (ctx ).ID (attachments [i ].ID ).Update (attachments [i ]); err != nil {
923- return fmt .Errorf ("update attachment [%d]: %w" , attachments [i ].ID , err )
924- }
925- }
926- comment .Attachments = attachments
927- return nil
928- }
929-
930927func createDeadlineComment (ctx context.Context , doer * user_model.User , issue * Issue , newDeadlineUnix timeutil.TimeStamp ) (* Comment , error ) {
931928 var content string
932929 var commentType CommentType
@@ -1182,8 +1179,8 @@ func DeleteComment(ctx context.Context, comment *Comment) error {
11821179 return err
11831180 }
11841181
1185- if comment .Type == CommentTypeComment {
1186- if _ , err := e . ID ( comment .IssueID ). Decr ( "num_comments" ). Update ( new ( Issue ) ); err != nil {
1182+ if comment .Type . CountedAsConversation () {
1183+ if err := UpdateIssueNumComments ( ctx , comment .IssueID ); err != nil {
11871184 return err
11881185 }
11891186 }
@@ -1300,6 +1297,21 @@ func (c *Comment) HasOriginalAuthor() bool {
13001297 return c .OriginalAuthor != "" && c .OriginalAuthorID != 0
13011298}
13021299
1300+ func UpdateIssueNumCommentsBuilder (issueID int64 ) * builder.Builder {
1301+ subQuery := builder .Select ("COUNT(*)" ).From ("`comment`" ).Where (
1302+ builder.Eq {"issue_id" : issueID }.And (
1303+ builder .In ("`type`" , ConversationCountedCommentType ()),
1304+ ))
1305+
1306+ return builder .Update (builder.Eq {"num_comments" : subQuery }).
1307+ From ("`issue`" ).Where (builder.Eq {"id" : issueID })
1308+ }
1309+
1310+ func UpdateIssueNumComments (ctx context.Context , issueID int64 ) error {
1311+ _ , err := db .GetEngine (ctx ).Exec (UpdateIssueNumCommentsBuilder (issueID ))
1312+ return err
1313+ }
1314+
13031315// InsertIssueComments inserts many comments of issues.
13041316func InsertIssueComments (ctx context.Context , comments []* Comment ) error {
13051317 if len (comments ) == 0 {
@@ -1332,8 +1344,7 @@ func InsertIssueComments(ctx context.Context, comments []*Comment) error {
13321344 }
13331345
13341346 for _ , issueID := range issueIDs {
1335- if _ , err := db .Exec (ctx , "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?" ,
1336- issueID , CommentTypeComment , issueID ); err != nil {
1347+ if err := UpdateIssueNumComments (ctx , issueID ); err != nil {
13371348 return err
13381349 }
13391350 }
0 commit comments