mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Fix https://github.com/go-gitea/gitea/pull/29874#discussion_r1542227686 - 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`
		
			
				
	
	
		
			109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // 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
 | |
| }
 |