feat: check for cycles when creating or updating a project's parent
This commit is contained in:
@ -627,7 +627,7 @@ func (p *Project) CheckIsArchived(s *xorm.Session) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkProjectBeforeUpdateOrDelete(s *xorm.Session, project *Project) error {
|
||||
func checkProjectBeforeUpdateOrDelete(s *xorm.Session, project *Project) (err error) {
|
||||
if project.ParentProjectID < 0 {
|
||||
return &ErrProjectCannotBelongToAPseudoParentProject{ProjectID: project.ID, ParentProjectID: project.ParentProjectID}
|
||||
}
|
||||
@ -640,10 +640,34 @@ func checkProjectBeforeUpdateOrDelete(s *xorm.Session, project *Project) error {
|
||||
}
|
||||
}
|
||||
|
||||
_, err := GetProjectSimpleByID(s, project.ParentProjectID)
|
||||
var parent *Project
|
||||
parent, err = GetProjectSimpleByID(s, project.ParentProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if there's a cycle in the parent relation
|
||||
parentsVisited := make(map[int64]bool)
|
||||
parentsVisited[project.ID] = true
|
||||
for {
|
||||
if parent.ParentProjectID == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// FIXME: Can we do this with better performance?
|
||||
parent, err = GetProjectSimpleByID(s, parent.ParentProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if parentsVisited[parent.ID] {
|
||||
return &ErrProjectCannotHaveACyclicRelationship{
|
||||
ProjectID: project.ID,
|
||||
}
|
||||
}
|
||||
|
||||
parentsVisited[parent.ID] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the identifier is unique and not empty
|
||||
|
Reference in New Issue
Block a user