first-commit
This commit is contained in:
14
models/migrations/v1_22/main_test.go
Normal file
14
models/migrations/v1_22/main_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
base.MainTest(m)
|
||||
}
|
29
models/migrations/v1_22/v280.go
Normal file
29
models/migrations/v1_22/v280.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func RenameUserThemes(x *xorm.Engine) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("UPDATE `user` SET `theme` = 'gitea-light' WHERE `theme` = 'gitea'"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := sess.Exec("UPDATE `user` SET `theme` = 'gitea-dark' WHERE `theme` = 'arc-green'"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := sess.Exec("UPDATE `user` SET `theme` = 'gitea-auto' WHERE `theme` = 'auto'"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
21
models/migrations/v1_22/v281.go
Normal file
21
models/migrations/v1_22/v281.go
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func CreateAuthTokenTable(x *xorm.Engine) error {
|
||||
type AuthToken struct {
|
||||
ID string `xorm:"pk"`
|
||||
TokenHash string
|
||||
UserID int64 `xorm:"INDEX"`
|
||||
ExpiresUnix timeutil.TimeStamp `xorm:"INDEX"`
|
||||
}
|
||||
|
||||
return x.Sync(new(AuthToken))
|
||||
}
|
16
models/migrations/v1_22/v282.go
Normal file
16
models/migrations/v1_22/v282.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddIndexToPullAutoMergeDoerID(x *xorm.Engine) error {
|
||||
type PullAutoMerge struct {
|
||||
DoerID int64 `xorm:"INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
return x.Sync(&PullAutoMerge{})
|
||||
}
|
47
models/migrations/v1_22/v283.go
Normal file
47
models/migrations/v1_22/v283.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func AddCombinedIndexToIssueUser(x *xorm.Engine) error {
|
||||
type OldIssueUser struct {
|
||||
IssueID int64
|
||||
UID int64
|
||||
Cnt int64
|
||||
}
|
||||
|
||||
var duplicatedIssueUsers []OldIssueUser
|
||||
if err := x.SQL("select * from (select issue_id, uid, count(1) as cnt from issue_user group by issue_id, uid) a where a.cnt > 1").
|
||||
Find(&duplicatedIssueUsers); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, issueUser := range duplicatedIssueUsers {
|
||||
if x.Dialect().URI().DBType == schemas.MSSQL {
|
||||
if _, err := x.Exec(fmt.Sprintf("delete from issue_user where id in (SELECT top %d id FROM issue_user WHERE issue_id = ? and uid = ?)", issueUser.Cnt-1), issueUser.IssueID, issueUser.UID); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
var ids []int64
|
||||
if err := x.SQL("SELECT id FROM issue_user WHERE issue_id = ? and uid = ? limit ?", issueUser.IssueID, issueUser.UID, issueUser.Cnt-1).Find(&ids); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := x.Table("issue_user").In("id", ids).Delete(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type IssueUser struct {
|
||||
UID int64 `xorm:"INDEX unique(uid_to_issue)"` // User ID.
|
||||
IssueID int64 `xorm:"INDEX unique(uid_to_issue)"`
|
||||
}
|
||||
|
||||
return x.Sync(&IssueUser{})
|
||||
}
|
28
models/migrations/v1_22/v283_test.go
Normal file
28
models/migrations/v1_22/v283_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_AddCombinedIndexToIssueUser(t *testing.T) {
|
||||
type IssueUser struct { // old struct
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UID int64 `xorm:"INDEX"` // User ID.
|
||||
IssueID int64 `xorm:"INDEX"`
|
||||
IsRead bool
|
||||
IsMentioned bool
|
||||
}
|
||||
|
||||
// Prepare and load the testing database
|
||||
x, deferable := base.PrepareTestEnv(t, 0, new(IssueUser))
|
||||
defer deferable()
|
||||
|
||||
assert.NoError(t, AddCombinedIndexToIssueUser(x))
|
||||
}
|
19
models/migrations/v1_22/v284.go
Normal file
19
models/migrations/v1_22/v284.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddIgnoreStaleApprovalsColumnToProtectedBranchTable(x *xorm.Engine) error {
|
||||
type ProtectedBranch struct {
|
||||
IgnoreStaleApprovals bool `xorm:"NOT NULL DEFAULT false"`
|
||||
}
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, new(ProtectedBranch))
|
||||
return err
|
||||
}
|
22
models/migrations/v1_22/v285.go
Normal file
22
models/migrations/v1_22/v285.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddPreviousDurationToActionRun(x *xorm.Engine) error {
|
||||
type ActionRun struct {
|
||||
PreviousDuration time.Duration
|
||||
}
|
||||
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, &ActionRun{})
|
||||
return err
|
||||
}
|
107
models/migrations/v1_22/v286.go
Normal file
107
models/migrations/v1_22/v286.go
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func expandHashReferencesToSha256(x *xorm.Engine) error {
|
||||
alteredTables := [][2]string{
|
||||
{"commit_status", "context_hash"},
|
||||
{"comment", "commit_sha"},
|
||||
{"pull_request", "merge_base"},
|
||||
{"pull_request", "merged_commit_id"},
|
||||
{"review", "commit_id"},
|
||||
{"review_state", "commit_sha"},
|
||||
{"repo_archiver", "commit_id"},
|
||||
{"release", "sha1"},
|
||||
{"repo_indexer_status", "commit_sha"},
|
||||
}
|
||||
|
||||
db := x.NewSession()
|
||||
defer db.Close()
|
||||
|
||||
if err := db.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !setting.Database.Type.IsSQLite3() {
|
||||
if setting.Database.Type.IsMSSQL() {
|
||||
// drop indexes that need to be re-created afterwards
|
||||
droppedIndexes := []string{
|
||||
"DROP INDEX [IDX_commit_status_context_hash] ON [commit_status]",
|
||||
"DROP INDEX [UQE_review_state_pull_commit_user] ON [review_state]",
|
||||
"DROP INDEX [UQE_repo_archiver_s] ON [repo_archiver]",
|
||||
}
|
||||
for _, s := range droppedIndexes {
|
||||
_, err := db.Exec(s)
|
||||
if err != nil {
|
||||
return errors.New(s + " " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, alts := range alteredTables {
|
||||
var err error
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` MODIFY COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
|
||||
} else if setting.Database.Type.IsMSSQL() {
|
||||
_, err = db.Exec(fmt.Sprintf("ALTER TABLE [%s] ALTER COLUMN [%s] NVARCHAR(64)", alts[0], alts[1]))
|
||||
} else {
|
||||
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` TYPE VARCHAR(64)", alts[0], alts[1]))
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("alter column '%s' of table '%s' failed: %w", alts[1], alts[0], err)
|
||||
}
|
||||
}
|
||||
|
||||
if setting.Database.Type.IsMSSQL() {
|
||||
recreateIndexes := []string{
|
||||
"CREATE INDEX IDX_commit_status_context_hash ON commit_status(context_hash)",
|
||||
"CREATE UNIQUE INDEX UQE_review_state_pull_commit_user ON review_state(user_id, pull_id, commit_sha)",
|
||||
"CREATE UNIQUE INDEX UQE_repo_archiver_s ON repo_archiver(repo_id, type, commit_id)",
|
||||
}
|
||||
for _, s := range recreateIndexes {
|
||||
_, err := db.Exec(s)
|
||||
if err != nil {
|
||||
return errors.New(s + " " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Debug("Updated database tables to hold SHA256 git hash references")
|
||||
|
||||
return db.Commit()
|
||||
}
|
||||
|
||||
func addObjectFormatNameToRepository(x *xorm.Engine) error {
|
||||
type Repository struct {
|
||||
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
|
||||
}
|
||||
|
||||
if _, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, new(Repository)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Here to catch weird edge-cases where column constraints above are
|
||||
// not applied by the DB backend
|
||||
_, err := x.Exec("UPDATE `repository` set `object_format_name` = 'sha1' WHERE `object_format_name` = '' or `object_format_name` IS NULL")
|
||||
return err
|
||||
}
|
||||
|
||||
func AdjustDBForSha256(x *xorm.Engine) error {
|
||||
if err := expandHashReferencesToSha256(x); err != nil {
|
||||
return err
|
||||
}
|
||||
return addObjectFormatNameToRepository(x)
|
||||
}
|
118
models/migrations/v1_22/v286_test.go
Normal file
118
models/migrations/v1_22/v286_test.go
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func PrepareOldRepository(t *testing.T) (*xorm.Engine, func()) {
|
||||
type Repository struct { // old struct
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
}
|
||||
|
||||
type CommitStatus struct {
|
||||
ID int64
|
||||
ContextHash string `xorm:"char(40) index"`
|
||||
}
|
||||
|
||||
type RepoArchiver struct {
|
||||
ID int64
|
||||
RepoID int64 `xorm:"index unique(s)"`
|
||||
Type int `xorm:"unique(s)"`
|
||||
CommitID string `xorm:"VARCHAR(40) unique(s)"`
|
||||
}
|
||||
|
||||
type ReviewState struct {
|
||||
ID int64
|
||||
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
|
||||
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"`
|
||||
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"`
|
||||
}
|
||||
|
||||
type Comment struct {
|
||||
ID int64
|
||||
CommitSHA string
|
||||
}
|
||||
|
||||
type PullRequest struct {
|
||||
ID int64
|
||||
CommitSHA string
|
||||
MergeBase string
|
||||
MergedCommitID string
|
||||
}
|
||||
|
||||
type Release struct {
|
||||
ID int64
|
||||
Sha1 string
|
||||
}
|
||||
|
||||
type RepoIndexerStatus struct {
|
||||
ID int64
|
||||
CommitSHA string
|
||||
}
|
||||
|
||||
type Review struct {
|
||||
ID int64
|
||||
CommitID string
|
||||
}
|
||||
|
||||
// Prepare and load the testing database
|
||||
return base.PrepareTestEnv(t, 0,
|
||||
new(Repository),
|
||||
new(CommitStatus),
|
||||
new(RepoArchiver),
|
||||
new(ReviewState),
|
||||
new(Review),
|
||||
new(Comment),
|
||||
new(PullRequest),
|
||||
new(Release),
|
||||
new(RepoIndexerStatus),
|
||||
)
|
||||
}
|
||||
|
||||
func Test_RepositoryFormat(t *testing.T) {
|
||||
x, deferable := PrepareOldRepository(t)
|
||||
defer deferable()
|
||||
|
||||
assert.NoError(t, AdjustDBForSha256(x))
|
||||
|
||||
type Repository struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
ObjectFormatName string `xorg:"not null default('sha1')"`
|
||||
}
|
||||
|
||||
repo := new(Repository)
|
||||
|
||||
// check we have some records to migrate
|
||||
count, err := x.Count(new(Repository))
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 4, count)
|
||||
|
||||
repo.ObjectFormatName = "sha256"
|
||||
_, err = x.Insert(repo)
|
||||
assert.NoError(t, err)
|
||||
id := repo.ID
|
||||
|
||||
count, err = x.Count(new(Repository))
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 5, count)
|
||||
|
||||
repo = new(Repository)
|
||||
ok, err := x.ID(2).Get(repo)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "sha1", repo.ObjectFormatName)
|
||||
|
||||
repo = new(Repository)
|
||||
ok, err = x.ID(id).Get(repo)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "sha256", repo.ObjectFormatName)
|
||||
}
|
46
models/migrations/v1_22/v287.go
Normal file
46
models/migrations/v1_22/v287.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type BadgeUnique struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Slug string `xorm:"UNIQUE"`
|
||||
}
|
||||
|
||||
func (BadgeUnique) TableName() string {
|
||||
return "badge"
|
||||
}
|
||||
|
||||
func UseSlugInsteadOfIDForBadges(x *xorm.Engine) error {
|
||||
type Badge struct {
|
||||
Slug string
|
||||
}
|
||||
|
||||
err := x.Sync(new(Badge))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = sess.Exec("UPDATE `badge` SET `slug` = `id` Where `slug` IS NULL")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = sess.Sync(new(BadgeUnique))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
57
models/migrations/v1_22/v287_test.go
Normal file
57
models/migrations/v1_22/v287_test.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_UpdateBadgeColName(t *testing.T) {
|
||||
type Badge struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Description string
|
||||
ImageURL string
|
||||
}
|
||||
|
||||
// Prepare and load the testing database
|
||||
x, deferable := base.PrepareTestEnv(t, 0, new(Badge))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
oldBadges := []*Badge{
|
||||
{Description: "Test Badge 1", ImageURL: "https://example.com/badge1.png"},
|
||||
{Description: "Test Badge 2", ImageURL: "https://example.com/badge2.png"},
|
||||
{Description: "Test Badge 3", ImageURL: "https://example.com/badge3.png"},
|
||||
}
|
||||
|
||||
for _, badge := range oldBadges {
|
||||
_, err := x.Insert(badge)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
if err := UseSlugInsteadOfIDForBadges(x); err != nil {
|
||||
assert.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
got := []BadgeUnique{}
|
||||
if err := x.Table("badge").Asc("id").Find(&got); !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
for i, e := range oldBadges {
|
||||
got := got[i+1] // 1 is in the badge.yml
|
||||
assert.Equal(t, e.ID, got.ID)
|
||||
assert.Equal(t, strconv.FormatInt(e.ID, 10), got.Slug)
|
||||
}
|
||||
|
||||
// TODO: check if badges have been updated
|
||||
}
|
26
models/migrations/v1_22/v288.go
Normal file
26
models/migrations/v1_22/v288.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type Blocking struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
BlockerID int64 `xorm:"UNIQUE(block)"`
|
||||
BlockeeID int64 `xorm:"UNIQUE(block)"`
|
||||
Note string
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
}
|
||||
|
||||
func (*Blocking) TableName() string {
|
||||
return "user_blocking"
|
||||
}
|
||||
|
||||
func AddUserBlockingTable(x *xorm.Engine) error {
|
||||
return x.Sync(&Blocking{})
|
||||
}
|
21
models/migrations/v1_22/v289.go
Normal file
21
models/migrations/v1_22/v289.go
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func AddDefaultWikiBranch(x *xorm.Engine) error {
|
||||
type Repository struct {
|
||||
ID int64
|
||||
DefaultWikiBranch string
|
||||
}
|
||||
if _, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, &Repository{}); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := x.Exec("UPDATE `repository` SET default_wiki_branch = 'master' WHERE (default_wiki_branch IS NULL) OR (default_wiki_branch = '')")
|
||||
return err
|
||||
}
|
24
models/migrations/v1_22/v290.go
Normal file
24
models/migrations/v1_22/v290.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type HookTask struct {
|
||||
PayloadVersion int `xorm:"DEFAULT 1"`
|
||||
}
|
||||
|
||||
func AddPayloadVersionToHookTaskTable(x *xorm.Engine) error {
|
||||
// create missing column
|
||||
if _, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, new(HookTask)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := x.Exec("UPDATE hook_task SET payload_version = 1 WHERE payload_version IS NULL")
|
||||
return err
|
||||
}
|
18
models/migrations/v1_22/v291.go
Normal file
18
models/migrations/v1_22/v291.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func AddCommentIDIndexofAttachment(x *xorm.Engine) error {
|
||||
type Attachment struct {
|
||||
CommentID int64 `xorm:"INDEX"`
|
||||
}
|
||||
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreDropIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, &Attachment{})
|
||||
return err
|
||||
}
|
9
models/migrations/v1_22/v292.go
Normal file
9
models/migrations/v1_22/v292.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
// NOTE: noop the original migration has bug which some projects will be skip, so
|
||||
// these projects will have no default board.
|
||||
// So that this migration will be skipped and go to v293.go
|
||||
// This file is a placeholder so that readers can know what happened
|
108
models/migrations/v1_22/v293.go
Normal file
108
models/migrations/v1_22/v293.go
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// CheckProjectColumnsConsistency ensures there is exactly one default board per project present
|
||||
func CheckProjectColumnsConsistency(x *xorm.Engine) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
limit := setting.Database.IterateBufferSize
|
||||
if limit <= 0 {
|
||||
limit = 50
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ID int64
|
||||
CreatorID int64
|
||||
BoardID int64
|
||||
}
|
||||
|
||||
type ProjectBoard struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Title string
|
||||
Default bool `xorm:"NOT NULL DEFAULT false"` // issues not assigned to a specific board will be assigned to this board
|
||||
Sorting int8 `xorm:"NOT NULL DEFAULT 0"`
|
||||
Color string `xorm:"VARCHAR(7)"`
|
||||
|
||||
ProjectID int64 `xorm:"INDEX NOT NULL"`
|
||||
CreatorID int64 `xorm:"NOT NULL"`
|
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
|
||||
for {
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// all these projects without defaults will be fixed in the same loop, so
|
||||
// we just need to always get projects without defaults until no such project
|
||||
var projects []*Project
|
||||
if err := sess.Select("project.id as id, project.creator_id, project_board.id as board_id").
|
||||
Join("LEFT", "project_board", "project_board.project_id = project.id AND project_board.`default`=?", true).
|
||||
Where("project_board.id is NULL OR project_board.id = 0").
|
||||
Limit(limit).
|
||||
Find(&projects); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, p := range projects {
|
||||
if _, err := sess.Insert(ProjectBoard{
|
||||
ProjectID: p.ID,
|
||||
Default: true,
|
||||
Title: "Uncategorized",
|
||||
CreatorID: p.CreatorID,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := sess.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(projects) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
sess.Close()
|
||||
|
||||
return removeDuplicatedBoardDefault(x)
|
||||
}
|
||||
|
||||
func removeDuplicatedBoardDefault(x *xorm.Engine) error {
|
||||
type ProjectInfo struct {
|
||||
ProjectID int64
|
||||
DefaultNum int
|
||||
}
|
||||
var projects []ProjectInfo
|
||||
if err := x.Select("project_id, count(*) AS default_num").
|
||||
Table("project_board").
|
||||
Where("`default` = ?", true).
|
||||
GroupBy("project_id").
|
||||
Having("count(*) > 1").
|
||||
Find(&projects); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, project := range projects {
|
||||
if _, err := x.Where("project_id=?", project.ProjectID).
|
||||
Table("project_board").
|
||||
Limit(project.DefaultNum - 1).
|
||||
Update(map[string]bool{
|
||||
"`default`": false,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
44
models/migrations/v1_22/v293_test.go
Normal file
44
models/migrations/v1_22/v293_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
"code.gitea.io/gitea/models/project"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_CheckProjectColumnsConsistency(t *testing.T) {
|
||||
// Prepare and load the testing database
|
||||
x, deferable := base.PrepareTestEnv(t, 0, new(project.Project), new(project.Column))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
assert.NoError(t, CheckProjectColumnsConsistency(x))
|
||||
|
||||
// check if default column was added
|
||||
var defaultColumn project.Column
|
||||
has, err := x.Where("project_id=? AND `default` = ?", 1, true).Get(&defaultColumn)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.Equal(t, int64(1), defaultColumn.ProjectID)
|
||||
assert.True(t, defaultColumn.Default)
|
||||
|
||||
// check if multiple defaults, previous were removed and last will be kept
|
||||
expectDefaultColumn, err := project.GetColumn(db.DefaultContext, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), expectDefaultColumn.ProjectID)
|
||||
assert.False(t, expectDefaultColumn.Default)
|
||||
|
||||
expectNonDefaultColumn, err := project.GetColumn(db.DefaultContext, 3)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), expectNonDefaultColumn.ProjectID)
|
||||
assert.True(t, expectNonDefaultColumn.Default)
|
||||
}
|
53
models/migrations/v1_22/v294.go
Normal file
53
models/migrations/v1_22/v294.go
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// AddUniqueIndexForProjectIssue adds unique indexes for project issue table
|
||||
func AddUniqueIndexForProjectIssue(x *xorm.Engine) error {
|
||||
// remove possible duplicated records in table project_issue
|
||||
type result struct {
|
||||
IssueID int64
|
||||
ProjectID int64
|
||||
Cnt int
|
||||
}
|
||||
var results []result
|
||||
if err := x.Select("issue_id, project_id, count(*) as cnt").
|
||||
Table("project_issue").
|
||||
GroupBy("issue_id, project_id").
|
||||
Having("count(*) > 1").
|
||||
Find(&results); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, r := range results {
|
||||
if x.Dialect().URI().DBType == schemas.MSSQL {
|
||||
if _, err := x.Exec(fmt.Sprintf("delete from project_issue where id in (SELECT top %d id FROM project_issue WHERE issue_id = ? and project_id = ?)", r.Cnt-1), r.IssueID, r.ProjectID); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
var ids []int64
|
||||
if err := x.SQL("SELECT id FROM project_issue WHERE issue_id = ? and project_id = ? limit ?", r.IssueID, r.ProjectID, r.Cnt-1).Find(&ids); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := x.Table("project_issue").In("id", ids).Delete(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add unique index for project_issue table
|
||||
type ProjectIssue struct { //revive:disable-line:exported
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
IssueID int64 `xorm:"INDEX unique(s)"`
|
||||
ProjectID int64 `xorm:"INDEX unique(s)"`
|
||||
}
|
||||
|
||||
return x.Sync(new(ProjectIssue))
|
||||
}
|
51
models/migrations/v1_22/v294_test.go
Normal file
51
models/migrations/v1_22/v294_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func Test_AddUniqueIndexForProjectIssue(t *testing.T) {
|
||||
type ProjectIssue struct { //revive:disable-line:exported
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
IssueID int64 `xorm:"INDEX"`
|
||||
ProjectID int64 `xorm:"INDEX"`
|
||||
}
|
||||
|
||||
// Prepare and load the testing database
|
||||
x, deferable := base.PrepareTestEnv(t, 0, new(ProjectIssue))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
cnt, err := x.Table("project_issue").Where("project_id=1 AND issue_id=1").Count()
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 2, cnt)
|
||||
|
||||
assert.NoError(t, AddUniqueIndexForProjectIssue(x))
|
||||
|
||||
cnt, err = x.Table("project_issue").Where("project_id=1 AND issue_id=1").Count()
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
tables, err := x.DBMetas()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, tables, 1)
|
||||
found := false
|
||||
for _, index := range tables[0].Indexes {
|
||||
if index.Type == schemas.UniqueType {
|
||||
found = true
|
||||
assert.ElementsMatch(t, index.Cols, []string{"project_id", "issue_id"})
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, found)
|
||||
}
|
18
models/migrations/v1_22/v295.go
Normal file
18
models/migrations/v1_22/v295.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func AddCommitStatusSummary(x *xorm.Engine) error {
|
||||
type CommitStatusSummary struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX UNIQUE(repo_id_sha)"`
|
||||
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_id_sha)"`
|
||||
State string `xorm:"VARCHAR(7) NOT NULL"`
|
||||
}
|
||||
// there is no migrations because if there is no data on this table, it will fall back to get data
|
||||
// from commit status
|
||||
return x.Sync2(new(CommitStatusSummary))
|
||||
}
|
16
models/migrations/v1_22/v296.go
Normal file
16
models/migrations/v1_22/v296.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func AddCommitStatusSummary2(x *xorm.Engine) error {
|
||||
type CommitStatusSummary struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
TargetURL string `xorm:"TEXT"`
|
||||
}
|
||||
// there is no migrations because if there is no data on this table, it will fall back to get data
|
||||
// from commit status
|
||||
return x.Sync(new(CommitStatusSummary))
|
||||
}
|
17
models/migrations/v1_22/v297.go
Normal file
17
models/migrations/v1_22/v297.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddRepoUnitEveryoneAccessMode(x *xorm.Engine) error {
|
||||
type RepoUnit struct { //revive:disable-line:exported
|
||||
EveryoneAccessMode perm.AccessMode `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
return x.Sync(&RepoUnit{})
|
||||
}
|
10
models/migrations/v1_22/v298.go
Normal file
10
models/migrations/v1_22/v298.go
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_22
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func DropWronglyCreatedTable(x *xorm.Engine) error {
|
||||
return x.DropTables("o_auth2_application")
|
||||
}
|
Reference in New Issue
Block a user