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.8KB

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