code.gitea.io/gitea@v1.21.7/models/migrations/v1_14/v158.go (about) 1 // Copyright 2020 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package v1_14 //nolint 5 6 import ( 7 "fmt" 8 "strconv" 9 10 "code.gitea.io/gitea/modules/log" 11 "code.gitea.io/gitea/modules/setting" 12 13 "xorm.io/xorm" 14 ) 15 16 func UpdateCodeCommentReplies(x *xorm.Engine) error { 17 type Comment struct { 18 ID int64 `xorm:"pk autoincr"` 19 CommitSHA string `xorm:"VARCHAR(40)"` 20 Patch string `xorm:"TEXT patch"` 21 Invalidated bool 22 23 // Not extracted but used in the below query 24 Type int `xorm:"INDEX"` 25 Line int64 // - previous line / + proposed line 26 TreePath string 27 ReviewID int64 `xorm:"index"` 28 } 29 30 if err := x.Sync(new(Comment)); err != nil { 31 return err 32 } 33 34 sqlSelect := `SELECT comment.id as id, first.commit_sha as commit_sha, first.patch as patch, first.invalidated as invalidated` 35 sqlTail := ` FROM comment INNER JOIN ( 36 SELECT C.id, C.review_id, C.line, C.tree_path, C.patch, C.commit_sha, C.invalidated 37 FROM comment AS C 38 WHERE C.type = 21 39 AND C.created_unix = 40 (SELECT MIN(comment.created_unix) 41 FROM comment 42 WHERE comment.review_id = C.review_id 43 AND comment.type = 21 44 AND comment.line = C.line 45 AND comment.tree_path = C.tree_path) 46 ) AS first 47 ON comment.review_id = first.review_id 48 AND comment.tree_path = first.tree_path AND comment.line = first.line 49 WHERE comment.type = 21 50 AND comment.id != first.id 51 AND comment.commit_sha != first.commit_sha` 52 53 var ( 54 sqlCmd string 55 start = 0 56 batchSize = 100 57 sess = x.NewSession() 58 ) 59 defer sess.Close() 60 for { 61 if err := sess.Begin(); err != nil { 62 return err 63 } 64 65 if setting.Database.Type.IsMSSQL() { 66 if _, err := sess.Exec(sqlSelect + " INTO #temp_comments" + sqlTail); err != nil { 67 log.Error("unable to create temporary table") 68 return err 69 } 70 } 71 72 comments := make([]*Comment, 0, batchSize) 73 74 switch { 75 case setting.Database.Type.IsMySQL(): 76 sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + ", " + strconv.Itoa(start) 77 case setting.Database.Type.IsPostgreSQL(): 78 fallthrough 79 case setting.Database.Type.IsSQLite3(): 80 sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + " OFFSET " + strconv.Itoa(start) 81 case setting.Database.Type.IsMSSQL(): 82 sqlCmd = "SELECT TOP " + strconv.Itoa(batchSize) + " * FROM #temp_comments WHERE " + 83 "(id NOT IN ( SELECT TOP " + strconv.Itoa(start) + " id FROM #temp_comments ORDER BY id )) ORDER BY id" 84 default: 85 return fmt.Errorf("Unsupported database type") 86 } 87 88 if err := sess.SQL(sqlCmd).Find(&comments); err != nil { 89 log.Error("failed to select: %v", err) 90 return err 91 } 92 93 for _, comment := range comments { 94 if _, err := sess.Table("comment").ID(comment.ID).Cols("commit_sha", "patch", "invalidated").Update(comment); err != nil { 95 log.Error("failed to update comment[%d]: %v %v", comment.ID, comment, err) 96 return err 97 } 98 } 99 100 start += len(comments) 101 102 if err := sess.Commit(); err != nil { 103 return err 104 } 105 if len(comments) < batchSize { 106 break 107 } 108 } 109 110 return nil 111 }