You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by wa...@apache.org on 2022/09/24 14:06:16 UTC
[incubator-devlake] 03/03: feat(zentao): fix execution time
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 3d8811013f3816a7c41670b58c0aeba85cd152bd
Author: Yingchu Chen <yi...@merico.dev>
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 5b02e9c9..a69e9b4a 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()
+}