aboutsummaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/db/engine_test.go33
-rw-r--r--models/fixtures/foreign_reference.yml1
-rw-r--r--models/foreignreference/error.go52
-rw-r--r--models/foreignreference/foreignreference.go31
-rw-r--r--models/issues/issue.go60
-rw-r--r--models/issues/issue_test.go34
-rw-r--r--models/migrate.go7
-rw-r--r--models/migrate_test.go12
-rw-r--r--models/migrations/migrations.go2
-rw-r--r--models/migrations/v1_19/v237.go15
10 files changed, 55 insertions, 192 deletions
diff --git a/models/db/engine_test.go b/models/db/engine_test.go
index fa1ac08a17..5514366777 100644
--- a/models/db/engine_test.go
+++ b/models/db/engine_test.go
@@ -12,6 +12,8 @@ import (
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting"
+ _ "code.gitea.io/gitea/cmd" // for TestPrimaryKeys
+
"github.com/stretchr/testify/assert"
)
@@ -51,3 +53,34 @@ func TestDeleteOrphanedObjects(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, countBefore, countAfter)
}
+
+func TestPrimaryKeys(t *testing.T) {
+ // Some dbs require that all tables have primary keys, see
+ // https://github.com/go-gitea/gitea/issues/21086
+ // https://github.com/go-gitea/gitea/issues/16802
+ // To avoid creating tables without primary key again, this test will check them.
+ // Import "code.gitea.io/gitea/cmd" to make sure each db.RegisterModel in init functions has been called.
+
+ beans, err := db.NamesToBean()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ whitelist := map[string]string{
+ "the_table_name_to_skip_checking": "Write a note here to explain why",
+ }
+
+ for _, bean := range beans {
+ table, err := db.TableInfo(bean)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if why, ok := whitelist[table.Name]; ok {
+ t.Logf("ignore %q because %q", table.Name, why)
+ continue
+ }
+ if len(table.PrimaryKeys) == 0 {
+ t.Errorf("table %q has no primary key", table.Name)
+ }
+ }
+}
diff --git a/models/fixtures/foreign_reference.yml b/models/fixtures/foreign_reference.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/foreign_reference.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/foreignreference/error.go b/models/foreignreference/error.go
deleted file mode 100644
index 07ed1052a6..0000000000
--- a/models/foreignreference/error.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2022 Gitea. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package foreignreference
-
-import (
- "fmt"
-
- "code.gitea.io/gitea/modules/util"
-)
-
-// ErrLocalIndexNotExist represents a "LocalIndexNotExist" kind of error.
-type ErrLocalIndexNotExist struct {
- RepoID int64
- ForeignIndex int64
- Type string
-}
-
-// ErrLocalIndexNotExist checks if an error is a ErrLocalIndexNotExist.
-func IsErrLocalIndexNotExist(err error) bool {
- _, ok := err.(ErrLocalIndexNotExist)
- return ok
-}
-
-func (err ErrLocalIndexNotExist) Error() string {
- return fmt.Sprintf("repository %d has no LocalIndex for ForeignIndex %d of type %s", err.RepoID, err.ForeignIndex, err.Type)
-}
-
-func (err ErrLocalIndexNotExist) Unwrap() error {
- return util.ErrNotExist
-}
-
-// ErrForeignIndexNotExist represents a "ForeignIndexNotExist" kind of error.
-type ErrForeignIndexNotExist struct {
- RepoID int64
- LocalIndex int64
- Type string
-}
-
-// ErrForeignIndexNotExist checks if an error is a ErrForeignIndexNotExist.
-func IsErrForeignIndexNotExist(err error) bool {
- _, ok := err.(ErrForeignIndexNotExist)
- return ok
-}
-
-func (err ErrForeignIndexNotExist) Error() string {
- return fmt.Sprintf("repository %d has no ForeignIndex for LocalIndex %d of type %s", err.RepoID, err.LocalIndex, err.Type)
-}
-
-func (err ErrForeignIndexNotExist) Unwrap() error {
- return util.ErrNotExist
-}
diff --git a/models/foreignreference/foreignreference.go b/models/foreignreference/foreignreference.go
deleted file mode 100644
index 2d2ad04c5a..0000000000
--- a/models/foreignreference/foreignreference.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2022 Gitea. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package foreignreference
-
-import (
- "code.gitea.io/gitea/models/db"
-)
-
-// Type* are valid values for the Type field of ForeignReference
-const (
- TypeIssue = "issue"
- TypePullRequest = "pull_request"
- TypeComment = "comment"
- TypeReview = "review"
- TypeReviewComment = "review_comment"
- TypeRelease = "release"
-)
-
-// ForeignReference represents external references
-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)"`
-}
-
-func init() {
- db.RegisterModel(new(ForeignReference))
-}
diff --git a/models/issues/issue.go b/models/issues/issue.go
index fc93fcf454..f45e635c0e 100644
--- a/models/issues/issue.go
+++ b/models/issues/issue.go
@@ -9,11 +9,9 @@ import (
"fmt"
"regexp"
"sort"
- "strconv"
"strings"
"code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/foreignreference"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access"
@@ -136,12 +134,11 @@ type Issue struct {
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
- Attachments []*repo_model.Attachment `xorm:"-"`
- Comments []*Comment `xorm:"-"`
- Reactions ReactionList `xorm:"-"`
- TotalTrackedTime int64 `xorm:"-"`
- Assignees []*user_model.User `xorm:"-"`
- ForeignReference *foreignreference.ForeignReference `xorm:"-"`
+ Attachments []*repo_model.Attachment `xorm:"-"`
+ Comments []*Comment `xorm:"-"`
+ Reactions ReactionList `xorm:"-"`
+ TotalTrackedTime int64 `xorm:"-"`
+ Assignees []*user_model.User `xorm:"-"`
// IsLocked limits commenting abilities to users on an issue
// with write access
@@ -321,29 +318,6 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) {
return nil
}
-func (issue *Issue) loadForeignReference(ctx context.Context) (err error) {
- if issue.ForeignReference != nil {
- return nil
- }
- reference := &foreignreference.ForeignReference{
- RepoID: issue.RepoID,
- LocalIndex: issue.Index,
- Type: foreignreference.TypeIssue,
- }
- has, err := db.GetEngine(ctx).Get(reference)
- if err != nil {
- return err
- } else if !has {
- return foreignreference.ErrForeignIndexNotExist{
- RepoID: issue.RepoID,
- LocalIndex: issue.Index,
- Type: foreignreference.TypeIssue,
- }
- }
- issue.ForeignReference = reference
- return nil
-}
-
// LoadMilestone load milestone of this issue.
func (issue *Issue) LoadMilestone(ctx context.Context) (err error) {
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
@@ -406,10 +380,6 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
}
}
- if err = issue.loadForeignReference(ctx); err != nil && !foreignreference.IsErrForeignIndexNotExist(err) {
- return err
- }
-
return issue.loadReactions(ctx)
}
@@ -1097,26 +1067,6 @@ func GetIssueByIndex(repoID, index int64) (*Issue, error) {
return issue, nil
}
-// GetIssueByForeignIndex returns raw issue by foreign ID
-func GetIssueByForeignIndex(ctx context.Context, repoID, foreignIndex int64) (*Issue, error) {
- reference := &foreignreference.ForeignReference{
- RepoID: repoID,
- ForeignIndex: strconv.FormatInt(foreignIndex, 10),
- Type: foreignreference.TypeIssue,
- }
- has, err := db.GetEngine(ctx).Get(reference)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, foreignreference.ErrLocalIndexNotExist{
- RepoID: repoID,
- ForeignIndex: foreignIndex,
- Type: foreignreference.TypeIssue,
- }
- }
- return GetIssueByIndex(repoID, reference.LocalIndex)
-}
-
// GetIssueWithAttrsByIndex returns issue by index in a repository.
func GetIssueWithAttrsByIndex(repoID, index int64) (*Issue, error) {
issue, err := GetIssueByIndex(repoID, index)
diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go
index 6764a9e626..de1da19ab9 100644
--- a/models/issues/issue_test.go
+++ b/models/issues/issue_test.go
@@ -7,13 +7,11 @@ import (
"context"
"fmt"
"sort"
- "strconv"
"sync"
"testing"
"time"
"code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/foreignreference"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo"
@@ -501,38 +499,6 @@ func TestCorrectIssueStats(t *testing.T) {
assert.EqualValues(t, issueStats.OpenCount, issueAmount)
}
-func TestIssueForeignReference(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4})
- assert.NotEqualValues(t, issue.Index, issue.ID) // make sure they are different to avoid false positive
-
- // it is fine for an issue to not have a foreign reference
- err := issue.LoadAttributes(db.DefaultContext)
- assert.NoError(t, err)
- assert.Nil(t, issue.ForeignReference)
-
- var foreignIndex int64 = 12345
- _, err = issues_model.GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex)
- assert.True(t, foreignreference.IsErrLocalIndexNotExist(err))
-
- err = db.Insert(db.DefaultContext, &foreignreference.ForeignReference{
- LocalIndex: issue.Index,
- ForeignIndex: strconv.FormatInt(foreignIndex, 10),
- RepoID: issue.RepoID,
- Type: foreignreference.TypeIssue,
- })
- assert.NoError(t, err)
-
- err = issue.LoadAttributes(db.DefaultContext)
- assert.NoError(t, err)
-
- assert.EqualValues(t, issue.ForeignReference.ForeignIndex, strconv.FormatInt(foreignIndex, 10))
-
- found, err := issues_model.GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex)
- assert.NoError(t, err)
- assert.EqualValues(t, found.Index, issue.Index)
-}
-
func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
miles := issues_model.MilestoneList{
diff --git a/models/migrate.go b/models/migrate.go
index b1b5568126..82cacd4a75 100644
--- a/models/migrate.go
+++ b/models/migrate.go
@@ -83,13 +83,6 @@ func insertIssue(ctx context.Context, issue *issues_model.Issue) error {
}
}
- if issue.ForeignReference != nil {
- issue.ForeignReference.LocalIndex = issue.Index
- if _, err := sess.Insert(issue.ForeignReference); err != nil {
- return err
- }
- }
-
return nil
}
diff --git a/models/migrate_test.go b/models/migrate_test.go
index 48cd905e4c..42102f9a7d 100644
--- a/models/migrate_test.go
+++ b/models/migrate_test.go
@@ -4,11 +4,9 @@
package models
import (
- "strconv"
"testing"
"code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/foreignreference"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -48,7 +46,6 @@ func assertCreateIssues(t *testing.T, isPull bool) {
UserID: owner.ID,
}
- foreignIndex := int64(12345)
title := "issuetitle1"
is := &issues_model.Issue{
RepoID: repo.ID,
@@ -62,20 +59,11 @@ func assertCreateIssues(t *testing.T, isPull bool) {
IsClosed: true,
Labels: []*issues_model.Label{label},
Reactions: []*issues_model.Reaction{reaction},
- ForeignReference: &foreignreference.ForeignReference{
- ForeignIndex: strconv.FormatInt(foreignIndex, 10),
- RepoID: repo.ID,
- Type: foreignreference.TypeIssue,
- },
}
err := InsertIssues(is)
assert.NoError(t, err)
i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title})
- assert.Nil(t, i.ForeignReference)
- err = i.LoadAttributes(db.DefaultContext)
- assert.NoError(t, err)
- assert.EqualValues(t, strconv.FormatInt(foreignIndex, 10), i.ForeignReference.ForeignIndex)
unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: owner.ID, IssueID: i.ID})
}
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 591bfa3e86..9d9c8f5165 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -444,6 +444,8 @@ var migrations = []Migration{
NewMigration("Add index for access_token", v1_19.AddIndexForAccessToken),
// v236 -> v237
NewMigration("Create secrets table", v1_19.CreateSecretsTable),
+ // v237 -> v238
+ NewMigration("Drop ForeignReference table", v1_19.DropForeignReferenceTable),
}
// GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v1_19/v237.go b/models/migrations/v1_19/v237.go
new file mode 100644
index 0000000000..b23c765aa5
--- /dev/null
+++ b/models/migrations/v1_19/v237.go
@@ -0,0 +1,15 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_19 //nolint
+
+import (
+ "xorm.io/xorm"
+)
+
+func DropForeignReferenceTable(x *xorm.Engine) error {
+ // Drop the table introduced in `v211`, it's considered badly designed and doesn't look like to be used.
+ // See: https://github.com/go-gitea/gitea/issues/21086#issuecomment-1318217453
+ type ForeignReference struct{}
+ return x.DropTables(new(ForeignReference))
+}