mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-15 15:03:32 +02:00
Tighten v332 migration cleanup pass
- Use setting.Database.Type.IsSQLite3() / IsMySQL() for dialect checks to match the rest of models/migrations/. - Trim the migration's comment to the load-bearing why (MSSQL rejects inline DEFAULT, MySQL drops it on MODIFY COLUMN), drop the discovery narrative. - Trim test comments and tighten the type-name assertion list to the values dialects actually emit (verified empirically against the CI image versions: MySQL/MSSQL report "INT", Postgres reports "INTEGER"; "INT4" never surfaces, removed). Re-tested against postgres:14, bitnamilegacy/mysql:8.0, mssql:2019-latest, and SQLite — all pass. Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
parent
d6ae7c1c50
commit
d18464fd58
@ -5,23 +5,20 @@ package v1_27
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// WidenProjectBoardSorting changes project_board.sorting from int8 (TINYINT/SMALLINT)
|
||||
// to int. The previous int8 type capped projects at 127 columns and forced the API
|
||||
// to truncate user-supplied sort values. SQLite uses dynamic typing so the schema
|
||||
// type is cosmetic; existing rows already store the wider value.
|
||||
//
|
||||
// `base.ModifyColumn` is called with DefaultIsEmpty: true because MSSQL's ALTER
|
||||
// COLUMN syntax does not accept inline DEFAULT (it would error on the keyword).
|
||||
// On MySQL, MODIFY COLUMN without an explicit DEFAULT drops the existing default,
|
||||
// so it has to be reapplied. On Postgres and MSSQL the DEFAULT constraint is
|
||||
// maintained separately from the column type and is preserved automatically.
|
||||
// WidenProjectBoardSorting changes project_board.sorting from int8 to int so the
|
||||
// API can stop truncating sort values and the column count is no longer capped at
|
||||
// 127. DefaultIsEmpty: true is required because MSSQL's ALTER COLUMN rejects an
|
||||
// inline DEFAULT, and MySQL's MODIFY COLUMN drops any DEFAULT not restated, so the
|
||||
// default is reapplied for MySQL afterwards. Postgres and MSSQL keep the existing
|
||||
// DEFAULT constraint independently of the type change.
|
||||
func WidenProjectBoardSorting(x *xorm.Engine) error {
|
||||
if x.Dialect().URI().DBType == schemas.SQLITE {
|
||||
if setting.Database.Type.IsSQLite3() {
|
||||
return nil
|
||||
}
|
||||
if err := base.ModifyColumn(x, "project_board", &schemas.Column{
|
||||
@ -32,7 +29,7 @@ func WidenProjectBoardSorting(x *xorm.Engine) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if x.Dialect().URI().DBType == schemas.MYSQL {
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
if _, err := x.Exec("ALTER TABLE `project_board` ALTER `sorting` SET DEFAULT 0"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -14,8 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func Test_WidenProjectBoardSorting(t *testing.T) {
|
||||
// Pre-migration shape of project_board (only the column we care about plus the
|
||||
// minimum needed to pass NOT NULL constraints during INSERT).
|
||||
// Pre-migration shape: int8 sorting column.
|
||||
type projectBoard struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Title string
|
||||
@ -27,34 +26,28 @@ func Test_WidenProjectBoardSorting(t *testing.T) {
|
||||
x, deferrable := base.PrepareTestEnv(t, 0, new(projectBoard))
|
||||
defer deferrable()
|
||||
|
||||
// Seed two rows: one at the int8 lower bound and one at the upper bound,
|
||||
// proving the migration preserves edge values without truncation.
|
||||
_, err := x.Insert(
|
||||
&projectBoard{Title: "first", Sorting: 0, ProjectID: 1, CreatorID: 1},
|
||||
&projectBoard{Title: "boundary", Sorting: 127, ProjectID: 1, CreatorID: 1},
|
||||
&projectBoard{Title: "boundary", Sorting: 127, ProjectID: 1, CreatorID: 1}, // int8 max
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, WidenProjectBoardSorting(x))
|
||||
|
||||
// Verify column type widened (skipped on SQLite where the migration is a no-op).
|
||||
// SQLite uses dynamic typing so the schema metadata still reports the original
|
||||
// declared type; only verify schema metadata on real RDBMSes.
|
||||
if !setting.Database.Type.IsSQLite3() {
|
||||
table := base.LoadTableSchemasMap(t, x)["project_board"]
|
||||
require.NotNil(t, table)
|
||||
col := table.GetColumn("sorting")
|
||||
require.NotNil(t, col)
|
||||
// Each dialect spells INT differently; verify the type is one of the wider
|
||||
// names rather than TINYINT/INT2.
|
||||
assert.Contains(t,
|
||||
[]string{"INT", "INTEGER", "INT4"},
|
||||
col.SQLType.Name,
|
||||
"sorting column should have widened to int",
|
||||
)
|
||||
assert.False(t, col.Nullable, "sorting column should remain NOT NULL")
|
||||
assert.Equal(t, "0", col.Default, "sorting column should keep DEFAULT 0")
|
||||
// MySQL and MSSQL report "INT", Postgres reports "INTEGER".
|
||||
assert.Contains(t, []string{"INT", "INTEGER"}, col.SQLType.Name)
|
||||
assert.False(t, col.Nullable)
|
||||
assert.Equal(t, "0", col.Default)
|
||||
}
|
||||
|
||||
// Existing rows must be preserved verbatim.
|
||||
// Post-migration shape: same table, int sorting.
|
||||
type projectBoardWide struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Title string
|
||||
@ -68,8 +61,7 @@ func Test_WidenProjectBoardSorting(t *testing.T) {
|
||||
assert.Equal(t, 0, rows[0].Sorting)
|
||||
assert.Equal(t, 127, rows[1].Sorting)
|
||||
|
||||
// Inserting a value > 127 must succeed after widening (would have failed with
|
||||
// TINYINT/INT2 either by truncation or out-of-range error).
|
||||
// Value well past int8 range — proves the column genuinely widened.
|
||||
_, err = x.Table("project_board").Insert(&projectBoardWide{
|
||||
Title: "wide",
|
||||
Sorting: 30000,
|
||||
@ -82,5 +74,5 @@ func Test_WidenProjectBoardSorting(t *testing.T) {
|
||||
has, err := x.Table("project_board").Where("title=?", "wide").Get(&got)
|
||||
require.NoError(t, err)
|
||||
require.True(t, has)
|
||||
assert.Equal(t, 30000, got.Sorting, "value should round-trip without truncation")
|
||||
assert.Equal(t, 30000, got.Sorting)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user