aboutsummaryrefslogtreecommitdiffstats
path: root/models/migrations/v1_17
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2022-11-02 16:54:36 +0800
committerGitHub <noreply@github.com>2022-11-02 16:54:36 +0800
commite72acd5e5b2d043fcf0a0182a1eedaed8120c155 (patch)
tree77e4c341bef6450e5dfa7a1f61c9693527a133d0 /models/migrations/v1_17
parent4827f42f56bcc70d40e073a8502930d9cce39798 (diff)
downloadgitea-e72acd5e5b2d043fcf0a0182a1eedaed8120c155.tar.gz
gitea-e72acd5e5b2d043fcf0a0182a1eedaed8120c155.zip
Split migrations folder (#21549)
There are too many files in `models/migrations` folder so that I split them into sub folders.
Diffstat (limited to 'models/migrations/v1_17')
-rw-r--r--models/migrations/v1_17/main_test.go15
-rw-r--r--models/migrations/v1_17/v211.go26
-rw-r--r--models/migrations/v1_17/v212.go94
-rw-r--r--models/migrations/v1_17/v213.go18
-rw-r--r--models/migrations/v1_17/v214.go23
-rw-r--r--models/migrations/v1_17/v215.go25
-rw-r--r--models/migrations/v1_17/v216.go8
-rw-r--r--models/migrations/v1_17/v217.go26
-rw-r--r--models/migrations/v1_17/v218.go53
-rw-r--r--models/migrations/v1_17/v219.go31
-rw-r--r--models/migrations/v1_17/v220.go28
-rw-r--r--models/migrations/v1_17/v221.go75
-rw-r--r--models/migrations/v1_17/v221_test.go67
-rw-r--r--models/migrations/v1_17/v222.go65
-rw-r--r--models/migrations/v1_17/v223.go104
15 files changed, 658 insertions, 0 deletions
diff --git a/models/migrations/v1_17/main_test.go b/models/migrations/v1_17/main_test.go
new file mode 100644
index 0000000000..0f1708de8b
--- /dev/null
+++ b/models/migrations/v1_17/main_test.go
@@ -0,0 +1,15 @@
+// Copyright 2021 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_17 // nolint
+
+import (
+ "testing"
+
+ "code.gitea.io/gitea/models/migrations/base"
+)
+
+func TestMain(m *testing.M) {
+ base.MainTest(m)
+}
diff --git a/models/migrations/v1_17/v211.go b/models/migrations/v1_17/v211.go
new file mode 100644
index 0000000000..de9eb4b4b0
--- /dev/null
+++ b/models/migrations/v1_17/v211.go
@@ -0,0 +1,26 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "fmt"
+
+ "xorm.io/xorm"
+)
+
+func CreateForeignReferenceTable(x *xorm.Engine) error {
+ type ForeignReference struct {
+ // RepoID is the first column in all indices. now we only need 2 indices: (repo, local) and (repo, foreign, type)
+ RepoID int64 `xorm:"UNIQUE(repo_foreign_type) INDEX(repo_local)" `
+ LocalIndex int64 `xorm:"INDEX(repo_local)"` // the resource key inside Gitea, it can be IssueIndex, or some model ID.
+ ForeignIndex string `xorm:"INDEX UNIQUE(repo_foreign_type)"`
+ Type string `xorm:"VARCHAR(16) INDEX UNIQUE(repo_foreign_type)"`
+ }
+
+ if err := x.Sync2(new(ForeignReference)); err != nil {
+ return fmt.Errorf("Sync2: %w", err)
+ }
+ return nil
+}
diff --git a/models/migrations/v1_17/v212.go b/models/migrations/v1_17/v212.go
new file mode 100644
index 0000000000..5187f5e72f
--- /dev/null
+++ b/models/migrations/v1_17/v212.go
@@ -0,0 +1,94 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func AddPackageTables(x *xorm.Engine) error {
+ type Package struct {
+ ID int64 `xorm:"pk autoincr"`
+ OwnerID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ RepoID int64 `xorm:"INDEX"`
+ Type string `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ Name string `xorm:"NOT NULL"`
+ LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ SemverCompatible bool `xorm:"NOT NULL DEFAULT false"`
+ }
+
+ if err := x.Sync2(new(Package)); err != nil {
+ return err
+ }
+
+ type PackageVersion struct {
+ ID int64 `xorm:"pk autoincr"`
+ PackageID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ CreatorID int64 `xorm:"NOT NULL DEFAULT 0"`
+ Version string `xorm:"NOT NULL"`
+ LowerVersion string `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
+ IsInternal bool `xorm:"INDEX NOT NULL DEFAULT false"`
+ MetadataJSON string `xorm:"metadata_json TEXT"`
+ DownloadCount int64 `xorm:"NOT NULL DEFAULT 0"`
+ }
+
+ if err := x.Sync2(new(PackageVersion)); err != nil {
+ return err
+ }
+
+ type PackageProperty struct {
+ ID int64 `xorm:"pk autoincr"`
+ RefType int64 `xorm:"INDEX NOT NULL"`
+ RefID int64 `xorm:"INDEX NOT NULL"`
+ Name string `xorm:"INDEX NOT NULL"`
+ Value string `xorm:"TEXT NOT NULL"`
+ }
+
+ if err := x.Sync2(new(PackageProperty)); err != nil {
+ return err
+ }
+
+ type PackageFile struct {
+ ID int64 `xorm:"pk autoincr"`
+ VersionID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ BlobID int64 `xorm:"INDEX NOT NULL"`
+ Name string `xorm:"NOT NULL"`
+ LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ CompositeKey string `xorm:"UNIQUE(s) INDEX"`
+ IsLead bool `xorm:"NOT NULL DEFAULT false"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
+ }
+
+ if err := x.Sync2(new(PackageFile)); err != nil {
+ return err
+ }
+
+ type PackageBlob struct {
+ ID int64 `xorm:"pk autoincr"`
+ Size int64 `xorm:"NOT NULL DEFAULT 0"`
+ HashMD5 string `xorm:"hash_md5 char(32) UNIQUE(md5) INDEX NOT NULL"`
+ HashSHA1 string `xorm:"hash_sha1 char(40) UNIQUE(sha1) INDEX NOT NULL"`
+ HashSHA256 string `xorm:"hash_sha256 char(64) UNIQUE(sha256) INDEX NOT NULL"`
+ HashSHA512 string `xorm:"hash_sha512 char(128) UNIQUE(sha512) INDEX NOT NULL"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
+ }
+
+ if err := x.Sync2(new(PackageBlob)); err != nil {
+ return err
+ }
+
+ type PackageBlobUpload struct {
+ ID string `xorm:"pk"`
+ BytesReceived int64 `xorm:"NOT NULL DEFAULT 0"`
+ HashStateBytes []byte `xorm:"BLOB"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"updated INDEX NOT NULL"`
+ }
+
+ return x.Sync2(new(PackageBlobUpload))
+}
diff --git a/models/migrations/v1_17/v213.go b/models/migrations/v1_17/v213.go
new file mode 100644
index 0000000000..7b1b158f9f
--- /dev/null
+++ b/models/migrations/v1_17/v213.go
@@ -0,0 +1,18 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "xorm.io/xorm"
+)
+
+func AddAllowMaintainerEdit(x *xorm.Engine) error {
+ // PullRequest represents relation between pull request and repositories.
+ type PullRequest struct {
+ AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
+ }
+
+ return x.Sync2(new(PullRequest))
+}
diff --git a/models/migrations/v1_17/v214.go b/models/migrations/v1_17/v214.go
new file mode 100644
index 0000000000..e6fa53d4b8
--- /dev/null
+++ b/models/migrations/v1_17/v214.go
@@ -0,0 +1,23 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "xorm.io/xorm"
+)
+
+func AddAutoMergeTable(x *xorm.Engine) error {
+ type MergeStyle string
+ type PullAutoMerge struct {
+ ID int64 `xorm:"pk autoincr"`
+ PullID int64 `xorm:"UNIQUE"`
+ DoerID int64 `xorm:"NOT NULL"`
+ MergeStyle MergeStyle `xorm:"varchar(30)"`
+ Message string `xorm:"LONGTEXT"`
+ CreatedUnix int64 `xorm:"created"`
+ }
+
+ return x.Sync2(&PullAutoMerge{})
+}
diff --git a/models/migrations/v1_17/v215.go b/models/migrations/v1_17/v215.go
new file mode 100644
index 0000000000..e148515964
--- /dev/null
+++ b/models/migrations/v1_17/v215.go
@@ -0,0 +1,25 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "code.gitea.io/gitea/models/pull"
+ "code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func AddReviewViewedFiles(x *xorm.Engine) error {
+ type ReviewState struct {
+ ID int64 `xorm:"pk autoincr"`
+ 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)"`
+ UpdatedFiles map[string]pull.ViewedState `xorm:"NOT NULL LONGTEXT JSON"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
+ }
+
+ return x.Sync2(new(ReviewState))
+}
diff --git a/models/migrations/v1_17/v216.go b/models/migrations/v1_17/v216.go
new file mode 100644
index 0000000000..bde5825772
--- /dev/null
+++ b/models/migrations/v1_17/v216.go
@@ -0,0 +1,8 @@
+// Copyright 2022 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_17 // nolint
+
+// This migration added non-ideal indices to the action table which on larger datasets slowed things down
+// it has been superceded by v218.go
diff --git a/models/migrations/v1_17/v217.go b/models/migrations/v1_17/v217.go
new file mode 100644
index 0000000000..abba9e8ec9
--- /dev/null
+++ b/models/migrations/v1_17/v217.go
@@ -0,0 +1,26 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "code.gitea.io/gitea/modules/setting"
+
+ "xorm.io/xorm"
+)
+
+func AlterHookTaskTextFieldsToLongText(x *xorm.Engine) error {
+ sess := x.NewSession()
+ defer sess.Close()
+ if err := sess.Begin(); err != nil {
+ return err
+ }
+
+ if setting.Database.UseMySQL {
+ if _, err := sess.Exec("ALTER TABLE `hook_task` CHANGE `payload_content` `payload_content` LONGTEXT, CHANGE `request_content` `request_content` LONGTEXT, change `response_content` `response_content` LONGTEXT"); err != nil {
+ return err
+ }
+ }
+ return sess.Commit()
+}
diff --git a/models/migrations/v1_17/v218.go b/models/migrations/v1_17/v218.go
new file mode 100644
index 0000000000..a5cd1c591a
--- /dev/null
+++ b/models/migrations/v1_17/v218.go
@@ -0,0 +1,53 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/xorm"
+ "xorm.io/xorm/schemas"
+)
+
+type improveActionTableIndicesAction struct {
+ ID int64 `xorm:"pk autoincr"`
+ UserID int64 // Receiver user id.
+ OpType int
+ ActUserID int64 // Action user id.
+ RepoID int64
+ CommentID int64 `xorm:"INDEX"`
+ IsDeleted bool `xorm:"NOT NULL DEFAULT false"`
+ RefName string
+ IsPrivate bool `xorm:"NOT NULL DEFAULT false"`
+ Content string `xorm:"TEXT"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created"`
+}
+
+// TableName sets the name of this table
+func (*improveActionTableIndicesAction) TableName() string {
+ return "action"
+}
+
+// TableIndices implements xorm's TableIndices interface
+func (*improveActionTableIndicesAction) TableIndices() []*schemas.Index {
+ repoIndex := schemas.NewIndex("r_u_d", schemas.IndexType)
+ repoIndex.AddColumn("repo_id", "user_id", "is_deleted")
+
+ actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
+ actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
+ indices := []*schemas.Index{actUserIndex, repoIndex}
+ if setting.Database.UsePostgreSQL {
+ cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
+ cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
+ indices = append(indices, cudIndex)
+ }
+
+ return indices
+}
+
+func ImproveActionTableIndices(x *xorm.Engine) error {
+ return x.Sync2(&improveActionTableIndicesAction{})
+}
diff --git a/models/migrations/v1_17/v219.go b/models/migrations/v1_17/v219.go
new file mode 100644
index 0000000000..d22f4e6b8e
--- /dev/null
+++ b/models/migrations/v1_17/v219.go
@@ -0,0 +1,31 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "time"
+
+ "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func AddSyncOnCommitColForPushMirror(x *xorm.Engine) error {
+ type PushMirror struct {
+ ID int64 `xorm:"pk autoincr"`
+ RepoID int64 `xorm:"INDEX"`
+ Repo *repo.Repository `xorm:"-"`
+ RemoteName string
+
+ SyncOnCommit bool `xorm:"NOT NULL DEFAULT true"`
+ Interval time.Duration
+ CreatedUnix timeutil.TimeStamp `xorm:"created"`
+ LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"`
+ LastError string `xorm:"text"`
+ }
+
+ return x.Sync2(new(PushMirror))
+}
diff --git a/models/migrations/v1_17/v220.go b/models/migrations/v1_17/v220.go
new file mode 100644
index 0000000000..bbceb933b3
--- /dev/null
+++ b/models/migrations/v1_17/v220.go
@@ -0,0 +1,28 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ packages_model "code.gitea.io/gitea/models/packages"
+ container_module "code.gitea.io/gitea/modules/packages/container"
+
+ "xorm.io/xorm"
+ "xorm.io/xorm/schemas"
+)
+
+func AddContainerRepositoryProperty(x *xorm.Engine) (err error) {
+ switch x.Dialect().URI().DBType {
+ case schemas.SQLITE:
+ _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
+ packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
+ case schemas.MSSQL:
+ _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name + '/' + p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
+ packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
+ default:
+ _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, CONCAT(u.lower_name, '/', p.lower_name) FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
+ packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
+ }
+ return err
+}
diff --git a/models/migrations/v1_17/v221.go b/models/migrations/v1_17/v221.go
new file mode 100644
index 0000000000..17744d53ab
--- /dev/null
+++ b/models/migrations/v1_17/v221.go
@@ -0,0 +1,75 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "encoding/base32"
+ "fmt"
+
+ "code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func StoreWebauthnCredentialIDAsBytes(x *xorm.Engine) error {
+ // Create webauthnCredential table
+ type webauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ Name string
+ LowerName string `xorm:"unique(s)"`
+ UserID int64 `xorm:"INDEX unique(s)"`
+ CredentialID string `xorm:"INDEX VARCHAR(410)"`
+ // Note the lack of INDEX here - these will be created once the column is renamed in v223.go
+ CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
+ PublicKey []byte
+ AttestationType string
+ AAGUID []byte
+ SignCount uint32 `xorm:"BIGINT"`
+ CloneWarning bool
+ CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
+ }
+ if err := x.Sync2(&webauthnCredential{}); err != nil {
+ return err
+ }
+
+ var start int
+ creds := make([]*webauthnCredential, 0, 50)
+ for {
+ err := x.Select("id, credential_id").OrderBy("id").Limit(50, start).Find(&creds)
+ if err != nil {
+ return err
+ }
+
+ err = func() error {
+ sess := x.NewSession()
+ defer sess.Close()
+ if err := sess.Begin(); err != nil {
+ return fmt.Errorf("unable to allow start session. Error: %w", err)
+ }
+ for _, cred := range creds {
+ cred.CredentialIDBytes, err = base32.HexEncoding.DecodeString(cred.CredentialID)
+ if err != nil {
+ return fmt.Errorf("unable to parse credential id %s for credential[%d]: %w", cred.CredentialID, cred.ID, err)
+ }
+ count, err := sess.ID(cred.ID).Cols("credential_id_bytes").Update(cred)
+ if count != 1 || err != nil {
+ return fmt.Errorf("unable to update credential id bytes for credential[%d]: %d,%w", cred.ID, count, err)
+ }
+ }
+ return sess.Commit()
+ }()
+ if err != nil {
+ return err
+ }
+
+ if len(creds) < 50 {
+ break
+ }
+ start += 50
+ creds = creds[:0]
+ }
+ return nil
+}
diff --git a/models/migrations/v1_17/v221_test.go b/models/migrations/v1_17/v221_test.go
new file mode 100644
index 0000000000..d635820f82
--- /dev/null
+++ b/models/migrations/v1_17/v221_test.go
@@ -0,0 +1,67 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "encoding/base32"
+ "testing"
+
+ "code.gitea.io/gitea/models/migrations/base"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func Test_StoreWebauthnCredentialIDAsBytes(t *testing.T) {
+ // Create webauthnCredential table
+ type WebauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ Name string
+ LowerName string `xorm:"unique(s)"`
+ UserID int64 `xorm:"INDEX unique(s)"`
+ CredentialID string `xorm:"INDEX VARCHAR(410)"`
+ PublicKey []byte
+ AttestationType string
+ AAGUID []byte
+ SignCount uint32 `xorm:"BIGINT"`
+ CloneWarning bool
+ }
+
+ type ExpectedWebauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ CredentialID string // CredentialID is at most 1023 bytes as per spec released 20 July 2022
+ }
+
+ type ConvertedWebauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
+ }
+
+ // Prepare and load the testing database
+ x, deferable := base.PrepareTestEnv(t, 0, new(WebauthnCredential), new(ExpectedWebauthnCredential))
+ defer deferable()
+ if x == nil || t.Failed() {
+ return
+ }
+
+ if err := StoreWebauthnCredentialIDAsBytes(x); err != nil {
+ assert.NoError(t, err)
+ return
+ }
+
+ expected := []ExpectedWebauthnCredential{}
+ if err := x.Table("expected_webauthn_credential").Asc("id").Find(&expected); !assert.NoError(t, err) {
+ return
+ }
+
+ got := []ConvertedWebauthnCredential{}
+ if err := x.Table("webauthn_credential").Select("id, credential_id_bytes").Asc("id").Find(&got); !assert.NoError(t, err) {
+ return
+ }
+
+ for i, e := range expected {
+ credIDBytes, _ := base32.HexEncoding.DecodeString(e.CredentialID)
+ assert.Equal(t, credIDBytes, got[i].CredentialIDBytes)
+ }
+}
diff --git a/models/migrations/v1_17/v222.go b/models/migrations/v1_17/v222.go
new file mode 100644
index 0000000000..3aafb1848d
--- /dev/null
+++ b/models/migrations/v1_17/v222.go
@@ -0,0 +1,65 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "context"
+ "fmt"
+
+ "code.gitea.io/gitea/models/migrations/base"
+ "code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func DropOldCredentialIDColumn(x *xorm.Engine) error {
+ // This migration maybe rerun so that we should check if it has been run
+ credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id")
+ if err != nil {
+ return err
+ }
+ if !credentialIDExist {
+ // Column is already non-extant
+ return nil
+ }
+ credentialIDBytesExists, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id_bytes")
+ if err != nil {
+ return err
+ }
+ if !credentialIDBytesExists {
+ // looks like 221 hasn't properly run
+ return fmt.Errorf("webauthn_credential does not have a credential_id_bytes column... it is not safe to run this migration")
+ }
+
+ // Create webauthnCredential table
+ type webauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ Name string
+ LowerName string `xorm:"unique(s)"`
+ UserID int64 `xorm:"INDEX unique(s)"`
+ CredentialID string `xorm:"INDEX VARCHAR(410)"`
+ // Note the lack of the INDEX on CredentialIDBytes - we will add this in v223.go
+ CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
+ PublicKey []byte
+ AttestationType string
+ AAGUID []byte
+ SignCount uint32 `xorm:"BIGINT"`
+ CloneWarning bool
+ CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
+ }
+ if err := x.Sync2(&webauthnCredential{}); err != nil {
+ return err
+ }
+
+ // Drop the old credential ID
+ sess := x.NewSession()
+ defer sess.Close()
+
+ if err := base.DropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil {
+ return fmt.Errorf("unable to drop old credentialID column: %w", err)
+ }
+ return sess.Commit()
+}
diff --git a/models/migrations/v1_17/v223.go b/models/migrations/v1_17/v223.go
new file mode 100644
index 0000000000..530ddf0e05
--- /dev/null
+++ b/models/migrations/v1_17/v223.go
@@ -0,0 +1,104 @@
+// Copyright 2022 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_17 // nolint
+
+import (
+ "context"
+ "fmt"
+
+ "code.gitea.io/gitea/models/migrations/base"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func RenameCredentialIDBytes(x *xorm.Engine) error {
+ // This migration maybe rerun so that we should check if it has been run
+ credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id")
+ if err != nil {
+ return err
+ }
+ if credentialIDExist {
+ credentialIDBytesExists, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id_bytes")
+ if err != nil {
+ return err
+ }
+ if !credentialIDBytesExists {
+ return nil
+ }
+ }
+
+ err = func() error {
+ // webauthnCredential table
+ type webauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ Name string
+ LowerName string `xorm:"unique(s)"`
+ UserID int64 `xorm:"INDEX unique(s)"`
+ // Note the lack of INDEX here
+ CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
+ PublicKey []byte
+ AttestationType string
+ AAGUID []byte
+ SignCount uint32 `xorm:"BIGINT"`
+ CloneWarning bool
+ CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
+ }
+ sess := x.NewSession()
+ defer sess.Close()
+ if err := sess.Begin(); err != nil {
+ return err
+ }
+
+ if err := sess.Sync2(new(webauthnCredential)); err != nil {
+ return fmt.Errorf("error on Sync2: %w", err)
+ }
+
+ if credentialIDExist {
+ // if both errors and message exist, drop message at first
+ if err := base.DropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil {
+ return err
+ }
+ }
+
+ switch {
+ case setting.Database.UseMySQL:
+ if _, err := sess.Exec("ALTER TABLE `webauthn_credential` CHANGE credential_id_bytes credential_id VARBINARY(1024)"); err != nil {
+ return err
+ }
+ case setting.Database.UseMSSQL:
+ if _, err := sess.Exec("sp_rename 'webauthn_credential.credential_id_bytes', 'credential_id', 'COLUMN'"); err != nil {
+ return err
+ }
+ default:
+ if _, err := sess.Exec("ALTER TABLE `webauthn_credential` RENAME COLUMN credential_id_bytes TO credential_id"); err != nil {
+ return err
+ }
+ }
+ return sess.Commit()
+ }()
+ if err != nil {
+ return err
+ }
+
+ // Create webauthnCredential table
+ type webauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ Name string
+ LowerName string `xorm:"unique(s)"`
+ UserID int64 `xorm:"INDEX unique(s)"`
+ CredentialID []byte `xorm:"INDEX VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
+ PublicKey []byte
+ AttestationType string
+ AAGUID []byte
+ SignCount uint32 `xorm:"BIGINT"`
+ CloneWarning bool
+ CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
+ }
+ return x.Sync2(&webauthnCredential{})
+}