-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Fix the missing users in the subscriptions endpoint. #26797
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
CaiCandong
wants to merge
18
commits into
go-gitea:main
from
CaiCandong:bugfix/Fix-missing-watcher-in-endpoint
Closed
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
e397ee4
fix
CaiCandong 80e8cf0
fix sql
CaiCandong 69f003e
fix test
CaiCandong 89a6456
adjust comment
CaiCandong ae1fb80
fix lint
CaiCandong e44e0c3
Format
CaiCandong 6c69b9f
Revert "Format"
CaiCandong 6f7348e
Merge branch 'main' into bugfix/Fix-missing-watcher-in-endpoint
CaiCandong f3bf0b5
Apply suggestions from code review
CaiCandong 5a15e00
Adjust index order of issue_watch table
CaiCandong 9f68ca8
Merge branch 'bugfix/Fix-missing-watcher-in-endpoint' of github.com:C…
CaiCandong 02e894f
Reduce unnecessary database queries & rename
CaiCandong 4adb2e5
rename & fix count
CaiCandong cec368f
fix test
CaiCandong 695b5c7
fix
CaiCandong a3b6a6e
fix lint & add comments
CaiCandong 2bd395d
fix lint
CaiCandong c5138e9
Merge branch 'main' into bugfix/Fix-missing-watcher-in-endpoint
CaiCandong File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright 2023 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package issues | ||
|
||
import ( | ||
"context" | ||
|
||
"code.gitea.io/gitea/models/db" | ||
repo_model "code.gitea.io/gitea/models/repo" | ||
user_model "code.gitea.io/gitea/models/user" | ||
|
||
"xorm.io/builder" | ||
) | ||
|
||
// CheckIssueSubscriber check if a user is subscribing an issue | ||
// it takes participants and repo watch into account | ||
func CheckIssueSubscriber(user *user_model.User, issue *Issue) (bool, error) { | ||
iw, exist, err := GetIssueWatch(db.DefaultContext, user.ID, issue.ID) | ||
if err != nil { | ||
return false, err | ||
} | ||
if exist { | ||
return iw.IsWatching, nil | ||
} | ||
w, err := repo_model.GetWatch(db.DefaultContext, user.ID, issue.RepoID) | ||
if err != nil { | ||
return false, err | ||
} | ||
return repo_model.IsWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil | ||
} | ||
|
||
// GetIssueSubscribers returns subscribers of a given issue | ||
func GetIssueSubscribers(ctx context.Context, issue *Issue, listOptions db.ListOptions) (user_model.UserList, error) { | ||
subscribeUserIds := builder.Select("`issue_watch`.user_id"). | ||
From("issue_watch"). | ||
Where(builder.Eq{"`issue_watch`.issue_id": issue.ID, "`issue_watch`.is_watching": true}) | ||
|
||
unsubscribeUserIds := builder.Select("`issue_watch`.user_id"). | ||
From("issue_watch"). | ||
Where(builder.Eq{"`issue_watch`.issue_id": issue.ID, "`issue_watch`.is_watching": false}) | ||
|
||
participantsUserIds := builder.Select("`comment`.poster_id"). | ||
From("comment"). | ||
Where(builder.Eq{"`comment`.issue_id": issue.ID}). | ||
And(builder.In("`comment`.type", CommentTypeComment, CommentTypeCode, CommentTypeReview)) | ||
|
||
repoSubscribeUserIds := builder.Select("`watch`.user_id"). | ||
From("watch"). | ||
Where(builder.Eq{"`watch`.repo_id": issue.RepoID}). | ||
And(builder.NotIn("`watch`.mode", repo_model.WatchModeDont, repo_model.WatchModeNone)) | ||
|
||
sess := db.GetEngine(ctx).Table("user"). | ||
Where(builder.Or( | ||
builder.In("id", subscribeUserIds), | ||
builder.In("id", repoSubscribeUserIds), | ||
builder.In("id", participantsUserIds), | ||
builder.In("id", issue.PosterID), | ||
). | ||
And(builder.NotIn("id", unsubscribeUserIds)). | ||
And(builder.Eq{"`user`.is_active": true, "`user`.prohibit_login": false})) | ||
|
||
if listOptions.Page != 0 { | ||
sess = db.SetSessionPagination(sess, &listOptions) | ||
users := make(user_model.UserList, 0, listOptions.PageSize) | ||
return users, sess.Find(&users) | ||
} | ||
users := make(user_model.UserList, 0, 8) | ||
return users, sess.Find(&users) | ||
} | ||
|
||
// CountIssueSubscribers count subscribers of a given issue | ||
func CountIssueSubscribers(ctx context.Context, issue *Issue) (int64, error) { | ||
subscribeUserIds := builder.Select("`issue_watch`.user_id"). | ||
From("issue_watch"). | ||
Where(builder.Eq{"`issue_watch`.issue_id": issue.ID, "`issue_watch`.is_watching": true}) | ||
|
||
unsubscribeUserIds := builder.Select("`issue_watch`.user_id"). | ||
From("issue_watch"). | ||
Where(builder.Eq{"`issue_watch`.issue_id": issue.ID, "`issue_watch`.is_watching": false}) | ||
|
||
participantsUserIds := builder.Select("`comment`.poster_id"). | ||
From("comment"). | ||
Where(builder.Eq{"`comment`.issue_id": issue.ID}). | ||
And(builder.In("`comment`.type", CommentTypeComment, CommentTypeCode, CommentTypeReview)) | ||
|
||
repoSubscribeUserIds := builder.Select("`watch`.user_id"). | ||
From("watch"). | ||
Where(builder.Eq{"`watch`.repo_id": issue.RepoID}). | ||
And(builder.NotIn("`watch`.mode", repo_model.WatchModeDont, repo_model.WatchModeNone)) | ||
|
||
sess := db.GetEngine(ctx).Table("user"). | ||
Where(builder.Or( | ||
builder.In("id", subscribeUserIds), | ||
builder.In("id", repoSubscribeUserIds), | ||
builder.In("id", participantsUserIds), | ||
builder.In("id", issue.PosterID), | ||
). | ||
And(builder.NotIn("id", unsubscribeUserIds)). | ||
And(builder.Eq{"`user`.is_active": true, "`user`.prohibit_login": false})) | ||
|
||
return sess.Count(new(user_model.User)) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright 2023 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package issues_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"code.gitea.io/gitea/models/db" | ||
issues_model "code.gitea.io/gitea/models/issues" | ||
"code.gitea.io/gitea/models/unittest" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGetIssueWatchers(t *testing.T) { | ||
assert.NoError(t, unittest.PrepareTestDatabase()) | ||
|
||
issueList := issues_model.IssueList{ | ||
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}), // repo 1 | ||
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}), // repo 1 | ||
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5}), // repo 1 | ||
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 7}), // repo 2 | ||
} | ||
|
||
iws, err := issues_model.GetIssueSubscribers(db.DefaultContext, issueList[0], db.ListOptions{}) | ||
assert.NoError(t, err) | ||
// +isIssueWatching[] | ||
// -noIssueWatching[] | ||
// +participates[2,3,5] | ||
// +poster[1] | ||
// +repoWatch[1,4,9,11] | ||
// -inactive[3,9] | ||
// => [1,4,5,11] | ||
assert.Len(t, iws, 4) | ||
|
||
iws, err = issues_model.GetIssueSubscribers(db.DefaultContext, issueList[1], db.ListOptions{}) | ||
assert.NoError(t, err) | ||
// +isIssueWatching[] | ||
// -noIssueWatching[2] | ||
// +participates[1] | ||
// +poster[1] | ||
// +repoWatch[1,4,9,11] | ||
// -inactive[3,9] | ||
// => [1,4,11] | ||
assert.Len(t, iws, 3) | ||
|
||
iws, err = issues_model.GetIssueSubscribers(db.DefaultContext, issueList[2], db.ListOptions{}) | ||
assert.NoError(t, err) | ||
// +isIssueWatching[] | ||
// -noIssueWatching[] | ||
// +participates[] | ||
// +poster[2] | ||
// +repoWatch[1,4,9,11] | ||
// -inactive[3,9] | ||
// => [1,2,4,11] | ||
assert.Len(t, iws, 4) | ||
|
||
iws, err = issues_model.GetIssueSubscribers(db.DefaultContext, issueList[3], db.ListOptions{}) | ||
assert.NoError(t, err) | ||
// +isIssueWatching[] | ||
// -noIssueWatching[] | ||
// +participates[] | ||
// +poster[2] | ||
// +repoWatch[] | ||
// -inactive[3,9] | ||
// => [2] | ||
assert.Len(t, iws, 1) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright 2023 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package v1_21 //nolint | ||
import ( | ||
"code.gitea.io/gitea/modules/timeutil" | ||
|
||
"xorm.io/xorm" | ||
) | ||
|
||
func AdjustIssueWatchIndexOrder(x *xorm.Engine) error { | ||
type IssueWatch struct { | ||
ID int64 `xorm:"pk autoincr"` | ||
UserID int64 `xorm:"UNIQUE(watch) NOT NULL"` | ||
IssueID int64 `xorm:"UNIQUE(watch) NOT NULL"` | ||
IsWatching bool `xorm:"NOT NULL"` | ||
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` | ||
UpdatedUnix timeutil.TimeStamp `xorm:"updated NOT NULL"` | ||
} | ||
// Drop the old index :(user_id,issue_id) | ||
// Then automatically created new index => (issue_id,user_id) | ||
return x.DropIndexes(new(IssueWatch)) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create the new indexes?