mirror of
https://github.com/gogs/gogs.git
synced 2026-03-04 11:11:03 +01:00
refactor(db): migrate methods off user.go (#7219)
This commit is contained in:
@@ -105,7 +105,7 @@ func TestAccessTokens(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *accessTokens)
|
||||
test func(t *testing.T, db *accessTokens)
|
||||
}{
|
||||
{"Create", accessTokensCreate},
|
||||
{"DeleteByID", accessTokensDeleteByID},
|
||||
|
||||
@@ -106,7 +106,7 @@ func TestActions(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *actions)
|
||||
test func(t *testing.T, db *actions)
|
||||
}{
|
||||
{"CommitRepo", actionsCommitRepo},
|
||||
{"ListByOrganization", actionsListByOrganization},
|
||||
|
||||
@@ -124,6 +124,7 @@ func Init(w logger.Writer) (*gorm.DB, error) {
|
||||
Follows = NewFollowsStore(db)
|
||||
LoginSources = &loginSources{DB: db, files: sourceFiles}
|
||||
LFS = &lfs{DB: db}
|
||||
OrgUsers = NewOrgUsersStore(db)
|
||||
Perms = &perms{DB: db}
|
||||
Repos = NewReposStore(db)
|
||||
TwoFactors = &twoFactors{DB: db}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// FollowsStore is the persistent interface for follows.
|
||||
// FollowsStore is the persistent interface for user follows.
|
||||
//
|
||||
// NOTE: All methods are sorted in alphabetical order.
|
||||
type FollowsStore interface {
|
||||
@@ -31,7 +31,7 @@ type follows struct {
|
||||
*gorm.DB
|
||||
}
|
||||
|
||||
// NewFollowsStore returns a persistent interface for follows with given
|
||||
// NewFollowsStore returns a persistent interface for user follows with given
|
||||
// database connection.
|
||||
func NewFollowsStore(db *gorm.DB) FollowsStore {
|
||||
return &follows{DB: db}
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestFollows(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *follows)
|
||||
test func(t *testing.T, db *follows)
|
||||
}{
|
||||
{"Follow", followsFollow},
|
||||
{"IsFollowing", followsIsFollowing},
|
||||
|
||||
@@ -30,7 +30,7 @@ func TestLFS(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *lfs)
|
||||
test func(t *testing.T, db *lfs)
|
||||
}{
|
||||
{"CreateObject", lfsCreateObject},
|
||||
{"GetObjectByOID", lfsGetObjectByOID},
|
||||
|
||||
@@ -157,7 +157,7 @@ func TestLoginSource_AfterFind(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_loginSources(t *testing.T) {
|
||||
func TestLoginSources(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
@@ -170,7 +170,7 @@ func Test_loginSources(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *loginSources)
|
||||
test func(t *testing.T, db *loginSources)
|
||||
}{
|
||||
{"Create", loginSourcesCreate},
|
||||
{"Count", loginSourcesCount},
|
||||
|
||||
@@ -235,14 +235,14 @@ func DeleteOrganization(org *User) (err error) {
|
||||
// \_______ /__| \___ /|______//____ >\___ >__|
|
||||
// \/ /_____/ \/ \/
|
||||
|
||||
// OrgUser represents an organization-user relation.
|
||||
// OrgUser represents relations of organizations and their members.
|
||||
type OrgUser struct {
|
||||
ID int64
|
||||
Uid int64 `xorm:"INDEX UNIQUE(s)"`
|
||||
OrgID int64 `xorm:"INDEX UNIQUE(s)"`
|
||||
IsPublic bool
|
||||
IsOwner bool
|
||||
NumTeams int
|
||||
ID int64 `gorm:"primaryKey"`
|
||||
Uid int64 `xorm:"INDEX UNIQUE(s)" gorm:"uniqueIndex:org_user_user_org_unique;index;not null"`
|
||||
OrgID int64 `xorm:"INDEX UNIQUE(s)" gorm:"uniqueIndex:org_user_user_org_unique;index;not null"`
|
||||
IsPublic bool `gorm:"not null;default:FALSE"`
|
||||
IsOwner bool `gorm:"not null;default:FALSE"`
|
||||
NumTeams int `gorm:"not null;default:0"`
|
||||
}
|
||||
|
||||
// IsOrganizationOwner returns true if given user is in the owner team.
|
||||
@@ -278,12 +278,6 @@ func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) {
|
||||
return getOrgsByUserID(x.NewSession(), userID, showAll)
|
||||
}
|
||||
|
||||
// GetOrgsByUserIDDesc returns a list of organizations that the given user ID
|
||||
// has joined, ordered descending by the given condition.
|
||||
func GetOrgsByUserIDDesc(userID int64, desc string, showAll bool) ([]*User, error) {
|
||||
return getOrgsByUserID(x.NewSession().Desc(desc), userID, showAll)
|
||||
}
|
||||
|
||||
func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
|
||||
orgs := make([]*User, 0, 10)
|
||||
return orgs, sess.Where("`org_user`.uid=?", userID).And("`org_user`.is_owner=?", true).
|
||||
|
||||
38
internal/db/org_users.go
Normal file
38
internal/db/org_users.go
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2022 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 (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// OrgUsersStore is the persistent interface for organization-user relations.
|
||||
//
|
||||
// NOTE: All methods are sorted in alphabetical order.
|
||||
type OrgUsersStore interface {
|
||||
// CountByUser returns the number of organizations the user is a member of.
|
||||
CountByUser(ctx context.Context, userID int64) (int64, error)
|
||||
}
|
||||
|
||||
var OrgUsers OrgUsersStore
|
||||
|
||||
var _ OrgUsersStore = (*orgUsers)(nil)
|
||||
|
||||
type orgUsers struct {
|
||||
*gorm.DB
|
||||
}
|
||||
|
||||
// NewOrgUsersStore returns a persistent interface for organization-user
|
||||
// relations with given database connection.
|
||||
func NewOrgUsersStore(db *gorm.DB) OrgUsersStore {
|
||||
return &orgUsers{DB: db}
|
||||
}
|
||||
|
||||
func (db *orgUsers) CountByUser(ctx context.Context, userID int64) (int64, error) {
|
||||
var count int64
|
||||
return count, db.WithContext(ctx).Model(&OrgUser{}).Where("uid = ?", userID).Count(&count).Error
|
||||
}
|
||||
51
internal/db/org_users_test.go
Normal file
51
internal/db/org_users_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2022 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 (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gogs.io/gogs/internal/dbtest"
|
||||
)
|
||||
|
||||
func TestOrgUsers(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
tables := []interface{}{new(OrgUser)}
|
||||
db := &orgUsers{
|
||||
DB: dbtest.NewDB(t, "orgUsers", tables...),
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(t *testing.T, db *orgUsers)
|
||||
}{
|
||||
{"CountByUser", orgUsersCountByUser},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
err := clearTables(t, db.DB, tables...)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
tc.test(t, db)
|
||||
})
|
||||
if t.Failed() {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func orgUsersCountByUser(t *testing.T, db *orgUsers) {
|
||||
// TODO: Use OrgUsers.Join to replace SQL hack when the method is available.
|
||||
err := db.Exec(`INSERT INTO org_user (uid, org_id) VALUES (?, ?)`, 1, 1).Error
|
||||
require.NoError(t, err)
|
||||
err = db.Exec(`INSERT INTO org_user (uid, org_id) VALUES (?, ?)`, 2, 1).Error
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func TestPerms(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *perms)
|
||||
test func(t *testing.T, db *perms)
|
||||
}{
|
||||
{"AccessMode", permsAccessMode},
|
||||
{"Authorize", permsAuthorize},
|
||||
|
||||
@@ -92,7 +92,7 @@ func TestRepos(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *repos)
|
||||
test func(t *testing.T, db *repos)
|
||||
}{
|
||||
{"Create", reposCreate},
|
||||
{"GetByName", reposGetByName},
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestTwoFactors(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *twoFactors)
|
||||
test func(t *testing.T, db *twoFactors)
|
||||
}{
|
||||
{"Create", twoFactorsCreate},
|
||||
{"GetByUserID", twoFactorsGetByUserID},
|
||||
|
||||
@@ -53,37 +53,13 @@ func (u *User) AfterSet(colName string, _ xorm.Cell) {
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: Use OrgsUsers.CountByUser instead.
|
||||
//
|
||||
// TODO(unknwon): Delete me once no more call sites.
|
||||
func (u *User) getOrganizationCount(e Engine) (int64, error) {
|
||||
return e.Where("uid=?", u.ID).Count(new(OrgUser))
|
||||
}
|
||||
|
||||
// GetOrganizationCount returns count of membership of organization of user.
|
||||
func (u *User) GetOrganizationCount() (int64, error) {
|
||||
return u.getOrganizationCount(x)
|
||||
}
|
||||
|
||||
// GetRepositories returns repositories that user owns, including private repositories.
|
||||
func (u *User) GetRepositories(page, pageSize int) (err error) {
|
||||
u.Repos, err = GetUserRepositories(&UserRepoOptions{
|
||||
UserID: u.ID,
|
||||
Private: true,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRepositories returns mirror repositories that user owns, including private repositories.
|
||||
func (u *User) GetMirrorRepositories() ([]*Repository, error) {
|
||||
return GetUserMirrorRepositories(u.ID)
|
||||
}
|
||||
|
||||
// GetOwnedOrganizations returns all organizations that user owns.
|
||||
func (u *User) GetOwnedOrganizations() (err error) {
|
||||
u.OwnedOrgs, err = GetOwnedOrgsByUserID(u.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetOrganizations returns all organizations that user belongs to.
|
||||
func (u *User) GetOrganizations(showPrivate bool) error {
|
||||
orgIDs, err := GetOrgIDsByUserID(u.ID, showPrivate)
|
||||
@@ -101,25 +77,6 @@ func (u *User) GetOrganizations(showPrivate bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisplayName returns full name if it's not empty,
|
||||
// returns username otherwise.
|
||||
func (u *User) DisplayName() string {
|
||||
if len(u.FullName) > 0 {
|
||||
return u.FullName
|
||||
}
|
||||
return u.Name
|
||||
}
|
||||
|
||||
func (u *User) ShortName(length int) string {
|
||||
return strutil.Ellipsis(u.Name, length)
|
||||
}
|
||||
|
||||
// IsMailable checks if a user is eligible
|
||||
// to receive emails.
|
||||
func (u *User) IsMailable() bool {
|
||||
return u.IsActive
|
||||
}
|
||||
|
||||
// IsUserExist checks if given user name exist,
|
||||
// the user name should be noncased unique.
|
||||
// If uid is presented, then check will rule out that one,
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"gogs.io/gogs/internal/cryptoutil"
|
||||
"gogs.io/gogs/internal/errutil"
|
||||
"gogs.io/gogs/internal/osutil"
|
||||
"gogs.io/gogs/internal/strutil"
|
||||
"gogs.io/gogs/internal/tool"
|
||||
"gogs.io/gogs/internal/userutil"
|
||||
)
|
||||
@@ -451,9 +452,7 @@ type User struct {
|
||||
LoginSource int64 `xorm:"NOT NULL DEFAULT 0" gorm:"not null;default:0"`
|
||||
LoginName string
|
||||
Type UserType
|
||||
OwnedOrgs []*User `xorm:"-" gorm:"-" json:"-"`
|
||||
Orgs []*User `xorm:"-" gorm:"-" json:"-"`
|
||||
Repos []*Repository `xorm:"-" gorm:"-" json:"-"`
|
||||
Orgs []*User `xorm:"-" gorm:"-" json:"-"`
|
||||
Location string
|
||||
Website string
|
||||
Rands string `xorm:"VARCHAR(10)" gorm:"type:VARCHAR(10)"`
|
||||
@@ -521,6 +520,11 @@ func (u *User) IsOrganization() bool {
|
||||
return u.Type == UserTypeOrganization
|
||||
}
|
||||
|
||||
// IsMailable returns true if the user is eligible to receive emails.
|
||||
func (u *User) IsMailable() bool {
|
||||
return u.IsActive
|
||||
}
|
||||
|
||||
// APIFormat returns the API format of a user.
|
||||
func (u *User) APIFormat() *api.User {
|
||||
return &api.User{
|
||||
@@ -562,6 +566,15 @@ func (u *User) CanImportLocal() bool {
|
||||
return conf.Repository.EnableLocalPathMigration && (u.IsAdmin || u.AllowImportLocal)
|
||||
}
|
||||
|
||||
// DisplayName returns the full name of the user if it's not empty, returns the
|
||||
// username otherwise.
|
||||
func (u *User) DisplayName() string {
|
||||
if len(u.FullName) > 0 {
|
||||
return u.FullName
|
||||
}
|
||||
return u.Name
|
||||
}
|
||||
|
||||
// HomeURLPath returns the URL path to the user or organization home page.
|
||||
//
|
||||
// TODO(unknwon): This is also used in templates, which should be fixed by
|
||||
@@ -649,3 +662,20 @@ func (u *User) IsUserOrgOwner(orgId int64) bool {
|
||||
func (u *User) IsPublicMember(orgId int64) bool {
|
||||
return IsPublicMembership(orgId, u.ID)
|
||||
}
|
||||
|
||||
// GetOrganizationCount returns the count of organization membership that the
|
||||
// user has.
|
||||
//
|
||||
// TODO(unknwon): This is also used in templates, which should be fixed by
|
||||
// having a dedicated type `template.User`.
|
||||
func (u *User) GetOrganizationCount() (int64, error) {
|
||||
return OrgUsers.CountByUser(context.TODO(), u.ID)
|
||||
}
|
||||
|
||||
// ShortName truncates and returns the username at most in given length.
|
||||
//
|
||||
// TODO(unknwon): This is also used in templates, which should be fixed by
|
||||
// having a dedicated type `template.User`.
|
||||
func (u *User) ShortName(length int) string {
|
||||
return strutil.Ellipsis(u.Name, length)
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestUsers(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *users)
|
||||
test func(t *testing.T, db *users)
|
||||
}{
|
||||
{"Authenticate", usersAuthenticate},
|
||||
{"Create", usersCreate},
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestWatches(t *testing.T) {
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
test func(*testing.T, *watches)
|
||||
test func(t *testing.T, db *watches)
|
||||
}{
|
||||
{"ListByRepo", watchesListByRepo},
|
||||
} {
|
||||
|
||||
@@ -145,14 +145,21 @@ func Dashboard(c *context.Context) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = ctxUser.GetRepositories(1, conf.UI.User.RepoPagingNum); err != nil {
|
||||
repos, err = db.GetUserRepositories(
|
||||
&db.UserRepoOptions{
|
||||
UserID: ctxUser.ID,
|
||||
Private: true,
|
||||
Page: 1,
|
||||
PageSize: conf.UI.User.RepoPagingNum,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
c.Error(err, "get repositories")
|
||||
return
|
||||
}
|
||||
repos = ctxUser.Repos
|
||||
repoCount = int64(ctxUser.NumRepos)
|
||||
|
||||
mirrors, err = ctxUser.GetMirrorRepositories()
|
||||
mirrors, err = db.GetUserMirrorRepositories(ctxUser.ID)
|
||||
if err != nil {
|
||||
c.Error(err, "get mirror repositories")
|
||||
return
|
||||
@@ -228,11 +235,18 @@ func Issues(c *context.Context) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := ctxUser.GetRepositories(1, c.User.NumRepos); err != nil {
|
||||
repos, err = db.GetUserRepositories(
|
||||
&db.UserRepoOptions{
|
||||
UserID: ctxUser.ID,
|
||||
Private: true,
|
||||
Page: 1,
|
||||
PageSize: ctxUser.NumRepos,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
c.Error(err, "get repositories")
|
||||
return
|
||||
}
|
||||
repos = ctxUser.Repos
|
||||
}
|
||||
|
||||
userRepoIDs = make([]int64, 0, len(repos))
|
||||
|
||||
Reference in New Issue
Block a user