2017-02-07 17:17:55 +05:30
// Copyright 2017 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
import (
2021-11-18 11:28:42 +05:30
admin_model "code.gitea.io/gitea/models/admin"
2021-09-19 17:19:59 +05:30
"code.gitea.io/gitea/models/db"
2021-12-10 06:57:50 +05:30
repo_model "code.gitea.io/gitea/models/repo"
2021-11-24 15:19:20 +05:30
user_model "code.gitea.io/gitea/models/user"
2022-05-10 06:19:01 +05:30
"code.gitea.io/gitea/modules/setting"
2021-11-12 06:26:45 +05:30
2020-05-29 18:54:15 +05:30
"xorm.io/builder"
2017-02-07 17:17:55 +05:30
)
2020-05-29 18:54:15 +05:30
// CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore
func CountOrphanedLabels ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
noref , err := db . GetEngine ( db . DefaultContext ) . Table ( "label" ) . Where ( "repo_id=? AND org_id=?" , 0 , 0 ) . Count ( "label.id" )
2020-05-29 18:54:15 +05:30
if err != nil {
return 0 , err
}
2021-09-23 21:15:36 +05:30
norepo , err := db . GetEngine ( db . DefaultContext ) . Table ( "label" ) .
2021-06-08 10:06:23 +05:30
Where ( builder . And (
builder . Gt { "repo_id" : 0 } ,
builder . NotIn ( "repo_id" , builder . Select ( "id" ) . From ( "repository" ) ) ,
) ) .
Count ( )
2020-05-29 18:54:15 +05:30
if err != nil {
return 0 , err
}
2021-09-23 21:15:36 +05:30
noorg , err := db . GetEngine ( db . DefaultContext ) . Table ( "label" ) .
2021-06-08 10:06:23 +05:30
Where ( builder . And (
builder . Gt { "org_id" : 0 } ,
builder . NotIn ( "org_id" , builder . Select ( "id" ) . From ( "user" ) ) ,
) ) .
Count ( )
2020-05-29 18:54:15 +05:30
if err != nil {
return 0 , err
}
return noref + norepo + noorg , nil
}
// DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore
func DeleteOrphanedLabels ( ) error {
// delete labels with no reference
2021-09-23 21:15:36 +05:30
if _ , err := db . GetEngine ( db . DefaultContext ) . Table ( "label" ) . Where ( "repo_id=? AND org_id=?" , 0 , 0 ) . Delete ( new ( Label ) ) ; err != nil {
2020-05-29 18:54:15 +05:30
return err
}
// delete labels with none existing repos
2021-09-23 21:15:36 +05:30
if _ , err := db . GetEngine ( db . DefaultContext ) .
2021-06-08 10:06:23 +05:30
Where ( builder . And (
builder . Gt { "repo_id" : 0 } ,
builder . NotIn ( "repo_id" , builder . Select ( "id" ) . From ( "repository" ) ) ,
) ) .
2020-05-29 18:54:15 +05:30
Delete ( Label { } ) ; err != nil {
return err
}
// delete labels with none existing orgs
2021-09-23 21:15:36 +05:30
if _ , err := db . GetEngine ( db . DefaultContext ) .
2021-06-08 10:06:23 +05:30
Where ( builder . And (
builder . Gt { "org_id" : 0 } ,
builder . NotIn ( "org_id" , builder . Select ( "id" ) . From ( "user" ) ) ,
) ) .
2020-05-29 18:54:15 +05:30
Delete ( Label { } ) ; err != nil {
return err
}
return nil
}
2021-03-20 00:31:24 +05:30
// CountOrphanedIssueLabels return count of IssueLabels witch have no label behind anymore
func CountOrphanedIssueLabels ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
return db . GetEngine ( db . DefaultContext ) . Table ( "issue_label" ) .
2021-06-08 10:06:23 +05:30
NotIn ( "label_id" , builder . Select ( "id" ) . From ( "label" ) ) .
Count ( )
2021-03-20 00:31:24 +05:30
}
// DeleteOrphanedIssueLabels delete IssueLabels witch have no label behind anymore
func DeleteOrphanedIssueLabels ( ) error {
2021-09-23 21:15:36 +05:30
_ , err := db . GetEngine ( db . DefaultContext ) .
2021-06-08 10:06:23 +05:30
NotIn ( "label_id" , builder . Select ( "id" ) . From ( "label" ) ) .
2021-03-20 00:31:24 +05:30
Delete ( IssueLabel { } )
return err
}
2020-05-29 18:54:15 +05:30
// CountOrphanedIssues count issues without a repo
func CountOrphanedIssues ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
return db . GetEngine ( db . DefaultContext ) . Table ( "issue" ) .
2020-05-29 18:54:15 +05:30
Join ( "LEFT" , "repository" , "issue.repo_id=repository.id" ) .
Where ( builder . IsNull { "repository.id" } ) .
2022-06-05 00:48:50 +05:30
Select ( "COUNT(`issue`.`id`)" ) .
Count ( )
2020-05-29 18:54:15 +05:30
}
// DeleteOrphanedIssues delete issues without a repo
func DeleteOrphanedIssues ( ) error {
2021-09-19 17:19:59 +05:30
ctx , committer , err := db . TxContext ( )
if err != nil {
2020-05-29 18:54:15 +05:30
return err
}
2021-09-19 17:19:59 +05:30
defer committer . Close ( )
2020-05-29 18:54:15 +05:30
var ids [ ] int64
2021-09-23 21:15:36 +05:30
if err := db . GetEngine ( ctx ) . Table ( "issue" ) . Distinct ( "issue.repo_id" ) .
2020-05-29 18:54:15 +05:30
Join ( "LEFT" , "repository" , "issue.repo_id=repository.id" ) .
Where ( builder . IsNull { "repository.id" } ) . GroupBy ( "issue.repo_id" ) .
Find ( & ids ) ; err != nil {
return err
}
var attachmentPaths [ ] string
for i := range ids {
2022-05-20 19:38:52 +05:30
paths , err := deleteIssuesByRepoID ( ctx , ids [ i ] )
2020-05-29 18:54:15 +05:30
if err != nil {
return err
}
attachmentPaths = append ( attachmentPaths , paths ... )
}
2021-09-19 17:19:59 +05:30
if err := committer . Commit ( ) ; err != nil {
2020-05-29 18:54:15 +05:30
return err
}
2021-09-19 17:19:59 +05:30
committer . Close ( )
2020-05-29 18:54:15 +05:30
// Remove issue attachment files.
for i := range attachmentPaths {
2021-11-18 23:12:27 +05:30
admin_model . RemoveAllWithNotice ( db . DefaultContext , "Delete issue attachment" , attachmentPaths [ i ] )
2020-05-29 18:54:15 +05:30
}
return nil
}
// CountOrphanedObjects count subjects with have no existing refobject anymore
func CountOrphanedObjects ( subject , refobject , joinCond string ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
return db . GetEngine ( db . DefaultContext ) . Table ( "`" + subject + "`" ) .
2021-10-30 14:47:40 +05:30
Join ( "LEFT" , "`" + refobject + "`" , joinCond ) .
2020-05-29 18:54:15 +05:30
Where ( builder . IsNull { "`" + refobject + "`.id" } ) .
2022-06-05 00:48:50 +05:30
Select ( "COUNT(`" + subject + "`.`id`)" ) .
Count ( )
2020-05-29 18:54:15 +05:30
}
// DeleteOrphanedObjects delete subjects with have no existing refobject anymore
func DeleteOrphanedObjects ( subject , refobject , joinCond string ) error {
2021-04-30 23:38:46 +05:30
subQuery := builder . Select ( "`" + subject + "`.id" ) .
2020-05-29 18:54:15 +05:30
From ( "`" + subject + "`" ) .
Join ( "LEFT" , "`" + refobject + "`" , joinCond ) .
2021-04-30 23:38:46 +05:30
Where ( builder . IsNull { "`" + refobject + "`.id" } )
sql , args , err := builder . Delete ( builder . In ( "id" , subQuery ) ) . From ( "`" + subject + "`" ) . ToSQL ( )
if err != nil {
return err
}
2021-09-23 21:15:36 +05:30
_ , err = db . GetEngine ( db . DefaultContext ) . Exec ( append ( [ ] interface { } { sql } , args ... ) ... )
2020-05-29 18:54:15 +05:30
return err
}
2020-06-12 01:48:11 +05:30
// CountNullArchivedRepository counts the number of repositories with is_archived is null
func CountNullArchivedRepository ( ) ( int64 , error ) {
2021-12-10 06:57:50 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( builder . IsNull { "is_archived" } ) . Count ( new ( repo_model . Repository ) )
2020-06-12 01:48:11 +05:30
}
// FixNullArchivedRepository sets is_archived to false where it is null
func FixNullArchivedRepository ( ) ( int64 , error ) {
2021-12-10 06:57:50 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( builder . IsNull { "is_archived" } ) . Cols ( "is_archived" ) . NoAutoTime ( ) . Update ( & repo_model . Repository {
2020-06-12 01:48:11 +05:30
IsArchived : false ,
} )
}
2021-01-30 00:00:43 +05:30
// CountWrongUserType count OrgUser who have wrong type
func CountWrongUserType ( ) ( int64 , error ) {
2021-11-24 15:19:20 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( builder . Eq { "type" : 0 } . And ( builder . Neq { "num_teams" : 0 } ) ) . Count ( new ( user_model . User ) )
2021-01-30 00:00:43 +05:30
}
// FixWrongUserType fix OrgUser who have wrong type
func FixWrongUserType ( ) ( int64 , error ) {
2021-11-24 15:19:20 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( builder . Eq { "type" : 0 } . And ( builder . Neq { "num_teams" : 0 } ) ) . Cols ( "type" ) . NoAutoTime ( ) . Update ( & user_model . User { Type : 1 } )
2021-01-30 00:00:43 +05:30
}
2021-02-10 08:20:44 +05:30
// CountCommentTypeLabelWithEmptyLabel count label comments with empty label
func CountCommentTypeLabelWithEmptyLabel ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( builder . Eq { "type" : CommentTypeLabel , "label_id" : 0 } ) . Count ( new ( Comment ) )
2021-02-10 08:20:44 +05:30
}
// FixCommentTypeLabelWithEmptyLabel count label comments with empty label
func FixCommentTypeLabelWithEmptyLabel ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( builder . Eq { "type" : CommentTypeLabel , "label_id" : 0 } ) . Delete ( new ( Comment ) )
2021-02-10 08:20:44 +05:30
}
2021-03-18 11:36:40 +05:30
2021-03-19 18:55:14 +05:30
// CountCommentTypeLabelWithOutsideLabels count label comments with outside label
func CountCommentTypeLabelWithOutsideLabels ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( "comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))" , CommentTypeLabel ) .
2021-03-19 18:55:14 +05:30
Table ( "comment" ) .
Join ( "inner" , "label" , "label.id = comment.label_id" ) .
Join ( "inner" , "issue" , "issue.id = comment.issue_id " ) .
Join ( "inner" , "repository" , "issue.repo_id = repository.id" ) .
Count ( new ( Comment ) )
}
// FixCommentTypeLabelWithOutsideLabels count label comments with outside label
func FixCommentTypeLabelWithOutsideLabels ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
res , err := db . GetEngine ( db . DefaultContext ) . Exec ( ` DELETE FROM comment WHERE comment . id IN (
2021-03-19 18:55:14 +05:30
SELECT il_too . id FROM (
SELECT com . id
FROM comment AS com
INNER JOIN label ON com . label_id = label . id
INNER JOIN issue on issue . id = com . issue_id
2021-03-24 04:40:19 +05:30
INNER JOIN repository ON issue . repo_id = repository . id
2021-03-19 18:55:14 +05:30
WHERE
2021-03-24 04:40:19 +05:30
com . type = ? AND ( ( label . org_id = 0 AND issue . repo_id != label . repo_id ) OR ( label . repo_id = 0 AND label . org_id != repository . owner_id ) )
2021-03-19 18:55:14 +05:30
) AS il_too ) ` , CommentTypeLabel )
if err != nil {
return 0 , err
}
return res . RowsAffected ( )
}
// CountIssueLabelWithOutsideLabels count label comments with outside label
func CountIssueLabelWithOutsideLabels ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
return db . GetEngine ( db . DefaultContext ) . Where ( builder . Expr ( "(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)" ) ) .
2021-03-19 18:55:14 +05:30
Table ( "issue_label" ) .
2021-03-23 15:53:33 +05:30
Join ( "inner" , "label" , "issue_label.label_id = label.id " ) .
2021-03-19 18:55:14 +05:30
Join ( "inner" , "issue" , "issue.id = issue_label.issue_id " ) .
Join ( "inner" , "repository" , "issue.repo_id = repository.id" ) .
Count ( new ( IssueLabel ) )
}
// FixIssueLabelWithOutsideLabels fix label comments with outside label
func FixIssueLabelWithOutsideLabels ( ) ( int64 , error ) {
2021-09-23 21:15:36 +05:30
res , err := db . GetEngine ( db . DefaultContext ) . Exec ( ` DELETE FROM issue_label WHERE issue_label . id IN (
2021-03-19 18:55:14 +05:30
SELECT il_too . id FROM (
SELECT il_too_too . id
FROM issue_label AS il_too_too
2021-03-22 23:56:38 +05:30
INNER JOIN label ON il_too_too . label_id = label . id
2021-03-19 18:55:14 +05:30
INNER JOIN issue on issue . id = il_too_too . issue_id
INNER JOIN repository on repository . id = issue . repo_id
WHERE
2021-03-24 04:40:19 +05:30
( label . org_id = 0 AND issue . repo_id != label . repo_id ) OR ( label . repo_id = 0 AND label . org_id != repository . owner_id )
2021-03-19 18:55:14 +05:30
) AS il_too ) ` )
if err != nil {
return 0 , err
}
return res . RowsAffected ( )
}
2022-05-10 06:19:01 +05:30
// CountActionCreatedUnixString count actions where created_unix is an empty string
func CountActionCreatedUnixString ( ) ( int64 , error ) {
if setting . Database . UseSQLite3 {
return db . GetEngine ( db . DefaultContext ) . Where ( ` created_unix = "" ` ) . Count ( new ( Action ) )
}
return 0 , nil
}
// FixActionCreatedUnixString set created_unix to zero if it is an empty string
func FixActionCreatedUnixString ( ) ( int64 , error ) {
if setting . Database . UseSQLite3 {
res , err := db . GetEngine ( db . DefaultContext ) . Exec ( ` UPDATE action SET created_unix = 0 WHERE created_unix = "" ` )
if err != nil {
return 0 , err
}
return res . RowsAffected ( )
}
return 0 , nil
}