2019-05-07 09:12:51 +08:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
2020-01-24 01:28:15 +08:00
import (
2021-09-19 19:49:59 +08:00
"code.gitea.io/gitea/models/db"
2020-01-24 01:28:15 +08:00
"code.gitea.io/gitea/modules/structs"
"xorm.io/builder"
)
2019-05-07 09:12:51 +08:00
2019-06-29 21:38:22 +08:00
// InsertMilestones creates milestones of repository.
func InsertMilestones ( ms ... * Milestone ) ( err error ) {
if len ( ms ) == 0 {
return nil
}
2021-11-21 23:41:00 +08:00
ctx , committer , err := db . TxContext ( )
if err != nil {
2019-05-07 09:12:51 +08:00
return err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
sess := db . GetEngine ( ctx )
2019-05-07 09:12:51 +08:00
2019-06-29 21:38:22 +08:00
// 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
}
}
2021-11-21 23:41:00 +08:00
if _ , err = db . Exec ( ctx , "UPDATE `repository` SET num_milestones = num_milestones + ? WHERE id = ?" , len ( ms ) , ms [ 0 ] . RepoID ) ; err != nil {
2019-05-07 09:12:51 +08:00
return err
}
2021-11-21 23:41:00 +08:00
return committer . Commit ( )
2019-05-07 09:12:51 +08:00
}
2019-06-29 21:38:22 +08:00
// InsertIssues insert issues to database
func InsertIssues ( issues ... * Issue ) error {
2021-11-21 23:41:00 +08:00
ctx , committer , err := db . TxContext ( )
if err != nil {
2019-06-29 21:38:22 +08:00
return err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
2019-06-29 21:38:22 +08:00
for _ , issue := range issues {
2021-11-21 23:41:00 +08:00
if err := insertIssue ( db . GetEngine ( ctx ) , issue ) ; err != nil {
2019-05-07 09:12:51 +08:00
return err
}
}
2021-11-21 23:41:00 +08:00
return committer . Commit ( )
2019-06-29 21:38:22 +08:00
}
2021-11-21 23:41:00 +08:00
func insertIssue ( sess db . Engine , issue * Issue ) error {
2019-05-07 09:12:51 +08:00
if _ , err := sess . NoAutoTime ( ) . Insert ( issue ) ; err != nil {
return err
}
2021-03-15 02:52:12 +08:00
issueLabels := make ( [ ] IssueLabel , 0 , len ( issue . Labels ) )
labelIDs := make ( [ ] int64 , 0 , len ( issue . Labels ) )
2019-06-29 21:38:22 +08:00
for _ , label := range issue . Labels {
2019-05-07 09:12:51 +08:00
issueLabels = append ( issueLabels , IssueLabel {
IssueID : issue . ID ,
2019-06-29 21:38:22 +08:00
LabelID : label . ID ,
2019-05-07 09:12:51 +08:00
} )
2019-06-29 21:38:22 +08:00
labelIDs = append ( labelIDs , label . ID )
2019-05-07 09:12:51 +08:00
}
2020-04-18 01:42:57 +08:00
if len ( issueLabels ) > 0 {
if _ , err := sess . Insert ( issueLabels ) ; err != nil {
return err
}
2019-05-07 09:12:51 +08:00
}
2019-08-04 02:38:42 +08:00
2020-01-15 19:14:07 +08:00
for _ , reaction := range issue . Reactions {
reaction . IssueID = issue . ID
}
2020-04-18 01:42:57 +08:00
if len ( issue . Reactions ) > 0 {
if _ , err := sess . Insert ( issue . Reactions ) ; err != nil {
return err
}
2020-01-15 19:14:07 +08:00
}
2019-08-04 02:38:42 +08:00
cols := make ( [ ] string , 0 )
2019-05-07 09:12:51 +08:00
if ! issue . IsPull {
sess . ID ( issue . RepoID ) . Incr ( "num_issues" )
2019-08-04 02:38:42 +08:00
cols = append ( cols , "num_issues" )
2019-05-07 09:12:51 +08:00
if issue . IsClosed {
sess . Incr ( "num_closed_issues" )
2019-08-04 02:38:42 +08:00
cols = append ( cols , "num_closed_issues" )
2019-05-07 09:12:51 +08:00
}
} else {
sess . ID ( issue . RepoID ) . Incr ( "num_pulls" )
2019-08-04 02:38:42 +08:00
cols = append ( cols , "num_pulls" )
2019-05-07 09:12:51 +08:00
if issue . IsClosed {
sess . Incr ( "num_closed_pulls" )
2019-08-04 02:38:42 +08:00
cols = append ( cols , "num_closed_pulls" )
2019-05-07 09:12:51 +08:00
}
}
2019-08-04 02:38:42 +08:00
if _ , err := sess . NoAutoTime ( ) . Cols ( cols ... ) . Update ( issue . Repo ) ; err != nil {
2019-05-07 09:12:51 +08:00
return err
}
2019-08-04 02:38:42 +08:00
cols = [ ] string { "num_issues" }
2019-05-07 09:12:51 +08:00
sess . Incr ( "num_issues" )
if issue . IsClosed {
sess . Incr ( "num_closed_issues" )
2019-08-04 02:38:42 +08:00
cols = append ( cols , "num_closed_issues" )
2019-05-07 09:12:51 +08:00
}
2019-08-04 02:38:42 +08:00
if _ , err := sess . In ( "id" , labelIDs ) . NoAutoTime ( ) . Cols ( cols ... ) . Update ( new ( Label ) ) ; err != nil {
2019-05-07 09:12:51 +08:00
return err
}
if issue . MilestoneID > 0 {
2019-08-04 02:38:42 +08:00
cols = [ ] string { "num_issues" }
2019-06-29 21:38:22 +08:00
sess . Incr ( "num_issues" )
2019-08-04 02:38:42 +08:00
cl := "num_closed_issues"
2019-06-29 21:38:22 +08:00
if issue . IsClosed {
sess . Incr ( "num_closed_issues" )
2019-08-04 02:38:42 +08:00
cols = append ( cols , "num_closed_issues" )
cl = "(num_closed_issues + 1)"
2019-06-29 21:38:22 +08:00
}
if _ , err := sess . ID ( issue . MilestoneID ) .
2019-08-04 02:38:42 +08:00
SetExpr ( "completeness" , cl + " * 100 / (num_issues + 1)" ) .
NoAutoTime ( ) . Cols ( cols ... ) .
2019-06-29 21:38:22 +08:00
Update ( new ( Milestone ) ) ; err != nil {
2019-05-07 09:12:51 +08:00
return err
}
}
return nil
}
2019-06-29 21:38:22 +08:00
// InsertIssueComments inserts many comments of issues.
func InsertIssueComments ( comments [ ] * Comment ) error {
if len ( comments ) == 0 {
return nil
}
2021-03-15 02:52:12 +08:00
issueIDs := make ( map [ int64 ] bool )
2019-06-29 21:38:22 +08:00
for _ , comment := range comments {
issueIDs [ comment . IssueID ] = true
}
2021-11-21 23:41:00 +08:00
ctx , committer , err := db . TxContext ( )
if err != nil {
2019-05-07 09:12:51 +08:00
return err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
2020-01-15 19:14:07 +08:00
for _ , comment := range comments {
2021-11-21 23:41:00 +08:00
if _ , err := db . GetEngine ( ctx ) . NoAutoTime ( ) . Insert ( comment ) ; err != nil {
2020-01-15 19:14:07 +08:00
return err
}
for _ , reaction := range comment . Reactions {
reaction . IssueID = comment . IssueID
reaction . CommentID = comment . ID
}
2020-04-18 01:42:57 +08:00
if len ( comment . Reactions ) > 0 {
2021-11-21 23:41:00 +08:00
if err := db . Insert ( ctx , comment . Reactions ) ; err != nil {
2020-04-18 01:42:57 +08:00
return err
}
2020-01-15 19:14:07 +08:00
}
2019-05-07 09:12:51 +08:00
}
2020-01-15 19:14:07 +08:00
2019-06-29 21:38:22 +08:00
for issueID := range issueIDs {
2022-01-03 23:35:01 +08:00
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 {
2019-06-29 21:38:22 +08:00
return err
}
2019-05-07 09:12:51 +08:00
}
2021-11-21 23:41:00 +08:00
return committer . Commit ( )
2019-05-07 09:12:51 +08:00
}
2019-06-29 21:38:22 +08:00
// InsertPullRequests inserted pull requests
func InsertPullRequests ( prs ... * PullRequest ) error {
2021-11-21 23:41:00 +08:00
ctx , committer , err := db . TxContext ( )
if err != nil {
2019-05-07 09:12:51 +08:00
return err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
sess := db . GetEngine ( ctx )
2019-06-29 21:38:22 +08:00
for _ , pr := range prs {
if err := insertIssue ( sess , pr . Issue ) ; err != nil {
return err
}
pr . IssueID = pr . Issue . ID
if _ , err := sess . NoAutoTime ( ) . Insert ( pr ) ; err != nil {
return err
}
2019-05-07 09:12:51 +08:00
}
2019-06-29 21:38:22 +08:00
2021-11-21 23:41:00 +08:00
return committer . Commit ( )
2019-05-07 09:12:51 +08:00
}
2019-06-29 21:38:22 +08:00
// InsertReleases migrates release
func InsertReleases ( rels ... * Release ) error {
2021-11-21 23:41:00 +08:00
ctx , committer , err := db . TxContext ( )
if err != nil {
2019-05-07 09:12:51 +08:00
return err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
sess := db . GetEngine ( ctx )
2019-05-07 09:12:51 +08:00
2019-06-29 21:38:22 +08:00
for _ , rel := range rels {
2019-05-07 09:12:51 +08:00
if _ , err := sess . NoAutoTime ( ) . Insert ( rel ) ; err != nil {
return err
}
2020-04-18 01:42:57 +08:00
if len ( rel . Attachments ) > 0 {
for i := range rel . Attachments {
rel . Attachments [ i ] . ReleaseID = rel . ID
}
2019-05-07 09:12:51 +08:00
2020-04-18 01:42:57 +08:00
if _ , err := sess . NoAutoTime ( ) . Insert ( rel . Attachments ) ; err != nil {
return err
}
2019-06-29 21:38:22 +08:00
}
2019-05-07 09:12:51 +08:00
}
2021-11-21 23:41:00 +08:00
return committer . Commit ( )
2019-05-07 09:12:51 +08:00
}
2020-01-24 01:28:15 +08:00
2020-02-18 08:42:13 +08:00
func migratedIssueCond ( tp structs . GitServiceType ) builder . Cond {
return builder . In ( "issue_id" ,
builder . Select ( "issue.id" ) .
From ( "issue" ) .
InnerJoin ( "repository" , "issue.repo_id = repository.id" ) .
Where ( builder . Eq {
"repository.original_service_type" : tp ,
} ) ,
)
}
2020-01-24 01:28:15 +08:00
// UpdateReviewsMigrationsByType updates reviews' migrations information via given git service type and original id and poster id
func UpdateReviewsMigrationsByType ( tp structs . GitServiceType , originalAuthorID string , posterID int64 ) error {
2021-09-23 23:45:36 +08:00
_ , err := db . GetEngine ( db . DefaultContext ) . Table ( "review" ) .
2020-02-18 08:42:13 +08:00
Where ( "original_author_id = ?" , originalAuthorID ) .
And ( migratedIssueCond ( tp ) ) .
2020-01-24 01:28:15 +08:00
Update ( map [ string ] interface { } {
2020-02-18 08:42:13 +08:00
"reviewer_id" : posterID ,
2020-01-24 01:28:15 +08:00
"original_author" : "" ,
"original_author_id" : 0 ,
} )
return err
}
2021-11-28 22:11:58 +08:00
// 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 := UpdateIssuesMigrationsByType ( tp , externalUserID , userID ) ; err != nil {
return err
}
if err := UpdateCommentsMigrationsByType ( tp , externalUserID , userID ) ; err != nil {
return err
}
if err := UpdateReleasesMigrationsByType ( tp , externalUserID , userID ) ; err != nil {
return err
}
if err := UpdateReactionsMigrationsByType ( tp , externalUserID , userID ) ; err != nil {
return err
}
return UpdateReviewsMigrationsByType ( tp , externalUserID , userID )
}