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.

issue_watch.go 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2017 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 models
  5. import "code.gitea.io/gitea/modules/timeutil"
  6. // IssueWatch is connection request for receiving issue notification.
  7. type IssueWatch struct {
  8. ID int64 `xorm:"pk autoincr"`
  9. UserID int64 `xorm:"UNIQUE(watch) NOT NULL"`
  10. IssueID int64 `xorm:"UNIQUE(watch) NOT NULL"`
  11. IsWatching bool `xorm:"NOT NULL"`
  12. CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
  13. UpdatedUnix timeutil.TimeStamp `xorm:"updated NOT NULL"`
  14. }
  15. // IssueWatchList contains IssueWatch
  16. type IssueWatchList []*IssueWatch
  17. // CreateOrUpdateIssueWatch set watching for a user and issue
  18. func CreateOrUpdateIssueWatch(userID, issueID int64, isWatching bool) error {
  19. iw, exists, err := getIssueWatch(x, userID, issueID)
  20. if err != nil {
  21. return err
  22. }
  23. if !exists {
  24. iw = &IssueWatch{
  25. UserID: userID,
  26. IssueID: issueID,
  27. IsWatching: isWatching,
  28. }
  29. if _, err := x.Insert(iw); err != nil {
  30. return err
  31. }
  32. } else {
  33. iw.IsWatching = isWatching
  34. if _, err := x.ID(iw.ID).Cols("is_watching", "updated_unix").Update(iw); err != nil {
  35. return err
  36. }
  37. }
  38. return nil
  39. }
  40. // GetIssueWatch returns an issue watch by user and issue
  41. func GetIssueWatch(userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
  42. return getIssueWatch(x, userID, issueID)
  43. }
  44. func getIssueWatch(e Engine, userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
  45. iw = new(IssueWatch)
  46. exists, err = e.
  47. Where("user_id = ?", userID).
  48. And("issue_id = ?", issueID).
  49. And("is_watching = ?", true).
  50. Get(iw)
  51. return
  52. }
  53. // GetIssueWatchersIDs returns IDs of subscribers to a given issue id
  54. // but avoids joining with `user` for performance reasons
  55. // User permissions must be verified elsewhere if required
  56. func GetIssueWatchersIDs(issueID int64) ([]int64, error) {
  57. ids := make([]int64, 0, 64)
  58. return ids, x.Table("issue_watch").
  59. Where("issue_id=?", issueID).
  60. And("is_watching = ?", true).
  61. Select("user_id").
  62. Find(&ids)
  63. }
  64. // GetIssueWatchers returns watchers/unwatchers of a given issue
  65. func GetIssueWatchers(issueID int64) (IssueWatchList, error) {
  66. return getIssueWatchers(x, issueID)
  67. }
  68. func getIssueWatchers(e Engine, issueID int64) (watches IssueWatchList, err error) {
  69. err = e.
  70. Where("`issue_watch`.issue_id = ?", issueID).
  71. And("`issue_watch`.is_watching = ?", true).
  72. And("`user`.is_active = ?", true).
  73. And("`user`.prohibit_login = ?", false).
  74. Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id").
  75. Find(&watches)
  76. return
  77. }
  78. func removeIssueWatchersByRepoID(e Engine, userID int64, repoID int64) error {
  79. iw := &IssueWatch{
  80. IsWatching: false,
  81. }
  82. _, err := e.
  83. Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", repoID).
  84. Cols("is_watching", "updated_unix").
  85. Where("`issue_watch`.user_id = ?", userID).
  86. Update(iw)
  87. return err
  88. }
  89. // LoadWatchUsers return watching users
  90. func (iwl IssueWatchList) LoadWatchUsers() (users UserList, err error) {
  91. return iwl.loadWatchUsers(x)
  92. }
  93. func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList, err error) {
  94. if len(iwl) == 0 {
  95. return []*User{}, nil
  96. }
  97. var userIDs = make([]int64, 0, len(iwl))
  98. for _, iw := range iwl {
  99. if iw.IsWatching {
  100. userIDs = append(userIDs, iw.UserID)
  101. }
  102. }
  103. if len(userIDs) == 0 {
  104. return []*User{}, nil
  105. }
  106. err = e.In("id", userIDs).Find(&users)
  107. return
  108. }