-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix #29874 (comment) - The migration of v292 will miss many projects. These projects will have no default board. This PR introduced a new migration number and removed v292 migration. - This PR also added the missed transactions on project-related operations. - Only `SetDefaultBoard` will remove duplicated defaults but not in `GetDefaultBoard`
- Loading branch information
Showing
6 changed files
with
162 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright 2024 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package v1_22 //nolint | ||
|
||
import ( | ||
"code.gitea.io/gitea/modules/setting" | ||
"code.gitea.io/gitea/modules/timeutil" | ||
|
||
"xorm.io/xorm" | ||
) | ||
|
||
// CheckProjectColumnsConsistency ensures there is exactly one default board per project present | ||
func CheckProjectColumnsConsistency(x *xorm.Engine) error { | ||
sess := x.NewSession() | ||
defer sess.Close() | ||
|
||
limit := setting.Database.IterateBufferSize | ||
if limit <= 0 { | ||
limit = 50 | ||
} | ||
|
||
type Project struct { | ||
ID int64 | ||
CreatorID int64 | ||
BoardID int64 | ||
} | ||
|
||
type ProjectBoard struct { | ||
ID int64 `xorm:"pk autoincr"` | ||
Title string | ||
Default bool `xorm:"NOT NULL DEFAULT false"` // issues not assigned to a specific board will be assigned to this board | ||
Sorting int8 `xorm:"NOT NULL DEFAULT 0"` | ||
Color string `xorm:"VARCHAR(7)"` | ||
|
||
ProjectID int64 `xorm:"INDEX NOT NULL"` | ||
CreatorID int64 `xorm:"NOT NULL"` | ||
|
||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||
} | ||
|
||
for { | ||
if err := sess.Begin(); err != nil { | ||
return err | ||
} | ||
|
||
// all these projects without defaults will be fixed in the same loop, so | ||
// we just need to always get projects without defaults until no such project | ||
var projects []*Project | ||
if err := sess.Select("project.id as id, project.creator_id, project_board.id as board_id"). | ||
Join("LEFT", "project_board", "project_board.project_id = project.id AND project_board.`default`=?", true). | ||
Where("project_board.id is NULL OR project_board.id = 0"). | ||
Limit(limit). | ||
Find(&projects); err != nil { | ||
return err | ||
} | ||
|
||
for _, p := range projects { | ||
if _, err := sess.Insert(ProjectBoard{ | ||
ProjectID: p.ID, | ||
Default: true, | ||
Title: "Uncategorized", | ||
CreatorID: p.CreatorID, | ||
}); err != nil { | ||
return err | ||
} | ||
} | ||
if err := sess.Commit(); err != nil { | ||
return err | ||
} | ||
|
||
if len(projects) == 0 { | ||
break | ||
} | ||
} | ||
sess.Close() | ||
|
||
return removeDuplicatedBoardDefault(x) | ||
} | ||
|
||
func removeDuplicatedBoardDefault(x *xorm.Engine) error { | ||
type ProjectInfo struct { | ||
ProjectID int64 | ||
DefaultNum int | ||
} | ||
var projects []ProjectInfo | ||
if err := x.Select("project_id, count(*) AS default_num"). | ||
Table("project_board"). | ||
Where("`default` = ?", true). | ||
GroupBy("project_id"). | ||
Having("count(*) > 1"). | ||
Find(&projects); err != nil { | ||
return err | ||
} | ||
|
||
for _, project := range projects { | ||
if _, err := x.Where("project_id=?", project.ProjectID). | ||
Table("project_board"). | ||
Limit(project.DefaultNum - 1). | ||
Update(map[string]bool{ | ||
"`default`": false, | ||
}); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters