Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve action table indices #19472

Merged
merged 16 commits into from Jun 18, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 19 additions & 7 deletions models/action.go
Expand Up @@ -30,6 +30,7 @@ import (
"code.gitea.io/gitea/modules/util"

"xorm.io/builder"
"xorm.io/xorm/schemas"
)

// ActionType represents the type of an action.
Expand Down Expand Up @@ -70,25 +71,36 @@ const (
// used in template render.
type Action struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"INDEX"` // Receiver user id.
UserID int64 // Receiver user id.
OpType ActionType
ActUserID int64 `xorm:"INDEX"` // Action user id.
ActUser *user_model.User `xorm:"-"`
RepoID int64 `xorm:"INDEX"`
ActUserID int64 // Action user id.
ActUser *user_model.User `xorm:"-"`
RepoID int64
Repo *repo_model.Repository `xorm:"-"`
CommentID int64 `xorm:"INDEX"`
Comment *issues_model.Comment `xorm:"-"`
IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"`
IsDeleted bool `xorm:"NOT NULL DEFAULT false"`
RefName string
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
IsPrivate bool `xorm:"NOT NULL DEFAULT false"`
lunny marked this conversation as resolved.
Show resolved Hide resolved
Content string `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
CreatedUnix timeutil.TimeStamp `xorm:"created"`
}

func init() {
db.RegisterModel(new(Action))
}

// TableIndices implements xorm's TableIndices interface
func (a *Action) TableIndices() []*schemas.Index {
actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")

repoIndex := schemas.NewIndex("r_c_u_d", schemas.IndexType)
repoIndex.AddColumn("repo_id", "created_unix", "user_id", "is_deleted")

return []*schemas.Index{actUserIndex, repoIndex}
}

// GetOpType gets the ActionType of this action.
func (a *Action) GetOpType() ActionType {
return a.OpType
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Expand Up @@ -387,6 +387,8 @@ var migrations = []Migration{
NewMigration("Add auto merge table", addAutoMergeTable),
// v215 -> v216
NewMigration("allow to view files in PRs", addReviewViewedFiles),
// v216 -> v217
NewMigration("Improve Action table indices", improveActionTableIndices),
}

// GetCurrentDBVersion returns the current db version
Expand Down
66 changes: 66 additions & 0 deletions models/migrations/v216.go
@@ -0,0 +1,66 @@
// 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 migrations

import (
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/xorm"
zeripath marked this conversation as resolved.
Show resolved Hide resolved
"xorm.io/xorm/schemas"
)

type improveActionTableIndicesAction struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know whether a private struct could work with xorm.

Copy link
Contributor Author

@zeripath zeripath Jun 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if you're meaning this as a comment, e.g. I didn't know that a private struct would work with xorm, or if you're trying to express doubt that this will work, e.g. I don't think a private struct will work with xorm.

It will work.

If you are given a pointer to a nonExportedStruct:

package someplace

type notExportedStruct {
   Exported string
}

func NewNotExported() *notExportedStruct {
  return &notExportedStruct{}
}

you can always create another copy of it using:

package main

import "someplace"

func main() {
  notExported := somplace.NewNotExported()

	val := reflect.ValueOf(notExported).Elem()
	typ := val.Type()

	newNotExportedVal := reflect.New(typ)
  newNotExportedVal.Elem().FieldByName("Exported").SetString("I have been set by reflection")

	fmt.Println(newNotExportedVal.Interface())
}

Which is what xorm does internally anyway.

Xorm doesn't need to know or be able to cast to the non-exported type - it just uses reflection to look across the exported fields which will always work or casts to interfaces it knows e.g. TableName. newNotExportedVal can be cast to an interface{} using the .Interface() function as normal.

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 (a *improveActionTableIndicesAction) TableName() string {
return "action"
}

// TableIndices implements xorm's TableIndices interface
func (a *improveActionTableIndicesAction) TableIndices() []*schemas.Index {
actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")

repoIndex := schemas.NewIndex("r_c_u_d", schemas.IndexType)
repoIndex.AddColumn("repo_id", "created_unix", "user_id", "is_deleted")

return []*schemas.Index{actUserIndex, repoIndex}
}

func improveActionTableIndices(x *xorm.Engine) error {
{
type Action struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"INDEX"` // Receiver user id.
OpType int
ActUserID int64 `xorm:"INDEX"` // Action user id.
RepoID int64 `xorm:"INDEX"`
CommentID int64 `xorm:"INDEX"`
IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"`
RefName string
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
Content string `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
}
if err := x.Sync2(&Action{}); err != nil {
return err
}
if err := x.DropIndexes(&Action{}); err != nil {
return err
}
}
return x.Sync2(&improveActionTableIndicesAction{})
}