Skip to content

Commit 209f76e

Browse files
committed
fix counting error on issues/prs
1 parent 8ced437 commit 209f76e

File tree

4 files changed

+87
-105
lines changed

4 files changed

+87
-105
lines changed

models/issue.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,12 +1630,12 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
16301630

16311631
// UserIssueStatsOptions contains parameters accepted by GetUserIssueStats.
16321632
type UserIssueStatsOptions struct {
1633-
UserID int64
1634-
RepoID int64
1635-
UserRepoIDs []int64
1636-
FilterMode int
1637-
IsPull bool
1638-
IsClosed bool
1633+
UserID int64
1634+
RepoID int64
1635+
RepoSubQuery *builder.Builder
1636+
FilterMode int
1637+
IsPull bool
1638+
IsClosed bool
16391639
}
16401640

16411641
// GetUserIssueStats returns issue statistic information for dashboard by given conditions.
@@ -1647,18 +1647,18 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
16471647
cond = cond.And(builder.Eq{"issue.is_pull": opts.IsPull})
16481648
if opts.RepoID > 0 {
16491649
cond = cond.And(builder.Eq{"issue.repo_id": opts.RepoID})
1650+
} else if opts.RepoSubQuery != nil {
1651+
cond = cond.And(builder.In("issue.repo_id", opts.RepoSubQuery))
16501652
}
16511653

16521654
switch opts.FilterMode {
16531655
case FilterModeAll:
16541656
stats.OpenCount, err = x.Where(cond).And("is_closed = ?", false).
1655-
And(builder.In("issue.repo_id", opts.UserRepoIDs)).
16561657
Count(new(Issue))
16571658
if err != nil {
16581659
return nil, err
16591660
}
16601661
stats.ClosedCount, err = x.Where(cond).And("is_closed = ?", true).
1661-
And(builder.In("issue.repo_id", opts.UserRepoIDs)).
16621662
Count(new(Issue))
16631663
if err != nil {
16641664
return nil, err
@@ -1733,7 +1733,6 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
17331733
}
17341734

17351735
stats.YourRepositoriesCount, err = x.Where(cond).
1736-
And(builder.In("issue.repo_id", opts.UserRepoIDs)).
17371736
Count(new(Issue))
17381737
if err != nil {
17391738
return nil, err

models/issue_test.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/stretchr/testify/assert"
13+
"xorm.io/builder"
1314
)
1415

1516
func TestIssue_ReplaceLabels(t *testing.T) {
@@ -266,10 +267,12 @@ func TestGetUserIssueStats(t *testing.T) {
266267
},
267268
{
268269
UserIssueStatsOptions{
269-
UserID: 2,
270-
UserRepoIDs: []int64{1, 2},
271-
FilterMode: FilterModeAll,
272-
IsClosed: true,
270+
UserID: 2,
271+
RepoSubQuery: builder.Select("repository.id").
272+
From("repository").
273+
Where(builder.In("repository.id", []int64{1, 2})),
274+
FilterMode: FilterModeAll,
275+
IsClosed: true,
273276
},
274277
IssueStats{
275278
YourRepositoriesCount: 2,

models/user.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -620,10 +620,30 @@ func (u *User) UnitRepositoriesSubQuery(units ...UnitType) *builder.Builder {
620620
b := builder.Select("repository.id").From("repository")
621621

622622
if len(units) > 0 {
623-
b = b.Join("INNER", "repo_unit", "repository.id = repo_unit.repo_id")
624-
b = b.Where(builder.In("repo_unit.type", units))
623+
b.Join("INNER", "repo_unit", builder.Expr("repository.id = repo_unit.repo_id").
624+
And(builder.In("repo_unit.type", units)),
625+
)
625626
}
626-
return b.Where(builder.Eq{"owner_id": u.ID})
627+
return b.Where(builder.Eq{"repository.owner_id": u.ID})
628+
}
629+
630+
// OrgUnitRepositoriesSubQuery returns repositories query builder according orgnizations and units
631+
func (u *User) OrgUnitRepositoriesSubQuery(userID int64, units ...UnitType) *builder.Builder {
632+
b := builder.
633+
Select("team_repo.repo_id").
634+
From("team_repo").
635+
Join("INNER", "team_user", builder.Eq{"team_user.uid": userID}.And(
636+
builder.Expr("team_user.team_id = team_repo.team_id"),
637+
))
638+
if len(units) > 0 {
639+
b.Join("INNER", "team_unit", builder.Eq{"team_unit.org_id": u.ID}.And(
640+
builder.Expr("team_unit.team_id = team_repo.team_id").And(
641+
builder.In("`type`", units),
642+
),
643+
))
644+
}
645+
return b.Where(builder.Eq{"team_repo.org_id": u.ID}).
646+
GroupBy("team_repo.repo_id")
627647
}
628648

629649
// GetMirrorRepositories returns mirror repositories that user owns, including private repositories.

routers/user/home.go

Lines changed: 49 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@ import (
1414
"code.gitea.io/gitea/models"
1515
"code.gitea.io/gitea/modules/base"
1616
"code.gitea.io/gitea/modules/context"
17-
"code.gitea.io/gitea/modules/log"
1817
"code.gitea.io/gitea/modules/setting"
1918
"code.gitea.io/gitea/modules/util"
2019

2120
"github.com/keybase/go-crypto/openpgp"
2221
"github.com/keybase/go-crypto/openpgp/armor"
23-
"github.com/unknwon/com"
2422
)
2523

2624
const (
@@ -152,6 +150,24 @@ func Dashboard(ctx *context.Context) {
152150
// Issues render the user issues page
153151
func Issues(ctx *context.Context) {
154152
isPullList := ctx.Params(":type") == "pulls"
153+
repoID := ctx.QueryInt64("repo")
154+
if repoID > 0 {
155+
repo, err := models.GetRepositoryByID(repoID)
156+
if err != nil {
157+
ctx.ServerError("GetRepositoryByID", err)
158+
return
159+
}
160+
perm, err := models.GetUserRepoPermission(repo, ctx.User)
161+
if err != nil {
162+
ctx.ServerError("GetUserRepoPermission", err)
163+
return
164+
}
165+
if !perm.CanReadIssuesOrPulls(isPullList) {
166+
ctx.NotFound("Repository does not exist or you have no permission", nil)
167+
return
168+
}
169+
}
170+
155171
if isPullList {
156172
ctx.Data["Title"] = ctx.Tr("pull_requests")
157173
ctx.Data["PageIsPulls"] = true
@@ -194,54 +210,32 @@ func Issues(ctx *context.Context) {
194210
page = 1
195211
}
196212

197-
repoID := ctx.QueryInt64("repo")
198-
isShowClosed := ctx.Query("state") == "closed"
213+
var (
214+
isShowClosed = ctx.Query("state") == "closed"
215+
err error
216+
opts = &models.IssuesOptions{
217+
IsClosed: util.OptionalBoolOf(isShowClosed),
218+
IsPull: util.OptionalBoolOf(isPullList),
219+
SortType: sortType,
220+
}
221+
)
199222

200223
// Get repositories.
201-
var err error
202-
var userRepoIDs []int64
203-
opts := &models.IssuesOptions{
204-
IsClosed: util.OptionalBoolOf(isShowClosed),
205-
IsPull: util.OptionalBoolOf(isPullList),
206-
SortType: sortType,
207-
}
208-
209-
if ctxUser.IsOrganization() {
210-
env, err := ctxUser.AccessibleReposEnv(ctx.User.ID)
211-
if err != nil {
212-
ctx.ServerError("AccessibleReposEnv", err)
213-
return
214-
}
215-
userRepoIDs, err = env.RepoIDs(1, ctxUser.NumRepos)
216-
if err != nil {
217-
ctx.ServerError("env.RepoIDs", err)
218-
return
219-
}
224+
if repoID > 0 {
225+
opts.RepoIDs = []int64{repoID}
220226
} else {
221227
unitType := models.UnitTypeIssues
222228
if isPullList {
223229
unitType = models.UnitTypePullRequests
224230
}
225-
opts.RepoSubQuery = ctxUser.UnitRepositoriesSubQuery(unitType)
226-
}
227-
if len(userRepoIDs) == 0 {
228-
userRepoIDs = []int64{-1}
229-
}
230-
231-
if repoID > 0 {
232-
opts.RepoIDs = []int64{repoID}
231+
if ctxUser.IsOrganization() {
232+
opts.RepoSubQuery = ctxUser.OrgUnitRepositoriesSubQuery(ctx.User.ID, unitType)
233+
} else {
234+
opts.RepoSubQuery = ctxUser.UnitRepositoriesSubQuery(unitType)
235+
}
233236
}
234237

235238
switch filterMode {
236-
case models.FilterModeAll:
237-
if repoID > 0 {
238-
if !com.IsSliceContainsInt64(userRepoIDs, repoID) {
239-
// force an empty result
240-
opts.RepoIDs = []int64{-1}
241-
}
242-
} else {
243-
opts.RepoIDs = userRepoIDs
244-
}
245239
case models.FilterModeAssign:
246240
opts.AssigneeID = ctxUser.ID
247241
case models.FilterModeCreate:
@@ -250,14 +244,6 @@ func Issues(ctx *context.Context) {
250244
opts.MentionedID = ctxUser.ID
251245
}
252246

253-
counts, err := models.CountIssuesByRepo(opts)
254-
if err != nil {
255-
ctx.ServerError("CountIssuesByRepo", err)
256-
return
257-
}
258-
259-
opts.Page = page
260-
opts.PageSize = setting.UI.IssuePagingNum
261247
var labelIDs []int64
262248
selectLabels := ctx.Query("labels")
263249
if len(selectLabels) > 0 && selectLabels != "0" {
@@ -269,6 +255,15 @@ func Issues(ctx *context.Context) {
269255
}
270256
opts.LabelIDs = labelIDs
271257

258+
counts, err := models.CountIssuesByRepo(opts)
259+
if err != nil {
260+
ctx.ServerError("CountIssuesByRepo", err)
261+
return
262+
}
263+
264+
opts.Page = page
265+
opts.PageSize = setting.UI.IssuePagingNum
266+
272267
issues, err := models.Issues(opts)
273268
if err != nil {
274269
ctx.ServerError("Issues", err)
@@ -285,41 +280,6 @@ func Issues(ctx *context.Context) {
285280
showReposMap[repoID] = repo
286281
}
287282

288-
if repoID > 0 {
289-
if _, ok := showReposMap[repoID]; !ok {
290-
repo, err := models.GetRepositoryByID(repoID)
291-
if models.IsErrRepoNotExist(err) {
292-
ctx.NotFound("GetRepositoryByID", err)
293-
return
294-
} else if err != nil {
295-
ctx.ServerError("GetRepositoryByID", fmt.Errorf("[%d]%v", repoID, err))
296-
return
297-
}
298-
showReposMap[repoID] = repo
299-
}
300-
301-
repo := showReposMap[repoID]
302-
303-
// Check if user has access to given repository.
304-
perm, err := models.GetUserRepoPermission(repo, ctxUser)
305-
if err != nil {
306-
ctx.ServerError("GetUserRepoPermission", fmt.Errorf("[%d]%v", repoID, err))
307-
return
308-
}
309-
if !perm.CanRead(models.UnitTypeIssues) {
310-
if log.IsTrace() {
311-
log.Trace("Permission Denied: User %-v cannot read %-v of repo %-v\n"+
312-
"User in repo has Permissions: %-+v",
313-
ctxUser,
314-
models.UnitTypeIssues,
315-
repo,
316-
perm)
317-
}
318-
ctx.Status(404)
319-
return
320-
}
321-
}
322-
323283
showRepos := models.RepositoryListOfMap(showReposMap)
324284
sort.Sort(showRepos)
325285
if err = showRepos.LoadAttributes(); err != nil {
@@ -337,12 +297,12 @@ func Issues(ctx *context.Context) {
337297
}
338298

339299
issueStats, err := models.GetUserIssueStats(models.UserIssueStatsOptions{
340-
UserID: ctxUser.ID,
341-
RepoID: repoID,
342-
UserRepoIDs: userRepoIDs,
343-
FilterMode: filterMode,
344-
IsPull: isPullList,
345-
IsClosed: isShowClosed,
300+
UserID: ctxUser.ID,
301+
RepoID: repoID,
302+
RepoSubQuery: opts.RepoSubQuery,
303+
FilterMode: filterMode,
304+
IsPull: isPullList,
305+
IsClosed: isShowClosed,
346306
})
347307
if err != nil {
348308
ctx.ServerError("GetUserIssueStats", err)

0 commit comments

Comments
 (0)