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.

review_list.go 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package issues
  4. import (
  5. "context"
  6. "code.gitea.io/gitea/models/db"
  7. user_model "code.gitea.io/gitea/models/user"
  8. "code.gitea.io/gitea/modules/container"
  9. "code.gitea.io/gitea/modules/util"
  10. "xorm.io/builder"
  11. )
  12. type ReviewList []*Review
  13. // LoadReviewers loads reviewers
  14. func (reviews ReviewList) LoadReviewers(ctx context.Context) error {
  15. reviewerIDs := make([]int64, len(reviews))
  16. for i := 0; i < len(reviews); i++ {
  17. reviewerIDs[i] = reviews[i].ReviewerID
  18. }
  19. reviewers, err := user_model.GetPossibleUserByIDs(ctx, reviewerIDs)
  20. if err != nil {
  21. return err
  22. }
  23. userMap := make(map[int64]*user_model.User, len(reviewers))
  24. for _, reviewer := range reviewers {
  25. userMap[reviewer.ID] = reviewer
  26. }
  27. for _, review := range reviews {
  28. review.Reviewer = userMap[review.ReviewerID]
  29. }
  30. return nil
  31. }
  32. func (reviews ReviewList) LoadIssues(ctx context.Context) error {
  33. issueIDs := container.Set[int64]{}
  34. for i := 0; i < len(reviews); i++ {
  35. issueIDs.Add(reviews[i].IssueID)
  36. }
  37. issues, err := GetIssuesByIDs(ctx, issueIDs.Values())
  38. if err != nil {
  39. return err
  40. }
  41. if _, err := issues.LoadRepositories(ctx); err != nil {
  42. return err
  43. }
  44. issueMap := make(map[int64]*Issue, len(issues))
  45. for _, issue := range issues {
  46. issueMap[issue.ID] = issue
  47. }
  48. for _, review := range reviews {
  49. review.Issue = issueMap[review.IssueID]
  50. }
  51. return nil
  52. }
  53. // FindReviewOptions represent possible filters to find reviews
  54. type FindReviewOptions struct {
  55. db.ListOptions
  56. Type ReviewType
  57. IssueID int64
  58. ReviewerID int64
  59. OfficialOnly bool
  60. Dismissed util.OptionalBool
  61. }
  62. func (opts *FindReviewOptions) toCond() builder.Cond {
  63. cond := builder.NewCond()
  64. if opts.IssueID > 0 {
  65. cond = cond.And(builder.Eq{"issue_id": opts.IssueID})
  66. }
  67. if opts.ReviewerID > 0 {
  68. cond = cond.And(builder.Eq{"reviewer_id": opts.ReviewerID})
  69. }
  70. if opts.Type != ReviewTypeUnknown {
  71. cond = cond.And(builder.Eq{"type": opts.Type})
  72. }
  73. if opts.OfficialOnly {
  74. cond = cond.And(builder.Eq{"official": true})
  75. }
  76. if !opts.Dismissed.IsNone() {
  77. cond = cond.And(builder.Eq{"dismissed": opts.Dismissed.IsTrue()})
  78. }
  79. return cond
  80. }
  81. // FindReviews returns reviews passing FindReviewOptions
  82. func FindReviews(ctx context.Context, opts FindReviewOptions) (ReviewList, error) {
  83. reviews := make([]*Review, 0, 10)
  84. sess := db.GetEngine(ctx).Where(opts.toCond())
  85. if opts.Page > 0 && !opts.IsListAll() {
  86. sess = db.SetSessionPagination(sess, &opts)
  87. }
  88. return reviews, sess.
  89. Asc("created_unix").
  90. Asc("id").
  91. Find(&reviews)
  92. }
  93. // FindLatestReviews returns only latest reviews per user, passing FindReviewOptions
  94. func FindLatestReviews(ctx context.Context, opts FindReviewOptions) (ReviewList, error) {
  95. reviews := make([]*Review, 0, 10)
  96. cond := opts.toCond()
  97. sess := db.GetEngine(ctx).Where(cond)
  98. if opts.Page > 0 {
  99. sess = db.SetSessionPagination(sess, &opts)
  100. }
  101. sess.In("id", builder.
  102. Select("max(id)").
  103. From("review").
  104. Where(cond).
  105. GroupBy("reviewer_id"))
  106. return reviews, sess.
  107. Asc("created_unix").
  108. Asc("id").
  109. Find(&reviews)
  110. }
  111. // CountReviews returns count of reviews passing FindReviewOptions
  112. func CountReviews(ctx context.Context, opts FindReviewOptions) (int64, error) {
  113. return db.GetEngine(ctx).Where(opts.toCond()).Count(&Review{})
  114. }
  115. // GetReviewersFromOriginalAuthorsByIssueID gets the latest review of each original authors for a pull request
  116. func GetReviewersFromOriginalAuthorsByIssueID(ctx context.Context, issueID int64) (ReviewList, error) {
  117. reviews := make([]*Review, 0, 10)
  118. // Get latest review of each reviewer, sorted in order they were made
  119. if err := db.GetEngine(ctx).SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND original_author_id <> 0 GROUP BY issue_id, original_author_id) ORDER BY review.updated_unix ASC",
  120. issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest).
  121. Find(&reviews); err != nil {
  122. return nil, err
  123. }
  124. return reviews, nil
  125. }
  126. // GetReviewsByIssueID gets the latest review of each reviewer for a pull request
  127. func GetReviewsByIssueID(ctx context.Context, issueID int64) (ReviewList, error) {
  128. reviews := make([]*Review, 0, 10)
  129. sess := db.GetEngine(ctx)
  130. // Get latest review of each reviewer, sorted in order they were made
  131. if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = 0 AND type in (?, ?, ?) AND dismissed = ? AND original_author_id = 0 GROUP BY issue_id, reviewer_id) ORDER BY review.updated_unix ASC",
  132. issueID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, false).
  133. Find(&reviews); err != nil {
  134. return nil, err
  135. }
  136. teamReviewRequests := make([]*Review, 0, 5)
  137. if err := sess.SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id <> 0 AND original_author_id = 0 GROUP BY issue_id, reviewer_team_id) ORDER BY review.updated_unix ASC",
  138. issueID).
  139. Find(&teamReviewRequests); err != nil {
  140. return nil, err
  141. }
  142. if len(teamReviewRequests) > 0 {
  143. reviews = append(reviews, teamReviewRequests...)
  144. }
  145. return reviews, nil
  146. }