This is an automated email from the ASF dual-hosted git repository. warren pushed a commit to branch feat-plugin-zentao in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
commit 9919d22f29f03cbd6dbc4420039eb07899e73335 Author: Yingchu Chen <[email protected]> AuthorDate: Mon Sep 19 11:05:59 2022 +0800 feat(zentao): fix execution time --- plugins/helper/iso8601time.go | 31 ++++++++++ plugins/zentao/impl/impl.go | 1 + plugins/zentao/models/archived/execution.go | 78 ++++++++++++------------- plugins/zentao/models/archived/project.go | 4 +- plugins/zentao/models/execution.go | 78 ++++++++++++------------- plugins/zentao/models/project.go | 4 +- plugins/zentao/tasks/execution_convertor.go | 91 +++++++++++++++++++++++++++++ 7 files changed, 205 insertions(+), 82 deletions(-) diff --git a/plugins/helper/iso8601time.go b/plugins/helper/iso8601time.go index 8d409262..3029adb1 100644 --- a/plugins/helper/iso8601time.go +++ b/plugins/helper/iso8601time.go @@ -18,6 +18,7 @@ limitations under the License. package helper import ( + "database/sql/driver" "fmt" "regexp" "strings" @@ -63,6 +64,10 @@ func init() { Matcher: regexp.MustCompile(`[+-][\d]{2}:[\d]{2}$`), Format: "2006-01-02T15:04:05-07:00", }, + { + Matcher: regexp.MustCompile(`[+-][\d]{2}-[\d]{2}$`), + Format: "2006-01-02", + }, } } @@ -131,3 +136,29 @@ func Iso8601TimeToTime(iso8601Time *Iso8601Time) *time.Time { t := iso8601Time.ToTime() return &t } + +// Value FIXME ... +func (jt *Iso8601Time) Value() (driver.Value, error) { + if jt == nil { + return nil, nil + } + var zeroTime time.Time + t := jt.time + if t.UnixNano() == zeroTime.UnixNano() { + return nil, nil + } + return t, nil +} + +// Scan FIXME ... +func (jt *Iso8601Time) Scan(v interface{}) error { + value, ok := v.(time.Time) + if ok { + *jt = Iso8601Time{ + time: value, + format: time.RFC3339, + } + return nil + } + return fmt.Errorf("can not convert %v to timestamp", v) +} diff --git a/plugins/zentao/impl/impl.go b/plugins/zentao/impl/impl.go index 920bced0..b4004753 100644 --- a/plugins/zentao/impl/impl.go +++ b/plugins/zentao/impl/impl.go @@ -56,6 +56,7 @@ func (plugin Zentao) SubTaskMetas() []core.SubTaskMeta { tasks.ExtractProjectsMeta, tasks.CollectExecutionMeta, tasks.ExtractExecutionsMeta, + tasks.ConvertExecutionsMeta, } } diff --git a/plugins/zentao/models/archived/execution.go b/plugins/zentao/models/archived/execution.go index 787527c1..7fe6cd16 100644 --- a/plugins/zentao/models/archived/execution.go +++ b/plugins/zentao/models/archived/execution.go @@ -2,51 +2,51 @@ package archived import ( "github.com/apache/incubator-devlake/models/migrationscripts/archived" - "time" + "github.com/apache/incubator-devlake/plugins/helper" ) type ZentaoExecution struct { - ConnectionId uint64 `gorm:"primaryKey"` - Id uint64 `json:"id"` - Project uint64 `json:"project"` - Model string `json:"model"` - Type string `json:"type"` - Lifetime string `json:"lifetime"` - Budget string `json:"budget"` - BudgetUnit string `json:"budgetUnit"` - Attribute string `json:"attribute"` - Percent int `json:"percent"` - Milestone string `json:"milestone"` - Output string `json:"output"` - Auth string `json:"auth"` - Parent int `json:"parent"` - Path string `json:"path"` - Grade int `json:"grade"` - Name string `json:"name"` - Code string `json:"code"` - Begin string `json:"begin"` - End string `json:"end"` - RealBegan string `json:"realBegan"` - RealEnd string `json:"realEnd"` - Days int `json:"days"` - Status string `json:"status"` - SubStatus string `json:"subStatus"` - Pri string `json:"pri"` - Desc string `json:"desc"` - Version int `json:"version"` - ParentVersion int `json:"parentVersion"` - PlanDuration int `json:"planDuration"` - RealDuration int `json:"realDuration"` + ConnectionId uint64 `gorm:"primaryKey"` + Id uint64 `json:"id" gorm:"primaryKey"` + Project uint64 `json:"project"` + Model string `json:"model"` + Type string `json:"type"` + Lifetime string `json:"lifetime"` + Budget string `json:"budget"` + BudgetUnit string `json:"budgetUnit"` + Attribute string `json:"attribute"` + Percent int `json:"percent"` + Milestone string `json:"milestone"` + Output string `json:"output"` + Auth string `json:"auth"` + Parent int `json:"parent"` + Path string `json:"path"` + Grade int `json:"grade"` + Name string `json:"name"` + Code string `json:"code"` + Begin *helper.Iso8601Time `json:"begin"` + End *helper.Iso8601Time `json:"end"` + RealBegan *helper.Iso8601Time `json:"realBegan"` + RealEnd *helper.Iso8601Time `json:"realEnd"` + Days int `json:"days"` + Status string `json:"status"` + SubStatus string `json:"subStatus"` + Pri string `json:"pri"` + Desc string `json:"desc"` + Version int `json:"version"` + ParentVersion int `json:"parentVersion"` + PlanDuration int `json:"planDuration"` + RealDuration int `json:"realDuration"` OpenedBy `json:"openedBy"` - OpenedDate time.Time `json:"openedDate"` - OpenedVersion string `json:"openedVersion"` + OpenedDate *helper.Iso8601Time `json:"openedDate"` + OpenedVersion string `json:"openedVersion"` LastEditedBy `json:"lastEditedBy"` - LastEditedDate time.Time `json:"lastEditedDate"` + LastEditedDate *helper.Iso8601Time `json:"lastEditedDate"` ClosedBy `json:"closedBy"` - ClosedDate time.Time `json:"closedDate"` + ClosedDate *helper.Iso8601Time `json:"closedDate"` CanceledBy `json:"canceledBy"` - CanceledDate time.Time `json:"canceledDate"` - SuspendedDate string `json:"suspendedDate"` + CanceledDate *helper.Iso8601Time `json:"canceledDate"` + SuspendedDate *helper.Iso8601Time `json:"suspendedDate"` PO `json:"PO"` PM `json:"PM"` QD `json:"QD"` @@ -147,5 +147,5 @@ type TeamMember struct { } func (ZentaoExecution) TableName() string { - return "_tool_zentao_execution" + return "_tool_zentao_executions" } diff --git a/plugins/zentao/models/archived/project.go b/plugins/zentao/models/archived/project.go index 63c498dd..94fcdfcb 100644 --- a/plugins/zentao/models/archived/project.go +++ b/plugins/zentao/models/archived/project.go @@ -25,7 +25,7 @@ import ( type ZentaoProject struct { archived.NoPKModel ConnectionId uint64 `gorm:"primaryKey;type:BIGINT NOT NULL"` - ID int `json:"id"` + ID int `json:"id" gorm:"primaryKey;type:BIGINT NOT NULL"` Project int `json:"project"` Model string `json:"model"` Type string `json:"type"` @@ -109,5 +109,5 @@ type Hours struct { } func (ZentaoProject) TableName() string { - return "_tool_zentao_project" + return "_tool_zentao_projects" } diff --git a/plugins/zentao/models/execution.go b/plugins/zentao/models/execution.go index e51102cf..054f21d7 100644 --- a/plugins/zentao/models/execution.go +++ b/plugins/zentao/models/execution.go @@ -2,51 +2,51 @@ package models import ( "github.com/apache/incubator-devlake/models/common" - "time" + "github.com/apache/incubator-devlake/plugins/helper" ) type ZentaoExecution struct { - ConnectionId uint64 `gorm:"primaryKey"` - Id uint64 `json:"id"` - Project uint64 `json:"project"` - Model string `json:"model"` - Type string `json:"type"` - Lifetime string `json:"lifetime"` - Budget string `json:"budget"` - BudgetUnit string `json:"budgetUnit"` - Attribute string `json:"attribute"` - Percent int `json:"percent"` - Milestone string `json:"milestone"` - Output string `json:"output"` - Auth string `json:"auth"` - Parent int `json:"parent"` - Path string `json:"path"` - Grade int `json:"grade"` - Name string `json:"name"` - Code string `json:"code"` - Begin string `json:"begin"` - End string `json:"end"` - RealBegan string `json:"realBegan"` - RealEnd string `json:"realEnd"` - Days int `json:"days"` - Status string `json:"status"` - SubStatus string `json:"subStatus"` - Pri string `json:"pri"` - Desc string `json:"desc"` - Version int `json:"version"` - ParentVersion int `json:"parentVersion"` - PlanDuration int `json:"planDuration"` - RealDuration int `json:"realDuration"` + ConnectionId uint64 `gorm:"primaryKey"` + Id uint64 `json:"id" gorm:"primaryKey"` + Project uint64 `json:"project"` + Model string `json:"model"` + Type string `json:"type"` + Lifetime string `json:"lifetime"` + Budget string `json:"budget"` + BudgetUnit string `json:"budgetUnit"` + Attribute string `json:"attribute"` + Percent int `json:"percent"` + Milestone string `json:"milestone"` + Output string `json:"output"` + Auth string `json:"auth"` + Parent int `json:"parent"` + Path string `json:"path"` + Grade int `json:"grade"` + Name string `json:"name"` + Code string `json:"code"` + Begin *helper.Iso8601Time `json:"begin"` + End *helper.Iso8601Time `json:"end"` + RealBegan *helper.Iso8601Time `json:"realBegan"` + RealEnd *helper.Iso8601Time `json:"realEnd"` + Days int `json:"days"` + Status string `json:"status"` + SubStatus string `json:"subStatus"` + Pri string `json:"pri"` + Desc string `json:"desc"` + Version int `json:"version"` + ParentVersion int `json:"parentVersion"` + PlanDuration int `json:"planDuration"` + RealDuration int `json:"realDuration"` OpenedBy `json:"openedBy"` - OpenedDate time.Time `json:"openedDate"` - OpenedVersion string `json:"openedVersion"` + OpenedDate *helper.Iso8601Time `json:"openedDate"` + OpenedVersion string `json:"openedVersion"` LastEditedBy `json:"lastEditedBy"` - LastEditedDate time.Time `json:"lastEditedDate"` + LastEditedDate *helper.Iso8601Time `json:"lastEditedDate"` ClosedBy `json:"closedBy"` - ClosedDate time.Time `json:"closedDate"` + ClosedDate *helper.Iso8601Time `json:"closedDate"` CanceledBy `json:"canceledBy"` - CanceledDate time.Time `json:"canceledDate"` - SuspendedDate string `json:"suspendedDate"` + CanceledDate *helper.Iso8601Time `json:"canceledDate"` + SuspendedDate *helper.Iso8601Time `json:"suspendedDate"` PO `json:"PO"` PM `json:"PM"` QD `json:"QD"` @@ -72,7 +72,7 @@ type ZentaoExecution struct { } func (ZentaoExecution) TableName() string { - return "_tool_zentao_execution" + return "_tool_zentao_executions" } type OpenedBy struct { diff --git a/plugins/zentao/models/project.go b/plugins/zentao/models/project.go index 5a51d738..db9450bf 100644 --- a/plugins/zentao/models/project.go +++ b/plugins/zentao/models/project.go @@ -25,7 +25,7 @@ import ( type ZentaoProject struct { common.NoPKModel ConnectionId uint64 `gorm:"primaryKey;type:BIGINT NOT NULL"` - ID int `json:"id"` + ID int `json:"id" gorm:"primaryKey;type:BIGINT NOT NULL"` Project int `json:"project"` Model string `json:"model"` Type string `json:"type"` @@ -109,5 +109,5 @@ type Hours struct { } func (ZentaoProject) TableName() string { - return "_tool_zentao_project" + return "_tool_zentao_projects" } diff --git a/plugins/zentao/tasks/execution_convertor.go b/plugins/zentao/tasks/execution_convertor.go new file mode 100644 index 00000000..727ba92d --- /dev/null +++ b/plugins/zentao/tasks/execution_convertor.go @@ -0,0 +1,91 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tasks + +import ( + "github.com/apache/incubator-devlake/models/domainlayer" + "github.com/apache/incubator-devlake/models/domainlayer/didgen" + "github.com/apache/incubator-devlake/models/domainlayer/ticket" + "github.com/apache/incubator-devlake/plugins/core" + "github.com/apache/incubator-devlake/plugins/core/dal" + "github.com/apache/incubator-devlake/plugins/helper" + "github.com/apache/incubator-devlake/plugins/zentao/models" + "reflect" +) + +var _ core.SubTaskEntryPoint = ConvertExecutions + +var ConvertExecutionsMeta = core.SubTaskMeta{ + Name: "convertExecutions", + EntryPoint: ConvertExecutions, + EnabledByDefault: true, + Description: "convert Zentao executions", + DomainTypes: []string{core.DOMAIN_TYPE_TICKET}, +} + +func ConvertExecutions(taskCtx core.SubTaskContext) error { + data := taskCtx.GetData().(*ZentaoTaskData) + db := taskCtx.GetDal() + boardIdGen := didgen.NewDomainIdGenerator(&models.ZentaoExecution{}) + cursor, err := db.Cursor( + dal.From(&models.ZentaoExecution{}), + dal.Where(`_tool_zentao_executions.id = ? and + _tool_zentao_executions.connection_id = ?`, data.Options.ExecutionId, data.Options.ConnectionId), + ) + if err != nil { + return err + } + defer cursor.Close() + convertor, err := helper.NewDataConverter(helper.DataConverterArgs{ + InputRowType: reflect.TypeOf(models.ZentaoExecution{}), + Input: cursor, + RawDataSubTaskArgs: helper.RawDataSubTaskArgs{ + Ctx: taskCtx, + Params: ZentaoApiParams{ + ProductId: data.Options.ProductId, + ExecutionId: data.Options.ExecutionId, + ProjectId: data.Options.ProjectId, + }, + Table: RAW_EXECUTION_TABLE, + }, + Convert: func(inputRow interface{}) ([]interface{}, error) { + toolExecution := inputRow.(*models.ZentaoExecution) + + domainBoard := &ticket.Board{ + DomainEntity: domainlayer.DomainEntity{ + Id: boardIdGen.Generate(toolExecution.ConnectionId, toolExecution.Id), + }, + Name: toolExecution.Name, + Description: toolExecution.Desc, + Url: toolExecution.Path, + CreatedDate: toolExecution.OpenedDate.ToNullableTime(), + Type: toolExecution.Type, + } + + results := make([]interface{}, 0) + results = append(results, domainBoard) + return results, nil + }, + }) + + if err != nil { + return err + } + + return convertor.Execute() +}
