From 2ebe609d65f16b67ee54fe123f226bcd737be79e Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Thu, 28 Jan 2021 23:58:33 +0100 Subject: [PATCH] Fix migration v141 (#14387) * Fix mig 141 * Add Migration to fix it * update null values to false first * Alter Table if posible * use dropTableColumns instead of recreateTable * MySQL use Alter * Postgres use Alter * Update models/migrations/v167.go * Apply suggestions from code review * use 2x add col & 2x update & 2x drop col * let sqlite be the only issue * use recreate since it just WORKS --- models/migrations/migrations.go | 2 + models/migrations/v141.go | 2 +- models/migrations/v168.go | 106 ++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 models/migrations/v168.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 3227f6f75..3e2a79970 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -281,6 +281,8 @@ var migrations = []Migration{ NewMigration("Where Password is Valid with Empty String delete it", recalculateUserEmptyPWD), // v167 -> v168 NewMigration("Add user redirect", addUserRedirect), + // v168 -> v169 + NewMigration("Recreate user table to fix default values", recreateUserTableToFixDefaultValues), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v141.go b/models/migrations/v141.go index b5824ecd4..ab05698b8 100644 --- a/models/migrations/v141.go +++ b/models/migrations/v141.go @@ -12,7 +12,7 @@ import ( func addKeepActivityPrivateUserColumn(x *xorm.Engine) error { type User struct { - KeepActivityPrivate bool + KeepActivityPrivate bool `xorm:"NOT NULL DEFAULT false"` } if err := x.Sync2(new(User)); err != nil { diff --git a/models/migrations/v168.go b/models/migrations/v168.go new file mode 100644 index 000000000..246b120d3 --- /dev/null +++ b/models/migrations/v168.go @@ -0,0 +1,106 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "xorm.io/builder" + "xorm.io/xorm" + "xorm.io/xorm/schemas" +) + +func recreateUserTableToFixDefaultValues(x *xorm.Engine) error { + type User struct { + ID int64 `xorm:"pk autoincr"` + LowerName string `xorm:"UNIQUE NOT NULL"` + Name string `xorm:"UNIQUE NOT NULL"` + FullName string + Email string `xorm:"NOT NULL"` + KeepEmailPrivate bool + EmailNotificationsPreference string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'enabled'"` + Passwd string `xorm:"NOT NULL"` + PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'argon2'"` + + MustChangePassword bool `xorm:"NOT NULL DEFAULT false"` + + LoginType int + LoginSource int64 `xorm:"NOT NULL DEFAULT 0"` + LoginName string + Type int + Location string + Website string + Rands string `xorm:"VARCHAR(10)"` + Salt string `xorm:"VARCHAR(10)"` + Language string `xorm:"VARCHAR(5)"` + Description string + + CreatedUnix int64 `xorm:"INDEX created"` + UpdatedUnix int64 `xorm:"INDEX updated"` + LastLoginUnix int64 `xorm:"INDEX"` + + LastRepoVisibility bool + MaxRepoCreation int `xorm:"NOT NULL DEFAULT -1"` + + // Permissions + IsActive bool `xorm:"INDEX"` + IsAdmin bool + IsRestricted bool `xorm:"NOT NULL DEFAULT false"` + AllowGitHook bool + AllowImportLocal bool + AllowCreateOrganization bool `xorm:"DEFAULT true"` + ProhibitLogin bool `xorm:"NOT NULL DEFAULT false"` + + // Avatar + Avatar string `xorm:"VARCHAR(2048) NOT NULL"` + AvatarEmail string `xorm:"NOT NULL"` + UseCustomAvatar bool + + // Counters + NumFollowers int + NumFollowing int `xorm:"NOT NULL DEFAULT 0"` + NumStars int + NumRepos int + + // For organization + NumTeams int + NumMembers int + Visibility int `xorm:"NOT NULL DEFAULT 0"` + RepoAdminChangeTeamAccess bool `xorm:"NOT NULL DEFAULT false"` + + // Preferences + DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"` + Theme string `xorm:"NOT NULL DEFAULT ''"` + KeepActivityPrivate bool `xorm:"NOT NULL DEFAULT false"` + } + + if _, err := x.Where(builder.IsNull{"keep_activity_private"}). + Cols("keep_activity_private"). + Update(User{KeepActivityPrivate: false}); err != nil { + return err + } + + switch x.Dialect().URI().DBType { + case schemas.MYSQL: + _, err := x.Exec("ALTER TABLE `user` MODIFY COLUMN keep_activity_private tinyint(1) DEFAULT 0 NOT NULL;") + return err + case schemas.POSTGRES: + if _, err := x.Exec("ALTER TABLE `user` ALTER COLUMN keep_activity_private SET NOT NULL;"); err != nil { + return err + } + _, err := x.Exec("ALTER TABLE `user` ALTER COLUMN keep_activity_private SET DEFAULT false;") + return err + } + + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + if err := recreateTable(sess, new(User)); err != nil { + return err + } + + return sess.Commit() +}