This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 09baac4e refactor: refdiff db to dal (#2161)
09baac4e is described below
commit 09baac4eb3ff83c68716d820ce3095292974bb3d
Author: mappjzc <[email protected]>
AuthorDate: Sat Jun 11 10:32:58 2022 +0800
refactor: refdiff db to dal (#2161)
Change gorm.db to dal on refdiff.
Change dal interface to Clause
Add Raw
Add Pluck
Add CreateIfNotExist
Add Model to From
Nddtfjiang <[email protected]>
---
impl/dalgorm/dalgorm.go | 63 +++++++++++-----
plugins/core/dal/dal.go | 84 ++++++++++++----------
plugins/jira/tasks/changelog_collector.go | 2 +-
plugins/jira/tasks/worklog_collector.go | 2 +-
.../refdiff/tasks/ref_commit_diff_calculator.go | 23 +++---
plugins/refdiff/tasks/ref_issue_diff_calculator.go | 25 ++++---
.../tasks/refs_pr_cherry_pick_calculator.go | 35 +++++----
7 files changed, 134 insertions(+), 100 deletions(-)
diff --git a/impl/dalgorm/dalgorm.go b/impl/dalgorm/dalgorm.go
index ce6e60bf..5a340b02 100644
--- a/impl/dalgorm/dalgorm.go
+++ b/impl/dalgorm/dalgorm.go
@@ -38,23 +38,29 @@ type Dalgorm struct {
//return s.name
//}
-func buildTx(tx *gorm.DB, clauses []interface{}) *gorm.DB {
+func buildTx(tx *gorm.DB, clauses []dal.Clause) *gorm.DB {
for _, clause := range clauses {
- switch clause := clause.(type) {
- case *dal.JoinClause:
- tx = tx.Joins(clause.Expr, clause.Params...)
- case *dal.WhereClause:
- tx = tx.Where(clause.Expr, clause.Params...)
+ t := clause.Type
+ d := clause.Data
+ switch t {
+ case dal.JoinClause:
+ tx = tx.Joins(d.(dal.DalClause).Expr,
d.(dal.DalClause).Params...)
+ case dal.WhereClause:
+ tx = tx.Where(d.(dal.DalClause).Expr,
d.(dal.DalClause).Params...)
case dal.OrderbyClause:
- tx = tx.Order(string(clause))
+ tx = tx.Order(d.(string))
case dal.LimitClause:
- tx = tx.Limit(int(clause))
+ tx = tx.Limit(d.(int))
case dal.OffsetClause:
- tx = tx.Offset(int(clause))
+ tx = tx.Offset(d.(int))
case dal.FromClause:
- tx = tx.Table(string(clause))
+ if str, ok := d.(string); ok {
+ tx = tx.Table(str)
+ } else {
+ tx = tx.Model(d)
+ }
case dal.SelectClause:
- tx = tx.Select(string(clause))
+ tx = tx.Select(d.(string))
}
}
return tx
@@ -62,53 +68,72 @@ func buildTx(tx *gorm.DB, clauses []interface{}) *gorm.DB {
var _ dal.Dal = (*Dalgorm)(nil)
+// Exec executes raw sql query
+func (d *Dalgorm) Raw(query string, params ...interface{}) (*sql.Rows, error) {
+ return d.db.Raw(query, params...).Rows()
+}
+
// Exec executes raw sql query
func (d *Dalgorm) Exec(query string, params ...interface{}) error {
return d.db.Exec(query, params...).Error
}
// CreateTable creates a table with gorm definition from `entity`
-func (d *Dalgorm) AutoMigrate(entity interface{}, clauses ...interface{})
error {
+func (d *Dalgorm) AutoMigrate(entity interface{}, clauses ...dal.Clause) error
{
return buildTx(d.db, clauses).AutoMigrate(entity)
}
// Cursor returns a database cursor, cursor is especially useful when handling
big amount of rows of data
-func (d *Dalgorm) Cursor(clauses ...interface{}) (*sql.Rows, error) {
+func (d *Dalgorm) Cursor(clauses ...dal.Clause) (*sql.Rows, error) {
return buildTx(d.db, clauses).Rows()
}
+func (d *Dalgorm) CursorTx(clauses ...dal.Clause) *gorm.DB {
+ return buildTx(d.db, clauses)
+}
+
// Fetch loads row data from `cursor` into `dst`
func (d *Dalgorm) Fetch(cursor *sql.Rows, dst interface{}) error {
return d.db.ScanRows(cursor, dst)
}
// All loads matched rows from database to `dst`, USE IT WITH COUTIOUS!!
-func (d *Dalgorm) All(dst interface{}, clauses ...interface{}) error {
+func (d *Dalgorm) All(dst interface{}, clauses ...dal.Clause) error {
return buildTx(d.db, clauses).Find(dst).Error
}
// First loads first matched row from database to `dst`, error will be
returned if no records were found
-func (d *Dalgorm) First(dst interface{}, clauses ...interface{}) error {
+func (d *Dalgorm) First(dst interface{}, clauses ...dal.Clause) error {
return buildTx(d.db, clauses).First(dst).Error
}
+// Pluck used to query single column
+func (d *Dalgorm) Pluck(column string, dest interface{}, clauses
...dal.Clause) error {
+ return buildTx(d.db, clauses).Pluck(column, dest).Error
+}
+
// Create insert record to database
-func (d *Dalgorm) Create(entity interface{}, clauses ...interface{}) error {
+func (d *Dalgorm) Create(entity interface{}, clauses ...dal.Clause) error {
return buildTx(d.db, clauses).Create(entity).Error
}
// Update updates record
-func (d *Dalgorm) Update(entity interface{}, clauses ...interface{}) error {
+func (d *Dalgorm) Update(entity interface{}, clauses ...dal.Clause) error {
return buildTx(d.db, clauses).Save(entity).Error
}
// CreateOrUpdate tries to create the record, or fallback to update all if
failed
-func (d *Dalgorm) CreateOrUpdate(entity interface{}, clauses ...interface{})
error {
+func (d *Dalgorm) CreateOrUpdate(entity interface{}, clauses ...dal.Clause)
error {
return buildTx(d.db, clauses).Clauses(clause.OnConflict{UpdateAll:
true}).Create(entity).Error
}
+// CreateIfNotExist tries to create the record if not exist
+func (d *Dalgorm) CreateIfNotExist(entity interface{}, clauses ...dal.Clause)
error {
+ return buildTx(d.db, clauses).Clauses(clause.OnConflict{DoNothing:
true}).Create(entity).Error
+}
+
// Delete records from database
-func (d *Dalgorm) Delete(entity interface{}, clauses ...interface{}) error {
+func (d *Dalgorm) Delete(entity interface{}, clauses ...dal.Clause) error {
return buildTx(d.db, clauses).Delete(entity).Error
}
diff --git a/plugins/core/dal/dal.go b/plugins/core/dal/dal.go
index 5318b6ca..daf43b4a 100644
--- a/plugins/core/dal/dal.go
+++ b/plugins/core/dal/dal.go
@@ -17,91 +17,97 @@ limitations under the License.
package dal
-import "database/sql"
+import (
+ "database/sql"
+)
+
+type Clause struct {
+ Type string
+ Data interface{}
+}
// Dal aims to facilitate an isolation of Database Access Layer by defining a
set of operations should a
// Database Access Layer provide
// This is inroduced by the fact that mocking *gorm.DB is hard, and `gomonkey`
is not working on macOS
type Dal interface {
+ // Raw executes raw sql query with sql.Rows and error return
+ Raw(query string, params ...interface{}) (*sql.Rows, error)
// Exec executes raw sql query
Exec(query string, params ...interface{}) error
- // CreateTable creates a table with gorm definition from `entity`
- AutoMigrate(entity interface{}, clauses ...interface{}) error
+ // CreateTable creates a table with gorm definition from `entity`R
+ AutoMigrate(entity interface{}, clauses ...Clause) error
// Cursor returns a database cursor, cursor is especially useful when
handling big amount of rows of data
- Cursor(clauses ...interface{}) (*sql.Rows, error)
+ Cursor(clauses ...Clause) (*sql.Rows, error)
// Fetch loads row data from `cursor` into `dst`
Fetch(cursor *sql.Rows, dst interface{}) error
// All loads matched rows from database to `dst`, USE IT WITH COUTIOUS!!
- All(dst interface{}, clauses ...interface{}) error
+ All(dst interface{}, clauses ...Clause) error
// First loads first matched row from database to `dst`, error will be
returned if no records were found
- First(dst interface{}, clauses ...interface{}) error
+ First(dst interface{}, clauses ...Clause) error
+ // Pluck used to query single column
+ Pluck(column string, dest interface{}, clauses ...Clause) error
// Create insert record to database
- Create(entity interface{}, clauses ...interface{}) error
+ Create(entity interface{}, clauses ...Clause) error
// Update updates record
- Update(entity interface{}, clauses ...interface{}) error
+ Update(entity interface{}, clauses ...Clause) error
// CreateOrUpdate tries to create the record, or fallback to update all
if failed
- CreateOrUpdate(entity interface{}, clauses ...interface{}) error
+ CreateOrUpdate(entity interface{}, clauses ...Clause) error
+ // CreateIfNotExist tries to create the record if not exist
+ CreateIfNotExist(entity interface{}, clauses ...Clause) error
// Delete records from database
- Delete(entity interface{}, clauses ...interface{}) error
+ Delete(entity interface{}, clauses ...Clause) error
}
-type dalClause struct {
+type DalClause struct {
Expr string
Params []interface{}
}
-// JoinClause represents a SQL `JOIN` clause
-type JoinClause dalClause
+const JoinClause string = "Join"
// Join creates a new JoinClause
-func Join(clause string, params ...interface{}) *JoinClause {
- return &JoinClause{clause, params}
+func Join(clause string, params ...interface{}) Clause {
+ return Clause{Type: JoinClause, Data: DalClause{clause, params}}
}
-// WhereClause represents a SQL `WHERE` clause
-type WhereClause dalClause
+const WhereClause string = "Where"
// Where creates a new WhereClause
-func Where(clause string, params ...interface{}) *WhereClause {
- return &WhereClause{clause, params}
+func Where(clause string, params ...interface{}) Clause {
+ return Clause{Type: WhereClause, Data: DalClause{clause, params}}
}
-// LimitClause represents a SQL `LIMIT` clause
-type LimitClause int
+const LimitClause string = "Limit"
// Limit creates a new LimitClause
-func Limit(limit int) LimitClause {
- return LimitClause(limit)
+func Limit(limit int) Clause {
+ return Clause{Type: LimitClause, Data: limit}
}
-// OffsetClause represents a SQL `OFFSET` clause
-type OffsetClause int
+const OffsetClause string = "Offset"
// Offset creates a new OffsetClause
-func Offset(offset int) OffsetClause {
- return OffsetClause(offset)
+func Offset(offset int) Clause {
+ return Clause{Type: OffsetClause, Data: offset}
}
-// FromClause represents a SQL `OFFSET` clause
-type FromClause string
+const FromClause string = "From"
// From creates a new TableClause
-func From(table string) FromClause {
- return FromClause(table)
+func From(table interface{}) Clause {
+ return Clause{Type: FromClause, Data: table}
}
-// SelectClause represents a SQL `OFFSET` clause
-type SelectClause string
+const SelectClause string = "Select"
// Select creates a new TableClause
-func Select(fields string) SelectClause {
- return SelectClause(fields)
+func Select(fields string) Clause {
+ return Clause{Type: SelectClause, Data: fields}
}
-// OrderbyClause represents a SQL `ORDER BY` clause
-type OrderbyClause string
+const OrderbyClause string = "OrderBy"
// Orderby creates a new Orderby
-func Orderby(expr string) OrderbyClause {
- return OrderbyClause(expr)
+func Orderby(expr string) Clause {
+ return Clause{Type: OrderbyClause, Data: expr}
}
diff --git a/plugins/jira/tasks/changelog_collector.go
b/plugins/jira/tasks/changelog_collector.go
index b4150735..22030f7d 100644
--- a/plugins/jira/tasks/changelog_collector.go
+++ b/plugins/jira/tasks/changelog_collector.go
@@ -45,7 +45,7 @@ func CollectChangelogs(taskCtx core.SubTaskContext) error {
since := data.Since
// filter out issue_ids that needed collection
- clauses := []interface{}{
+ clauses := []Clause{
Select("bi.issue_id, NOW() AS update_time"),
From("_tool_jira_board_issues bi"),
Join("LEFT JOIN _tool_jira_issues i ON (bi.connection_id =
i.connection_id AND bi.issue_id = i.issue_id)"),
diff --git a/plugins/jira/tasks/worklog_collector.go
b/plugins/jira/tasks/worklog_collector.go
index 2ec8fea2..53282fb0 100644
--- a/plugins/jira/tasks/worklog_collector.go
+++ b/plugins/jira/tasks/worklog_collector.go
@@ -38,7 +38,7 @@ func CollectWorklogs(taskCtx core.SubTaskContext) error {
logger := taskCtx.GetLogger()
// filter out issue_ids that needed collection
- clauses := []interface{}{
+ clauses := []Clause{
Select("bi.issue_id, NOW() AS update_time"),
From("_tool_jira_board_issues bi"),
Join("LEFT JOIN _tool_jira_issues i ON (bi.connection_id =
i.connection_id AND bi.issue_id = i.issue_id)"),
diff --git a/plugins/refdiff/tasks/ref_commit_diff_calculator.go
b/plugins/refdiff/tasks/ref_commit_diff_calculator.go
index af71c905..a4956604 100644
--- a/plugins/refdiff/tasks/ref_commit_diff_calculator.go
+++ b/plugins/refdiff/tasks/ref_commit_diff_calculator.go
@@ -23,14 +23,14 @@ import (
"github.com/apache/incubator-devlake/models/domainlayer/code"
"github.com/apache/incubator-devlake/plugins/core"
+ "github.com/apache/incubator-devlake/plugins/core/dal"
"github.com/apache/incubator-devlake/plugins/refdiff/utils"
- "gorm.io/gorm/clause"
)
func CalculateCommitsDiff(taskCtx core.SubTaskContext) error {
data := taskCtx.GetData().(*RefdiffTaskData)
repoId := data.Options.RepoId
- db := taskCtx.GetDb()
+ db := taskCtx.GetDal()
ctx := taskCtx.GetContext()
logger := taskCtx.GetLogger()
insertCountLimitOfRefsCommitsDiff := int(65535 /
reflect.ValueOf(code.RefsCommitsDiff{}).NumField())
@@ -41,11 +41,12 @@ func CalculateCommitsDiff(taskCtx core.SubTaskContext)
error {
// load commits from db
commitParent := &code.CommitParent{}
- cursor, err := db.Table("commit_parents cp").
- Select("cp.*").
- Joins("LEFT JOIN repo_commits rc ON (rc.commit_sha =
cp.commit_sha)").
- Where("rc.repo_id = ?", repoId).
- Rows()
+ cursor, err := db.Cursor(
+ dal.Select("cp.*"),
+ dal.Join("LEFT JOIN repo_commits rc ON (rc.commit_sha =
cp.commit_sha)"),
+ dal.From("commit_parents cp"),
+ dal.Where("rc.repo_id = ?", repoId),
+ )
if err != nil {
panic(err)
}
@@ -57,7 +58,7 @@ func CalculateCommitsDiff(taskCtx core.SubTaskContext) error {
return ctx.Err()
default:
}
- err = db.ScanRows(cursor, commitParent)
+ err = db.Fetch(cursor, commitParent)
if err != nil {
return fmt.Errorf("failed to read commit from database:
%v", err)
}
@@ -84,7 +85,7 @@ func CalculateCommitsDiff(taskCtx core.SubTaskContext) error {
commitsDiff.OldRefId = fmt.Sprintf("%s:%s", repoId, pair[3])
// delete records before creation
- err = db.Delete(&code.RefsCommitsDiff{NewRefId:
commitsDiff.NewRefId, OldRefId: commitsDiff.OldRefId}).Error
+ err = db.Delete(&code.RefsCommitsDiff{NewRefId:
commitsDiff.NewRefId, OldRefId: commitsDiff.OldRefId})
if err != nil {
return err
}
@@ -112,7 +113,7 @@ func CalculateCommitsDiff(taskCtx core.SubTaskContext)
error {
// sql limit placeholders count only 65535
if
commitsDiff.SortingIndex%insertCountLimitOfRefsCommitsDiff == 0 {
logger.Info("commitsDiffs count in limited[%d]
index[%d]--exec and clean", len(commitsDiffs), commitsDiff.SortingIndex)
- err = db.Clauses(clause.OnConflict{DoNothing:
true}).Create(commitsDiffs).Error
+ err = db.CreateIfNotExist(commitsDiffs)
if err != nil {
return err
}
@@ -124,7 +125,7 @@ func CalculateCommitsDiff(taskCtx core.SubTaskContext)
error {
if len(commitsDiffs) > 0 {
logger.Info("insert data count [%d]", len(commitsDiffs))
- err = db.Clauses(clause.OnConflict{DoNothing:
true}).Create(commitsDiffs).Error
+ err = db.CreateIfNotExist(commitsDiffs)
if err != nil {
return err
}
diff --git a/plugins/refdiff/tasks/ref_issue_diff_calculator.go
b/plugins/refdiff/tasks/ref_issue_diff_calculator.go
index 43e9c853..4e938eae 100644
--- a/plugins/refdiff/tasks/ref_issue_diff_calculator.go
+++ b/plugins/refdiff/tasks/ref_issue_diff_calculator.go
@@ -23,6 +23,7 @@ import (
"github.com/apache/incubator-devlake/models/domainlayer/crossdomain"
"github.com/apache/incubator-devlake/plugins/core"
+ "github.com/apache/incubator-devlake/plugins/core/dal"
"github.com/apache/incubator-devlake/plugins/helper"
)
@@ -44,29 +45,31 @@ func CaculatePairList(taskCtx core.SubTaskContext)
(RefPairLists, error) {
func CalculateIssuesDiff(taskCtx core.SubTaskContext) error {
data := taskCtx.GetData().(*RefdiffTaskData)
repoId := data.Options.RepoId
- db := taskCtx.GetDb()
+ db := taskCtx.GetDal()
// use to calculate progress
pairList, err := CaculatePairList(taskCtx)
if err != nil {
return err
}
- cursor, err := db.Table("refs_commits_diffs").
- Joins(
+ cursor, err := db.Cursor(
+ dal.From("refs_commits_diffs"),
+ dal.Join(
`left join (
select pull_request_id as id, commit_sha from pull_request_commits
left join pull_requests p on
pull_request_commits.pull_request_id = p.id
where p.base_repo_id = ?
union
select id, merge_commit_sha as commit_sha from
pull_requests where base_repo_id = ?) _combine_pr
- on _combine_pr.commit_sha =
refs_commits_diffs.commit_sha`, repoId, repoId).
- Joins("left join pull_request_issues on
pull_request_issues.pull_request_id = _combine_pr.id").
- Joins("left join refs on refs.commit_sha =
refs_commits_diffs.new_ref_commit_sha").
- Order("refs_commits_diffs.new_ref_id ASC").
- Where("refs.repo_id = ? and pull_request_issues.issue_number >
0 and (refs_commits_diffs.new_ref_id, refs_commits_diffs.old_ref_id) in ?",
- repoId, pairList).
- Select(`refs_commits_diffs.new_ref_commit_sha as
new_ref_commit_sha, refs_commits_diffs.old_ref_commit_sha as
old_ref_commit_sha,
+ on _combine_pr.commit_sha =
refs_commits_diffs.commit_sha`, repoId, repoId),
+ dal.Join("left join pull_request_issues on
pull_request_issues.pull_request_id = _combine_pr.id"),
+ dal.Join("left join refs on refs.commit_sha =
refs_commits_diffs.new_ref_commit_sha"),
+ dal.Orderby("refs_commits_diffs.new_ref_id ASC"),
+ dal.Where("refs.repo_id = ? and
pull_request_issues.issue_number > 0 and (refs_commits_diffs.new_ref_id,
refs_commits_diffs.old_ref_id) in ?",
+ repoId, pairList),
+ dal.Select(`refs_commits_diffs.new_ref_commit_sha as
new_ref_commit_sha, refs_commits_diffs.old_ref_commit_sha as
old_ref_commit_sha,
pull_request_issues.issue_id as issue_id,
pull_request_issues.issue_number as issue_number,
- refs_commits_diffs.new_ref_id as new_ref_id,
refs_commits_diffs.old_ref_id as old_ref_id`).Rows()
+ refs_commits_diffs.new_ref_id as new_ref_id,
refs_commits_diffs.old_ref_id as old_ref_id`),
+ )
if err != nil {
return err
}
diff --git a/plugins/refdiff/tasks/refs_pr_cherry_pick_calculator.go
b/plugins/refdiff/tasks/refs_pr_cherry_pick_calculator.go
index e5f2b0b4..1d85f249 100644
--- a/plugins/refdiff/tasks/refs_pr_cherry_pick_calculator.go
+++ b/plugins/refdiff/tasks/refs_pr_cherry_pick_calculator.go
@@ -25,7 +25,7 @@ import (
"github.com/apache/incubator-devlake/models/domainlayer/code"
"github.com/apache/incubator-devlake/plugins/core"
- "gorm.io/gorm/clause"
+ "github.com/apache/incubator-devlake/plugins/core/dal"
)
type cherryPick struct {
@@ -42,7 +42,7 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext) error
{
data := taskCtx.GetData().(*RefdiffTaskData)
repoId := data.Options.RepoId
ctx := taskCtx.GetContext()
- db := taskCtx.GetDb()
+ db := taskCtx.GetDal()
var prTitleRegex *regexp.Regexp
prTitlePattern := taskCtx.GetConfig("GITHUB_PR_TITLE_PATTERN")
@@ -50,9 +50,11 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext)
error {
prTitleRegex = regexp.MustCompile(prTitlePattern)
}
- cursor, err := db.Model(&code.PullRequest{}).
- Joins("left join repos on pull_requests.base_repo_id =
repos.id").
- Where("repos.id = ?", repoId).Rows()
+ cursor, err := db.Cursor(
+ dal.From(&code.PullRequest{}),
+ dal.Join("left join repos on pull_requests.base_repo_id =
repos.id"),
+ dal.Where("repos.id = ?", repoId),
+ )
if err != nil {
return err
}
@@ -71,7 +73,7 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext) error
{
default:
}
- err = db.ScanRows(cursor, pr)
+ err = db.Fetch(cursor, pr)
if err != nil {
return err
}
@@ -89,9 +91,10 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext)
error {
}
var parentPrId string
- err = db.Model(&code.PullRequest{}).
- Where("pull_request_key = ? and base_repo_id = ?",
parentPrKeyInt, repoId).
- Pluck("id", &parentPrId).Error
+ err = db.Pluck("id", &parentPrId,
+ dal.Where("pull_request_key = ? and base_repo_id = ?",
parentPrKeyInt, repoId),
+ dal.From("pull_requests"),
+ )
if err != nil {
return err
}
@@ -100,7 +103,7 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext)
error {
}
pr.ParentPrId = parentPrId
- err = db.Save(pr).Error
+ err = db.Update(pr)
if err != nil {
return err
}
@@ -125,7 +128,7 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext)
error {
ORDER BY pr1.parent_pr_id,
pr2.created_date,
pr1.base_ref ASC
- `).Rows()
+ `)
if err != nil {
return err
}
@@ -138,7 +141,7 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext)
error {
var cherrypickPrKeys []string
for cursor2.Next() {
var item cherryPick
- err = db.ScanRows(cursor2, &item)
+ err = db.Fetch(cursor2, &item)
if err != nil {
return err
}
@@ -149,9 +152,7 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext)
error {
if refsPrCherryPick != nil {
refsPrCherryPick.CherrypickBaseBranches =
strings.Join(cherrypickBaseBranches, ",")
refsPrCherryPick.CherrypickPrKeys =
strings.Join(cherrypickPrKeys, ",")
- err = db.Clauses(clause.OnConflict{
- UpdateAll: true,
- }).Create(refsPrCherryPick).Error
+ err = db.CreateOrUpdate(refsPrCherryPick)
if err != nil {
return err
}
@@ -170,9 +171,7 @@ func CalculatePrCherryPick(taskCtx core.SubTaskContext)
error {
}
if refsPrCherryPick != nil {
- err = db.Clauses(clause.OnConflict{
- UpdateAll: true,
- }).Create(refsPrCherryPick).Error
+ err = db.CreateOrUpdate(refsPrCherryPick)
if err != nil {
return err
}