diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/git/branch_list.go | 34 | ||||
-rw-r--r-- | models/git/branch_test.go | 6 | ||||
-rw-r--r-- | models/issues/milestone.go | 9 | ||||
-rw-r--r-- | models/issues/milestone_list.go | 143 | ||||
-rw-r--r-- | models/issues/milestone_test.go | 76 |
5 files changed, 94 insertions, 174 deletions
diff --git a/models/git/branch_list.go b/models/git/branch_list.go index 2efe495264..0e8d28038a 100644 --- a/models/git/branch_list.go +++ b/models/git/branch_list.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/modules/util" "xorm.io/builder" - "xorm.io/xorm" ) type BranchList []*Branch @@ -91,31 +90,20 @@ func (opts FindBranchOptions) ToConds() builder.Cond { return cond } -func CountBranches(ctx context.Context, opts FindBranchOptions) (int64, error) { - return db.GetEngine(ctx).Where(opts.ToConds()).Count(&Branch{}) -} - -func orderByBranches(sess *xorm.Session, opts FindBranchOptions) *xorm.Session { +func (opts FindBranchOptions) ToOrders() string { + orderBy := opts.OrderBy if !opts.IsDeletedBranch.IsFalse() { // if deleted branch included, put them at the end - sess = sess.OrderBy("is_deleted ASC") + if orderBy != "" { + orderBy += ", " + } + orderBy += "is_deleted ASC" } - - if opts.OrderBy == "" { + if orderBy == "" { // the commit_time might be the same, so add the "name" to make sure the order is stable - opts.OrderBy = "commit_time DESC, name ASC" + return "commit_time DESC, name ASC" } - return sess.OrderBy(opts.OrderBy) -} -func FindBranches(ctx context.Context, opts FindBranchOptions) (BranchList, error) { - sess := db.GetEngine(ctx).Where(opts.ToConds()) - if opts.PageSize > 0 && !opts.IsListAll() { - sess = db.SetSessionPagination(sess, &opts.ListOptions) - } - sess = orderByBranches(sess, opts) - - var branches []*Branch - return branches, sess.Find(&branches) + return orderBy } func FindBranchNames(ctx context.Context, opts FindBranchOptions) ([]string, error) { @@ -123,9 +111,9 @@ func FindBranchNames(ctx context.Context, opts FindBranchOptions) ([]string, err if opts.PageSize > 0 && !opts.IsListAll() { sess = db.SetSessionPagination(sess, &opts.ListOptions) } - sess = orderByBranches(sess, opts) + var branches []string - if err := sess.Table("branch").Find(&branches); err != nil { + if err := sess.Table("branch").OrderBy(opts.ToOrders()).Find(&branches); err != nil { return nil, err } return branches, nil diff --git a/models/git/branch_test.go b/models/git/branch_test.go index 07b243e5e6..ce4cbd56a1 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -45,10 +45,8 @@ func TestGetDeletedBranches(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - branches, err := git_model.FindBranches(db.DefaultContext, git_model.FindBranchOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, + branches, err := db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{ + ListOptions: db.ListOptionsAll, RepoID: repo.ID, IsDeletedBranch: util.OptionalBoolTrue, }) diff --git a/models/issues/milestone.go b/models/issues/milestone.go index ad1d5d0453..9db7cb2b15 100644 --- a/models/issues/milestone.go +++ b/models/issues/milestone.go @@ -295,16 +295,15 @@ func DeleteMilestoneByRepoID(ctx context.Context, repoID, id int64) error { return err } - numMilestones, err := CountMilestones(ctx, GetMilestonesOption{ + numMilestones, err := db.Count[Milestone](ctx, FindMilestoneOptions{ RepoID: repo.ID, - State: api.StateAll, }) if err != nil { return err } - numClosedMilestones, err := CountMilestones(ctx, GetMilestonesOption{ - RepoID: repo.ID, - State: api.StateClosed, + numClosedMilestones, err := db.Count[Milestone](ctx, FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: util.OptionalBoolTrue, }) if err != nil { return err diff --git a/models/issues/milestone_list.go b/models/issues/milestone_list.go index d55c18a995..f331b2590f 100644 --- a/models/issues/milestone_list.go +++ b/models/issues/milestone_list.go @@ -8,8 +8,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/setting" - api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -25,31 +24,31 @@ func (milestones MilestoneList) getMilestoneIDs() []int64 { return ids } -// GetMilestonesOption contain options to get milestones -type GetMilestonesOption struct { +// FindMilestoneOptions contain options to get milestones +type FindMilestoneOptions struct { db.ListOptions RepoID int64 - State api.StateType + IsClosed util.OptionalBool Name string SortType string + RepoCond builder.Cond + RepoIDs []int64 } -func (opts GetMilestonesOption) toCond() builder.Cond { +func (opts FindMilestoneOptions) ToConds() builder.Cond { cond := builder.NewCond() if opts.RepoID != 0 { cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) } - - switch opts.State { - case api.StateClosed: - cond = cond.And(builder.Eq{"is_closed": true}) - case api.StateAll: - break - // api.StateOpen: - default: - cond = cond.And(builder.Eq{"is_closed": false}) + if opts.IsClosed != util.OptionalBoolNone { + cond = cond.And(builder.Eq{"is_closed": opts.IsClosed.IsTrue()}) + } + if opts.RepoCond != nil && opts.RepoCond.IsValid() { + cond = cond.And(builder.In("repo_id", builder.Select("id").From("repository").Where(opts.RepoCond))) + } + if len(opts.RepoIDs) > 0 { + cond = cond.And(builder.In("repo_id", opts.RepoIDs)) } - if len(opts.Name) != 0 { cond = cond.And(db.BuildCaseInsensitiveLike("name", opts.Name)) } @@ -57,34 +56,23 @@ func (opts GetMilestonesOption) toCond() builder.Cond { return cond } -// GetMilestones returns milestones filtered by GetMilestonesOption's -func GetMilestones(ctx context.Context, opts GetMilestonesOption) (MilestoneList, int64, error) { - sess := db.GetEngine(ctx).Where(opts.toCond()) - - if opts.Page != 0 { - sess = db.SetSessionPagination(sess, &opts) - } - +func (opts FindMilestoneOptions) ToOrders() string { switch opts.SortType { case "furthestduedate": - sess.Desc("deadline_unix") + return "deadline_unix DESC" case "leastcomplete": - sess.Asc("completeness") + return "completeness ASC" case "mostcomplete": - sess.Desc("completeness") + return "completeness DESC" case "leastissues": - sess.Asc("num_issues") + return "num_issues ASC" case "mostissues": - sess.Desc("num_issues") + return "num_issues DESC" case "id": - sess.Asc("id") + return "id ASC" default: - sess.Asc("deadline_unix").Asc("id") + return "deadline_unix ASC, id ASC" } - - miles := make([]*Milestone, 0, opts.PageSize) - total, err := sess.FindAndCount(&miles) - return miles, total, err } // GetMilestoneIDsByNames returns a list of milestone ids by given names. @@ -99,49 +87,6 @@ func GetMilestoneIDsByNames(ctx context.Context, names []string) ([]int64, error Find(&ids) } -// SearchMilestones search milestones -func SearchMilestones(ctx context.Context, repoCond builder.Cond, page int, isClosed bool, sortType, keyword string) (MilestoneList, error) { - miles := make([]*Milestone, 0, setting.UI.IssuePagingNum) - sess := db.GetEngine(ctx).Where("is_closed = ?", isClosed) - if len(keyword) > 0 { - sess = sess.And(builder.Like{"UPPER(name)", strings.ToUpper(keyword)}) - } - if repoCond.IsValid() { - sess.In("repo_id", builder.Select("id").From("repository").Where(repoCond)) - } - if page > 0 { - sess = sess.Limit(setting.UI.IssuePagingNum, (page-1)*setting.UI.IssuePagingNum) - } - - switch sortType { - case "furthestduedate": - sess.Desc("deadline_unix") - case "leastcomplete": - sess.Asc("completeness") - case "mostcomplete": - sess.Desc("completeness") - case "leastissues": - sess.Asc("num_issues") - case "mostissues": - sess.Desc("num_issues") - default: - sess.Asc("deadline_unix") - } - return miles, sess.Find(&miles) -} - -// GetMilestonesByRepoIDs returns a list of milestones of given repositories and status. -func GetMilestonesByRepoIDs(ctx context.Context, repoIDs []int64, page int, isClosed bool, sortType string) (MilestoneList, error) { - return SearchMilestones( - ctx, - builder.In("repo_id", repoIDs), - page, - isClosed, - sortType, - "", - ) -} - // LoadTotalTrackedTimes loads for every milestone in the list the TotalTrackedTime by a batch request func (milestones MilestoneList) LoadTotalTrackedTimes(ctx context.Context) error { type totalTimesByMilestone struct { @@ -183,47 +128,9 @@ func (milestones MilestoneList) LoadTotalTrackedTimes(ctx context.Context) error return nil } -// CountMilestones returns number of milestones in given repository with other options -func CountMilestones(ctx context.Context, opts GetMilestonesOption) (int64, error) { - return db.GetEngine(ctx). - Where(opts.toCond()). - Count(new(Milestone)) -} - -// CountMilestonesByRepoCond map from repo conditions to number of milestones matching the options` -func CountMilestonesByRepoCond(ctx context.Context, repoCond builder.Cond, isClosed bool) (map[int64]int64, error) { - sess := db.GetEngine(ctx).Where("is_closed = ?", isClosed) - if repoCond.IsValid() { - sess.In("repo_id", builder.Select("id").From("repository").Where(repoCond)) - } - - countsSlice := make([]*struct { - RepoID int64 - Count int64 - }, 0, 10) - if err := sess.GroupBy("repo_id"). - Select("repo_id AS repo_id, COUNT(*) AS count"). - Table("milestone"). - Find(&countsSlice); err != nil { - return nil, err - } - - countMap := make(map[int64]int64, len(countsSlice)) - for _, c := range countsSlice { - countMap[c.RepoID] = c.Count - } - return countMap, nil -} - // CountMilestonesByRepoCondAndKw map from repo conditions and the keyword of milestones' name to number of milestones matching the options` -func CountMilestonesByRepoCondAndKw(ctx context.Context, repoCond builder.Cond, keyword string, isClosed bool) (map[int64]int64, error) { - sess := db.GetEngine(ctx).Where("is_closed = ?", isClosed) - if len(keyword) > 0 { - sess = sess.And(builder.Like{"UPPER(name)", strings.ToUpper(keyword)}) - } - if repoCond.IsValid() { - sess.In("repo_id", builder.Select("id").From("repository").Where(repoCond)) - } +func CountMilestonesMap(ctx context.Context, opts FindMilestoneOptions) (map[int64]int64, error) { + sess := db.GetEngine(ctx).Where(opts.ToConds()) countsSlice := make([]*struct { RepoID int64 diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index ecfccf6ddb..0581d3d148 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" "xorm.io/builder" @@ -39,10 +40,15 @@ func TestGetMilestoneByRepoID(t *testing.T) { func TestGetMilestonesByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64, state api.StateType) { + var isClosed util.OptionalBool + switch state { + case api.StateClosed, api.StateOpen: + isClosed = util.OptionalBoolOf(state == api.StateClosed) + } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: repo.ID, - State: state, + milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: isClosed, }) assert.NoError(t, err) @@ -77,9 +83,9 @@ func TestGetMilestonesByRepoID(t *testing.T) { test(3, api.StateClosed) test(3, api.StateAll) - milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: unittest.NonexistentID, - State: api.StateOpen, + milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: unittest.NonexistentID, + IsClosed: util.OptionalBoolFalse, }) assert.NoError(t, err) assert.Len(t, milestones, 0) @@ -90,13 +96,13 @@ func TestGetMilestones(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, }, RepoID: repo.ID, - State: api.StateOpen, + IsClosed: util.OptionalBoolFalse, SortType: sortType, }) assert.NoError(t, err) @@ -107,13 +113,13 @@ func TestGetMilestones(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - milestones, _, err = issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, }, RepoID: repo.ID, - State: api.StateClosed, + IsClosed: util.OptionalBoolTrue, Name: "", SortType: sortType, }) @@ -150,9 +156,8 @@ func TestCountRepoMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ RepoID: repoID, - State: api.StateAll, }) assert.NoError(t, err) assert.EqualValues(t, repo.NumMilestones, count) @@ -161,9 +166,8 @@ func TestCountRepoMilestones(t *testing.T) { test(2) test(3) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ RepoID: unittest.NonexistentID, - State: api.StateAll, }) assert.NoError(t, err) assert.EqualValues(t, 0, count) @@ -173,9 +177,9 @@ func TestCountRepoClosedMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: repoID, - State: api.StateClosed, + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: repoID, + IsClosed: util.OptionalBoolTrue, }) assert.NoError(t, err) assert.EqualValues(t, repo.NumClosedMilestones, count) @@ -184,9 +188,9 @@ func TestCountRepoClosedMilestones(t *testing.T) { test(2) test(3) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: unittest.NonexistentID, - State: api.StateClosed, + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: unittest.NonexistentID, + IsClosed: util.OptionalBoolTrue, }) assert.NoError(t, err) assert.EqualValues(t, 0, count) @@ -201,12 +205,19 @@ func TestCountMilestonesByRepoIDs(t *testing.T) { repo1OpenCount, repo1ClosedCount := milestonesCount(1) repo2OpenCount, repo2ClosedCount := milestonesCount(2) - openCounts, err := issues_model.CountMilestonesByRepoCond(db.DefaultContext, builder.In("repo_id", []int64{1, 2}), false) + openCounts, err := issues_model.CountMilestonesMap(db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoIDs: []int64{1, 2}, + IsClosed: util.OptionalBoolFalse, + }) assert.NoError(t, err) assert.EqualValues(t, repo1OpenCount, openCounts[1]) assert.EqualValues(t, repo2OpenCount, openCounts[2]) - closedCounts, err := issues_model.CountMilestonesByRepoCond(db.DefaultContext, builder.In("repo_id", []int64{1, 2}), true) + closedCounts, err := issues_model.CountMilestonesMap(db.DefaultContext, + issues_model.FindMilestoneOptions{ + RepoIDs: []int64{1, 2}, + IsClosed: util.OptionalBoolTrue, + }) assert.NoError(t, err) assert.EqualValues(t, repo1ClosedCount, closedCounts[1]) assert.EqualValues(t, repo2ClosedCount, closedCounts[2]) @@ -218,7 +229,15 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - openMilestones, err := issues_model.GetMilestonesByRepoIDs(db.DefaultContext, []int64{repo1.ID, repo2.ID}, page, false, sortType) + openMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: setting.UI.IssuePagingNum, + }, + RepoIDs: []int64{repo1.ID, repo2.ID}, + IsClosed: util.OptionalBoolFalse, + SortType: sortType, + }) assert.NoError(t, err) assert.Len(t, openMilestones, repo1.NumOpenMilestones+repo2.NumOpenMilestones) values := make([]int, len(openMilestones)) @@ -227,7 +246,16 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - closedMilestones, err := issues_model.GetMilestonesByRepoIDs(db.DefaultContext, []int64{repo1.ID, repo2.ID}, page, true, sortType) + closedMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, + issues_model.FindMilestoneOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: setting.UI.IssuePagingNum, + }, + RepoIDs: []int64{repo1.ID, repo2.ID}, + IsClosed: util.OptionalBoolTrue, + SortType: sortType, + }) assert.NoError(t, err) assert.Len(t, closedMilestones, repo1.NumClosedMilestones+repo2.NumClosedMilestones) values = make([]int, len(closedMilestones)) |