aboutsummaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/asymkey/deploy_key.go31
-rw-r--r--services/asymkey/ssh_key.go13
-rw-r--r--services/asymkey/ssh_key_principals.go42
-rw-r--r--services/auth/source/oauth2/store.go15
-rw-r--r--services/contexttest/context_tests.go2
-rw-r--r--services/issue/label.go38
-rw-r--r--services/issue/milestone.go15
-rw-r--r--services/issue/status.go30
-rw-r--r--services/org/team.go243
-rw-r--r--services/packages/cleanup/cleanup.go52
-rw-r--r--services/packages/packages.go19
-rw-r--r--services/pull/merge.go68
-rw-r--r--services/repository/avatar.go72
-rw-r--r--services/repository/collaboration.go50
-rw-r--r--services/repository/repo_team.go28
-rw-r--r--services/repository/setting.go52
-rw-r--r--services/user/avatar.go32
17 files changed, 334 insertions, 468 deletions
diff --git a/services/asymkey/deploy_key.go b/services/asymkey/deploy_key.go
index 9e5a6d6292..04023f9ffb 100644
--- a/services/asymkey/deploy_key.go
+++ b/services/asymkey/deploy_key.go
@@ -49,28 +49,21 @@ func deleteDeployKeyFromDB(ctx context.Context, key *asymkey_model.DeployKey) er
// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed.
// Permissions check should be done outside.
func DeleteDeployKey(ctx context.Context, repo *repo_model.Repository, id int64) error {
- dbCtx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- key, err := asymkey_model.GetDeployKeyByID(ctx, id)
- if err != nil {
- if asymkey_model.IsErrDeployKeyNotExist(err) {
- return nil
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ key, err := asymkey_model.GetDeployKeyByID(ctx, id)
+ if err != nil {
+ if asymkey_model.IsErrDeployKeyNotExist(err) {
+ return nil
+ }
+ return fmt.Errorf("GetDeployKeyByID: %w", err)
}
- return fmt.Errorf("GetDeployKeyByID: %w", err)
- }
- if key.RepoID != repo.ID {
- return fmt.Errorf("deploy key %d does not belong to repository %d", id, repo.ID)
- }
+ if key.RepoID != repo.ID {
+ return fmt.Errorf("deploy key %d does not belong to repository %d", id, repo.ID)
+ }
- if err := deleteDeployKeyFromDB(dbCtx, key); err != nil {
- return err
- }
- if err := committer.Commit(); err != nil {
+ return deleteDeployKeyFromDB(ctx, key)
+ }); err != nil {
return err
}
diff --git a/services/asymkey/ssh_key.go b/services/asymkey/ssh_key.go
index da57059d4b..01fa7ff15f 100644
--- a/services/asymkey/ssh_key.go
+++ b/services/asymkey/ssh_key.go
@@ -27,20 +27,9 @@ func DeletePublicKey(ctx context.Context, doer *user_model.User, id int64) (err
}
}
- dbCtx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if _, err = db.DeleteByID[asymkey_model.PublicKey](dbCtx, id); err != nil {
- return err
- }
-
- if err = committer.Commit(); err != nil {
+ if _, err = db.DeleteByID[asymkey_model.PublicKey](ctx, id); err != nil {
return err
}
- committer.Close()
if key.Type == asymkey_model.KeyTypePrincipal {
return RewriteAllPrincipalKeys(ctx)
diff --git a/services/asymkey/ssh_key_principals.go b/services/asymkey/ssh_key_principals.go
index 5ed5cfa782..6493c1cc51 100644
--- a/services/asymkey/ssh_key_principals.go
+++ b/services/asymkey/ssh_key_principals.go
@@ -14,24 +14,6 @@ import (
// AddPrincipalKey adds new principal to database and authorized_principals file.
func AddPrincipalKey(ctx context.Context, ownerID int64, content string, authSourceID int64) (*asymkey_model.PublicKey, error) {
- dbCtx, committer, err := db.TxContext(ctx)
- if err != nil {
- return nil, err
- }
- defer committer.Close()
-
- // Principals cannot be duplicated.
- has, err := db.GetEngine(dbCtx).
- Where("content = ? AND type = ?", content, asymkey_model.KeyTypePrincipal).
- Get(new(asymkey_model.PublicKey))
- if err != nil {
- return nil, err
- } else if has {
- return nil, asymkey_model.ErrKeyAlreadyExist{
- Content: content,
- }
- }
-
key := &asymkey_model.PublicKey{
OwnerID: ownerID,
Name: content,
@@ -40,15 +22,27 @@ func AddPrincipalKey(ctx context.Context, ownerID int64, content string, authSou
Type: asymkey_model.KeyTypePrincipal,
LoginSourceID: authSourceID,
}
- if err = db.Insert(dbCtx, key); err != nil {
- return nil, fmt.Errorf("addKey: %w", err)
- }
- if err = committer.Commit(); err != nil {
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ // Principals cannot be duplicated.
+ has, err := db.GetEngine(ctx).
+ Where("content = ? AND type = ?", content, asymkey_model.KeyTypePrincipal).
+ Get(new(asymkey_model.PublicKey))
+ if err != nil {
+ return err
+ } else if has {
+ return asymkey_model.ErrKeyAlreadyExist{
+ Content: content,
+ }
+ }
+
+ if err = db.Insert(ctx, key); err != nil {
+ return fmt.Errorf("addKey: %w", err)
+ }
+ return nil
+ }); err != nil {
return nil, err
}
- committer.Close()
-
return key, RewriteAllPrincipalKeys(ctx)
}
diff --git a/services/auth/source/oauth2/store.go b/services/auth/source/oauth2/store.go
index 90fa965602..7b6b26edc8 100644
--- a/services/auth/source/oauth2/store.go
+++ b/services/auth/source/oauth2/store.go
@@ -11,7 +11,6 @@ import (
"code.gitea.io/gitea/modules/log"
session_module "code.gitea.io/gitea/modules/session"
- chiSession "gitea.com/go-chi/session"
"github.com/gorilla/sessions"
)
@@ -35,11 +34,11 @@ func (st *SessionsStore) New(r *http.Request, name string) (*sessions.Session, e
// getOrNew gets the session from the chi-session if it exists. Override permits the overriding of an unexpected object.
func (st *SessionsStore) getOrNew(r *http.Request, name string, override bool) (*sessions.Session, error) {
- chiStore := chiSession.GetSession(r)
+ store := session_module.GetContextSession(r)
session := sessions.NewSession(st, name)
- rawData := chiStore.Get(name)
+ rawData := store.Get(name)
if rawData != nil {
oldSession, ok := rawData.(*sessions.Session)
if ok {
@@ -56,21 +55,21 @@ func (st *SessionsStore) getOrNew(r *http.Request, name string, override bool) (
}
session.IsNew = override
- session.ID = chiStore.ID() // Simply copy the session id from the chi store
+ session.ID = store.ID() // Simply copy the session id from the chi store
- return session, chiStore.Set(name, session)
+ return session, store.Set(name, session)
}
// Save should persist session to the underlying store implementation.
func (st *SessionsStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
- chiStore := chiSession.GetSession(r)
+ store := session_module.GetContextSession(r)
if session.IsNew {
_, _ = session_module.RegenerateSession(w, r)
session.IsNew = false
}
- if err := chiStore.Set(session.Name(), session); err != nil {
+ if err := store.Set(session.Name(), session); err != nil {
return err
}
@@ -83,7 +82,7 @@ func (st *SessionsStore) Save(r *http.Request, w http.ResponseWriter, session *s
}
}
- return chiStore.Release()
+ return store.Release()
}
type sizeWriter struct {
diff --git a/services/contexttest/context_tests.go b/services/contexttest/context_tests.go
index b54023897b..44d9f4a70f 100644
--- a/services/contexttest/context_tests.go
+++ b/services/contexttest/context_tests.go
@@ -49,7 +49,7 @@ func mockRequest(t *testing.T, reqPath string) *http.Request {
type MockContextOption struct {
Render context.Render
- SessionStore *session.MockStore
+ SessionStore session.Store
}
// MockContext mock context for unit tests
diff --git a/services/issue/label.go b/services/issue/label.go
index 6b8070d8aa..e30983df37 100644
--- a/services/issue/label.go
+++ b/services/issue/label.go
@@ -46,32 +46,24 @@ func AddLabels(ctx context.Context, issue *issues_model.Issue, doer *user_model.
// RemoveLabel removes a label from issue by given ID.
func RemoveLabel(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, label *issues_model.Label) error {
- dbCtx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err := issue.LoadRepo(dbCtx); err != nil {
- return err
- }
-
- perm, err := access_model.GetUserRepoPermission(dbCtx, issue.Repo, doer)
- if err != nil {
- return err
- }
- if !perm.CanWriteIssuesOrPulls(issue.IsPull) {
- if label.OrgID > 0 {
- return issues_model.ErrOrgLabelNotExist{}
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ if err := issue.LoadRepo(ctx); err != nil {
+ return err
}
- return issues_model.ErrRepoLabelNotExist{}
- }
- if err := issues_model.DeleteIssueLabel(dbCtx, issue, label, doer); err != nil {
- return err
- }
+ perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer)
+ if err != nil {
+ return err
+ }
+ if !perm.CanWriteIssuesOrPulls(issue.IsPull) {
+ if label.OrgID > 0 {
+ return issues_model.ErrOrgLabelNotExist{}
+ }
+ return issues_model.ErrRepoLabelNotExist{}
+ }
- if err := committer.Commit(); err != nil {
+ return issues_model.DeleteIssueLabel(ctx, issue, label, doer)
+ }); err != nil {
return err
}
diff --git a/services/issue/milestone.go b/services/issue/milestone.go
index afca70794d..05aefad752 100644
--- a/services/issue/milestone.go
+++ b/services/issue/milestone.go
@@ -69,21 +69,12 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *is
// ChangeMilestoneAssign changes assignment of milestone for issue.
func ChangeMilestoneAssign(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, oldMilestoneID int64) (err error) {
- dbCtx, committer, err := db.TxContext(ctx)
- if err != nil {
+ if err := db.WithTx(ctx, func(dbCtx context.Context) error {
+ return changeMilestoneAssign(dbCtx, doer, issue, oldMilestoneID)
+ }); err != nil {
return err
}
- defer committer.Close()
-
- if err = changeMilestoneAssign(dbCtx, doer, issue, oldMilestoneID); err != nil {
- return err
- }
-
- if err = committer.Commit(); err != nil {
- return fmt.Errorf("Commit: %w", err)
- }
notify_service.IssueChangeMilestone(ctx, doer, issue, oldMilestoneID)
-
return nil
}
diff --git a/services/issue/status.go b/services/issue/status.go
index f9d7dca841..fa59df93ba 100644
--- a/services/issue/status.go
+++ b/services/issue/status.go
@@ -15,30 +15,24 @@ import (
// CloseIssue close an issue.
func CloseIssue(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, commitID string) error {
- dbCtx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- comment, err := issues_model.CloseIssue(dbCtx, issue, doer)
- if err != nil {
- if issues_model.IsErrDependenciesLeft(err) {
- if _, err := issues_model.FinishIssueStopwatch(dbCtx, doer, issue); err != nil {
- log.Error("Unable to stop stopwatch for issue[%d]#%d: %v", issue.ID, issue.Index, err)
+ var comment *issues_model.Comment
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ var err error
+ comment, err = issues_model.CloseIssue(ctx, issue, doer)
+ if err != nil {
+ if issues_model.IsErrDependenciesLeft(err) {
+ if _, err := issues_model.FinishIssueStopwatch(ctx, doer, issue); err != nil {
+ log.Error("Unable to stop stopwatch for issue[%d]#%d: %v", issue.ID, issue.Index, err)
+ }
}
+ return err
}
- return err
- }
- if _, err := issues_model.FinishIssueStopwatch(dbCtx, doer, issue); err != nil {
+ _, err = issues_model.FinishIssueStopwatch(ctx, doer, issue)
return err
- }
-
- if err := committer.Commit(); err != nil {
+ }); err != nil {
return err
}
- committer.Close()
notify_service.IssueChangeStatus(ctx, doer, commitID, issue, comment, true)
diff --git a/services/org/team.go b/services/org/team.go
index 6890dafd90..773bd11f49 100644
--- a/services/org/team.go
+++ b/services/org/team.go
@@ -54,39 +54,33 @@ func NewTeam(ctx context.Context, t *organization.Team) (err error) {
return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName}
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err = db.Insert(ctx, t); err != nil {
- return err
- }
-
- // insert units for team
- if len(t.Units) > 0 {
- for _, unit := range t.Units {
- unit.TeamID = t.ID
- }
- if err = db.Insert(ctx, &t.Units); err != nil {
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ if err = db.Insert(ctx, t); err != nil {
return err
}
- }
- // Add all repositories to the team if it has access to all of them.
- if t.IncludesAllRepositories {
- err = repo_service.AddAllRepositoriesToTeam(ctx, t)
- if err != nil {
- return fmt.Errorf("addAllRepositories: %w", err)
+ // insert units for team
+ if len(t.Units) > 0 {
+ for _, unit := range t.Units {
+ unit.TeamID = t.ID
+ }
+ if err = db.Insert(ctx, &t.Units); err != nil {
+ return err
+ }
+ }
+
+ // Add all repositories to the team if it has access to all of them.
+ if t.IncludesAllRepositories {
+ err = repo_service.AddAllRepositoriesToTeam(ctx, t)
+ if err != nil {
+ return fmt.Errorf("addAllRepositories: %w", err)
+ }
}
- }
- // Update organization number of teams.
- if _, err = db.Exec(ctx, "UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
+ // Update organization number of teams.
+ _, err = db.Exec(ctx, "UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID)
return err
- }
- return committer.Commit()
+ })
}
// UpdateTeam updates information of team.
@@ -99,128 +93,117 @@ func UpdateTeam(ctx context.Context, t *organization.Team, authChanged, includeA
t.Description = t.Description[:255]
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- t.LowerName = strings.ToLower(t.Name)
- has, err := db.Exist[organization.Team](ctx, builder.Eq{
- "org_id": t.OrgID,
- "lower_name": t.LowerName,
- }.And(builder.Neq{"id": t.ID}),
- )
- if err != nil {
- return err
- } else if has {
- return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName}
- }
-
- sess := db.GetEngine(ctx)
- if _, err = sess.ID(t.ID).Cols("name", "lower_name", "description",
- "can_create_org_repo", "authorize", "includes_all_repositories").Update(t); err != nil {
- return fmt.Errorf("update: %w", err)
- }
-
- // update units for team
- if len(t.Units) > 0 {
- for _, unit := range t.Units {
- unit.TeamID = t.ID
- }
- // Delete team-unit.
- if _, err := sess.
- Where("team_id=?", t.ID).
- Delete(new(organization.TeamUnit)); err != nil {
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ t.LowerName = strings.ToLower(t.Name)
+ has, err := db.Exist[organization.Team](ctx, builder.Eq{
+ "org_id": t.OrgID,
+ "lower_name": t.LowerName,
+ }.And(builder.Neq{"id": t.ID}),
+ )
+ if err != nil {
return err
+ } else if has {
+ return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName}
}
- if _, err = sess.Cols("org_id", "team_id", "type", "access_mode").Insert(&t.Units); err != nil {
- return err
+
+ sess := db.GetEngine(ctx)
+ if _, err = sess.ID(t.ID).Cols("name", "lower_name", "description",
+ "can_create_org_repo", "authorize", "includes_all_repositories").Update(t); err != nil {
+ return fmt.Errorf("update: %w", err)
}
- }
- // Update access for team members if needed.
- if authChanged {
- repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
- TeamID: t.ID,
- })
- if err != nil {
- return fmt.Errorf("GetTeamRepositories: %w", err)
+ // update units for team
+ if len(t.Units) > 0 {
+ for _, unit := range t.Units {
+ unit.TeamID = t.ID
+ }
+ // Delete team-unit.
+ if _, err := sess.
+ Where("team_id=?", t.ID).
+ Delete(new(organization.TeamUnit)); err != nil {
+ return err
+ }
+ if _, err = sess.Cols("org_id", "team_id", "type", "access_mode").Insert(&t.Units); err != nil {
+ return err
+ }
}
- for _, repo := range repos {
- if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil {
- return fmt.Errorf("recalculateTeamAccesses: %w", err)
+ // Update access for team members if needed.
+ if authChanged {
+ repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
+ TeamID: t.ID,
+ })
+ if err != nil {
+ return fmt.Errorf("GetTeamRepositories: %w", err)
+ }
+
+ for _, repo := range repos {
+ if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil {
+ return fmt.Errorf("recalculateTeamAccesses: %w", err)
+ }
}
}
- }
- // Add all repositories to the team if it has access to all of them.
- if includeAllChanged && t.IncludesAllRepositories {
- err = repo_service.AddAllRepositoriesToTeam(ctx, t)
- if err != nil {
- return fmt.Errorf("addAllRepositories: %w", err)
+ // Add all repositories to the team if it has access to all of them.
+ if includeAllChanged && t.IncludesAllRepositories {
+ err = repo_service.AddAllRepositoriesToTeam(ctx, t)
+ if err != nil {
+ return fmt.Errorf("addAllRepositories: %w", err)
+ }
}
- }
- return committer.Commit()
+ return nil
+ })
}
// DeleteTeam deletes given team.
// It's caller's responsibility to assign organization ID.
func DeleteTeam(ctx context.Context, t *organization.Team) error {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err := t.LoadMembers(ctx); err != nil {
- return err
- }
-
- // update branch protections
- {
- protections := make([]*git_model.ProtectedBranch, 0, 10)
- err := db.GetEngine(ctx).In("repo_id",
- builder.Select("id").From("repository").Where(builder.Eq{"owner_id": t.OrgID})).
- Find(&protections)
- if err != nil {
- return fmt.Errorf("findProtectedBranches: %w", err)
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ if err := t.LoadMembers(ctx); err != nil {
+ return err
}
- for _, p := range protections {
- if err := git_model.RemoveTeamIDFromProtectedBranch(ctx, p, t.ID); err != nil {
- return err
+
+ // update branch protections
+ {
+ protections := make([]*git_model.ProtectedBranch, 0, 10)
+ err := db.GetEngine(ctx).In("repo_id",
+ builder.Select("id").From("repository").Where(builder.Eq{"owner_id": t.OrgID})).
+ Find(&protections)
+ if err != nil {
+ return fmt.Errorf("findProtectedBranches: %w", err)
+ }
+ for _, p := range protections {
+ if err := git_model.RemoveTeamIDFromProtectedBranch(ctx, p, t.ID); err != nil {
+ return err
+ }
}
}
- }
-
- if err := repo_service.RemoveAllRepositoriesFromTeam(ctx, t); err != nil {
- return err
- }
- if err := db.DeleteBeans(ctx,
- &organization.Team{ID: t.ID},
- &organization.TeamUser{OrgID: t.OrgID, TeamID: t.ID},
- &organization.TeamUnit{TeamID: t.ID},
- &organization.TeamInvite{TeamID: t.ID},
- &issues_model.Review{Type: issues_model.ReviewTypeRequest, ReviewerTeamID: t.ID}, // batch delete the binding relationship between team and PR (request review from team)
- ); err != nil {
- return err
- }
+ if err := repo_service.RemoveAllRepositoriesFromTeam(ctx, t); err != nil {
+ return err
+ }
- for _, tm := range t.Members {
- if err := removeInvalidOrgUser(ctx, t.OrgID, tm); err != nil {
+ if err := db.DeleteBeans(ctx,
+ &organization.Team{ID: t.ID},
+ &organization.TeamUser{OrgID: t.OrgID, TeamID: t.ID},
+ &organization.TeamUnit{TeamID: t.ID},
+ &organization.TeamInvite{TeamID: t.ID},
+ &issues_model.Review{Type: issues_model.ReviewTypeRequest, ReviewerTeamID: t.ID}, // batch delete the binding relationship between team and PR (request review from team)
+ ); err != nil {
return err
}
- }
- // Update organization number of teams.
- if _, err := db.Exec(ctx, "UPDATE `user` SET num_teams=num_teams-1 WHERE id=?", t.OrgID); err != nil {
- return err
- }
+ for _, tm := range t.Members {
+ if err := removeInvalidOrgUser(ctx, t.OrgID, tm); err != nil {
+ return err
+ }
+ }
- return committer.Commit()
+ // Update organization number of teams.
+ _, err := db.Exec(ctx, "UPDATE `user` SET num_teams=num_teams-1 WHERE id=?", t.OrgID)
+ return err
+ })
}
// AddTeamMember adds new membership of given team to given organization,
@@ -363,13 +346,7 @@ func removeInvalidOrgUser(ctx context.Context, orgID int64, user *user_model.Use
// RemoveTeamMember removes member from given team of given organization.
func RemoveTeamMember(ctx context.Context, team *organization.Team, user *user_model.User) error {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
- if err := removeTeamMember(ctx, team, user); err != nil {
- return err
- }
- return committer.Commit()
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ return removeTeamMember(ctx, team, user)
+ })
}
diff --git a/services/packages/cleanup/cleanup.go b/services/packages/cleanup/cleanup.go
index 959babe7cd..ec860db1bb 100644
--- a/services/packages/cleanup/cleanup.go
+++ b/services/packages/cleanup/cleanup.go
@@ -164,42 +164,38 @@ func ExecuteCleanupRules(ctx context.Context) error {
})
}
-func CleanupExpiredData(outerCtx context.Context, olderThan time.Duration) error {
- ctx, committer, err := db.TxContext(outerCtx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err := container_service.Cleanup(ctx, olderThan); err != nil {
- return err
- }
-
- ps, err := packages_model.FindUnreferencedPackages(ctx)
- if err != nil {
- return err
- }
- for _, p := range ps {
- if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypePackage, p.ID); err != nil {
+func CleanupExpiredData(ctx context.Context, olderThan time.Duration) error {
+ pbs := make([]*packages_model.PackageBlob, 0, 100)
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ if err := container_service.Cleanup(ctx, olderThan); err != nil {
return err
}
- if err := packages_model.DeletePackageByID(ctx, p.ID); err != nil {
+
+ ps, err := packages_model.FindUnreferencedPackages(ctx)
+ if err != nil {
return err
}
- }
-
- pbs, err := packages_model.FindExpiredUnreferencedBlobs(ctx, olderThan)
- if err != nil {
- return err
- }
+ for _, p := range ps {
+ if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypePackage, p.ID); err != nil {
+ return err
+ }
+ if err := packages_model.DeletePackageByID(ctx, p.ID); err != nil {
+ return err
+ }
+ }
- for _, pb := range pbs {
- if err := packages_model.DeleteBlobByID(ctx, pb.ID); err != nil {
+ pbs, err = packages_model.FindExpiredUnreferencedBlobs(ctx, olderThan)
+ if err != nil {
return err
}
- }
- if err := committer.Commit(); err != nil {
+ for _, pb := range pbs {
+ if err := packages_model.DeleteBlobByID(ctx, pb.ID); err != nil {
+ return err
+ }
+ }
+ return nil
+ }); err != nil {
return err
}
diff --git a/services/packages/packages.go b/services/packages/packages.go
index 4b16ee7285..22b26b6563 100644
--- a/services/packages/packages.go
+++ b/services/packages/packages.go
@@ -469,24 +469,15 @@ func RemovePackageVersionByNameAndVersion(ctx context.Context, doer *user_model.
// RemovePackageVersion deletes the package version and all associated files
func RemovePackageVersion(ctx context.Context, doer *user_model.User, pv *packages_model.PackageVersion) error {
- dbCtx, committer, err := db.TxContext(ctx)
+ pd, err := packages_model.GetPackageDescriptor(ctx, pv)
if err != nil {
return err
}
- defer committer.Close()
-
- pd, err := packages_model.GetPackageDescriptor(dbCtx, pv)
- if err != nil {
- return err
- }
-
- log.Trace("Deleting package: %v", pv.ID)
- if err := DeletePackageVersionAndReferences(dbCtx, pv); err != nil {
- return err
- }
-
- if err := committer.Commit(); err != nil {
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ log.Trace("Deleting package: %v", pv.ID)
+ return DeletePackageVersionAndReferences(ctx, pv)
+ }); err != nil {
return err
}
diff --git a/services/pull/merge.go b/services/pull/merge.go
index cd9aeb2ad1..a941c20435 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -687,48 +687,40 @@ func SetMerged(ctx context.Context, pr *issues_model.PullRequest, mergedCommitID
return false, fmt.Errorf("unable to merge PullRequest[%d], some required fields are empty", pr.Index)
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return false, err
- }
- defer committer.Close()
-
- pr.Issue = nil
- if err := pr.LoadIssue(ctx); err != nil {
- return false, err
- }
-
- if err := pr.Issue.LoadRepo(ctx); err != nil {
- return false, err
- }
+ return db.WithTx2(ctx, func(ctx context.Context) (bool, error) {
+ pr.Issue = nil
+ if err := pr.LoadIssue(ctx); err != nil {
+ return false, err
+ }
- if err := pr.Issue.Repo.LoadOwner(ctx); err != nil {
- return false, err
- }
+ if err := pr.Issue.LoadRepo(ctx); err != nil {
+ return false, err
+ }
- // Removing an auto merge pull and ignore if not exist
- if err := pull_model.DeleteScheduledAutoMerge(ctx, pr.ID); err != nil && !db.IsErrNotExist(err) {
- return false, fmt.Errorf("DeleteScheduledAutoMerge[%d]: %v", pr.ID, err)
- }
+ if err := pr.Issue.Repo.LoadOwner(ctx); err != nil {
+ return false, err
+ }
- // Set issue as closed
- if _, err := issues_model.SetIssueAsClosed(ctx, pr.Issue, pr.Merger, true); err != nil {
- return false, fmt.Errorf("ChangeIssueStatus: %w", err)
- }
+ // Removing an auto merge pull and ignore if not exist
+ if err := pull_model.DeleteScheduledAutoMerge(ctx, pr.ID); err != nil && !db.IsErrNotExist(err) {
+ return false, fmt.Errorf("DeleteScheduledAutoMerge[%d]: %v", pr.ID, err)
+ }
- // We need to save all of the data used to compute this merge as it may have already been changed by testPullRequestBranchMergeable. FIXME: need to set some state to prevent testPullRequestBranchMergeable from running whilst we are merging.
- if cnt, err := db.GetEngine(ctx).Where("id = ?", pr.ID).
- And("has_merged = ?", false).
- Cols("has_merged, status, merge_base, merged_commit_id, merger_id, merged_unix, conflicted_files").
- Update(pr); err != nil {
- return false, fmt.Errorf("failed to update pr[%d]: %w", pr.ID, err)
- } else if cnt != 1 {
- return false, issues_model.ErrIssueAlreadyChanged
- }
+ // Set issue as closed
+ if _, err := issues_model.SetIssueAsClosed(ctx, pr.Issue, pr.Merger, true); err != nil {
+ return false, fmt.Errorf("ChangeIssueStatus: %w", err)
+ }
- if err := committer.Commit(); err != nil {
- return false, err
- }
+ // We need to save all of the data used to compute this merge as it may have already been changed by testPullRequestBranchMergeable. FIXME: need to set some state to prevent testPullRequestBranchMergeable from running whilst we are merging.
+ if cnt, err := db.GetEngine(ctx).Where("id = ?", pr.ID).
+ And("has_merged = ?", false).
+ Cols("has_merged, status, merge_base, merged_commit_id, merger_id, merged_unix, conflicted_files").
+ Update(pr); err != nil {
+ return false, fmt.Errorf("failed to update pr[%d]: %w", pr.ID, err)
+ } else if cnt != 1 {
+ return false, issues_model.ErrIssueAlreadyChanged
+ }
- return true, nil
+ return true, nil
+ })
}
diff --git a/services/repository/avatar.go b/services/repository/avatar.go
index 26bf6da465..998ac42230 100644
--- a/services/repository/avatar.go
+++ b/services/repository/avatar.go
@@ -29,35 +29,30 @@ func UploadAvatar(ctx context.Context, repo *repo_model.Repository, data []byte)
return nil
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- oldAvatarPath := repo.CustomAvatarRelativePath()
-
- // Users can upload the same image to other repo - prefix it with ID
- // Then repo will be removed - only it avatar file will be removed
- repo.Avatar = newAvatar
- if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "avatar"); err != nil {
- return fmt.Errorf("UploadAvatar: Update repository avatar: %w", err)
- }
-
- if err := storage.SaveFrom(storage.RepoAvatars, repo.CustomAvatarRelativePath(), func(w io.Writer) error {
- _, err := w.Write(avatarData)
- return err
- }); err != nil {
- return fmt.Errorf("UploadAvatar %s failed: Failed to remove old repo avatar %s: %w", repo.RepoPath(), newAvatar, err)
- }
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ oldAvatarPath := repo.CustomAvatarRelativePath()
+
+ // Users can upload the same image to other repo - prefix it with ID
+ // Then repo will be removed - only it avatar file will be removed
+ repo.Avatar = newAvatar
+ if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "avatar"); err != nil {
+ return fmt.Errorf("UploadAvatar: Update repository avatar: %w", err)
+ }
- if len(oldAvatarPath) > 0 {
- if err := storage.RepoAvatars.Delete(oldAvatarPath); err != nil {
- return fmt.Errorf("UploadAvatar: Failed to remove old repo avatar %s: %w", oldAvatarPath, err)
+ if err := storage.SaveFrom(storage.RepoAvatars, repo.CustomAvatarRelativePath(), func(w io.Writer) error {
+ _, err := w.Write(avatarData)
+ return err
+ }); err != nil {
+ return fmt.Errorf("UploadAvatar %s failed: Failed to remove old repo avatar %s: %w", repo.RepoPath(), newAvatar, err)
}
- }
- return committer.Commit()
+ if len(oldAvatarPath) > 0 {
+ if err := storage.RepoAvatars.Delete(oldAvatarPath); err != nil {
+ return fmt.Errorf("UploadAvatar: Failed to remove old repo avatar %s: %w", oldAvatarPath, err)
+ }
+ }
+ return nil
+ })
}
// DeleteAvatar deletes the repos's custom avatar.
@@ -70,22 +65,17 @@ func DeleteAvatar(ctx context.Context, repo *repo_model.Repository) error {
avatarPath := repo.CustomAvatarRelativePath()
log.Trace("DeleteAvatar[%d]: %s", repo.ID, avatarPath)
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- repo.Avatar = ""
- if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "avatar"); err != nil {
- return fmt.Errorf("DeleteAvatar: Update repository avatar: %w", err)
- }
-
- if err := storage.RepoAvatars.Delete(avatarPath); err != nil {
- return fmt.Errorf("DeleteAvatar: Failed to remove %s: %w", avatarPath, err)
- }
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ repo.Avatar = ""
+ if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "avatar"); err != nil {
+ return fmt.Errorf("DeleteAvatar: Update repository avatar: %w", err)
+ }
- return committer.Commit()
+ if err := storage.RepoAvatars.Delete(avatarPath); err != nil {
+ return fmt.Errorf("DeleteAvatar: Failed to remove %s: %w", avatarPath, err)
+ }
+ return nil
+ })
}
// RemoveRandomAvatars removes the randomly generated avatars that were created for repositories
diff --git a/services/repository/collaboration.go b/services/repository/collaboration.go
index b5fc523623..53b3c2e203 100644
--- a/services/repository/collaboration.go
+++ b/services/repository/collaboration.go
@@ -71,40 +71,32 @@ func DeleteCollaboration(ctx context.Context, repo *repo_model.Repository, colla
UserID: collaborator.ID,
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if has, err := db.GetEngine(ctx).Delete(collaboration); err != nil {
- return err
- } else if has == 0 {
- return committer.Commit()
- }
-
- if err := repo.LoadOwner(ctx); err != nil {
- return err
- }
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ if has, err := db.GetEngine(ctx).Delete(collaboration); err != nil {
+ return err
+ } else if has == 0 {
+ return nil
+ }
- if err = access_model.RecalculateAccesses(ctx, repo); err != nil {
- return err
- }
+ if err := repo.LoadOwner(ctx); err != nil {
+ return err
+ }
- if err = repo_model.WatchRepo(ctx, collaborator, repo, false); err != nil {
- return err
- }
+ if err = access_model.RecalculateAccesses(ctx, repo); err != nil {
+ return err
+ }
- if err = ReconsiderWatches(ctx, repo, collaborator); err != nil {
- return err
- }
+ if err = repo_model.WatchRepo(ctx, collaborator, repo, false); err != nil {
+ return err
+ }
- // Unassign a user from any issue (s)he has been assigned to in the repository
- if err := ReconsiderRepoIssuesAssignee(ctx, repo, collaborator); err != nil {
- return err
- }
+ if err = ReconsiderWatches(ctx, repo, collaborator); err != nil {
+ return err
+ }
- return committer.Commit()
+ // Unassign a user from any issue (s)he has been assigned to in the repository
+ return ReconsiderRepoIssuesAssignee(ctx, repo, collaborator)
+ })
}
func ReconsiderRepoIssuesAssignee(ctx context.Context, repo *repo_model.Repository, user *user_model.User) error {
diff --git a/services/repository/repo_team.go b/services/repository/repo_team.go
index 672ee49fea..8ea186f8cc 100644
--- a/services/repository/repo_team.go
+++ b/services/repository/repo_team.go
@@ -86,17 +86,9 @@ func RemoveAllRepositoriesFromTeam(ctx context.Context, t *organization.Team) (e
return nil
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err = removeAllRepositoriesFromTeam(ctx, t); err != nil {
- return err
- }
-
- return committer.Commit()
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ return removeAllRepositoriesFromTeam(ctx, t)
+ })
}
// removeAllRepositoriesFromTeam removes all repositories from team and recalculates access
@@ -167,17 +159,9 @@ func RemoveRepositoryFromTeam(ctx context.Context, t *organization.Team, repoID
return err
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err = removeRepositoryFromTeam(ctx, t, repo, true); err != nil {
- return err
- }
-
- return committer.Commit()
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ return removeRepositoryFromTeam(ctx, t, repo, true)
+ })
}
// removeRepositoryFromTeam removes a repository from a team and recalculates access
diff --git a/services/repository/setting.go b/services/repository/setting.go
index e0c787dd2d..b6873691eb 100644
--- a/services/repository/setting.go
+++ b/services/repository/setting.go
@@ -16,41 +16,37 @@ import (
// UpdateRepositoryUnits updates a repository's units
func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, units []repo_model.RepoUnit, deleteUnitTypes []unit.Type) (err error) {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- // Delete existing settings of units before adding again
- for _, u := range units {
- deleteUnitTypes = append(deleteUnitTypes, u.Type)
- }
-
- if slices.Contains(deleteUnitTypes, unit.TypeActions) {
- if err := actions_service.CleanRepoScheduleTasks(ctx, repo); err != nil {
- log.Error("CleanRepoScheduleTasks: %v", err)
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ // Delete existing settings of units before adding again
+ for _, u := range units {
+ deleteUnitTypes = append(deleteUnitTypes, u.Type)
}
- }
- for _, u := range units {
- if u.Type == unit.TypeActions {
- if err := actions_service.DetectAndHandleSchedules(ctx, repo); err != nil {
- log.Error("DetectAndHandleSchedules: %v", err)
+ if slices.Contains(deleteUnitTypes, unit.TypeActions) {
+ if err := actions_service.CleanRepoScheduleTasks(ctx, repo); err != nil {
+ log.Error("CleanRepoScheduleTasks: %v", err)
}
- break
}
- }
- if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(repo_model.RepoUnit)); err != nil {
- return err
- }
+ for _, u := range units {
+ if u.Type == unit.TypeActions {
+ if err := actions_service.DetectAndHandleSchedules(ctx, repo); err != nil {
+ log.Error("DetectAndHandleSchedules: %v", err)
+ }
+ break
+ }
+ }
- if len(units) > 0 {
- if err = db.Insert(ctx, units); err != nil {
+ if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(repo_model.RepoUnit)); err != nil {
return err
}
- }
- return committer.Commit()
+ if len(units) > 0 {
+ if err = db.Insert(ctx, units); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ })
}
diff --git a/services/user/avatar.go b/services/user/avatar.go
index 3f87466eaa..df188e5adc 100644
--- a/services/user/avatar.go
+++ b/services/user/avatar.go
@@ -24,26 +24,22 @@ func UploadAvatar(ctx context.Context, u *user_model.User, data []byte) error {
return err
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- u.UseCustomAvatar = true
- u.Avatar = avatar.HashAvatar(u.ID, data)
- if err = user_model.UpdateUserCols(ctx, u, "use_custom_avatar", "avatar"); err != nil {
- return fmt.Errorf("updateUser: %w", err)
- }
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ u.UseCustomAvatar = true
+ u.Avatar = avatar.HashAvatar(u.ID, data)
+ if err = user_model.UpdateUserCols(ctx, u, "use_custom_avatar", "avatar"); err != nil {
+ return fmt.Errorf("updateUser: %w", err)
+ }
- if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error {
- _, err := w.Write(avatarData)
- return err
- }); err != nil {
- return fmt.Errorf("Failed to create dir %s: %w", u.CustomAvatarRelativePath(), err)
- }
+ if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error {
+ _, err := w.Write(avatarData)
+ return err
+ }); err != nil {
+ return fmt.Errorf("Failed to create dir %s: %w", u.CustomAvatarRelativePath(), err)
+ }
- return committer.Commit()
+ return nil
+ })
}
// DeleteAvatar deletes the user's custom avatar.