1
1
mirror of https://github.com/go-gitea/gitea synced 2025-09-15 05:08:13 +00:00

Remove incorrect "db.DefaultContext" usages (#35366)

This commit is contained in:
wxiaoguang
2025-08-28 11:52:43 +08:00
committed by GitHub
parent 7aef7ea2d4
commit 0cbaa0b662
256 changed files with 1951 additions and 2098 deletions

View File

@@ -17,26 +17,23 @@ import (
"xorm.io/xorm"
)
// DefaultContext is the default context to run xorm queries in
// will be overwritten by Init with HammerContext
var DefaultContext context.Context
type engineContextKeyType struct{}
var engineContextKey = engineContextKeyType{}
// Context represents a db context
type Context struct {
type xormContextType struct {
context.Context
engine Engine
}
func newContext(ctx context.Context, e Engine) *Context {
return &Context{Context: ctx, engine: e}
var xormContext *xormContextType
func newContext(ctx context.Context, e Engine) *xormContextType {
return &xormContextType{Context: ctx, engine: e}
}
// Value shadows Value for context.Context but allows us to get ourselves and an Engined object
func (ctx *Context) Value(key any) any {
func (ctx *xormContextType) Value(key any) any {
if key == engineContextKey {
return ctx
}
@@ -44,7 +41,7 @@ func (ctx *Context) Value(key any) any {
}
// WithContext returns this engine tied to this context
func (ctx *Context) WithContext(other context.Context) *Context {
func (ctx *xormContextType) WithContext(other context.Context) *xormContextType {
return newContext(ctx, ctx.engine.Context(other))
}
@@ -90,20 +87,24 @@ func contextSafetyCheck(e Engine) {
}
// GetEngine gets an existing db Engine/Statement or creates a new Session
func GetEngine(ctx context.Context) Engine {
func GetEngine(ctx context.Context) (e Engine) {
defer func() { contextSafetyCheck(e) }()
if e := getExistingEngine(ctx); e != nil {
return e
}
return xormEngine.Context(ctx)
}
func GetXORMEngineForTesting() *xorm.Engine {
return xormEngine
}
// getExistingEngine gets an existing db Engine/Statement from this context or returns nil
func getExistingEngine(ctx context.Context) (e Engine) {
defer func() { contextSafetyCheck(e) }()
if engined, ok := ctx.(*Context); ok {
if engined, ok := ctx.(*xormContextType); ok {
return engined.engine
}
if engined, ok := ctx.Value(engineContextKey).(*Context); ok {
if engined, ok := ctx.Value(engineContextKey).(*xormContextType); ok {
return engined.engine
}
return nil
@@ -150,7 +151,7 @@ func (c *halfCommitter) Close() error {
// So calling `Commit()` will do nothing, but calling `Close()` without calling `Commit()` will rollback the transaction.
// And all operations submitted by the caller stack will be rollbacked as well, not only the operations in the current function.
// d. It doesn't mean rollback is forbidden, but always do it only when there is an error, and you do want to rollback.
func TxContext(parentCtx context.Context) (*Context, Committer, error) {
func TxContext(parentCtx context.Context) (context.Context, Committer, error) {
if sess, ok := inTransaction(parentCtx); ok {
return newContext(parentCtx, sess), &halfCommitter{committer: sess}, nil
}
@@ -161,7 +162,7 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) {
return nil, nil, err
}
return newContext(DefaultContext, sess), sess, nil
return newContext(xormContext, sess), sess, nil
}
// WithTx represents executing database operations on a transaction, if the transaction exist,

View File

@@ -39,7 +39,7 @@ func Test_halfCommitter(t *testing.T) {
/*
Do something like:
ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(t.Context())
if err != nil {
return nil
}

View File

@@ -15,13 +15,13 @@ import (
func TestInTransaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
assert.False(t, db.InTransaction(db.DefaultContext))
assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
assert.False(t, db.InTransaction(t.Context()))
assert.NoError(t, db.WithTx(t.Context(), func(ctx context.Context) error {
assert.True(t, db.InTransaction(ctx))
return nil
}))
ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(t.Context())
assert.NoError(t, err)
defer committer.Close()
assert.True(t, db.InTransaction(ctx))
@@ -35,14 +35,14 @@ func TestTxContext(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
{ // create new transaction
ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(t.Context())
assert.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
assert.NoError(t, committer.Commit())
}
{ // reuse the transaction created by TxContext and commit it
ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(t.Context())
engine := db.GetEngine(ctx)
assert.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
@@ -57,7 +57,7 @@ func TestTxContext(t *testing.T) {
}
{ // reuse the transaction created by TxContext and close it
ctx, committer, err := db.TxContext(db.DefaultContext)
ctx, committer, err := db.TxContext(t.Context())
engine := db.GetEngine(ctx)
assert.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
@@ -72,7 +72,7 @@ func TestTxContext(t *testing.T) {
}
{ // reuse the transaction created by WithTx
assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
assert.NoError(t, db.WithTx(t.Context(), func(ctx context.Context) error {
assert.True(t, db.InTransaction(ctx))
{
ctx, committer, err := db.TxContext(ctx)
@@ -93,16 +93,16 @@ func TestContextSafety(t *testing.T) {
ID int64
}
assert.NoError(t, unittest.GetXORMEngine().Sync(&TestModel1{}, &TestModel2{}))
assert.NoError(t, db.TruncateBeans(db.DefaultContext, &TestModel1{}, &TestModel2{}))
assert.NoError(t, db.TruncateBeans(t.Context(), &TestModel1{}, &TestModel2{}))
testCount := 10
for i := 1; i <= testCount; i++ {
assert.NoError(t, db.Insert(db.DefaultContext, &TestModel1{ID: int64(i)}))
assert.NoError(t, db.Insert(db.DefaultContext, &TestModel2{ID: int64(-i)}))
assert.NoError(t, db.Insert(t.Context(), &TestModel1{ID: int64(i)}))
assert.NoError(t, db.Insert(t.Context(), &TestModel2{ID: int64(-i)}))
}
actualCount := 0
// here: db.GetEngine(db.DefaultContext) is a new *Session created from *Engine
_ = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
// here: db.GetEngine(t.Context()) is a new *Session created from *Engine
_ = db.WithTx(t.Context(), func(ctx context.Context) error {
_ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error {
// here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false,
// and the internal states (including "cond" and others) are always there and not be reset in this callback.
@@ -123,7 +123,7 @@ func TestContextSafety(t *testing.T) {
// deny the bad usages
assert.PanicsWithError(t, "using database context in an iterator would cause corrupted results", func() {
_ = unittest.GetXORMEngine().Iterate(&TestModel1{}, func(i int, bean any) error {
_ = db.GetEngine(db.DefaultContext)
_ = db.GetEngine(t.Context())
return nil
})
})

View File

@@ -59,8 +59,14 @@ type Engine interface {
Cols(...string) *xorm.Session
Context(ctx context.Context) *xorm.Session
Ping() error
IsTableExist(tableNameOrBean any) (bool, error)
}
var (
_ Engine = (*xorm.Engine)(nil)
_ Engine = (*xorm.Session)(nil)
)
// TableInfo returns table's information via an object
func TableInfo(v any) (*schemas.Table, error) {
return xormEngine.TableInfo(v)

View File

@@ -52,7 +52,7 @@ func newXORMEngine() (*xorm.Engine, error) {
return engine, nil
}
// InitEngine initializes the xorm.Engine and sets it as db.DefaultContext
// InitEngine initializes the xorm.Engine and sets it as XORM's default context
func InitEngine(ctx context.Context) error {
xe, err := newXORMEngine()
if err != nil {
@@ -70,7 +70,6 @@ func InitEngine(ctx context.Context) error {
xe.SetMaxOpenConns(setting.Database.MaxOpenConns)
xe.SetMaxIdleConns(setting.Database.MaxIdleConns)
xe.SetConnMaxLifetime(setting.Database.ConnMaxLifetime)
xe.SetDefaultContext(ctx)
if setting.Database.SlowQueryThreshold > 0 {
xe.AddHook(&EngineHook{
@@ -86,22 +85,23 @@ func InitEngine(ctx context.Context) error {
// SetDefaultEngine sets the default engine for db
func SetDefaultEngine(ctx context.Context, eng *xorm.Engine) {
xormEngine = eng
DefaultContext = &Context{Context: ctx, engine: xormEngine}
xormEngine.SetDefaultContext(ctx)
xormContext = &xormContextType{Context: ctx, engine: xormEngine}
}
// UnsetDefaultEngine closes and unsets the default engine
// We hope the SetDefaultEngine and UnsetDefaultEngine can be paired, but it's impossible now,
// there are many calls to InitEngine -> SetDefaultEngine directly to overwrite the `xormEngine` and DefaultContext without close
// there are many calls to InitEngine -> SetDefaultEngine directly to overwrite the `xormEngine` and `xormContext` without close
// Global database engine related functions are all racy and there is no graceful close right now.
func UnsetDefaultEngine() {
if xormEngine != nil {
_ = xormEngine.Close()
xormEngine = nil
}
DefaultContext = nil
xormContext = nil
}
// InitEngineWithMigration initializes a new xorm.Engine and sets it as the db.DefaultContext
// InitEngineWithMigration initializes a new xorm.Engine and sets it as the XORM's default context
// This function must never call .Sync() if the provided migration function fails.
// When called from the "doctor" command, the migration function is a version check
// that prevents the doctor from fixing anything in the database if the migration level

View File

@@ -27,7 +27,7 @@ func TestDumpDatabase(t *testing.T) {
ID int64 `xorm:"pk autoincr"`
Version int64
}
assert.NoError(t, db.GetEngine(db.DefaultContext).Sync(new(Version)))
assert.NoError(t, db.GetEngine(t.Context()).Sync(new(Version)))
for _, dbType := range setting.SupportedDatabaseTypes {
assert.NoError(t, db.DumpDatabase(filepath.Join(dir, dbType+".sql"), dbType))
@@ -37,20 +37,20 @@ func TestDumpDatabase(t *testing.T) {
func TestDeleteOrphanedObjects(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
countBefore, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
countBefore, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{})
assert.NoError(t, err)
_, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003})
_, err = db.GetEngine(t.Context()).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003})
assert.NoError(t, err)
orphaned, err := db.CountOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
orphaned, err := db.CountOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id")
assert.NoError(t, err)
assert.EqualValues(t, 3, orphaned)
err = db.DeleteOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
err = db.DeleteOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id")
assert.NoError(t, err)
countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
countAfter, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{})
assert.NoError(t, err)
assert.Equal(t, countBefore, countAfter)
}

View File

@@ -35,30 +35,30 @@ func TestSyncMaxResourceIndex(t *testing.T) {
xe := unittest.GetXORMEngine()
assert.NoError(t, xe.Sync(&TestIndex{}))
err := db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 51)
err := db.SyncMaxResourceIndex(t.Context(), "test_index", 10, 51)
assert.NoError(t, err)
// sync new max index
maxIndex, err := getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
maxIndex, err := getCurrentResourceIndex(t.Context(), "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 51, maxIndex)
// smaller index doesn't change
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 30)
err = db.SyncMaxResourceIndex(t.Context(), "test_index", 10, 30)
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 51, maxIndex)
// larger index changes
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 62)
err = db.SyncMaxResourceIndex(t.Context(), "test_index", 10, 62)
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 62, maxIndex)
// commit transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
err = db.WithTx(t.Context(), func(ctx context.Context) error {
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 73)
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
@@ -67,12 +67,12 @@ func TestSyncMaxResourceIndex(t *testing.T) {
return nil
})
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 73, maxIndex)
// rollback transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
err = db.WithTx(t.Context(), func(ctx context.Context) error {
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 84)
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
assert.NoError(t, err)
@@ -80,7 +80,7 @@ func TestSyncMaxResourceIndex(t *testing.T) {
return errors.New("test rollback")
})
assert.Error(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10)
assert.NoError(t, err)
assert.EqualValues(t, 73, maxIndex) // the max index doesn't change because the transaction was rolled back
}
@@ -91,36 +91,36 @@ func TestGetNextResourceIndex(t *testing.T) {
assert.NoError(t, xe.Sync(&TestIndex{}))
// create a new record
maxIndex, err := db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
maxIndex, err := db.GetNextResourceIndex(t.Context(), "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 1, maxIndex)
// increase the existing record
maxIndex, err = db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
maxIndex, err = db.GetNextResourceIndex(t.Context(), "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 2, maxIndex)
// commit transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
err = db.WithTx(t.Context(), func(ctx context.Context) error {
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 3, maxIndex)
return nil
})
assert.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 3, maxIndex)
// rollback transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
err = db.WithTx(t.Context(), func(ctx context.Context) error {
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 4, maxIndex)
return errors.New("test rollback")
})
assert.Error(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 20)
assert.NoError(t, err)
assert.EqualValues(t, 3, maxIndex) // the max index doesn't change because the transaction was rolled back
}

View File

@@ -4,27 +4,22 @@
package install
import (
"context"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/setting"
"xorm.io/xorm"
)
func getXORMEngine() *xorm.Engine {
return db.GetEngine(db.DefaultContext).(*xorm.Engine)
}
// CheckDatabaseConnection checks the database connection
func CheckDatabaseConnection() error {
e := db.GetEngine(db.DefaultContext)
_, err := e.Exec("SELECT 1")
func CheckDatabaseConnection(ctx context.Context) error {
_, err := db.GetEngine(ctx).Exec("SELECT 1")
return err
}
// GetMigrationVersion gets the database migration version
func GetMigrationVersion() (int64, error) {
func GetMigrationVersion(ctx context.Context) (int64, error) {
var installedDbVersion int64
x := getXORMEngine()
x := db.GetEngine(ctx)
exist, err := x.IsTableExist("version")
if err != nil {
return 0, err
@@ -40,8 +35,8 @@ func GetMigrationVersion() (int64, error) {
}
// HasPostInstallationUsers checks whether there are users after installation
func HasPostInstallationUsers() (bool, error) {
x := getXORMEngine()
func HasPostInstallationUsers(ctx context.Context) (bool, error) {
x := db.GetEngine(ctx)
exist, err := x.IsTableExist("user")
if err != nil {
return false, err

View File

@@ -19,18 +19,18 @@ func TestIterate(t *testing.T) {
xe := unittest.GetXORMEngine()
assert.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
cnt, err := db.GetEngine(db.DefaultContext).Count(&repo_model.RepoUnit{})
cnt, err := db.GetEngine(t.Context()).Count(&repo_model.RepoUnit{})
assert.NoError(t, err)
var repoUnitCnt int
err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repo *repo_model.RepoUnit) error {
err = db.Iterate(t.Context(), nil, func(ctx context.Context, repo *repo_model.RepoUnit) error {
repoUnitCnt++
return nil
})
assert.NoError(t, err)
assert.EqualValues(t, cnt, repoUnitCnt)
err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error {
err = db.Iterate(t.Context(), nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error {
has, err := db.ExistByID[repo_model.RepoUnit](ctx, repoUnit.ID)
if err != nil {
return err

View File

@@ -32,20 +32,20 @@ func TestFind(t *testing.T) {
assert.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
var repoUnitCount int
_, err := db.GetEngine(db.DefaultContext).SQL("SELECT COUNT(*) FROM repo_unit").Get(&repoUnitCount)
_, err := db.GetEngine(t.Context()).SQL("SELECT COUNT(*) FROM repo_unit").Get(&repoUnitCount)
assert.NoError(t, err)
assert.NotEmpty(t, repoUnitCount)
opts := mockListOptions{}
repoUnits, err := db.Find[repo_model.RepoUnit](db.DefaultContext, opts)
repoUnits, err := db.Find[repo_model.RepoUnit](t.Context(), opts)
assert.NoError(t, err)
assert.Len(t, repoUnits, repoUnitCount)
cnt, err := db.Count[repo_model.RepoUnit](db.DefaultContext, opts)
cnt, err := db.Count[repo_model.RepoUnit](t.Context(), opts)
assert.NoError(t, err)
assert.EqualValues(t, repoUnitCount, cnt)
repoUnits, newCnt, err := db.FindAndCount[repo_model.RepoUnit](db.DefaultContext, opts)
repoUnits, newCnt, err := db.FindAndCount[repo_model.RepoUnit](t.Context(), opts)
assert.NoError(t, err)
assert.Equal(t, cnt, newCnt)
assert.Len(t, repoUnits, repoUnitCount)