Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use db.Find instead of writing methods for every object #28084

Merged
merged 32 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
72b3ac7
Use db.Find instead of writing methods for every object
lunny Nov 16, 2023
4e5b90d
remove comment code
lunny Nov 16, 2023
e4ab82f
Move FindProjects
lunny Nov 16, 2023
172181c
Fix lint
lunny Nov 16, 2023
42b06ac
Fix bug
lunny Nov 16, 2023
95a8eef
refactor more find/count functions
lunny Nov 17, 2023
926d455
Merge branch 'main' into lunny/use_db_find
lunny Nov 17, 2023
990cfcf
more refactor
lunny Nov 17, 2023
d98c24d
more refactor
lunny Nov 17, 2023
1228312
Fix check
lunny Nov 17, 2023
a5c62d1
Merge branch 'main' into lunny/use_db_find
lunny Nov 17, 2023
b29cb74
Follow @delvh suggestion
lunny Nov 18, 2023
1266b2e
Merge branch 'main' into lunny/use_db_find
lunny Nov 18, 2023
a32c00d
Fix lint
lunny Nov 18, 2023
90a4937
Fix typo
lunny Nov 18, 2023
ed0f18f
Merge branch 'main' into lunny/use_db_find
lunny Nov 18, 2023
108c087
more refactors
lunny Nov 19, 2023
08e41fb
Merge branch 'main' into lunny/use_db_find
lunny Nov 19, 2023
8108df9
refactor for keys
lunny Nov 21, 2023
5572c2b
more refactors
lunny Nov 21, 2023
7d6bb45
Merge branch 'main' into lunny/use_db_find
lunny Nov 21, 2023
b71d0aa
Merge branch 'main' into lunny/use_db_find
lunny Nov 21, 2023
463add4
Fix check
lunny Nov 21, 2023
abac7ac
follow delvh's suggestion
lunny Nov 22, 2023
9f8d57e
Merge branch 'main' into lunny/use_db_find
lunny Nov 22, 2023
7952cd0
Keep all db.Find and db.FindAndCount with pointer of struct and make …
lunny Nov 23, 2023
4281592
Merge branch 'main' into lunny/use_db_find
lunny Nov 23, 2023
395c8aa
Follow @wxiaoguang's suggestion
lunny Nov 23, 2023
28b0b5b
Merge branch 'main' into lunny/use_db_find
lunny Nov 23, 2023
743f9ff
make review easier
lunny Nov 23, 2023
3345e90
make review easier
lunny Nov 23, 2023
c81056b
Merge branch 'main' into lunny/use_db_find
lunny Nov 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion models/actions/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func CancelRunningJobs(ctx context.Context, repoID int64, ref, workflowID string
// Iterate over each found run and cancel its associated jobs.
for _, run := range runs {
// Find all jobs associated with the current run.
jobs, _, err := db.FindAndCount[*ActionRunJob](ctx, FindRunJobOptions{
jobs, err := db.Find[*ActionRunJob](ctx, FindRunJobOptions{
RunID: run.ID,
})
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion models/activities/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ func CreateOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
// init
var toNotify container.Set[int64]
notifications, err := getNotificationsByIssueID(ctx, issueID)
notifications, err := db.Find[*Notification](ctx, FindNotificationOptions{
IssueID: issueID,
})
if err != nil {
return err
}
Expand Down
115 changes: 73 additions & 42 deletions models/activities/notification_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"code.gitea.io/gitea/modules/timeutil"

"xorm.io/builder"
"xorm.io/xorm"
)

// FindNotificationOptions represent the filters for notifications. If an ID is 0 it will be ignored.
Expand Down Expand Up @@ -65,22 +64,6 @@ func (opts FindNotificationOptions) ToOrders() string {
return "notification.updated_unix DESC"
}

// ToSession will convert the given options to a xorm Session by using the conditions from ToCond and joining with issue table if required
func (opts *FindNotificationOptions) ToSession(ctx context.Context) *xorm.Session {
sess := db.GetEngine(ctx).Where(opts.ToConds())
if opts.Page != 0 {
sess = db.SetSessionPagination(sess, opts)
}
return sess
}

func getNotificationsByIssueID(ctx context.Context, issueID int64) (notifications []*Notification, err error) {
err = db.GetEngine(ctx).
Where("issue_id = ?", issueID).
Find(&notifications)
return notifications, err
}

func notificationExists(notifications []*Notification, issueID, userID int64) bool {
for _, notification := range notifications {
if notification.IssueID == issueID && notification.UserID == userID {
Expand All @@ -91,25 +74,6 @@ func notificationExists(notifications []*Notification, issueID, userID int64) bo
return false
}

// NotificationsForUser returns notifications for a given user and status
func NotificationsForUser(ctx context.Context, user *user_model.User, statuses []NotificationStatus, page, perPage int) (notifications NotificationList, err error) {
if len(statuses) == 0 {
return nil, nil
}

sess := db.GetEngine(ctx).
Where("user_id = ?", user.ID).
In("status", statuses).
OrderBy("updated_unix DESC")

if page > 0 && perPage > 0 {
sess.Limit(perPage, (page-1)*perPage)
}

err = sess.Find(&notifications)
return notifications, err
}

// UserIDCount is a simple coalition of UserID and Count
type UserIDCount struct {
UserID int64
Expand All @@ -130,12 +94,17 @@ type NotificationList []*Notification

// LoadAttributes load Repo Issue User and Comment if not loaded
func (nl NotificationList) LoadAttributes(ctx context.Context) error {
var err error
for i := 0; i < len(nl); i++ {
err = nl[i].LoadAttributes(ctx)
if err != nil && !issues_model.IsErrCommentNotExist(err) {
return err
}
if _, _, err := nl.LoadRepos(ctx); err != nil {
return err
}
if _, err := nl.LoadIssues(ctx); err != nil {
return err
}
if _, err := nl.LoadUsers(ctx); err != nil {
return err
}
if _, err := nl.LoadComments(ctx); err != nil {
return err
}
return nil
}
Expand Down Expand Up @@ -309,6 +278,68 @@ func (nl NotificationList) getPendingCommentIDs() []int64 {
return ids.Values()
}

func (nl NotificationList) getUserIDs() []int64 {
ids := make(container.Set[int64], len(nl))
for _, notification := range nl {
if notification.UserID == 0 || notification.User != nil {
continue
}
ids.Add(notification.UserID)
}
return ids.Values()
}

// LoadUsers loads users from database
func (nl NotificationList) LoadUsers(ctx context.Context) ([]int, error) {
if len(nl) == 0 {
return []int{}, nil
}

userIDs := nl.getUserIDs()
users := make(map[int64]*user_model.User, len(userIDs))
left := len(userIDs)
for left > 0 {
limit := db.DefaultMaxInSize
if left < limit {
limit = left
}
rows, err := db.GetEngine(ctx).
In("id", userIDs[:limit]).
Rows(new(user_model.User))
if err != nil {
return nil, err
}

for rows.Next() {
var user user_model.User
err = rows.Scan(&user)
if err != nil {
rows.Close()
return nil, err
}

users[user.ID] = &user
}
_ = rows.Close()

left -= limit
userIDs = userIDs[limit:]
}

failures := []int{}
for i, notification := range nl {
if notification.UserID > 0 && notification.User == nil && users[notification.UserID] != nil {
notification.User = users[notification.UserID]
if notification.User == nil {
log.Error("Notification[%d]: UserID[%d] failed to load", notification.ID, notification.UserID)
failures = append(failures, i)
continue
}
}
}
return failures, nil
}

// LoadComments loads comments from database
func (nl NotificationList) LoadComments(ctx context.Context) ([]int, error) {
if len(nl) == 0 {
Expand Down
16 changes: 0 additions & 16 deletions models/activities/notification_test.go
lunny marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,6 @@ func TestCreateOrUpdateIssueNotifications(t *testing.T) {
assert.Equal(t, activities_model.NotificationStatusUnread, notf.Status)
}

func TestNotificationsForUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
statuses := []activities_model.NotificationStatus{activities_model.NotificationStatusRead, activities_model.NotificationStatusUnread}
notfs, err := activities_model.NotificationsForUser(db.DefaultContext, user, statuses, 1, 10)
assert.NoError(t, err)
if assert.Len(t, notfs, 3) {
assert.EqualValues(t, 5, notfs[0].ID)
assert.EqualValues(t, user.ID, notfs[0].UserID)
assert.EqualValues(t, 4, notfs[1].ID)
assert.EqualValues(t, user.ID, notfs[1].UserID)
assert.EqualValues(t, 2, notfs[2].ID)
assert.EqualValues(t, user.ID, notfs[2].UserID)
}
}

func TestNotification_GetRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1})
Expand Down
7 changes: 4 additions & 3 deletions models/auth/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,15 +264,16 @@ func IsSSPIEnabled(ctx context.Context) bool {
if !db.HasEngine {
return false
}
sources, err := db.Find[Source](ctx, FindSourcesOptions{

exist, err := db.Exits[Source](ctx, FindSourcesOptions{
IsActive: util.OptionalBoolTrue,
LoginType: SSPI,
})
if err != nil {
log.Error("ActiveSources: %v", err)
log.Error("Active SSPI Sources: %v", err)
return false
}
return len(sources) > 0
return exist
}

// GetSourceByID returns login source by given ID.
Expand Down
5 changes: 5 additions & 0 deletions models/db/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,8 @@ func inTransaction(ctx context.Context) (*xorm.Session, bool) {
return nil, false
}
}

func Exits[T any](ctx context.Context, opts FindOptions) (bool, error) {
lunny marked this conversation as resolved.
Show resolved Hide resolved
var bean T
return GetEngine(ctx).Where(opts.ToConds()).Exist(&bean)
}
9 changes: 2 additions & 7 deletions routers/api/v1/org/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,9 @@ func listUserOrgs(ctx *context.APIContext, u *user_model.User) {
UserID: u.ID,
IncludePrivate: showPrivate,
}
orgs, err := db.Find[*organization.Organization](ctx, opts)
orgs, maxResults, err := db.FindAndCount[*organization.Organization](ctx, opts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "FindOrgs", err)
return
}
maxResults, err := db.Count[organization.Organization](ctx, opts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CountOrgs", err)
ctx.Error(http.StatusInternalServerError, "db.FindAndCount[*organization.Organization]", err)
return
}

Expand Down
7 changes: 1 addition & 6 deletions routers/web/shared/actions/runners.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,12 @@ func RunnerDetails(ctx *context.Context, page int, runnerID, ownerID, repoID int
RunnerID: runner.ID,
}

count, err := db.Count[actions_model.ActionTask](ctx, opts)
tasks, count, err := db.FindAndCount[*actions_model.ActionTask](ctx, opts)
if err != nil {
ctx.ServerError("CountTasks", err)
return
}

tasks, err := db.Find[*actions_model.ActionTask](ctx, opts)
if err != nil {
ctx.ServerError("FindTasks", err)
return
}
if err = actions_model.TaskList(tasks).LoadAttributes(ctx); err != nil {
ctx.ServerError("TasksLoadAttributes", err)
return
Expand Down
2 changes: 1 addition & 1 deletion routers/web/shared/user/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func LoadHeaderCount(ctx *context.Context) error {
} else {
projectType = project_model.TypeIndividual
}
projectCount, err := project_model.CountProjects(ctx, project_model.SearchOptions{
projectCount, err := db.Count[project_model.Project](ctx, project_model.SearchOptions{
OwnerID: ctx.ContextUser.ID,
IsClosed: util.OptionalBoolOf(false),
Type: projectType,
Expand Down
13 changes: 11 additions & 2 deletions routers/web/user/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,21 @@ func getNotifications(ctx *context.Context) {
}

statuses := []activities_model.NotificationStatus{status, activities_model.NotificationStatusPinned}
notifications, err := activities_model.NotificationsForUser(ctx, ctx.Doer, statuses, page, perPage)
nls, err := db.Find[*activities_model.Notification](ctx, activities_model.FindNotificationOptions{
ListOptions: db.ListOptions{
PageSize: perPage,
Page: page,
},
UserID: ctx.Doer.ID,
Status: statuses,
})
if err != nil {
ctx.ServerError("ErrNotificationsForUser", err)
ctx.ServerError("db.Find[*activities_model.Notification]", err)
return
}

notifications := activities_model.NotificationList(nls)

failCount := 0

repos, failures, err := notifications.LoadRepos(ctx)
Expand Down