* delete attachments from the database and file system * add migration * fix import statements * fix package name * remove conditional should in case the confi has been changed and the server restarted * simplify deletion of attachments in DB * fix CI build * fix review * add copyright in the proper place * fix reviewtags/v1.21.12.1
| @@ -246,6 +246,8 @@ var migrations = []Migration{ | |||||
| NewMigration("add enable_status_check, status_check_contexts to protected_branch", addStatusCheckColumnsForProtectedBranches), | NewMigration("add enable_status_check, status_check_contexts to protected_branch", addStatusCheckColumnsForProtectedBranches), | ||||
| // v95 -> v96 | // v95 -> v96 | ||||
| NewMigration("add table columns for cross referencing issues", addCrossReferenceColumns), | NewMigration("add table columns for cross referencing issues", addCrossReferenceColumns), | ||||
| // v96 -> v97 | |||||
| NewMigration("delete orphaned attachments", deleteOrphanedAttachments), | |||||
| } | } | ||||
| // Migrate database to current version | // Migrate database to current version | ||||
| @@ -14,5 +14,4 @@ func addIsLockedToIssues(x *xorm.Engine) error { | |||||
| } | } | ||||
| return x.Sync2(new(Issue)) | return x.Sync2(new(Issue)) | ||||
| } | } | ||||
| @@ -0,0 +1,48 @@ | |||||
| // Copyright 2019 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 ( | |||||
| "os" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "github.com/go-xorm/xorm" | |||||
| ) | |||||
| func deleteOrphanedAttachments(x *xorm.Engine) error { | |||||
| type Attachment struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| UUID string `xorm:"uuid UNIQUE"` | |||||
| IssueID int64 `xorm:"INDEX"` | |||||
| ReleaseID int64 `xorm:"INDEX"` | |||||
| CommentID int64 | |||||
| } | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| err := sess.BufferSize(setting.Database.IterateBufferSize). | |||||
| Where("`comment_id` = 0 and (`release_id` = 0 or `release_id` not in (select `id` from `release`))").Cols("uuid"). | |||||
| Iterate(new(Attachment), | |||||
| func(idx int, bean interface{}) error { | |||||
| attachment := bean.(*Attachment) | |||||
| if err := os.RemoveAll(models.AttachmentLocalPath(attachment.UUID)); err != nil { | |||||
| return err | |||||
| } | |||||
| _, err := sess.ID(attachment.ID).NoAutoCondition().Delete(attachment) | |||||
| return err | |||||
| }) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| return sess.Commit() | |||||
| } | |||||
| @@ -1,4 +1,5 @@ | |||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | // Copyright 2014 The Gogs Authors. All rights reserved. | ||||
| // Copyright 2019 The Gitea Authors. All rights reserved. | |||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| @@ -6,6 +7,7 @@ package models | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| "os" | |||||
| "sort" | "sort" | ||||
| "strings" | "strings" | ||||
| @@ -357,6 +359,17 @@ func DeleteReleaseByID(id int64, doer *User, delTag bool) error { | |||||
| return fmt.Errorf("LoadAttributes: %v", err) | return fmt.Errorf("LoadAttributes: %v", err) | ||||
| } | } | ||||
| if _, err := x.Delete(&Attachment{ReleaseID: id}); err != nil { | |||||
| return err | |||||
| } | |||||
| for i := range rel.Attachments { | |||||
| attachment := rel.Attachments[i] | |||||
| if err := os.RemoveAll(attachment.LocalPath()); err != nil { | |||||
| return err | |||||
| } | |||||
| } | |||||
| mode, _ := AccessLevel(doer, rel.Repo) | mode, _ := AccessLevel(doer, rel.Repo) | ||||
| if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{ | if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{ | ||||
| Action: api.HookReleaseDeleted, | Action: api.HookReleaseDeleted, | ||||