@@ -7,9 +7,12 @@ package models
77import (
88 "fmt"
99 "reflect"
10+ "strconv"
1011 "strings"
1112 "testing"
1213
14+ "code.gitea.io/gitea/modules/setting"
15+
1316 "github.com/stretchr/testify/assert"
1417 "xorm.io/builder"
1518)
@@ -299,45 +302,70 @@ func FixNullArchivedRepository() (int64, error) {
299302
300303// CountOrFixUpdatableCodeCommentReplies count or fix CodeCommentReplies missing the CommitSHA
301304func CountOrFixUpdatableCodeCommentReplies (fix bool ) (int64 , []string , error ) {
302- sess := x .NewSession ()
303- defer sess .Close ()
304- if err := sess .Begin (); err != nil {
305- return 0 , nil , err
306- }
307305
308306 var (
309307 start = 0
310308 batchSize = 100
309+ sqlCmd string
311310 count int64
312311 result []string
313312 )
314313
314+ sqlSelect := `SELECT comment.id as id, first.commit_sha as commit_sha, first.patch as patch, first.invalidated as invalidated`
315+ sqlTail := ` FROM comment INNER JOIN (
316+ SELECT C.id, C.review_id, C.line, C.tree_path, C.patch, C.commit_sha, C.invalidated
317+ FROM comment AS C
318+ WHERE C.type = 21
319+ AND C.created_unix =
320+ (SELECT MIN(comment.created_unix)
321+ FROM comment
322+ WHERE comment.review_id = C.review_id
323+ AND comment.type = 21
324+ AND comment.line = C.line
325+ AND comment.tree_path = C.tree_path)
326+ ) AS first
327+ ON comment.review_id = first.review_id
328+ AND comment.tree_path = first.tree_path AND comment.line = first.line
329+ WHERE comment.type = 21
330+ AND comment.id != first.id
331+ AND comment.commit_sha != first.commit_sha`
332+
333+ sess := x .NewSession ()
334+ defer sess .Close ()
315335 for {
336+ if err := sess .Begin (); err != nil {
337+ return 0 , nil , err
338+ }
339+
340+ if setting .Database .UseMSSQL {
341+ if _ , err := sess .Exec (sqlSelect + " INTO #temp_comments" + sqlTail ); err != nil {
342+ return 0 , nil , fmt .Errorf ("unable to create temporary table" )
343+ }
344+ }
345+
316346 var comments = make ([]* Comment , 0 , batchSize )
317- if err := sess .SQL (`SELECT comment.id as id, first.commit_sha as commit_sha, first.patch as patch, first.invalidated as invalidated
318- FROM comment INNER JOIN (
319- SELECT C.id, C.review_id, C.line, C.tree_path, C.patch, C.commit_sha, C.invalidated
320- FROM comment AS C
321- WHERE C.type = 21
322- AND C.created_unix =
323- (SELECT MIN(comment.created_unix)
324- FROM comment
325- WHERE comment.review_id = C.review_id
326- AND comment.type = 21
327- AND comment.line = C.line
328- AND comment.tree_path = C.tree_path)
329- ) AS first
330- ON comment.review_id = first.review_id
331- AND comment.tree_path = first.tree_path AND comment.line = first.line
332- WHERE comment.type = 21
333- AND comment.id != first.id
334- AND comment.commit_sha != first.commit_sha` ).Limit (batchSize , start ).Find (& comments ); err != nil {
347+
348+ switch {
349+ case setting .Database .UseMySQL :
350+ sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv .Itoa (batchSize ) + ", " + strconv .Itoa (start )
351+ case setting .Database .UsePostgreSQL :
352+ fallthrough
353+ case setting .Database .UseSQLite3 :
354+ sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv .Itoa (batchSize ) + " OFFSET " + strconv .Itoa (start )
355+ case setting .Database .UseMSSQL :
356+ sqlCmd = "SELECT TOP " + strconv .Itoa (batchSize ) + " * FROM #temp_comments WHERE " +
357+ "(id NOT IN ( SELECT TOP " + strconv .Itoa (start ) + " id FROM #temp_comments ORDER BY id )) ORDER BY id"
358+ default :
359+ return 0 , nil , fmt .Errorf ("Unsupported database type" )
360+ }
361+
362+ if err := sess .SQL (sqlCmd ).Find (& comments ); err != nil {
335363 return 0 , nil , fmt .Errorf ("failed to select: %v" , err )
336364 }
337365
338366 if fix {
339367 for _ , comment := range comments {
340- if _ , err := sess .Table ("comment" ).Cols ("commit_sha" , "patch" , "invalidated" ).Update (comment ); err != nil {
368+ if _ , err := sess .Table ("comment" ).ID ( comment . ID ). Cols ("commit_sha" , "patch" , "invalidated" ).Update (comment ); err != nil {
341369 return 0 , nil , fmt .Errorf ("failed to update comment[%d]: %v %v" , comment .ID , comment , err )
342370 }
343371 result = append (result , fmt .Sprintf ("update comment[%d]: %s\n " , comment .ID , comment .CommitSHA ))
@@ -346,14 +374,17 @@ func CountOrFixUpdatableCodeCommentReplies(fix bool) (int64, []string, error) {
346374
347375 count += int64 (len (comments ))
348376 start += len (comments )
377+
378+ if fix {
379+ if err := sess .Commit (); err != nil {
380+ return count , result , err
381+ }
382+ }
383+
349384 if len (comments ) < batchSize {
350385 break
351386 }
352387 }
353388
354- if fix {
355- return count , result , sess .Commit ()
356- }
357-
358- return count , nil , nil
389+ return count , result , nil
359390}
0 commit comments