diff --git a/models/db/engine.go b/models/db/engine.go index 78b4ac22dd..bd55aa7a03 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -128,16 +128,35 @@ func syncTables() error { return x.StoreEngine("InnoDB").Sync2(tables...) } -// NewTestEngine sets a new test xorm.Engine -func NewTestEngine() (err error) { +// NewInstallTestEngine creates a new xorm.Engine for testing during install +// +// This function will cause the basic database schema to be created +func NewInstallTestEngine(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err error) { x, err = GetNewEngine() if err != nil { - return fmt.Errorf("Connect to database: %v", err) + return fmt.Errorf("failed to connect to database: %w", err) } x.SetMapper(names.GonicMapper{}) x.SetLogger(NewXORMLogger(!setting.IsProd)) x.ShowSQL(!setting.IsProd) + + x.SetDefaultContext(ctx) + + if err = x.Ping(); err != nil { + return err + } + + // We have to run migrateFunc here in case the user is re-running installation on a previously created DB. + // If we do not then table schemas will be changed and there will be conflicts when the migrations run properly. + // + // Installation should only be being re-run if users want to recover an old database. + // However, we should think carefully about should we support re-install on an installed instance, + // as there may be other problems due to secret reinitialization. + if err = migrateFunc(x); err != nil { + return fmt.Errorf("migrate: %v", err) + } + return syncTables() } diff --git a/routers/install/install.go b/routers/install/install.go index 8143ad8089..1c042f9b4e 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/migrations" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/generate" @@ -208,7 +209,7 @@ func SubmitInstall(ctx *context.Context) { } // Set test engine. - if err = db.NewTestEngine(); err != nil { + if err = db.NewInstallTestEngine(ctx, migrations.Migrate); err != nil { if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { ctx.Data["Err_DbType"] = true ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/en-us/install-from-binary/"), tplInstall, &form)