Skip to content

Commit

Permalink
refactor: delete iterations and their sub items together
Browse files Browse the repository at this point in the history
feat: initialize issueService

feat: add option to delete only iterations or all

feat: add BatchUpdateIssueIterationID

feat: batch deletion of functions and addition of transactions

feat: add BatchDeleteIssueByIterationID function

feat: expose interfaces

refactor: Transaction validation and change the parameter transfer method
  • Loading branch information
jing-zhi committed Feb 22, 2024
1 parent 1951d11 commit db408cd
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (
"context"

"github.com/erda-project/erda-infra/providers/component-protocol/cptype"
"github.com/erda-project/erda-proto-go/dop/issue/core/pb"
"github.com/erda-project/erda/bundle"
"github.com/erda-project/erda/internal/apps/dop/providers/issue/core"
)

type BatchOperationTipModal struct {
Expand All @@ -30,7 +30,7 @@ type BatchOperationTipModal struct {
SDK *cptype.SDK
CtxBdl *bundle.Bundle
ctx context.Context
issueSvc pb.IssueCoreServiceServer
issueSvc core.IssueService
}

type Props struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/erda-project/erda-infra/providers/component-protocol/utils/cputil"
"github.com/erda-project/erda-proto-go/dop/issue/core/pb"
"github.com/erda-project/erda/internal/apps/dop/component-protocol/types"
"github.com/erda-project/erda/internal/apps/dop/providers/issue/core"
)

func init() {
Expand Down Expand Up @@ -90,7 +91,7 @@ func (bot *BatchOperationTipModal) Render(ctx context.Context, c *cptype.Compone
bot.ctx = ctx
cputil.MustObjJSONTransfer(&c.State, &bot.State)
bot.State.Visible = false
issueSvc := ctx.Value(types.IssueService).(pb.IssueCoreServiceServer)
issueSvc := ctx.Value(types.IssueService).(core.IssueService)
bot.issueSvc = issueSvc
_, err = bot.DeleteItems(bot.State.SelectedRowKeys, projectid)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions internal/apps/dop/endpoints/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/erda-project/erda/bundle"
"github.com/erda-project/erda/internal/apps/dop/dao"
"github.com/erda-project/erda/internal/apps/dop/event"
"github.com/erda-project/erda/internal/apps/dop/providers/issue/core"
issuequery "github.com/erda-project/erda/internal/apps/dop/providers/issue/core/query"
issuedao "github.com/erda-project/erda/internal/apps/dop/providers/issue/dao"
"github.com/erda-project/erda/internal/apps/dop/providers/projectpipeline"
Expand Down Expand Up @@ -630,6 +631,7 @@ type Endpoints struct {
namespace *namespace.Namespace
envConfig *environment.EnvConfig
issue *issue.Issue
issueService core.IssueService
issueState *issuestate.IssueState
workBench *workbench.Workbench
iteration *iteration.Iteration
Expand Down Expand Up @@ -895,6 +897,13 @@ func WithIssue(issue *issue.Issue) Option {
}
}

// WithIssueService Configure issueService
func WithIssueService(issueService *core.IssueService) Option {
return func(e *Endpoints) {
e.issueService = *issueService
}
}

func WithIssueState(state *issuestate.IssueState) Option {
return func(e *Endpoints) {
e.issueState = state
Expand Down
23 changes: 23 additions & 0 deletions internal/apps/dop/endpoints/iteration.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/erda-project/erda/internal/apps/dop/dao"
"github.com/erda-project/erda/internal/apps/dop/services/apierrors"
"github.com/erda-project/erda/internal/pkg/user"
"github.com/erda-project/erda/pkg/common/apis"
"github.com/erda-project/erda/pkg/http/httpserver"
"github.com/erda-project/erda/pkg/http/httpserver/errorresp"
"github.com/erda-project/erda/pkg/strutil"
Expand Down Expand Up @@ -205,6 +206,7 @@ func (e *Endpoints) DeleteIteration(ctx context.Context, r *http.Request, vars m
}

iterationID, err := strconv.ParseUint(vars["id"], 10, 64)
onlyIteration := r.URL.Query().Get("onlyIteration")
if err != nil {
return apierrors.ErrDeleteIteration.InvalidParameter("id").ToResp(), nil
}
Expand Down Expand Up @@ -235,6 +237,27 @@ func (e *Endpoints) DeleteIteration(ctx context.Context, r *http.Request, vars m
return errorresp.ErrResp(err)
}

itemIDs, err := e.issueService.DBClient().GetIssuesIDByIterationID(iterationID)
if err != nil {
return apierrors.ErrDeleteIteration.InternalError(err).ToResp(), nil
}

if len(itemIDs) > 0 {
ctx = apis.WithUserIDContext(ctx, identityInfo.UserID)
if onlyIteration == "true" {
err = e.issueService.BatchUpdateIssueIterationIDByIterationID(ctx, iterationID, -1)
if err != nil {
return apierrors.ErrDeleteIteration.InternalError(err).ToResp(), nil
}
goto come
} else if onlyIteration == "false" {
err = e.issueService.BatchDeleteIssueByIterationID(ctx, iterationID)
if err != nil {
return apierrors.ErrDeleteIteration.InternalError(err).ToResp(), nil
}
}
}
come:
// delete relation labels
if err = e.db.DeleteLabelRelations(apistructs.LabelTypeIteration, strconv.FormatUint(iterationID, 10), nil); err != nil {
return apierrors.ErrDeleteIteration.InternalError(err).ToResp(), nil
Expand Down
1 change: 1 addition & 0 deletions internal/apps/dop/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ func (p *provider) initEndpoints(db *dao.DBClient) (*endpoints.Endpoints, error)
endpoints.WithNamespace(ns),
endpoints.WithEnvConfig(env),
endpoints.WithIssue(issue),
endpoints.WithIssueService(p.IssueCoreSvc),
endpoints.WithIssueState(issueState),
endpoints.WithIteration(itr),
endpoints.WithPublisher(pub),
Expand Down
66 changes: 50 additions & 16 deletions internal/apps/dop/providers/issue/core/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
"github.com/erda-project/erda/internal/apps/dop/services/testcase"
mttestplan "github.com/erda-project/erda/internal/apps/dop/services/testplan"
"github.com/erda-project/erda/pkg/common/apis"
"github.com/erda-project/erda/pkg/database/dbengine"
"github.com/erda-project/erda/pkg/strutil"
)

Expand Down Expand Up @@ -554,16 +555,10 @@ func (i *IssueService) DeleteIssue(ctx context.Context, req *pb.DeleteIssueReque
// BatchDeleteIssues 批量删除
func (i *IssueService) BatchDeleteIssues(ctx context.Context, req *pb.BatchDeleteIssueRequest) (*pb.BatchDeleteIssueResponse, error) {
numSlice := make([]uint64, len(req.Ids))
for i, str := range req.Ids {
num, err := strconv.ParseUint(str, 10, 64)
if err != nil {
return nil, apierrors.ErrBatchDeleteIssue.InvalidParameter(err)
}
numSlice[i] = num
}
ids := make([]int64, len(req.Ids))
for k, v := range numSlice {
ids[k] = int64(v)
for i, str := range req.Ids {
numSlice[i], _ = strconv.ParseUint(str, 10, 64)
ids[i] = int64(numSlice[i])
}

identityInfo := apis.GetIdentityInfo(ctx)
Expand All @@ -572,11 +567,15 @@ func (i *IssueService) BatchDeleteIssues(ctx context.Context, req *pb.BatchDelet
}

issues, _, err := i.query.Paging(pb.PagingIssueRequest{IDs: ids, ProjectID: req.ProjectID})

if err != nil {
return nil, err
}

tx := i.db.Begin()
client := &dao.DBClient{
DBEngine: &dbengine.DBEngine{DB: tx},
}

for k, issue := range issues {
rels, err := i.GetTestPlanCaseRels(uint64(issue.Id))
if err != nil {
Expand Down Expand Up @@ -615,26 +614,31 @@ func (i *IssueService) BatchDeleteIssues(ctx context.Context, req *pb.BatchDelet

// 删除测试计划用例关联
if issue.Type == pb.IssueTypeEnum_BUG {
if err := i.db.DeleteIssueTestCaseRelationsByIssueIDs([]uint64{numSlice[k]}); err != nil {
if err := client.DeleteIssueTestCaseRelationsByIssueIDs([]uint64{numSlice[k]}); err != nil {
tx.Rollback()
return nil, apierrors.ErrBatchDeleteIssue.InternalError(err)
}
}
}

if err := i.db.BatchCleanIssueRelation(numSlice); err != nil {
if err := client.BatchCleanIssueRelation(numSlice); err != nil {
tx.Rollback()
return nil, apierrors.ErrBatchDeleteIssue.InternalError(err)
}

if err := i.db.BatchDeletePropertyRelationByIssueID(ids); err != nil {
if err := client.BatchDeletePropertyRelationByIssueID(ids); err != nil {
tx.Rollback()
return nil, apierrors.ErrBatchDeleteIssue.InternalError(err)
}

// delete issue state transition
if err = i.db.BatchDeleteIssuesStateTransition(numSlice); err != nil {
if err = client.BatchDeleteIssuesStateTransition(numSlice); err != nil {
tx.Rollback()
return nil, apierrors.ErrBatchDeleteIssue.InternalError(err)
}

if err = i.db.BatchDeleteIssues(numSlice); err != nil {
if err = client.BatchDeleteIssues(numSlice); err != nil {
tx.Rollback()
return nil, err
}

Expand All @@ -646,10 +650,40 @@ func (i *IssueService) BatchDeleteIssues(ctx context.Context, req *pb.BatchDelet
logrus.Errorf("update project active time err: %v", err)
}
}

tx.Commit()
return &pb.BatchDeleteIssueResponse{Data: issues}, nil
}

// BatchDeleteIssueByIterationID 根据迭代 id 批量删除 issue
func (i *IssueService) BatchDeleteIssueByIterationID(ctx context.Context, iterationID uint64) (err error) {
identityInfo := apis.GetIdentityInfo(ctx)
if identityInfo == nil {
return apierrors.ErrUpdateIssue.NotLogin()
}
tx := i.db.Begin()
if err = i.db.BatchDeleteIssueByIterationID(iterationID, tx); err != nil {
tx.Rollback()
return
}
tx.Commit()
return
}

// BatchUpdateIssueIterationIDByIterationID 根据迭代 id 批量更新 issue 的 iteration_id
func (i *IssueService) BatchUpdateIssueIterationIDByIterationID(ctx context.Context, iterationID uint64, ID int64) (err error) {
identityInfo := apis.GetIdentityInfo(ctx)
if identityInfo == nil {
return apierrors.ErrUpdateIssue.NotLogin()
}
tx := i.db.Begin()
if err = i.db.BatchUpdateIssueIterationIDByIterationID(iterationID, ID, tx); err != nil {
tx.Rollback()
return
}
tx.Commit()
return
}

func (i *IssueService) GetTestPlanCaseRels(issueID uint64) ([]*pb.TestPlanCaseRel, error) {
// 查询关联的测试计划用例
testPlanCaseRels := make([]*pb.TestPlanCaseRel, 0)
Expand Down
26 changes: 26 additions & 0 deletions internal/apps/dop/providers/issue/dao/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ func (client *DBClient) UpdateIssues(requirementID uint64, fields map[string]int
Updates(fields).Error
}

func (client *DBClient) BatchUpdateIssueIterationIDByIterationID(iterationID uint64, ID int64, tx *gorm.DB) error {
return tx.Model(Issue{}).Where("deleted = 0").Where("iteration_id = ?", iterationID).Updates(map[string]interface{}{"iteration_id": ID}).Error
}

// UpdateIssueType 转换issueType
func (client *DBClient) UpdateIssueType(issue *Issue) error {
return client.Model(Issue{}).Save(issue).Error
Expand Down Expand Up @@ -226,6 +230,19 @@ func (client *DBClient) BatchDeleteIssues(ids []uint64) error {
return client.Model(Issue{}).Where("id IN (?)", ids).Update("deleted", 1).Error
}

func (client *DBClient) BatchDeleteIssueByIterationID(iterationID uint64, tx *gorm.DB) error {
sql := fmt.Sprintf(`
UPDATE dice_issues AS dis
LEFT JOIN dice_issue_testcase_relations AS ditr ON ditr.issue_id = dis.id
LEFT JOIN dice_issue_relation AS dir ON dir.issue_id = dis.id
LEFT JOIN dice_issue_property_relation AS dipr ON dipr.issue_id = dis.id
LEFT JOIN erda_issue_state_transition AS eist ON eist.issue_id = dis.id
SET dis.deleted = 1
WHERE dis.iteration_id = ?;
`)
return tx.Exec(sql, iterationID).Error
}

// DeleteIssuesByRequirement .
func (client *DBClient) DeleteIssuesByRequirement(requirementID uint64) error {
return client.Model(Issue{}).Where("requirement_id = ?", requirementID).Update("deleted", 1).Error
Expand Down Expand Up @@ -405,6 +422,15 @@ func (client *DBClient) GetIssueWithOutDelete(id int64) (Issue, error) {
return issue, err
}

func (client *DBClient) GetIssuesIDByIterationID(iterationID uint64) (ids []uint64, err error) {
var issues []Issue
err = client.Model(Issue{}).Where("deleted = 0").Where("iteration_id = ?", iterationID).Select("id").Find(&issues).Error
for _, v := range issues {
ids = append(ids, v.ID)
}
return ids, err
}

func (client *DBClient) ListIssueByIDs(issueIDs []int64) ([]Issue, error) {
var issues []Issue
if err := client.Where("`id` IN (?)", issueIDs).Find(&issues).Error; err != nil {
Expand Down
22 changes: 0 additions & 22 deletions internal/apps/dop/services/iteration/iteration.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package iteration
import (
"github.com/jinzhu/gorm"

"github.com/erda-project/erda-proto-go/dop/issue/core/pb"
"github.com/erda-project/erda/apistructs"
"github.com/erda-project/erda/internal/apps/dop/dao"
"github.com/erda-project/erda/internal/apps/dop/providers/issue/core/query"
Expand Down Expand Up @@ -159,27 +158,6 @@ func (itr *Iteration) GetByTitle(projectID uint64, title string) (*dao.Iteration

// Delete 删除 iteration
func (itr *Iteration) Delete(id uint64) error {
iteration, err := itr.db.GetIteration(id)
if err != nil {
return err
}

// 检查 iteration 下是否有需求/任务/bug; 若有,不可删除
issueReq := pb.PagingIssueRequest{
ProjectID: iteration.ProjectID,
IterationID: int64(id),
External: true,
PageNo: 1,
PageSize: 1,
}
issues, _, err := itr.issue.Paging(issueReq)
if err != nil {
return err
}
if len(issues) > 0 {
return apierrors.ErrDeleteIteration.InvalidParameter("该迭代下存在事件,请先删除事件后再删除迭代")
}

if err := itr.db.DeleteIteration(id); err != nil {
return apierrors.ErrDeleteIteration.InternalError(err)
}
Expand Down

0 comments on commit db408cd

Please sign in to comment.