summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/git/branch_list.go34
-rw-r--r--models/git/branch_test.go6
-rw-r--r--models/issues/milestone.go9
-rw-r--r--models/issues/milestone_list.go143
-rw-r--r--models/issues/milestone_test.go76
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))