mirror of
https://github.com/go-gitea/gitea
synced 2025-08-05 09:08:22 +00:00
Use db.WithTx/WithTx2 instead of TxContext when possible (#35130)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -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 {
|
||||
if _, err = db.DeleteByID[asymkey_model.PublicKey](ctx, id); 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 {
|
||||
return err
|
||||
}
|
||||
committer.Close()
|
||||
|
||||
if key.Type == asymkey_model.KeyTypePrincipal {
|
||||
return RewriteAllPrincipalKeys(ctx)
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -15,31 +15,25 @@ 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
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := committer.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
committer.Close()
|
||||
|
||||
notify_service.IssueChangeStatus(ctx, doer, commitID, issue, comment, true)
|
||||
|
||||
return nil
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update organization number of teams.
|
||||
if _, err = db.Exec(ctx, "UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
|
||||
// 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.
|
||||
_, 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 err
|
||||
}
|
||||
if _, err = sess.Cols("org_id", "team_id", "type", "access_mode").Insert(&t.Units); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Update access for team members if needed.
|
||||
if authChanged {
|
||||
repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{
|
||||
TeamID: t.ID,
|
||||
})
|
||||
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 fmt.Errorf("GetTeamRepositories: %w", err)
|
||||
return err
|
||||
} else if has {
|
||||
return organization.ErrTeamAlreadyExist{OrgID: t.OrgID, Name: t.LowerName}
|
||||
}
|
||||
|
||||
for _, repo := range repos {
|
||||
if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil {
|
||||
return fmt.Errorf("recalculateTeamAccesses: %w", 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 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
// 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 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 {
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
for _, tm := range t.Members {
|
||||
if err := removeInvalidOrgUser(ctx, t.OrgID, tm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := repo_service.RemoveAllRepositoriesFromTeam(ctx, t); 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
for _, tm := range t.Members {
|
||||
if err := removeInvalidOrgUser(ctx, t.OrgID, tm); 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
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
})
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
pbs, err := packages_model.FindExpiredUnreferencedBlobs(ctx, olderThan)
|
||||
if 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
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
pd, err := packages_model.GetPackageDescriptor(dbCtx, pv)
|
||||
pd, err := packages_model.GetPackageDescriptor(ctx, 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
|
||||
}
|
||||
|
||||
|
@@ -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()
|
||||
return db.WithTx2(ctx, func(ctx context.Context) (bool, error) {
|
||||
pr.Issue = nil
|
||||
if err := pr.LoadIssue(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
pr.Issue = nil
|
||||
if err := pr.LoadIssue(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := pr.Issue.LoadRepo(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if err := pr.Issue.LoadRepo(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := pr.Issue.Repo.LoadOwner(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if err := pr.Issue.Repo.LoadOwner(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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
// Set issue as closed
|
||||
if _, err := issues_model.SetIssueAsClosed(ctx, pr.Issue, pr.Merger, true); err != nil {
|
||||
return false, fmt.Errorf("ChangeIssueStatus: %w", 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)
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
if err := committer.Commit(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return true, nil
|
||||
})
|
||||
}
|
||||
|
@@ -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()
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
oldAvatarPath := repo.CustomAvatarRelativePath()
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
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)
|
||||
}
|
||||
|
||||
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()
|
||||
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)
|
||||
}
|
||||
|
||||
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 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
|
||||
|
@@ -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()
|
||||
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 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
|
||||
}
|
||||
|
||||
if err := repo.LoadOwner(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = access_model.RecalculateAccesses(ctx, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = access_model.RecalculateAccesses(ctx, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = repo_model.WatchRepo(ctx, collaborator, repo, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = repo_model.WatchRepo(ctx, collaborator, repo, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ReconsiderWatches(ctx, repo, collaborator); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = ReconsiderWatches(ctx, repo, collaborator); 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
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
})
|
||||
}
|
||||
|
@@ -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()
|
||||
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)
|
||||
}
|
||||
|
||||
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.
|
||||
|
Reference in New Issue
Block a user