forked from gitea/gitea
		
	Second part of refactor db.Find (#28194)
				
					
				
			Continue of #27798 and move more functions to `db.Find` and `db.Count`.
This commit is contained in:
		
							parent
							
								
									0abb5633e3
								
							
						
					
					
						commit
						537fa69962
					
				| @ -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 | ||||
|  | ||||
| @ -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, | ||||
| 	}) | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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)) | ||||
|  | ||||
| @ -668,11 +668,9 @@ func RepoAssignment(ctx *Context) context.CancelFunc { | ||||
| 	branchOpts := git_model.FindBranchOptions{ | ||||
| 		RepoID:          ctx.Repo.Repository.ID, | ||||
| 		IsDeletedBranch: util.OptionalBoolFalse, | ||||
| 		ListOptions: db.ListOptions{ | ||||
| 			ListAll: true, | ||||
| 		}, | ||||
| 		ListOptions:     db.ListOptionsAll, | ||||
| 	} | ||||
| 	branchesTotal, err := git_model.CountBranches(ctx, branchOpts) | ||||
| 	branchesTotal, err := db.Count[git_model.Branch](ctx, branchOpts) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("CountBranches", err) | ||||
| 		return cancel | ||||
|  | ||||
| @ -49,11 +49,9 @@ func SyncRepoBranchesWithRepo(ctx context.Context, repo *repo_model.Repository, | ||||
| 
 | ||||
| 	dbBranches := make(map[string]*git_model.Branch) | ||||
| 	{ | ||||
| 		branches, err := git_model.FindBranches(ctx, git_model.FindBranchOptions{ | ||||
| 			ListOptions: db.ListOptions{ | ||||
| 				ListAll: true, | ||||
| 			}, | ||||
| 			RepoID: repo.ID, | ||||
| 		branches, err := db.Find[git_model.Branch](ctx, git_model.FindBranchOptions{ | ||||
| 			ListOptions: db.ListOptionsAll, | ||||
| 			RepoID:      repo.ID, | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
|  | ||||
| @ -10,6 +10,7 @@ import ( | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	"code.gitea.io/gitea/models/organization" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| @ -137,7 +138,7 @@ func DeleteBranch(ctx *context.APIContext) { | ||||
| 	} | ||||
| 
 | ||||
| 	// check whether branches of this repository has been synced | ||||
| 	totalNumOfBranches, err := git_model.CountBranches(ctx, git_model.FindBranchOptions{ | ||||
| 	totalNumOfBranches, err := db.Count[git_model.Branch](ctx, git_model.FindBranchOptions{ | ||||
| 		RepoID:          ctx.Repo.Repository.ID, | ||||
| 		IsDeletedBranch: util.OptionalBoolFalse, | ||||
| 	}) | ||||
| @ -341,7 +342,7 @@ func ListBranches(ctx *context.APIContext) { | ||||
| 			IsDeletedBranch: util.OptionalBoolFalse, | ||||
| 		} | ||||
| 		var err error | ||||
| 		totalNumOfBranches, err = git_model.CountBranches(ctx, branchOpts) | ||||
| 		totalNumOfBranches, err = db.Count[git_model.Branch](ctx, branchOpts) | ||||
| 		if err != nil { | ||||
| 			ctx.Error(http.StatusInternalServerError, "CountBranches", err) | ||||
| 			return | ||||
| @ -360,7 +361,7 @@ func ListBranches(ctx *context.APIContext) { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		branches, err := git_model.FindBranches(ctx, branchOpts) | ||||
| 		branches, err := db.Find[git_model.Branch](ctx, branchOpts) | ||||
| 		if err != nil { | ||||
| 			ctx.Error(http.StatusInternalServerError, "GetBranches", err) | ||||
| 			return | ||||
|  | ||||
| @ -9,10 +9,12 @@ import ( | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	issues_model "code.gitea.io/gitea/models/issues" | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/routers/api/v1/utils" | ||||
| 	"code.gitea.io/gitea/services/convert" | ||||
| @ -58,14 +60,21 @@ func ListMilestones(ctx *context.APIContext) { | ||||
| 	//   "404": | ||||
| 	//     "$ref": "#/responses/notFound" | ||||
| 
 | ||||
| 	milestones, total, err := issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ | ||||
| 	state := api.StateType(ctx.FormString("state")) | ||||
| 	var isClosed util.OptionalBool | ||||
| 	switch state { | ||||
| 	case api.StateClosed, api.StateOpen: | ||||
| 		isClosed = util.OptionalBoolOf(state == api.StateClosed) | ||||
| 	} | ||||
| 
 | ||||
| 	milestones, total, err := db.FindAndCount[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ | ||||
| 		ListOptions: utils.GetListOptions(ctx), | ||||
| 		RepoID:      ctx.Repo.Repository.ID, | ||||
| 		State:       api.StateType(ctx.FormString("state")), | ||||
| 		IsClosed:    isClosed, | ||||
| 		Name:        ctx.FormString("name"), | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "GetMilestones", err) | ||||
| 		ctx.Error(http.StatusInternalServerError, "db.FindAndCount[issues_model.Milestone]", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -510,9 +510,8 @@ func Issues(ctx *context.Context) { | ||||
| 
 | ||||
| func renderMilestones(ctx *context.Context) { | ||||
| 	// Get milestones | ||||
| 	milestones, _, err := issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ | ||||
| 	milestones, err := db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ | ||||
| 		RepoID: ctx.Repo.Repository.ID, | ||||
| 		State:  api.StateAll, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("GetAllRepoMilestones", err) | ||||
| @ -534,17 +533,17 @@ func renderMilestones(ctx *context.Context) { | ||||
| // RetrieveRepoMilestonesAndAssignees find all the milestones and assignees of a repository | ||||
| func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *repo_model.Repository) { | ||||
| 	var err error | ||||
| 	ctx.Data["OpenMilestones"], _, err = issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ | ||||
| 		RepoID: repo.ID, | ||||
| 		State:  api.StateOpen, | ||||
| 	ctx.Data["OpenMilestones"], err = db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ | ||||
| 		RepoID:   repo.ID, | ||||
| 		IsClosed: util.OptionalBoolFalse, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("GetMilestones", err) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["ClosedMilestones"], _, err = issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ | ||||
| 		RepoID: repo.ID, | ||||
| 		State:  api.StateClosed, | ||||
| 	ctx.Data["ClosedMilestones"], err = db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ | ||||
| 		RepoID:   repo.ID, | ||||
| 		IsClosed: util.OptionalBoolTrue, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("GetMilestones", err) | ||||
|  | ||||
| @ -16,7 +16,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| @ -46,18 +45,13 @@ func Milestones(ctx *context.Context) { | ||||
| 		page = 1 | ||||
| 	} | ||||
| 
 | ||||
| 	state := structs.StateOpen | ||||
| 	if isShowClosed { | ||||
| 		state = structs.StateClosed | ||||
| 	} | ||||
| 
 | ||||
| 	miles, total, err := issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ | ||||
| 	miles, total, err := db.FindAndCount[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ | ||||
| 		ListOptions: db.ListOptions{ | ||||
| 			Page:     page, | ||||
| 			PageSize: setting.UI.IssuePagingNum, | ||||
| 		}, | ||||
| 		RepoID:   ctx.Repo.Repository.ID, | ||||
| 		State:    state, | ||||
| 		IsClosed: util.OptionalBoolOf(isShowClosed), | ||||
| 		SortType: sortType, | ||||
| 		Name:     keyword, | ||||
| 	}) | ||||
| @ -80,7 +74,7 @@ func Milestones(ctx *context.Context) { | ||||
| 		url.QueryEscape(keyword), url.QueryEscape(sortType)) | ||||
| 
 | ||||
| 	if ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { | ||||
| 		if err := miles.LoadTotalTrackedTimes(ctx); err != nil { | ||||
| 		if err := issues_model.MilestoneList(miles).LoadTotalTrackedTimes(ctx); err != nil { | ||||
| 			ctx.ServerError("LoadTotalTrackedTimes", err) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| @ -212,13 +212,26 @@ func Milestones(ctx *context.Context) { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	counts, err := issues_model.CountMilestonesByRepoCondAndKw(ctx, userRepoCond, keyword, isShowClosed) | ||||
| 	counts, err := issues_model.CountMilestonesMap(ctx, issues_model.FindMilestoneOptions{ | ||||
| 		RepoCond: userRepoCond, | ||||
| 		Name:     keyword, | ||||
| 		IsClosed: util.OptionalBoolOf(isShowClosed), | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("CountMilestonesByRepoIDs", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	milestones, err := issues_model.SearchMilestones(ctx, repoCond, page, isShowClosed, sortType, keyword) | ||||
| 	milestones, err := db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ | ||||
| 		ListOptions: db.ListOptions{ | ||||
| 			Page:     page, | ||||
| 			PageSize: setting.UI.IssuePagingNum, | ||||
| 		}, | ||||
| 		RepoCond: repoCond, | ||||
| 		IsClosed: util.OptionalBoolOf(isShowClosed), | ||||
| 		SortType: sortType, | ||||
| 		Name:     keyword, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("SearchMilestones", err) | ||||
| 		return | ||||
|  | ||||
| @ -65,16 +65,16 @@ func TestGiteaUploadRepo(t *testing.T) { | ||||
| 	assert.True(t, repo.HasWiki()) | ||||
| 	assert.EqualValues(t, repo_model.RepositoryReady, repo.Status) | ||||
| 
 | ||||
| 	milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ | ||||
| 		RepoID: repo.ID, | ||||
| 		State:  structs.StateOpen, | ||||
| 	milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ | ||||
| 		RepoID:   repo.ID, | ||||
| 		IsClosed: util.OptionalBoolFalse, | ||||
| 	}) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Len(t, milestones, 1) | ||||
| 
 | ||||
| 	milestones, _, err = issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ | ||||
| 		RepoID: repo.ID, | ||||
| 		State:  structs.StateClosed, | ||||
| 	milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ | ||||
| 		RepoID:   repo.ID, | ||||
| 		IsClosed: util.OptionalBoolTrue, | ||||
| 	}) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Empty(t, milestones) | ||||
|  | ||||
| @ -66,22 +66,17 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git | ||||
| 		Keyword: keyword, | ||||
| 	} | ||||
| 
 | ||||
| 	totalNumOfBranches, err := git_model.CountBranches(ctx, branchOpts) | ||||
| 	dbBranches, totalNumOfBranches, err := db.FindAndCount[git_model.Branch](ctx, branchOpts) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, 0, err | ||||
| 	} | ||||
| 
 | ||||
| 	branchOpts.ExcludeBranchNames = []string{repo.DefaultBranch} | ||||
| 
 | ||||
| 	dbBranches, err := git_model.FindBranches(ctx, branchOpts) | ||||
| 	if err != nil { | ||||
| 	if err := git_model.BranchList(dbBranches).LoadDeletedBy(ctx); err != nil { | ||||
| 		return nil, nil, 0, err | ||||
| 	} | ||||
| 
 | ||||
| 	if err := dbBranches.LoadDeletedBy(ctx); err != nil { | ||||
| 		return nil, nil, 0, err | ||||
| 	} | ||||
| 	if err := dbBranches.LoadPusher(ctx); err != nil { | ||||
| 	if err := git_model.BranchList(dbBranches).LoadPusher(ctx); err != nil { | ||||
| 		return nil, nil, 0, err | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 GitHub
							GitHub