mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-23 03:11:22 +02:00
Migrations should never use model structs directly, because the model structs can be different in different releases. e.g. if one migration uses "User" model, it works in the early releases, then one day, when the User model changes, the migration breaks because it will use the new (incorrect) User model, it should only use the old User model. The same to "modules/structs". --------- Signed-off-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: delvh <dev.lh@web.de>
80 lines
2.1 KiB
Go
80 lines
2.1 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package v1_27
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitea.dev/modelmigration/base"
|
|
|
|
"xorm.io/xorm/schemas"
|
|
)
|
|
|
|
// legacyDateTimeColumns are the persisted real datetime columns that old Gitea
|
|
// versions created as MSSQL DATETIME. Every other time value is stored as a
|
|
// unix timestamp integer, so these are the only columns affected.
|
|
var legacyDateTimeColumns = []struct {
|
|
bean any
|
|
column string
|
|
}{
|
|
{new(externalLoginUserWithExpiresAt), "expires_at"},
|
|
{new(lfsLockWithCreated), "created"},
|
|
}
|
|
|
|
type externalLoginUserWithExpiresAt struct {
|
|
ExpiresAt time.Time
|
|
}
|
|
|
|
func (externalLoginUserWithExpiresAt) TableName() string {
|
|
return "external_login_user"
|
|
}
|
|
|
|
type lfsLockWithCreated struct {
|
|
Created time.Time `xorm:"created"`
|
|
}
|
|
|
|
func (lfsLockWithCreated) TableName() string {
|
|
return "lfs_lock"
|
|
}
|
|
|
|
// FixLegacyMSSQLDateTimeColumns converts legacy locale-dependent DATETIME columns
|
|
// to DATETIME2. Databases created by old Gitea versions stored these columns as
|
|
// DATETIME, which fails to parse ISO datetime strings ('YYYY-MM-DD HH:MM:SS')
|
|
// when the MSSQL session language is not English, breaking external account
|
|
// linking and LFS lock creation. New installs already use DATETIME2, so only
|
|
// legacy MSSQL columns need converting.
|
|
func FixLegacyMSSQLDateTimeColumns(x base.EngineMigration) error {
|
|
if x.Dialect().URI().DBType != schemas.MSSQL {
|
|
return nil
|
|
}
|
|
|
|
for _, c := range legacyDateTimeColumns {
|
|
table, err := x.TableInfo(c.bean)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var dataType string
|
|
has, err := x.SQL("SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND COLUMN_NAME = ?", table.Name, c.column).Get(&dataType)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !has || !strings.EqualFold(dataType, "datetime") {
|
|
continue
|
|
}
|
|
|
|
column := table.GetColumn(c.column)
|
|
if column == nil {
|
|
return fmt.Errorf("column %s does not exist in table %s", c.column, table.Name)
|
|
}
|
|
if err := base.ModifyColumn(x, table.Name, column); err != nil {
|
|
return fmt.Errorf("modify %s.%s: %w", table.Name, c.column, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|