2019-03-11 06:44:58 +03: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 migrations
import (
2019-03-20 19:37:50 +03:00
"fmt"
2019-03-11 06:44:58 +03:00
"code.gitea.io/gitea/models"
2019-03-27 12:33:00 +03:00
"code.gitea.io/gitea/modules/git"
2019-03-20 19:37:50 +03:00
2019-10-17 12:26:49 +03:00
"xorm.io/xorm"
2019-03-11 06:44:58 +03:00
)
func fixReleaseSha1OnReleaseTable ( x * xorm . Engine ) error {
type Release struct {
ID int64
RepoID int64
Sha1 string
TagName string
}
2019-03-20 19:37:50 +03:00
type Repository struct {
ID int64
OwnerID int64
Name string
}
type User struct {
ID int64
Name string
}
2019-03-11 06:44:58 +03:00
// Update release sha1
const batchSize = 100
sess := x . NewSession ( )
defer sess . Close ( )
var (
err error
count int
gitRepoCache = make ( map [ int64 ] * git . Repository )
2019-03-20 19:37:50 +03:00
repoCache = make ( map [ int64 ] * Repository )
userCache = make ( map [ int64 ] * User )
2019-03-11 06:44:58 +03:00
)
if err = sess . Begin ( ) ; err != nil {
return err
}
for start := 0 ; ; start += batchSize {
releases := make ( [ ] * Release , 0 , batchSize )
if err = sess . Limit ( batchSize , start ) . Asc ( "id" ) . Where ( "is_tag=?" , false ) . Find ( & releases ) ; err != nil {
return err
}
if len ( releases ) == 0 {
break
}
for _ , release := range releases {
gitRepo , ok := gitRepoCache [ release . RepoID ]
if ! ok {
repo , ok := repoCache [ release . RepoID ]
if ! ok {
2019-03-20 19:37:50 +03:00
repo = new ( Repository )
has , err := sess . ID ( release . RepoID ) . Get ( repo )
2019-03-11 06:44:58 +03:00
if err != nil {
return err
2019-03-20 19:37:50 +03:00
} else if ! has {
return fmt . Errorf ( "Repository %d is not exist" , release . RepoID )
2019-03-11 06:44:58 +03:00
}
2019-03-20 19:37:50 +03:00
2019-03-11 06:44:58 +03:00
repoCache [ release . RepoID ] = repo
}
2019-03-20 19:37:50 +03:00
user , ok := userCache [ repo . OwnerID ]
if ! ok {
user = new ( User )
has , err := sess . ID ( repo . OwnerID ) . Get ( user )
if err != nil {
return err
} else if ! has {
return fmt . Errorf ( "User %d is not exist" , repo . OwnerID )
}
userCache [ repo . OwnerID ] = user
}
gitRepo , err = git . OpenRepository ( models . RepoPath ( user . Name , repo . Name ) )
2019-03-11 06:44:58 +03:00
if err != nil {
return err
}
2019-11-13 10:01:19 +03:00
defer gitRepo . Close ( )
2019-03-11 06:44:58 +03:00
gitRepoCache [ release . RepoID ] = gitRepo
}
release . Sha1 , err = gitRepo . GetTagCommitID ( release . TagName )
2019-03-20 19:37:50 +03:00
if err != nil && ! git . IsErrNotExist ( err ) {
2019-03-11 06:44:58 +03:00
return err
}
2019-03-20 19:37:50 +03:00
if err == nil {
if _ , err = sess . ID ( release . ID ) . Cols ( "sha1" ) . Update ( release ) ; err != nil {
return err
}
2019-03-11 06:44:58 +03:00
}
count ++
if count >= 1000 {
if err = sess . Commit ( ) ; err != nil {
return err
}
if err = sess . Begin ( ) ; err != nil {
return err
}
count = 0
}
}
}
return sess . Commit ( )
}