From dcb3ddb5c5e092f49ed0e495e4973a6205ebb177 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Fri, 27 Sep 2019 18:56:17 -0300 Subject: [PATCH] Revert #7898 --- models/issue.go | 52 +++++++++++++++++++++---------------- routers/api/v1/repo/pull.go | 7 +++++ routers/repo/pull.go | 7 +++++ 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/models/issue.go b/models/issue.go index 77712c0fec72e..eea39fb2c5bae 100644 --- a/models/issue.go +++ b/models/issue.go @@ -5,6 +5,7 @@ package models import ( + "errors" "fmt" "path" "regexp" @@ -73,7 +74,6 @@ var ( const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sx]\]\s.)|(\n\s*[-*]\s\[[\sx]\]\s.)` const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[x]\]\s.)|(\n\s*[-*]\s\[[x]\]\s.)` -const issueMaxDupIndexAttempts = 3 func init() { issueTasksPat = regexp.MustCompile(issueTasksRegexpStr) @@ -1053,9 +1053,36 @@ type NewIssueOptions struct { IsPull bool } +// GetMaxIndexOfIssue returns the max index on issue +func GetMaxIndexOfIssue(repoID int64) (int64, error) { + return getMaxIndexOfIssue(x, repoID) +} + +func getMaxIndexOfIssue(e Engine, repoID int64) (int64, error) { + var ( + maxIndex int64 + has bool + err error + ) + + has, err = e.SQL("SELECT COALESCE((SELECT MAX(`index`) FROM issue WHERE repo_id = ?),0)", repoID).Get(&maxIndex) + if err != nil { + return 0, err + } else if !has { + return 0, errors.New("Retrieve Max index from issue failed") + } + return maxIndex, nil +} + func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) { opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) + maxIndex, err := getMaxIndexOfIssue(e, opts.Issue.RepoID) + if err != nil { + return err + } + opts.Issue.Index = maxIndex + 1 + if opts.Issue.MilestoneID > 0 { milestone, err := getMilestoneByRepoID(e, opts.Issue.RepoID, opts.Issue.MilestoneID) if err != nil && !IsErrMilestoneNotExist(err) { @@ -1104,31 +1131,10 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) { } // Milestone and assignee validation should happen before insert actual object. - - // There's no good way to identify a duplicate key error in database/sql; brute force some retries - dupIndexAttempts := issueMaxDupIndexAttempts - for { - _, err := e.SetExpr("`index`", "coalesce(MAX(`index`),0)+1"). - Where("repo_id=?", opts.Issue.RepoID). - Insert(opts.Issue) - if err == nil { - break - } - - dupIndexAttempts-- - if dupIndexAttempts <= 0 { - return err - } - } - - inserted, err := getIssueByID(e, opts.Issue.ID) - if err != nil { + if _, err = e.Insert(opts.Issue); err != nil { return err } - // Patch Index with the value calculated by the database - opts.Issue.Index = inserted.Index - if opts.Issue.MilestoneID > 0 { if err = changeMilestoneAssign(e, doer, opts.Issue, -1); err != nil { return err diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 0f9eab2f5029d..370a95eabff1c 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -254,8 +254,15 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) } + maxIndex, err := models.GetMaxIndexOfIssue(repo.ID) + if err != nil { + ctx.ServerError("GetPatch", err) + return + } + prIssue := &models.Issue{ RepoID: repo.ID, + Index: maxIndex + 1, Title: form.Title, PosterID: ctx.User.ID, Poster: ctx.User, diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 180d592e3dbf8..f6332d0d5d204 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -766,8 +766,15 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) return } + maxIndex, err := models.GetMaxIndexOfIssue(repo.ID) + if err != nil { + ctx.ServerError("GetPatch", err) + return + } + pullIssue := &models.Issue{ RepoID: repo.ID, + Index: maxIndex + 1, Title: form.Title, PosterID: ctx.User.ID, Poster: ctx.User,