aboutsummaryrefslogtreecommitdiffstats
path: root/models/issue.go
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-06-14 10:22:55 +0800
committerGitHub <noreply@github.com>2021-06-14 10:22:55 +0800
commit0393a57511dc863bea4783fbb4b57cd11c41688a (patch)
treef479085c97ffe419e6fe02c88f6a2730a673fcb8 /models/issue.go
parenta005265718b840d34858a3b705f8133e1b4dbdbf (diff)
downloadgitea-0393a57511dc863bea4783fbb4b57cd11c41688a.tar.gz
gitea-0393a57511dc863bea4783fbb4b57cd11c41688a.zip
Add a new table issue_index to store the max issue index so that issue could be deleted with no duplicated index (#15599)
* Add a new table issue_index to store the max issue index so that issue could be deleted with no duplicated index * Fix pull index * Add tests for concurrent creating issues * Fix lint * Fix tests * Fix postgres test * Add test for migration v180 * Rename wrong test file name Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lauris BH <lauris@nix.lv>
Diffstat (limited to 'models/issue.go')
-rw-r--r--models/issue.go42
1 files changed, 13 insertions, 29 deletions
diff --git a/models/issue.go b/models/issue.go
index 760aaaab09..769988795a 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -78,9 +78,8 @@ var (
)
const (
- issueTasksRegexpStr = `(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`
- issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`
- issueMaxDupIndexAttempts = 3
+ issueTasksRegexpStr = `(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`
+ issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`
)
func init() {
@@ -896,21 +895,17 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
}
}
- // Milestone validation should happen before insert actual object.
- if _, err := e.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
- Where("repo_id=?", opts.Issue.RepoID).
- Insert(opts.Issue); err != nil {
- return ErrNewIssueInsert{err}
+ if opts.Issue.Index <= 0 {
+ return fmt.Errorf("no issue index provided")
+ }
+ if opts.Issue.ID > 0 {
+ return fmt.Errorf("issue exist")
}
- 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 = e.Exec("UPDATE `milestone` SET num_issues=num_issues+1 WHERE id=?", opts.Issue.MilestoneID); err != nil {
return err
@@ -987,24 +982,13 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
// NewIssue creates new issue with labels for repository.
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
- // Retry several times in case INSERT fails due to duplicate key for (repo_id, index); see #7887
- i := 0
- for {
- if err = newIssueAttempt(repo, issue, labelIDs, uuids); err == nil {
- return nil
- }
- if !IsErrNewIssueInsert(err) {
- return err
- }
- if i++; i == issueMaxDupIndexAttempts {
- break
- }
- log.Error("NewIssue: error attempting to insert the new issue; will retry. Original error: %v", err)
+ idx, err := GetNextResourceIndex("issue_index", repo.ID)
+ if err != nil {
+ return fmt.Errorf("generate issue index failed: %v", err)
}
- return fmt.Errorf("NewIssue: too many errors attempting to insert the new issue. Last error was: %v", err)
-}
-func newIssueAttempt(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
+ issue.Index = idx
+
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {