88 "strings"
99
1010 "code.gitea.io/gitea/models/db"
11- "code.gitea.io/gitea/modules/setting"
12- api "code.gitea.io/gitea/modules/structs"
11+ "code.gitea.io/gitea/modules/util"
1312
1413 "xorm.io/builder"
1514)
@@ -25,66 +24,55 @@ func (milestones MilestoneList) getMilestoneIDs() []int64 {
2524 return ids
2625}
2726
28- // GetMilestonesOption contain options to get milestones
29- type GetMilestonesOption struct {
27+ // FindMilestoneOptions contain options to get milestones
28+ type FindMilestoneOptions struct {
3029 db.ListOptions
3130 RepoID int64
32- State api. StateType
31+ IsClosed util. OptionalBool
3332 Name string
3433 SortType string
34+ RepoCond builder.Cond
35+ RepoIDs []int64
3536}
3637
37- func (opts GetMilestonesOption ) toCond () builder.Cond {
38+ func (opts FindMilestoneOptions ) ToConds () builder.Cond {
3839 cond := builder .NewCond ()
3940 if opts .RepoID != 0 {
4041 cond = cond .And (builder.Eq {"repo_id" : opts .RepoID })
4142 }
42-
43- switch opts .State {
44- case api .StateClosed :
45- cond = cond .And (builder.Eq {"is_closed" : true })
46- case api .StateAll :
47- break
48- // api.StateOpen:
49- default :
50- cond = cond .And (builder.Eq {"is_closed" : false })
43+ if opts .IsClosed != util .OptionalBoolNone {
44+ cond = cond .And (builder.Eq {"is_closed" : opts .IsClosed .IsTrue ()})
45+ }
46+ if opts .RepoCond != nil && opts .RepoCond .IsValid () {
47+ cond = cond .And (builder .In ("repo_id" , builder .Select ("id" ).From ("repository" ).Where (opts .RepoCond )))
48+ }
49+ if len (opts .RepoIDs ) > 0 {
50+ cond = cond .And (builder .In ("repo_id" , opts .RepoIDs ))
5151 }
52-
5352 if len (opts .Name ) != 0 {
5453 cond = cond .And (db .BuildCaseInsensitiveLike ("name" , opts .Name ))
5554 }
5655
5756 return cond
5857}
5958
60- // GetMilestones returns milestones filtered by GetMilestonesOption's
61- func GetMilestones (ctx context.Context , opts GetMilestonesOption ) (MilestoneList , int64 , error ) {
62- sess := db .GetEngine (ctx ).Where (opts .toCond ())
63-
64- if opts .Page != 0 {
65- sess = db .SetSessionPagination (sess , & opts )
66- }
67-
59+ func (opts FindMilestoneOptions ) ToOrders () string {
6860 switch opts .SortType {
6961 case "furthestduedate" :
70- sess . Desc ( "deadline_unix" )
62+ return "deadline_unix DESC"
7163 case "leastcomplete" :
72- sess . Asc ( "completeness" )
64+ return "completeness ASC"
7365 case "mostcomplete" :
74- sess . Desc ( "completeness" )
66+ return "completeness DESC"
7567 case "leastissues" :
76- sess . Asc ( "num_issues" )
68+ return "num_issues ASC"
7769 case "mostissues" :
78- sess . Desc ( "num_issues" )
70+ return "num_issues DESC"
7971 case "id" :
80- sess . Asc ( "id" )
72+ return "id ASC"
8173 default :
82- sess . Asc ( "deadline_unix" ). Asc ( "id" )
74+ return "deadline_unix ASC, id ASC"
8375 }
84-
85- miles := make ([]* Milestone , 0 , opts .PageSize )
86- total , err := sess .FindAndCount (& miles )
87- return miles , total , err
8876}
8977
9078// GetMilestoneIDsByNames returns a list of milestone ids by given names.
@@ -99,49 +87,6 @@ func GetMilestoneIDsByNames(ctx context.Context, names []string) ([]int64, error
9987 Find (& ids )
10088}
10189
102- // SearchMilestones search milestones
103- func SearchMilestones (ctx context.Context , repoCond builder.Cond , page int , isClosed bool , sortType , keyword string ) (MilestoneList , error ) {
104- miles := make ([]* Milestone , 0 , setting .UI .IssuePagingNum )
105- sess := db .GetEngine (ctx ).Where ("is_closed = ?" , isClosed )
106- if len (keyword ) > 0 {
107- sess = sess .And (builder.Like {"UPPER(name)" , strings .ToUpper (keyword )})
108- }
109- if repoCond .IsValid () {
110- sess .In ("repo_id" , builder .Select ("id" ).From ("repository" ).Where (repoCond ))
111- }
112- if page > 0 {
113- sess = sess .Limit (setting .UI .IssuePagingNum , (page - 1 )* setting .UI .IssuePagingNum )
114- }
115-
116- switch sortType {
117- case "furthestduedate" :
118- sess .Desc ("deadline_unix" )
119- case "leastcomplete" :
120- sess .Asc ("completeness" )
121- case "mostcomplete" :
122- sess .Desc ("completeness" )
123- case "leastissues" :
124- sess .Asc ("num_issues" )
125- case "mostissues" :
126- sess .Desc ("num_issues" )
127- default :
128- sess .Asc ("deadline_unix" )
129- }
130- return miles , sess .Find (& miles )
131- }
132-
133- // GetMilestonesByRepoIDs returns a list of milestones of given repositories and status.
134- func GetMilestonesByRepoIDs (ctx context.Context , repoIDs []int64 , page int , isClosed bool , sortType string ) (MilestoneList , error ) {
135- return SearchMilestones (
136- ctx ,
137- builder .In ("repo_id" , repoIDs ),
138- page ,
139- isClosed ,
140- sortType ,
141- "" ,
142- )
143- }
144-
14590// LoadTotalTrackedTimes loads for every milestone in the list the TotalTrackedTime by a batch request
14691func (milestones MilestoneList ) LoadTotalTrackedTimes (ctx context.Context ) error {
14792 type totalTimesByMilestone struct {
@@ -183,47 +128,9 @@ func (milestones MilestoneList) LoadTotalTrackedTimes(ctx context.Context) error
183128 return nil
184129}
185130
186- // CountMilestones returns number of milestones in given repository with other options
187- func CountMilestones (ctx context.Context , opts GetMilestonesOption ) (int64 , error ) {
188- return db .GetEngine (ctx ).
189- Where (opts .toCond ()).
190- Count (new (Milestone ))
191- }
192-
193- // CountMilestonesByRepoCond map from repo conditions to number of milestones matching the options`
194- func CountMilestonesByRepoCond (ctx context.Context , repoCond builder.Cond , isClosed bool ) (map [int64 ]int64 , error ) {
195- sess := db .GetEngine (ctx ).Where ("is_closed = ?" , isClosed )
196- if repoCond .IsValid () {
197- sess .In ("repo_id" , builder .Select ("id" ).From ("repository" ).Where (repoCond ))
198- }
199-
200- countsSlice := make ([]* struct {
201- RepoID int64
202- Count int64
203- }, 0 , 10 )
204- if err := sess .GroupBy ("repo_id" ).
205- Select ("repo_id AS repo_id, COUNT(*) AS count" ).
206- Table ("milestone" ).
207- Find (& countsSlice ); err != nil {
208- return nil , err
209- }
210-
211- countMap := make (map [int64 ]int64 , len (countsSlice ))
212- for _ , c := range countsSlice {
213- countMap [c .RepoID ] = c .Count
214- }
215- return countMap , nil
216- }
217-
218131// CountMilestonesByRepoCondAndKw map from repo conditions and the keyword of milestones' name to number of milestones matching the options`
219- func CountMilestonesByRepoCondAndKw (ctx context.Context , repoCond builder.Cond , keyword string , isClosed bool ) (map [int64 ]int64 , error ) {
220- sess := db .GetEngine (ctx ).Where ("is_closed = ?" , isClosed )
221- if len (keyword ) > 0 {
222- sess = sess .And (builder.Like {"UPPER(name)" , strings .ToUpper (keyword )})
223- }
224- if repoCond .IsValid () {
225- sess .In ("repo_id" , builder .Select ("id" ).From ("repository" ).Where (repoCond ))
226- }
132+ func CountMilestonesMap (ctx context.Context , opts FindMilestoneOptions ) (map [int64 ]int64 , error ) {
133+ sess := db .GetEngine (ctx ).Where (opts .ToConds ())
227134
228135 countsSlice := make ([]* struct {
229136 RepoID int64
0 commit comments