From 9797508a0a99d3ba4233d2da82931b4dca319b33 Mon Sep 17 00:00:00 2001 From: Joe Chen Date: Sat, 4 Nov 2023 22:11:02 -0400 Subject: [PATCH] GetUserMirrorRepositories --- internal/db/org.go | 43 ------------------------------------ internal/db/org_team.go | 14 ------------ internal/db/organizations.go | 40 +++++++++++++++++++++++++++++++-- internal/route/user/home.go | 2 +- 4 files changed, 39 insertions(+), 60 deletions(-) delete mode 100644 internal/db/org.go diff --git a/internal/db/org.go b/internal/db/org.go deleted file mode 100644 index 6c47a79f2..000000000 --- a/internal/db/org.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package db - -import ( - "fmt" - - "xorm.io/builder" -) - -// GetUserMirrorRepositories returns mirror repositories of the organization which the user has access to. -func (u *User) GetUserMirrorRepositories(userID int64) ([]*Repository, error) { - teamIDs, err := u.GetUserTeamIDs(userID) - if err != nil { - return nil, fmt.Errorf("GetUserTeamIDs: %v", err) - } - if len(teamIDs) == 0 { - teamIDs = []int64{-1} - } - - var teamRepoIDs []int64 - err = x.Table("team_repo").In("team_id", teamIDs).Distinct("repo_id").Find(&teamRepoIDs) - if err != nil { - return nil, fmt.Errorf("get team repository ids: %v", err) - } - if len(teamRepoIDs) == 0 { - // team has no repo but "IN ()" is invalid SQL - teamRepoIDs = []int64{-1} // there is no repo with id=-1 - } - - repos := make([]*Repository, 0, 10) - if err = x.Where("owner_id = ?", u.ID). - And("is_private = ?", false). - Or(builder.In("id", teamRepoIDs)). - And("is_mirror = ?", true). // Don't move up because it's an independent condition - Desc("updated_unix"). - Find(&repos); err != nil { - return nil, fmt.Errorf("get user repositories: %v", err) - } - return repos, nil -} diff --git a/internal/db/org_team.go b/internal/db/org_team.go index ef5d9cd0e..280e72556 100644 --- a/internal/db/org_team.go +++ b/internal/db/org_team.go @@ -689,20 +689,6 @@ func (u *User) getUserTeams(e Engine, userID int64, cols ...string) ([]*Team, er Cols(cols...).Find(&teams) } -// GetUserTeamIDs returns of all team IDs of the organization that user is member of. -func (u *User) GetUserTeamIDs(userID int64) ([]int64, error) { - teams, err := u.getUserTeams(x, userID, "team.id") - if err != nil { - return nil, fmt.Errorf("getUserTeams [%d]: %v", userID, err) - } - - teamIDs := make([]int64, len(teams)) - for i := range teams { - teamIDs[i] = teams[i].ID - } - return teamIDs, nil -} - // GetTeams returns all teams that belong to organization, // and that the user has joined. func (u *User) GetUserTeams(userID int64) ([]*Team, error) { diff --git a/internal/db/organizations.go b/internal/db/organizations.go index 8e3b36070..a1803f676 100644 --- a/internal/db/organizations.go +++ b/internal/db/organizations.go @@ -65,9 +65,11 @@ type OrganizationsStore interface { // AccessibleRepositoriesByUser returns a range of repositories in the // organization that the user has access to and the total number of it. Results - // are paginated by given page and page size, and sorted by the given order - // (e.g. "updated_unix DESC"). + // are paginated by given page and page size, and OrderByUpdatedDesc is used. AccessibleRepositoriesByUser(ctx context.Context, orgID, userID int64, page, pageSize int, opts AccessibleRepositoriesByUserOptions) ([]*Repository, int64, error) + // MirrorRepositoriesByUser returns a list of mirror repositories of the + // organization which the user has access to. + MirrorRepositoriesByUser(ctx context.Context, orgID, userID int64) ([]*Repository, error) } var Organizations OrganizationsStore @@ -299,6 +301,40 @@ func (db *organizations) AccessibleRepositoriesByUser(ctx context.Context, orgID return repos, count, nil } +func (db *organizations) MirrorRepositoriesByUser(ctx context.Context, orgID, userID int64) ([]*Repository, error) { + /* + Equivalent SQL for PostgreSQL: + + SELECT * FROM "repository" + JOIN team_repo ON repository.id = team_repo.repo_id + WHERE + owner_id = @orgID + AND repository.is_mirror = TRUE + AND ( + team_repo.team_id IN ( + SELECT team_id FROM "team_user" + WHERE team_user.org_id = @orgID AND uid = @userID) + ) + OR repository.is_private = FALSE + ) + ORDER BY updated_unix DESC + */ + var repos []*Repository + return repos, db.WithContext(ctx). + Joins("JOIN team_repo ON repository.id = team_repo.repo_id"). + Where("owner_id = ? AND repository.is_mirror = ? AND (?)", orgID, true, db. + Where("team_repo.team_id IN (?)", db. + Select("team_id"). + Table("team_user"). + Where("team_user.org_id = ? AND uid = ?", orgID, userID), + ). + Or("repository.is_private = ?", false), + ). + Order("updated_unix DESC"). + Find(&repos). + Error +} + func (db *organizations) getOrgUser(ctx context.Context, orgID, userID int64) (*OrgUser, error) { var ou OrgUser return &ou, db.WithContext(ctx).Where("org_id = ? AND uid = ?", orgID, userID).First(&ou).Error diff --git a/internal/route/user/home.go b/internal/route/user/home.go index 35e66fa9b..62e7e1576 100644 --- a/internal/route/user/home.go +++ b/internal/route/user/home.go @@ -153,7 +153,7 @@ func Dashboard(c *context.Context) { return } - mirrors, err = ctxUser.GetUserMirrorRepositories(c.User.ID) + mirrors, err = db.Organizations.MirrorRepositoriesByUser(c.Req.Context(), ctxUser.ID, c.User.ID) if err != nil { c.Error(err, "get user mirror repositories") return