Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete related PullAutoMerge and ReviewState on User/Repo Deletion #19649

Merged
merged 12 commits into from
May 8, 2022
15 changes: 15 additions & 0 deletions models/db/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,18 @@ func IsErrSSHDisabled(err error) bool {
func (err ErrSSHDisabled) Error() string {
return "SSH is disabled"
}

// ErrNotExist represents a non-exist error.
type ErrNotExist struct {
ID int64
6543 marked this conversation as resolved.
Show resolved Hide resolved
}

// IsErrNotExist checks if an error is an ErrNotExist
func IsErrNotExist(err error) bool {
_, ok := err.(ErrNotExist)
return ok
}

func (err ErrNotExist) Error() string {
return fmt.Sprintf("record does not exist [id: %d]", err.ID)
6543 marked this conversation as resolved.
Show resolved Hide resolved
}
15 changes: 0 additions & 15 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,6 @@ import (
"code.gitea.io/gitea/modules/git"
)

// ErrNotExist represents a non-exist error.
type ErrNotExist struct {
ID int64
}

// IsErrNotExist checks if an error is an ErrNotExist
func IsErrNotExist(err error) bool {
_, ok := err.(ErrNotExist)
return ok
}

func (err ErrNotExist) Error() string {
return fmt.Sprintf("record does not exist [id: %d]", err.ID)
}

// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
type ErrUserOwnRepos struct {
UID int64
Expand Down
22 changes: 22 additions & 0 deletions models/issue_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,28 @@ func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *Pul
return
}

// CreateAutoMergeComment is a internal function, only use it for CommentTypePRScheduledToAutoMerge and CommentTypePRUnScheduledToAutoMerge CommentTypes
func CreateAutoMergeComment(ctx context.Context, typ CommentType, pr *PullRequest, doer *user_model.User) (comment *Comment, err error) {
6543 marked this conversation as resolved.
Show resolved Hide resolved
if typ != CommentTypePRScheduledToAutoMerge && typ != CommentTypePRUnScheduledToAutoMerge {
return nil, fmt.Errorf("comment type %d cannot be used to create an auto merge comment", typ)
}
if err = pr.LoadIssueCtx(ctx); err != nil {
6543 marked this conversation as resolved.
Show resolved Hide resolved
return
}

if err = pr.LoadBaseRepoCtx(ctx); err != nil {
return
}

comment, err = CreateCommentCtx(ctx, &CreateCommentOptions{
Type: typ,
Doer: doer,
Repo: pr.BaseRepo,
Issue: pr.Issue,
})
return
}

// getCommitsFromRepo get commit IDs from repo in between oldCommitID and newCommitID
// isForcePush will be true if oldCommit isn't on the branch
// Commit on baseBranch will skip
Expand Down
6 changes: 3 additions & 3 deletions models/issue_tracked_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error {
return err
}
if removedTime == 0 {
return ErrNotExist{}
return db.ErrNotExist{}
6543 marked this conversation as resolved.
Show resolved Hide resolved
}

if err := issue.LoadRepo(ctx); err != nil {
Expand Down Expand Up @@ -311,7 +311,7 @@ func deleteTimes(e db.Engine, opts FindTrackedTimesOptions) (removedTime int64,

func deleteTime(e db.Engine, t *TrackedTime) error {
if t.Deleted {
return ErrNotExist{ID: t.ID}
return db.ErrNotExist{ID: t.ID}
6543 marked this conversation as resolved.
Show resolved Hide resolved
}
t.Deleted = true
_, err := e.ID(t.ID).Cols("deleted").Update(t)
Expand All @@ -325,7 +325,7 @@ func GetTrackedTimeByID(id int64) (*TrackedTime, error) {
if err != nil {
return nil, err
} else if !has {
return nil, ErrNotExist{ID: id}
return nil, db.ErrNotExist{ID: id}
6543 marked this conversation as resolved.
Show resolved Hide resolved
}
return time, nil
}
2 changes: 1 addition & 1 deletion models/migrations/v215.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func addReviewViewedFiles(x *xorm.Engine) error {
type ReviewState struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
PullID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user) DEFAULT 0"`
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"`
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"`
UpdatedFiles map[string]pull.ViewedState `xorm:"NOT NULL LONGTEXT JSON"`
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
Expand Down
2 changes: 1 addition & 1 deletion models/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ func getNotificationByID(e db.Engine, notificationID int64) (*Notification, erro
}

if !ok {
return nil, ErrNotExist{ID: notificationID}
return nil, db.ErrNotExist{ID: notificationID}
6543 marked this conversation as resolved.
Show resolved Hide resolved
}

return notification, nil
Expand Down
20 changes: 20 additions & 0 deletions models/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strings"

"code.gitea.io/gitea/models/db"
pull_model "code.gitea.io/gitea/models/pull"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
Expand Down Expand Up @@ -96,6 +97,25 @@ func init() {
db.RegisterModel(new(PullRequest))
}

func deletePullsByBaseRepoID(sess db.Engine, repoID int64) error {
deleteCond := builder.Select("id").From("pull_request").Where(builder.Eq{"pull_request.base_repo_id": repoID})

// Delete scheduled auto merges
if _, err := sess.In("pull_id", deleteCond).
Delete(&pull_model.AutoMerge{}); err != nil {
return err
}

// Delete review states
if _, err := sess.In("pull_id", deleteCond).
Delete(&pull_model.ReviewState{}); err != nil {
return err
}
6543 marked this conversation as resolved.
Show resolved Hide resolved

_, err := sess.Delete(&PullRequest{BaseRepoID: repoID})
return err
}

// MustHeadUserName returns the HeadRepo's username if failed return blank
func (pr *PullRequest) MustHeadUserName() string {
if err := pr.LoadHeadRepo(); err != nil {
Expand Down
65 changes: 10 additions & 55 deletions models/pull/automerge.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"context"
"fmt"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
Expand Down Expand Up @@ -59,21 +58,12 @@ func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pullID int64,
return ErrAlreadyScheduledToAutoMerge{PullID: pullID}
}

if _, err := db.GetEngine(ctx).Insert(&AutoMerge{
_, err := db.GetEngine(ctx).Insert(&AutoMerge{
DoerID: doer.ID,
PullID: pullID,
MergeStyle: style,
Message: message,
}); err != nil {
return err
}

pr, err := models.GetPullRequestByID(ctx, pullID)
if err != nil {
return err
}

_, err = createAutoMergeComment(ctx, models.CommentTypePRScheduledToAutoMerge, pr, doer)
})
return err
}

Expand All @@ -94,50 +84,15 @@ func GetScheduledMergeByPullID(ctx context.Context, pullID int64) (bool, *AutoMe
return true, scheduledPRM, nil
}

// RemoveScheduledAutoMerge cancels a previously scheduled pull request
func RemoveScheduledAutoMerge(ctx context.Context, doer *user_model.User, pullID int64, comment bool) error {
return db.WithTx(func(ctx context.Context) error {
exist, scheduledPRM, err := GetScheduledMergeByPullID(ctx, pullID)
if err != nil {
return err
} else if !exist {
return models.ErrNotExist{ID: pullID}
}

if _, err := db.GetEngine(ctx).ID(scheduledPRM.ID).Delete(&AutoMerge{}); err != nil {
return err
}

// if pull got merged we don't need to add "auto-merge canceled comment"
if !comment || doer == nil {
return nil
}

pr, err := models.GetPullRequestByID(ctx, pullID)
if err != nil {
return err
}

_, err = createAutoMergeComment(ctx, models.CommentTypePRUnScheduledToAutoMerge, pr, doer)
// DeleteScheduledAutoMerge delete a scheduled pull request
func DeleteScheduledAutoMerge(ctx context.Context, pullID int64) error {
exist, scheduledPRM, err := GetScheduledMergeByPullID(ctx, pullID)
if err != nil {
return err
}, ctx)
}

// createAutoMergeComment is a internal function, only use it for CommentTypePRScheduledToAutoMerge and CommentTypePRUnScheduledToAutoMerge CommentTypes
func createAutoMergeComment(ctx context.Context, typ models.CommentType, pr *models.PullRequest, doer *user_model.User) (comment *models.Comment, err error) {
if err = pr.LoadIssueCtx(ctx); err != nil {
return
} else if !exist {
return db.ErrNotExist{ID: pullID}
6543 marked this conversation as resolved.
Show resolved Hide resolved
}

if err = pr.LoadBaseRepoCtx(ctx); err != nil {
return
}

comment, err = models.CreateCommentCtx(ctx, &models.CreateCommentOptions{
Type: typ,
Doer: doer,
Repo: pr.BaseRepo,
Issue: pr.Issue,
})
return
_, err = db.GetEngine(ctx).ID(scheduledPRM.ID).Delete(&AutoMerge{})
return err
}
8 changes: 4 additions & 4 deletions models/pull/review_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ func (viewedState ViewedState) String() string {
type ReviewState struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
PullID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
UpdatedFiles map[string]ViewedState `xorm:"NOT NULL LONGTEXT JSON"` // Stores for each of the changed files of a PR whether they have been viewed, changed since last viewed, or not viewed
UpdatedUnix timeutil.TimeStamp `xorm:"updated"` // Is an accurate indicator of the order of commits as we do not expect it to be possible to make reviews on previous commits
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
UpdatedFiles map[string]ViewedState `xorm:"NOT NULL LONGTEXT JSON"` // Stores for each of the changed files of a PR whether they have been viewed, changed since last viewed, or not viewed
UpdatedUnix timeutil.TimeStamp `xorm:"updated"` // Is an accurate indicator of the order of commits as we do not expect it to be possible to make reviews on previous commits
}

func init() {
Expand Down
6 changes: 5 additions & 1 deletion models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,6 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
&Notification{RepoID: repoID},
&ProtectedBranch{RepoID: repoID},
&ProtectedTag{RepoID: repoID},
&PullRequest{BaseRepoID: repoID},
&repo_model.PushMirror{RepoID: repoID},
&Release{RepoID: repoID},
&repo_model.RepoIndexerStatus{RepoID: repoID},
Expand All @@ -723,6 +722,11 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
return err
}

// Delete Pulls and related objects
if err := deletePullsByBaseRepoID(sess, repoID); err != nil {
return err
}

// Delete Issues and related objects
var attachmentPaths []string
if attachmentPaths, err = deleteIssuesByRepoID(sess, repoID); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
pull_model "code.gitea.io/gitea/models/pull"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
Expand Down Expand Up @@ -82,6 +83,8 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
&Collaboration{UserID: u.ID},
&Stopwatch{UserID: u.ID},
&user_model.Setting{UserID: u.ID},
&pull_model.AutoMerge{DoerID: u.ID},
&pull_model.ReviewState{UserID: u.ID},
); err != nil {
return fmt.Errorf("deleteBeans: %v", err)
}
Expand Down
3 changes: 2 additions & 1 deletion routers/api/v1/notify/threads.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
)
Expand Down Expand Up @@ -102,7 +103,7 @@ func ReadThread(ctx *context.APIContext) {
func getThread(ctx *context.APIContext) *models.Notification {
n, err := models.GetNotificationByID(ctx.ParamsInt64(":id"))
if err != nil {
if models.IsErrNotExist(err) {
if db.IsErrNotExist(err) {
ctx.Error(http.StatusNotFound, "GetNotificationByID", err)
} else {
ctx.InternalServerError(err)
Expand Down
5 changes: 3 additions & 2 deletions routers/api/v1/repo/issue_tracked_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
Expand Down Expand Up @@ -281,7 +282,7 @@ func ResetIssueTime(ctx *context.APIContext) {

err = models.DeleteIssueUserTimes(issue, ctx.Doer)
if err != nil {
if models.IsErrNotExist(err) {
if db.IsErrNotExist(err) {
ctx.Error(http.StatusNotFound, "DeleteIssueUserTimes", err)
} else {
ctx.Error(http.StatusInternalServerError, "DeleteIssueUserTimes", err)
Expand Down Expand Up @@ -352,7 +353,7 @@ func DeleteTime(ctx *context.APIContext) {

time, err := models.GetTrackedTimeByID(ctx.ParamsInt64(":id"))
if err != nil {
if models.IsErrNotExist(err) {
if db.IsErrNotExist(err) {
ctx.NotFound(err)
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/api/v1/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) {
}
}

if err := pull_model.RemoveScheduledAutoMerge(ctx, ctx.Doer, pull.ID, true); err != nil {
if err := automerge.RemoveScheduledAutoMerge(ctx, ctx.Doer, pull); err != nil {
ctx.InternalServerError(err)
} else {
ctx.Status(http.StatusNoContent)
Expand Down
3 changes: 2 additions & 1 deletion routers/web/repo/issue_timetrack.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
Expand Down Expand Up @@ -63,7 +64,7 @@ func DeleteTime(c *context.Context) {

t, err := models.GetTrackedTimeByID(c.ParamsInt64(":timeid"))
if err != nil {
if models.IsErrNotExist(err) {
if db.IsErrNotExist(err) {
c.NotFound("time not found", err)
return
}
Expand Down
Loading