You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

v158.go 3.0KB

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