@ -1090,6 +1090,7 @@ type IssuesOptions struct {
AssigneeID int64
AssigneeID int64
PosterID int64
PosterID int64
MentionedID int64
MentionedID int64
ReviewRequestedID int64
MilestoneIDs [ ] int64
MilestoneIDs [ ] int64
ProjectID int64
ProjectID int64
ProjectBoardID int64
ProjectBoardID int64
@ -1151,8 +1152,7 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) {
}
}
if len ( opts . RepoIDs ) > 0 {
if len ( opts . RepoIDs ) > 0 {
// In case repository IDs are provided but actually no repository has issue.
applyReposCondition ( sess , opts . RepoIDs )
sess . In ( "issue.repo_id" , opts . RepoIDs )
}
}
switch opts . IsClosed {
switch opts . IsClosed {
@ -1163,18 +1163,19 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) {
}
}
if opts . AssigneeID > 0 {
if opts . AssigneeID > 0 {
sess . Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
applyAssigneeCondition ( sess , opts . AssigneeID )
And ( "issue_assignees.assignee_id = ?" , opts . AssigneeID )
}
}
if opts . PosterID > 0 {
if opts . PosterID > 0 {
sess . And ( "issue.poster_id=?" , opts . PosterID )
applyPosterCondition ( sess , opts . PosterID )
}
}
if opts . MentionedID > 0 {
if opts . MentionedID > 0 {
sess . Join ( "INNER" , "issue_user" , "issue.id = issue_user.issue_id" ) .
applyMentionedCondition ( sess , opts . MentionedID )
And ( "issue_user.is_mentioned = ?" , true ) .
}
And ( "issue_user.uid = ?" , opts . MentionedID )
if opts . ReviewRequestedID > 0 {
applyReviewRequestedCondition ( sess , opts . ReviewRequestedID )
}
}
if len ( opts . MilestoneIDs ) > 0 {
if len ( opts . MilestoneIDs ) > 0 {
@ -1232,6 +1233,33 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) {
}
}
}
}
func applyReposCondition ( sess * xorm . Session , repoIDs [ ] int64 ) * xorm . Session {
return sess . In ( "issue.repo_id" , repoIDs )
}
func applyAssigneeCondition ( sess * xorm . Session , assigneeID int64 ) * xorm . Session {
return sess . Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
And ( "issue_assignees.assignee_id = ?" , assigneeID )
}
func applyPosterCondition ( sess * xorm . Session , posterID int64 ) * xorm . Session {
return sess . And ( "issue.poster_id=?" , posterID )
}
func applyMentionedCondition ( sess * xorm . Session , mentionedID int64 ) * xorm . Session {
return sess . Join ( "INNER" , "issue_user" , "issue.id = issue_user.issue_id" ) .
And ( "issue_user.is_mentioned = ?" , true ) .
And ( "issue_user.uid = ?" , mentionedID )
}
func applyReviewRequestedCondition ( sess * xorm . Session , reviewRequestedID int64 ) * xorm . Session {
return sess . Join ( "INNER" , [ ] string { "review" , "r" } , "issue.id = r.issue_id" ) .
And ( "r.type = ?" , ReviewTypeRequest ) .
And ( "r.reviewer_id = ? and r.id in (select max(id) from review where issue_id = r.issue_id and reviewer_id = r.reviewer_id and type in (?, ?, ?))" +
" or r.reviewer_team_id in (select team_id from team_user where uid = ?)" ,
reviewRequestedID , ReviewTypeApprove , ReviewTypeReject , ReviewTypeRequest , reviewRequestedID )
}
// CountIssuesByRepo map from repoID to number of issues matching the options
// CountIssuesByRepo map from repoID to number of issues matching the options
func CountIssuesByRepo ( opts * IssuesOptions ) ( map [ int64 ] int64 , error ) {
func CountIssuesByRepo ( opts * IssuesOptions ) ( map [ int64 ] int64 , error ) {
sess := x . NewSession ( )
sess := x . NewSession ( )
@ -1364,6 +1392,7 @@ type IssueStats struct {
AssignCount int64
AssignCount int64
CreateCount int64
CreateCount int64
MentionCount int64
MentionCount int64
ReviewRequestedCount int64
}
}
// Filter modes.
// Filter modes.
@ -1372,6 +1401,7 @@ const (
FilterModeAssign
FilterModeAssign
FilterModeCreate
FilterModeCreate
FilterModeMention
FilterModeMention
FilterModeReviewRequested
)
)
func parseCountResult ( results [ ] map [ string ] [ ] byte ) int64 {
func parseCountResult ( results [ ] map [ string ] [ ] byte ) int64 {
@ -1387,14 +1417,15 @@ func parseCountResult(results []map[string][]byte) int64 {
// IssueStatsOptions contains parameters accepted by GetIssueStats.
// IssueStatsOptions contains parameters accepted by GetIssueStats.
type IssueStatsOptions struct {
type IssueStatsOptions struct {
RepoID int64
RepoID int64
Labels string
Labels string
MilestoneID int64
MilestoneID int64
AssigneeID int64
AssigneeID int64
MentionedID int64
MentionedID int64
PosterID int64
PosterID int64
IsPull util . OptionalBool
ReviewRequestedID int64
IssueIDs [ ] int64
IsPull util . OptionalBool
IssueIDs [ ] int64
}
}
// GetIssueStats returns issue statistic information by given conditions.
// GetIssueStats returns issue statistic information by given conditions.
@ -1423,6 +1454,7 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
accum . AssignCount += stats . AssignCount
accum . AssignCount += stats . AssignCount
accum . CreateCount += stats . CreateCount
accum . CreateCount += stats . CreateCount
accum . OpenCount += stats . MentionCount
accum . OpenCount += stats . MentionCount
accum . ReviewRequestedCount += stats . ReviewRequestedCount
i = chunk
i = chunk
}
}
return accum , nil
return accum , nil
@ -1460,18 +1492,19 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
}
}
if opts . AssigneeID > 0 {
if opts . AssigneeID > 0 {
sess . Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
applyAssigneeCondition ( sess , opts . AssigneeID )
And ( "issue_assignees.assignee_id = ?" , opts . AssigneeID )
}
}
if opts . PosterID > 0 {
if opts . PosterID > 0 {
sess . And ( "issue.poster_id = ?" , opts . PosterID )
applyPosterCondition ( sess , opts . PosterID )
}
}
if opts . MentionedID > 0 {
if opts . MentionedID > 0 {
sess . Join ( "INNER" , "issue_user" , "issue.id = issue_user.issue_id" ) .
applyMentionedCondition ( sess , opts . MentionedID )
And ( "issue_user.uid = ?" , opts . MentionedID ) .
}
And ( "issue_user.is_mentioned = ?" , true )
if opts . ReviewRequestedID > 0 {
applyReviewRequestedCondition ( sess , opts . ReviewRequestedID )
}
}
switch opts . IsPull {
switch opts . IsPull {
@ -1539,57 +1572,66 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
switch opts . FilterMode {
switch opts . FilterMode {
case FilterModeAll :
case FilterModeAll :
stats . OpenCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , false ) .
stats . OpenCount , err = applyReposCondition ( sess ( cond ) , opts . UserRepoIDs ) .
And ( builder . In ( "issue.repo_id" , opts . UserRepoIDs ) ) .
And ( "issue.is_closed = ?" , false ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
stats . ClosedCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , true ) .
stats . ClosedCount , err = applyReposCondition ( sess ( cond ) , opts . UserRepoIDs ) .
And ( builder . In ( "issue.repo_ id" , opts . UserRepoIDs ) ) .
And ( "issue.is_close d = ? " , true ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
case FilterModeAssign :
case FilterModeAssign :
stats . OpenCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , false ) .
stats . OpenCount , err = applyAssigneeCondition ( sess ( cond ) , opts . UserID ) .
Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
And ( "issue.is_closed = ?" , false ) .
And ( "issue_assignees.assignee_id = ?" , opts . UserID ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
stats . ClosedCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , true ) .
stats . ClosedCount , err = applyAssigneeCondition ( sess ( cond ) , opts . UserID ) .
Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
And ( "issue.is_closed = ?" , true ) .
And ( "issue_assignees.assignee_id = ?" , opts . UserID ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
case FilterModeCreate :
case FilterModeCreate :
stats . OpenCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , false ) .
stats . OpenCount , err = applyPosterCondition ( sess ( cond ) , opts . UserID ) .
And ( "issue.poster_id = ?" , opts . UserID ) .
And ( "issue.is_closed = ?" , false ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
stats . ClosedCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , true ) .
stats . ClosedCount , err = applyPosterCondition ( sess ( cond ) , opts . UserID ) .
And ( "issue.poster_id = ?" , opts . UserID ) .
And ( "issue.is_closed = ?" , true ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
case FilterModeMention :
case FilterModeMention :
stats . OpenCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , false ) .
stats . OpenCount , err = applyMentionedCondition ( sess ( cond ) , opts . UserID ) .
Join ( "INNER" , "issue_user" , "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?" , true ) .
And ( "issue.is_closed = ?" , false ) .
And ( "issue_user.uid = ?" , opts . UserID ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
stats . ClosedCount , err = sess ( cond ) . And ( "issue.is_closed = ?" , true ) .
stats . ClosedCount , err = applyMentionedCondition ( sess ( cond ) , opts . UserID ) .
Join ( "INNER" , "issue_user" , "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?" , true ) .
And ( "issue.is_closed = ?" , true ) .
And ( "issue_user.uid = ?" , opts . UserID ) .
Count ( new ( Issue ) )
if err != nil {
return nil , err
}
case FilterModeReviewRequested :
stats . OpenCount , err = applyReviewRequestedCondition ( sess ( cond ) , opts . UserID ) .
And ( "issue.is_closed = ?" , false ) .
Count ( new ( Issue ) )
if err != nil {
return nil , err
}
stats . ClosedCount , err = applyReviewRequestedCondition ( sess ( cond ) , opts . UserID ) .
And ( "issue.is_closed = ?" , true ) .
Count ( new ( Issue ) )
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
@ -1597,32 +1639,27 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
}
}
cond = cond . And ( builder . Eq { "issue.is_closed" : opts . IsClosed } )
cond = cond . And ( builder . Eq { "issue.is_closed" : opts . IsClosed } )
stats . AssignCount , err = sess ( cond ) .
stats . AssignCount , err = applyAssigneeCondition ( sess ( cond ) , opts . UserID ) . Count ( new ( Issue ) )
Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
And ( "issue_assignees.assignee_id = ?" , opts . UserID ) .
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
stats . CreateCount , err = sess ( cond ) .
stats . CreateCount , err = applyPosterCondition ( sess ( cond ) , opts . UserID ) . Count ( new ( Issue ) )
And ( "poster_id = ?" , opts . UserID ) .
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
stats . MentionCount , err = sess ( cond ) .
stats . MentionCount , err = applyMentionedCondition ( sess ( cond ) , opts . UserID ) . Count ( new ( Issue ) )
Join ( "INNER" , "issue_user" , "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?" , true ) .
And ( "issue_user.uid = ?" , opts . UserID ) .
Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
stats . YourRepositoriesCount , err = sess ( cond ) .
stats . YourRepositoriesCount , err = applyReposCondition ( sess ( cond ) , opts . UserRepoIDs ) . Count ( new ( Issue ) )
And ( builder . In ( "issue.repo_id" , opts . UserRepoIDs ) ) .
if err != nil {
Count ( new ( Issue ) )
return nil , err
}
stats . ReviewRequestedCount , err = applyReviewRequestedCondition ( sess ( cond ) , opts . UserID ) . Count ( new ( Issue ) )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
@ -1646,13 +1683,11 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen
switch filterMode {
switch filterMode {
case FilterModeAssign :
case FilterModeAssign :
openCountSession . Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
applyAssigneeCondition ( openCountSession , uid )
And ( "issue_assignees.assignee_id = ?" , uid )
applyAssigneeCondition ( closedCountSession , uid )
closedCountSession . Join ( "INNER" , "issue_assignees" , "issue.id = issue_assignees.issue_id" ) .
And ( "issue_assignees.assignee_id = ?" , uid )
case FilterModeCreate :
case FilterModeCreate :
openCountSession . And ( "poster_id = ?" , uid )
applyPosterCondition ( openCountSession , uid )
closedCountSession . And ( "poster_id = ?" , uid )
applyPosterCondition ( closedCountSession , uid )
}
}
openResult , _ := openCountSession . Count ( new ( Issue ) )
openResult , _ := openCountSession . Count ( new ( Issue ) )