code.gitea.io/gitea@v1.21.7/models/migrations/v1_10/v96.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package v1_10 //nolint
     5  
     6  import (
     7  	"path/filepath"
     8  
     9  	"code.gitea.io/gitea/modules/setting"
    10  	"code.gitea.io/gitea/modules/util"
    11  
    12  	"xorm.io/xorm"
    13  )
    14  
    15  func DeleteOrphanedAttachments(x *xorm.Engine) error {
    16  	type Attachment struct {
    17  		ID        int64  `xorm:"pk autoincr"`
    18  		UUID      string `xorm:"uuid UNIQUE"`
    19  		IssueID   int64  `xorm:"INDEX"`
    20  		ReleaseID int64  `xorm:"INDEX"`
    21  		CommentID int64
    22  	}
    23  
    24  	sess := x.NewSession()
    25  	defer sess.Close()
    26  
    27  	limit := setting.Database.IterateBufferSize
    28  	if limit <= 0 {
    29  		limit = 50
    30  	}
    31  
    32  	for {
    33  		attachments := make([]Attachment, 0, limit)
    34  		if err := sess.Where("`issue_id` = 0 and (`release_id` = 0 or `release_id` not in (select `id` from `release`))").
    35  			Cols("id, uuid").Limit(limit).
    36  			Asc("id").
    37  			Find(&attachments); err != nil {
    38  			return err
    39  		}
    40  		if len(attachments) == 0 {
    41  			return nil
    42  		}
    43  
    44  		ids := make([]int64, 0, limit)
    45  		for _, attachment := range attachments {
    46  			ids = append(ids, attachment.ID)
    47  		}
    48  		if len(ids) > 0 {
    49  			if _, err := sess.In("id", ids).Delete(new(Attachment)); err != nil {
    50  				return err
    51  			}
    52  		}
    53  
    54  		for _, attachment := range attachments {
    55  			uuid := attachment.UUID
    56  			if err := util.RemoveAll(filepath.Join(setting.Attachment.Storage.Path, uuid[0:1], uuid[1:2], uuid)); err != nil {
    57  				return err
    58  			}
    59  		}
    60  		if len(attachments) < limit {
    61  			return nil
    62  		}
    63  	}
    64  }