|
|
|
@ -187,6 +187,18 @@ func (issue *Issue) LoadAttributes() error {
|
|
|
|
|
return issue.loadAttributes(x)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetIsRead load the `IsRead` field of the issue
|
|
|
|
|
func (issue *Issue) GetIsRead(userID int64) error {
|
|
|
|
|
issueUser := &IssueUser{IssueID: issue.ID, UID: userID}
|
|
|
|
|
if has, err := x.Get(issueUser); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
} else if !has {
|
|
|
|
|
return ErrUserNotExist{UID: userID}
|
|
|
|
|
}
|
|
|
|
|
issue.IsRead = issueUser.IsRead
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HTMLURL returns the absolute URL to this issue.
|
|
|
|
|
func (issue *Issue) HTMLURL() string {
|
|
|
|
|
var path string
|
|
|
|
@ -554,8 +566,6 @@ func (issue *Issue) changeStatus(e *xorm.Session, doer *User, repo *Repository,
|
|
|
|
|
|
|
|
|
|
if err = updateIssueCols(e, issue, "is_closed"); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
} else if err = updateIssueUsersByStatus(e, issue.ID, isClosed); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update issue count of labels
|
|
|
|
@ -1087,13 +1097,9 @@ type IssueUser struct {
|
|
|
|
|
ID int64 `xorm:"pk autoincr"`
|
|
|
|
|
UID int64 `xorm:"INDEX"` // User ID.
|
|
|
|
|
IssueID int64
|
|
|
|
|
RepoID int64 `xorm:"INDEX"`
|
|
|
|
|
MilestoneID int64
|
|
|
|
|
IsRead bool
|
|
|
|
|
IsAssigned bool
|
|
|
|
|
IsMentioned bool
|
|
|
|
|
IsPoster bool
|
|
|
|
|
IsClosed bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newIssueUsers(e *xorm.Session, repo *Repository, issue *Issue) error {
|
|
|
|
@ -1109,24 +1115,17 @@ func newIssueUsers(e *xorm.Session, repo *Repository, issue *Issue) error {
|
|
|
|
|
// and just waste 1 unit is cheaper than re-allocate memory once.
|
|
|
|
|
issueUsers := make([]*IssueUser, 0, len(assignees)+1)
|
|
|
|
|
for _, assignee := range assignees {
|
|
|
|
|
isPoster := assignee.ID == issue.PosterID
|
|
|
|
|
issueUsers = append(issueUsers, &IssueUser{
|
|
|
|
|
IssueID: issue.ID,
|
|
|
|
|
RepoID: repo.ID,
|
|
|
|
|
UID: assignee.ID,
|
|
|
|
|
IsPoster: isPoster,
|
|
|
|
|
IsAssigned: assignee.ID == issue.AssigneeID,
|
|
|
|
|
})
|
|
|
|
|
if !isPosterAssignee && isPoster {
|
|
|
|
|
isPosterAssignee = true
|
|
|
|
|
}
|
|
|
|
|
isPosterAssignee = isPosterAssignee || assignee.ID == issue.PosterID
|
|
|
|
|
}
|
|
|
|
|
if !isPosterAssignee {
|
|
|
|
|
issueUsers = append(issueUsers, &IssueUser{
|
|
|
|
|
IssueID: issue.ID,
|
|
|
|
|
RepoID: repo.ID,
|
|
|
|
|
UID: issue.PosterID,
|
|
|
|
|
IsPoster: true,
|
|
|
|
|
IssueID: issue.ID,
|
|
|
|
|
UID: issue.PosterID,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1151,62 +1150,6 @@ func NewIssueUsers(repo *Repository, issue *Issue) (err error) {
|
|
|
|
|
return sess.Commit()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PairsContains returns true when pairs list contains given issue.
|
|
|
|
|
func PairsContains(ius []*IssueUser, issueID, uid int64) int {
|
|
|
|
|
for i := range ius {
|
|
|
|
|
if ius[i].IssueID == issueID &&
|
|
|
|
|
ius[i].UID == uid {
|
|
|
|
|
return i
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetIssueUsers returns issue-user pairs by given repository and user.
|
|
|
|
|
func GetIssueUsers(rid, uid int64, isClosed bool) ([]*IssueUser, error) {
|
|
|
|
|
ius := make([]*IssueUser, 0, 10)
|
|
|
|
|
err := x.Where("is_closed=?", isClosed).Find(&ius, &IssueUser{RepoID: rid, UID: uid})
|
|
|
|
|
return ius, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetIssueUserPairsByRepoIds returns issue-user pairs by given repository IDs.
|
|
|
|
|
func GetIssueUserPairsByRepoIds(rids []int64, isClosed bool, page int) ([]*IssueUser, error) {
|
|
|
|
|
if len(rids) == 0 {
|
|
|
|
|
return []*IssueUser{}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ius := make([]*IssueUser, 0, 10)
|
|
|
|
|
sess := x.
|
|
|
|
|
Limit(20, (page-1)*20).
|
|
|
|
|
Where("is_closed=?", isClosed).
|
|
|
|
|
In("repo_id", rids)
|
|
|
|
|
err := sess.Find(&ius)
|
|
|
|
|
return ius, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetIssueUserPairsByMode returns issue-user pairs by given repository and user.
|
|
|
|
|
func GetIssueUserPairsByMode(uid, rid int64, isClosed bool, page, filterMode int) ([]*IssueUser, error) {
|
|
|
|
|
ius := make([]*IssueUser, 0, 10)
|
|
|
|
|
sess := x.
|
|
|
|
|
Limit(20, (page-1)*20).
|
|
|
|
|
Where("uid=?", uid).
|
|
|
|
|
And("is_closed=?", isClosed)
|
|
|
|
|
if rid > 0 {
|
|
|
|
|
sess.And("repo_id=?", rid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch filterMode {
|
|
|
|
|
case FilterModeAssign:
|
|
|
|
|
sess.And("is_assigned=?", true)
|
|
|
|
|
case FilterModeCreate:
|
|
|
|
|
sess.And("is_poster=?", true)
|
|
|
|
|
default:
|
|
|
|
|
return ius, nil
|
|
|
|
|
}
|
|
|
|
|
err := sess.Find(&ius)
|
|
|
|
|
return ius, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateIssueMentions extracts mentioned people from content and
|
|
|
|
|
// updates issue-user relations for them.
|
|
|
|
|
func UpdateIssueMentions(e Engine, issueID int64, mentions []string) error {
|
|
|
|
@ -1436,16 +1379,6 @@ func UpdateIssue(issue *Issue) error {
|
|
|
|
|
return updateIssue(x, issue)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func updateIssueUsersByStatus(e Engine, issueID int64, isClosed bool) error {
|
|
|
|
|
_, err := e.Exec("UPDATE `issue_user` SET is_closed=? WHERE issue_id=?", isClosed, issueID)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateIssueUsersByStatus updates issue-user relations by issue status.
|
|
|
|
|
func UpdateIssueUsersByStatus(issueID int64, isClosed bool) error {
|
|
|
|
|
return updateIssueUsersByStatus(x, issueID, isClosed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func updateIssueUserByAssignee(e *xorm.Session, issue *Issue) (err error) {
|
|
|
|
|
if _, err = e.Exec("UPDATE `issue_user` SET is_assigned = ? WHERE issue_id = ?", false, issue.ID); err != nil {
|
|
|
|
|
return err
|
|
|
|
@ -1790,8 +1723,6 @@ func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilesto
|
|
|
|
|
|
|
|
|
|
if err = updateMilestone(e, m); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
} else if _, err = e.Exec("UPDATE `issue_user` SET milestone_id = 0 WHERE issue_id = ?", issue.ID); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1808,8 +1739,6 @@ func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilesto
|
|
|
|
|
|
|
|
|
|
if err = updateMilestone(e, m); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
} else if _, err = e.Exec("UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?", m.ID, issue.ID); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1873,8 +1802,6 @@ func DeleteMilestoneByRepoID(repoID, id int64) error {
|
|
|
|
|
|
|
|
|
|
if _, err = sess.Exec("UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?", m.ID); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
} else if _, err = sess.Exec("UPDATE `issue_user` SET milestone_id = 0 WHERE milestone_id = ?", m.ID); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return sess.Commit()
|
|
|
|
|
}
|
|
|
|
|