Skip to content

Commit 9f73cae

Browse files
authored
Fix wrong type on hooktask to convert typ from char(16) to varchar(16) (#14148)
* Fix wrong type on hooktask to convert typ from char(16) to varchar(16) * Fix bugs * Improve code * Use different trim function for MSSQL * Fix bug * Removed wrong changed line * Removed wrong changed line * Fix nullable * Fix lint * Ignore sqlite on migration * Fix mssql modify column failure * Move modifyColumn to migrations.go so that other migrate function could use it
1 parent d2ee122 commit 9f73cae

File tree

5 files changed

+114
-8
lines changed

5 files changed

+114
-8
lines changed

models/migrations/migrations.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package migrations
77

88
import (
9+
"context"
910
"fmt"
1011
"os"
1112
"reflect"
@@ -16,6 +17,7 @@ import (
1617
"code.gitea.io/gitea/modules/setting"
1718

1819
"xorm.io/xorm"
20+
"xorm.io/xorm/schemas"
1921
)
2022

2123
const minDBVersion = 70 // Gitea 1.5.3
@@ -273,6 +275,8 @@ var migrations = []Migration{
273275
NewMigration("Convert topic name from 25 to 50", convertTopicNameFrom25To50),
274276
// v164 -> v165
275277
NewMigration("Add scope and nonce columns to oauth2_grant table", addScopeAndNonceColumnsToOAuth2Grant),
278+
// v165 -> v166
279+
NewMigration("Convert hook task type from char(16) to varchar(16) and trim the column", convertHookTaskTypeToVarcharAndTrim),
276280
}
277281

278282
// GetCurrentDBVersion returns the current db version
@@ -737,3 +741,39 @@ func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
737741

738742
return nil
739743
}
744+
745+
// modifyColumn will modify column's type or other propertity. SQLITE is not supported
746+
func modifyColumn(x *xorm.Engine, tableName string, col *schemas.Column) error {
747+
var indexes map[string]*schemas.Index
748+
var err error
749+
// MSSQL have to remove index at first, otherwise alter column will fail
750+
// ref. https://sqlzealots.com/2018/05/09/error-message-the-index-is-dependent-on-column-alter-table-alter-column-failed-because-one-or-more-objects-access-this-column/
751+
if x.Dialect().URI().DBType == schemas.MSSQL {
752+
indexes, err = x.Dialect().GetIndexes(x.DB(), context.Background(), tableName)
753+
if err != nil {
754+
return err
755+
}
756+
757+
for _, index := range indexes {
758+
_, err = x.Exec(x.Dialect().DropIndexSQL(tableName, index))
759+
if err != nil {
760+
return err
761+
}
762+
}
763+
}
764+
765+
defer func() {
766+
for _, index := range indexes {
767+
_, err = x.Exec(x.Dialect().CreateIndexSQL(tableName, index))
768+
if err != nil {
769+
log.Error("Create index %s on table %s failed: %v", index.Name, tableName, err)
770+
}
771+
}
772+
}()
773+
774+
alterSQL := x.Dialect().ModifyColumnSQL(tableName, col)
775+
if _, err := x.Exec(alterSQL); err != nil {
776+
return err
777+
}
778+
return nil
779+
}

models/migrations/v161.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func convertTaskTypeToString(x *xorm.Engine) error {
3434
}
3535

3636
type HookTask struct {
37-
Typ string `xorm:"char(16) index"`
37+
Typ string `xorm:"VARCHAR(16) index"`
3838
}
3939
if err := x.Sync2(new(HookTask)); err != nil {
4040
return err

models/migrations/v165.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2020 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"xorm.io/xorm"
9+
"xorm.io/xorm/schemas"
10+
)
11+
12+
func convertHookTaskTypeToVarcharAndTrim(x *xorm.Engine) error {
13+
dbType := x.Dialect().URI().DBType
14+
if dbType == schemas.SQLITE { // For SQLITE, varchar or char will always be represented as TEXT
15+
return nil
16+
}
17+
18+
type HookTask struct {
19+
Typ string `xorm:"VARCHAR(16) index"`
20+
}
21+
22+
if err := modifyColumn(x, "hook_task", &schemas.Column{
23+
Name: "typ",
24+
SQLType: schemas.SQLType{
25+
Name: "VARCHAR",
26+
},
27+
Length: 16,
28+
Nullable: true, // To keep compatible as nullable
29+
}); err != nil {
30+
return err
31+
}
32+
33+
var hookTaskTrimSQL string
34+
if dbType == schemas.MSSQL {
35+
hookTaskTrimSQL = "UPDATE hook_task SET typ = RTRIM(LTRIM(typ))"
36+
} else {
37+
hookTaskTrimSQL = "UPDATE hook_task SET typ = TRIM(typ)"
38+
}
39+
if _, err := x.Exec(hookTaskTrimSQL); err != nil {
40+
return err
41+
}
42+
43+
type Webhook struct {
44+
Type string `xorm:"VARCHAR(16) index"`
45+
}
46+
47+
if err := modifyColumn(x, "webhook", &schemas.Column{
48+
Name: "type",
49+
SQLType: schemas.SQLType{
50+
Name: "VARCHAR",
51+
},
52+
Length: 16,
53+
Nullable: true, // To keep compatible as nullable
54+
}); err != nil {
55+
return err
56+
}
57+
58+
var webhookTrimSQL string
59+
if dbType == schemas.MSSQL {
60+
webhookTrimSQL = "UPDATE webhook SET type = RTRIM(LTRIM(type))"
61+
} else {
62+
webhookTrimSQL = "UPDATE webhook SET type = TRIM(type)"
63+
}
64+
_, err := x.Exec(webhookTrimSQL)
65+
return err
66+
}

models/webhook.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ type Webhook struct {
113113
*HookEvent `xorm:"-"`
114114
IsSSL bool `xorm:"is_ssl"`
115115
IsActive bool `xorm:"INDEX"`
116-
Type HookTaskType `xorm:"char(16) 'type'"`
116+
Type HookTaskType `xorm:"VARCHAR(16) 'type'"`
117117
Meta string `xorm:"TEXT"` // store hook-specific attributes
118118
LastStatus HookStatus // Last delivery status
119119

@@ -641,9 +641,9 @@ type HookTask struct {
641641
RepoID int64 `xorm:"INDEX"`
642642
HookID int64
643643
UUID string
644-
Typ HookTaskType
645-
URL string `xorm:"TEXT"`
646-
Signature string `xorm:"TEXT"`
644+
Typ HookTaskType `xorm:"VARCHAR(16) index"`
645+
URL string `xorm:"TEXT"`
646+
Signature string `xorm:"TEXT"`
647647
api.Payloader `xorm:"-"`
648648
PayloadContent string `xorm:"TEXT"`
649649
HTTPMethod string `xorm:"http_method"`

services/webhook/webhook.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ var (
6060

6161
// RegisterWebhook registers a webhook
6262
func RegisterWebhook(name string, webhook *webhook) {
63-
webhooks[models.HookTaskType(strings.TrimSpace(name))] = webhook
63+
webhooks[models.HookTaskType(name)] = webhook
6464
}
6565

6666
// IsValidHookTaskType returns true if a webhook registered
6767
func IsValidHookTaskType(name string) bool {
6868
if name == models.GITEA || name == models.GOGS {
6969
return true
7070
}
71-
_, ok := webhooks[models.HookTaskType(strings.TrimSpace(name))]
71+
_, ok := webhooks[models.HookTaskType(name)]
7272
return ok
7373
}
7474

@@ -147,7 +147,7 @@ func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.Hoo
147147

148148
var payloader api.Payloader
149149
var err error
150-
webhook, ok := webhooks[strings.TrimSpace(w.Type)] // NOTICE: w.Type maynot be trimmed before store into database
150+
webhook, ok := webhooks[w.Type]
151151
if ok {
152152
payloader, err = webhook.payloadCreator(p, event, w.Meta)
153153
if err != nil {

0 commit comments

Comments
 (0)