mirror of
https://github.com/go-gitea/gitea
synced 2024-06-03 03:46:51 +02:00
Fix functions that gets moved in #26969
This commit is contained in:
parent
3b8291ff95
commit
065469cffc
|
@ -1290,3 +1290,77 @@ func InsertIssueComments(ctx context.Context, comments []*Comment) error {
|
||||||
}
|
}
|
||||||
return committer.Commit()
|
return committer.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpsertIssueComments inserts many comments of issues.
|
||||||
|
func UpsertIssueComments(ctx context.Context, comments []*Comment) error {
|
||||||
|
if len(comments) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
issueIDs := make(map[int64]bool)
|
||||||
|
for _, comment := range comments {
|
||||||
|
issueIDs[comment.IssueID] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
sess := db.GetEngine(ctx)
|
||||||
|
for _, comment := range comments {
|
||||||
|
exists, err := sess.Exist(&Comment{
|
||||||
|
IssueID: comment.IssueID,
|
||||||
|
OriginalID: comment.OriginalID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
if _, err := sess.NoAutoTime().Insert(comment); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := sess.NoAutoTime().Where(
|
||||||
|
"issue_id = ? AND original_id = ?", comment.IssueID, comment.OriginalID,
|
||||||
|
).AllCols().Update(comment); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, reaction := range comment.Reactions {
|
||||||
|
reaction.IssueID = comment.IssueID
|
||||||
|
reaction.CommentID = comment.ID
|
||||||
|
}
|
||||||
|
if len(comment.Reactions) > 0 {
|
||||||
|
for _, reaction := range comment.Reactions {
|
||||||
|
// issue comment reaction is uniquely identified by issue_id, comment_id and type
|
||||||
|
exists, err := sess.Exist(&Reaction{
|
||||||
|
IssueID: reaction.IssueID,
|
||||||
|
CommentID: reaction.CommentID,
|
||||||
|
Type: reaction.Type,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
if _, err := sess.Where(
|
||||||
|
"issue_id = ? AND comment_id = ? AND type = ?",
|
||||||
|
reaction.IssueID, reaction.CommentID, reaction.Type,
|
||||||
|
).AllCols().Update(&reaction); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := sess.Insert(&reaction); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for issueID := range issueIDs {
|
||||||
|
if _, err := db.Exec(ctx, "UPDATE issue SET num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?",
|
||||||
|
issueID, CommentTypeComment, issueID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -939,3 +939,86 @@ func insertIssue(ctx context.Context, issue *Issue) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpsertIssues creates new issues and updates existing issues in database
|
||||||
|
func UpsertIssues(ctx context.Context, issues ...*Issue) error {
|
||||||
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
for _, issue := range issues {
|
||||||
|
if _, err := upsertIssue(ctx, issue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func upsertIssue(ctx context.Context, issue *Issue) (isInsert bool, err error) {
|
||||||
|
sess := db.GetEngine(ctx)
|
||||||
|
|
||||||
|
var issueIDs []int64
|
||||||
|
err = sess.Table("issue").Where("repo_id = ? AND `index` = ?", issue.RepoID, issue.Index).Cols("id").Find(&issueIDs)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(issueIDs) == 0 {
|
||||||
|
return true, insertIssue(ctx, issue)
|
||||||
|
}
|
||||||
|
|
||||||
|
issue.ID = issueIDs[0]
|
||||||
|
return false, updateIssue(ctx, issue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateIssue(ctx context.Context, issue *Issue) error {
|
||||||
|
sess := db.GetEngine(ctx)
|
||||||
|
if _, err := sess.NoAutoTime().ID(issue.ID).AllCols().Update(issue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
issueLabels := resolveIssueLabels(issue.ID, issue.Labels)
|
||||||
|
if len(issueLabels) > 0 {
|
||||||
|
// delete old labels
|
||||||
|
if _, err := sess.Table("issue_label").Where("issue_id = ?", issue.ID).Delete(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// insert new labels
|
||||||
|
if _, err := sess.Insert(issueLabels); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, reaction := range issue.Reactions {
|
||||||
|
reaction.IssueID = issue.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(issue.Reactions) > 0 {
|
||||||
|
// update existing reactions and insert new ones
|
||||||
|
for _, reaction := range issue.Reactions {
|
||||||
|
exists, err := sess.Exist(&Reaction{ID: reaction.ID})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
if _, err := sess.ID(reaction.ID).AllCols().Update(&reaction); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := sess.Insert(&reaction); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveIssueLabels(issueID int64, labels []*Label) []IssueLabel {
|
||||||
|
issueLabels := make([]IssueLabel, 0, len(labels))
|
||||||
|
for _, label := range labels {
|
||||||
|
issueLabels = append(issueLabels, IssueLabel{
|
||||||
|
IssueID: issueID,
|
||||||
|
LabelID: label.ID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return issueLabels
|
||||||
|
}
|
||||||
|
|
|
@ -383,3 +383,85 @@ func InsertMilestones(ctx context.Context, ms ...*Milestone) (err error) {
|
||||||
}
|
}
|
||||||
return committer.Commit()
|
return committer.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateMilestones updates milestones of repository.
|
||||||
|
func UpdateMilestones(ctx context.Context, ms ...*Milestone) (err error) {
|
||||||
|
if len(ms) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
sess := db.GetEngine(ctx)
|
||||||
|
|
||||||
|
// get existing milestones
|
||||||
|
existingMilestones := make([]*Milestone, 0)
|
||||||
|
if err = sess.Where("repo_id = ?", ms[0].RepoID).Find(&existingMilestones); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
milestonesToAdd := make([]*Milestone, 0)
|
||||||
|
milestonesToUpdate := make([]*Milestone, 0)
|
||||||
|
milestonesToDelete := make([]*Milestone, 0)
|
||||||
|
foundMap := make(map[int64]bool)
|
||||||
|
|
||||||
|
openCount := 0
|
||||||
|
closedCount := 0
|
||||||
|
|
||||||
|
for _, m := range ms {
|
||||||
|
var foundMilestone *Milestone
|
||||||
|
for _, existingMilestone := range existingMilestones {
|
||||||
|
if existingMilestone.OriginalID == m.OriginalID {
|
||||||
|
foundMilestone = existingMilestone
|
||||||
|
foundMap[existingMilestone.ID] = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if foundMilestone == nil {
|
||||||
|
milestonesToAdd = append(milestonesToAdd, m)
|
||||||
|
} else if foundMilestone.OriginalID != m.OriginalID {
|
||||||
|
m.ID = foundMilestone.ID
|
||||||
|
milestonesToUpdate = append(milestonesToUpdate, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.IsClosed {
|
||||||
|
closedCount++
|
||||||
|
} else {
|
||||||
|
openCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, existingMilestone := range existingMilestones {
|
||||||
|
if _, exist := foundMap[existingMilestone.ID]; !exist {
|
||||||
|
milestonesToDelete = append(milestonesToDelete, existingMilestone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(milestonesToAdd) > 0 {
|
||||||
|
if _, err = sess.Insert(milestonesToAdd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range milestonesToUpdate {
|
||||||
|
if _, err = sess.ID(m.ID).AllCols().Update(m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range milestonesToDelete {
|
||||||
|
if _, err = sess.ID(m.ID).Delete(m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.ID(ms[0].RepoID).Update(&repo_model.Repository{
|
||||||
|
NumMilestones: len(ms),
|
||||||
|
NumOpenMilestones: openCount,
|
||||||
|
NumClosedMilestones: closedCount,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1125,3 +1125,32 @@ func InsertPullRequests(ctx context.Context, prs ...*PullRequest) error {
|
||||||
}
|
}
|
||||||
return committer.Commit()
|
return committer.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpsertPullRequests inserts new pull requests and updates existing pull requests in database
|
||||||
|
func UpsertPullRequests(ctx context.Context, prs ...*PullRequest) error {
|
||||||
|
if len(prs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
sess := db.GetEngine(ctx)
|
||||||
|
for _, pr := range prs {
|
||||||
|
isInsert, err := upsertIssue(ctx, pr.Issue)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pr.IssueID = pr.Issue.ID
|
||||||
|
|
||||||
|
if isInsert {
|
||||||
|
if _, err := sess.NoAutoTime().Insert(pr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := sess.NoAutoTime().ID(pr.ID).AllCols().Update(pr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1,530 +0,0 @@
|
||||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
|
||||||
"code.gitea.io/gitea/modules/container"
|
|
||||||
"code.gitea.io/gitea/modules/storage"
|
|
||||||
"code.gitea.io/gitea/modules/structs"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InsertMilestones creates milestones of repository.
|
|
||||||
func InsertMilestones(ms ...*issues_model.Milestone) (err error) {
|
|
||||||
if len(ms) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
|
|
||||||
// to return the id, so we should not use batch insert
|
|
||||||
for _, m := range ms {
|
|
||||||
if _, err = sess.NoAutoTime().Insert(m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = sess.Exec("UPDATE `repository` SET num_milestones = num_milestones + ? WHERE id = ?", len(ms), ms[0].RepoID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMilestones updates milestones of repository.
|
|
||||||
func UpdateMilestones(ctx context.Context, ms ...*issues_model.Milestone) (err error) {
|
|
||||||
if len(ms) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
|
|
||||||
// get existing milestones
|
|
||||||
existingMilestones := make([]*issues_model.Milestone, 0)
|
|
||||||
if err = sess.Where("repo_id = ?", ms[0].RepoID).Find(&existingMilestones); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
milestonesToAdd := make([]*issues_model.Milestone, 0)
|
|
||||||
milestonesToUpdate := make([]*issues_model.Milestone, 0)
|
|
||||||
milestonesToDelete := make([]*issues_model.Milestone, 0)
|
|
||||||
foundMap := make(map[int64]bool)
|
|
||||||
|
|
||||||
openCount := 0
|
|
||||||
closedCount := 0
|
|
||||||
|
|
||||||
for _, m := range ms {
|
|
||||||
var foundMilestone *issues_model.Milestone
|
|
||||||
for _, existingMilestone := range existingMilestones {
|
|
||||||
if existingMilestone.OriginalID == m.OriginalID {
|
|
||||||
foundMilestone = existingMilestone
|
|
||||||
foundMap[existingMilestone.ID] = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if foundMilestone == nil {
|
|
||||||
milestonesToAdd = append(milestonesToAdd, m)
|
|
||||||
} else if foundMilestone.OriginalID != m.OriginalID {
|
|
||||||
m.ID = foundMilestone.ID
|
|
||||||
milestonesToUpdate = append(milestonesToUpdate, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.IsClosed {
|
|
||||||
closedCount++
|
|
||||||
} else {
|
|
||||||
openCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, existingMilestone := range existingMilestones {
|
|
||||||
if _, exist := foundMap[existingMilestone.ID]; !exist {
|
|
||||||
milestonesToDelete = append(milestonesToDelete, existingMilestone)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(milestonesToAdd) > 0 {
|
|
||||||
if _, err = sess.Insert(milestonesToAdd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, m := range milestonesToUpdate {
|
|
||||||
if _, err = sess.ID(m.ID).AllCols().Update(m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, m := range milestonesToDelete {
|
|
||||||
if _, err = sess.ID(m.ID).Delete(m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = sess.ID(ms[0].RepoID).Update(&repo_model.Repository{
|
|
||||||
NumMilestones: len(ms),
|
|
||||||
NumOpenMilestones: openCount,
|
|
||||||
NumClosedMilestones: closedCount,
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertIssues insert issues to database
|
|
||||||
func InsertIssues(issues ...*issues_model.Issue) error {
|
|
||||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
|
|
||||||
for _, issue := range issues {
|
|
||||||
if err := insertIssue(ctx, issue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolveIssueLabels(issueID int64, labels []*issues_model.Label) []issues_model.IssueLabel {
|
|
||||||
issueLabels := make([]issues_model.IssueLabel, 0, len(labels))
|
|
||||||
for _, label := range labels {
|
|
||||||
issueLabels = append(issueLabels, issues_model.IssueLabel{
|
|
||||||
IssueID: issueID,
|
|
||||||
LabelID: label.ID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return issueLabels
|
|
||||||
}
|
|
||||||
|
|
||||||
func insertIssue(ctx context.Context, issue *issues_model.Issue) error {
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
if _, err := sess.NoAutoTime().Insert(issue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
issueLabels := resolveIssueLabels(issue.ID, issue.Labels)
|
|
||||||
if len(issueLabels) > 0 {
|
|
||||||
if _, err := sess.Insert(issueLabels); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, reaction := range issue.Reactions {
|
|
||||||
reaction.IssueID = issue.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(issue.Reactions) > 0 {
|
|
||||||
if _, err := sess.Insert(issue.Reactions); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpsertIssues creates new issues and updates existing issues in database
|
|
||||||
func UpsertIssues(ctx context.Context, issues ...*issues_model.Issue) error {
|
|
||||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
|
||||||
for _, issue := range issues {
|
|
||||||
if _, err := upsertIssue(ctx, issue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateIssue(ctx context.Context, issue *issues_model.Issue) error {
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
if _, err := sess.NoAutoTime().ID(issue.ID).AllCols().Update(issue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
issueLabels := resolveIssueLabels(issue.ID, issue.Labels)
|
|
||||||
if len(issueLabels) > 0 {
|
|
||||||
// delete old labels
|
|
||||||
if _, err := sess.Table("issue_label").Where("issue_id = ?", issue.ID).Delete(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// insert new labels
|
|
||||||
if _, err := sess.Insert(issueLabels); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, reaction := range issue.Reactions {
|
|
||||||
reaction.IssueID = issue.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(issue.Reactions) > 0 {
|
|
||||||
// update existing reactions and insert new ones
|
|
||||||
for _, reaction := range issue.Reactions {
|
|
||||||
exists, err := sess.Exist(&issues_model.Reaction{ID: reaction.ID})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if exists {
|
|
||||||
if _, err := sess.ID(reaction.ID).AllCols().Update(&reaction); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err := sess.Insert(&reaction); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func upsertIssue(ctx context.Context, issue *issues_model.Issue) (isInsert bool, err error) {
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
|
|
||||||
var issueIDs []int64
|
|
||||||
err = sess.Table("issue").Where("repo_id = ? AND `index` = ?", issue.RepoID, issue.Index).Cols("id").Find(&issueIDs)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(issueIDs) == 0 {
|
|
||||||
return true, insertIssue(ctx, issue)
|
|
||||||
}
|
|
||||||
|
|
||||||
issue.ID = issueIDs[0]
|
|
||||||
return false, updateIssue(ctx, issue)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertIssueComments inserts many comments of issues.
|
|
||||||
func InsertIssueComments(comments []*issues_model.Comment) error {
|
|
||||||
if len(comments) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
issueIDs := make(container.Set[int64])
|
|
||||||
for _, comment := range comments {
|
|
||||||
issueIDs.Add(comment.IssueID)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
for _, comment := range comments {
|
|
||||||
if _, err := db.GetEngine(ctx).NoAutoTime().Insert(comment); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, reaction := range comment.Reactions {
|
|
||||||
reaction.IssueID = comment.IssueID
|
|
||||||
reaction.CommentID = comment.ID
|
|
||||||
}
|
|
||||||
if len(comment.Reactions) > 0 {
|
|
||||||
if err := db.Insert(ctx, comment.Reactions); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for issueID := range issueIDs {
|
|
||||||
if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?",
|
|
||||||
issueID, issues_model.CommentTypeComment, issueID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpsertIssueComments inserts many comments of issues.
|
|
||||||
func UpsertIssueComments(ctx context.Context, comments []*issues_model.Comment) error {
|
|
||||||
if len(comments) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
issueIDs := make(map[int64]bool)
|
|
||||||
for _, comment := range comments {
|
|
||||||
issueIDs[comment.IssueID] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
for _, comment := range comments {
|
|
||||||
exists, err := sess.Exist(&issues_model.Comment{
|
|
||||||
IssueID: comment.IssueID,
|
|
||||||
OriginalID: comment.OriginalID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !exists {
|
|
||||||
if _, err := sess.NoAutoTime().Insert(comment); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err := sess.NoAutoTime().Where(
|
|
||||||
"issue_id = ? AND original_id = ?", comment.IssueID, comment.OriginalID,
|
|
||||||
).AllCols().Update(comment); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, reaction := range comment.Reactions {
|
|
||||||
reaction.IssueID = comment.IssueID
|
|
||||||
reaction.CommentID = comment.ID
|
|
||||||
}
|
|
||||||
if len(comment.Reactions) > 0 {
|
|
||||||
for _, reaction := range comment.Reactions {
|
|
||||||
// issue comment reaction is uniquely identified by issue_id, comment_id and type
|
|
||||||
exists, err := sess.Exist(&issues_model.Reaction{
|
|
||||||
IssueID: reaction.IssueID,
|
|
||||||
CommentID: reaction.CommentID,
|
|
||||||
Type: reaction.Type,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if exists {
|
|
||||||
if _, err := sess.Where(
|
|
||||||
"issue_id = ? AND comment_id = ? AND type = ?",
|
|
||||||
reaction.IssueID, reaction.CommentID, reaction.Type,
|
|
||||||
).AllCols().Update(&reaction); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err := sess.Insert(&reaction); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for issueID := range issueIDs {
|
|
||||||
if _, err := db.Exec(ctx, "UPDATE issue SET num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?",
|
|
||||||
issueID, issues_model.CommentTypeComment, issueID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertPullRequests inserted pull requests
|
|
||||||
func InsertPullRequests(ctx context.Context, prs ...*issues_model.PullRequest) error {
|
|
||||||
ctx, committer, err := db.TxContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
for _, pr := range prs {
|
|
||||||
if err := insertIssue(ctx, pr.Issue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pr.IssueID = pr.Issue.ID
|
|
||||||
if _, err := sess.NoAutoTime().Insert(pr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpsertPullRequests inserts new pull requests and updates existing pull requests in database
|
|
||||||
func UpsertPullRequests(ctx context.Context, prs ...*issues_model.PullRequest) error {
|
|
||||||
if len(prs) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
for _, pr := range prs {
|
|
||||||
isInsert, err := upsertIssue(ctx, pr.Issue)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pr.IssueID = pr.Issue.ID
|
|
||||||
|
|
||||||
if isInsert {
|
|
||||||
if _, err := sess.NoAutoTime().Insert(pr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err := sess.NoAutoTime().ID(pr.ID).AllCols().Update(pr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertReleases migrates release
|
|
||||||
func InsertReleases(rels ...*repo_model.Release) error {
|
|
||||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
|
|
||||||
for _, rel := range rels {
|
|
||||||
if _, err := sess.NoAutoTime().Insert(rel); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rel.Attachments) > 0 {
|
|
||||||
for i := range rel.Attachments {
|
|
||||||
rel.Attachments[i].ReleaseID = rel.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := sess.NoAutoTime().Insert(rel.Attachments); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpsertReleases inserts new releases and updates existing releases
|
|
||||||
func UpsertReleases(rels ...*repo_model.Release) error {
|
|
||||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
sess := db.GetEngine(ctx)
|
|
||||||
|
|
||||||
for _, rel := range rels {
|
|
||||||
exists, err := sess.Where("repo_id = ? AND tag_name = ?", rel.RepoID, rel.TagName).Exist(&repo_model.Release{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !exists {
|
|
||||||
if _, err := sess.NoAutoTime().Insert(rel); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rel.Attachments) > 0 {
|
|
||||||
for i := range rel.Attachments {
|
|
||||||
rel.Attachments[i].ReleaseID = rel.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := sess.NoAutoTime().Insert(rel.Attachments); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err := sess.NoAutoTime().
|
|
||||||
Where("repo_id = ? AND tag_name = ?", rel.RepoID, rel.TagName).
|
|
||||||
AllCols().Update(rel); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rel.Attachments) > 0 {
|
|
||||||
for i := range rel.Attachments {
|
|
||||||
rel.Attachments[i].ReleaseID = rel.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
var existingReleases []*repo_model.Attachment
|
|
||||||
err := sess.Where("release_id = ?", rel.ID).Find(&existingReleases)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := sess.NoAutoTime().Insert(rel.Attachments); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var ids []int64
|
|
||||||
for _, existingRelease := range existingReleases {
|
|
||||||
// TODO: file operations are not atomic, so errors should be handled
|
|
||||||
err = storage.Attachments.Delete(existingRelease.RelativePath())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ids = append(ids, existingRelease.ID)
|
|
||||||
}
|
|
||||||
if _, err := sess.NoAutoTime().In("id", ids).Delete(&repo_model.Attachment{}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID
|
|
||||||
func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, userID int64) error {
|
|
||||||
if err := issues_model.UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := issues_model.UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := repo_model.UpdateReleasesMigrationsByType(tp, externalUserID, userID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := issues_model.UpdateReactionsMigrationsByType(tp, externalUserID, userID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return issues_model.UpdateReviewsMigrationsByType(tp, externalUserID, userID)
|
|
||||||
}
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/container"
|
"code.gitea.io/gitea/modules/container"
|
||||||
|
"code.gitea.io/gitea/modules/storage"
|
||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
@ -580,3 +581,74 @@ func InsertReleases(ctx context.Context, rels ...*Release) error {
|
||||||
|
|
||||||
return committer.Commit()
|
return committer.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpsertReleases inserts new releases and updates existing releases
|
||||||
|
func UpsertReleases(ctx context.Context, rels ...*Release) error {
|
||||||
|
ctx, committer, err := db.TxContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer committer.Close()
|
||||||
|
sess := db.GetEngine(ctx)
|
||||||
|
|
||||||
|
for _, rel := range rels {
|
||||||
|
exists, err := sess.Where("repo_id = ? AND tag_name = ?", rel.RepoID, rel.TagName).Exist(&Release{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
if _, err := sess.NoAutoTime().Insert(rel); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(rel.Attachments) > 0 {
|
||||||
|
for i := range rel.Attachments {
|
||||||
|
rel.Attachments[i].ReleaseID = rel.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := sess.NoAutoTime().Insert(rel.Attachments); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := sess.NoAutoTime().
|
||||||
|
Where("repo_id = ? AND tag_name = ?", rel.RepoID, rel.TagName).
|
||||||
|
AllCols().Update(rel); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(rel.Attachments) > 0 {
|
||||||
|
for i := range rel.Attachments {
|
||||||
|
rel.Attachments[i].ReleaseID = rel.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingReleases []*Attachment
|
||||||
|
err := sess.Where("release_id = ?", rel.ID).Find(&existingReleases)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := sess.NoAutoTime().Insert(rel.Attachments); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids []int64
|
||||||
|
for _, existingRelease := range existingReleases {
|
||||||
|
// TODO: file operations are not atomic, so errors should be handled
|
||||||
|
err = storage.Attachments.Delete(existingRelease.RelativePath())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ids = append(ids, existingRelease.ID)
|
||||||
|
}
|
||||||
|
if _, err := sess.NoAutoTime().In("id", ids).Delete(&Attachment{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return committer.Commit()
|
||||||
|
}
|
||||||
|
|
|
@ -728,7 +728,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
|
||||||
}
|
}
|
||||||
ctx.Data["CanCompareOrPull"] = canCompare
|
ctx.Data["CanCompareOrPull"] = canCompare
|
||||||
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
|
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
|
||||||
ctx.Data["AllowsIssues"] = repo.AllowsIssues()
|
ctx.Data["AllowsIssues"] = repo.AllowsIssues(ctx)
|
||||||
|
|
||||||
if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer {
|
if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer {
|
||||||
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
|
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
|
||||||
|
|
|
@ -996,7 +996,7 @@ func (g *GiteaLocalUploader) UpdateTopics(topics ...string) error {
|
||||||
|
|
||||||
func (g *GiteaLocalUploader) UpdateMilestones(milestones ...*base.Milestone) error {
|
func (g *GiteaLocalUploader) UpdateMilestones(milestones ...*base.Milestone) error {
|
||||||
mss := g.prepareMilestones(milestones...)
|
mss := g.prepareMilestones(milestones...)
|
||||||
err := models.UpdateMilestones(g.ctx, mss...)
|
err := issues_model.UpdateMilestones(g.ctx, mss...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1025,7 +1025,7 @@ func (g *GiteaLocalUploader) PatchReleases(releases ...*base.Release) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return models.UpsertReleases(rels...)
|
return repo_model.UpsertReleases(g.ctx, rels...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GiteaLocalUploader) PatchIssues(issues ...*base.Issue) error {
|
func (g *GiteaLocalUploader) PatchIssues(issues ...*base.Issue) error {
|
||||||
|
@ -1037,7 +1037,7 @@ func (g *GiteaLocalUploader) PatchIssues(issues ...*base.Issue) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := models.UpsertIssues(g.ctx, iss...); err != nil {
|
if err := issues_model.UpsertIssues(g.ctx, iss...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1056,7 +1056,7 @@ func (g *GiteaLocalUploader) PatchComments(comments ...*base.Comment) error {
|
||||||
if len(cms) == 0 {
|
if len(cms) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return models.UpsertIssueComments(g.ctx, cms)
|
return issues_model.UpsertIssueComments(g.ctx, cms)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GiteaLocalUploader) PatchPullRequests(prs ...*base.PullRequest) error {
|
func (g *GiteaLocalUploader) PatchPullRequests(prs ...*base.PullRequest) error {
|
||||||
|
@ -1064,7 +1064,7 @@ func (g *GiteaLocalUploader) PatchPullRequests(prs ...*base.PullRequest) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := models.UpsertPullRequests(g.ctx, gprs...); err != nil {
|
if err := issues_model.UpsertPullRequests(g.ctx, gprs...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, pr := range gprs {
|
for _, pr := range gprs {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user