mirror of https://github.com/go-gitea/gitea
parent
8a5c597c1d
commit
b482567059
@ -0,0 +1,9 @@ |
||||
- |
||||
id: 1 |
||||
project_id: 1 |
||||
issue_id: 1 |
||||
|
||||
- |
||||
id: 2 |
||||
project_id: 1 |
||||
issue_id: 1 |
@ -0,0 +1,14 @@ |
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_23 //nolint
|
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"code.gitea.io/gitea/models/migrations/base" |
||||
) |
||||
|
||||
func TestMain(m *testing.M) { |
||||
base.MainTest(m) |
||||
} |
@ -0,0 +1,53 @@ |
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_23 //nolint
|
||||
|
||||
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)) |
||||
} |
@ -0,0 +1,52 @@ |
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_23 //nolint
|
||||
|
||||
import ( |
||||
"slices" |
||||
"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.EqualValues(t, 1, len(tables)) |
||||
found := false |
||||
for _, index := range tables[0].Indexes { |
||||
if index.Type == schemas.UniqueType { |
||||
found = true |
||||
slices.Equal(index.Cols, []string{"project_id", "issue_id"}) |
||||
break |
||||
} |
||||
} |
||||
assert.True(t, found) |
||||
} |
Loading…
Reference in new issue