aboutsummaryrefslogtreecommitdiffstats
path: root/services/issue
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2023-07-22 22:14:27 +0800
committerGitHub <noreply@github.com>2023-07-22 22:14:27 +0800
commitb167f35113e643ccdb17a2dde55bdec5960b284b (patch)
tree99a6e53bf1a9d4c9199c19113650cc48a8c1fd0e /services/issue
parentc42b71877edb4830b9573101d20853222d66fb3c (diff)
downloadgitea-b167f35113e643ccdb17a2dde55bdec5960b284b.tar.gz
gitea-b167f35113e643ccdb17a2dde55bdec5960b284b.zip
Add context parameter to some database functions (#26055)
To avoid deadlock problem, almost database related functions should be have ctx as the first parameter. This PR do a refactor for some of these functions.
Diffstat (limited to 'services/issue')
-rw-r--r--services/issue/comments.go6
-rw-r--r--services/issue/commit.go24
-rw-r--r--services/issue/commit_test.go17
-rw-r--r--services/issue/status.go9
4 files changed, 25 insertions, 31 deletions
diff --git a/services/issue/comments.go b/services/issue/comments.go
index 4a181499bc..ed05f725ff 100644
--- a/services/issue/comments.go
+++ b/services/issue/comments.go
@@ -36,13 +36,13 @@ func CreateComment(ctx context.Context, opts *issues_model.CreateCommentOptions)
}
// CreateRefComment creates a commit reference comment to issue.
-func CreateRefComment(doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, commitSHA string) error {
+func CreateRefComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, commitSHA string) error {
if len(commitSHA) == 0 {
return fmt.Errorf("cannot create reference with empty commit SHA")
}
// Check if same reference from same commit has already existed.
- has, err := db.GetEngine(db.DefaultContext).Get(&issues_model.Comment{
+ has, err := db.GetEngine(ctx).Get(&issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
IssueID: issue.ID,
CommitSHA: commitSHA,
@@ -53,7 +53,7 @@ func CreateRefComment(doer *user_model.User, repo *repo_model.Repository, issue
return nil
}
- _, err = CreateComment(db.DefaultContext, &issues_model.CreateCommentOptions{
+ _, err = CreateComment(ctx, &issues_model.CreateCommentOptions{
Type: issues_model.CommentTypeCommitRef,
Doer: doer,
Repo: repo,
diff --git a/services/issue/commit.go b/services/issue/commit.go
index 7a8c71e609..e493a03211 100644
--- a/services/issue/commit.go
+++ b/services/issue/commit.go
@@ -4,6 +4,7 @@
package issue
import (
+ "context"
"fmt"
"html"
"net/url"
@@ -12,7 +13,6 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
@@ -78,20 +78,20 @@ func timeLogToAmount(str string) int64 {
return a
}
-func issueAddTime(issue *issues_model.Issue, doer *user_model.User, time time.Time, timeLog string) error {
+func issueAddTime(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, time time.Time, timeLog string) error {
amount := timeLogToAmount(timeLog)
if amount == 0 {
return nil
}
- _, err := issues_model.AddTime(doer, issue, amount, time)
+ _, err := issues_model.AddTime(ctx, doer, issue, amount, time)
return err
}
// getIssueFromRef returns the issue referenced by a ref. Returns a nil *Issue
// if the provided ref references a non-existent issue.
-func getIssueFromRef(repo *repo_model.Repository, index int64) (*issues_model.Issue, error) {
- issue, err := issues_model.GetIssueByIndex(repo.ID, index)
+func getIssueFromRef(ctx context.Context, repo *repo_model.Repository, index int64) (*issues_model.Issue, error) {
+ issue, err := issues_model.GetIssueByIndex(ctx, repo.ID, index)
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
return nil, nil
@@ -102,7 +102,7 @@ func getIssueFromRef(repo *repo_model.Repository, index int64) (*issues_model.Is
}
// UpdateIssuesCommit checks if issues are manipulated by commit message.
-func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, commits []*repository.PushCommit, branchName string) error {
+func UpdateIssuesCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, commits []*repository.PushCommit, branchName string) error {
// Commits are appended in the reverse order.
for i := len(commits) - 1; i >= 0; i-- {
c := commits[i]
@@ -120,7 +120,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm
// issue is from another repo
if len(ref.Owner) > 0 && len(ref.Name) > 0 {
- refRepo, err = repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, ref.Owner, ref.Name)
+ refRepo, err = repo_model.GetRepositoryByOwnerAndName(ctx, ref.Owner, ref.Name)
if err != nil {
if repo_model.IsErrRepoNotExist(err) {
log.Warn("Repository referenced in commit but does not exist: %v", err)
@@ -132,14 +132,14 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm
} else {
refRepo = repo
}
- if refIssue, err = getIssueFromRef(refRepo, ref.Index); err != nil {
+ if refIssue, err = getIssueFromRef(ctx, refRepo, ref.Index); err != nil {
return err
}
if refIssue == nil {
continue
}
- perm, err := access_model.GetUserRepoPermission(db.DefaultContext, refRepo, doer)
+ perm, err := access_model.GetUserRepoPermission(ctx, refRepo, doer)
if err != nil {
return err
}
@@ -159,7 +159,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm
}
message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, html.EscapeString(repo.Link()), html.EscapeString(url.PathEscape(c.Sha1)), html.EscapeString(strings.SplitN(c.Message, "\n", 2)[0]))
- if err = CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil {
+ if err = CreateRefComment(ctx, doer, refRepo, refIssue, message, c.Sha1); err != nil {
return err
}
@@ -187,13 +187,13 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm
}
close := ref.Action == references.XRefActionCloses
if close && len(ref.TimeLog) > 0 {
- if err := issueAddTime(refIssue, doer, c.Timestamp, ref.TimeLog); err != nil {
+ if err := issueAddTime(ctx, refIssue, doer, c.Timestamp, ref.TimeLog); err != nil {
return err
}
}
if close != refIssue.IsClosed {
refIssue.Repo = refRepo
- if err := ChangeStatus(refIssue, doer, c.Sha1, close); err != nil {
+ if err := ChangeStatus(ctx, refIssue, doer, c.Sha1, close); err != nil {
return err
}
}
diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go
index 590e7adce9..1bc9f6f951 100644
--- a/services/issue/commit_test.go
+++ b/services/issue/commit_test.go
@@ -7,6 +7,7 @@ import (
"testing"
activities_model "code.gitea.io/gitea/models/activities"
+ "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -60,7 +61,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -87,7 +88,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch"))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -113,7 +114,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -139,7 +140,7 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) {
issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4}
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
@@ -172,7 +173,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch"))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -207,7 +208,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -242,7 +243,7 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -292,7 +293,7 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, commentBean2)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
+ assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, commentBean2)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
diff --git a/services/issue/status.go b/services/issue/status.go
index d4a0fce3e5..3718a5048f 100644
--- a/services/issue/status.go
+++ b/services/issue/status.go
@@ -6,7 +6,6 @@ package issue
import (
"context"
- "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
@@ -14,13 +13,7 @@ import (
)
// ChangeStatus changes issue status to open or closed.
-func ChangeStatus(issue *issues_model.Issue, doer *user_model.User, commitID string, closed bool) error {
- return changeStatusCtx(db.DefaultContext, issue, doer, commitID, closed)
-}
-
-// changeStatusCtx changes issue status to open or closed.
-// TODO: if context is not db.DefaultContext we get a deadlock!!!
-func changeStatusCtx(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, commitID string, closed bool) error {
+func ChangeStatus(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, commitID string, closed bool) error {
comment, err := issues_model.ChangeIssueStatus(ctx, issue, doer, closed)
if err != nil {
if issues_model.IsErrDependenciesLeft(err) && closed {