diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/asymkey/deploy_key.go | 31 | ||||
-rw-r--r-- | services/asymkey/ssh_key.go | 13 | ||||
-rw-r--r-- | services/asymkey/ssh_key_principals.go | 42 | ||||
-rw-r--r-- | services/auth/source/oauth2/store.go | 15 | ||||
-rw-r--r-- | services/contexttest/context_tests.go | 2 | ||||
-rw-r--r-- | services/issue/label.go | 38 | ||||
-rw-r--r-- | services/issue/milestone.go | 15 | ||||
-rw-r--r-- | services/issue/status.go | 30 | ||||
-rw-r--r-- | services/org/team.go | 243 | ||||
-rw-r--r-- | services/packages/cleanup/cleanup.go | 52 | ||||
-rw-r--r-- | services/packages/packages.go | 19 | ||||
-rw-r--r-- | services/pull/merge.go | 68 | ||||
-rw-r--r-- | services/repository/avatar.go | 72 | ||||
-rw-r--r-- | services/repository/collaboration.go | 50 | ||||
-rw-r--r-- | services/repository/repo_team.go | 28 | ||||
-rw-r--r-- | services/repository/setting.go | 52 | ||||
-rw-r--r-- | services/user/avatar.go | 32 |
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. |