Adjust transaction handling via db.Context (#20031)

This commit is contained in:
Lunny Xiao 2022-06-20 20:38:58 +08:00 committed by GitHub
parent cb50375e2b
commit 0649c54275
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 42 deletions

View file

@ -23,23 +23,30 @@ type contextKey struct {
name string name string
} }
// EnginedContextKey is a context key. It is used with context.Value() to get the current Engined for the context // enginedContextKey is a context key. It is used with context.Value() to get the current Engined for the context
var EnginedContextKey = &contextKey{"engined"} var enginedContextKey = &contextKey{"engined"}
var _ Engined = &Context{}
// Context represents a db context // Context represents a db context
type Context struct { type Context struct {
context.Context context.Context
e Engine e Engine
transaction bool
} }
// WithEngine returns a Context from a context.Context and Engine func newContext(ctx context.Context, e Engine, transaction bool) *Context {
func WithEngine(ctx context.Context, e Engine) *Context {
return &Context{ return &Context{
Context: ctx, Context: ctx,
e: e.Context(ctx), e: e,
transaction: transaction,
} }
} }
// InTransaction if context is in a transaction
func (ctx *Context) InTransaction() bool {
return ctx.transaction
}
// Engine returns db engine // Engine returns db engine
func (ctx *Context) Engine() Engine { func (ctx *Context) Engine() Engine {
return ctx.e return ctx.e
@ -47,7 +54,7 @@ func (ctx *Context) Engine() Engine {
// Value shadows Value for context.Context but allows us to get ourselves and an Engined object // Value shadows Value for context.Context but allows us to get ourselves and an Engined object
func (ctx *Context) Value(key interface{}) interface{} { func (ctx *Context) Value(key interface{}) interface{} {
if key == EnginedContextKey { if key == enginedContextKey {
return ctx return ctx
} }
return ctx.Context.Value(key) return ctx.Context.Value(key)
@ -55,7 +62,7 @@ func (ctx *Context) Value(key interface{}) interface{} {
// WithContext returns this engine tied to this context // WithContext returns this engine tied to this context
func (ctx *Context) WithContext(other context.Context) *Context { func (ctx *Context) WithContext(other context.Context) *Context {
return WithEngine(other, ctx.e) return newContext(ctx, ctx.e.Context(other), ctx.transaction)
} }
// Engined structs provide an Engine // Engined structs provide an Engine
@ -68,7 +75,7 @@ func GetEngine(ctx context.Context) Engine {
if engined, ok := ctx.(Engined); ok { if engined, ok := ctx.(Engined); ok {
return engined.Engine() return engined.Engine()
} }
enginedInterface := ctx.Value(EnginedContextKey) enginedInterface := ctx.Value(enginedContextKey)
if enginedInterface != nil { if enginedInterface != nil {
return enginedInterface.(Engined).Engine() return enginedInterface.(Engined).Engine()
} }
@ -89,18 +96,7 @@ func TxContext() (*Context, Committer, error) {
return nil, nil, err return nil, nil, err
} }
return &Context{ return newContext(DefaultContext, sess, true), sess, nil
Context: DefaultContext,
e: sess,
}, sess, nil
}
// WithContext represents executing database operations
func WithContext(f func(ctx *Context) error) error {
return f(&Context{
Context: DefaultContext,
e: x,
})
} }
// WithTx represents executing database operations on a transaction // WithTx represents executing database operations on a transaction
@ -118,10 +114,7 @@ func WithTx(f func(ctx context.Context) error, stdCtx ...context.Context) error
return err return err
} }
if err := f(&Context{ if err := f(newContext(parentCtx, sess, true)); err != nil {
Context: parentCtx,
e: sess,
}); err != nil {
return err return err
} }

View file

@ -680,7 +680,7 @@ type accessibleReposEnv struct {
user *user_model.User user *user_model.User
team *Team team *Team
teamIDs []int64 teamIDs []int64
e db.Engine ctx context.Context
keyword string keyword string
orderBy db.SearchOrderBy orderBy db.SearchOrderBy
} }
@ -706,7 +706,7 @@ func AccessibleReposEnv(ctx context.Context, org *Organization, userID int64) (A
org: org, org: org,
user: user, user: user,
teamIDs: teamIDs, teamIDs: teamIDs,
e: db.GetEngine(ctx), ctx: ctx,
orderBy: db.SearchOrderByRecentUpdated, orderBy: db.SearchOrderByRecentUpdated,
}, nil }, nil
} }
@ -717,7 +717,7 @@ func (org *Organization) AccessibleTeamReposEnv(team *Team) AccessibleReposEnvir
return &accessibleReposEnv{ return &accessibleReposEnv{
org: org, org: org,
team: team, team: team,
e: db.GetEngine(db.DefaultContext), ctx: db.DefaultContext,
orderBy: db.SearchOrderByRecentUpdated, orderBy: db.SearchOrderByRecentUpdated,
} }
} }
@ -744,7 +744,7 @@ func (env *accessibleReposEnv) cond() builder.Cond {
} }
func (env *accessibleReposEnv) CountRepos() (int64, error) { func (env *accessibleReposEnv) CountRepos() (int64, error) {
repoCount, err := env.e. repoCount, err := db.GetEngine(env.ctx).
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
Where(env.cond()). Where(env.cond()).
Distinct("`repository`.id"). Distinct("`repository`.id").
@ -761,7 +761,7 @@ func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) {
} }
repoIDs := make([]int64, 0, pageSize) repoIDs := make([]int64, 0, pageSize)
return repoIDs, env.e. return repoIDs, db.GetEngine(env.ctx).
Table("repository"). Table("repository").
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
Where(env.cond()). Where(env.cond()).
@ -783,7 +783,7 @@ func (env *accessibleReposEnv) Repos(page, pageSize int) ([]*repo_model.Reposito
return repos, nil return repos, nil
} }
return repos, env.e. return repos, db.GetEngine(env.ctx).
In("`repository`.id", repoIDs). In("`repository`.id", repoIDs).
OrderBy(string(env.orderBy)). OrderBy(string(env.orderBy)).
Find(&repos) Find(&repos)
@ -791,7 +791,7 @@ func (env *accessibleReposEnv) Repos(page, pageSize int) ([]*repo_model.Reposito
func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) { func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) {
repoIDs := make([]int64, 0, 10) repoIDs := make([]int64, 0, 10)
return repoIDs, env.e. return repoIDs, db.GetEngine(env.ctx).
Table("repository"). Table("repository").
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true). Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true).
Where(env.cond()). Where(env.cond()).
@ -812,7 +812,7 @@ func (env *accessibleReposEnv) MirrorRepos() ([]*repo_model.Repository, error) {
return repos, nil return repos, nil
} }
return repos, env.e. return repos, db.GetEngine(env.ctx).
In("`repository`.id", repoIDs). In("`repository`.id", repoIDs).
Find(&repos) Find(&repos)
} }

View file

@ -319,13 +319,7 @@ func (repo *Repository) LoadUnits(ctx context.Context) (err error) {
// UnitEnabled if this repository has the given unit enabled // UnitEnabled if this repository has the given unit enabled
func (repo *Repository) UnitEnabled(tp unit.Type) (result bool) { func (repo *Repository) UnitEnabled(tp unit.Type) (result bool) {
if err := db.WithContext(func(ctx *db.Context) error { return repo.UnitEnabledCtx(db.DefaultContext, tp)
result = repo.UnitEnabledCtx(ctx, tp)
return nil
}); err != nil {
log.Error("repo.UnitEnabled: %v", err)
}
return result
} }
// UnitEnabled if this repository has the given unit enabled // UnitEnabled if this repository has the given unit enabled

View file

@ -229,7 +229,7 @@ func UpdateRepository(ctx context.Context, repo *repo_model.Repository, visibili
} }
// Create/Remove git-daemon-export-ok for git-daemon... // Create/Remove git-daemon-export-ok for git-daemon...
if err := CheckDaemonExportOK(db.WithEngine(ctx, e), repo); err != nil { if err := CheckDaemonExportOK(ctx, repo); err != nil {
return err return err
} }