0
0
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:
silverwind 2026-04-27 13:00:47 +02:00 committed by beardev-in
parent d6ae7c1c50
commit d18464fd58
No known key found for this signature in database
GPG Key ID: 625E0CB70AFF32B9
2 changed files with 20 additions and 31 deletions

View File

@ -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
}

View File

@ -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)
}