forked from forgejo/forgejo
Split migrations folder (#21549)
There are too many files in `models/migrations` folder so that I split them into sub folders.
This commit is contained in:
parent
4827f42f56
commit
e72acd5e5b
190 changed files with 1711 additions and 1481 deletions
57
models/migrations/v1_13/v140.go
Normal file
57
models/migrations/v1_13/v140.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func FixLanguageStatsToSaveSize(x *xorm.Engine) error {
|
||||
// LanguageStat see models/repo_language_stats.go
|
||||
type LanguageStat struct {
|
||||
Size int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
// RepoIndexerType specifies the repository indexer type
|
||||
type RepoIndexerType int
|
||||
|
||||
const (
|
||||
// RepoIndexerTypeCode code indexer
|
||||
RepoIndexerTypeCode RepoIndexerType = iota // 0
|
||||
// RepoIndexerTypeStats repository stats indexer
|
||||
RepoIndexerTypeStats // 1
|
||||
)
|
||||
|
||||
// RepoIndexerStatus see models/repo_indexer.go
|
||||
type RepoIndexerStatus struct {
|
||||
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(LanguageStat)); err != nil {
|
||||
return fmt.Errorf("Sync2: %w", err)
|
||||
}
|
||||
|
||||
x.Delete(&RepoIndexerStatus{IndexerType: RepoIndexerTypeStats})
|
||||
|
||||
// Delete language stat statuses
|
||||
truncExpr := "TRUNCATE TABLE"
|
||||
if setting.Database.UseSQLite3 {
|
||||
truncExpr = "DELETE FROM"
|
||||
}
|
||||
|
||||
// Delete language stats
|
||||
if _, err := x.Exec(fmt.Sprintf("%s language_stat", truncExpr)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
return base.DropTableColumns(sess, "language_stat", "percentage")
|
||||
}
|
22
models/migrations/v1_13/v141.go
Normal file
22
models/migrations/v1_13/v141.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddKeepActivityPrivateUserColumn(x *xorm.Engine) error {
|
||||
type User struct {
|
||||
KeepActivityPrivate bool `xorm:"NOT NULL DEFAULT false"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(User)); err != nil {
|
||||
return fmt.Errorf("Sync2: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
25
models/migrations/v1_13/v142.go
Normal file
25
models/migrations/v1_13/v142.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func SetIsArchivedToFalse(x *xorm.Engine) error {
|
||||
type Repository struct {
|
||||
IsArchived bool `xorm:"INDEX"`
|
||||
}
|
||||
count, err := x.Where(builder.IsNull{"is_archived"}).Cols("is_archived").Update(&Repository{
|
||||
IsArchived: false,
|
||||
})
|
||||
if err == nil {
|
||||
log.Debug("Updated %d repositories with is_archived IS NULL", count)
|
||||
}
|
||||
return err
|
||||
}
|
52
models/migrations/v1_13/v143.go
Normal file
52
models/migrations/v1_13/v143.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func RecalculateStars(x *xorm.Engine) (err error) {
|
||||
// because of issue https://github.com/go-gitea/gitea/issues/11949,
|
||||
// recalculate Stars number for all users to fully fix it.
|
||||
|
||||
type User struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
}
|
||||
|
||||
const batchSize = 100
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
for start := 0; ; start += batchSize {
|
||||
users := make([]User, 0, batchSize)
|
||||
if err = sess.Limit(batchSize, start).Where("type = ?", 0).Cols("id").Find(&users); err != nil {
|
||||
return
|
||||
}
|
||||
if len(users) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if err = sess.Begin(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE uid=?) WHERE id=?", user.ID, user.ID); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = sess.Commit(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("recalculate Stars number for all user finished")
|
||||
|
||||
return err
|
||||
}
|
26
models/migrations/v1_13/v144.go
Normal file
26
models/migrations/v1_13/v144.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func UpdateMatrixWebhookHTTPMethod(x *xorm.Engine) error {
|
||||
matrixHookTaskType := 9 // value comes from the models package
|
||||
type Webhook struct {
|
||||
HTTPMethod string
|
||||
}
|
||||
|
||||
cond := builder.Eq{"hook_task_type": matrixHookTaskType}.And(builder.Neq{"http_method": "PUT"})
|
||||
count, err := x.Where(cond).Cols("http_method").Update(&Webhook{HTTPMethod: "PUT"})
|
||||
if err == nil {
|
||||
log.Debug("Updated %d Matrix webhooks with http_method 'PUT'", count)
|
||||
}
|
||||
return err
|
||||
}
|
82
models/migrations/v1_13/v145.go
Normal file
82
models/migrations/v1_13/v145.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func IncreaseLanguageField(x *xorm.Engine) error {
|
||||
type LanguageStat struct {
|
||||
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
Language string `xorm:"VARCHAR(50) UNIQUE(s) INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(LanguageStat)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseSQLite3 {
|
||||
// SQLite maps VARCHAR to TEXT without size so we're done
|
||||
return nil
|
||||
}
|
||||
|
||||
// need to get the correct type for the new column
|
||||
inferredTable, err := x.TableInfo(new(LanguageStat))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
column := inferredTable.GetColumn("language")
|
||||
sqlType := x.Dialect().SQLType(column)
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat MODIFY COLUMN language %s", sqlType)); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UseMSSQL:
|
||||
// Yet again MSSQL just has to be awkward.
|
||||
// Here we have to drop the constraints first and then rebuild them
|
||||
constraints := make([]string, 0)
|
||||
if err := sess.SQL(`SELECT i.name AS Name
|
||||
FROM sys.indexes i INNER JOIN sys.index_columns ic
|
||||
ON i.index_id = ic.index_id AND i.object_id = ic.object_id
|
||||
INNER JOIN sys.tables AS t
|
||||
ON t.object_id = i.object_id
|
||||
INNER JOIN sys.columns c
|
||||
ON t.object_id = c.object_id AND ic.column_id = c.column_id
|
||||
WHERE t.name = 'language_stat' AND c.name = 'language'`).Find(&constraints); err != nil {
|
||||
return fmt.Errorf("Find constraints: %w", err)
|
||||
}
|
||||
for _, constraint := range constraints {
|
||||
if _, err := sess.Exec(fmt.Sprintf("DROP INDEX [%s] ON `language_stat`", constraint)); err != nil {
|
||||
return fmt.Errorf("Drop table `language_stat` constraint `%s`: %w", constraint, err)
|
||||
}
|
||||
}
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language %s", sqlType)); err != nil {
|
||||
return err
|
||||
}
|
||||
// Finally restore the constraint
|
||||
if err := sess.CreateUniques(new(LanguageStat)); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UsePostgreSQL:
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language TYPE %s", sqlType)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
84
models/migrations/v1_13/v146.go
Normal file
84
models/migrations/v1_13/v146.go
Normal file
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddProjectsInfo(x *xorm.Engine) error {
|
||||
// Create new tables
|
||||
type (
|
||||
ProjectType uint8
|
||||
ProjectBoardType uint8
|
||||
)
|
||||
|
||||
type Project struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Title string `xorm:"INDEX NOT NULL"`
|
||||
Description string `xorm:"TEXT"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
CreatorID int64 `xorm:"NOT NULL"`
|
||||
IsClosed bool `xorm:"INDEX"`
|
||||
|
||||
BoardType ProjectBoardType
|
||||
Type ProjectType
|
||||
|
||||
ClosedDateUnix timeutil.TimeStamp
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(Project)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type Comment struct {
|
||||
OldProjectID int64
|
||||
ProjectID int64
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(Comment)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
ID int64
|
||||
NumProjects int `xorm:"NOT NULL DEFAULT 0"`
|
||||
NumClosedProjects int `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(Repository)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ProjectIssue saves relation from issue to a project
|
||||
type ProjectIssue struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
IssueID int64 `xorm:"INDEX"`
|
||||
ProjectID int64 `xorm:"INDEX"`
|
||||
ProjectBoardID int64 `xorm:"INDEX"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(ProjectIssue)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type ProjectBoard struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Title string
|
||||
Default bool `xorm:"NOT NULL DEFAULT false"`
|
||||
|
||||
ProjectID int64 `xorm:"INDEX NOT NULL"`
|
||||
CreatorID int64 `xorm:"NOT NULL"`
|
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(ProjectBoard))
|
||||
}
|
154
models/migrations/v1_13/v147.go
Normal file
154
models/migrations/v1_13/v147.go
Normal file
|
@ -0,0 +1,154 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func CreateReviewsForCodeComments(x *xorm.Engine) error {
|
||||
// Review
|
||||
type Review struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Type int
|
||||
ReviewerID int64 `xorm:"index"`
|
||||
OriginalAuthor string
|
||||
OriginalAuthorID int64
|
||||
IssueID int64 `xorm:"index"`
|
||||
Content string `xorm:"TEXT"`
|
||||
// Official is a review made by an assigned approver (counts towards approval)
|
||||
Official bool `xorm:"NOT NULL DEFAULT false"`
|
||||
CommitID string `xorm:"VARCHAR(40)"`
|
||||
Stale bool `xorm:"NOT NULL DEFAULT false"`
|
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
|
||||
const ReviewTypeComment = 2
|
||||
|
||||
// Comment represents a comment in commit and issue page.
|
||||
type Comment struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Type int `xorm:"INDEX"`
|
||||
PosterID int64 `xorm:"INDEX"`
|
||||
OriginalAuthor string
|
||||
OriginalAuthorID int64
|
||||
IssueID int64 `xorm:"INDEX"`
|
||||
LabelID int64
|
||||
OldProjectID int64
|
||||
ProjectID int64
|
||||
OldMilestoneID int64
|
||||
MilestoneID int64
|
||||
AssigneeID int64
|
||||
RemovedAssignee bool
|
||||
ResolveDoerID int64
|
||||
OldTitle string
|
||||
NewTitle string
|
||||
OldRef string
|
||||
NewRef string
|
||||
DependentIssueID int64
|
||||
|
||||
CommitID int64
|
||||
Line int64 // - previous line / + proposed line
|
||||
TreePath string
|
||||
Content string `xorm:"TEXT"`
|
||||
|
||||
// Path represents the 4 lines of code cemented by this comment
|
||||
PatchQuoted string `xorm:"TEXT patch"`
|
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
|
||||
// Reference issue in commit message
|
||||
CommitSHA string `xorm:"VARCHAR(40)"`
|
||||
|
||||
ReviewID int64 `xorm:"index"`
|
||||
Invalidated bool
|
||||
|
||||
// Reference an issue or pull from another comment, issue or PR
|
||||
// All information is about the origin of the reference
|
||||
RefRepoID int64 `xorm:"index"` // Repo where the referencing
|
||||
RefIssueID int64 `xorm:"index"`
|
||||
RefCommentID int64 `xorm:"index"` // 0 if origin is Issue title or content (or PR's)
|
||||
RefAction int `xorm:"SMALLINT"` // What happens if RefIssueID resolves
|
||||
RefIsPull bool
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(Review), new(Comment)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updateComment := func(comments []*Comment) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, comment := range comments {
|
||||
review := &Review{
|
||||
Type: ReviewTypeComment,
|
||||
ReviewerID: comment.PosterID,
|
||||
IssueID: comment.IssueID,
|
||||
Official: false,
|
||||
CommitID: comment.CommitSHA,
|
||||
Stale: comment.Invalidated,
|
||||
OriginalAuthor: comment.OriginalAuthor,
|
||||
OriginalAuthorID: comment.OriginalAuthorID,
|
||||
CreatedUnix: comment.CreatedUnix,
|
||||
UpdatedUnix: comment.CreatedUnix,
|
||||
}
|
||||
if _, err := sess.NoAutoTime().Insert(review); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reviewComment := &Comment{
|
||||
Type: 22,
|
||||
PosterID: comment.PosterID,
|
||||
Content: "",
|
||||
IssueID: comment.IssueID,
|
||||
ReviewID: review.ID,
|
||||
OriginalAuthor: comment.OriginalAuthor,
|
||||
OriginalAuthorID: comment.OriginalAuthorID,
|
||||
CreatedUnix: comment.CreatedUnix,
|
||||
UpdatedUnix: comment.CreatedUnix,
|
||||
}
|
||||
if _, err := sess.NoAutoTime().Insert(reviewComment); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
comment.ReviewID = review.ID
|
||||
if _, err := sess.ID(comment.ID).Cols("review_id").NoAutoTime().Update(comment); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
start := 0
|
||||
batchSize := 100
|
||||
for {
|
||||
comments := make([]*Comment, 0, batchSize)
|
||||
if err := x.Where("review_id = 0 and type = 21").Limit(batchSize, start).Find(&comments); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updateComment(comments); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
start += len(comments)
|
||||
|
||||
if len(comments) < batchSize {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
14
models/migrations/v1_13/v148.go
Normal file
14
models/migrations/v1_13/v148.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func PurgeInvalidDependenciesComments(x *xorm.Engine) error {
|
||||
_, err := x.Exec("DELETE FROM comment WHERE dependent_issue_id != 0 AND dependent_issue_id NOT IN (SELECT id FROM issue)")
|
||||
return err
|
||||
}
|
25
models/migrations/v1_13/v149.go
Normal file
25
models/migrations/v1_13/v149.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddCreatedAndUpdatedToMilestones(x *xorm.Engine) error {
|
||||
type Milestone struct {
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(Milestone)); err != nil {
|
||||
return fmt.Errorf("Sync2: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
40
models/migrations/v1_13/v150.go
Normal file
40
models/migrations/v1_13/v150.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddPrimaryKeyToRepoTopic(x *xorm.Engine) error {
|
||||
// Topic represents a topic of repositories
|
||||
type Topic struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Name string `xorm:"UNIQUE VARCHAR(25)"`
|
||||
RepoCount int
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
|
||||
// RepoTopic represents associated repositories and topics
|
||||
type RepoTopic struct {
|
||||
RepoID int64 `xorm:"pk"`
|
||||
TopicID int64 `xorm:"pk"`
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
base.RecreateTable(sess, &Topic{})
|
||||
base.RecreateTable(sess, &RepoTopic{})
|
||||
|
||||
return sess.Commit()
|
||||
}
|
197
models/migrations/v1_13/v151.go
Normal file
197
models/migrations/v1_13/v151.go
Normal file
|
@ -0,0 +1,197 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func SetDefaultPasswordToArgon2(x *xorm.Engine) error {
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
_, err := x.Exec("ALTER TABLE `user` ALTER passwd_hash_algo SET DEFAULT 'argon2';")
|
||||
return err
|
||||
case setting.Database.UsePostgreSQL:
|
||||
_, err := x.Exec("ALTER TABLE `user` ALTER COLUMN passwd_hash_algo SET DEFAULT 'argon2';")
|
||||
return err
|
||||
case setting.Database.UseMSSQL:
|
||||
// need to find the constraint and drop it, then recreate it.
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := sess.QueryString("SELECT [name] FROM sys.default_constraints WHERE parent_object_id=OBJECT_ID(?) AND COL_NAME(parent_object_id, parent_column_id)=?;", "user", "passwd_hash_algo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(res) > 0 {
|
||||
constraintName := res[0]["name"]
|
||||
log.Error("Results of select constraint: %s", constraintName)
|
||||
_, err := sess.Exec("ALTER TABLE [user] DROP CONSTRAINT " + constraintName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = sess.Exec("ALTER TABLE [user] ADD CONSTRAINT " + constraintName + " DEFAULT 'argon2' FOR passwd_hash_algo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, err := sess.Exec("ALTER TABLE [user] ADD DEFAULT('argon2') FOR passwd_hash_algo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return sess.Commit()
|
||||
|
||||
case setting.Database.UseSQLite3:
|
||||
// drop through
|
||||
default:
|
||||
log.Fatal("Unrecognized DB")
|
||||
}
|
||||
|
||||
tables, err := x.DBMetas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Now for SQLite we have to recreate the table
|
||||
var table *schemas.Table
|
||||
tableName := "user"
|
||||
|
||||
for _, table = range tables {
|
||||
if table.Name == tableName {
|
||||
break
|
||||
}
|
||||
}
|
||||
if table == nil || table.Name != tableName {
|
||||
type User struct {
|
||||
PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'argon2'"`
|
||||
}
|
||||
return x.Sync2(new(User))
|
||||
}
|
||||
column := table.GetColumn("passwd_hash_algo")
|
||||
if column == nil {
|
||||
type User struct {
|
||||
PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'argon2'"`
|
||||
}
|
||||
return x.Sync2(new(User))
|
||||
}
|
||||
|
||||
tempTableName := "tmp_recreate__user"
|
||||
column.Default = "'argon2'"
|
||||
|
||||
createTableSQL, _, err := x.Dialect().CreateTableSQL(context.Background(), x.DB(), table, tempTableName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := sess.Exec(createTableSQL); err != nil {
|
||||
log.Error("Unable to create table %s. Error: %v\n", tempTableName, err, createTableSQL)
|
||||
return err
|
||||
}
|
||||
for _, index := range table.Indexes {
|
||||
if _, err := sess.Exec(x.Dialect().CreateIndexSQL(tempTableName, index)); err != nil {
|
||||
log.Error("Unable to create indexes on temporary table %s. Error: %v", tempTableName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
newTableColumns := table.Columns()
|
||||
if len(newTableColumns) == 0 {
|
||||
return fmt.Errorf("no columns in new table")
|
||||
}
|
||||
hasID := false
|
||||
for _, column := range newTableColumns {
|
||||
hasID = hasID || (column.IsPrimaryKey && column.IsAutoIncrement)
|
||||
}
|
||||
|
||||
sqlStringBuilder := &strings.Builder{}
|
||||
_, _ = sqlStringBuilder.WriteString("INSERT INTO `")
|
||||
_, _ = sqlStringBuilder.WriteString(tempTableName)
|
||||
_, _ = sqlStringBuilder.WriteString("` (`")
|
||||
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
|
||||
_, _ = sqlStringBuilder.WriteString("`")
|
||||
for _, column := range newTableColumns[1:] {
|
||||
_, _ = sqlStringBuilder.WriteString(", `")
|
||||
_, _ = sqlStringBuilder.WriteString(column.Name)
|
||||
_, _ = sqlStringBuilder.WriteString("`")
|
||||
}
|
||||
_, _ = sqlStringBuilder.WriteString(")")
|
||||
_, _ = sqlStringBuilder.WriteString(" SELECT ")
|
||||
if newTableColumns[0].Default != "" {
|
||||
_, _ = sqlStringBuilder.WriteString("COALESCE(`")
|
||||
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
|
||||
_, _ = sqlStringBuilder.WriteString("`, ")
|
||||
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Default)
|
||||
_, _ = sqlStringBuilder.WriteString(")")
|
||||
} else {
|
||||
_, _ = sqlStringBuilder.WriteString("`")
|
||||
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
|
||||
_, _ = sqlStringBuilder.WriteString("`")
|
||||
}
|
||||
|
||||
for _, column := range newTableColumns[1:] {
|
||||
if column.Default != "" {
|
||||
_, _ = sqlStringBuilder.WriteString(", COALESCE(`")
|
||||
_, _ = sqlStringBuilder.WriteString(column.Name)
|
||||
_, _ = sqlStringBuilder.WriteString("`, ")
|
||||
_, _ = sqlStringBuilder.WriteString(column.Default)
|
||||
_, _ = sqlStringBuilder.WriteString(")")
|
||||
} else {
|
||||
_, _ = sqlStringBuilder.WriteString(", `")
|
||||
_, _ = sqlStringBuilder.WriteString(column.Name)
|
||||
_, _ = sqlStringBuilder.WriteString("`")
|
||||
}
|
||||
}
|
||||
_, _ = sqlStringBuilder.WriteString(" FROM `")
|
||||
_, _ = sqlStringBuilder.WriteString(tableName)
|
||||
_, _ = sqlStringBuilder.WriteString("`")
|
||||
|
||||
if _, err := sess.Exec(sqlStringBuilder.String()); err != nil {
|
||||
log.Error("Unable to set copy data in to temp table %s. Error: %v", tempTableName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// SQLite will drop all the constraints on the old table
|
||||
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
|
||||
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, index := range table.Indexes {
|
||||
if _, err := sess.Exec(x.Dialect().DropIndexSQL(tempTableName, index)); err != nil {
|
||||
log.Error("Unable to drop indexes on temporary table %s. Error: %v", tempTableName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil {
|
||||
log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, index := range table.Indexes {
|
||||
if _, err := sess.Exec(x.Dialect().CreateIndexSQL(tableName, index)); err != nil {
|
||||
log.Error("Unable to recreate indexes on table %s. Error: %v", tableName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
14
models/migrations/v1_13/v152.go
Normal file
14
models/migrations/v1_13/v152.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func AddTrustModelToRepository(x *xorm.Engine) error {
|
||||
type Repository struct {
|
||||
TrustModel int
|
||||
}
|
||||
return x.Sync2(new(Repository))
|
||||
}
|
25
models/migrations/v1_13/v153.go
Normal file
25
models/migrations/v1_13/v153.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddTeamReviewRequestSupport(x *xorm.Engine) error {
|
||||
type Review struct {
|
||||
ReviewerTeamID int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
type Comment struct {
|
||||
AssigneeTeamID int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(Review)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return x.Sync2(new(Comment))
|
||||
}
|
56
models/migrations/v1_13/v154.go
Normal file
56
models/migrations/v1_13/v154.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2020 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 v1_13 //nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddTimeStamps(x *xorm.Engine) error {
|
||||
// this will add timestamps where it is useful to have
|
||||
|
||||
// Star represents a starred repo by an user.
|
||||
type Star struct {
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
}
|
||||
if err := x.Sync2(new(Star)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Label represents a label of repository for issues.
|
||||
type Label struct {
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
if err := x.Sync2(new(Label)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Follow represents relations of user and their followers.
|
||||
type Follow struct {
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
}
|
||||
if err := x.Sync2(new(Follow)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Watch is connection request for receiving repository notification.
|
||||
type Watch struct {
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
if err := x.Sync2(new(Watch)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Collaboration represent the relation between an individual and a repository.
|
||||
type Collaboration struct {
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
return x.Sync2(new(Collaboration))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue